You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kile/src/kile/templates.cpp

386 lines
12 KiB

/*******************************************************************************************
begin : Sat Apr 26 2003
copyright : (C) 2003 by Jeroen Wijnhout (wijnhout@science.uva.nl)
2005 by Holger Danielsson (holger.danielsson@t-online.de)
2007 by Michel Ludwig (michel.ludwig@kdemail.net)
*******************************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "templates.h"
#include <kapp.h>
#include "kiledebug.h"
#include <tdeglobal.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <tdeio/job.h>
#include <tdeio/netaccess.h>
#include <tdemessagebox.h>
#include <tqdir.h>
#include <tqfileinfo.h>
#include <tqstringlist.h>
#include <tqregexp.h>
#include "kileinfo.h"
// 2005-08-04: dani
// - added script support to search existing class files
// (classes: Koma, Beamer, Prosper, HA-prosper)
// - sort items ('Empty Document' will always be the first entry)
// 2006-30-04: tbraun
// - drag and drop makes no sense here
// - use the Select mode
namespace KileTemplate {
////////////////////// Info //////////////////////
Info::Info() : type(KileDocument::Undefined)
{
}
bool Info::operator==(const Info ti) const
{
return name==ti.name;
}
////////////////////// Manager //////////////////////
Manager::Manager(KileInfo* kileInfo, TQObject* parent, const char* name) : TQObject(parent, name), m_kileInfo(kileInfo)
{
}
Manager::~Manager() {
}
bool Manager::copyAppData(const KURL& src, const TQString& subdir, const TQString& fileName) {
TQString dir;
//let saveLocation find and create the appropriate place to
//store the templates (usually $HOME/.trinity/share/apps/kile/templates)
dir = TDEGlobal::dirs()->saveLocation("appdata", subdir, true);
KURL targetURL = KURL::fromPathOrURL(dir);
targetURL.addPath(fileName);
//if a directory is found
if (!dir.isNull()) {
return TDEIO::NetAccess::copy(src, targetURL, kapp->mainWidget());
}
else {
KMessageBox::error(0, i18n("Could not find a folder to save %1 to.\nCheck whether you have a .kde folder with write permissions in your home folder.").arg(fileName));
return false;
}
}
bool Manager::removeAppData(const TQString &file) {
TQFileInfo fileInfo(file);
if(fileInfo.exists()) {
return TDEIO::NetAccess::del(KURL::fromPathOrURL(file), kapp->mainWidget());
}
return true;
}
bool Manager::searchForTemplate(const TQString& name, KileDocument::Type& type) const {
for (KileTemplate::TemplateListConstIterator i = m_TemplateList.constBegin(); i != m_TemplateList.constEnd(); ++i)
{
KileTemplate::Info info = *i;
if(info.name == name && info.type == type) {
return true;
}
}
return false;
}
bool Manager::add(const KURL& templateSourceURL, const TQString& name, const KURL& icon) {
KileDocument::Extensions *extensions = m_kileInfo->extensions();
KileDocument::Type type = extensions->determineDocumentType(templateSourceURL);
return add(templateSourceURL, type, name, icon);
}
bool Manager::add(const KURL& templateSourceURL, KileDocument::Type type, const TQString& name, const KURL& icon) {
KileDocument::Extensions *extensions = m_kileInfo->extensions();
TQString extension = extensions->defaultExtensionForDocumentType(type);
return copyAppData(templateSourceURL, "templates", "template_" + name + extension) && copyAppData(icon, "pics", "type_" + name + extension + ".kileicon");
}
bool Manager::remove(Info ti) {
return removeAppData(ti.path) && removeAppData(ti.icon);
}
bool Manager::replace(const KileTemplate::Info& toBeReplaced, const KURL& newTemplateSourceURL, const TQString& newName, const KURL& newIcon) {
KileDocument::Type type = m_kileInfo->extensions()->determineDocumentType(newTemplateSourceURL);
//start by copying the files that belong to the new template to a safe place
TQString templateTempFile, iconTempFile;
if(!TDEIO::NetAccess::download(newTemplateSourceURL, templateTempFile, kapp->mainWidget())) {
return false;
}
if(!TDEIO::NetAccess::download(newIcon, iconTempFile, kapp->mainWidget())) {
TDEIO::NetAccess::removeTempFile(templateTempFile);
return false;
}
//now delete the template that should be replaced
if(!remove(toBeReplaced)) {
TDEIO::NetAccess::removeTempFile(templateTempFile);
TDEIO::NetAccess::removeTempFile(iconTempFile);
}
//finally, create the new template
if(!add(KURL::fromPathOrURL(templateTempFile), type, newName, KURL::fromPathOrURL(iconTempFile))) {
TDEIO::NetAccess::removeTempFile(templateTempFile);
TDEIO::NetAccess::removeTempFile(iconTempFile);
return false;
}
TDEIO::NetAccess::removeTempFile(templateTempFile);
TDEIO::NetAccess::removeTempFile(iconTempFile);
return true;
}
void Manager::scanForTemplates() {
KILE_DEBUG() << "===scanForTemplates()===================" << endl;
TQStringList dirs = TDEGlobal::dirs()->findDirs("appdata", "templates");
TQDir templates;
KileTemplate::Info ti;
KileDocument::Extensions *extensions = m_kileInfo->extensions();
m_TemplateList.clear();
for ( TQValueListIterator<TQString> i = dirs.begin(); i != dirs.end(); ++i)
{
templates = TQDir(*i, "template_*");
for ( uint j = 0; j< templates.count(); ++j)
{
ti.path = templates.path() + '/' + templates[j];
TQFileInfo fileInfo(ti.path);
ti.name = fileInfo.baseName(true).mid(9); //remove "template_", do it this way to avoid problems with user input!
ti.type = extensions->determineDocumentType(KURL::fromPathOrURL(ti.path));
ti.icon = TDEGlobal::dirs()->findResource("appdata","pics/type_" + ti.name + extensions->defaultExtensionForDocumentType(ti.type) + ".kileicon");
if (m_TemplateList.contains(ti))
{
KILE_DEBUG() << "\tignoring: " << ti.path << endl;
}
else
{
m_TemplateList.append(ti);
KILE_DEBUG() << "\tadding: " << ti.name << " " << ti.path << endl;
}
}
}
}
TemplateList Manager::getAllTemplates() const {
return m_TemplateList;
}
TemplateList Manager::getTemplates(KileDocument::Type type) const {
if(type == KileDocument::Undefined)
{
return getAllTemplates();
}
TemplateList toReturn;
for (KileTemplate::TemplateListConstIterator i = m_TemplateList.constBegin(); i != m_TemplateList.constEnd(); ++i)
{
KileTemplate::Info info = *i;
if(info.type == type) {
toReturn.push_back(info);
}
}
return toReturn;
}
}
////////////////////// TemplateItem //////////////////////
// new compare function to make the "Empty (...) Document" items appear at the beginning
TemplateItem::TemplateItem(TQIconView * parent, const KileTemplate::Info& info) : TQIconViewItem(parent,info.name, TQPixmap(info.icon))
{
setDragEnabled(false);
m_info = info;
}
int TemplateItem::compare( TQIconViewItem *i ) const
{
if ( key() == DEFAULT_EMPTY_CAPTION ) {
return -1;
}
else if ( i->key() == DEFAULT_EMPTY_CAPTION ) {
return 1;
}
else {
return key().compare( i->key() );
}
}
////////////////////// TemplateIconView //////////////////////
TemplateIconView::TemplateIconView(TQWidget *parent, const char *name, WFlags f) : TDEIconView(parent, name, f), m_templateManager(NULL), m_proc(NULL) {
setItemsMovable(false);
setMode(TDEIconView::Select);
setResizeMode(TQIconView::Adjust);
setSelectionMode(TQIconView::Single);
setResizePolicy(TQScrollView::Default);
setArrangement(TQIconView::TopToBottom);
setMinimumHeight(100);
}
TemplateIconView::~TemplateIconView() {
}
void TemplateIconView::setTemplateManager(KileTemplate::Manager *templateManager) {
m_templateManager = templateManager;
}
void TemplateIconView::fillWithTemplates(KileDocument::Type type) {
if(!m_templateManager) {
return;
}
clear();
if(type == KileDocument::LaTeX) {
searchLaTeXClassFiles();
}
else {
addTemplateIcons(type);
}
}
void TemplateIconView::searchLaTeXClassFiles()
{
if(!m_templateManager) return;
TQString command = "kpsewhich -format=tex scrartcl.cls beamer.cls prosper.cls HA-prosper.sty";
delete m_proc;
m_proc = new TDEProcess(this);
m_proc->clearArguments();
m_proc->setUseShell(true);
(*m_proc) << TQStringList::split(' ', command);
m_output = TQString();
connect(m_proc, TQ_SIGNAL(receivedStdout(TDEProcess*,char*,int)),
this, TQ_SLOT(slotProcessOutput(TDEProcess*,char*,int)) );
connect(m_proc, TQ_SIGNAL(receivedStderr(TDEProcess*,char*,int)),
this, TQ_SLOT(slotProcessOutput(TDEProcess*,char*,int)) );
connect(m_proc, TQ_SIGNAL(processExited(TDEProcess*)),
this, TQ_SLOT(slotProcessExited(TDEProcess*)) );
KILE_DEBUG() << "=== NewFileWidget::searchClassFiles() ====================" << endl;
KILE_DEBUG() << "\texecute: " << command << endl;
if ( ! m_proc->start(TDEProcess::NotifyOnExit, TDEProcess::AllOutput) )
{
KILE_DEBUG() << "\tstart of shell process failed" << endl;
addTemplateIcons(KileDocument::LaTeX);
}
}
void TemplateIconView::slotProcessOutput(TDEProcess*, char* buf, int len)
{
m_output += TQString::fromLocal8Bit(buf,len);
}
void TemplateIconView::slotProcessExited(TDEProcess *proc)
{
if ( ! proc->normalExit() )
m_output = TQString();
addTemplateIcons(KileDocument::LaTeX);
emit classFileSearchFinished();
}
void TemplateIconView::addTemplateIcons(KileDocument::Type type)
{
if(!m_templateManager) return;
TQString emptyIcon = TDEGlobal::dirs()->findResource("appdata", "pics/"+ TQString(DEFAULT_EMPTY_ICON) + ".png" );
KileTemplate::Info emptyDocumentInfo;
emptyDocumentInfo.name = DEFAULT_EMPTY_CAPTION;
emptyDocumentInfo.icon = emptyIcon;
emptyDocumentInfo.type = type;
TemplateItem *emp = new TemplateItem(this, emptyDocumentInfo);
setSelected(emp, true);
if(type == KileDocument::LaTeX) {
// disable non standard templates
TQMap<TQString,bool> map;
map["Scrartcl"] = false;
map["Scrbook"] = false;
map["Scrreprt"] = false;
map["Scrlttr2"] = false;
map["Beamer"] = false;
map["Prosper"] = false;
map["HA-prosper"] = false;
// split search results and look, which class files are present
TQStringList list = TQStringList::split("\n",m_output);
for ( TQStringList::Iterator it=list.begin(); it!=list.end(); ++it )
{
TQString filename = TQFileInfo(*it).fileName();
if ( filename=="scrartcl.cls" )
{
map["Scrartcl"] = true;
map["Scrbook"] = true;
map["Scrreprt"] = true;
map["Scrlttr2"] = true;
}
else if ( filename=="beamer.cls" )
map["Beamer"] = true;
else if ( filename=="prosper.cls" )
map["Prosper"] = true;
else if ( filename=="HA-prosper.sty" )
map["HA-prosper"] = true;
}
KileTemplate::TemplateList templateList = m_templateManager->getTemplates(KileDocument::LaTeX);
// insert all standard templates, all user defined templates
// and those templates, which have a present class
for (KileTemplate::TemplateListIterator i=templateList.begin(); i != templateList.end(); ++i)
{
KileTemplate::Info info = *i;
TQString classname = info.name;
if ( !map.contains(classname) || map[classname]==true )
{
new TemplateItem(this, info);
}
}
}
else {
KileTemplate::TemplateList templateList = m_templateManager->getTemplates(type);
for (KileTemplate::TemplateListIterator i=templateList.begin(); i != templateList.end(); ++i)
{
new TemplateItem(this, *i);
}
}
// sort all items (item for 'Empty Document' will always be the first one)
sort();
// set the default item, if its given
for ( TQIconViewItem *item = firstItem(); item; item = item->nextItem() ) {
if ( static_cast<TemplateItem*>(item)->name() == m_selicon ) {
setSelected(item, true);
ensureItemVisible(item);
}
}
}
#include "templates.moc"