diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h index a48818af4eb3f6b3e71a3cd345f06cd37891ffd1..73e522f4254611c6e70228ae9d8ee81ddd79a99f 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h @@ -120,6 +120,8 @@ namespace Mantid std::string getString(const std::string& keyName, bool use_cache=true) const; /// Searches for a key in the configuration property std::vector<std::string> getKeys(const std::string& keyName) const; + /// Launches a process i.e opening a program + void ConfigServiceImpl::launchProcess(const std::string& programFilePath, const std::vector<std::string>& programArguments) const; /// Sets a configuration property void setString(const std::string & keyName, const std::string & keyValue); // Searches for a configuration property and returns its value diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp index f1cd69188b7b2ca18ddef85814687212b9a47421..da2ebe3cb02cc51b66404fe8d219b591dff843dc 100644 --- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp +++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp @@ -23,6 +23,7 @@ #include <Poco/DOM/NodeList.h> #include <Poco/Notification.h> #include <Poco/Environment.h> +#include <Poco/Process.h> #include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/join.hpp> @@ -784,6 +785,8 @@ void ConfigServiceImpl::saveConfig(const std::string & filename) const writer.close(); } + + /** Searches for a string within the currently loaded configuaration values and * returns the value as a string. If the key is one of those that was a possible relative path * then the local store is searched first. @@ -836,6 +839,26 @@ std::vector<std::string> ConfigServiceImpl::getKeys(const std::string& keyName) return keyVector; } +/** Runs a command line string to open a program. The function can take program arguments. + * i.e it can load in a file to the program on startup. + * + * @param programFilePath :: The directory where the program is located. + * @param programArguments :: The arguments that the program can take on startup. For example, + * the file to load up. + */ + +void ConfigServiceImpl::launchProcess(const std::string& programFilePath, const std::vector<std::string>& programArguments) const +{ + try + { + Poco::Process::launch(programFilePath, programArguments); + } + catch(Poco::SystemException &e) + { + throw std::runtime_error(e.what()); + } +} + /** * Set a configuration property. An existing key will have its value updated. * @param key :: The key to refer to this property diff --git a/Code/Mantid/Framework/Properties/MantidTest.properties b/Code/Mantid/Framework/Properties/MantidTest.properties index d95d88f40ead6c7b1dc46d601d74f8544682304c..0e5808fb5095e0b0bc20a3815ee6488bffb7434f 100644 --- a/Code/Mantid/Framework/Properties/MantidTest.properties +++ b/Code/Mantid/Framework/Properties/MantidTest.properties @@ -20,5 +20,4 @@ defaultsave.directory = ../../nonexistent workspace.sendto.1 = python,SaveNexus workspace.sendto.2 = gsas,SaveGSS workspace.sendto.3 = SansView,SaveCansas1D -workspace.sendto.4.5 = SansView,SaveCansas1D - +workspace.sendto.4.5 = SansView,SaveCansas1D \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index 33fd62a73e506c12eedd64495e9eb1cc00a19e1b..38e6d68c3a709caa7fb6241b0597727cd77349d9 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -3958,8 +3958,8 @@ void ApplicationWindow::importASCII(const QStringList& files, int import_mode, c case ImportASCIIDialog::NewWorkspace: { try - { - Mantid::API::IAlgorithm_sptr alg =mantidUI->CreateAlgorithm("LoadAscii"); + {///////////////////////////////////////////////////////////////// + Mantid::API::IAlgorithm_sptr alg =mantidUI->createAlgorithm("LoadAscii"); QStringList sorted_files = files; sorted_files.sort(); for (int i=0; i<sorted_files.size(); i++){ @@ -6160,8 +6160,8 @@ void ApplicationWindow::exportASCII(const QString& tableName, const QString& sep { //call save ascii try - { - Mantid::API::IAlgorithm_sptr alg =mantidUI->CreateAlgorithm("SaveAscii"); + {//////////////////////////////////////////////////// + Mantid::API::IAlgorithm_sptr alg =mantidUI->createAlgorithm("SaveAscii"); alg->setPropertyValue("Filename",fname.toStdString()); alg->setPropertyValue("Workspace",tableName.toStdString()); alg->execute(); diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp index b251595b07c108b12ad090f3f5e7c2c3a55d4b09..b98e8a0c7d921ee3864947bef6448e26d461a0c0 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp @@ -7,6 +7,7 @@ #include <MantidAPI/IEventWorkspace.h> #include <MantidAPI/IMDEventWorkspace.h> #include <MantidAPI/IMDWorkspace.h> +#include <MantidAPI/FileProperty.h> #include <MantidGeometry/MDGeometry/IMDDimension.h> #include "MantidMatrix.h" #include <QInputDialog> @@ -25,6 +26,7 @@ #include <QtGui> #include <map> +#include <vector> #include <iostream> #include <sstream> @@ -67,6 +69,7 @@ QDockWidget(tr("Workspaces"),parent), m_mantidUI(mui), m_known_groups() // m_loadMenu = new QMenu(this); + QAction* loadFileAction = new QAction("File",this); QAction *loadDAEAction = new QAction("from DAE",this); m_loadMapper = new QSignalMapper(this); @@ -232,6 +235,16 @@ void MantidDockWidget::createWorkspaceMenuActions() m_saveNexus = new QAction(tr("Save Nexus"),this); connect(m_saveNexus,SIGNAL(activated()),m_mantidUI,SLOT(saveNexusWorkspace())); + //m_saveToProgram = new QMenu(tr("Save to program"),this); + + ////Sub-menu of save to programs + //m_program1 = new QAction(tr("Program 1"),this); + //connect(m_program1,SIGNAL(activated()),this,SLOT(saveToProgram1())); + //m_program2 = new QAction(tr("Program 2"),this); + //connect(m_program2,SIGNAL(activated()),this,SLOT(saveToProgram2())); + //m_program3 = new QAction(tr("Program 3"),this); + //connect(m_program3,SIGNAL(activated()),this,SLOT(saveToProgram3())); + m_rename = new QAction(tr("Rename"),this); connect(m_rename,SIGNAL(activated()),this,SLOT(renameWorkspace())); @@ -779,6 +792,124 @@ void MantidDockWidget::deleteWorkspaces() }//end of for loop for selected items } +/** +* Saves a workspace based on the program the user chooses to save to. +* @param programSave :: A string containing the name of the program +*/ + +void MantidDockWidget::saveToProgram(const QString & name) +{ + //Create a map for the keys and details to go into + std::map<std::string,std::string> programKeysAndDetails; + programKeysAndDetails["name"] = name.toStdString(); + + //Could use a standard vector but no #include <vector> + //Get a list of the program detail keys (mandatory - target, saveusing) (optional - arguments, save parameters, workspace type) + std::vector<std::string> programKeys = (Mantid::Kernel::ConfigService::Instance().getKeys(("workspace.sendto." + programKeysAndDetails.find("name")->second))); + + for (int i(0); i<programKeys.size(); i++) + { + //Assign a key to its value using the map + programKeysAndDetails[programKeys[i]] = (Mantid::Kernel::ConfigService::Instance().getString(("workspace.sendto." + programKeysAndDetails.find("name")->second + "." + programKeys[i]))); + } + + //Check to see if mandatory information is included + if ((programKeysAndDetails.count("name") != 0) && (programKeysAndDetails.count("target") != 0) && (programKeysAndDetails.count("saveusing") != 0)) + { + QFileInfo target = QString::fromStdString(programKeysAndDetails.find("target")->second); + if(target.exists()) + { + //Setup a shared pointer for the algorithm using the appropriate save type + Mantid::API::IAlgorithm_sptr alg; + + //Convert to QString and create Algorithm + QString saveUsing = QString::fromStdString(programKeysAndDetails.find("saveusing")->second); + + //Create a new save based on what files the new program can open + alg = m_mantidUI->createAlgorithm(saveUsing); + + //Get the file extention based on the workspace + Property* prop = alg->getProperty("Filename"); + FileProperty *fileProp = dynamic_cast<FileProperty*>(prop); + std::string ext; + if(fileProp) + { + ext = fileProp->getDefaultExt(); + } + + //Save as.. default save + the file type i.e .nxs + alg->setPropertyValue("fileName", "auto_save_" + selectedWsName.toStdString() + ext); + + //Save the workspace + alg->setPropertyValue("InputWorkspace", selectedWsName.toStdString()); + + //If there are any save parameters + if (programKeysAndDetails.count("saveparameters") != 0) + { + QString saveParametersGrouped = QString::fromStdString(programKeysAndDetails.find("saveparameters")->second); + QStringList saveParameters = saveParametersGrouped.split(','); + + //For each one found split it up and assign the parameter + for (int i(0); i<saveParameters.size(); i++) + { + QStringList saveParameterDetails = saveParameters[i].split('='); + std::string saveParameterName = saveParameterDetails[0].toStdString(); + + if(saveParameterDetails[1] == "True") + alg->setProperty(saveParameterName, true); + else if(saveParameterDetails[1] == "False") + alg->setProperty(saveParameterName, false); + else //if not true or false then must be a value + { + alg->setPropertyValue(saveParameterName, saveParameterDetails[1].toStdString()); + } + } + } + + //Execute the save + m_mantidUI->executeAlgorithmAsync(alg, true); + //alg->execute(); + + //Get the save location of the file (should be default Mantid folder) + //std::string savedFile = alg->getProperty("Filename"); + QString savedFile = QString::fromStdString(alg->getProperty("Filename")); + QStringList arguments; + + //Arguments for the program to take. Default will be the file anyway. + if (programKeysAndDetails.count("arguments") != 0) + { + QString temp = QString::fromStdString(programKeysAndDetails.find("arguments")->second); + temp.replace(QString("[File]"), savedFile); + //temp.replace(QString("[User]"), user; + arguments = temp.split(","); + } + else + arguments.insert(0, savedFile); + + //convert the list into a standard vector for compatibility with Poco + std::vector<std::string> argumentsV; + + for (int i(0); i<arguments.size(); i++) + { + argumentsV.assign(1, (arguments[i].toStdString())); + } + + //Execute the program + try + { + Mantid::Kernel::ConfigService::Instance().launchProcess(programKeysAndDetails.find("target")->second, argumentsV); + } + catch(std::runtime_error&) + { + QMessageBox::information(this, "Error", "User tried to open program from: " + QString::fromStdString(programKeysAndDetails.find("target")->second) + " There was an error opening the program. Please check the target and arguments list to ensure that these are correct"); + } + } + else + QMessageBox::information(this, "Target Path Error", "User tried to open program from: " + QString::fromStdString(programKeysAndDetails.find("target")->second) + " The target file path for the program can't be found. Please check that the full path is correct"); + } +} + + void MantidDockWidget::renameWorkspace() { //get selected workspace @@ -806,7 +937,7 @@ void MantidDockWidget::showDetectorTable() void MantidDockWidget::popupMenu(const QPoint & pos) { QTreeWidgetItem* treeItem = m_tree->itemAt(pos); - QString selectedWsName(""); + selectedWsName = ""; if( treeItem ) selectedWsName = treeItem->text(0); else m_tree->selectionModel()->clear(); QMenu *menu(NULL); @@ -851,6 +982,30 @@ void MantidDockWidget::popupMenu(const QPoint & pos) } else {} + //Get the names of the programs for the send to option + std::vector<std::string> programNames = (Mantid::Kernel::ConfigService::Instance().getKeys("workspace.sendto.name")); + if (programNames.size() > 0) + { + m_saveToProgram = new QMenu(tr("Send to"),this); + menu->addMenu(m_saveToProgram); + + //Sub-menu for program list + m_programMapper = new QSignalMapper(this); + + for (int i(0); i<programNames.size(); i++) + { + //Convert name from std string to QString for use with QAction menu entry + QString name = QString::fromStdString(programNames[i]); + //Setup new menu option for the program + m_program = new QAction(tr(name),this); + connect(m_program,SIGNAL(activated()),m_programMapper,SLOT(map())); + //Send name of program when clicked + m_programMapper->setMapping(m_program, name); + m_saveToProgram->addAction(m_program); + } + + connect(m_programMapper, SIGNAL(mapped(const QString &)), this, SLOT(saveToProgram(const QString &))); + } //Rename is valid for all workspace types menu->addAction(m_rename); //separate delete @@ -1386,5 +1541,4 @@ void AlgorithmTreeWidget::mouseDoubleClickEvent(QMouseEvent *e) } QTreeWidget::mouseDoubleClickEvent(e); -} - +} \ No newline at end of file diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.h b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.h index 9af4889403eb26a1013a3f991446d0b41ed0c1d4..24c34281fb7745e9737c36dc74f0a4dd05a0d479 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.h +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.h @@ -37,6 +37,7 @@ public slots: void deleteWorkspaces(); void renameWorkspace(); void populateChildData(QTreeWidgetItem* item); + void saveToProgram(const QString & name); protected slots: void popupMenu(const QPoint & pos); @@ -77,18 +78,20 @@ protected: friend class MantidUI; private: + QString selectedWsName; + MantidUI * const m_mantidUI; QSet<QString> m_known_groups; QPushButton *m_loadButton; - QMenu *m_loadMenu; + QMenu *m_loadMenu, *m_saveToProgram; QPushButton *m_deleteButton; QPushButton *m_groupButton; - QSignalMapper *m_loadMapper; + QSignalMapper *m_loadMapper, *m_programMapper; //Context-menu actions QAction *m_showData, *m_showInst, *m_plotSpec, *m_plotSpecDistr, *m_showDetectors, *m_colorFill, *m_showLogs, *m_showHist, - *m_saveNexus, *m_rename, *m_delete; + *m_saveNexus, *m_rename, *m_delete, *m_program; static Mantid::Kernel::Logger& logObject; }; diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidMatrix.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidMatrix.cpp index 524335a009ef72ddbbb677d743d4761b6b1ec588..927d1ac1b1ebc1684b2c5989ad5d6daed95f02a4 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidMatrix.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidMatrix.cpp @@ -1106,7 +1106,7 @@ bool MantidMatrix::setSelectedColumns() QTableView *tv = activeView(); QItemSelectionModel *selModel = tv->selectionModel(); if( !selModel || !selModel->hasSelection()) return false; - + m_selectedCols.clear(); const QModelIndexList cols = selModel->selectedColumns(); QModelIndexList::const_iterator it; diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp index bbc45aa73297da1f57cc7be463bd58e7daca6b75..f2c04a12d8e9b1c70455fd51533010d7440e6816 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.cpp @@ -290,19 +290,6 @@ int MantidUI::runningAlgCount() const return m_algMonitor->count(); } -/** - CreateAlgorithm - - @param algName :: Algorithm's name - @return Pointer to the created algorithm - */ -IAlgorithm_sptr MantidUI::CreateAlgorithm(const QString& algName) -{ - IAlgorithm_sptr alg = AlgorithmManager::Instance().create(algName.toStdString()); - - return alg; -} - /** * Ticket #678 */ @@ -821,30 +808,11 @@ void MantidUI::executeAlgorithm() bool MantidUI::runAlgorithmAsync_PyCallback(const QString & alg_name) { Mantid::API::IAlgorithm_sptr alg = findAlgorithmPointer(alg_name); - if( !alg ) { return false; } - if( m_algMonitor ) - { - m_algMonitor->add(alg); - } - Poco::ActiveResult<bool> result(alg->executeAsync()); - while( !result.available() ) - { - QCoreApplication::processEvents(); - } - result.wait(); - - try - { - return result.data(); - } - catch( Poco::NullPointerException& ) - { - return false; - } + return executeAlgorithmAsync(alg, true); } /** @@ -1263,19 +1231,38 @@ Mantid::API::IAlgorithm_sptr MantidUI::createAlgorithm(const QString& algName, i return alg; } -void MantidUI::executeAlgorithmAsync(Mantid::API::IAlgorithm_sptr alg) +bool MantidUI::executeAlgorithmAsync(Mantid::API::IAlgorithm_sptr alg, const bool wait) { - m_algMonitor->add(alg); + if( m_algMonitor ) + { + m_algMonitor->add(alg); + } - try + if( wait ) { - alg->executeAsync(); + Poco::ActiveResult<bool> result(alg->executeAsync()); + while( !result.available() ) + { + QCoreApplication::processEvents(); + } + result.wait(); + + try + { + return result.data(); + } + catch( Poco::NullPointerException& ) + { + return false; + } } - catch(...) + else { - QMessageBox::critical(appWindow(),"MantidPlot - Algorithm error","Exception is caught"); + alg->executeAsync(); + return true; } } + bool MantidUI::executeICatLogout(int version) { Mantid::API::IAlgorithm_sptr alg = this->createAlgorithm("CatalogLogout", version); @@ -1369,7 +1356,7 @@ void MantidUI::createLoadDAEMantidMatrix(const QString& wsQName) int updateInterval = m_DAE_map[wsName]; if (updateInterval > 0) { - IAlgorithm_sptr updater = CreateAlgorithm("UpdateDAE"); + IAlgorithm_sptr updater = createAlgorithm("UpdateDAE"); updater->setPropertyValue("Workspace",wsName); updater->setPropertyValue("UpdateRate",QString::number(updateInterval).toStdString()); executeAlgorithmAsync(updater); @@ -2710,7 +2697,7 @@ void MantidUI::savedatainNexusFormat(const std::string& fileName,const std::stri { try { - Mantid::API::IAlgorithm_sptr alg =CreateAlgorithm("SaveNexusProcessed"); + Mantid::API::IAlgorithm_sptr alg =createAlgorithm("SaveNexusProcessed"); alg->setPropertyValue("Filename",fileName); alg->setPropertyValue("InputWorkspace",wsName); alg->execute(); @@ -2728,7 +2715,7 @@ void MantidUI::loaddataFromNexusFile(const std::string& wsName,const std::string if(fileName.empty()) return ; try { - Mantid::API::IAlgorithm_sptr alg =CreateAlgorithm("LoadNexus"); + Mantid::API::IAlgorithm_sptr alg =createAlgorithm("LoadNexus"); alg->setPropertyValue("Filename",fileName); alg->setPropertyValue("OutputWorkspace",wsName); if(project)alg->execute(); @@ -2747,7 +2734,7 @@ void MantidUI::loadadataFromRawFile(const std::string& wsName,const std::string& if(fileName.empty()) return ; try { - Mantid::API::IAlgorithm_sptr alg =CreateAlgorithm("LoadRaw"); + Mantid::API::IAlgorithm_sptr alg =createAlgorithm("LoadRaw"); alg->setPropertyValue("Filename",fileName); alg->setPropertyValue("OutputWorkspace",wsName); if(project)alg->execute(); diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h index 9a9d1e8428b4a5ba16d18595b4662bd784246736..5617800a0eafa29ae67cdc88d22877dddcb43411 100644 --- a/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h +++ b/Code/Mantid/MantidPlot/src/Mantid/MantidUI.h @@ -124,7 +124,11 @@ public: int runningAlgCount() const; // Create an algorithm using Mantid FrameworkManager - Mantid::API::IAlgorithm_sptr CreateAlgorithm(const QString& algName); + // Create a pointer to the named algorithm and version + Mantid::API::IAlgorithm_sptr createAlgorithm(const QString& algName, int version = -1); + + // Execute algorithm asinchronously + bool executeAlgorithmAsync(Mantid::API::IAlgorithm_sptr alg, const bool wait = false); // Gets a pointer to workspace workspaceName Mantid::API::Workspace_sptr getWorkspace(const QString& workspaceName); @@ -415,11 +419,6 @@ public: private: -// Create a pointer to the named algorithm and version - Mantid::API::IAlgorithm_sptr createAlgorithm(const QString& algName, int version); - // Execute algorithm asinchronously - void executeAlgorithmAsync(Mantid::API::IAlgorithm_sptr alg); - // Notification handlers and corresponding observers. void handleLoadDAEFinishedNotification(const Poco::AutoPtr<Mantid::API::Algorithm::FinishedNotification>& pNf); Poco::NObserver<MantidUI, Mantid::API::Algorithm::FinishedNotification> m_finishedLoadDAEObserver;