|
|
|
/***************************************************************************
|
|
|
|
begin : Tue Nov 25 2003
|
|
|
|
copyright : (C) 2003 by Jeroen Wijnhout
|
|
|
|
email : Jeroen.Wijnhout@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 "kiletoolmanager.h"
|
|
|
|
|
|
|
|
#include <stdlib.h> //for getenv()
|
|
|
|
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqwidgetstack.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqthread.h>
|
|
|
|
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <ktextedit.h>
|
|
|
|
#include <tdeconfig.h>
|
|
|
|
#include "kiledebug.h"
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <tdeparts/partmanager.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <ksimpleconfig.h>
|
|
|
|
|
|
|
|
#include "kileinfo.h"
|
|
|
|
#include "kileconfig.h"
|
|
|
|
#include "kileproject.h"
|
|
|
|
#include "kiletool_enums.h"
|
|
|
|
#include "kilestdtools.h"
|
|
|
|
#include "kilelogwidget.h"
|
|
|
|
#include "kileoutputwidget.h"
|
|
|
|
#include "kiledocmanager.h"
|
|
|
|
#include "kilesidebar.h"
|
|
|
|
|
|
|
|
namespace KileTool
|
|
|
|
{
|
|
|
|
QueueItem::QueueItem(Base *tool, const TQString & cfg, bool block) : m_tool(tool), m_cfg(cfg), m_bBlock(block)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QueueItem::~QueueItem()
|
|
|
|
{
|
|
|
|
delete m_tool;
|
|
|
|
}
|
|
|
|
|
|
|
|
Base* Queue::tool() const
|
|
|
|
{
|
|
|
|
if ( head() )
|
|
|
|
return head()->tool();
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQString Queue::cfg() const
|
|
|
|
{
|
|
|
|
if ( head() )
|
|
|
|
return head()->cfg();
|
|
|
|
else
|
|
|
|
return TQString();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Queue::shouldBlock() const
|
|
|
|
{
|
|
|
|
if ( head() )
|
|
|
|
return head()->shouldBlock();
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Queue::enqueueNext(QueueItem *item)
|
|
|
|
{
|
|
|
|
if ( count() < 2 )
|
|
|
|
enqueue(item);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
QueueItem *headitem = dequeue();
|
|
|
|
Queue *oldqueue = new Queue(*this);
|
|
|
|
|
|
|
|
setAutoDelete(false); clear();
|
|
|
|
KILE_DEBUG() << "\tenqueueing: " << headitem->tool()->name() << endl;
|
|
|
|
enqueue(headitem);
|
|
|
|
KILE_DEBUG() << "\tenqueueing: " << item->tool()->name() << endl;
|
|
|
|
enqueue(item);
|
|
|
|
while ( oldqueue->head() )
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "\tenqueueing: " << oldqueue->head()->tool()->name() << endl;
|
|
|
|
enqueue(oldqueue->dequeue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Manager::Manager(KileInfo *ki, TDEConfig *config, KileWidget::LogMsg *log, KileWidget::Output *output, KParts::PartManager *manager, TQWidgetStack *stack, KAction *stop, uint to) :
|
|
|
|
m_ki(ki),
|
|
|
|
m_config(config),
|
|
|
|
m_log(log),
|
|
|
|
m_output(output),
|
|
|
|
m_pm(manager),
|
|
|
|
m_stack(stack),
|
|
|
|
m_stop(stop),
|
|
|
|
m_bClear(true),
|
|
|
|
m_nLastResult(Success),
|
|
|
|
m_nTimeout(to)
|
|
|
|
{
|
|
|
|
m_timer = new TQTimer(this);
|
|
|
|
connect(m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(enableClear()));
|
|
|
|
connect(stop, TQT_SIGNAL(activated()), this, TQT_SLOT(stop()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Manager::~Manager() {}
|
|
|
|
|
|
|
|
bool Manager::shouldBlock()
|
|
|
|
{
|
|
|
|
return m_queue.shouldBlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::enableClear()
|
|
|
|
{
|
|
|
|
m_bClear = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Manager::queryContinue(const TQString & question, const TQString & caption /*= TQString()*/)
|
|
|
|
{
|
|
|
|
return (KMessageBox::warningContinueCancel(m_stack, question, caption, KStdGuiItem::cont(), "showNotALaTeXRootDocumentWarning") == KMessageBox::Continue);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::run(const TQString &tool, const TQString & cfg, bool insertNext /*= false*/, bool block /*= false*/)
|
|
|
|
{
|
|
|
|
if (!m_factory)
|
|
|
|
{
|
|
|
|
m_log->printMsg(Error, i18n("No factory installed, contact the author of Kile."));
|
|
|
|
return ConfigureFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
Base* pTool = m_factory->create(tool);
|
|
|
|
if (!pTool)
|
|
|
|
{
|
|
|
|
m_log->printMsg(Error, i18n("Unknown tool %1.").arg(tool));
|
|
|
|
return ConfigureFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
return run(pTool, cfg, insertNext, block);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::run(Base *tool, const TQString & cfg, bool insertNext /*= false*/, bool block /*= false*/)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "==KileTool::Manager::run(Base *)============" << endl;
|
|
|
|
if (m_bClear && (m_queue.count() == 0) )
|
|
|
|
{
|
|
|
|
m_log->clear();
|
|
|
|
m_ki->setLogPresent(false);
|
|
|
|
m_output->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( tool->needsToBePrepared() )
|
|
|
|
tool->prepareToRun(cfg);
|
|
|
|
else
|
|
|
|
tool->configure(cfg);
|
|
|
|
|
|
|
|
//FIXME: shouldn't restart timer if a Sequence command takes longer than the 10 secs
|
|
|
|
//restart timer, so we only clear the logs if a tool is started after 10 sec.
|
|
|
|
m_bClear=false;
|
|
|
|
m_timer->start(m_nTimeout);
|
|
|
|
|
|
|
|
if ( insertNext )
|
|
|
|
m_queue.enqueueNext(new QueueItem(tool, cfg, block));
|
|
|
|
else
|
|
|
|
m_queue.enqueue(new QueueItem(tool, cfg, block));
|
|
|
|
|
|
|
|
KILE_DEBUG() << "\tin queue: " << m_queue.count() << endl;
|
|
|
|
if ( m_queue.count() == 1 )
|
|
|
|
return runNextInQueue();
|
|
|
|
else if ( m_queue.count() > 1 )
|
|
|
|
return Running;
|
|
|
|
else
|
|
|
|
return ConfigureFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::runNext(const TQString &tool , const TQString &config, bool block /*= false*/)
|
|
|
|
{
|
|
|
|
return run(tool, config, true, block);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::runNext(Base *tool, const TQString &config, bool block /*= false*/)
|
|
|
|
{
|
|
|
|
return run(tool, config, true, block);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::runBlocking(const TQString &tool, const TQString &config /*= TQString()*/, bool insertAtTop /*= false*/)
|
|
|
|
{
|
|
|
|
if ( run(tool, config, insertAtTop, true) == Running )
|
|
|
|
return lastResult();
|
|
|
|
else
|
|
|
|
return Failed;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::runNextBlocking(const TQString &tool, const TQString &config)
|
|
|
|
{
|
|
|
|
return runBlocking(tool, config, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Manager::runNextInQueue()
|
|
|
|
{
|
|
|
|
Base *head = m_queue.tool();
|
|
|
|
if (head)
|
|
|
|
{
|
|
|
|
if (m_log->lines() > 1)
|
|
|
|
m_log->append("\n");
|
|
|
|
|
|
|
|
if ( ! head->isPrepared() )
|
|
|
|
head->prepareToRun();
|
|
|
|
|
|
|
|
int status;
|
|
|
|
if ( (status=head->run()) != Running ) //tool did not even start, clear queue
|
|
|
|
{
|
|
|
|
stop();
|
|
|
|
m_queue.setAutoDelete(true); m_queue.clear(); m_queue.setAutoDelete(false);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
emit(toolStarted());
|
|
|
|
|
|
|
|
return Running;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ConfigureFailed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::initTool(Base *tool)
|
|
|
|
{
|
|
|
|
tool->setInfo(m_ki);
|
|
|
|
tool->setConfig(m_config);
|
|
|
|
|
|
|
|
connect(tool, TQT_SIGNAL(message(int, const TQString &, const TQString &)), m_log, TQT_SLOT(printMsg(int, const TQString &, const TQString &)));
|
|
|
|
connect(tool, TQT_SIGNAL(output(const TQString &)), m_output, TQT_SLOT(receive(const TQString &)));
|
|
|
|
connect(tool, TQT_SIGNAL(done(Base*,int)), this, TQT_SLOT(done(Base*, int)));
|
|
|
|
connect(tool, TQT_SIGNAL(start(Base* )), this, TQT_SLOT(started(Base*)));
|
|
|
|
connect(tool, TQT_SIGNAL(requestSaveAll(bool, bool)), this, TQT_SIGNAL(requestSaveAll(bool, bool)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::started(Base *tool)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "STARTING tool: " << tool->name() << endl;
|
|
|
|
m_stop->setEnabled(true);
|
|
|
|
|
|
|
|
if (tool->isViewer())
|
|
|
|
{
|
|
|
|
if ( tool == m_queue.tool() ) m_queue.dequeue();
|
|
|
|
m_stop->setEnabled(false);
|
|
|
|
TQTimer::singleShot(100, this, TQT_SLOT(runNextInQueue()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::stop()
|
|
|
|
{
|
|
|
|
m_stop->setEnabled(false);
|
|
|
|
if ( m_queue.tool() )
|
|
|
|
m_queue.tool()->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::done(Base *tool, int result)
|
|
|
|
{
|
|
|
|
m_stop->setEnabled(false);
|
|
|
|
m_nLastResult = result;
|
|
|
|
|
|
|
|
if ( tool != m_queue.tool() ) //oops, tool finished async, could happen with view tools
|
|
|
|
{
|
|
|
|
delete tool;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete m_queue.dequeue();
|
|
|
|
|
|
|
|
if ( result == Aborted)
|
|
|
|
tool->sendMessage(Error, i18n("Aborted"));
|
|
|
|
|
|
|
|
if ( result != Success && result != Silent ) //abort execution, delete all remaining tools
|
|
|
|
{
|
|
|
|
m_queue.setAutoDelete(true); m_queue.clear(); m_queue.setAutoDelete(false);
|
|
|
|
m_ki->outputView()->showPage(m_log);
|
|
|
|
}
|
|
|
|
else //continue
|
|
|
|
runNextInQueue();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Manager::currentGroup(const TQString &name, bool usequeue, bool useproject)
|
|
|
|
{
|
|
|
|
if (useproject)
|
|
|
|
{
|
|
|
|
KileProject *project = m_ki->docManager()->activeProject();
|
|
|
|
if (project)
|
|
|
|
{
|
|
|
|
TQString cfg = configName(name, dynamic_cast<TDEConfig*>(project->config()));
|
|
|
|
if ( cfg.length() > 0 ) return groupFor(name, cfg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (usequeue && m_queue.tool() && (m_queue.tool()->name() == name) && (!m_queue.cfg().isNull()) )
|
|
|
|
return groupFor(name, m_queue.cfg());
|
|
|
|
else
|
|
|
|
return groupFor(name, m_config);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Manager::retrieveEntryMap(const TQString & name, Config & map, bool usequeue, bool useproject, const TQString & cfg /*= TQString()*/)
|
|
|
|
{
|
|
|
|
TQString group = (cfg == TQString() )
|
|
|
|
? currentGroup(name, usequeue, useproject) : groupFor(name, cfg);
|
|
|
|
|
|
|
|
KILE_DEBUG() << "==KileTool::Manager::retrieveEntryMap=============" << endl;
|
|
|
|
KILE_DEBUG() << "\t" << name << " => " << group << endl;
|
|
|
|
if ( m_config->hasGroup(group) )
|
|
|
|
{
|
|
|
|
map = m_config->entryMap(group);
|
|
|
|
|
|
|
|
//use project overrides
|
|
|
|
KileProject *project = m_ki->docManager()->activeProject();
|
|
|
|
if ( useproject && project)
|
|
|
|
{
|
|
|
|
TDEConfig *prjcfg = dynamic_cast<TDEConfig*>(project->config());
|
|
|
|
if ( prjcfg )
|
|
|
|
{
|
|
|
|
TQString grp = groupFor(name, prjcfg);
|
|
|
|
Config prjmap = prjcfg->entryMap(grp);
|
|
|
|
for (Config::Iterator it = prjmap.begin(); it != prjmap.end(); ++it)
|
|
|
|
{
|
|
|
|
map[it.key()] = it.data();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::saveEntryMap(const TQString & name, Config & map, bool usequeue, bool useproject)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "==KileTool::Manager::saveEntryMap=============" << endl;
|
|
|
|
TQString group = currentGroup(name, usequeue, useproject);
|
|
|
|
KILE_DEBUG() << "\t" << name << " => " << group << endl;
|
|
|
|
m_config->setGroup(group);
|
|
|
|
|
|
|
|
Config::Iterator it;
|
|
|
|
for ( it = map.begin() ; it != map.end(); ++it)
|
|
|
|
{
|
|
|
|
if ( ! it.data().isEmpty() )
|
|
|
|
m_config->writeEntry(it.key(), it.data());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Manager::configure(Base *tool, const TQString & cfg /*=TQString()*/)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "==KileTool::Manager::configure()===============" << endl;
|
|
|
|
//configure the tool
|
|
|
|
|
|
|
|
Config map;
|
|
|
|
|
|
|
|
if ( ! retrieveEntryMap(tool->name(), map, true, true, cfg) )
|
|
|
|
{
|
|
|
|
m_log->printMsg(Error, i18n("Cannot find the tool %1 in the configuration database.").arg(tool->name()));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
tool->setEntryMap(map);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Manager::wantGUIState(const TQString & state)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "REQUESTED state: " << state << endl;
|
|
|
|
emit(requestGUIState(state));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList toolList(TDEConfig *config, bool menuOnly)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "==KileTool::toolList()==================" << endl;
|
|
|
|
|
|
|
|
TQStringList groups = config->groupList(), tools;
|
|
|
|
TQRegExp re = TQRegExp("Tool/(.+)/.+");
|
|
|
|
|
|
|
|
for ( uint i = 0; i < groups.count(); ++i )
|
|
|
|
{
|
|
|
|
if ( re.exactMatch(groups[i]) )
|
|
|
|
{
|
|
|
|
if ( ! groups[i].endsWith(configName(re.cap(1), config)) ) continue;
|
|
|
|
|
|
|
|
if ( (! menuOnly) || ( menuFor(re.cap(1),config) != "none" ) )
|
|
|
|
{
|
|
|
|
tools.append(re.cap(1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tools.sort();
|
|
|
|
|
|
|
|
return tools;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString configName(const TQString & tool, TDEConfig *config)
|
|
|
|
{
|
|
|
|
config->setGroup("Tools");
|
|
|
|
return config->readEntry(tool, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
void setConfigName(const TQString & tool, const TQString & name, TDEConfig *config)
|
|
|
|
{
|
|
|
|
KILE_DEBUG() << "==KileTool::Manager::setConfigName(" << tool << "," << name << ")===============" << endl;
|
|
|
|
config->setGroup("Tools");
|
|
|
|
config->writeEntry(tool, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString groupFor(const TQString &tool, TDEConfig *config)
|
|
|
|
{
|
|
|
|
return groupFor(tool, configName(tool, config));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString groupFor(const TQString & tool, const TQString & cfg /* = Default */ )
|
|
|
|
{
|
|
|
|
return "Tool/" + tool + '/' + cfg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void extract(const TQString &str, TQString &tool, TQString &cfg)
|
|
|
|
{
|
|
|
|
static TQRegExp re("([^\\(]*)\\((.*)\\)");
|
|
|
|
TQString lcl = str;
|
|
|
|
lcl.stripWhiteSpace();
|
|
|
|
cfg = TQString();
|
|
|
|
if ( re.exactMatch(lcl) )
|
|
|
|
{
|
|
|
|
tool = re.cap(1).stripWhiteSpace();
|
|
|
|
cfg = re.cap(2).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
tool = lcl;
|
|
|
|
KILE_DEBUG() << "===void extract(const TQString &str = " << str << " , TQString &tool = " << tool << ", TQString &cfg = " << cfg << " )===" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString format(const TQString & tool, const TQString &cfg)
|
|
|
|
{
|
|
|
|
if (!cfg.isNull())
|
|
|
|
return tool + '(' + cfg + ')';
|
|
|
|
else
|
|
|
|
return tool;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList configNames(const TQString &tool, TDEConfig *config)
|
|
|
|
{
|
|
|
|
TQStringList groups = config->groupList(), configs;
|
|
|
|
TQRegExp re = TQRegExp("Tool/"+ tool +"/(.+)");
|
|
|
|
|
|
|
|
for ( uint i = 0; i < groups.count(); ++i )
|
|
|
|
{
|
|
|
|
if ( re.exactMatch(groups[i]) )
|
|
|
|
{
|
|
|
|
configs.append(re.cap(1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return configs;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString menuFor(const TQString &tool, TDEConfig *config)
|
|
|
|
{
|
|
|
|
config->setGroup("ToolsGUI");
|
|
|
|
return config->readEntry(tool, "Other,gear").section(',',0,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString iconFor(const TQString &tool, TDEConfig *config)
|
|
|
|
{
|
|
|
|
config->setGroup("ToolsGUI");
|
|
|
|
return config->readEntry(tool, "Other,gear").section(',',1,1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setGUIOptions(const TQString &tool, const TQString &menu, const TQString &icon, TDEConfig *config)
|
|
|
|
{
|
|
|
|
TQString entry = menu + ',' + icon;
|
|
|
|
|
|
|
|
config->setGroup("ToolsGUI");
|
|
|
|
config->writeEntry(tool, entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString categoryFor(const TQString &clss)
|
|
|
|
{
|
|
|
|
if ( clss == "Compile" || clss == "LaTeX" )
|
|
|
|
return "Compile";
|
|
|
|
if ( clss == "Convert" )
|
|
|
|
return "Convert";
|
|
|
|
if ( clss == "View" || clss == "ViewBib" || clss == "ViewHTML" || clss == "ForwardDVI" )
|
|
|
|
return "View";
|
|
|
|
if ( clss == "Sequence" )
|
|
|
|
return "Sequence";
|
|
|
|
if ( clss == "Archive")
|
|
|
|
return "Archive";
|
|
|
|
return "Base";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "kiletoolmanager.moc"
|