Source

pynoto / src / Main / PynotoWindow.cpp

#include <QDebug>
#include <QtPlugin>
#include <QTimer>
#include <QFileDialog>
#include <QCloseEvent>
#include <QLabel>
#include <QSplitter>
#include <QToolButton>
#include "PynotoWindow.h"
#include "ui_PynotoWindow.h"
#include "Include/PynotoApplication.h"
#include "Include/PluginManager.h"
#include "Include/IProjectPlugin.h"
#include "Settings.h"
#include "Include/IEditorsManagerPlugin.h"
#include "Include/IPreferencesPlugin.h"
#include "ConsoleWidget.h"
#include "PynotoStyle.h"

namespace Main {

PynotoWindow::PynotoWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::PynotoWindow),
    _console(NULL),
    _statusGroup(new QButtonGroup(this))
{
    ui->setupUi(this);
    setWindowIcon(QIcon(":/pynoto.svgz"));
    QApplication::setStyle(new PynotoStyle);
    connect(Aux::app(), SIGNAL(preferencesChanged()), SLOT(onPreferencesChanged()));

    setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);

    loadPlugins();

    Settings set;
    QStringList recent = set.recentProjects();
    foreach(QString prj, recent){
        QFileInfo info(prj);
        if (!info.exists())
            continue;

        QAction *action = new QAction(info.filePath(), this);
        action->setData(prj);
        setAction(action, SLOT(openProject()));
        ui->menuOpenRecent->addAction(action);
    }

    setAction(ui->actionPreferences, SLOT(showPreferences()), "configure");
    setAction(ui->actionOpenProject, SLOT(openProject()), "project-open");
    setAction(ui->actionClosePoject, SLOT(closeProject()), "project-close");
    setAction(ui->actionProjectProperties, SLOT(configureProject()), "configure");
    setAction(ui->actionRun, SLOT(runProject()), "project-run");
    setAction(ui->actionFindInProject, SLOT(findInProject()), "edit-find-project");
    setAction(ui->actionNewProject, SLOT(newProject()), "project-new");
    setAction(ui->actionReset, SLOT(resetEditor()));

    updateProjectMenu(false);

    createStatusBtn("Issues", "errors", 0);
    createStatusBtn("Application output", "system-run", 1);
    createStatusBtn("Search results", "search", 2);
    createStatusBtn("System log", "text-x-log", 3);

    _statusGroup->setExclusive(true);
    connect(_statusGroup, SIGNAL(buttonClicked(int)), _console, SLOT(switchTo(int)));
    connect(_console, SIGNAL(consoleChanged(int)), this, SLOT(consoleChanged(int)));


    /*
    connect(_projectManager, SIGNAL(openFile(const QString&, int, bool)), _editors, SLOT(openEditor(const QString&, int, bool)));
    connect(_projectManager, SIGNAL(filesFound(const QStringList&)), ui->bottomDoc, SLOT(filesFound(const QStringList&)));
    */

    QTimer::singleShot(100, this, SLOT(restoreSession()));
}

PynotoWindow::~PynotoWindow()
{
    delete ui;
}

void PynotoWindow::consoleChanged(int id)
{
    _statusGroup->button(id)->setChecked(true);
}

QToolButton * PynotoWindow::createStatusBtn(const QString& text, const QString& icon, int consoleNum)
{
    QToolButton* btn = new QToolButton;
    btn->setText(text);
    btn->setProperty("fancy", true);
    btn->setProperty("consoleNum", consoleNum);
    btn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
    btn->setIcon(_iconProvider->icon(icon));
    btn->setCheckable(true);
    statusBar()->addPermanentWidget(btn);
    _statusGroup->addButton(btn, consoleNum);
    return btn;
}

void PynotoWindow::loadPlugins()
{
    Settings sets;
    _iconProvider = Aux::icons();

    _mSplit = new QSplitter(this);
    _pSplit = new QSplitter(this);
    _pSplit->setOrientation(Qt::Vertical);
    _split = new QSplitter(this);
    _split->setOrientation(Qt::Vertical);

    _project = Aux::plugin<Project::IProjectPlugin*>("project");
    _editors = Aux::plugin<EditorsManager::IEditorsManagerPlugin*>("editorsmanager");

    QWidget *pWid = new QWidget(this);
    pWid->setLayout(new QVBoxLayout);
    pWid->layout()->setContentsMargins(0, 0, 0, 0);
    pWid->layout()->setSpacing(0);
    _title = new QLabel(this);
    _title->setProperty("panelWidget", true);
    pWid->layout()->addWidget(_title);

    QWidget *prj = _project->widget(this);
    prj->setMinimumWidth(200);
    _pSplit->addWidget(prj);
    pWid->layout()->addWidget(prj);
    _pSplit->addWidget(pWid);

    _split->addWidget(_editors->createManager(this));


    QWidget *vbox = new QWidget(this);
    vbox->setLayout(new QVBoxLayout);
    vbox->layout()->setContentsMargins(0, 0, 0, 0);
    vbox->layout()->setSpacing(0);
    QLabel *label = new QLabel(tr("Open Documents"), this);
    label->setProperty("panelWidget", true);
    vbox->layout()->addWidget(label);
    vbox->layout()->addWidget(_editors->openedDocumentsWidget(this));

    _pSplit->addWidget(vbox);

    connect(_project->project(), SIGNAL(loaded()), SLOT(onProjectLoaded()));
    connect(_project->project(), SIGNAL(unloaded()), SLOT(onProjectUnloaded()));

    _console = new ConsoleWidget(this);
    _split->addWidget(_console);

    _mSplit->addWidget(_pSplit);
    _mSplit->addWidget(_split);
    setCentralWidget(_mSplit);

    _split->restoreState(sets.editorSplitSize());
    _mSplit->restoreState(sets.workSplitSize());
    _pSplit->restoreState(sets.leftSplitSize());
    //connect(_bottom, SIGNAL(dockModeSelected(DockShowMode)), title, SLOT(dockModeSelected(DockShowMode)));

    connect(_editors, SIGNAL(undoAvailable(bool)), ui->actionUndo, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(redoAvailable(bool)), ui->actionRedo, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionCopy, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionCut, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionDelete, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(pasteAvailable(bool)), ui->actionPaste, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionUppercase, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionLowercase, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionCapitalize, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionCamelCase, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(copyAvailable(bool)), ui->actionUnderScoreCase, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(modificationChanged(bool)), ui->actionSave, SLOT(setEnabled(bool)));

    connect(_editors, SIGNAL(findAvailable(bool)), ui->actionFindNext, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(findAvailable(bool)), ui->actionFindPrevious, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(replaceAvailable(bool)), ui->actionReplace, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(replaceAvailable(bool)), ui->actionReplaceAll, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(replaceAvailable(bool)), ui->actionReplaceFind, SLOT(setEnabled(bool)));
    connect(_editors, SIGNAL(replaceAvailable(bool)), ui->actionReplaceFindPrevious, SLOT(setEnabled(bool)));


    connect(_project->project(), SIGNAL(openFileOffset(QString,int)), _editors, SLOT(openFileOffset(QString,int)));


    //Edit menu
    ui->actionUndo->setIcon(_iconProvider->icon("edit-undo"));
    _editors->setAction(ui->actionUndo, SLOT(undo()));

    ui->actionRedo->setIcon(_iconProvider->icon("edit-redo"));
    _editors->setAction(ui->actionRedo, SLOT(redo()));

    ui->actionCopy->setIcon(_iconProvider->icon("edit-copy"));
    _editors->setAction(ui->actionCopy, SLOT(copy()));

    ui->actionPaste->setIcon(_iconProvider->icon("edit-paste"));
    _editors->setAction(ui->actionPaste, SLOT(paste()));

    ui->actionDelete->setIcon(_iconProvider->icon("edit-delete"));
    _editors->setAction(ui->actionDelete, SLOT(del()));

    ui->actionCut->setIcon(_iconProvider->icon("edit-cut"));
    _editors->setAction(ui->actionCut, SLOT(cut()));
    _editors->setAction(ui->actionUppercase, SLOT(upperCase()));
    _editors->setAction(ui->actionLowercase, SLOT(lowerCase()));
    _editors->setAction(ui->actionCapitalize, SLOT(capitalize()));
    _editors->setAction(ui->actionCamelCase, SLOT(camelize()));
    _editors->setAction(ui->actionUnderScoreCase, SLOT(underlize()));

    ui->actionSelectAll->setIcon(_iconProvider->icon("edit-select-all"));
    _editors->setAction(ui->actionSelectAll, SLOT(selectAll()));

    ui->actionFindReplace->setIcon(_iconProvider->icon("edit-find"));
    _editors->setAction(ui->actionFindReplace, SLOT(showFind()));

    _editors->setAction(ui->actionFindNext, SLOT(findNext()));
    _editors->setAction(ui->actionFindPrevious, SLOT(findPrevious()));


    //File menu
    _editors->setAction(ui->actionCloseFile, SLOT(closeEditor()));
    ui->actionSave->setIcon(_iconProvider->icon("document-save"));
    _editors->setAction(ui->actionSave, SLOT(save()));
    _editors->setAction(ui->actionSaveAll, SLOT(saveAll()));
    _editors->setAction(ui->actionSaveAs, SLOT(saveAs()));

    _console->setup(_editors, _statusGroup);


    //connect(_bottom, SIGNAL(jumpCurrentFileLine(int)), _editors, SLOT(jumpCurrentFileLine(int)));
    //connect(_bottom, SIGNAL(jumpFileLine(QString,int)), _editors, SLOT(jumpFileLine(QString,int)));

    /*
    connect(ui->bottomDoc, SIGNAL(jumpFileLine(QString,int)), _editors, SLOT(jumpToFileLine(QString,int)));

    connect(_editors, SIGNAL(activated(QString)), _projectManager, SLOT(fileActivated(QString)));
    connect(_editors, SIGNAL(fileNavigate(QString, int)), _projectManager, SLOT(navigateFile(QString, int)));
    connect(_editors, SIGNAL(modifyChanged(QString, bool)), _projectManager, SLOT(modifyChanged(QString, bool)));


    setAction(_editors, ui->actionOpenFile,     SLOT(openFile()),  "document-open");
    setAction(_editors, ui->actionSwitchSourceUi, SLOT(switchSourceUi()));*/
}

void PynotoWindow::setAction(QAction *action, const char *slot, const QString & iconName)
{
    setAction(this, action, slot, iconName);
}

void PynotoWindow::setAction(QWidget * reciver, QAction *action, const char *slot, const QString & iconName)
{
    reciver->addAction(action);
    connect(action, SIGNAL(triggered()), reciver, slot);
    if (!iconName.isEmpty())
        action->setIcon(_iconProvider->icon(iconName));
}

void PynotoWindow::onProjectLoaded()
{
    _title->setText(tr("Project: ")+_project->project()->name());
    setWindowTitle(_project->project()->name()+" - pyNoto");
    Settings set;
    set.setLastProject(_project->project()->fileName());
    updateProjectMenu(true);
}

void PynotoWindow::onProjectUnloaded()
{
    _title->setText("");
    setWindowTitle("pyNoto");
    updateProjectMenu(false);
}

void PynotoWindow::openProject()
{
    QAction *act = qobject_cast<QAction*>(sender());
    if (!act->data().isNull()){
        _project->project()->load(act->data().toString());
    } else {
        QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("Projects (*.pynotoprj)"));
        if (!fileName.isEmpty()){
            _project->project()->load(fileName);
        }
    }
}

void PynotoWindow::showPreferences()
{
    Preferences::IPreferencesPlugin* pref = Aux::manager()->plugin<Preferences::IPreferencesPlugin*>("preferences");
    pref->editPreferences(this);
}

void PynotoWindow::updateProjectMenu(bool enabled)
{
    ui->actionClosePoject->setEnabled(enabled);
    ui->actionFindInProject->setEnabled(enabled);
    ui->actionProjectProperties->setEnabled(enabled);
    ui->actionRun->setEnabled(enabled);
}

void PynotoWindow::runProject()
{
    //ui->bottomDoc->modeSelected(ShowRun);
    //_project->project()->run(ui->bottomDoc->console());
}

void PynotoWindow::restoreSession()
{
    Settings set;
    if (set.lastProject() != "")
        _project->project()->load(set.lastProject());
}

void PynotoWindow::closeProject()
{
    _project->project()->unload();
}

void PynotoWindow::configureProject()
{
    _project->editProperties(this);
}

void PynotoWindow::findInProject()
{

}

void PynotoWindow::newProject()
{
    _project->createNewProject(this);
}

void PynotoWindow::resetEditor()
{
    if (_editors)
        _editors->resetEditor();
}

void PynotoWindow::closeEvent(QCloseEvent *ev)
{
    if (!_editors->close()){
        ev->ignore();
        return;
    }

    Settings set;
    set.setEditorSplitSize(_split->saveState());
    set.setLeftSplitSize(_pSplit->saveState());
    set.setWorkSplitSize(_mSplit->saveState());

    QMainWindow::closeEvent(ev);
}

void PynotoWindow::onPreferencesChanged()
{

}

}