Skip to content
Snippets Groups Projects
ApplicationWindow.cpp 571 KiB
Newer Older
/***************************************************************************
	File                 : ApplicationWindow.cpp
	Project              : QtiPlot
--------------------------------------------------------------------
	Copyright            : (C) 2006 by Ion Vasilief,
	                       Tilman Hoener zu Siederdissen,
                           Knut Franke
	Email (use @ for *)  : ion_vasilief*yahoo.fr, thzs*gmx.net,
	                       knut.franke*gmx.de
	Description          : QtiPlot's main window

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *  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, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
 *   Boston, MA  02110-1301  USA                                           *
 *                                                                         *
 ***************************************************************************/
#include "globals.h"
#include "ApplicationWindow.h"
#include "pixmaps.h"
#include "CurvesDialog.h"
#include "PlotDialog.h"
#include "AxesDialog.h"
#include "LineDialog.h"
#include "TextDialog.h"
#include "ExportDialog.h"
#include "TableDialog.h"
#include "SetColValuesDialog.h"
#include "ErrDialog.h"
#include "LegendWidget.h"
#include "ArrowMarker.h"
#include "ImageMarker.h"
#include "Graph.h"
#include "Plot.h"
#include "Grid.h"
#include "PlotWizard.h"
#include "PolynomFitDialog.h"
#include "ExpDecayDialog.h"
#include "FunctionDialog.h"
#include "FitDialog.h"
#include "SurfaceDialog.h"
#include "Graph3D.h"
#include "Plot3DDialog.h"
#include "ImageDialog.h"
#include "MultiLayer.h"
#include "LayerDialog.h"
#include "DataSetDialog.h"
#include "IntDialog.h"
#include "ConfigDialog.h"
#include "MatrixDialog.h"
#include "MatrixSizeDialog.h"
#include "MatrixValuesDialog.h"
#include "MatrixModel.h"
#include "MatrixCommand.h"
#include "importOPJ.h"
#include "AssociationsDialog.h"
#include "RenameWindowDialog.h"
#include "QwtErrorPlotCurve.h"
#include "InterpolationDialog.h"
#include "ImportASCIIDialog.h"
#include "ImageExportDialog.h"
#include "SmoothCurveDialog.h"
#include "FilterDialog.h"
#include "FFTDialog.h"
#include "Note.h"
#include "Folder.h"
#include "FindDialog.h"
#include "ScaleDraw.h"
#include "plot2D/ScaleEngine.h"
#include "ScriptingLangDialog.h"
#include "ScriptingWindow.h"
#include "ScriptFileInterpreter.h"
#include "TableStatistics.h"
#include "Fit.h"
#include "MultiPeakFit.h"
#include "PolynomialFit.h"
#include "SigmoidalFit.h"
#include "LogisticFit.h"
#include "NonLinearFit.h"
#include "FunctionCurve.h"
#include "QwtPieCurve.h"
#include "Spectrogram.h"
#include "Integration.h"
#include "Differentiation.h"
#include "SmoothFilter.h"
#include "FFTFilter.h"
#include "Convolution.h"
#include "Correlation.h"
#include "CurveRangeDialog.h"
#include "ColorBox.h"
#include "QwtHistogram.h"
#include "OpenProjectDialog.h"
#include "ColorMapDialog.h"
#include "TextEditor.h"
#include "SymbolDialog.h"
#include "CustomActionDialog.h"
#include "MdiSubWindow.h"
#include "FloatingWindow.h"
#include "DataPickerTool.h"

// TODO: move tool-specific code to an extension manager
#include "ScreenPickerTool.h"
#include "TranslateCurveTool.h"
#include "MultiPeakFitTool.h"
#include "LineProfileTool.h"
#include "RangeSelectorTool.h"
#include "PlotToolInterface.h"
#include "Mantid/MantidMatrix.h"
#include "Mantid/MantidTable.h"
#include "Mantid/MantidMatrixCurve.h"
#include "ContourLinesEditor.h"
#include "Mantid/InstrumentWidget/InstrumentWindow.h"
#include "Mantid/RemoveErrorsDialog.h"

#include <stdio.h>
#include <stdlib.h>

#include <qwt_scale_engine.h>
#include <QFileDialog>
#include <QInputDialog>
#include <QProgressDialog>
#include <QPrintDialog>
#include <QPixmapCache>
#include <QMenuBar>
#include <QClipboard>
#include <QTranslator>
#include <QSplitter>
#include <QSettings>
#include <QApplication>
#include <QMessageBox>
#include <QPrinter>
#include <QPrinterInfo>
#include <QActionGroup>
#include <QAction>
#include <QToolBar>
#include <QKeySequence>
#include <QImageReader>
#include <QImageWriter>
#include <QDateTime>
#include <QShortcut>
#include <QDockWidget>
#include <QTextStream>
#include <QVarLengthArray>
#include <QList>
#include <QUrl>
#include <QFontComboBox>
#include <QSpinBox>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QSignalMapper>
#include <QDesktopWidget>
#include <QtAlgorithms>
#include <zlib.h>

#include <gsl/gsl_sort.h>

#include <boost/regex.hpp>
#include <boost/scoped_ptr.hpp>
//Mantid
#include "ScriptingWindow.h"

#include "Mantid/MantidUI.h"
#include "Mantid/MantidAbout.h"
#include "Mantid/PeakPickerTool.h"
#include "Mantid/ManageCustomMenus.h"
#include "Mantid/ManageInterfaceCategories.h"
#include "Mantid/FirstTimeSetup.h"
#include "Mantid/SetUpParaview.h"
#include "MantidQtAPI/FileDialogHandler.h"
#include "MantidQtAPI/InterfaceManager.h"
#include "MantidQtAPI/UserSubWindow.h"
#include "MantidQtAPI/AlgorithmInputHistory.h"
#include "MantidQtAPI/ManageUserDirectories.h"
#include "MantidQtAPI/Message.h"
#include "MantidQtMantidWidgets/CatalogSearch.h"
#include "MantidQtMantidWidgets/FitPropertyBrowser.h"
#include "MantidQtMantidWidgets/MessageDisplay.h"
#include "MantidQtMantidWidgets/MuonFitPropertyBrowser.h"

#include "MantidKernel/ConfigService.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/MantidVersion.h"

#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAPI/AlgorithmFactory.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/AnalysisDataService.h"

#include "MantidQtAPI/ScriptRepositoryView.h"

using namespace Qwt3D;
using namespace MantidQt::API;

extern "C"
{
void file_compress(const char  *file, const char  *mode);
void file_uncompress(const char  *file);
}

ApplicationWindow::ApplicationWindow(bool factorySettings)
: QMainWindow(), 
Scripted(ScriptingLangManager::newEnv(this)),
blockWindowActivation(false),
m_enableQtiPlotFitting(false),
m_exitCode(0), g_log(Mantid::Kernel::Logger::get("ApplicationWindow")),
#ifdef Q_OS_MAC // Mac
  settings(QSettings::IniFormat, QSettings::UserScope, "Mantid", "MantidPlot")
#else
  settings("Mantid", "MantidPlot")
  QStringList empty;
  init(factorySettings, empty);
}

ApplicationWindow::ApplicationWindow(bool factorySettings, const QStringList& args)
: QMainWindow(), 
Scripted(ScriptingLangManager::newEnv(this)),
blockWindowActivation(false),
m_enableQtiPlotFitting(false),
m_exitCode(0), g_log(Mantid::Kernel::Logger::get("ApplicationWindow")),
#ifdef Q_OS_MAC // Mac
  settings(QSettings::IniFormat, QSettings::UserScope, "Mantid", "MantidPlot")
  settings("Mantid", "MantidPlot")
#endif
{
  init(factorySettings, args);
/**
 * This function is responsible for copying the old configuration
 * information from the ISIS\MantidPlot area to the new Mantid\MantidPlot
 * area. The old area is deleted once the trnasfer is complete. On subsequent
 * runs, if the old configuration area is missing or empty, the copying
 * is ignored.
 */
void ApplicationWindow::handleConfigDir()
{
#ifdef Q_OS_WIN
  // We use the registry for settings on Windows
  QSettings oldSettings("ISIS", "MantidPlot");
  QStringList keys = oldSettings.allKeys();
  // If the keys are empty, we removed the MantidPlot entries
  if (!keys.empty())
  {
    foreach (QString key, keys)
    {
	    settings.setValue(key, oldSettings.value(key));
    }
    // This unfortunately cannot remove the top-level entry
    oldSettings.remove("");
  }
#else
  QFileInfo curConfig(settings.fileName());
  QString oldPath = settings.fileName();
  oldPath.replace("Mantid", "ISIS");
  QFileInfo oldConfig(oldPath);

  // If the old config directory exists, copy it's contents and
  // then delete it
  QDir oldConfigDir = oldConfig.dir();
  if (oldConfigDir.exists())
  {
    QStringList entries = oldConfigDir.entryList();
    foreach ( QString entry, entries )
    {
      if (!entry.startsWith("."))
      {
        QFileInfo oldFile(oldConfig.dir(), entry);
        QFileInfo newFile(curConfig.dir(), entry);
        // Qt will not overwrite files, so remove new one first
        QFile::remove(newFile.filePath());
        QFile::copy(oldFile.filePath(), newFile.filePath());
        QFile::remove(oldFile.filePath());
      }
    }
    oldConfigDir.rmdir(oldConfig.path());
  }
/**
 * Calls QCoreApplication::exit(m_exitCode)
 */
void ApplicationWindow::exitWithPresetCode()
{
  QCoreApplication::exit(m_exitCode);
void ApplicationWindow::init(bool factorySettings, const QStringList& args)
  QCoreApplication::setOrganizationName("Mantid");
  QCoreApplication::setApplicationName("MantidPlot");
  setAttribute(Qt::WA_DeleteOnClose);

  #ifdef SHARED_MENUBAR
  m_sharedMenuBar = new QMenuBar(NULL);
  m_sharedMenuBar->setNativeMenuBar(true);
#endif
  setWindowTitle(tr("MantidPlot - untitled"));//Mantid
  setObjectName("main application");
  initGlobalConstants();
  QPixmapCache::setCacheLimit(20*QPixmapCache::cacheLimit ());

  // Logging as early as possible
  logWindow = new QDockWidget(this);
  logWindow->hide();
  logWindow->setObjectName("logWindow"); // this is needed for QMainWindow::restoreState()
  logWindow->setWindowTitle(tr("Results Log"));
  addDockWidget( Qt::TopDockWidgetArea, logWindow );
  using MantidQt::MantidWidgets::MessageDisplay;
  using MantidQt::API::Message;
  qRegisterMetaType<Message>("Message"); // Required to use it in signals-slots
  resultsLog = new MessageDisplay(MessageDisplay::EnableLogLevelControl, logWindow);
  logWindow->setWidget(resultsLog);
  connect(resultsLog, SIGNAL(errorReceived(const QString &)), logWindow, SLOT(show()));
  // Start Mantid
  // Set the Paraview path BEFORE libaries are loaded. Doing it here prevents
  // the logs being poluted with library loading errors.
  trySetParaviewPath(args);
  using Mantid::Kernel::ConfigService;
  ConfigService::Instance(); // Starts logging
  resultsLog->attachLoggingChannel(); // Must be done after logging starts
  using Mantid::API::FrameworkManager;
  FrameworkManager::Instance(); // Starts logging
  // Create UI object
  mantidUI = new MantidUI(this);

  // Everything else...
  tablesDepend = new QMenu(this);
  explorerWindow = new QDockWidget( this );
  explorerWindow->setWindowTitle(tr("Project Explorer"));
  explorerWindow->setObjectName("explorerWindow"); // this is needed for QMainWindow::restoreState()
  explorerWindow->setMinimumHeight(150);
  addDockWidget( Qt::BottomDockWidgetArea, explorerWindow );

  actionSaveFile=NULL;
  actionSaveProject=NULL;
  folders = new FolderListView(this);
  folders->header()->setClickEnabled( false );
  folders->addColumn( tr("Folder") );
  folders->setRootIsDecorated( true );
  folders->setResizeMode(Q3ListView::LastColumn);
  folders->header()->hide();
  folders->setSelectionMode(Q3ListView::Single);

  connect(folders, SIGNAL(currentChanged(Q3ListViewItem *)),
      this, SLOT(folderItemChanged(Q3ListViewItem *)));
  connect(folders, SIGNAL(itemRenamed(Q3ListViewItem *, int, const QString &)),
      this, SLOT(renameFolder(Q3ListViewItem *, int, const QString &)));
  connect(folders, SIGNAL(contextMenuRequested(Q3ListViewItem *, const QPoint &, int)),
      this, SLOT(showFolderPopupMenu(Q3ListViewItem *, const QPoint &, int)));
  connect(folders, SIGNAL(dragItems(QList<Q3ListViewItem *>)),
      this, SLOT(dragFolderItems(QList<Q3ListViewItem *>)));
  connect(folders, SIGNAL(dropItems(Q3ListViewItem *)),
      this, SLOT(dropFolderItems(Q3ListViewItem *)));
  connect(folders, SIGNAL(renameItem(Q3ListViewItem *)),
      this, SLOT(startRenameFolder(Q3ListViewItem *)));
  connect(folders, SIGNAL(addFolderItem()), this, SLOT(addFolder()));
  connect(folders, SIGNAL(deleteSelection()), this, SLOT(deleteSelectedItems()));

  current_folder = new Folder( 0, tr("UNTITLED"));
  FolderListItem *fli = new FolderListItem(folders, current_folder);
  current_folder->setFolderListItem(fli);
  fli->setOpen( true );

  lv = new FolderListView();
  lv->addColumn (tr("Name"),-1 );
  lv->addColumn (tr("Type"),-1 );
  lv->addColumn (tr("View"),-1 );
  lv->addColumn (tr("Size"),-1 );
  lv->addColumn (tr("Created"),-1);
  lv->addColumn (tr("Label"),-1);
  lv->setResizeMode(Q3ListView::LastColumn);
  lv->setMinimumHeight(80);
  lv->setSelectionMode(Q3ListView::Extended);
  lv->setDefaultRenameAction (Q3ListView::Accept);

  explorerSplitter = new QSplitter(Qt::Horizontal, explorerWindow);
  explorerSplitter->addWidget(folders);
  explorerSplitter->addWidget(lv);
  explorerWindow->setWidget(explorerSplitter);

  QList<int> splitterSizes;
  explorerSplitter->setSizes( splitterSizes << 45 << 45);
  explorerWindow->hide();

  // Needs to be done after initialization of dock windows,
  // because we now use QDockWidget::toggleViewAction()
  createActions();
  initToolBars();
  initMainMenu();
  makeToolbarsMenu();

  d_workspace = new QMdiArea();
  d_workspace->setOption(QMdiArea::DontMaximizeSubWindowOnActivation);
  d_workspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  d_workspace->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  setCentralWidget(d_workspace);

  setAcceptDrops(true);

  hiddenWindows = new QList<QWidget*>();

  scriptingWindow = NULL;
  d_text_editor = NULL;

  const QString scriptsDir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("mantidqt.python_interfaces_directory"));

  // Parse the list of registered PyQt interfaces and their respective categories.
  QString pyQtInterfacesProperty = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("mantidqt.python_interfaces"));
  foreach(const QString pyQtInterfaceInfo, QStringList::split(" ", pyQtInterfacesProperty))
  {
    QString pyQtInterfaceFile;
    QSet<QString> pyQtInterfaceCategories;
    const QStringList tokens = QStringList::split("/", pyQtInterfaceInfo);

    if( tokens.size() == 0 ) // Empty token - ignore.
    {
      continue;
    }
    else if( tokens.size() == 1 ) // Assume missing category.
    {
      pyQtInterfaceCategories += "Uncatagorised";
      pyQtInterfaceFile = tokens[0];
    }
    else if( tokens.size() == 2 ) // Assume correct interface name and categories.
    {
      pyQtInterfaceCategories += QStringList::split(";", tokens[0]).toSet();
      pyQtInterfaceFile = tokens[1];
    }
    else // Too many forward slashes, or no space between two interfaces.  Warn user and move on.
    {
      g_log.warning() << "The mantidqt.python_interfaces property contains an unparsable value: "
                      << pyQtInterfaceInfo.toStdString();
      continue;
    }

    const QString scriptPath = scriptsDir + '/' + pyQtInterfaceFile;

    if( QFileInfo(scriptPath).exists() )
    {
      const QString pyQtInterfaceName = QFileInfo(scriptPath).baseName().replace("_", " ");
      m_interfaceNameDataPairs.append(qMakePair(pyQtInterfaceName, scriptPath));

      // Keep track of the interface's categories as we go.
      m_interfaceCategories[pyQtInterfaceName] = pyQtInterfaceCategories;
      m_allCategories += pyQtInterfaceCategories;
    }
    else
    {
      Mantid::Kernel::Logger& g_log = Mantid::Kernel::Logger::get("ConfigService");
      g_log.warning() << "Could not find interface script: " << scriptPath.ascii() << "\n";
    }
  }
  
  MantidQt::API::InterfaceManager interfaceManager;
  // Add all interfaces inherited from UserSubWindow.
  foreach(const QString userSubWindowName, interfaceManager.getUserSubWindowKeys())
  {
    m_interfaceNameDataPairs.append(qMakePair(userSubWindowName, userSubWindowName));

    const QSet<QString> categories = UserSubWindowFactory::Instance().getInterfaceCategories(userSubWindowName);

    m_interfaceCategories[userSubWindowName] = categories;
    m_allCategories += categories;

  renamedTables = QStringList();
  if (!factorySettings)
    readSettings();
  createLanguagesList();
  insertTranslatedStrings();
  disableToolbars();
  displayToolbars();
  actionNextWindow = new QAction(QIcon(getQPixmap("next_xpm")), tr("&Next","next window"), this);
  actionNextWindow->setShortcut( tr("F5","next window shortcut") );
  connect(actionNextWindow, SIGNAL(activated()), d_workspace, SLOT(activateNextSubWindow()));

  actionPrevWindow = new QAction(QIcon(getQPixmap("prev_xpm")), tr("&Previous","previous window"), this);
  actionPrevWindow->setShortcut( tr("F6","previous window shortcut") );
  connect(actionPrevWindow, SIGNAL(activated()), d_workspace, SLOT(activatePreviousSubWindow()));

  connect(tablesDepend, SIGNAL(activated(int)), this, SLOT(showTable(int)));

  connect(this, SIGNAL(modified()),this, SLOT(modifiedProject()));
  connect(d_workspace, SIGNAL(subWindowActivated(QMdiSubWindow *)),
      this, SLOT(windowActivated(QMdiSubWindow*)));
  connect(lv, SIGNAL(doubleClicked(Q3ListViewItem *)),
      this, SLOT(activateWindow(Q3ListViewItem *)));
  connect(lv, SIGNAL(doubleClicked(Q3ListViewItem *)),
      this, SLOT(folderItemDoubleClicked(Q3ListViewItem *)));
  connect(lv, SIGNAL(contextMenuRequested(Q3ListViewItem *, const QPoint &, int)),
      this, SLOT(showWindowPopupMenu(Q3ListViewItem *, const QPoint &, int)));
  connect(lv, SIGNAL(dragItems(QList<Q3ListViewItem *>)),
      this, SLOT(dragFolderItems(QList<Q3ListViewItem *>)));
  connect(lv, SIGNAL(dropItems(Q3ListViewItem *)),
      this, SLOT(dropFolderItems(Q3ListViewItem *)));
  connect(lv, SIGNAL(renameItem(Q3ListViewItem *)),
      this, SLOT(startRenameFolder(Q3ListViewItem *)));
  connect(lv, SIGNAL(addFolderItem()), this, SLOT(addFolder()));
  connect(lv, SIGNAL(deleteSelection()), this, SLOT(deleteSelectedItems()));
  connect(lv, SIGNAL(itemRenamed(Q3ListViewItem *, int, const QString &)),
      this, SLOT(renameWindow(Q3ListViewItem *, int, const QString &)));

  connect(recent, SIGNAL(activated(int)), this, SLOT(openRecentProject(int)));

  //apply user settings
  updateAppFonts();
  setAppColors(workspaceColor, panelsColor, panelsTextColor, true);

  //Scripting
  m_script_envs = QHash<QString, ScriptingEnv*>();
  setScriptingLanguage(defaultScriptingLang);
  m_iface_script = NULL;

  m_interpreterDock = new QDockWidget(this);
  m_interpreterDock->setObjectName("interpreterDock"); // this is needed for QMainWindow::restoreState()
  m_interpreterDock->setWindowTitle("Script Interpreter");
  runPythonScript("from ipython_widget import *\nw = _qti.app._getInterpreterDock()\nw.setWidget(MantidIPythonWidget())",false,true,true);
  if ( ! restoreDockWidget(m_interpreterDock))
  {
    // Restoring the widget fails if the settings aren't found or read. Therefore, add it manually.
    addDockWidget( Qt::BottomDockWidgetArea, m_interpreterDock );
  }

  loadCustomActions();

  // Nullify catalogSearch
  catalogSearch = NULL;
  // Print a warning message if the scripting language is set to muParser
  if (defaultScriptingLang == "muParser")
  {
    logWindow->show();
    g_log.warning("The scripting language is set to muParser. This is probably not what you want! Change the default in View->Preferences.");
  }

  // Need to show first time setup dialog?
  using Mantid::Kernel::ConfigServiceImpl;
  ConfigServiceImpl& config = ConfigService::Instance();
  std::string facility = config.getString("default.facility");
  std::string instrument = config.getString("default.instrument");
  if ( facility.empty() || instrument.empty() )
  {
    showFirstTimeSetup();
  }
  using namespace Mantid::API;
  // Do this as late as possible to avoid unnecessary updates
  AlgorithmFactory::Instance().enableNotifications();
  AlgorithmFactory::Instance().notificationCenter.postNotification(new AlgorithmFactoryUpdateNotification);

  /*
  The scripting enironment call setScriptingLanguage is trampling over the PATH, so we have to set it again.
  Here we do not off the setup dialog.
  */
  const bool skipDialog = true;
  trySetParaviewPath(args, skipDialog);
/*
Function tries to set the paraview path.

Owen Arnold's avatar
Owen Arnold committed
This is a windows only feature. the PATH enviromental variable can be set at runtime on windows.

- Abort if Vates libraries do not seem to be present.
- Othwerise, if the paraview.path is already in the properties file, use it.
- Otherwise, if the user is not using executeandquit command arguments launch the Setup gui.

@param commandArguments : all command line arguments.
@param noDialog : set to true to skip over the a dialog launch.
void ApplicationWindow::trySetParaviewPath(const QStringList& commandArguments, bool noDialog)
Owen Arnold's avatar
Owen Arnold committed
#ifdef _WIN32
    Mantid::Kernel::ConfigServiceImpl& confService = Mantid::Kernel::ConfigService::Instance();
    //Early check of execute and quit command arguments used by system tests.
    QString str;
    bool b_skipDialog = noDialog;
Owen Arnold's avatar
Owen Arnold committed
    foreach(str, commandArguments)
    {
      if(this->shouldExecuteAndQuit(str))
      {
        b_skipDialog = true;
        break;
      }
    }

    //ONLY If skipping is not already selected
    if(!b_skipDialog)
    {
      //If the ignore property exists and is set to true, then skip the dialog.
      const std::string paraviewIgnoreProperty = "paraview.ignore";
      b_skipDialog = confService.hasProperty(paraviewIgnoreProperty) && QString(confService.getString(paraviewIgnoreProperty).c_str()).toInt() > 0;
    if(this->hasParaviewPath())
    {
      //Already have a path in the properties file, just apply it.
      std::string path = confService.getString("paraview.path");
      confService.setParaviewLibraryPath(path);
    }
    else
    {
      //Only run the following if skipping is not implied.
      if(!b_skipDialog)
      {
        //Launch the dialog to set the PV path.
        SetUpParaview pv(SetUpParaview::FirstLaunch);
Owen Arnold's avatar
Owen Arnold committed
#else
  UNUSED_ARG(commandArguments)
  UNUSED_ARG(noDialog)
Owen Arnold's avatar
Owen Arnold committed
#endif
/*
Getter to determine if the paraview path has been set.
*/
bool ApplicationWindow::hasParaviewPath() const
{
  const std::string propertyname = "paraview.path";
  Mantid::Kernel::ConfigServiceImpl& config = Mantid::Kernel::ConfigService::Instance();
  return config.hasProperty(propertyname) && !config.getString(propertyname).empty() ;
void ApplicationWindow::initWindow()
{
  switch(d_init_window_type){
  case TableWindow:
    newTable();
    break;
  case MatrixWindow:
    newMatrix();
    break;
  case MultiLayerWindow:
    newGraph();
    break;
  case NoteWindow:
    newNote();
    break;
  default:
    break;
  }
}

void ApplicationWindow::initGlobalConstants()
{
  d_auto_update_table_values = true;
  d_active_window = NULL;
  d_matrix_undo_stack_size = 10;

  d_opening_file = false;
  d_in_place_editing = true;

  d_matrix_tool_bar = true;
  d_standard_tool_bar = true;
  d_column_tool_bar = true;
  d_edit_tool_bar = true;
  d_plot_tool_bar = true;
  d_display_tool_bar = false;
  d_format_tool_bar = true;

  appStyle = qApp->style()->objectName();
  d_app_rect = QRect();
  projectname = "untitled";
  lastCopiedLayer = NULL;
  d_text_copy = NULL;
  d_arrow_copy = NULL;
  d_image_copy = NULL;

  savingTimerId = 0;

  autoSearchUpdatesRequest = false;

  show_windows_policy = ActiveFolder;
  d_init_window_type = NoWindow;

  QString aux = qApp->applicationDirPath();
  workingDir = aux;

  d_translations_folder = aux + "/translations";
  helpFilePath = aux + "/manual/index.html";
  d_python_config_folder = aux;

  fitPluginsPath = aux + "fitPlugins";
  fitModelsPath = QString::null;
  templatesDir = aux;
  asciiDirPath = aux;
  imagesDirPath = aux;
  scriptsDirPath = aux;
  customActionsDirPath = QString::null;

  appFont = QFont();
  QString family = appFont.family();
  int pointSize = appFont.pointSize();
  tableTextFont = appFont;
  tableHeaderFont = appFont;
  plotAxesFont = QFont(family, pointSize, QFont::Bold, false);
  plotNumbersFont = QFont(family, pointSize );
  plotLegendFont = appFont;
  plotTitleFont = QFont(family, pointSize + 2, QFont::Bold,false);

  plot3DAxesFont = QFont(family, pointSize, QFont::Bold, false );
  plot3DNumbersFont = QFont(family, pointSize);
  plot3DTitleFont = QFont(family, pointSize + 2, QFont::Bold,false);

  autoSearchUpdates = false;
  appLanguage = QLocale::system().name().section('_',0,0);
  show_windows_policy = ApplicationWindow::ActiveFolder;

  workspaceColor = QColor("darkGray");
  panelsColor = QColor("#ffffff");
  panelsTextColor = QColor("#000000");
  tableBkgdColor = QColor("#ffffff");
  tableTextColor = QColor("#000000");
  tableHeaderColor = QColor("#000000");

  plot3DColors = QStringList();
  plot3DColors << "blue";
  plot3DColors << "#000000";
  plot3DColors << "#000000";
  plot3DColors << "#000000";
  plot3DColors << "red";
  plot3DColors << "#000000";
  plot3DColors << "#000000";
  plot3DColors << "#ffffff";

  d_graph_tick_labels_dist = 4;
  d_graph_axes_labels_dist = 2;

  autoSave = false;
  autoSaveTime = 15;
  d_backup_files = true;
  defaultScriptingLang = "Python";  //Mantid M. Gigg
  // Scripting window geometry
  d_script_win_pos = QPoint(250,200);
  d_script_win_size = QSize(600,660);
  d_thousands_sep = true;
  d_locale = QLocale::system().name();
  if (!d_thousands_sep)
    d_locale.setNumberOptions(QLocale::OmitGroupSeparator);

  d_decimal_digits = 13;

  d_extended_open_dialog = true;
  d_extended_export_dialog = true;
  d_extended_import_ASCII_dialog = true;
  d_extended_plot_dialog = true;

  d_add_curves_dialog_size = QSize(700, 400);
  d_show_current_folder = false;

  confirmCloseFolder = false;
  confirmCloseTable = false;
  confirmCloseMatrix = false;
  confirmClosePlot2D = false;
  confirmClosePlot3D = false;
  confirmCloseNotes = false;
  d_inform_rename_table = false;
  confirmCloseInstrWindow=false;

  d_show_table_comments = false;

  titleOn = true;
  // 'Factory' default is to show top & right axes but without labels
  d_show_axes = QVector<bool> (QwtPlot::axisCnt, true);
  d_show_axes_labels = QVector<bool> (QwtPlot::axisCnt, true);
  d_show_axes_labels[1] = false;
  d_show_axes_labels[3] = false;
  canvasFrameWidth = 0;
  defaultPlotMargin = 0;
  drawBackbones = true;

  //these settings are overridden, but the default axes scales are linear
  d_axes_scales = QVector<QString> (QwtPlot::axisCnt, "linear");

  axesLineWidth = 1;
  autoscale2DPlots = true;
  autoScaleFonts = true;
  autoResizeLayers = true;
  antialiasing2DPlots = true; 
  fixedAspectRatio2DPlots = false; //Mantid
  d_scale_plots_on_print = false;
  d_print_cropmarks = false;
  d_synchronize_graph_scales = true;

  defaultCurveStyle = static_cast<int>(Graph::Line);
  defaultCurveLineWidth = 1;
  defaultSymbolSize = 7;

  majTicksStyle = static_cast<int>(ScaleDraw::In);
  minTicksStyle = static_cast<int>(ScaleDraw::In);
  minTicksLength = 5;
  majTicksLength = 9;

  legendFrameStyle = static_cast<int>(LegendWidget::Line);
  legendTextColor = Qt::black;
  legendBackground = Qt::white;
  legendBackground.setAlpha(255); // opaque by default;

  defaultArrowLineWidth = 1;
  defaultArrowColor = Qt::black;
  defaultArrowHeadLength = 4;
  defaultArrowHeadAngle = 45;
  defaultArrowHeadFill = true;
  defaultArrowLineStyle = Graph::getPenStyle("SolidLine");

  showPlot3DLegend = true;
  showPlot3DProjection = false;
  smooth3DMesh = false;
  plot3DResolution = 1;
  orthogonal3DPlots = false;
  autoscale3DPlots = true;

  fit_output_precision = 13;
  pasteFitResultsToPlot = false;
  writeFitResultsToLog = true;
  generateUniformFitPoints = true;
  fitPoints = 100;
  generatePeakCurves = true;
  peakCurvesColor = 2;
  fit_scale_errors = true;
  d_2_linear_fit_points = true;

  columnSeparator = "\t";
  ignoredLines = 0;
  renameColumns = true;
  strip_spaces = false;
  simplify_spaces = false;
  d_ASCII_file_filter = "*";
  d_ASCII_import_locale = QLocale::system().name();
  d_import_dec_separators = true;
  d_ASCII_import_mode = static_cast<int>(ImportASCIIDialog::NewTables);
  d_ASCII_comment_string = "#";
  d_ASCII_import_comments = false;
  d_ASCII_import_read_only = false;
  d_ASCII_import_preview = true;
  d_preview_lines = 100;
#ifdef Q_OS_MAC
  d_ASCII_end_line = CR;
  d_eol = CR;
#else
  d_ASCII_end_line = LF;
  d_eol = LF;
#endif

  d_export_col_separator = "\t";
  d_export_col_names = false;
  d_export_col_comment = false;
  d_export_table_selection = false;

  d_image_export_filter = ".png";
  d_export_transparency = false;
  d_export_quality = 100;

  // MG: On Linux, if cups defines a printer queue that cannot be contact, the
  // QPrinter constructor hangs and doesn't timeout.

  //	QPrinterInfo::availablePrinters();


  //	d_export_resolution = QPrinter().resolution();
  d_export_color = true;
  d_export_vector_size = static_cast<int>(QPrinter::Custom);
  d_keep_plot_aspect = true;
}

QMenuBar* ApplicationWindow::myMenuBar()
{
#ifdef SHARED_MENUBAR
  return m_sharedMenuBar == NULL ? menuBar() : m_sharedMenuBar;
#else
  return menuBar();
#endif
}

void ApplicationWindow::initToolBars()
{
  initPlot3DToolBar();

  //	setWindowIcon(QIcon(getQPixmap("logo_xpm")));
  setWindowIcon(QIcon(":/MantidPlot_Icon_32offset.png"));
  QPixmap openIcon, saveIcon;

  standardTools = new QToolBar(tr( "Standard Tools" ), this);
  standardTools->setObjectName("standardTools"); // this is needed for QMainWindow::restoreState()
  standardTools->setIconSize( QSize(18,20) );
  addToolBar( Qt::TopToolBarArea, standardTools );
  standardTools->addAction(actionLoadFile);
   standardTools->addSeparator ();
  standardTools->addAction(actionNewProject);
  standardTools->addAction(actionOpenProj);
  standardTools->addAction(actionSaveProject);
  standardTools->addSeparator ();
  standardTools->addAction(actionShowLog);
#ifdef SCRIPTING_PYTHON
  standardTools->addAction(actionShowScriptWindow);
  standardTools->addSeparator ();
  standardTools->addAction(actionManageDirs);
  standardTools->addSeparator ();

  standardTools->addAction(actionCopySelection);
  standardTools->addAction(actionPasteSelection);

  plotTools = new QToolBar(tr("Plot"), this);
  plotTools->setObjectName("plotTools"); // this is needed for QMainWindow::restoreState()
  plotTools->setIconSize( QSize(16,20) );
  addToolBar( plotTools );

  dataTools = new QActionGroup( this );
  dataTools->setExclusive( true );

  btnPointer = new QAction(tr("Disable &Tools"), this);
  btnPointer->setActionGroup(dataTools);
  btnPointer->setCheckable( true );
  btnPointer->setIcon(QIcon(getQPixmap("pointer_xpm")) );
  btnPointer->setChecked(true);
  plotTools->addAction(btnPointer);

  actionPanPlot->setActionGroup(dataTools);
  actionPanPlot->setCheckable( true );
  plotTools->addAction(actionPanPlot);

  btnZoomIn = new QAction(tr("&Zoom In"), this);
  btnZoomIn->setShortcut( tr("Ctrl++") );
  btnZoomIn->setActionGroup(dataTools);
  btnZoomIn->setCheckable( true );
  btnZoomIn->setIcon(QIcon(getQPixmap("zoom_xpm")) );
  plotTools->addAction(btnZoomIn);

  btnZoomOut = new QAction(tr("&Zoom Out"), this);
  btnZoomOut->setShortcut( tr("Ctrl+-") );
  btnZoomOut->setActionGroup(dataTools);
  btnZoomOut->setCheckable( true );
  btnZoomOut->setIcon(QIcon(getQPixmap("zoomOut_xpm")) );
  plotTools->addAction(btnZoomOut);
  plotTools->addAction(actionUnzoom);


  btnCursor = new QAction(tr("&Data Reader"), this);
  btnCursor->setShortcut( tr("CTRL+D") );
  btnCursor->setActionGroup(dataTools);
  btnCursor->setCheckable( true );
  btnCursor->setIcon(QIcon(getQPixmap("select_xpm")) );
  //plotTools->addAction(btnCursor); disabled until fixed (#2783)
  btnPicker = new QAction(tr("S&creen Reader"), this);
  btnPicker->setActionGroup(dataTools);
  btnPicker->setCheckable( true );
  btnPicker->setIcon(QIcon(getQPixmap("cursor_16_xpm")) );
  plotTools->addAction(btnPicker); //disabled until fixed (#2783)

  actionDrawPoints = new QAction(tr("&Draw Data Points"), this);
  actionDrawPoints->setActionGroup(dataTools);
  actionDrawPoints->setCheckable( true );
  actionDrawPoints->setIcon(QIcon(getQPixmap("draw_points_xpm")) );
  //plotTools->addAction(actionDrawPoints); disabled until fixed (#2783)

  btnMovePoints = new QAction(tr("&Move Data Points..."), this);
  btnMovePoints->setShortcut( tr("Ctrl+ALT+M") );
  btnMovePoints->setActionGroup(dataTools);
  btnMovePoints->setCheckable( true );
  btnMovePoints->setIcon(QIcon(getQPixmap("hand_xpm")) );