]> git.lyx.org Git - features.git/commitdiff
add progress view of system calls
authorPeter Kümmel <syntheticpp@gmx.net>
Sat, 8 Dec 2007 20:46:03 +0000 (20:46 +0000)
committerPeter Kümmel <syntheticpp@gmx.net>
Sat, 8 Dec 2007 20:46:03 +0000 (20:46 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22026 a592a061-630c-0410-9148-cb99ea01b6c8

14 files changed:
development/scons/scons_manifest.py
lib/ui/stdmenus.inc
src/Buffer.cpp
src/LaTeX.cpp
src/frontends/qt4/GuiProgress.cpp [new file with mode: 0644]
src/frontends/qt4/GuiProgress.h [new file with mode: 0644]
src/frontends/qt4/GuiView.cpp
src/frontends/qt4/Makefile.am
src/support/Makefile.am
src/support/ProgressInterface.h [new file with mode: 0644]
src/support/Systemcall.cpp
src/support/Systemcall.h
src/support/SystemcallPrivate.cpp [new file with mode: 0644]
src/support/SystemcallPrivate.h [new file with mode: 0644]

index 54a70a8ee2fc638ec5ab723bac4fc7cb8ecb0c38..351a9228d913249a6735a0a0b71aabe6f2e068ca 100644 (file)
@@ -297,7 +297,9 @@ src_support_header_files = Split('''
     RandomAccessList.h
     SignalSlot.h
     SignalSlotPrivate.h
+    ProgressInterface.h
     Systemcall.h
+    SystemcallPrivate.h
     Timeout.h
     Translator.h
     convert.h
@@ -338,6 +340,7 @@ src_support_files = Split('''
     Path.cpp
     SignalSlot.cpp
     Systemcall.cpp
+    SystemcallPrivate.cpp
     Timeout.cpp
     abort.cpp
     convert.cpp
@@ -755,6 +758,7 @@ src_frontends_qt4_header_files = Split('''
     GuiPopupMenu.h
     GuiPrefs.h
     GuiPrint.h
+    GuiProgress.h
     GuiRef.h
     GuiSearch.h
     GuiSelection.h
@@ -841,6 +845,7 @@ src_frontends_qt4_files = Split('''
     GuiParagraph.cpp
     GuiPopupMenu.cpp
     GuiPrefs.cpp
+    GuiProgress.cpp
     GuiPrint.cpp
     GuiRef.cpp
     GuiSearch.cpp
index d108e827de2124ab14d7afa011760d5d5de8acfd..c7ba324bcb45cbaf9bc6f9782ea900210e272e81 100644 (file)
@@ -286,6 +286,7 @@ Menuset
                Item "Fold Math Macro" "math-macro-fold"
                Separator
                Item "View Source|S" "dialog-toggle view-source"
+               Item "View LaTeX Progress|" "dialog-toggle latex-progress"
                Submenu "Update|U" "view_update"
                ViewFormats
                Separator
index bf0a5dced83357661745881c05e37d530e053a6f..ec79c061f06ae7ac79f2da6864bc203c68903e77 100644 (file)
@@ -1097,8 +1097,7 @@ void Buffer::writeLaTeXSource(odocstream & os,
        if (output_preamble) {
                if (!runparams.nice) {
                        // code for usual, NOT nice-latex-file
-                       os << "\\batchmode\n"; // changed
-                       // from \nonstopmode
+                       os << "\\nonstopmode\n"; 
                        d->texrow.newline();
                }
                if (!original_path.empty()) {
index 1934894058999d5f626bc595bd2cfc1f8a7cfe1d..2fe59820551d156e252623dcf8911036e07d351e 100644 (file)
@@ -415,11 +415,9 @@ int LaTeX::run(TeXErrors & terr)
 int LaTeX::startscript()
 {
        // onlyFilename() is needed for cygwin
-       string tmp = cmd + ' '
-                    + quoteName(onlyFilename(file.toFilesystemEncoding()))
-                    + " > " + os::nulldev();
-       Systemcall one;
-       return one.startscript(Systemcall::Wait, tmp);
+       string tmp = cmd + ' ' + "-max-print-line=200 "
+                               + quoteName(onlyFilename(file.toFilesystemEncoding()));
+       return Systemcall().startscript(Systemcall::Wait, tmp);
 }
 
 
diff --git a/src/frontends/qt4/GuiProgress.cpp b/src/frontends/qt4/GuiProgress.cpp
new file mode 100644 (file)
index 0000000..694a45e
--- /dev/null
@@ -0,0 +1,64 @@
+// -*- 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 <config.h>
+
+#include "GuiProgress.h"
+
+#include "support/Systemcall.h"
+
+#include <QApplication>
+
+
+namespace lyx {
+namespace frontend {
+
+
+GuiProgress::GuiProgress(GuiView & parent, Qt::DockWidgetArea area, 
+       Qt::WindowFlags flags) : DockView(parent, "latex-progress", area, flags)
+{
+       setWindowTitle(qt_("LaTeX Progress"));
+       setWidget(&text_edit);
+       lyx::support::Systemcall::registerProgressInterface(this);
+}
+
+
+void GuiProgress::appendMessage(QString const & msg)
+{
+       text_edit.append(msg);
+       // QEventLoop::ExcludeUserInputEvents: 
+       // don't allow user inputs while processing a document
+       // if we allow it, we open will Pandora's Box of multithreading
+       QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+}
+
+
+void GuiProgress::clearMessages()
+{
+       text_edit.clear();
+}
+
+
+Dialog * createGuiProgress(GuiView & lv)
+{
+       GuiView & guiview = static_cast<GuiView &>(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
+
+
diff --git a/src/frontends/qt4/GuiProgress.h b/src/frontends/qt4/GuiProgress.h
new file mode 100644 (file)
index 0000000..5658558
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- 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 <QTextEdit>
+
+#include <string>
+
+
+namespace lyx {
+namespace frontend {
+
+
+class GuiProgress : 
+       public DockView, 
+       public lyx::support::ProgressInterface
+{
+
+public:
+       GuiProgress(
+               GuiView & parent, ///< the main window where to dock.
+               Qt::DockWidgetArea area, ///< Position of the dock (and also drawer)
+               Qt::WindowFlags flags = 0);
+
+       void appendMessage(QString const &);
+       void clearMessages();
+
+       /// Controller inherited method.
+       ///@{
+       bool initialiseParams(std::string const & source) { return true; }
+       void clearParams() {}
+       void dispatchParams() {}
+       bool isBufferDependent() const { return true; }
+       bool canApply() const { return true; }
+       bool canApplyToReadOnly() const { return true; }
+       void updateView() {}
+       ///@}
+
+private:
+       QTextEdit text_edit;
+};
+
+
+} // namespace frontend
+} // namespace lyx
+
+#endif
+
index 6f3d42ca8e7dd37bd8b1b7b3c3992bc2b6bcc870..42e5e1ea67854832047c6f9ee9726ced2cf324d3 100644 (file)
@@ -23,6 +23,7 @@
 #include "GuiMenubar.h"
 #include "GuiToolbar.h"
 #include "GuiToolbars.h"
+#include "GuiProgress.h"
 
 #include "qt_helpers.h"
 
@@ -1569,7 +1570,7 @@ char const * const dialognames[] = {
 "thesaurus",
 #endif
 
-"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" };
+"texinfo", "toc", "href", "view-source", "latex-progress", "vspace", "wrap", "listings" };
 
 char const * const * const end_dialognames =
        dialognames + (sizeof(dialognames) / sizeof(char *));
@@ -1793,6 +1794,7 @@ Dialog * createGuiThesaurus(GuiView & lv);
 Dialog * createGuiHyperlink(GuiView & lv);
 Dialog * createGuiVSpace(GuiView & lv);
 Dialog * createGuiViewSource(GuiView & lv);
+Dialog * createGuiProgress(GuiView & lv);
 Dialog * createGuiWrap(GuiView & lv);
 
 
@@ -1844,6 +1846,8 @@ Dialog * GuiView::build(string const & name)
                return createGuiLog(*this);
        if (name == "view-source")
                return createGuiViewSource(*this);
+       if (name == "latex-progress")
+               return createGuiProgress(*this);
        if (name == "mathdelimiter")
                return createGuiDelimiter(*this);
        if (name == "mathmatrix")
index 8b8650a6a12e966c0de91d2e5221d80bcd627a6c..8fc0edf27109bf0e94395489637d838caf053584 100644 (file)
@@ -101,6 +101,7 @@ SOURCEFILES = \
        GuiPopupMenu.cpp \
        GuiPrefs.cpp \
        GuiPrint.cpp \
+       GuiProgress.cpp \
        GuiRef.cpp \
        GuiSearch.cpp \
        GuiSelection.cpp \
@@ -187,6 +188,7 @@ MOCHEADER = \
        GuiPopupMenu.h \
        GuiPrefs.h \
        GuiPrint.h \
+       GuiProgress.h \
        GuiRef.h \
        GuiSearch.h \
        GuiSelection.h \
index 3e69f53f008bb50ac22ab11e069a158c6dabf52f..a2697a4b138ba49e9c123e34d615edce40be6013 100644 (file)
@@ -75,6 +75,9 @@ liblyxsupport_la_SOURCES = \
        strfwd.h \
        Systemcall.cpp \
        Systemcall.h \
+       SystemcallPrivate.cpp \
+       SystemcallPrivate.h \
+       ProgressInterface.h \
        SignalSlot.cpp \
        SignalSlot.h \
        SignalSlotPrivate.h \
diff --git a/src/support/ProgressInterface.h b/src/support/ProgressInterface.h
new file mode 100644 (file)
index 0000000..1bc980e
--- /dev/null
@@ -0,0 +1,38 @@
+// -*- 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
+
+class QString;
+
+namespace lyx {
+namespace support {
+
+
+class ProgressInterface
+{
+public:
+       virtual ~ProgressInterface() {}
+
+       virtual void appendMessage(QString const &) = 0;
+       virtual void clearMessages() = 0;
+
+protected:
+       ProgressInterface() {}
+};
+
+
+} // namespace support
+} // namespace lyx
+
+#endif // LYX_SUPPORT_PROGRESSINTERFACE_H
+
index e8fbd6404e4206d91cb1e8600622184d27099e43..bf7192dd428f2e6742e7e03eb18b02ec7f71b10b 100644 (file)
@@ -4,6 +4,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Asger Alstrup
+ * \author Peter Kümmel
  *
  * Interface cleaned up by
  * \author Angus Leeming
 #include <config.h>
 
 #include "support/Systemcall.h"
-#include "support/os.h"
+#include "support/SystemcallPrivate.h"
+#include "support/ProgressInterface.h"
 
-#include <cstdlib>
+namespace lyx {
+namespace support {
 
-using std::string;
+static ProgressInterface* progress_impl = 0;
 
-#ifndef CXX_GLOBAL_CSTD
-using std::system;
-#endif
 
-namespace lyx {
-namespace support {
+void Systemcall::registerProgressInterface(ProgressInterface* p)
+{
+       progress_impl = p;
+}
 
-// Reuse of instance
-int Systemcall::startscript(Starttype how, string const & what)
+
+ProgressInterface* Systemcall::progress()
+{
+       return progress_impl;
+}
+
+
+int Systemcall::startscript(Starttype how, std::string const & what)
 {
-       string command = what;
-
-       if (how == DontWait) {
-               switch (os::shell()) {
-               case os::UNIX:
-                       command += " &";
-                       break;
-               case os::CMD_EXE:
-                       command = "start /min " + command;
-                       break;
-               }
-       }
-
-       return ::system(command.c_str());
+       // TODO Reuse of instance?
+       SystemcallPrivate* process = new SystemcallPrivate;
+       if (how == Wait)
+               return process->start(what, true);
+       return process->start(what, false);
 }
 
+
 } // namespace support
 } // namespace lyx
index 61ba092a2dde0a3c93296de11a6650569faea15c..8ed0277c0d922e407f249c9c52c6ffe73c1d88bf 100644 (file)
@@ -5,6 +5,7 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Asger Alstrup
+ * \author Peter Kümmel
  *
  * Interface cleaned up by
  * \author Angus Leeming
 namespace lyx {
 namespace support {
 
+class ProgressInterface;
+
 /**
  * An instance of Class Systemcall represents a single child process.
  *
- * Class Systemcall uses system() to launch the child process.
+ * Class Systemcall uses SystemcallPrivate to launch the child process.
  * The user can choose to wait or not wait for the process to complete, but no
  * callback is invoked upon completion of the child.
  *
@@ -43,6 +46,9 @@ public:
         *  by spaces.
         */
        int startscript(Starttype how, std::string const & what);
+
+       static void registerProgressInterface(ProgressInterface*);
+       static ProgressInterface* progress();
 };
 
 } // namespace support
diff --git a/src/support/SystemcallPrivate.cpp b/src/support/SystemcallPrivate.cpp
new file mode 100644 (file)
index 0000000..bebe91b
--- /dev/null
@@ -0,0 +1,115 @@
+// -*- C++ -*-
+/**
+ * \file SystemcallPrivate.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 <config.h>
+
+#include "SystemcallPrivate.h"
+
+#include "Systemcall.h"
+#include "ProgressInterface.h"
+
+#include "gettext.h"
+#include "qstring_helpers.h"
+
+
+namespace lyx {
+namespace support {
+
+
+// TODO should we move qt_ to qstring_helpers?
+static
+QString const qt_(char const * str)
+{
+       return toqstr(_(str));
+}
+
+
+
+SystemcallPrivate::SystemcallPrivate() 
+{ 
+       ProgressInterface* progress = Systemcall::progress();
+       if (progress) {
+               connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(newProcessOutput()));
+               connect(&process, SIGNAL(started()), this, SLOT(processStarted()));
+               connect(&process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
+               connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), 
+                               this, SLOT(processFinished(int, QProcess::ExitStatus)));                                
+       }
+}
+
+
+int SystemcallPrivate::start(const std::string& cmd, bool waitForFinished)
+{
+       ProgressInterface* progress = Systemcall::progress();
+       if (progress) {
+               progress->clearMessages();
+               progress->appendMessage(qt_("Starting LaTex with command "));
+               progress->appendMessage(cmd.c_str());
+       }
+
+       process.setReadChannel(QProcess::StandardOutput);
+       process.start(cmd.c_str(), QStringList(), QIODevice::ReadOnly);
+       // wait some seconds until the process has started
+       process.waitForStarted(10 * 1000);
+       if (waitForFinished) {
+               // with waitForFinished(-1); we only get one signal per run
+               while (process.state() == QProcess::Running)
+                       process.waitForFinished(500);
+               return process.exitCode();
+       }
+       if (process.state() != QProcess::Running) {
+               process.kill();
+               // TODO this needs more testing
+               deleteLater();
+               return -1;
+       }
+       return 0;
+}
+
+
+void SystemcallPrivate::newProcessOutput()
+{
+       ProgressInterface* progress = Systemcall::progress();
+       if (progress) {
+               const QString output = QString::fromLocal8Bit(process.readAllStandardOutput());
+               progress->appendMessage(output);
+       }
+}
+
+
+void SystemcallPrivate::processStarted()
+{
+       ProgressInterface* progress = Systemcall::progress();
+       if (progress) {
+               progress->appendMessage(qt_("LaTex started\n"));
+       }
+}
+
+
+void SystemcallPrivate::processError(QProcess::ProcessError)
+{
+       ProgressInterface* progress = Systemcall::progress();
+       if (progress) {
+               progress->appendMessage(qt_("LaTex error\n"));
+       }
+}
+
+
+void SystemcallPrivate::processFinished(int, QProcess::ExitStatus)
+{
+       deleteLater();
+}
+
+
+} // namespace support
+} // namespace lyx
+
+#include "SystemcallPrivate_moc.cpp"
diff --git a/src/support/SystemcallPrivate.h b/src/support/SystemcallPrivate.h
new file mode 100644 (file)
index 0000000..38d42e2
--- /dev/null
@@ -0,0 +1,51 @@
+// -*- C++ -*-
+/**
+ * \file SystemcallPrivate.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_SYSTEMCALLPRIVATE_H
+#define LYX_SUPPORT_SYSTEMCALLPRIVATE_H
+
+#include <QObject>
+#include <QProcess>
+
+#include <string>
+
+
+namespace lyx {
+namespace support {
+
+class ProgressInterface;
+
+class SystemcallPrivate : public QObject
+{
+       Q_OBJECT
+
+public:
+       SystemcallPrivate();
+
+       // When waitForFinished == true :   returns the exit code of the process
+       // When waitForFinished == false:   returns 0 if the process could be started
+       int start(const std::string& cmd, bool waitForFinished);
+
+public Q_SLOTS:
+       void newProcessOutput();
+       void processStarted();
+       void processError(QProcess::ProcessError);
+       void processFinished(int, QProcess::ExitStatus);
+       
+private:
+       QProcess process;
+};
+
+
+} // namespace support
+} // namespace lyx
+
+#endif // LYX_SUPPORT_SYSTEMCALLPRIVATE_H