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.
125 lines
3.6 KiB
125 lines
3.6 KiB
/*! @file |
|
|
|
@id $Id$ |
|
*/ |
|
// 1 2 3 4 5 6 7 8 |
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
|
|
#ifndef QBROWSERLIB_EXECUTOR_HXX |
|
#define QBROWSERLIB_EXECUTOR_HXX |
|
|
|
#include <qbrowserlib/log.hxx> |
|
#include <qbrowserlib/settings.hxx> |
|
#include <qbrowserlib/temporaryfile.hxx> |
|
|
|
#include <QtCore/QDir> |
|
#include <QtCore/QProcess> |
|
#include <QtNetwork/QNetworkReply> |
|
|
|
namespace qbrowserlib { |
|
|
|
//! Execute external processes |
|
/*! Implements a singleton pattern */ |
|
class Executor: public QObject { |
|
|
|
Q_OBJECT; |
|
|
|
Q_SIGNALS: |
|
|
|
void applicationStarted(); |
|
void applicationFinished(); |
|
|
|
private: |
|
|
|
Executor() {} // singleton |
|
Executor(const Executor&); // singleton |
|
|
|
public: |
|
|
|
static Executor& instance() { |
|
static Executor _instance; |
|
return _instance; |
|
} |
|
|
|
~Executor() { |
|
TRC; |
|
for (DownloadProcesses::iterator it(_downloadProcesses.begin()); |
|
it!=_downloadProcesses.end(); ++it) { |
|
LOG<<"cleanup:"<<it->second->fileName(); |
|
it->second->setAutoRemove(qbrowserlib::Settings::instance() |
|
.flag("CloseApps")); |
|
delete it->second; |
|
it->second = 0; |
|
if (qbrowserlib::Settings::instance().flag("CloseApps")) { |
|
LOG<<"terminate process"; |
|
it->first->terminate(); |
|
delete it->first; |
|
} |
|
} |
|
} |
|
|
|
public Q_SLOTS: |
|
|
|
void run(QNetworkReply* reply, QString filename, QString command) { |
|
TRC; LOG<<filename<<command; |
|
_reply = reply; |
|
_filename = filename; |
|
_command = command; |
|
if (_reply->isFinished()) { |
|
LOG<<"run immediate"; |
|
downloadFinished(); |
|
} else { |
|
LOG<<"run later"; |
|
assert(connect(reply, SIGNAL(finished()), SLOT(downloadFinished()))); |
|
} |
|
} |
|
|
|
private Q_SLOTS: |
|
|
|
void downloadFinished() { |
|
TRC; |
|
TemporaryFile *file(new TemporaryFile |
|
(QDir::tempPath()+QDir::separator() |
|
+QFileInfo(_filename).fileName())); |
|
file->open(); |
|
_reply->seek(0); |
|
file->write(_reply->readAll()); |
|
file->close(); |
|
LOG<<"Stored as:"<<file->fileName(); |
|
QProcess* process(new QProcess); |
|
_downloadProcesses[process] = file; |
|
assert(connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), |
|
SLOT(processFinished()))); |
|
QStringList args(_command.split(" ") |
|
.replaceInStrings("%1", file->fileName())); |
|
QString prg(args.takeFirst()); |
|
LOG<<"Running:"<<prg<<args.join(" "); |
|
process->start(prg, args); |
|
applicationStarted(); |
|
} |
|
|
|
void processFinished() { |
|
TRC; |
|
if (_downloadProcesses.find(qobject_cast<QProcess*>(sender())) |
|
== _downloadProcesses.end()) return; |
|
if (_downloadProcesses[qobject_cast<QProcess*>(sender())]) |
|
_downloadProcesses[qobject_cast<QProcess*>(sender())] |
|
->setAutoRemove(qbrowserlib::Settings::instance() |
|
.flag("CloseApps")); |
|
delete _downloadProcesses[qobject_cast<QProcess*>(sender())]; |
|
_downloadProcesses.erase(qobject_cast<QProcess*>(sender())); |
|
applicationFinished(); |
|
} |
|
|
|
private: |
|
|
|
typedef std::map<QProcess*, TemporaryFile*> DownloadProcesses; |
|
DownloadProcesses _downloadProcesses; |
|
QNetworkReply* _reply; |
|
QString _filename; |
|
QString _command; |
|
}; |
|
|
|
} |
|
|
|
#endif
|
|
|