diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a7da4ca9..5334f25e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,198 +1,199 @@ include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} ${KROSS_INCLUDES} Core/ Actions/ GraphicsItem/ Interface/ Interface/VisualEditor Models/ Plugins/ Scripts/ ) # Prepare library. set( rocs_core_SRCS Core/Data.cpp Core/DataStructure.cpp Core/Document.cpp Core/Group.cpp Core/DataStructurePluginInterface.cpp Core/DataStructurePluginManager.cpp Core/DocumentManager.cpp Core/DynamicPropertiesList.cpp Core/KrossBackend.cpp Core/Pointer.cpp Core/QtScriptBackend.cpp Core/Modifiers/Topology.cpp Core/Modifiers/ValueModifier.cpp Plugins/PluginManager.cpp Plugins/ToolsPluginInterface.cpp Plugins/FilePluginInterface.cpp GraphicsItem/GraphicsLayout.cpp GraphicsItem/DataItem.cpp GraphicsItem/PointerItem.cpp + + Scripts/IncludeManager.cpp ) kde4_add_library( rocslib SHARED ${rocs_core_SRCS} ) target_link_libraries( rocslib ${KDE4_KROSSCORE_LIBS} ${KDE4_KIO_LIBS} ${QT_QTSCRIPT_LIBRARY} ${QT_QTSCRIPTTOOLS_LIBRARY} ) set( rocslib_LIB_HDRS Core/DynamicPropertiesList.h Core/Data.h Core/DataStructure.h Core/Document.h Core/KrossBackend.h Core/Pointer.h Core/QtScriptBackend.h Core/rocslib_export.h Core/Rocs_Typedefs.h Core/DataStructurePluginInterface.h Core/DataStructurePluginManager.h Core/Modifiers/Topology.h Plugins/FilePluginInterface.h Plugins/PluginManager.h Plugins/ToolsPluginInterface.h GraphicsItem/DataItem.h GraphicsItem/PointerItem.h GraphicsItem/GraphicsLayout.h Scripts/IncludeManager.h ) set_target_properties( rocslib PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) install( TARGETS rocslib ${INSTALL_TARGETS_DEFAULT_ARGS} ) install( FILES ${rocslib_LIB_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/rocs COMPONENT Devel ) ###################### Outros SRCS ############################ #set ( kwelcomewidget_SRCS # KWelcomeWidget/kwelcomewidget.cpp #) set ( rocs_actions_SRCS Actions/AbstractAction.cpp Actions/AddConnectionHandAction.cpp Actions/AddDataAction.cpp Actions/AlignAction.cpp Actions/DeleteAction.cpp Actions/ZoomAction.cpp Actions/AddDataHandAction.cpp Actions/DeleteHandAction.cpp Actions/AssignValueAction.cpp Actions/SelectMoveHandAction.cpp ) set( rocs_interface_SRCS Interface/ImporterExporterManager.cpp Interface/IncludeManagerSettings.cpp Interface/MainWindow.cpp Interface/OpenedFilesWidget.cpp Interface/Separator.cpp Interface/GraphPropertiesWidget.cpp Interface/GraphLayers.cpp Interface/TabWidget.cpp Interface/CodeEditor.cpp Interface/NodePropertiesWidget.cpp Interface/edgepropertieswidget.cpp Interface/ConfigureDefaultProperties.cpp Interface/VisualEditor/GraphScene.cpp Interface/VisualEditor/GraphVisualEditor.cpp ) set( rocs_models_SRCS Models/model_GraphDocument.cpp Models/model_GraphLayers.cpp Models/model_GraphProperties.cpp ) # set( rocs_undoredo_SRCS # UndoRedo/URAddNode.cpp # UndoRedo/URAddEdge.cpp # ) set ( rocs_script_SRC Interface/PossibleIncludes.cpp - Scripts/IncludeManager.cpp ) set(rocs_SRCS Main.cpp ${rocs_actions_SRCS} ${rocs_interface_SRCS} ${rocs_models_SRCS} ${rocs_script_SRC} ) kde4_add_ui_files( rocs_SRCS Interface/OpenedFilesWidget.ui Interface/GraphPropertiesWidget.ui Interface/NodePropertiesWidget.ui Interface/EdgePropertiesWidget.ui Interface/ConfigureDefaultProperties.ui ) set (QT_USE_QTSCRIPT true) set(rocs_KCFGS settings.kcfgc) kde4_add_kcfg_files(rocs_Settings_SRCS ${rocs_KCFGS} ) kde4_add_executable(rocs ${rocs_SRCS} ${rocs_Settings_SRCS} ${rocs_RCC_SRCS}) target_link_libraries(rocs rocslib ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS} ${KDE4_KROSSUI_LIBS} ${KDE4_KIO_LIBS} ${KDE4_KTEXTEDITOR_LIBS} ${QT_QTSCRIPT_LIBRARY} ${QT_QTSCRIPTTOOLS_LIBRARY} ${KDE4_KNEWSTUFF3_LIBS} ) ################## INSTALLS ########################## install( TARGETS rocs ${INSTALL_TARGETS_DEFAULT_ARGS} ) install( PROGRAMS rocs.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) install( FILES rocsui.rc DESTINATION ${DATA_INSTALL_DIR}/rocs ) install( FILES rocs.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) install(FILES rocs.knsrc DESTINATION ${CONFIG_INSTALL_DIR}) install( FILES Core/RocsDataStructurePlugin.desktop Plugins/RocsToolsPlugin.desktop Plugins/RocsFilePlugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) add_subdirectory(Plugins) add_subdirectory(Scripts) #Build Tests if KDE_TEST is on if(KDE4_BUILD_TESTS) enable_testing() add_subdirectory(Tests) endif(KDE4_BUILD_TESTS) diff --git a/src/Core/QtScriptBackend.cpp b/src/Core/QtScriptBackend.cpp index af7145f1..9274fa08 100644 --- a/src/Core/QtScriptBackend.cpp +++ b/src/Core/QtScriptBackend.cpp @@ -1,142 +1,165 @@ -/* +/* This file is part of Rocs. Copyright 2004-2011 Tomaz Canabrava This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either + License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public + You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "QtScriptBackend.h" #include "DataStructure.h" #include "Data.h" #include #include #include "Document.h" #include #include // usleep #include static QtScriptBackend *self; static QScriptValue debug_script(QScriptContext* context, QScriptEngine* /*engine*/) { self->debug(QString("%1").arg(context->argument(0).toString())); return QScriptValue(); } static QScriptValue output_script(QScriptContext *context, QScriptEngine* /*engine*/){ self->output(QString("%1").arg(context->argument(0).toString())); return QScriptValue(); } +static QScriptValue include_script(QScriptContext *context, QScriptEngine* /*engine*/){ + self->includeFile(QString("%1").arg(context->argument(0).toString())); + return QScriptValue(); +} + void QtScriptBackend::stop(){ if (!_engine) return; if (_engine->isEvaluating()){ _engine->abortEvaluation(); } _engine->deleteLater(); _engine = 0; emit finished(); } void QtScriptBackend::start() { stop(); _engine = new QScriptEngine(); emit engineCreated(_engine); _engine->globalObject().setProperty("debug", engine()->newFunction(debug_script)); _engine->globalObject().setProperty("output", engine()->newFunction(output_script)); + _engine->globalObject().setProperty("include", engine()->newFunction(include_script)); int size = _document->dataStructures().size(); for (int i = 0; i < size; i++) { _document->dataStructures().at(i)->setEngine(_engine); } createGraphList(); _engine->setProcessEventsInterval(100); //! TODO: Make that changable. - + QString error = _engine->evaluate(_script).toString(); if (_engine && _engine->hasUncaughtException()) { emit scriptError(); emit sendDebug(""+error+""); } emit finished(); } bool QtScriptBackend::isRunning(){ if ((_engine) && (_engine->isEvaluating())){ return true; } return _runningTool; } QtScriptBackend::QtScriptBackend(QObject* parent): QObject(parent){ self = this; _engine = 0; _runningTool = false; } void QtScriptBackend::runTool(ToolsPluginInterface * plugin, Document *graphs){ _runningTool = true; _document = graphs; _script = plugin->run(graphs); if ( !_script.isEmpty()){ start(); } _runningTool = false; } void QtScriptBackend::setScript(const QString& s,Document *graphs ) { _script = s; _document = graphs; kDebug() << "script Set" << _script; } void QtScriptBackend::createGraphList() { QScriptValue graphList = _engine->newArray(); _engine->globalObject().setProperty("graphs", graphList); // Add all the graphs on the array as an array, and if it has a name, // also add it for direct acess with it's name. int size = _document->dataStructures().size(); for (int i = 0; i < size; i++) { graphList.property("push").call(graphList, QScriptValueList() << _document->dataStructures().at(i)->scriptValue()); } } void QtScriptBackend::loadFile(const QString& file) { _script.clear(); QFile f(file); if ( !f.open(QIODevice::ReadOnly | QIODevice::Text ) ) { kDebug() << "File not found"; return; } while ( ! f.atEnd() ) { QByteArray line = f.readLine(); _script += line; } _script += '\n'; } void QtScriptBackend::debug(const QString& str){ emit sendDebug(str); } void QtScriptBackend::output(const QString& str){ emit sendOutput(str); emit sendDebug(""+str+""); } +void QtScriptBackend::includeFile(const QString & includedFile){ + QString fileName = m_includeManager.seekFile(includedFile); + + if (m_includeManager.checkIfWasIncluded(fileName)) + return; + + QFile f(fileName); + if (f.open(QFile::ReadOnly)){ + QString script = m_includeManager.include(f.readAll(), fileName.section('/',0,-2), fileName.section('/',-1)); + QString error = _engine->evaluate(script, includedFile).toString(); + if (_engine && _engine->hasUncaughtException()) { + emit scriptError(); + emit sendDebug(i18n(" Error in include file %1").arg(includedFile)); + emit sendDebug(""+error+""); + } + } +} diff --git a/src/Core/QtScriptBackend.h b/src/Core/QtScriptBackend.h index e59d468e..0482c54b 100644 --- a/src/Core/QtScriptBackend.h +++ b/src/Core/QtScriptBackend.h @@ -1,76 +1,83 @@ -/* +/* This file is part of Rocs. Copyright 2004-2011 Tomaz Canabrava This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either + License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public + You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef QTSCRIPTBACKEND_H #define QTSCRIPTBACKEND_H #include #include #include #include "rocslib_export.h" +#include class Document; class ToolsPluginInterface; class ROCSLIB_EXPORT QtScriptBackend : public QObject{ Q_OBJECT public: // QtScriptBackend(); QtScriptBackend(QObject* parent = 0); void setScript(const QString& s, Document *document); void setDocument(Document *document); void loadFile(const QString& file); void debug(const QString& s); void output(const QString& s); QScriptEngine *engine(){ return _engine; } + void includeFile(const QString&); + /** return true if is evaluating a script or running a tool script. */ bool isRunning(); + IncludeManager& includeManager(){return m_includeManager;} + private: void createGraphList(); - + QString _script; Document *_document; QScriptEngine *_engine; bool _runningTool; + IncludeManager m_includeManager; + signals: void sendOutput(const QString& s); void sendDebug(const QString& s); void scriptError(); void engineCreated(QScriptEngine* e); void finished(); public slots: void start(); /** run a tool plugin in graph and later run it resulting script.*/ void runTool(ToolsPluginInterface * plugin, Document *document); /** abort script evaluation. In case of a too is running, stop will not stop tool. But the script resulting from tool will not be runned. */ void stop(); }; #endif diff --git a/src/Interface/MainWindow.cpp b/src/Interface/MainWindow.cpp index 62146197..a0ea4318 100644 --- a/src/Interface/MainWindow.cpp +++ b/src/Interface/MainWindow.cpp @@ -1,703 +1,702 @@ /* This file is part of Rocs. Copyright 2008-2011 Tomaz Canabrava Copyright 2008 Ugo Sangiori Copyright 2010-2011 Wagner Reck Copyright 2011 Andreas Cord-Landwehr This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "MainWindow.h" //Qt related includes #include #include #include #include #include #include #include #include #include // KDE Related Includes #include #include #include #include #include #include #include #include #include #include #include #include // UI RELATED INCLUDES #include "GraphLayers.h" #include "GraphVisualEditor.h" #include "GraphScene.h" #include "CodeEditor.h" #include "TabWidget.h" #include "GraphicsLayout.h" // MODEL Related Includes #include "model_GraphDocument.h" // Graph Related Includes #include "Document.h" #include "DataStructure.h" #include "settings.h" // Action Related Includes #include "AbstractAction.h" #include "AddDataHandAction.h" #include "AddConnectionHandAction.h" #include "SelectMoveHandAction.h" #include "DeleteHandAction.h" #include "AlignAction.h" #include "ZoomAction.h" #include "DeleteAction.h" #include #include // backends #include "QtScriptBackend.h" #include #include #include #include #include #include #include "../Plugins/PluginManager.h" #include #include #include "IncludeManagerSettings.h" #include "ConfigureDefaultProperties.h" #include #include "ImporterExporterManager.h" #include #include #include "DocumentManager.h" #include "PossibleIncludes.h" MainWindow::MainWindow() : KXmlGuiWindow() { setObjectName ( "RocsMainWindow" ); setupWidgets(); setupActions(); setupGUI(); //statusBar()->hide(); setupToolsPluginsAction(); setupDSPluginsAction(); DocumentManager *dm = DocumentManager::self(); connect(dm, SIGNAL(activateDocument()), this, SLOT(setActiveDocument())); connect(dm, SIGNAL(deactivateDocument(Document*)), this, SLOT(releaseDocument(Document*))); connect(dm, SIGNAL(documentRemoved(Document*)), this, SLOT(releaseDocument(Document*))); /* just for testing prurposes, * this should not be hardcoded here. * use KWelcomeWidget instead. */ DocumentManager::self()->loadDocument(); GraphicsLayout::self()->setViewStyleDataNode(Settings::dataNodeDisplay()); GraphicsLayout::self()->setViewStyleDataEdge(Settings::dataEdgeDisplay()); } MainWindow::~MainWindow() { Settings::setVSplitterSizeTop ( _vSplitter->sizes() [0] ); Settings::setVSplitterSizeBottom ( _vSplitter->sizes() [1] ); Settings::setHSplitterSizeLeft ( _hSplitter->sizes() [0] ); Settings::setHSplitterSizeRight ( _hSplitter->sizes() [1] ); Settings::setHScriptSplitterSizeLeft ( _hScriptSplitter->sizes() [0] ); Settings::setHScriptSplitterSizeRight ( _hScriptSplitter->sizes() [1] ); Settings::self()->writeConfig(); } void MainWindow::closeEvent(QCloseEvent *event) { switch (saveIfChanged()) { case KMessageBox::Cancel : event->ignore(); return; default: event->accept(); return; } } void MainWindow::setupWidgets() { // splits the main window horizontal _vSplitter = new QSplitter ( this ); _vSplitter->setOrientation ( Qt::Vertical ); // setup upper half QWidget *leftPanel = setupWhiteboardPanel(); // graph properties _graphVisualEditor = GraphVisualEditor::self(); // graph editor whiteboard _hSplitter = new QSplitter ( this ); _hSplitter->setOrientation( Qt::Horizontal ); _hSplitter->addWidget (leftPanel); _hSplitter->addWidget (_graphVisualEditor); // setup lower half QWidget *scriptPanel = setupScriptPanel(); _vSplitter->addWidget ( _hSplitter ); _vSplitter->addWidget ( scriptPanel ); _hScriptSplitter->setSizes ( QList() << Settings::hScriptSplitterSizeLeft() << Settings::hScriptSplitterSizeRight() << 80 ); _vSplitter->setSizes ( QList() << Settings::vSplitterSizeTop() << Settings::vSplitterSizeBottom() ); _hSplitter->setSizes ( QList() << Settings::hSplitterSizeLeft() << Settings::hSplitterSizeRight() ); setCentralWidget ( _vSplitter ); } void MainWindow::downloadNewExamples(){ KNS3::DownloadDialog dialog("rocs.knsrc", this); dialog.exec(); } void MainWindow::uploadScript() { KNS3::UploadDialog dialog(this); //First select the opened doc. KUrl str = _codeEditor->document()->url(); if (str.isEmpty()) { //... then try to open str = KFileDialog::getOpenFileName ( QString(), i18n ( "*.js|Script files" ), this, i18n ( "Rocs Script Files" ) ); if (str.isEmpty()) return; } //Compress the file to a temp file (How it can be made in KDE way ? ) QString local = QDir::temp().absoluteFilePath(str.fileName()); local.chop(3); local.append(".tar.gz"); //create compressed file and set to dialog. KTar tar = KTar(local); tar.open(QIODevice::WriteOnly); tar.addLocalFile(str.toLocalFile(), str.fileName()); tar.close(); dialog.setUploadFile(local); dialog.setUploadName(_codeEditor->document()->documentName()); dialog.setDescription(i18n("Added your description here.")); dialog.exec(); //Remove compressed file.. QDir::temp().remove(local); } QWidget* MainWindow::setupScriptPanel() { _hScriptSplitter = new QSplitter( this ); _hScriptSplitter->setOrientation( Qt::Horizontal ); _codeEditor = new CodeEditor ( this ); _txtDebug = new KTextBrowser ( this ); _txtOutput = new KTextBrowser( this ); QStackedWidget *stackedListing = new QStackedWidget; stackedListing->addWidget(_txtOutput); stackedListing->addWidget(_txtDebug); _selectListing = new QComboBox; _selectListing->addItem( KIcon ( "accessories-text-editor" ), i18n("Program Messages")); _selectListing->addItem( KIcon ( "tools-report-bug" ), i18n("Debug Messages")); QWidget *header = new QWidget( this ); header->setLayout( new QHBoxLayout ); header->layout()->addWidget(new QLabel(i18n("Select output:"))); header->layout()->addWidget(_selectListing); QWidget *listingWidget = new QWidget(this); listingWidget->setLayout( new QVBoxLayout ); listingWidget->layout()->addWidget( header ); listingWidget->layout()->addWidget( stackedListing ); QToolBar *executeCommands = new QToolBar; executeCommands->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); executeCommands->setOrientation(Qt::Vertical); _runScript = new KAction ( KIcon ( "system-run" ), i18n ( "Run" ), this ); _stopScript = new KAction ( KIcon ( "process-stop" ), i18n ( "Stop" ), this ); _stopScript->setEnabled(false); executeCommands->addAction(_runScript); executeCommands->addAction(_stopScript); connect(_runScript, SIGNAL(triggered()), this, SLOT(executeScript())); connect(_stopScript, SIGNAL(triggered()), this, SLOT(stopScript())); connect(_selectListing, SIGNAL(currentIndexChanged(int)), stackedListing, SLOT(setCurrentIndex(int))); _hScriptSplitter->addWidget( _codeEditor ); _hScriptSplitter->addWidget( listingWidget ); QWidget *scriptInterface = new QWidget( this ); scriptInterface->setLayout( new QHBoxLayout ); scriptInterface->layout()->addWidget( _hScriptSplitter ); scriptInterface->layout()->addWidget( executeCommands ); return scriptInterface; } QWidget* MainWindow::setupWhiteboardPanel() { _GraphLayers = new GraphLayers ( this ); return _GraphLayers; } void MainWindow::setupActions() { kDebug() << "Entering in Setup Actions"; KStandardAction::quit ( kapp,SLOT ( quit() ),actionCollection() ); KStandardAction::preferences(this, SLOT(showSettings()), actionCollection()); GraphScene *gc = _graphVisualEditor->scene(); _selectMoveAction = new SelectMoveHandAction (gc, this); AddDataHandAction* addDataAction = new AddDataHandAction(gc, this ); AddConnectionHandAction* addConnectionAction = new AddConnectionHandAction(gc, this); DeleteHandAction* deleteAction = new DeleteHandAction(gc, this); ZoomAction* zoomAction = new ZoomAction(gc, this); connect(_selectMoveAction, SIGNAL(triggered()), _selectMoveAction, SLOT( sendExecuteBit() )); connect(addDataAction, SIGNAL(triggered()), addDataAction, SLOT( sendExecuteBit() )); connect(addConnectionAction, SIGNAL(triggered()), addConnectionAction, SLOT( sendExecuteBit() )); connect(deleteAction, SIGNAL(triggered()), deleteAction, SLOT( sendExecuteBit() )); connect(zoomAction, SIGNAL(triggered()), zoomAction, SLOT( sendExecuteBit() )); _paletteActions = actionCollection(); QActionGroup *g = new QActionGroup ( this ); g->addAction ( _paletteActions->addAction ( "selectmove", _selectMoveAction ) ); g->addAction ( _paletteActions->addAction ( "add_node", addDataAction ) ); g->addAction ( _paletteActions->addAction ( "add_edge", addConnectionAction ) ); g->addAction ( _paletteActions->addAction ( "delete", deleteAction ) ); g->addAction ( _paletteActions->addAction ( "zoom", zoomAction ) ); actionCollection()->action ( "selectmove" )->toggle(); gc->setAction ( _selectMoveAction ); _paletteActions->addAction ( "align-hbottom",new AlignAction ( i18nc( "Alignment", "Base" ), AlignAction::Bottom, gc, _graphVisualEditor ) ); _paletteActions->addAction ( "align-hcenter",new AlignAction ( i18nc( "Alignment", "Center" ),AlignAction::HCenter,gc,_graphVisualEditor ) ); _paletteActions->addAction ( "align-htop", new AlignAction ( i18nc( "Alignment", "Top" ), AlignAction::Top, gc,_graphVisualEditor ) ); _paletteActions->addAction ( "align-vleft", new AlignAction ( i18nc( "Alignment", "Left" ), AlignAction::Left, gc,_graphVisualEditor ) ); _paletteActions->addAction ( "align-vcenter",new AlignAction ( i18nc( "Alignment", "Center" ),AlignAction::VCenter,gc,_graphVisualEditor ) ); _paletteActions->addAction ( "align-vright", new AlignAction ( i18nc( "Alignment", "Right" ), AlignAction::Right, gc,_graphVisualEditor ) ); _paletteActions->addAction ( "align-circle", new AlignAction ( i18nc( "Alignment", "Circle" ), AlignAction::Circle, gc,_graphVisualEditor ) ); _paletteActions->addAction ( "align-tree", new AlignAction ( i18nc( "Alignment", "Minimize Crossing Edges" ), AlignAction::MinCutTree, gc, _graphVisualEditor ) ); // Menu actions createAction("document-new", i18n("New Graph"), "new-graph", SLOT(newGraph()), this); createAction("document-open", i18n("Open Graph"), "open-graph", SLOT(openGraph()), this); createAction("document-save", i18n("Save Graph"), "save-graph", SLOT(saveGraph()), this); createAction("document-save-as", i18n("Save Graph as"), "save-graph-as", SLOT(saveGraphAs()), this); createAction("", i18n("Download Examples"), "download", SLOT(downloadNewExamples()), this); createAction("", i18n("Upload script"), "upload", SLOT(uploadScript()), this); createAction("document-save", i18n("Save All"), "save-all", Qt::Key_S, SLOT(saveAll()), this); createAction("document-save-as", i18n("Possible Includes"), "possible_includes", SLOT(showPossibleIncludes()), this); createAction("document-new", i18n("New Script"), "new-script", SLOT(newScript()), _codeEditor); createAction("document-open", i18n("Open Script"), "open-script", SLOT(openScript()), _codeEditor); createAction("document-save", i18n("Save Script"), "save-script", SLOT(saveActiveScript()), _codeEditor); createAction("document-save-as", i18n("Save Script as"), "save-script-as", SLOT(saveActiveScriptAs()), _codeEditor); // eventually create hooks for file plugins PluginManager::instance()->loadFilePlugins(); if (PluginManager::instance()->filePlugins().count()>0) { createAction("document-open", i18n("Import Graph"), "import-graph", SLOT(importFile()), this); createAction("document-save", i18n("Export Graph"), "export-graph", SLOT(exportFile()), this); } // EDIT actions actionCollection()->addAction("delete-selected", new DeleteAction( i18n("Delete"), _graphVisualEditor->scene(), 0) ); KStandardAction::quit ( kapp, SLOT ( quit() ), actionCollection() ); } void MainWindow::createAction(const QByteArray& iconName, const QString& actionTitle, const QString& actionName, const QKeySequence& shortcut, const char* slot, QObject *parent) { KAction* action = new KAction ( KIcon ( iconName ), actionTitle, parent ); action->setShortcut ( shortcut); action->setShortcutContext ( Qt::WidgetShortcut ); actionCollection()->addAction ( actionName, action ); connect(action, SIGNAL(triggered(bool)), parent, slot ); } void MainWindow::createAction(const QByteArray& iconName, const QString& actionTitle, const QString& actionName, const char* slot, QObject *parent) { KAction* action = new KAction ( KIcon ( iconName ), actionTitle, parent ); action->setShortcutContext ( Qt::WidgetShortcut ); actionCollection()->addAction ( actionName, action ); connect(action, SIGNAL(triggered(bool)), parent, slot); } void MainWindow::showSettings() { KConfigDialog dialog(this, "settings", Settings::self()); IncludeManagerSettings * set = new IncludeManagerSettings(&dialog); ConfigureDefaultProperties * defaultProperties = new ConfigureDefaultProperties( &dialog ); dialog.addPage(set,i18n("Include Manager"),QString(),i18n("Include Manager"),true); dialog.addPage(defaultProperties,i18n("Default Settings"),QString(),i18n("Default Settings"),true); connect(set, SIGNAL(changed(bool)), &dialog, SLOT(enableButtonApply(bool))); connect(defaultProperties, SIGNAL(changed(bool)), &dialog, SLOT(enableButtonApply(bool))); connect(&dialog, SIGNAL(applyClicked()), set, SLOT(saveSettings())); connect(&dialog, SIGNAL(okClicked()), set, SLOT(saveSettings())); connect(&dialog, SIGNAL(defaultClicked()), set, SLOT(readConfig())); connect(&dialog, SIGNAL(applyClicked()), defaultProperties, SLOT(saveConfig())); connect(&dialog, SIGNAL(okClicked()), defaultProperties, SLOT(saveConfig())); connect(&dialog, SIGNAL(defaultClicked()), defaultProperties, SLOT(readConfig())); dialog.exec(); } void MainWindow::setupToolsPluginsAction() { QList pluginList; QAction* action = 0; unplugActionList ( "tools_plugins" ); QList < ToolsPluginInterface*> avaliablePlugins = PluginManager::instance()->toolPlugins(); int count = 0; foreach ( ToolsPluginInterface* p, avaliablePlugins ){ action = new KAction ( p->displayName(), this ); action->setData(count++); connect(action, SIGNAL(triggered(bool)), this, SLOT(runToolPlugin())); pluginList.append( action ); } plugActionList( "tools_plugins", pluginList ); } void MainWindow::setupDSPluginsAction() { QList pluginList; QAction* action = 0; unplugActionList ( "DS_plugins" ); QList < DataStructurePluginInterface*> avaliablePlugins = DataStructurePluginManager::self()->pluginsList(); QActionGroup * group = new QActionGroup(this); int count = 0; foreach ( DataStructurePluginInterface* p, avaliablePlugins ) { action = new KAction ( p->name(), this ); action->setData(count++); action->setCheckable(true); if (p->name() == DataStructurePluginManager::self()->pluginName()){ action->setChecked(true); } action->setActionGroup(group); connect ( action, SIGNAL (triggered(bool)), DataStructurePluginManager::self(), SLOT(setDataStructurePlugin())); pluginList.append ( action ); } plugActionList ( "DS_plugins", pluginList ); } void MainWindow::setupDocumentsList(){ QList pluginList; QAction* action = 0; unplugActionList ( "Doc_List" ); QActionGroup * group = new QActionGroup(this); int count = 0; foreach(Document * doc, DocumentManager::self()->documentList()){ action = new KAction ( doc->name(), this ); action->setData(count++); action->setCheckable(true); if (doc == DocumentManager::self()->activeDocument()){ action->setChecked(true); } action->setActionGroup(group); connect(action, SIGNAL(triggered(bool)), DocumentManager::self(), SLOT(changeDocument())); pluginList.append ( action ); } plugActionList ( "Doc_List", pluginList ); } void MainWindow::setActiveDocument ( ) { kDebug() << "Setting the document in the main widnow"; Document *activeDocument = DocumentManager::self()->activeDocument(); QtScriptBackend *engine = activeDocument->engineBackend(); _graphVisualEditor->setActiveDocument(); _GraphLayers->setActiveDocument(); connect ( this, SIGNAL(runTool(ToolsPluginInterface*,Document*)), activeDocument->engineBackend(), SLOT(runTool(ToolsPluginInterface*,Document*))); // connect(this, SIGNAL(startEvaluation()), engine, SLOT(start())); connect( engine, SIGNAL(sendDebug(QString)), this, SLOT(debugString(QString))); connect( engine, SIGNAL(scriptError()), this, SLOT(showDebugOutput())); connect( engine, SIGNAL(sendOutput(QString)), this, SLOT(outputString(QString))); connect( engine, SIGNAL(finished()), this, SLOT(disableStopAction())); activeDocument->setModified(false); } void MainWindow::releaseDocument ( Document* d ){ if (d == 0){ return; } d->disconnect(this); disconnect(d); _graphVisualEditor->releaseDocument(); _GraphLayers->disconnect(d); d->engineBackend()->disconnect(this); d->engineBackend()->disconnect(_bottomTabs); } GraphScene* MainWindow::scene() const { return _graphVisualEditor->scene(); } void MainWindow::newGraph() { if (DocumentManager::self()->activeDocument() != 0){ if ( saveIfChanged() == KMessageBox::Cancel ) return; } loadDocument(); } void MainWindow::openGraph() { if ( saveIfChanged() == KMessageBox::Cancel ) return; QString fileName = KFileDialog::getOpenFileName ( QString(), i18n ( "*.graph|Graph files\n*|All files" ), this, i18n ( "Graph Files" ) ); if ( fileName == "" ) return; // ImporterExporterManager imp(this); // imp.openDocument(); loadDocument ( fileName ); } void MainWindow::loadDocument ( const QString& name ) { if ( !name.isEmpty() && !name.endsWith ( ".graph" ) ){ KMessageBox::sorry ( this, i18n ( "This does not seem to be a graph file." ), i18n ( "Invalid file" ) ); return; } DocumentManager::self()->loadDocument(name); } void MainWindow::saveGraph(){ Document *d = DocumentManager::self()->activeDocument(); if ( d->documentPath().isEmpty() ){ saveGraphAs(); }else{ d->savedDocumentAt ( d->documentPath() ); } } void MainWindow::saveGraphAs(){ Document *d = DocumentManager::self()->activeDocument(); if ( d == 0 ){ kDebug() << "Graph Document is NULL"; return; } d->saveAsInternalFormat ( KFileDialog::getSaveFileName() ); } void MainWindow::saveAll() { saveGraph(); _codeEditor->saveAllScripts(); } int MainWindow::saveIfChanged(){ if ( DocumentManager::self()->activeDocument()->isModified() && !_codeEditor->isModified() ){ const int btnCode = KMessageBox::warningYesNoCancel ( this, i18n ( "Changes on your graph document are unsaved. Do you want to save your changes?" ) ); if ( btnCode == KMessageBox::Yes ){ saveGraph(); } return btnCode; } if ( !DocumentManager::self()->activeDocument()->isModified() && _codeEditor->isModified() ){ const int btnCode = KMessageBox::warningYesNoCancel ( this, i18n ( "Changes on your script files are unsaved. Do you want to save all unsaved scripts?" ) ); if ( btnCode == KMessageBox::Yes ){ _codeEditor->saveAllScripts(); } return btnCode; } if ( DocumentManager::self()->activeDocument()->isModified() && _codeEditor->isModified() ){ const int btnCode = KMessageBox::warningYesNoCancel ( this, i18n ( "Changes on your script files and on your graph document are unsaved. Do you want to save your graph document and all unsaved scripts?" ) ); if ( btnCode == KMessageBox::Yes ){ _codeEditor->saveAllScripts(); saveGraph(); } return btnCode; } return KMessageBox::No; } void MainWindow::importFile(){ ImporterExporterManager importer(this); Document * gd = importer.importFile(); if (gd == 0){ return; } DocumentManager::self()->addDocument(gd); _graphVisualEditor->scene()->createItems(); if (importer.hasDialog()){ importer.dialogExec(); } if (!importer.scriptToRun().isEmpty()){ executeScript(importer.scriptToRun()); } } void MainWindow::exportFile() { ImporterExporterManager exp(this); exp.exportFile(DocumentManager::self()->activeDocument()); } void MainWindow::showPossibleIncludes() { PossibleIncludes dialog(this); dialog.exec(); } void MainWindow::runToolPlugin() { kDebug() << "seeking for a plugin"; QAction *action = qobject_cast ( sender() ); if (! action ){ return; } if (ToolsPluginInterface *plugin = PluginManager::instance()->toolPlugins().value(action->data().toInt()) ){ emit runTool ( plugin, DocumentManager::self()->activeDocument() ); } } void MainWindow::dsChanged(){ // kDebug() << "Data structure was changed, need to reload graphic part."; // setActiveDocument(); // QAction *action = qobject_cast ( sender() ); // // if (! action ){ // return; // } // DataStructurePluginInterface *plugin = DataStructurePluginManager::instance()->pluginsList().at(action->data().toInt() ); // // kDebug() << "Changed " << plugin->name(); } #ifdef USING_QTSCRIPT void MainWindow::executeScript(const QString& text) { kDebug() << "Going to execute the script"; if (_txtDebug == 0) return; if ( scene() == 0) return; _txtDebug->clear(); QString script = text.isEmpty() ? _codeEditor->text() : text; QString scriptPath = _codeEditor->document()->url().path(); - IncludeManager inc; - - script = inc.include(script, + QtScriptBackend *engine = DocumentManager::self()->activeDocument()->engineBackend(); + engine->includeManager().initialize(Settings::includePath()); + script = engine->includeManager().include(script, scriptPath.isEmpty()? scriptPath : scriptPath.section('/', 0, -2), _codeEditor->document()->documentName()); - QtScriptBackend *engine = DocumentManager::self()->activeDocument()->engineBackend(); if (engine->isRunning() ) { engine->stop(); } enableStopAction(); engine->setScript(script, DocumentManager::self()->activeDocument()); engine->start(); } void MainWindow::stopScript() { kDebug() << "Going to stop the script"; if (_txtDebug == 0) return; if ( scene() == 0) return; QtScriptBackend *engine = DocumentManager::self()->activeDocument()->engineBackend(); disableStopAction(); engine->stop(); } #endif void MainWindow::enableStopAction(){ _stopScript->setEnabled(true); } void MainWindow::disableStopAction(){ _stopScript->setEnabled(false); } void MainWindow::showDebugOutput() { _selectListing->setCurrentIndex(1); } void MainWindow::outputString ( const QString& s ) { _txtOutput->append ( s ); } void MainWindow::debugString ( const QString& s ) { _txtDebug->append ( s ); } diff --git a/src/Scripts/IncludeManager.cpp b/src/Scripts/IncludeManager.cpp index 4afecbf7..9fa223a9 100644 --- a/src/Scripts/IncludeManager.cpp +++ b/src/Scripts/IncludeManager.cpp @@ -1,189 +1,202 @@ /* This file is part of Rocs. Copyright 2010-2011 Wagner Reck This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "IncludeManager.h" #include #include #include #include #include -#include #include #include IncludeManager::IncludeManager() { addPath(KGlobal::dirs()->findDirs("appdata", "examples")); - QStringList list = Settings::includePath(); - - while(!list.isEmpty()){ - addPath(list.last()); - list.removeLast(); - } +// QStringList list = Settings::includePath(); +// +// while(!list.isEmpty()){ +// addPath(list.last()); +// list.removeLast(); +// } // kDebug() << _tempPath; } +void IncludeManager::initialize(const QStringList& tempPath) +{ + _tempPath.clear(); + _wasIncluded.clear(); + + addPath(KGlobal::dirs()->findDirs("appdata", "examples")); + addPath(tempPath); +} QString IncludeManager::include ( const QString& script, const QString& actualPath, const QString &filename) { int pos; bool inComment = false; if (!actualPath.isEmpty()) { _actualDir = QDir(actualPath); // try the path of saved file _tempPath << _actualDir; if (!seekFile(filename).isNull()){ _wasIncluded << seekFile(filename); } } else { if (!_tempPath.isEmpty()) { _actualDir = _tempPath.last(); // not disponible the path to saved file, use the first path from list } else { _actualDir = QDir(); //No path in list? use application path! } } QStringList lines = script.split('\n'); for (int i = 0; i < lines.count(); ++i) { if (lines[i].indexOf("//") != -1) { /*lines[i] = */ lines[i].truncate(lines[i].indexOf("//"));//Ignores after '//' } if (inComment){ if ((pos = lines[i].indexOf("*/")) != -1 ){ lines[i].remove(0, pos+2); inComment = false; }else{ lines.removeAt(i); --i; continue; } } while ((pos = lines[i].indexOf("/*")) != -1) { int pos2; if ((pos2 = lines[i].indexOf("*/", pos+2)) != -1 ){ lines[i].remove(pos, pos2-pos + 2); }else{ lines[i].remove(pos, lines[i].count()); inComment = true; } } if (lines[i].isEmpty()){ lines.removeAt(i); --i; continue; } QRegExp reg("^\\s*include\\s*\\(\\s*.*.js\\s*\\)"); if (lines[i].indexOf(reg)!= -1) { QString ret = processInclude(reg.cap()); lines[i].replace(reg.cap(),ret); } } QString str = lines.join("\n"); return str; } QString IncludeManager::processInclude ( QString arg1 ) { QString fileContent; QString file; int pos; QString path; if (arg1.indexOf('(') != -1) { file=arg1.replace(')', '(').section('(',1,1).trimmed(); // To avoid more ifs-elses fileContent = QString("debug(\"%1\")").arg(i18n("Cannot open file %2.", file)); // Add the path first if ((pos = file.lastIndexOf('/')) != -1) { //add the path of file to list path = file.left(pos+1); // QString filename = file.right(file.length() - pos +1); if (!path.startsWith(QDir::rootPath())) { path.prepend(_actualDir.absolutePath() + '/'); } _tempPath << QDir(path); } // then, try to open if (!_actualDir.exists(file)) { file = seekFile(file); }else file = _actualDir.absoluteFilePath(file); if ( !file.isEmpty() ) { if ( !checkIfWasIncluded ( file ) ) { _wasIncluded << file; QFile fp ( file ); if ( fp.open ( QFile::ReadOnly|QFile::Text ) ) { fileContent = fp.readAll(); fileContent = include ( fileContent ); } } else { return QString(); } } } else { fileContent = QString("debug(\"%1\")").arg(i18n("Invalid include directive: %1. Cannot find file in directive.",arg1)); } return fileContent; } QString IncludeManager::seekFile ( const QString & arg1 ) { if (arg1.isEmpty()){ return QString(); } + if (arg1.indexOf('/') != -1 ){ + QDir dir (arg1.section('/', 0, -2)); + if (dir.isAbsolute() && dir.exists(arg1)) + return arg1; + } + for (int count = _tempPath.count() - 1; count >= 0; -- count) { if (_tempPath.at(count).exists(arg1.trimmed())) { return _tempPath.at(count).absoluteFilePath(arg1.trimmed()); } } return QString(); } void IncludeManager::addPath(const QString& str) { QString tmp = !str.endsWith('/')? str + '/': str; if (!tempPath().contains(tmp)){ _tempPath << QDir(tmp); } } void IncludeManager::addPath ( const QStringList& str ) { foreach (const QString &s, str ) { QDir dir(s); if ( !_tempPath.contains ( dir ) ) { _tempPath.append ( dir ); } } } QStringList const IncludeManager::tempPath() const { QStringList list; foreach (const QDir &dir, _tempPath) { list << dir.path() + '/'; } return list; } diff --git a/src/Scripts/IncludeManager.h b/src/Scripts/IncludeManager.h index 8bd4476a..afbec770 100644 --- a/src/Scripts/IncludeManager.h +++ b/src/Scripts/IncludeManager.h @@ -1,56 +1,61 @@ /* This file is part of Rocs. Copyright 2010 Wagner Reck This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef INCLUDEMANAGER_H #define INCLUDEMANAGER_H #include #include #include #include "rocslib_export.h" class ROCSLIB_EXPORT IncludeManager { private: QList _tempPath; QString processInclude ( QString arg1 ); - QString seekFile ( const QString& arg1 ); QStringList _wasIncluded; QDir _actualDir; public: IncludeManager(); ~IncludeManager(){ } QString include(const QString& script, const QString& actualPath = QString(), const QString& filename = QString()); QStringList const tempPath() const; /** check if the file was included before. It's avoid cyclic includes. filename should be path to file not only the name of file. */ bool checkIfWasIncluded(const QString &file){ - return _wasIncluded.contains(file); + return _wasIncluded.contains(file); } + /** @brief Try find the fileName in the paths' list. If found, returns an absolute path to the file, otherwise return QString(). + * In the case of fileName be a absolute path to file, the fileName is returned. + */ + QString seekFile ( const QString& arg1 ); /** insert aditional path to seek files.*/ void addPath(const QString& str); void addPath(const QStringList & str); + void initialize(const QStringList& tempPath = QStringList()); + }; #endif // INCLUDEMANAGER_H