1. zjes
  2. pynoto

Commits

zjes  committed 52f03ae

Add simple application output console

  • Participants
  • Parent commits 94e1c76
  • Branches master

Comments (0)

Files changed (24)

File src/Main/CMakeLists.txt

View file
  • Ignore whitespace
 
     Consoles/ApplicationConsole.h
     Consoles/ApplicationOutput.h
+    Consoles/IApplicationOutput.h
     Consoles/ApplicationConsoleHeader.h
 
     Consoles/LogConsole.h
     Consoles/ApplicationConsole.cpp
     Consoles/ApplicationOutput.cpp
     Consoles/ApplicationConsoleHeader.cpp
+    Consoles/IApplicationOutput.cpp
 
     Consoles/LogConsole.cpp
     Consoles/LogOutput.cpp

File src/Main/ConsoleWidget.cpp

View file
  • Ignore whitespace
 #include "Include/IIconProvider.h"
 #include "ConsoleWidget.h"
 #include "ui_ConsoleWidget.h"
+#include "Consoles/IApplicationOutput.h"
 
 namespace Main {
 
     delete _ui;
 }
 
-IssuesConsole * ConsoleWidget::issues()
+IssuesConsole * ConsoleWidget::issues() const
 {
     return _issues;
 }
 
+IApplicationOutput * ConsoleWidget::application() const
+{
+    return _application;
+}
+
 void ConsoleWidget::setup(EditorsManager::IEditorsManagerPlugin* editors, QButtonGroup * btns)
 {
     _buttonGroup = btns;

File src/Main/ConsoleWidget.h

View file
  • Ignore whitespace
 
 class IssuesConsole;
 class ApplicationConsole;
+class IApplicationOutput;
 class LogConsole;
 
 class ConsoleWidget : public QWidget
     explicit ConsoleWidget(QWidget *parent = 0);
     virtual ~ConsoleWidget();
 
-    IssuesConsole * issues();
+    IssuesConsole * issues() const;
+    IApplicationOutput * application() const;
+
     void setup(EditorsManager::IEditorsManagerPlugin* editors, QButtonGroup * btns);
 public slots:
     void errorListChanged(QAbstractTableModel*);

File src/Main/Consoles/ApplicationConsole.cpp

View file
  • Ignore whitespace
 namespace Main {
 
 ApplicationConsole::ApplicationConsole(QWidget *parent) :
-    QWidget(parent),
+    IApplicationOutput(parent),
     _output(new ApplicationOutput(this)),
     _header(new ApplicationConsoleHeader(this))
 {
+    connect(_header, SIGNAL(run()), SIGNAL(run()));
+    connect(_header, SIGNAL(stop()), SIGNAL(stop()));
+    projectStoped();
 }
 
-
 QWidget * ApplicationConsole::header()
 {
     return _header;
     return _output;
 }
 
+void ApplicationConsole::projectRunned()
+{
+    _header->projectRunned(true);
+}
+
+void ApplicationConsole::projectStoped()
+{
+    _header->projectRunned(false);
+}
+
+void ApplicationConsole::addOutput(const QString& msg)
+{
+    _output->addOutput(msg);
 }
+
+void ApplicationConsole::addError(const QString& msg)
+{
+    _output->addError(msg);
+}
+
+
+}
+

File src/Main/Consoles/ApplicationConsole.h

View file
  • Ignore whitespace
 #define _APPLICATIONCONSOLE_H_
 
 #include <QWidget>
+#include "IApplicationOutput.h"
 
 
 namespace Main {
 class ApplicationOutput;
 class ApplicationConsoleHeader;
 
-class ApplicationConsole : public QWidget
+
+class ApplicationConsole : public IApplicationOutput
 {
     Q_OBJECT
 public:
     explicit ApplicationConsole(QWidget *parent = 0);
     QWidget * header();
     QWidget * control();
+public slots:
+    virtual void projectRunned();
+    virtual void projectStoped();
+
+    virtual void addOutput(const QString& msg);
+    virtual void addError(const QString& msg);
 private:
     ApplicationOutput * _output;
     ApplicationConsoleHeader * _header;

File src/Main/Consoles/ApplicationConsoleHeader.cpp

View file
  • Ignore whitespace
     _ui->setupUi(this);
     _ui->stopBtn->setIcon(Aux::icons()->icon("stop"));
     _ui->runBtn->setIcon(Aux::icons()->icon("run"));
-    //_ui->refreshBtn->setIcon(Aux::icons()->icon("reset"));
-    //connect(_ui->refreshBtn, SIGNAL(clicked()), SIGNAL(refresh()));
+
+    connect(_ui->runBtn, SIGNAL(clicked()), SIGNAL(run()));
+    connect(_ui->stopBtn, SIGNAL(clicked()), SIGNAL(stop()));
 }
 
 ApplicationConsoleHeader::~ApplicationConsoleHeader()
     delete _ui;
 }
 
+void ApplicationConsoleHeader::projectRunned(bool runned)
+{
+    _ui->runBtn->setEnabled(!runned);
+    _ui->stopBtn->setEnabled(runned);
+}
+
 }

File src/Main/Consoles/ApplicationConsoleHeader.h

View file
  • Ignore whitespace
 public:
     ApplicationConsoleHeader(QWidget * parent = 0);
     virtual ~ApplicationConsoleHeader();
+    void projectRunned(bool runned);
+signals:
+    void run();
+    void stop();
 private:
     Ui::ApplicationConsoleHeader *_ui;
 };

File src/Main/Consoles/ApplicationOutput.cpp

View file
  • Ignore whitespace
 #include <QDebug>
+#include <QScrollBar>
 #include "ApplicationOutput.h"
+#include "IApplicationOutput.h"
 
 namespace Main {
 
 ApplicationOutput::ApplicationOutput(QWidget *parent) :
-    QTextBrowser(parent)
+    QPlainTextEdit(parent)
 {
+    _errFmt.setForeground(Qt::red);
+    _normFmt.setForeground(Qt::black);
+
+}
+
+void ApplicationOutput::addOutput(const QString& line)
+{
+    qDebug() << "out" << line;
+    _mut.lock();
+    //_queue.append(Line(line, 0));
+    QTextCursor cursor = textCursor();
+    moveCursor(QTextCursor::End);
+    cursor.beginEditBlock();
+    cursor.insertText(line.endsWith("\n") ? line : line+"\n", _normFmt);
+    cursor.endEditBlock();
+    //setTextCursor(cursor);
+    scrollToBottom();
+    _mut.unlock();
+}
+
+void ApplicationOutput::addError(const QString& line)
+{
+    qDebug() << "err" << line;
+    _mut.lock();
+    //_queue.append(Line(line, 1));
+    QTextCursor cursor = textCursor();
+    moveCursor(QTextCursor::End);
+    cursor.beginEditBlock();
+    cursor.insertText(line.endsWith("\n") ? line : line+"\n", _errFmt);
+    cursor.endEditBlock();
+    //setTextCursor(cursor);
+    scrollToBottom();
+    _mut.unlock();
+}
+
+void ApplicationOutput::scrollToBottom()
+{
+    verticalScrollBar()->setValue(verticalScrollBar()->maximum());
+    verticalScrollBar()->setValue(verticalScrollBar()->maximum());
 }
 
 }

File src/Main/Consoles/ApplicationOutput.h

View file
  • Ignore whitespace
 #ifndef _APPLICATIONOUTPUT_H_
 #define _APPLICATIONOUTPUT_H_
 
-#include <QTextBrowser>
+#include <QPlainTextEdit>
+#include <QTextCharFormat>
+#include <QMutex>
 
 namespace Main {
 
-class ApplicationOutput : public QTextBrowser
+class ApplicationOutput : public QPlainTextEdit
 {
     Q_OBJECT
 public:
     ApplicationOutput(QWidget *parent = 0);
+    void addOutput(const QString& line);
+    void addError(const QString& line);
+private:
+    void scrollToBottom();
+    QTextCharFormat _errFmt;
+    QTextCharFormat _normFmt;
+    QMutex _mut;
 };
 
 }

File src/Main/Consoles/IApplicationOutput.cpp

View file
  • Ignore whitespace
+#include "IApplicationOutput.h"
+
+namespace Main {
+
+IApplicationOutput::IApplicationOutput(QWidget* parent):
+    QWidget(parent)
+{
+}
+
+IApplicationOutput::~IApplicationOutput()
+{
+
+}
+
+}

File src/Main/Consoles/IApplicationOutput.h

View file
  • Ignore whitespace
+#ifndef _IAPPLICATIONOUTPUT_H_
+#define _IAPPLICATIONOUTPUT_H_
+
+#include <QWidget>
+
+namespace Main {
+
+class IApplicationOutput: public QWidget
+{
+    Q_OBJECT
+public:
+    IApplicationOutput(QWidget * parent = 0);
+    virtual ~IApplicationOutput();
+public slots:
+    virtual void projectRunned() = 0;
+    virtual void projectStoped() = 0;
+
+    virtual void addOutput(const QString& msg) = 0;
+    virtual void addError(const QString& msg) = 0;
+signals:
+    void run();
+    void stop();
+};
+
+}
+
+#endif

File src/Main/PynotoWindow.cpp

View file
  • Ignore whitespace
 #include "Include/IPreferencesPlugin.h"
 #include "ConsoleWidget.h"
 #include "PynotoStyle.h"
+#include "Consoles/IApplicationOutput.h"
 
 namespace Main {
 
     _console->setup(_editors, _statusGroup);
 
 
+    connect(_project, SIGNAL(runned()), _console->application(), SLOT(projectRunned()));
+    connect(_project, SIGNAL(stoped()), _console->application(), SLOT(projectStoped()));
+    connect(_console->application(), SIGNAL(run()), _project, SLOT(run()));
+    connect(_console->application(), SIGNAL(stop()), _project, SLOT(stop()));
+    connect(_project, SIGNAL(output(QString)), _console->application(), SLOT(addOutput(QString)));
+    connect(_project, SIGNAL(error(QString)), _console->application(), SLOT(addError(QString)));
+
     //connect(_bottom, SIGNAL(jumpCurrentFileLine(int)), _editors, SLOT(jumpCurrentFileLine(int)));
     //connect(_bottom, SIGNAL(jumpFileLine(QString,int)), _editors, SLOT(jumpFileLine(QString,int)));
 
 
 void PynotoWindow::runProject()
 {
-    //ui->bottomDoc->modeSelected(ShowRun);
-    //_project->project()->run(ui->bottomDoc->console());
+    _console->switchTo(1);
+    _project->run();
 }
 
 void PynotoWindow::restoreSession()
 
 void PynotoWindow::closeProject()
 {
-    _project->project()->unload();
+    if (_editors->close()){
+        _project->project()->unload();
+    }
 }
 
 void PynotoWindow::configureProject()

File src/Project/CMakeLists.txt

View file
  • Ignore whitespace
     ProjectFile.h
     ProjectTreeModel.h
     Node.h
+    ProjectRunner.h
     Properties/ProjectProperties.h
     Properties/General.h
     Properties/CodeCheck.h
     CreateProjectDlg.h
     Properties/PathesModel.h
     NewItems/AddNewWizard.h
+    NewItems/SelectTypePage.h
 )
 
 SET(moc
     ProjectFile.cpp
     ProjectTreeModel.cpp
     Node.cpp
+    ProjectRunner.cpp
     Properties/ProjectProperties.cpp
     Properties/General.cpp
     Properties/CodeCheck.cpp
     CreateProjectDlg.cpp
     Properties/PathesModel.cpp
     NewItems/AddNewWizard.cpp
+    NewItems/SelectTypePage.cpp
 )
 
 SET(res
     Properties/General.ui
     Properties/CodeCheck.ui
     CreateProjectDlg.ui
+    NewItems/SelectTypePage.ui
 )
 
 QT4_ADD_RESOURCES(qrc ${res})

File src/Project/IProjectPlugin.h

View file
  • Ignore whitespace
 #include "Include/IProject.h"
 
 class QAction;
+namespace Main {class IApplicationOutput;}
 namespace Project {
 
 class IProjectPlugin: public IPlugin
     virtual IProject * project() = 0;
 signals:
     void preferecesChanged();
+    void runned();
+    void stoped();
+    void output(const QString& msg);
+    void error(const QString& msg);
 public slots:
     virtual void editProperties(QWidget * parent) = 0;
     virtual void createNewProject(QWidget *parent) = 0;
+    virtual void run() = 0;
+    virtual void stop() = 0;
 };
 
 }

File src/Project/NewItems/AddNewWizard.cpp

View file
  • Ignore whitespace
 #include "AddNewWizard.h"
+#include "SelectTypePage.h"
 
 namespace Project {
 
     _path(path),
     _type(type)
 {
+    setPage(SelectTape, new SelectTypePage(this, _type));
 
 }
 

File src/Project/NewItems/AddNewWizard.h

View file
  • Ignore whitespace
 public:
     AddNewWizard(const QString& path, NodeTypes type, QWidget * parent);
 private:
+    enum {
+        SelectTape
+    };
     QString _path;
     NodeTypes _type;
 };

File src/Project/NewItems/SelectTypePage.cpp

View file
  • Ignore whitespace
+#include "SelectTypePage.h"
+#include "ui_SelectTypePage.h"
+
+namespace Project {
+
+SelectTypePage::SelectTypePage(QWidget * parent, NodeTypes type):
+    QWizardPage(parent),
+    _ui(new Ui::SelectTypePage)
+{
+    _ui->setupUi(this);
+
+    items.append("Python class");
+    items.append("Empty Python file");
+    items.append("Python module");
+    items.append("Python Qt Designer class form");
+    items.append("Qt Designer form");
+    items.append("Qt Resource file");
+    items.append("Qml file");
+    items.append("Javascript file");
+    items.append("File");
+    items.append("Directory");
+
+}
+
+SelectTypePage::~SelectTypePage()
+{
+    delete _ui;
+}
+
+}

File src/Project/NewItems/SelectTypePage.h

View file
  • Ignore whitespace
+#ifndef _SELECTTYPEPAGE_H_
+#define _SELECTTYPEPAGE_H_
+#include <QWizardPage>
+#include "Node.h"
+
+
+namespace Ui {
+    class SelectTypePage;
+}
+namespace Project {
+
+class SelectTypePage: public QWizardPage
+{
+    Q_OBJECT
+public:
+    SelectTypePage(QWidget * parent, NodeTypes type);
+    virtual ~SelectTypePage();
+private:
+    Ui::SelectTypePage * _ui;
+    QList<QString> items;
+};
+
+}
+
+#endif

File src/Project/NewItems/SelectTypePage.ui

View file
  • Ignore whitespace
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SelectTypePage</class>
+ <widget class="QWizardPage" name="SelectTypePage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>606</width>
+    <height>437</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WizardPage</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QListWidget" name="items"/>
+     </item>
+     <item>
+      <widget class="QTextBrowser" name="descr"/>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

File src/Project/ProjectFile.cpp

View file
  • Ignore whitespace
     delete _settings;
     _settings = NULL;
     _loaded = false;
+    if (_pythonCode){
+        _pythonCode->close();
+        delete _pythonCode;
+        _pythonCode = NULL;
+    }
+
     emit unloaded();
 }
 
 
 QString ProjectFile::mainScript()
 {
+    if (!_settings)
+        return "";
     return _settings->value("common/mainscript", "").toString();
 }
 

File src/Project/ProjectPlugin.cpp

View file
  • Ignore whitespace
 #include "ProjectManagerWidget.h"
 #include "Properties/ProjectProperties.h"
 #include "CreateProjectDlg.h"
+#include "ProjectRunner.h"
 
 namespace Project {
 
 bool ProjectPlugin::initialize()
 {
     _project = new ProjectFile();
+    _runner = new ProjectRunner(_project);
+    connect(_runner, SIGNAL(stoped()), SIGNAL(stoped()));
+    connect(_runner, SIGNAL(output(QString)), SIGNAL(output(QString)));
+    connect(_runner, SIGNAL(error(QString)), SIGNAL(error(QString)));
     initialized = true;
     return false;
 }
     }
 }
 
+void ProjectPlugin::run()
+{
+    if (_runner->run())
+        emit runned();
+}
+
+void ProjectPlugin::stop()
+{
+    if (_runner->stop())
+        emit stoped();
+}
+
 }
 
 Q_EXPORT_PLUGIN2(project, Project::ProjectPlugin)

File src/Project/ProjectPlugin.h

View file
  • Ignore whitespace
 #include "ProjectFile.h"
 
 namespace Project {
+class ProjectRunner;
 
 class ProjectPlugin: public IProjectPlugin
 {
 public slots:
     virtual void editProperties(QWidget * parent);
     virtual void createNewProject(QWidget *parent);
+    virtual void run();
+    virtual void stop();
 private:
     ProjectFile * _project;
+    ProjectRunner * _runner;
 };
 
 }

File src/Project/ProjectRunner.cpp

View file
  • Ignore whitespace
+#include <QMessageBox>
+#include "ProjectRunner.h"
+#include "ProjectFile.h"
+
+
+namespace Project {
+
+ProjectRunner::ProjectRunner(ProjectFile * project, QObject *parent) :
+    QObject(parent),
+    _project(project),
+    _process(NULL)
+{
+}
+
+bool ProjectRunner::run()
+{
+    if (_process){
+        QMessageBox::warning(NULL, tr("Project run"), tr("Project already runned."));
+        return false;
+    }
+
+    if (_project->interpretExec().isEmpty()){
+        QMessageBox::warning(NULL, tr("Project run"), tr("Python iterpret doesn't configured for this project."));
+        return false;
+    }
+
+    if (_project->mainScript().isEmpty()){
+        QMessageBox::warning(NULL, tr("Project run"), tr("Python main script doesn't configured for this project."));
+        return false;
+    }
+
+    _process = new QProcess(this);
+
+    QStringList pathes = _project->extraPathes() + _project->interpretPathes();
+
+    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+    env.insert("LANG", "en_US.UTF-8");
+    env.insert("PYTHONPATH", pathes.join(":"));
+    _process->setProcessEnvironment(env);
+
+    connect(_process, SIGNAL(readyRead()), SLOT(onReadyRead()));
+    connect(_process, SIGNAL(readyReadStandardError()), SLOT(onReadyReadError()));
+    connect(_process, SIGNAL(finished(int)), SLOT(onRunFinished(int)));
+    connect(_process, SIGNAL(error(QProcess::ProcessError)), SLOT(onRunError(QProcess::ProcessError)));
+
+    _process->setWorkingDirectory(_project->path());
+    _process->start(_project->interpretExec(), QStringList() << "-u" << _project->mainScript());
+
+    return true;
+}
+
+bool ProjectRunner::stop()
+{
+    _process->terminate();
+    return true;
+}
+
+void ProjectRunner::onRunError(QProcess::ProcessError err)
+{
+    switch(err){
+    case QProcess::FailedToStart:
+        emit error(tr("The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program."));
+        break;
+    case QProcess::Crashed:
+        emit error(tr("The process crashed some time after starting successfully."));
+        break;
+    case QProcess::Timedout:
+        emit error(tr("The last waitFor...() function timed out."));
+        break;
+    case QProcess::WriteError:
+        emit error(tr("An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel."));
+        break;
+    case QProcess::ReadError:
+        emit error(tr("An error occurred when attempting to read from the process. For example, the process may not be running."));
+        break;
+    default:
+        emit error(tr("An error occurred when attempting to read from the process. For example, the process may not be running."));
+        break;
+    }
+}
+
+void ProjectRunner::onRunFinished(int status)
+{
+    emit output(tr("Project finished with status %1").arg(status));
+    _process->deleteLater();
+    _process = NULL;
+    emit stoped();
+}
+
+void ProjectRunner::onReadyReadError()
+{
+    _process->setReadChannel(QProcess::StandardError);
+    QByteArray text;
+    while(!(text = _process->readLine()).isEmpty())
+        emit error(text);
+}
+
+void ProjectRunner::onReadyRead()
+{
+    _process->setReadChannel(QProcess::StandardOutput);
+    QByteArray text;
+    while(!(text = _process->readLine()).isEmpty())
+        emit output(text);
+}
+
+}

File src/Project/ProjectRunner.h

View file
  • Ignore whitespace
+#ifndef _PROJECTRUNNER_H_
+#define _PROJECTRUNNER_H_
+
+#include <QObject>
+#include <QProcess>
+
+namespace Project {
+
+class ProjectFile;
+
+class ProjectRunner : public QObject
+{
+    Q_OBJECT
+public:
+    explicit ProjectRunner(ProjectFile * project, QObject *parent = 0);
+signals:
+    void stoped();
+    void error(const QString& msg);
+    void output(const QString& msg);
+public slots:
+    bool run();
+    bool stop();
+private slots:
+    void onRunError(QProcess::ProcessError err);
+    void onRunFinished(int status);
+    void onReadyReadError();
+    void onReadyRead();
+private:
+    ProjectFile * _project;
+    QProcess * _process;
+
+};
+
+}
+
+#endif