From: Peter Kümmel Date: Sun, 20 Dec 2009 14:26:55 +0000 (+0000) Subject: add progress widget X-Git-Tag: 2.0.0~4753 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=aa613aaf010f1dd991222dbf1e83d51aa9f4b8a7;p=features.git add progress widget git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@32598 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc index 693ee1f23d..c391338aa5 100644 --- a/lib/ui/stdmenus.inc +++ b/lib/ui/stdmenus.inc @@ -315,10 +315,11 @@ Menuset OptItem "View Master Document|M" "master-buffer-view" OptItem "Update Master Document|a" "master-buffer-update" Separator + Item "Show process messages" "dialog-toggle progress" Item "Split View Into Left and Right Half|i" "split-view horizontal" Item "Split View Into Upper and Lower Half|e" "split-view vertical" Item "Close Current View|w" "close-tab-group" - Item "Fullscreen|l" "ui-toggle fullscreen" + Item "Fullscreen|l" "ui-toggle fullscreen" Submenu "Toolbars|b" "toolbars" Separator Documents diff --git a/src/frontends/qt4/GuiProgress.cpp b/src/frontends/qt4/GuiProgress.cpp new file mode 100644 index 0000000000..b421616ab4 --- /dev/null +++ b/src/frontends/qt4/GuiProgress.cpp @@ -0,0 +1,111 @@ +// -*- C++ -*- +/** + * \file GuiProgress.cpp + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Peter Kümmel + * + * Full author contact details are available in file CREDITS. + */ + +#include + +#include "GuiProgress.h" + +#include "qt_helpers.h" + +#include "support/Systemcall.h" + +#include +#include + + +namespace lyx { +namespace frontend { + + + +GuiProgress::GuiProgress(GuiView & parent, Qt::DockWidgetArea area, + Qt::WindowFlags flags) : DockView(parent, "progress", "External tools", area, flags) +{ + setWindowTitle(qt_("Tool monitoring")); + setWidget(&text_edit); + text_edit.setReadOnly(true); + + connect(this, SIGNAL(processStarted(QString const &)), SLOT(doProcessStarted(QString const &))); + connect(this, SIGNAL(processFinished(QString const &)), SLOT(doProcessFinished(QString const &))); + connect(this, SIGNAL(appendMessage(QString const &)), SLOT(doAppendMessage(QString const &))); + connect(this, SIGNAL(appendError(QString const &)), SLOT(doAppendError(QString const &))); + connect(this, SIGNAL(clearMessages()), SLOT(doClearMessages())); +} + + +void GuiProgress::doProcessStarted(QString const & cmd) +{ + appendText("Process started : " + cmd + "\n"); +} + + +void GuiProgress::doProcessFinished(QString const & cmd) +{ + appendText("Process finished: " + cmd + "\n"); +} + + +void GuiProgress::doAppendMessage(QString const & msg) +{ + // No good messages from the processes + //appendText(msg); +} + + +void GuiProgress::doAppendError(QString const & msg) +{ + appendText(msg); +} + + +void GuiProgress::doClearMessages() +{ + text_edit.clear(); +} + + +void GuiProgress::appendText(QString const & text) +{ + text_edit.insertPlainText(text); + text_edit.ensureCursorVisible(); +} + + +void GuiProgress::showEvent(QShowEvent*) +{ + support::ProgressInterface::setInstance(this); +} + + +void GuiProgress::hideEvent(QHideEvent*) +{ + support::ProgressInterface::setInstance(0); +} + + + +Dialog * createGuiProgress(GuiView & lv) +{ + GuiView & guiview = static_cast(lv); +#ifdef Q_WS_MACX + // TODO where to show up on the Mac? + //return new GuiProgress(guiview, Qt::RightDockWidgetArea, Qt::Drawer); +#else + return new GuiProgress(guiview, Qt::BottomDockWidgetArea); +#endif +} + + + +} // namespace frontend +} // namespace lyx + +#include "moc_GuiProgress.cpp" \ No newline at end of file diff --git a/src/frontends/qt4/GuiProgress.h b/src/frontends/qt4/GuiProgress.h new file mode 100644 index 0000000000..79891548c1 --- /dev/null +++ b/src/frontends/qt4/GuiProgress.h @@ -0,0 +1,85 @@ +// -*- C++ -*- +/** + * \file GuiProgress.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Peter Kümmel + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef GUIPROGRESS_H +#define GUIPROGRESS_H + +#include "support/ProgressInterface.h" + +#include "DockView.h" + +#include +#include +#include + +#include + + +namespace lyx { +namespace frontend { + + +class GuiProgress : + public DockView, + public lyx::support::ProgressInterface +{ + + Q_OBJECT +public: + GuiProgress( + GuiView & parent, ///< the main window where to dock. + Qt::DockWidgetArea area, ///< Position of the dock (and also drawer) + Qt::WindowFlags flags = 0); + +Q_SIGNALS: + void processStarted(QString const &); + void processFinished(QString const &); + void appendMessage(QString const &); + void appendError(QString const &); + void clearMessages(); + +private Q_SLOTS: + void doProcessStarted(QString const &); + void doProcessFinished(QString const &); + void doAppendMessage(QString const &); + void doAppendError(QString const &); + void doClearMessages(); + +public: + /// Controller inherited method. + ///@{ + bool initialiseParams(std::string const &) { return true; } + void clearParams() {} + void dispatchParams() {} + bool isBufferDependent() const { return false; } + bool canApply() const { return true; } + bool canApplyToReadOnly() const { return true; } + void updateView() {} + ///@} + + + void showEvent(QShowEvent*); + void hideEvent(QHideEvent*); + +private: + QTextEdit text_edit; + + void appendText(QString const &); + +}; + + + +} // namespace frontend +} // namespace lyx + +#endif + diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 60926cf7dd..02801b7224 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -76,6 +76,7 @@ #include "support/Path.h" #include "support/Systemcall.h" #include "support/Timeout.h" +#include "support/ProgressInterface.h" #include #include @@ -1416,6 +1417,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) || name == "file" //FIXME: should be removed. || name == "prefs" || name == "texinfo" + || name == "progress" || name == "compare"; else if (name == "print") enable = doc_buffer->isExportable("dvi") @@ -3170,7 +3172,7 @@ char const * const dialognames[] = { "mathmatrix", "mathspace", "nomenclature", "nomencl_print", "note", "paragraph", "phantom", "prefs", "print", "ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate", "thesaurus", "texinfo", -"toc", "view-source", "vspace", "wrap" }; +"toc", "view-source", "vspace", "wrap", "progress" }; char const * const * const end_dialognames = dialognames + (sizeof(dialognames) / sizeof(char *)); @@ -3368,7 +3370,7 @@ Dialog * createGuiHyperlink(GuiView & lv); Dialog * createGuiVSpace(GuiView & lv); Dialog * createGuiViewSource(GuiView & lv); Dialog * createGuiWrap(GuiView & lv); - +Dialog * createGuiProgress(GuiView & lv); Dialog * GuiView::build(string const & name) { @@ -3472,6 +3474,8 @@ Dialog * GuiView::build(string const & name) return createGuiVSpace(*this); if (name == "wrap") return createGuiWrap(*this); + if (name == "progress") + return createGuiProgress(*this); return 0; } diff --git a/src/support/ProgressInterface.h b/src/support/ProgressInterface.h new file mode 100644 index 0000000000..4199fd82ae --- /dev/null +++ b/src/support/ProgressInterface.h @@ -0,0 +1,47 @@ +// -*- C++ -*- +/** + * \file ProgressInterface.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Peter Kümmel + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef LYX_SUPPORT_PROGRESSINTERFACE_H +#define LYX_SUPPORT_PROGRESSINTERFACE_H + +#include + +class QString; + +namespace lyx { +namespace support { + + +class ProgressInterface +{ +public: + virtual ~ProgressInterface() {} + + virtual void processStarted(QString const &) = 0; + virtual void processFinished(QString const &) = 0; + virtual void appendMessage(QString const &) = 0; + virtual void appendError(QString const &) = 0; + virtual void clearMessages() = 0; + + static void setInstance(ProgressInterface*); + static ProgressInterface* instance(); + +protected: + ProgressInterface() {} +}; + + + +} // namespace support +} // namespace lyx + +#endif // LYX_SUPPORT_PROGRESSINTERFACE_H + diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp index f5bd7254f0..ed1e857b07 100644 --- a/src/support/Systemcall.cpp +++ b/src/support/Systemcall.cpp @@ -19,6 +19,7 @@ #include "support/Systemcall.h" #include "support/SystemcallPrivate.h" #include "support/os.h" +#include "support/ProgressInterface.h" #include @@ -43,12 +44,45 @@ struct Sleep : QThread + using namespace std; namespace lyx { namespace support { +class ProgressDummy : public ProgressInterface +{ +public: + ProgressDummy() {} + + void processStarted(QString const &) {} + void processFinished(QString const &) {} + void appendMessage(QString const &) {} + void appendError(QString const &) {} + void clearMessages() {} +}; + + +static ProgressInterface* progress_instance = 0; + +void ProgressInterface::setInstance(ProgressInterface* p) +{ + progress_instance = p; +} + + +ProgressInterface* ProgressInterface::instance() +{ + if (!progress_instance) { + static ProgressDummy dummy; + return &dummy; + } + return progress_instance; +} + + + // Reuse of instance #ifndef USE_QPROCESS @@ -207,9 +241,9 @@ SystemcallPrivate::SystemcallPrivate(const std::string& of) : if (outfile != os::nulldev()) proc_->setStandardOutputFile(toqstr(outfile)); } else if (os::is_terminal(os::STDOUT)) - showout(); + setShowOut(true); if (os::is_terminal(os::STDERR)) - showerr(); + setShowErr(true); connect(proc_, SIGNAL(readyReadStandardOutput()), SLOT(stdOut())); connect(proc_, SIGNAL(readyReadStandardError()), SLOT(stdErr())); @@ -222,18 +256,19 @@ SystemcallPrivate::SystemcallPrivate(const std::string& of) : void SystemcallPrivate::startProcess(const QString& cmd) { + cmd_ = cmd; if (proc_) { state = SystemcallPrivate::Starting; - proc_->start(cmd); + proc_->start(cmd_); } } void SystemcallPrivate::processEvents() { - if(process_events) { - QCoreApplication::processEvents(QEventLoop::AllEvents); - } + //if(process_events) { + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + //} } @@ -286,13 +321,15 @@ SystemcallPrivate::~SystemcallPrivate() if (outindex_) { outdata_[outindex_] = '\0'; outindex_ = 0; - cout << outdata_; + if (showout_) + cout << outdata_; } cout.flush(); if (errindex_) { errdata_[errindex_] = '\0'; errindex_ = 0; - cerr << errdata_; + if (showerr_) + cerr << errdata_; } cerr.flush(); @@ -318,7 +355,7 @@ void SystemcallPrivate::flush() void SystemcallPrivate::stdOut() { - if (proc_ && showout_) { + if (proc_) { char c; proc_->setReadChannel(QProcess::StandardOutput); while (proc_->getChar(&c)) { @@ -326,17 +363,21 @@ void SystemcallPrivate::stdOut() if (c == '\n' || outindex_ + 1 == bufsize_) { outdata_[outindex_] = '\0'; outindex_ = 0; - cout << outdata_; + if (showout_) + cout << outdata_; } } } + const QString data = QString::fromLocal8Bit(outdata_); + if (!data.isEmpty()) + ProgressInterface::instance()->appendMessage(data); processEvents(); } void SystemcallPrivate::stdErr() { - if (proc_ && showerr_) { + if (proc_) { char c; proc_->setReadChannel(QProcess::StandardError); while (proc_->getChar(&c)) { @@ -344,10 +385,14 @@ void SystemcallPrivate::stdErr() if (c == '\n' || errindex_ + 1 == bufsize_) { errdata_[errindex_] = '\0'; errindex_ = 0; - cerr << errdata_; + if (showerr_) + cerr << errdata_; } } } + const QString data = QString::fromLocal8Bit(errdata_); + if (!data.isEmpty()) + ProgressInterface::instance()->appendError(data); processEvents(); } @@ -355,20 +400,21 @@ void SystemcallPrivate::stdErr() void SystemcallPrivate::processStarted() { state = Running; - // why do we get two started signals? - //disconnect(proc_, SIGNAL(started()), this, SLOT(processStarted())); + ProgressInterface::instance()->processStarted(cmd_); } void SystemcallPrivate::processFinished(int, QProcess::ExitStatus) { state = Finished; + ProgressInterface::instance()->processFinished(cmd_); } void SystemcallPrivate::processError(QProcess::ProcessError) { state = Error; + ProgressInterface::instance()->appendError(errorMessage()); } diff --git a/src/support/SystemcallPrivate.h b/src/support/SystemcallPrivate.h index 4151940278..4fee2c698b 100644 --- a/src/support/SystemcallPrivate.h +++ b/src/support/SystemcallPrivate.h @@ -34,10 +34,10 @@ public: ~SystemcallPrivate(); /// Should the standard output be displayed? - void showout() { showout_ = true; } + void setShowOut(bool val) { showout_ = val; } /// Should the standard error be displayed? - void showerr() { showerr_ = true; } + void setShowErr(bool val) { showerr_ = val; } enum State { Starting, @@ -81,6 +81,7 @@ private: /// bool showerr_; bool process_events; + QString cmd_; void waitAndProcessEvents(); void processEvents(); @@ -94,6 +95,8 @@ public Q_SLOTS: void processStarted(); void processFinished(int, QProcess::ExitStatus status); +Q_SIGNALS: + }; } // namespace support