Added the needed facility in the preferences which allows to switch the icon scheme between plain and dark. This is needed for some OS where qt doesn't provide the necessary information.
3415 lines
115 KiB
C++
3415 lines
115 KiB
C++
/****************************************************************************
|
|
|
|
PTextEdit.cpp
|
|
|
|
Author: Andreas Suter
|
|
e-mail: andreas.suter@psi.ch
|
|
|
|
*****************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* Copyright (C) 2010-2019 by Andreas Suter *
|
|
* andreas.suter@psi.ch *
|
|
* *
|
|
* 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., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
#include <QString>
|
|
#include <QStringList>
|
|
#include <QTextEdit>
|
|
#include <QStatusBar>
|
|
#include <QAction>
|
|
#include <QMenuBar>
|
|
#include <QMenu>
|
|
#include <QToolBar>
|
|
#include <QTabWidget>
|
|
#include <QApplication>
|
|
#include <QFontDatabase>
|
|
#include <QComboBox>
|
|
#include <QLineEdit>
|
|
#include <QFileInfo>
|
|
#include <QFile>
|
|
#include <QFileDialog>
|
|
#include <QtPrintSupport/QPrinter>
|
|
#include <QtPrintSupport/QPrintDialog>
|
|
#include <QColorDialog>
|
|
#include <QPainter>
|
|
#include <QMessageBox>
|
|
#include <QDialog>
|
|
#include <QPixmap>
|
|
#include <QTextCursor>
|
|
#include <QTextBlock>
|
|
#include <QTextDocumentFragment>
|
|
#include <QTextList>
|
|
#include <QProcess>
|
|
|
|
#include <QtDebug>
|
|
|
|
#include "PTextEdit.h"
|
|
#include "PHelp.h"
|
|
#include "PSubTextEdit.h"
|
|
#include "PAdmin.h"
|
|
#include "PFindDialog.h"
|
|
#include "PReplaceDialog.h"
|
|
#include "PReplaceConfirmationDialog.h"
|
|
#include "PFitOutputHandler.h"
|
|
#include "PDumpOutputHandler.h"
|
|
#include "PPrefsDialog.h"
|
|
#include "PGetMusrFTOptionsDialog.h"
|
|
#include "PMusrEditAbout.h"
|
|
#include "PMsr2DataDialog.h"
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Constructor
|
|
*
|
|
* \param parent pointer to the parent object
|
|
* \param f qt windows flags
|
|
*/
|
|
PTextEdit::PTextEdit( QWidget *parent, Qt::WindowFlags f )
|
|
: QMainWindow( parent, f )
|
|
{
|
|
getTheme();
|
|
|
|
// reads and manages the conents of the xml-startup (musredit_startup.xml) file
|
|
fAdmin = new PAdmin();
|
|
|
|
// set default setting of the fDarkThemeIcons
|
|
fAdmin->setDarkThemeIconsFlag(fDarkToolBarIcon);
|
|
|
|
// enable file system watcher. Needed to get notification if the msr-file is changed outside of musrfit at runtime
|
|
fFileSystemWatcherActive = true;
|
|
fFileSystemWatcher = new QFileSystemWatcher();
|
|
if (fFileSystemWatcher == nullptr) {
|
|
QMessageBox::information(this, "**ERROR**", "Couldn't invoke QFileSystemWatcher!");
|
|
} else {
|
|
connect( fFileSystemWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(const QString&)));
|
|
}
|
|
|
|
// initialize stuff
|
|
fMusrT0Action = nullptr;
|
|
|
|
fMsr2DataParam = nullptr;
|
|
fFindReplaceData = nullptr;
|
|
|
|
// setup menus
|
|
setupFileActions();
|
|
setupEditActions();
|
|
setupTextActions();
|
|
setupMusrActions();
|
|
setupHelpActions();
|
|
|
|
fTabWidget = new QTabWidget( this );
|
|
fTabWidget->setMovable(true); // allows to shuffle around tabs
|
|
setCentralWidget( fTabWidget );
|
|
|
|
textFamily(fAdmin->getFontName());
|
|
textSize(QString("%1").arg(fAdmin->getFontSize()));
|
|
fFontChanging = false;
|
|
|
|
QString iconName("");
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrfit-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrfit-plain.svg");
|
|
setWindowIcon( QIcon( QPixmap(iconName) ) );
|
|
|
|
// if arguments are give, try to load those files, otherwise create an empty new file
|
|
if ( qApp->arguments().size() != 1 ) {
|
|
for ( int i = 1; i < qApp->arguments().size(); ++i )
|
|
load( qApp->arguments()[ i ] );
|
|
} else {
|
|
fileNew();
|
|
}
|
|
|
|
connect( fTabWidget, SIGNAL( currentChanged(int) ), this, SLOT( applyFontSettings(int) ));
|
|
|
|
fLastDirInUse = fAdmin->getDefaultSavePath();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>This slot is called if the main application is on the way to quit. This ensures that allocated
|
|
* memory indeed can be free'd.
|
|
*/
|
|
void PTextEdit::aboutToQuit()
|
|
{
|
|
if (fAdmin) {
|
|
delete fAdmin;
|
|
fAdmin = nullptr;
|
|
}
|
|
if (fMusrT0Action) {
|
|
delete fMusrT0Action;
|
|
fMusrT0Action = nullptr;
|
|
}
|
|
if (fMsr2DataParam) {
|
|
delete fMsr2DataParam;
|
|
fMsr2DataParam = nullptr;
|
|
}
|
|
if (fFindReplaceData) {
|
|
delete fFindReplaceData;
|
|
fFindReplaceData = nullptr;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Setup the file menu and the necessary actions.
|
|
*/
|
|
void PTextEdit::setupFileActions()
|
|
{
|
|
QToolBar *tb = new QToolBar( this );
|
|
tb->setWindowTitle( "File Actions" );
|
|
addToolBar( tb );
|
|
|
|
QMenu *menu = new QMenu( tr( "F&ile" ), this );
|
|
menuBar()->addMenu( menu );
|
|
|
|
QAction *a;
|
|
QString iconName("");
|
|
|
|
// New
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/document-new-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/document-new-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&New..." ), this );
|
|
a->setShortcut( tr("Ctrl+N") );
|
|
a->setStatusTip( tr("Create a new msr-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileNew() ) );
|
|
menu->addAction(a);
|
|
fActions["New"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/document-new-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&New..." ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileNew() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Open
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/document-open-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/document-open-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Open..." ), this );
|
|
a->setShortcut( tr("Ctrl+O") );
|
|
a->setStatusTip( tr("Opens a msr-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileOpen() ) );
|
|
menu->addAction(a);
|
|
fActions["Open"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/document-open-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Open..." ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileOpen() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Recent Files
|
|
fRecentFilesMenu = menu->addMenu( tr("Recent Files") );
|
|
for (int i=0; i<MAX_RECENT_FILES; i++) {
|
|
fRecentFilesAction[i] = new QAction(fRecentFilesMenu);
|
|
fRecentFilesAction[i]->setVisible(false);
|
|
connect( fRecentFilesAction[i], SIGNAL(triggered()), this, SLOT(fileOpenRecent()));
|
|
fRecentFilesMenu->addAction(fRecentFilesAction[i]);
|
|
}
|
|
fillRecentFiles();
|
|
|
|
// Reload
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/view-refresh-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/view-refresh-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Reload..." ), this );
|
|
a->setShortcut( tr("F5") );
|
|
a->setStatusTip( tr("Reload msr-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileReload() ) );
|
|
menu->addAction(a);
|
|
fActions["Reload"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/view-refresh-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Reload..." ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileReload() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
a = new QAction( tr( "Open Prefs..." ), this);
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileOpenPrefs() ) );
|
|
menu->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
|
|
// Save
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/document-save-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/document-save-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Save..." ), this );
|
|
a->setShortcut( tr("Ctrl+S") );
|
|
a->setStatusTip( tr("Save msr-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileSave() ) );
|
|
menu->addAction(a);
|
|
fActions["Save"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/document-save-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Save..." ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileSave() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Save As
|
|
a = new QAction( tr( "Save &As..." ), this );
|
|
a->setStatusTip( tr("Save msr-file As") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileSaveAs() ) );
|
|
menu->addAction(a);
|
|
|
|
// Save Prefs
|
|
a = new QAction( tr( "Save Prefs..." ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileSavePrefs() ) );
|
|
menu->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
|
|
// Print
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/document-print-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/document-print-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Print..." ), this );
|
|
a->setShortcut( tr("Ctrl+P") );
|
|
a->setStatusTip( tr("Print msr-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( filePrint() ) );
|
|
menu->addAction(a);
|
|
fActions["Print"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/document-print-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Print..." ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( filePrint() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
|
|
// Close
|
|
a = new QAction( tr( "&Close" ), this );
|
|
a->setShortcut( tr("Ctrl+W") );
|
|
a->setStatusTip( tr("Close msr-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileClose() ) );
|
|
menu->addAction(a);
|
|
|
|
// Close All
|
|
a = new QAction( tr( "Close &All" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileCloseAll() ) );
|
|
menu->addAction(a);
|
|
|
|
// Close All Others
|
|
a = new QAction( tr( "Clo&se All Others" ), this );
|
|
a->setShortcut( tr("Ctrl+Shift+W") );
|
|
a->setStatusTip( tr("Close All Other Tabs") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileCloseAllOthers() ) );
|
|
menu->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
|
|
// Exit
|
|
a = new QAction( tr( "E&xit" ), this );
|
|
a->setShortcut( tr("Ctrl+Q") );
|
|
a->setStatusTip( tr("Exit Program") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( fileExit() ) );
|
|
menu->addAction(a);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Setup the edit menu and the necessary actions.
|
|
*/
|
|
void PTextEdit::setupEditActions()
|
|
{
|
|
QToolBar *tb = new QToolBar( this );
|
|
tb->setWindowTitle( "Edit Actions" );
|
|
addToolBar( tb );
|
|
|
|
QMenu *menu = new QMenu( tr( "&Edit" ), this );
|
|
menuBar()->addMenu( menu );
|
|
|
|
QAction *a;
|
|
QString iconName("");
|
|
|
|
// Undo
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/edit-undo-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/edit-undo-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Undo" ), this );
|
|
a->setShortcut( tr("Ctrl+Z") );
|
|
a->setStatusTip( tr("Edit Undo") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editUndo() ) );
|
|
menu->addAction(a);
|
|
fActions["Undo"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/edit-undo-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Undo" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editUndo() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Redo
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/edit-redo-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/edit-redo-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Redo" ), this );
|
|
a->setShortcut( tr("Ctrl+Y") );
|
|
a->setStatusTip( tr("Edit Redo") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editRedo() ) );
|
|
menu->addAction(a);
|
|
fActions["Redo"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/edit-redo-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Redo" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editRedo() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
|
|
// Select All
|
|
a = new QAction( tr( "Select &All" ), this );
|
|
a->setShortcut( tr("Ctrl+A") );
|
|
a->setStatusTip( tr("Edit Select All") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editSelectAll() ) );
|
|
menu->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
tb->addSeparator();
|
|
|
|
// Copy
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/edit-copy-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/edit-copy-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Copy" ), this );
|
|
a->setShortcut( tr("Ctrl+C") );
|
|
a->setStatusTip( tr("Edit Copy") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editCopy() ) );
|
|
menu->addAction(a);
|
|
fActions["Copy"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/edit-copy-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Copy" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editCopy() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Cut
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/edit-cut-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/edit-cut-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Cu&t" ), this );
|
|
a->setShortcut( tr("Ctrl+X") );
|
|
a->setStatusTip( tr("Edit Cut") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editCut() ) );
|
|
menu->addAction(a);
|
|
fActions["Cut"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/edit-cut-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Cu&t" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editCut() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Paste
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/edit-paste-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/edit-paste-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Paste" ), this );
|
|
a->setShortcut( tr("Ctrl+V") );
|
|
a->setStatusTip( tr("Edit Paste") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editPaste() ) );
|
|
menu->addAction(a);
|
|
fActions["Paste"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/edit-paste-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Paste" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editPaste() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
tb->addSeparator();
|
|
|
|
// Find
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/edit-find-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/edit-find-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Find" ), this );
|
|
a->setShortcut( tr("Ctrl+F") );
|
|
a->setStatusTip( tr("Edit Find") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFind() ) );
|
|
menu->addAction(a);
|
|
fActions["Find"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/edit-find-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Find" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFind() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Find Next
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/go-next-use-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/go-next-use-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Find &Next" ), this );
|
|
a->setShortcut( tr("F3") );
|
|
a->setStatusTip( tr("Edit Find Next") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFindNext() ) );
|
|
menu->addAction(a);
|
|
fActions["Find Next"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/go-next-use-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Find &Next" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFindNext() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Find Previous
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/go-previous-use-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/go-previous-use-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ) , tr( "Find Pre&vious" ), this );
|
|
a->setShortcut( tr("Shift+F4") );
|
|
a->setStatusTip( tr("Edit Find Previous") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFindPrevious() ) );
|
|
menu->addAction(a);
|
|
fActions["Find Previous"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/go-previous-use-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Find Pre&vious" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFindPrevious() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Replace
|
|
a = new QAction( tr( "Replace..." ), this );
|
|
a->setShortcut( tr("Ctrl+R") );
|
|
a->setStatusTip( tr("Edit Replace") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editFindAndReplace() ) );
|
|
menu->addAction(a);
|
|
menu->addSeparator();
|
|
|
|
QMenu *addSubMenu = new QMenu( tr ("Add Block"), this);
|
|
|
|
a = new QAction( tr("Title Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Title Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertTitle() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Parameter Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Parameter Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertParameterBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Theory Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Theory Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertTheoryBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Function Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Function Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertFunctionBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
// feed the theoryFunctions popup menu
|
|
QMenu *theoryFunctions = new QMenu( tr("Add Theory Function"), this );
|
|
for (unsigned int i=0; i<fAdmin->getTheoryCounts(); i++) {
|
|
PTheory *theoryItem = fAdmin->getTheoryItem(i);
|
|
a = new QAction( theoryItem->label, this);
|
|
theoryFunctions->addAction(a);
|
|
}
|
|
connect( theoryFunctions, SIGNAL( triggered(QAction*)), this, SLOT( insertTheoryFunction(QAction*) ) );
|
|
|
|
a = new QAction( tr("Asymmetry Run Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Asymmetry Run Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertAsymRunBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Single Histo Run Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Single Histo Run Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertSingleHistRunBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("NonMuSR Run Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR NonMuSR Run Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertNonMusrRunBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Command Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Command Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertCommandBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Fourier Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Fourier Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertFourierBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Plot Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Plot Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertPlotBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
a = new QAction( tr("Statistic Block"), this );
|
|
a->setStatusTip( tr("Invokes MSR Statistic Block Dialog") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( insertStatisticBlock() ));
|
|
addSubMenu->addAction(a);
|
|
|
|
menu->addMenu(addSubMenu);
|
|
menu->addMenu(theoryFunctions);
|
|
menu->addSeparator();
|
|
|
|
a = new QAction( tr( "Co&mment" ), this );
|
|
a->setShortcut( tr("Ctrl+M") );
|
|
a->setStatusTip( tr("Edit Comment Selected Lines") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editComment() ) );
|
|
menu->addAction(a);
|
|
|
|
a = new QAction( tr( "Unco&mment" ), this );
|
|
a->setShortcut( tr("Ctrl+Shift+M") );
|
|
a->setStatusTip( tr("Edit Uncomment Selected Lines") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( editUncomment() ) );
|
|
menu->addAction(a);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Setup the font/font size menu.
|
|
*/
|
|
void PTextEdit::setupTextActions()
|
|
{
|
|
QToolBar *tb = new QToolBar( this );
|
|
tb->setWindowTitle( "Format Actions" );
|
|
addToolBar( tb );
|
|
|
|
fComboFont = new QComboBox();
|
|
fComboFont->setEditable(true);
|
|
QFontDatabase db;
|
|
fComboFont->addItems( db.families() );
|
|
connect( fComboFont, SIGNAL( activated( const QString & ) ),
|
|
this, SLOT( textFamily( const QString & ) ) );
|
|
QLineEdit *edit = fComboFont->lineEdit();
|
|
if (edit == nullptr) {
|
|
return;
|
|
}
|
|
edit->setText( fAdmin->getFontName() );
|
|
tb->addWidget(fComboFont);
|
|
|
|
fComboSize = new QComboBox( tb );
|
|
fComboSize->setEditable(true);
|
|
QList<int> sizes = db.standardSizes();
|
|
QList<int>::Iterator it = sizes.begin();
|
|
for ( ; it != sizes.end(); ++it )
|
|
fComboSize->addItem( QString::number( *it ) );
|
|
connect( fComboSize, SIGNAL( activated( const QString & ) ),
|
|
this, SLOT( textSize( const QString & ) ) );
|
|
edit = fComboSize->lineEdit();
|
|
if (edit == nullptr) {
|
|
return;
|
|
}
|
|
edit->setText( QString("%1").arg(fAdmin->getFontSize()) );
|
|
tb->addWidget(fComboSize);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Setup the musrfit menu and the necessary actions.
|
|
*/
|
|
void PTextEdit::setupMusrActions()
|
|
{
|
|
addToolBarBreak();
|
|
|
|
QToolBar *tb = new QToolBar( this );
|
|
tb->setWindowTitle( "Musr Actions" );
|
|
addToolBar( tb );
|
|
|
|
QMenu *menu = new QMenu( tr( "&MusrFit" ), this );
|
|
menuBar()->addMenu( menu );
|
|
|
|
QAction *a;
|
|
QString iconName("");
|
|
|
|
// musrWiz
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrWiz-32x32-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrWiz-32x32.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "musr&Wiz" ), this );
|
|
a->setShortcut( tr("Alt+W") );
|
|
a->setStatusTip( tr("Call musrWiz which helps to create msr-files") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrWiz() ) );
|
|
menu->addAction(a);
|
|
fActions["musrWiz"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrWiz-32x32.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "musr&Wiz" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrWiz() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
tb->addSeparator();
|
|
|
|
// Calculate Chisq
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrchisq-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrchisq-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Calculate &Chisq" ), this );
|
|
a->setShortcut( tr("Alt+C") );
|
|
a->setStatusTip( tr("Calculate Chi Square (Log Max Likelihood)") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrCalcChisq() ) );
|
|
menu->addAction(a);
|
|
fActions["calcChisq"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrchisq-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Calculate &Chisq" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrCalcChisq() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// musrfit
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrfit-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrfit-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Fit" ), this );
|
|
a->setShortcut( tr("Alt+F") );
|
|
a->setStatusTip( tr("Fit") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrFit() ) );
|
|
menu->addAction(a);
|
|
fActions["musrfit"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrfit-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Fit" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrFit() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// Swap Msr/Mlog
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrswap-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrswap-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Swap Msr <-> Mlog" ), this );
|
|
a->setShortcut( tr("Alt+S") );
|
|
a->setStatusTip( tr("Swap msr-file <-> mlog-file") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrSwapMsrMlog() ) );
|
|
menu->addAction(a);
|
|
fActions["Swap Msr/Mlog"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrswap-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Swap Msr <-> Mlog" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrSwapMsrMlog() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// musrStep
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrStep-32x32-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrStep-32x32.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Set Ste&ps" ), this );
|
|
a->setShortcut( tr("Alt+P") );
|
|
a->setStatusTip( tr("Set Steps") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrSetSteps() ) );
|
|
menu->addAction(a);
|
|
fActions["musrStep"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrStep-32x32.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Set Ste&ps" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrSetSteps() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// msr2data
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/msr2data-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/msr2data-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Msr&2Data" ), this );
|
|
a->setShortcut( tr("Alt+2") );
|
|
a->setStatusTip( tr("Start msr2data interface") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrMsr2Data() ) );
|
|
menu->addAction(a);
|
|
fActions["msr2data"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/msr2data-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Msr2Data" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrMsr2Data() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// mupp
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/mupp-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/mupp-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "m&upp" ), this );
|
|
a->setShortcut( tr("Alt+U") );
|
|
a->setStatusTip( tr("Start mupp, the muSR parameter plotter") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( mupp() ) );
|
|
menu->addAction(a);
|
|
fActions["mupp"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/mupp-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "m&upp" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( mupp() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
tb->addSeparator();
|
|
|
|
// musrview
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrview-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrview-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&View" ), this );
|
|
a->setShortcut( tr("Alt+V") );
|
|
a->setStatusTip( tr("Start musrview") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrView() ) );
|
|
menu->addAction(a);
|
|
fActions["musrview"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrview-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&View" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrView() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// musrt0
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrt0-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrt0-plain.svg");
|
|
fMusrT0Action = new QAction( QIcon( QPixmap(iconName) ), tr( "&T0" ), this );
|
|
fMusrT0Action->setStatusTip( tr("Start musrt0") );
|
|
connect( fMusrT0Action, SIGNAL( triggered() ), this, SLOT( musrT0() ) );
|
|
menu->addAction(fMusrT0Action);
|
|
fActions["musrt0"] = fMusrT0Action;
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrt0-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&T0" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrT0() ) );
|
|
}
|
|
tb->addAction(fMusrT0Action);
|
|
fMusrT0Action->setEnabled(fAdmin->getEnableMusrT0Flag());
|
|
|
|
// musrFT
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrFT-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrFT-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Raw Fourier" ), this );
|
|
a->setStatusTip( tr("Start musrFT") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrFT() ) );
|
|
menu->addAction(a);
|
|
fActions["musrFT"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrFT-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "Raw Fourier" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrFT() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
// musrprefs
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrprefs-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrprefs-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Preferences" ), this );
|
|
a->setStatusTip( tr("Show Preferences") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrPrefs() ) );
|
|
menu->addAction(a);
|
|
fActions["musrprefs"] = a;
|
|
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrprefs-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Preferences" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrPrefs() ) );
|
|
}
|
|
tb->addAction(a);
|
|
|
|
menu->addSeparator();
|
|
tb->addSeparator();
|
|
|
|
// musrdump
|
|
if (fDarkTheme)
|
|
iconName = QString(":/icons/musrdump-dark.svg");
|
|
else
|
|
iconName = QString(":/icons/musrdump-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName)), tr( "&Dump Header"), this);
|
|
a->setStatusTip( tr("Dumps muSR File Header Information") );
|
|
connect( a, SIGNAL(triggered()), this, SLOT(musrDump()));
|
|
menu->addAction(a);
|
|
fActions["musrdump"] = a;
|
|
if (!fDarkToolBarIcon) { // tool bar icon is not dark, even though the theme is (ubuntu)
|
|
iconName = QString(":/icons/musrdump-plain.svg");
|
|
a = new QAction( QIcon( QPixmap(iconName) ), tr( "&Dump Header" ), this );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( musrDump() ) );
|
|
}
|
|
tb->addAction(a);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Setup the help menu and the necessary actions.
|
|
*/
|
|
void PTextEdit::setupHelpActions()
|
|
{
|
|
QMenu *menu = new QMenu( tr( "&Help" ), this );
|
|
menuBar()->addMenu( menu);
|
|
|
|
QAction *a;
|
|
a = new QAction(tr( "Contents ..." ), this );
|
|
a->setStatusTip( tr("Help Contents") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( helpContents() ));
|
|
menu->addAction(a);
|
|
|
|
a = new QAction(tr( "Author(s) ..." ), this );
|
|
a->setStatusTip( tr("Help About") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( helpAbout() ));
|
|
menu->addAction(a);
|
|
|
|
a = new QAction(tr( "About Qt..." ), this );
|
|
a->setStatusTip( tr("Help About Qt") );
|
|
connect( a, SIGNAL( triggered() ), this, SLOT( helpAboutQt() ));
|
|
menu->addAction(a);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>load a msr-file.
|
|
*
|
|
* \param f filename
|
|
* \param index if == -1, add the file as a new tab, otherwise, replace the contents of the tab at index.
|
|
*/
|
|
void PTextEdit::load( const QString &f, const int index )
|
|
{
|
|
// check if the file exists
|
|
if ( !QFile::exists( f ) )
|
|
return;
|
|
|
|
// create a new text edit object
|
|
PSubTextEdit *edit = new PSubTextEdit( fAdmin );
|
|
edit->setFont(QFont(fAdmin->getFontName(), fAdmin->getFontSize()));
|
|
|
|
// place the text edit object at the appropriate tab position
|
|
if (index == -1)
|
|
fTabWidget->addTab( edit, QFileInfo( f ).fileName() );
|
|
else
|
|
fTabWidget->insertTab( index, edit, QFileInfo( f ).fileName() );
|
|
QFile file( f );
|
|
if ( !file.open( QIODevice::ReadOnly ) )
|
|
return;
|
|
|
|
// add file name to recent file names
|
|
fAdmin->addRecentFile(f); // keep it in admin
|
|
fillRecentFiles(); // update menu
|
|
|
|
// add the msr-file to the file system watchersssss
|
|
fFileSystemWatcher->addPath(f);
|
|
|
|
// read the file
|
|
QTextStream ts( &file );
|
|
QString txt = ts.readAll();
|
|
edit->setPlainText( txt );
|
|
doConnections( edit ); // add all necessary signal/slot connections
|
|
|
|
// set the tab widget to the current tab
|
|
fTabWidget->setCurrentIndex(fTabWidget->indexOf(edit));
|
|
edit->viewport()->setFocus();
|
|
|
|
// update the filename mapper
|
|
fFilenames.remove( edit );
|
|
fFilenames.insert( edit, f );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>returns the currently tab selected textedit object.
|
|
*/
|
|
PSubTextEdit *PTextEdit::currentEditor() const
|
|
{
|
|
if ( fTabWidget->currentWidget() ) {
|
|
if (fTabWidget->currentWidget()->inherits( "PSubTextEdit" )) {
|
|
return dynamic_cast<PSubTextEdit*>(fTabWidget->currentWidget());
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Setup the necessray signal/slot connections for the textedit object.
|
|
*
|
|
* \param e textedit object
|
|
*/
|
|
void PTextEdit::doConnections( PSubTextEdit *e )
|
|
{
|
|
// connect( e, SIGNAL( currentFontChanged( const QFont & ) ),
|
|
// this, SLOT( fontChanged( const QFont & ) ) );
|
|
|
|
connect( e, SIGNAL( textChanged() ), this, SLOT( textChanged() ));
|
|
|
|
connect( e, SIGNAL( cursorPositionChanged() ), this, SLOT( currentCursorPosition() ));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file title. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-title
|
|
*/
|
|
void PTextEdit::insertTitle()
|
|
{
|
|
currentEditor()->insertTitle();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file fit-parameter block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-fitparameter-block
|
|
*/
|
|
void PTextEdit::insertParameterBlock()
|
|
{
|
|
currentEditor()->insertParameterBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file theory block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-theory-block
|
|
*/
|
|
void PTextEdit::insertTheoryBlock()
|
|
{
|
|
currentEditor()->insertTheoryBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Insert a selected theory function. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-theory-block
|
|
*
|
|
* \param a action of the selected theory function
|
|
*/
|
|
void PTextEdit::insertTheoryFunction(QAction *a)
|
|
{
|
|
currentEditor()->insertTheoryFunction(a->text());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file function block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-functions-block
|
|
*/
|
|
void PTextEdit::insertFunctionBlock()
|
|
{
|
|
currentEditor()->insertFunctionBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file asymmetry run block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-run-block
|
|
*/
|
|
void PTextEdit::insertAsymRunBlock()
|
|
{
|
|
currentEditor()->insertAsymRunBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file single histogram run block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-run-block
|
|
*/
|
|
void PTextEdit::insertSingleHistRunBlock()
|
|
{
|
|
currentEditor()->insertSingleHistRunBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file nonMusr run block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-run-block
|
|
*/
|
|
void PTextEdit::insertNonMusrRunBlock()
|
|
{
|
|
currentEditor()->insertNonMusrRunBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Inserts a default command block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-commands-block
|
|
*/
|
|
void PTextEdit::insertCommandBlock()
|
|
{
|
|
currentEditor()->insertCommandBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file Fourier block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-fourier-block
|
|
*/
|
|
void PTextEdit::insertFourierBlock()
|
|
{
|
|
currentEditor()->insertFourierBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Start the dialog to enter a msr-file plot block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-plot-block
|
|
*/
|
|
void PTextEdit::insertPlotBlock()
|
|
{
|
|
currentEditor()->insertPlotBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Inserts a default statistics block. See also http://lmu.web.psi.ch/musrfit/user/html/user-manual.html#the-statistic-block
|
|
*/
|
|
void PTextEdit::insertStatisticBlock()
|
|
{
|
|
currentEditor()->insertStatisticBlock();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: called when File/New is selected. Will generate an empty tab-textedit field in musredit.
|
|
*/
|
|
void PTextEdit::fileNew()
|
|
{
|
|
PSubTextEdit *edit = new PSubTextEdit( fAdmin );
|
|
edit->setFont(QFont(fAdmin->getFontName(), fAdmin->getFontSize()));
|
|
doConnections( edit );
|
|
fTabWidget->addTab( edit, tr( "noname" ) );
|
|
fTabWidget->setCurrentIndex(fTabWidget->indexOf(edit));
|
|
fFilenames.insert(edit, tr("noname"));
|
|
edit->viewport()->setFocus();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: called when File/Open is selected. Will open an msr-/mlog-file. It checks if the file is
|
|
* already open, and if so will just select the current tab. If you want to reload the file use the
|
|
* fileReload() slot.
|
|
*/
|
|
void PTextEdit::fileOpen()
|
|
{
|
|
QStringList flns = QFileDialog::getOpenFileNames( this, tr("Open msr-/mlog-File"),
|
|
fLastDirInUse,
|
|
tr( "msr-Files (*.msr);;msr-Files (*.msr *.mlog);;All Files (*)" ));
|
|
|
|
QStringList::Iterator it = flns.begin();
|
|
QFileInfo finfo1;
|
|
bool alreadyOpen = false;
|
|
int idx;
|
|
|
|
// if flns are present, keep the corresponding directory
|
|
if (flns.size() > 0) {
|
|
finfo1.setFile(flns.at(0));
|
|
fLastDirInUse = finfo1.absoluteFilePath();
|
|
}
|
|
|
|
while( it != flns.end() ) {
|
|
// check if the file is not already open
|
|
finfo1.setFile(*it);
|
|
alreadyOpen = fileAlreadyOpen(finfo1, idx);
|
|
|
|
if (!alreadyOpen) {
|
|
load(*it);
|
|
} else {
|
|
fTabWidget->setCurrentIndex(idx);
|
|
fileReload();
|
|
}
|
|
|
|
++it;
|
|
}
|
|
|
|
// in case there is a 1st empty tab "noname", remove it
|
|
QString tabStr = fTabWidget->tabText(0);
|
|
tabStr.remove('&'); // this is needed since the QTabWidget adds short-cut info as '&' to the tab name
|
|
if (tabStr == "noname") { // has to be the first, otherwise do nothing
|
|
fFileSystemWatcher->removePath("noname");
|
|
|
|
delete fTabWidget->widget(0);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>This slot will open the file from the recent file list. If already open, it will reload it.
|
|
*/
|
|
void PTextEdit::fileOpenRecent()
|
|
{
|
|
QAction *action = qobject_cast<QAction *>(sender());
|
|
|
|
if (action) {
|
|
// check if this file is already open and if so, switch the tab
|
|
QFileInfo finfo1, finfo2;
|
|
QString tabFln;
|
|
bool alreadyOpen = false;
|
|
QString fln = action->text();
|
|
fln.remove('&');
|
|
finfo1.setFile(fln);
|
|
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
tabFln = *fFilenames.find( dynamic_cast<PSubTextEdit*>(fTabWidget->widget(i)));
|
|
finfo2.setFile(tabFln);
|
|
if (finfo1.absoluteFilePath() == finfo2.absoluteFilePath()) {
|
|
alreadyOpen = true;
|
|
fTabWidget->setCurrentIndex(i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!alreadyOpen) {
|
|
// make sure the file exists
|
|
if (!finfo1.exists()) {
|
|
QMessageBox::critical(this, "ERROR", QString("File '%1' does not exist.\nWill not do anything.").arg(fln));
|
|
return;
|
|
}
|
|
load(fln);
|
|
} else {
|
|
fileReload();
|
|
}
|
|
|
|
// in case there is a 1st empty tab "noname", remove it
|
|
fln = fTabWidget->tabText(0);
|
|
fln.remove("&");
|
|
if (fln == "noname") { // has to be the first, otherwise do nothing
|
|
fFileSystemWatcher->removePath("noname");
|
|
|
|
delete fTabWidget->widget(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will reload the currently selected msr-file.
|
|
*/
|
|
void PTextEdit::fileReload()
|
|
{
|
|
if ( fFilenames.find( currentEditor() ) == fFilenames.end() ) {
|
|
QMessageBox::critical(this, "**ERROR**", "Cannot reload a file not previously saved ;-)");
|
|
} else {
|
|
int index = fTabWidget->currentIndex();
|
|
QString fln = *fFilenames.find( currentEditor() );
|
|
fileClose(false);
|
|
load(fln, index);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will save the currently selected file.
|
|
*/
|
|
void PTextEdit::fileOpenPrefs()
|
|
{
|
|
QString fln("");
|
|
QString msg("");
|
|
QMessageBox msgBox;
|
|
msgBox.setText("Which Preferences do you want to open?");
|
|
msgBox.addButton("Default", QMessageBox::AcceptRole);
|
|
msgBox.addButton("Custom", QMessageBox::AcceptRole);
|
|
msgBox.setStandardButtons(QMessageBox::Cancel);
|
|
int result = msgBox.exec();
|
|
if (result == QMessageBox::Cancel) {
|
|
return;
|
|
} else if (result == 0) { // default dir
|
|
fln = fAdmin->getDefaultPrefPathName();
|
|
msg = QString("Current Default Preferences Path-Name:\n") + fln;
|
|
if (QMessageBox::information(this, "Info", msg, QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel)
|
|
return;
|
|
} else if (result == 1) { // custom dir
|
|
fln = QFileDialog::getOpenFileName( this, tr("Open Prefs"),
|
|
fLastDirInUse,
|
|
tr( "xml-Files (*.xml);; All Files (*)" ));
|
|
}
|
|
|
|
if (fAdmin->loadPrefs(fln)) {
|
|
msg = QString("Prefs from '") + fln + QString("' loaded.");
|
|
QMessageBox::information(nullptr, "Info", msg);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will save the currently selected file.
|
|
*/
|
|
void PTextEdit::fileSave()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
fFileSystemWatcherActive = false;
|
|
|
|
if ( *fFilenames.find( currentEditor() ) == QString("noname") ) {
|
|
fileSaveAs();
|
|
} else {
|
|
QFile file( *fFilenames.find( currentEditor() ) );
|
|
if ( !file.open( QIODevice::WriteOnly ) )
|
|
return;
|
|
QTextStream ts( &file );
|
|
ts << currentEditor()->toPlainText();
|
|
|
|
// remove trailing '*' modification indicators
|
|
QString fln = *fFilenames.find( currentEditor() );
|
|
fTabWidget->setTabText(fTabWidget->indexOf( currentEditor() ), QFileInfo(fln).fileName());
|
|
}
|
|
|
|
fileSystemWatcherActivation(); // delayed activation of fFileSystemWatcherActive
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will open a file selector dialog to obtain a file name, and then save the file under the newly
|
|
* selected file name.
|
|
*/
|
|
void PTextEdit::fileSaveAs()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
fFileSystemWatcherActive = false;
|
|
|
|
QString fn = QFileDialog::getSaveFileName( this,
|
|
tr( "Save msr-/mlog-file As" ), *fFilenames.find( currentEditor() ),
|
|
tr( "msr-Files (*.msr *.mlog);;All Files (*)" ) );
|
|
if ( !fn.isEmpty() ) {
|
|
fFilenames.remove( currentEditor() );
|
|
fFilenames.insert( currentEditor(), fn );
|
|
fileSave();
|
|
fTabWidget->setTabText(fTabWidget->indexOf( currentEditor() ), QFileInfo(fn).fileName());
|
|
}
|
|
|
|
fileSystemWatcherActivation(); // delayed activation of fFileSystemWatcherActive
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will save the current preferences.
|
|
*/
|
|
void PTextEdit::fileSavePrefs()
|
|
{
|
|
QString fln("");
|
|
QString msg("");
|
|
QMessageBox msgBox;
|
|
msgBox.setText("Which Preferences do you want to open?");
|
|
msgBox.addButton("Default", QMessageBox::AcceptRole);
|
|
msgBox.addButton("Custom", QMessageBox::AcceptRole);
|
|
msgBox.setStandardButtons(QMessageBox::Cancel);
|
|
int result = msgBox.exec();
|
|
if (result == QMessageBox::Cancel) {
|
|
return;
|
|
} else if (result == 0) { // default dir
|
|
fln = fAdmin->getDefaultPrefPathName();
|
|
msg = QString("Current Default Preferences Path-Name:\n") + fln;
|
|
if (QMessageBox::information(this, "Info", msg, QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Cancel)
|
|
return;
|
|
} else if (result == 1) { // custom dir
|
|
fln = QFileDialog::getSaveFileName( this,
|
|
tr( "Save Prefs As" ), "musredit_startup.xml",
|
|
tr( "xml-Files (*.xml);;All Files (*)" ) );
|
|
}
|
|
|
|
if ( !fln.isEmpty() ) {
|
|
fAdmin->savePrefs(fln);
|
|
msg = QString("Prefs to '") + fln + QString("' saved.");
|
|
QMessageBox::information(nullptr, "Info", msg);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will call a print dialog and print the msr-file.
|
|
*/
|
|
void PTextEdit::filePrint()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
#ifndef QT_NO_PRINTER
|
|
QPrinter printer( QPrinter::HighResolution );
|
|
printer.setFullPage(true);
|
|
QPrintDialog dialog(&printer, this);
|
|
if (dialog.exec()) { // printer dialog
|
|
statusBar()->showMessage( "Printing..." );
|
|
|
|
QPainter p( &printer );
|
|
// Check that there is a valid device to print to.
|
|
if ( !p.device() )
|
|
return;
|
|
|
|
QFont font( currentEditor()->QWidget::font() );
|
|
font.setPointSize( 10 ); // we define 10pt to be a nice base size for printing
|
|
p.setFont( font );
|
|
|
|
int yPos = 0; // y-position for each line
|
|
QFontMetrics fm = p.fontMetrics();
|
|
int dpiy = printer.logicalDpiY();
|
|
int margin = static_cast<int>( (2/2.54)*dpiy ); // 2 cm margins
|
|
|
|
// print msr-file
|
|
QString fln = *fFilenames.find(currentEditor());
|
|
QString header1(fln);
|
|
QFileInfo flnInfo(fln);
|
|
QString header2 = QString("last modified: ") + flnInfo.lastModified().toString("dd.MM.yyyy - hh:mm:ss");
|
|
QString line("-------------------------------------");
|
|
QStringList strList = currentEditor()->toPlainText().split("\n");
|
|
for (QStringList::Iterator it = strList.begin(); it != strList.end(); ++it) {
|
|
// new page needed?
|
|
if ( margin + yPos > printer.height() - margin ) {
|
|
printer.newPage(); // no more room on this page
|
|
yPos = 0; // back to top of page
|
|
}
|
|
|
|
if (yPos == 0) { // print header
|
|
font.setPointSize( 8 );
|
|
p.setFont( font );
|
|
|
|
p.drawText(margin, margin+yPos, printer.width(), fm.lineSpacing(),
|
|
Qt::TextExpandTabs | Qt::TextDontClip, header1);
|
|
yPos += fm.lineSpacing();
|
|
p.drawText(margin, margin+yPos, printer.width(), fm.lineSpacing(),
|
|
Qt::TextExpandTabs | Qt::TextDontClip, header2);
|
|
yPos += fm.lineSpacing();
|
|
p.drawText(margin, margin+yPos, printer.width(), fm.lineSpacing(),
|
|
Qt::TextExpandTabs | Qt::TextDontClip, line);
|
|
yPos += 1.5*fm.lineSpacing();
|
|
|
|
font.setPointSize( 10 );
|
|
p.setFont( font );
|
|
}
|
|
|
|
// print data
|
|
p.drawText(margin, margin+yPos, printer.width(), fm.lineSpacing(),
|
|
Qt::TextExpandTabs | Qt::TextDontClip, *it);
|
|
yPos += fm.lineSpacing();
|
|
}
|
|
|
|
p.end();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will remove a textedit tab from musredit. Depending on check it will done with or without checking
|
|
* if the file has been saved before.
|
|
*
|
|
* \param check if set to true, a warning dialog will popup if the file is not saved yet.
|
|
*/
|
|
void PTextEdit::fileClose(const bool check)
|
|
{
|
|
// first check if there is any tab present
|
|
if (fTabWidget->count()==0) // no tabs present
|
|
return;
|
|
|
|
// check if the has modification
|
|
int idx = fTabWidget->currentIndex();
|
|
|
|
if ((fTabWidget->tabText(idx).indexOf("*")>0) && check) {
|
|
int result = QMessageBox::warning(this, "**WARNING**",
|
|
"Do you really want to close this file.\nChanges will be lost",
|
|
"Close", "Cancel");
|
|
if (result == 1) // Cancel
|
|
return;
|
|
}
|
|
|
|
QString str = *fFilenames.find(currentEditor());
|
|
fFileSystemWatcher->removePath(str);
|
|
|
|
delete currentEditor();
|
|
|
|
if ( currentEditor() )
|
|
currentEditor()->viewport()->setFocus();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Removes all textedit tabs from musredit. It checks if the files haven't been saved, and if so it will
|
|
* popup a warning dialog.
|
|
*/
|
|
void PTextEdit::fileCloseAll()
|
|
{
|
|
// check if any editor tab is present, if not: get out of here
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
// check if there are any unsaved tabs
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
if (fTabWidget->tabText(i).indexOf("*") > 0) {
|
|
int result = QMessageBox::warning(this, "**WARNING**",
|
|
"Do you really want to close all files.\nChanges of unsaved files will be lost",
|
|
"Close", "Cancel");
|
|
if (result == 1) // Cancel
|
|
return;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// close all editor tabs
|
|
QString str;
|
|
do {
|
|
// remove file from file system watcher
|
|
str = *fFilenames.find(currentEditor());
|
|
fFileSystemWatcher->removePath(str);
|
|
|
|
delete currentEditor();
|
|
|
|
if ( currentEditor() )
|
|
currentEditor()->viewport()->setFocus();
|
|
} while ( currentEditor() );
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will close all textedit tabs but the selected one. It checks if the files haven't been saved, and if so it will
|
|
* popup a warning dialog.
|
|
*/
|
|
void PTextEdit::fileCloseAllOthers()
|
|
{
|
|
// check if any editor tab is present, if not: get out of here
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
// check if there are any unsaved tabs
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
if (fTabWidget->tabText(i).indexOf("*") > 0) {
|
|
int result = QMessageBox::warning(this, "**WARNING**",
|
|
"Do you really want to close all files.\nChanges of unsaved files will be lost",
|
|
"Close", "Cancel");
|
|
if (result == 1) // Cancel
|
|
return;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// keep label of the current editor
|
|
QString label = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
|
|
// check if only the current editor is present. If yes: nothing to be done
|
|
if (fTabWidget->count() == 1)
|
|
return;
|
|
|
|
// close all editor tabs
|
|
int i=0;
|
|
QString str;
|
|
do {
|
|
if (fTabWidget->tabText(i) != label) {
|
|
// remove file from file system watcher
|
|
str = *fFilenames.find(dynamic_cast<PSubTextEdit*>(fTabWidget->widget(i)));
|
|
fFileSystemWatcher->removePath(str);
|
|
|
|
delete fTabWidget->widget(i);
|
|
} else {
|
|
i++;
|
|
}
|
|
} while ( fTabWidget->count() > 1 );
|
|
|
|
currentEditor()->viewport()->setFocus();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Will quit musredit.
|
|
*/
|
|
void PTextEdit::fileExit()
|
|
{
|
|
// check if there are still some modified files open
|
|
for (int i=0; i < fTabWidget->count(); i++) {
|
|
if (fTabWidget->tabText(i).indexOf("*") > 0) {
|
|
int result = QMessageBox::warning(this, "**WARNING**",
|
|
"Do you really want to exit from the applcation.\nChanges will be lost",
|
|
"Exit", "Cancel");
|
|
if (result == 1) // Cancel
|
|
return;
|
|
break;
|
|
}
|
|
}
|
|
|
|
qApp->quit();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Text undo of the current textedit tab.
|
|
*/
|
|
void PTextEdit::editUndo()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
currentEditor()->undo();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Text redo of the current textedit tab
|
|
*/
|
|
void PTextEdit::editRedo()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
currentEditor()->redo();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Select all text of the current textedit tab.
|
|
*/
|
|
void PTextEdit::editSelectAll()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
currentEditor()->selectAll();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Cut the selection of the current textedit tab.
|
|
*/
|
|
void PTextEdit::editCut()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
currentEditor()->cut();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Copy the selection of the current textedit tab.
|
|
*/
|
|
void PTextEdit::editCopy()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
currentEditor()->copy();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Paste at the cursor position of the current textedit tab.
|
|
*/
|
|
void PTextEdit::editPaste()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
currentEditor()->paste();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Starts a find dialog, and searches for a find string.
|
|
*/
|
|
void PTextEdit::editFind()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
// check if first time called, and if yes create find and replace data structure
|
|
if (fFindReplaceData == nullptr) {
|
|
fFindReplaceData = new PFindReplaceData();
|
|
fFindReplaceData->findText = QString("");
|
|
fFindReplaceData->replaceText = QString("");
|
|
fFindReplaceData->caseSensitive = true;
|
|
fFindReplaceData->wholeWordsOnly = false;
|
|
fFindReplaceData->fromCursor = true;
|
|
fFindReplaceData->findBackwards = false;
|
|
fFindReplaceData->selectedText = false;
|
|
fFindReplaceData->promptOnReplace = true;
|
|
}
|
|
|
|
if (fFindReplaceData == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR**", "Couldn't invoke find data structure, sorry :-(", QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
PFindDialog *dlg = new PFindDialog(fFindReplaceData, currentEditor()->textCursor().hasSelection());
|
|
if (dlg == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR**", "Couldn't invoke find dialog, sorry :-(", QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
dlg->exec();
|
|
|
|
if (dlg->result() != QDialog::Accepted) {
|
|
delete dlg;
|
|
return;
|
|
}
|
|
|
|
fFindReplaceData = dlg->getData();
|
|
|
|
delete dlg;
|
|
dlg = nullptr;
|
|
|
|
// try to find the search text
|
|
if (!fFindReplaceData->fromCursor)
|
|
currentEditor()->textCursor().setPosition(0);
|
|
|
|
QTextDocument::FindFlags flags = nullptr;
|
|
if (fFindReplaceData->caseSensitive)
|
|
flags |= QTextDocument::FindCaseSensitively;
|
|
else if (fFindReplaceData->findBackwards)
|
|
flags |= QTextDocument::FindBackward;
|
|
else if (fFindReplaceData->wholeWordsOnly)
|
|
flags |= QTextDocument::FindWholeWords;
|
|
|
|
currentEditor()->find(fFindReplaceData->findText, flags);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Searches for a find string in the forward direction.
|
|
*/
|
|
void PTextEdit::editFindNext()
|
|
{
|
|
QTextDocument::FindFlags flags = nullptr;
|
|
if (fFindReplaceData->caseSensitive)
|
|
flags |= QTextDocument::FindCaseSensitively;
|
|
else if (fFindReplaceData->wholeWordsOnly)
|
|
flags |= QTextDocument::FindWholeWords;
|
|
|
|
currentEditor()->find(fFindReplaceData->findText, flags);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Searches for a find string in the backward direction.
|
|
*/
|
|
void PTextEdit::editFindPrevious()
|
|
{
|
|
QTextDocument::FindFlags flags = nullptr;
|
|
if (fFindReplaceData->caseSensitive)
|
|
flags |= QTextDocument::FindCaseSensitively;
|
|
else if (fFindReplaceData->wholeWordsOnly)
|
|
flags |= QTextDocument::FindWholeWords;
|
|
|
|
flags |= QTextDocument::FindBackward;
|
|
|
|
currentEditor()->find(fFindReplaceData->findText, flags);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Starts a find/replace dialog, and searches for a find string and replaces it depending of the replace options.
|
|
*/
|
|
void PTextEdit::editFindAndReplace()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
// check if first time called, and if yes create find and replace data structure
|
|
if (fFindReplaceData == nullptr) {
|
|
fFindReplaceData = new PFindReplaceData();
|
|
fFindReplaceData->findText = QString("");
|
|
fFindReplaceData->replaceText = QString("");
|
|
fFindReplaceData->caseSensitive = true;
|
|
fFindReplaceData->wholeWordsOnly = false;
|
|
fFindReplaceData->fromCursor = true;
|
|
fFindReplaceData->findBackwards = false;
|
|
fFindReplaceData->selectedText = false;
|
|
fFindReplaceData->promptOnReplace = true;
|
|
}
|
|
|
|
if (fFindReplaceData == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR**", "Couldn't invoke find&replace data structure, sorry :-(", QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
PReplaceDialog *dlg = new PReplaceDialog(fFindReplaceData, currentEditor()->textCursor().hasSelection());
|
|
if (dlg == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR**", "Couldn't invoke find&replace dialog, sorry :-(", QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
dlg->exec();
|
|
|
|
if (dlg->result() != QDialog::Accepted) {
|
|
delete dlg;
|
|
return;
|
|
}
|
|
|
|
fFindReplaceData = dlg->getData();
|
|
|
|
delete dlg;
|
|
dlg = nullptr;
|
|
|
|
if (fFindReplaceData->promptOnReplace) {
|
|
editFindNext();
|
|
|
|
PReplaceConfirmationDialog confirmDlg(this);
|
|
|
|
// connect all the necessary signals/slots
|
|
QObject::connect(confirmDlg.fReplace_pushButton, SIGNAL(clicked()), this, SLOT(replace()));
|
|
QObject::connect(confirmDlg.fReplaceAndClose_pushButton, SIGNAL(clicked()), this, SLOT(replaceAndClose()));
|
|
QObject::connect(confirmDlg.fReplaceAll_pushButton, SIGNAL(clicked()), this, SLOT(replaceAll()));
|
|
QObject::connect(confirmDlg.fFindNext_pushButton, SIGNAL(clicked()), this, SLOT(editFindNext()));
|
|
QObject::connect(this, SIGNAL(close()), &confirmDlg, SLOT(accept()));
|
|
|
|
confirmDlg.exec();
|
|
} else {
|
|
replaceAll();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Comment a selection, i.e. add a '#' character in front of each line of the selection.
|
|
* (Multiple selections not yet supported).
|
|
*/
|
|
void PTextEdit::editComment()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
|
|
QTextCursor curs = currentEditor()->textCursor();
|
|
|
|
if (curs.hasComplexSelection()) { // multiple selections
|
|
// multiple selections (STILL MISSING)
|
|
} else if (curs.hasSelection()) { // simple selection
|
|
int pos = curs.position();
|
|
int secStart = curs.selectionStart(); // keep start position of the selection
|
|
int secEnd = curs.selectionEnd(); // keep end position of the selection
|
|
curs.clearSelection();
|
|
curs.setPosition(secStart); // set the anchor to the start of the selection
|
|
curs.movePosition(QTextCursor::StartOfBlock);
|
|
do {
|
|
curs.insertText("#");
|
|
} while (curs.movePosition(QTextCursor::NextBlock) && (curs.position() <= secEnd));
|
|
curs.setPosition(pos+1);
|
|
} else { // no selection
|
|
int pos = curs.position();
|
|
curs.clearSelection();
|
|
curs.movePosition(QTextCursor::StartOfLine);
|
|
curs.insertText("#");
|
|
curs.setPosition(pos+1);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Uncomment a selection, i.e. remove a '#' character in front of each line of the selection.
|
|
* (Multiple selections not yet supported).
|
|
*/
|
|
void PTextEdit::editUncomment()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
|
|
QTextCursor curs = currentEditor()->textCursor();
|
|
|
|
if (curs.hasComplexSelection()) {
|
|
// multiple selections (STILL MISSING)
|
|
} else if (curs.hasSelection()) {
|
|
int pos = curs.position();
|
|
int secStart = curs.selectionStart(); // keep start position of the selection
|
|
int secEnd = curs.selectionEnd(); // keep end position of the selection
|
|
curs.clearSelection();
|
|
curs.setPosition(secStart); // set the anchor to the start of the selection
|
|
curs.movePosition(QTextCursor::StartOfBlock);
|
|
while (curs.position() < secEnd) {
|
|
QString line = curs.block().text();
|
|
if (line.startsWith("#")) {
|
|
line.remove(0, 1);
|
|
curs.select(QTextCursor::BlockUnderCursor);
|
|
curs.removeSelectedText();
|
|
curs.insertText("\n"+line);
|
|
pos -= 1;
|
|
}
|
|
curs.movePosition(QTextCursor::NextBlock);
|
|
}
|
|
curs.setPosition(pos);
|
|
currentEditor()->setTextCursor(curs); // needed to update document cursor
|
|
} else { // no selection
|
|
int pos = curs.position();
|
|
curs.clearSelection();
|
|
curs.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor, 1);
|
|
QString line = curs.block().text();
|
|
if (line.startsWith("#")) {
|
|
line.remove(0, 1);
|
|
curs.select(QTextCursor::BlockUnderCursor);
|
|
curs.removeSelectedText();
|
|
if (currentEditor()->textCursor().columnNumber() == 0)
|
|
curs.insertText(line);
|
|
else
|
|
curs.insertText("\n"+line);
|
|
pos -= 1;
|
|
}
|
|
curs.setPosition(pos);
|
|
currentEditor()->setTextCursor(curs); // needed to update document cursor
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Chances the font.
|
|
*
|
|
* \param f font name
|
|
*/
|
|
void PTextEdit::textFamily( const QString &f )
|
|
{
|
|
fAdmin->setFontName(f);
|
|
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
currentEditor()->setFont(QFont(f,fAdmin->getFontSize()));
|
|
currentEditor()->viewport()->setFocus();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Chances the font size.
|
|
*
|
|
* \param p font size in points.
|
|
*/
|
|
void PTextEdit::textSize( const QString &p )
|
|
{
|
|
fAdmin->setFontSize(p.toInt());
|
|
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
currentEditor()->setFont(QFont(fAdmin->getFontName(), p.toInt()));
|
|
currentEditor()->viewport()->setFocus();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::musrWiz
|
|
*/
|
|
void PTextEdit::musrWiz()
|
|
{
|
|
QString cmd = fAdmin->getExecPath() + "/musrWiz";
|
|
#if defined(Q_OS_DARWIN) || defined(Q_OS_MAC)
|
|
cmd = QString("/Applications/musrWiz.app/Contents/MacOS/musrWiz");
|
|
#endif
|
|
QString workDir = "./"; // think about it!!
|
|
QStringList arg;
|
|
arg << "--log";
|
|
|
|
QProcess *proc = new QProcess(this);
|
|
if (proc == nullptr) {
|
|
QMessageBox::critical(nullptr, "**ERROR**", "Couldn't invoke QProcess!");
|
|
return;
|
|
}
|
|
|
|
// handle return status of musrWiz
|
|
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
|
[=](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrWiz(exitCode, exitStatus); });
|
|
|
|
// make sure that the system environment variables are properly set
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH"));
|
|
proc->setProcessEnvironment(env);
|
|
proc->setWorkingDirectory(workDir);
|
|
proc->start(cmd, arg);
|
|
if (!proc->waitForStarted()) {
|
|
// error handling
|
|
QString msg(tr("Could not execute the output command: ")+cmd[0]);
|
|
QMessageBox::critical( nullptr,
|
|
tr("Fatal error"),
|
|
msg,
|
|
tr("Quit") );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>calls musrfit --chisq-only <msr-file>.
|
|
*/
|
|
void PTextEdit::musrCalcChisq()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
int result = 0;
|
|
int fittype = currentEditor()->getFitType();
|
|
if (fAdmin->getEstimateN0Flag() && ((fittype==0) || (fittype==4)))
|
|
result = QMessageBox::question(this, "Estimate N0 active",
|
|
"Do you wish a chisq/mlh evaluation with an automatic N0 estimate?");
|
|
|
|
QString tabLabel = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
if (tabLabel == "noname") {
|
|
QMessageBox::critical(this, "**ERROR**", "For a fit a real msr-file is needed.");
|
|
return;
|
|
} else if (tabLabel == "noname*") {
|
|
fileSaveAs();
|
|
} else if (tabLabel.indexOf("*") > 0) {
|
|
fileSave();
|
|
}
|
|
|
|
QVector<QString> cmd;
|
|
QString str;
|
|
str = fAdmin->getExecPath() + "/musrfit";
|
|
|
|
cmd.append(str);
|
|
cmd.append(QFileInfo(*fFilenames.find( currentEditor())).fileName() );
|
|
cmd.append("--chisq-only");
|
|
if (fAdmin->getEstimateN0Flag() && (result == QMessageBox::Yes) && ((fittype==0) || (fittype==4)))
|
|
cmd.append("--estimateN0");
|
|
PFitOutputHandler fitOutputHandler(QFileInfo(*fFilenames.find( currentEditor() )).absolutePath(), cmd);
|
|
fitOutputHandler.setModal(true);
|
|
fitOutputHandler.exec();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>calls musrfit <options> <msr-file>. <options> can be set in the MusrFit/Preferences.
|
|
*/
|
|
void PTextEdit::musrFit()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
QString tabLabel = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
if (tabLabel == "noname") {
|
|
QMessageBox::critical(this, "**ERROR**", "For a fit a real msr-file is needed.");
|
|
return;
|
|
} else if (tabLabel == "noname*") {
|
|
fileSaveAs();
|
|
} else if (tabLabel.indexOf("*") > 0) {
|
|
fileSave();
|
|
}
|
|
|
|
QVector<QString> cmd;
|
|
QString str;
|
|
str = fAdmin->getExecPath() + "/musrfit";
|
|
|
|
cmd.append(str);
|
|
cmd.append(QFileInfo(*fFilenames.find( currentEditor())).fileName() );
|
|
|
|
// check if keep minuit2 output is wished
|
|
if (fAdmin->getKeepMinuit2OutputFlag())
|
|
cmd.append("--keep-mn2-output");
|
|
|
|
// check if title of the data file should be used to replace the msr-file title
|
|
if (fAdmin->getTitleFromDataFileFlag())
|
|
cmd.append("--title-from-data-file");
|
|
|
|
// check if dump files are wished
|
|
if (fAdmin->getDumpAsciiFlag()) {
|
|
cmd.append("--dump");
|
|
cmd.append("ascii");
|
|
}
|
|
if (fAdmin->getDumpRootFlag()) {
|
|
cmd.append("--dump");
|
|
cmd.append("root");
|
|
}
|
|
|
|
// check estimate N0 flag
|
|
if (fAdmin->getEstimateN0Flag()) {
|
|
cmd.append("--estimateN0");
|
|
}
|
|
|
|
// check per-run-block-chisq flag
|
|
if (fAdmin->getChisqPerRunBlockFlag()) {
|
|
cmd.append("--per-run-block-chisq");
|
|
}
|
|
|
|
// add timeout
|
|
cmd.append("--timeout");
|
|
QString numStr;
|
|
numStr.setNum(fAdmin->getTimeout());
|
|
cmd.append(numStr);
|
|
|
|
PFitOutputHandler fitOutputHandler(QFileInfo(*fFilenames.find( currentEditor() )).absolutePath(), cmd);
|
|
fitOutputHandler.setModal(true);
|
|
fFileSystemWatcherActive = false;
|
|
fitOutputHandler.exec();
|
|
|
|
// handle the reloading of the files
|
|
|
|
// get current file name
|
|
QString currentFileName = *fFilenames.find( currentEditor() );
|
|
QString complementFileName;
|
|
// check if it is a msr-, mlog-, or another file
|
|
int idx;
|
|
if ((idx = currentFileName.indexOf(".msr")) > 0) { // msr-file
|
|
complementFileName = currentFileName;
|
|
complementFileName.replace(idx, 5, ".mlog");
|
|
} else if ((idx = currentFileName.indexOf(".mlog")) > 0) { // mlog-file
|
|
complementFileName = currentFileName;
|
|
complementFileName.replace(idx, 5, ".msr ");
|
|
complementFileName = complementFileName.trimmed();
|
|
} else { // neither a msr- nor a mlog-file
|
|
QMessageBox::information( this, "musrFit",
|
|
"This is neither a msr- nor a mlog-file, hence no idea what to be done.\n",
|
|
QMessageBox::Ok );
|
|
return;
|
|
}
|
|
|
|
int currentIdx = fTabWidget->currentIndex();
|
|
|
|
// reload current file
|
|
fileClose();
|
|
load(currentFileName, currentIdx);
|
|
|
|
// check if swap file is open as well, and if yes, reload it
|
|
idx = -1;
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
if (fTabWidget->tabText(i).indexOf(complementFileName) >= 0) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
if (idx >= 0) { // complement file is open
|
|
fTabWidget->setCurrentIndex(idx);
|
|
fileClose();
|
|
load(complementFileName, idx);
|
|
fTabWidget->setCurrentIndex(currentIdx);
|
|
}
|
|
|
|
fileSystemWatcherActivation();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Starts a msr2data input dialog which collects all the necessary data before calling msr2data.
|
|
*/
|
|
void PTextEdit::musrMsr2Data()
|
|
{
|
|
if (fMsr2DataParam == nullptr) {
|
|
fMsr2DataParam = new PMsr2DataParam();
|
|
*fMsr2DataParam = fAdmin->getMsr2DataParam();
|
|
}
|
|
|
|
// init fMsr2DataParam
|
|
fMsr2DataParam->keepMinuit2Output = fAdmin->getKeepMinuit2OutputFlag();
|
|
fMsr2DataParam->titleFromDataFile = fAdmin->getTitleFromDataFileFlag();
|
|
fMsr2DataParam->estimateN0 = fAdmin->getEstimateN0Flag();
|
|
fMsr2DataParam->perRunBlockChisq = fAdmin->getChisqPerRunBlockFlag();
|
|
|
|
PMsr2DataDialog *dlg = new PMsr2DataDialog(fMsr2DataParam, fAdmin->getHelpUrl("msr2data"));
|
|
|
|
if (dlg == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR**", "Couldn't invoke msr2data dialog, sorry :-(", QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
if (dlg->exec() == QDialog::Accepted) {
|
|
QString runList;
|
|
QString runListFileName;
|
|
QFileInfo fi;
|
|
QString str;
|
|
int i, end;
|
|
QStringList list;
|
|
bool ok;
|
|
|
|
fMsr2DataParam = dlg->getMsr2DataParam();
|
|
fAdmin->setKeepMinuit2OutputFlag(fMsr2DataParam->keepMinuit2Output);
|
|
fAdmin->setTitleFromDataFileFlag(fMsr2DataParam->titleFromDataFile);
|
|
fAdmin->setEstimateN0Flag(fMsr2DataParam->estimateN0);
|
|
fAdmin->setChisqPerRunBlockFlag(fMsr2DataParam->perRunBlockChisq);
|
|
|
|
// analyze parameters
|
|
switch (dlg->getRunTag()) {
|
|
case -1: // not valid
|
|
QMessageBox::critical(this, "**ERROR**",
|
|
"No valid run list input found :-(\nCannot do anything.",
|
|
QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
break;
|
|
case 0: // run list
|
|
runList = fMsr2DataParam->runList;
|
|
break;
|
|
case 1: // run list file name
|
|
runListFileName = fMsr2DataParam->runListFileName;
|
|
fi.setFile(QFileInfo(*fFilenames.find( currentEditor() )).absolutePath() + "/" + runListFileName);
|
|
if (!fi.exists()) {
|
|
str = QString("Run List File '%1' doesn't exist.").arg(runListFileName);
|
|
QMessageBox::critical(this, "**ERROR**",
|
|
str, QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
break;
|
|
default: // never should reach this point
|
|
QMessageBox::critical(this, "**ERROR**",
|
|
"No idea how you could reach this point.\nPlease contact the developers.",
|
|
QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
break;
|
|
}
|
|
|
|
// form command
|
|
QVector<QString> cmd;
|
|
|
|
str = fAdmin->getExecPath() + "/msr2data";
|
|
cmd.append(str);
|
|
|
|
// run list argument
|
|
switch (dlg->getRunTag()) {
|
|
case 0:
|
|
end = 0;
|
|
while (!runList.section(' ', end, end, QString::SectionSkipEmpty).isEmpty()) {
|
|
end++;
|
|
}
|
|
// first element
|
|
if (end == 1) {
|
|
str = "[" + runList + "]";
|
|
cmd.append(str);
|
|
} else {
|
|
str = "[" + runList.section(' ', 0, 0, QString::SectionSkipEmpty);
|
|
cmd.append(str);
|
|
// middle elements
|
|
for (i=1; i<end-1; i++) {
|
|
cmd.append(runList.section(' ', i, i, QString::SectionSkipEmpty));
|
|
}
|
|
// last element
|
|
str = runList.section(' ', end-1, end-1, QString::SectionSkipEmpty) + "]";
|
|
cmd.append(str);
|
|
}
|
|
break;
|
|
case 1:
|
|
cmd.append(runListFileName);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// file extension
|
|
str = fMsr2DataParam->msrFileExtension;
|
|
if (str.isEmpty())
|
|
cmd.append("");
|
|
else
|
|
cmd.append(str);
|
|
|
|
// options
|
|
|
|
// parameter export list
|
|
if (!fMsr2DataParam->paramList.isEmpty()) {
|
|
cmd.append("paramList");
|
|
QStringList list = fMsr2DataParam->paramList.split(' ');
|
|
for (int i=0; i<list.size(); i++)
|
|
cmd.append(list[i]);
|
|
}
|
|
|
|
// no header flag?
|
|
if (!fMsr2DataParam->writeDbHeader)
|
|
cmd.append("noheader");
|
|
|
|
// ignore data header info flag present?
|
|
if (fMsr2DataParam->ignoreDataHeaderInfo)
|
|
cmd.append("nosummary");
|
|
|
|
// template run no fitting but: (i) no fit only flag, (ii) no create msr-file only flag
|
|
if ((fMsr2DataParam->templateRunNo != -1) && !fMsr2DataParam->fitOnly && !fMsr2DataParam->createMsrFileOnly) {
|
|
str = QString("%1").arg(fMsr2DataParam->templateRunNo);
|
|
str = "fit-" + str;
|
|
if (!fMsr2DataParam->chainFit) {
|
|
str += "!";
|
|
}
|
|
cmd.append(str);
|
|
}
|
|
|
|
// template run no AND create msr-file only flag
|
|
if ((fMsr2DataParam->templateRunNo != -1) && fMsr2DataParam->createMsrFileOnly) {
|
|
str = QString("%1").arg(fMsr2DataParam->templateRunNo);
|
|
str = "msr-" + str;
|
|
cmd.append(str);
|
|
}
|
|
|
|
// fit only
|
|
if (fMsr2DataParam->fitOnly) {
|
|
str = "fit";
|
|
cmd.append(str);
|
|
}
|
|
|
|
// keep minuit2 output
|
|
if (fMsr2DataParam->keepMinuit2Output) {
|
|
cmd.append("-k");
|
|
}
|
|
|
|
// replace msr-file title by data file title. Add flag only if a fit is done
|
|
if (fMsr2DataParam->titleFromDataFile && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
|
|
cmd.append("-t");
|
|
}
|
|
|
|
// estimate N0 (makes sence for single histo and muMinus fits only). Add flag only if a fit is done
|
|
if (fMsr2DataParam->estimateN0 && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
|
|
cmd.append("-e");
|
|
}
|
|
|
|
// write per-run-block chisq. Add flag only if a fit is done
|
|
if (fMsr2DataParam->perRunBlockChisq && (fMsr2DataParam->fitOnly || fMsr2DataParam->templateRunNo != -1)) {
|
|
cmd.append("-p");
|
|
}
|
|
|
|
// DB output wished
|
|
if (!fMsr2DataParam->dbOutputFileName.isEmpty()) {
|
|
str = "-o" + fMsr2DataParam->dbOutputFileName;
|
|
cmd.append(str);
|
|
}
|
|
|
|
// write column data
|
|
if (fMsr2DataParam->writeColumnData) {
|
|
cmd.append("data");
|
|
}
|
|
|
|
// global flag check
|
|
if (fMsr2DataParam->global) {
|
|
cmd.append("global");
|
|
}
|
|
|
|
// global+ flag check
|
|
if (fMsr2DataParam->globalPlus) {
|
|
if (fMsr2DataParam->chainFit) {
|
|
cmd.append("global+");
|
|
} else {
|
|
cmd.append("global+!");
|
|
}
|
|
}
|
|
|
|
// recreate db file
|
|
if (fMsr2DataParam->recreateDbFile) {
|
|
cmd.append("new");
|
|
}
|
|
|
|
// if NO tab is present use the local directory
|
|
QString workDir = QString("./");
|
|
if (fTabWidget->count() != 0) {
|
|
workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
}
|
|
PFitOutputHandler fitOutputHandler(workDir, cmd);
|
|
fitOutputHandler.setModal(true);
|
|
fFileSystemWatcherActive = false;
|
|
fitOutputHandler.exec();
|
|
|
|
// check if it is necessary to load msr-files
|
|
if (fMsr2DataParam->openFilesAfterFitting) {
|
|
QString fln;
|
|
QFile *file;
|
|
QTextStream *stream;
|
|
QFileInfo finfo;
|
|
bool alreadOpen=false;
|
|
int idx=0;
|
|
|
|
if (!fMsr2DataParam->global) { // standard fits
|
|
switch(dlg->getRunTag()) {
|
|
case 0: // run list
|
|
list = getRunList(runList, ok);
|
|
if (!ok)
|
|
return;
|
|
for (int i=0; i<list.size(); i++) {
|
|
fln = list[i];
|
|
if (fMsr2DataParam->msrFileExtension.isEmpty())
|
|
fln += ".msr";
|
|
else
|
|
fln += fMsr2DataParam->msrFileExtension + ".msr";
|
|
|
|
workDir = QString("./");
|
|
if (fTabWidget->count() != 0) {
|
|
workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
}
|
|
finfo.setFile(workDir + "/" + fln);
|
|
alreadOpen = fileAlreadyOpen(finfo, idx);
|
|
if (!alreadOpen) {
|
|
load(workDir + "/" + fln);
|
|
} else {
|
|
fTabWidget->setCurrentIndex(idx);
|
|
fileReload();
|
|
}
|
|
}
|
|
break;
|
|
case 1: // run list file
|
|
file = new QFile(QFileInfo(*fFilenames.find( currentEditor() )).absolutePath() + "/" + fMsr2DataParam->runListFileName);
|
|
if (!file->open(QIODevice::ReadOnly)) {
|
|
str = QString("Couldn't open run list file %1, sorry.").arg(fMsr2DataParam->runListFileName);
|
|
QMessageBox::critical(this, "**ERROR**", str.toLatin1(), QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
stream = new QTextStream(file);
|
|
while ( !stream->atEnd() ) {
|
|
str = stream->readLine(); // line of text excluding '\n'
|
|
str = str.trimmed();
|
|
if (!str.isEmpty() && !str.startsWith("#") && !str.startsWith("run", Qt::CaseInsensitive)) {
|
|
fln = str.section(' ', 0, 0, QString::SectionSkipEmpty);
|
|
if (fMsr2DataParam->msrFileExtension.isEmpty())
|
|
fln += ".msr";
|
|
else
|
|
fln += fMsr2DataParam->msrFileExtension + ".msr";
|
|
|
|
workDir = QString("./");
|
|
if (fTabWidget->count() != 0) {
|
|
workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
}
|
|
finfo.setFile(workDir + "/" + fln);
|
|
alreadOpen = fileAlreadyOpen(finfo, idx);
|
|
if (!alreadOpen) {
|
|
load(workDir + "/" + fln);
|
|
} else {
|
|
fTabWidget->setCurrentIndex(idx);
|
|
fileReload();
|
|
}
|
|
}
|
|
}
|
|
|
|
file->close();
|
|
|
|
// clean up
|
|
delete stream;
|
|
delete file;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else { // global tag set
|
|
// get the first run number needed to build the global fit file name
|
|
fln = QString("");
|
|
switch(dlg->getRunTag()) {
|
|
case 0: // run list
|
|
fln = runList.section(" ", 0, 0, QString::SectionSkipEmpty) + QString("+global") + fMsr2DataParam->msrFileExtension + QString(".msr");
|
|
break;
|
|
case 1: // run list file name
|
|
file = new QFile(QFileInfo(*fFilenames.find( currentEditor() )).absolutePath() + "/" + fMsr2DataParam->runListFileName);
|
|
if (!file->open(QIODevice::ReadOnly)) {
|
|
str = QString("Couldn't open run list file %1, sorry.").arg(fMsr2DataParam->runListFileName);
|
|
QMessageBox::critical(this, "**ERROR**", str.toLatin1(), QMessageBox::Ok, QMessageBox::NoButton);
|
|
return;
|
|
}
|
|
|
|
stream = new QTextStream(file);
|
|
while ( !stream->atEnd() ) {
|
|
str = stream->readLine(); // line of text excluding '\n'
|
|
str = str.trimmed();
|
|
if (!str.isEmpty() && !str.startsWith("#") && !str.startsWith("run", Qt::CaseInsensitive)) {
|
|
fln = str.section(' ', 0, 0, QString::SectionSkipEmpty);
|
|
break;
|
|
}
|
|
}
|
|
|
|
file->close();
|
|
|
|
fln += QString("+global") + fMsr2DataParam->msrFileExtension + QString(".msr");
|
|
|
|
// clean up
|
|
delete stream;
|
|
delete file;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
load(QFileInfo(*fFilenames.find( currentEditor() )).absolutePath() + "/" + fln);
|
|
}
|
|
}
|
|
}
|
|
|
|
delete dlg;
|
|
dlg = nullptr;
|
|
|
|
fileSystemWatcherActivation();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Calls musrview <msr-file>.
|
|
*/
|
|
void PTextEdit::musrView()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
QString tabLabel = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
if (tabLabel == "noname") {
|
|
QMessageBox::critical(this, "**ERROR**", "For a view a real mlog/msr-file is needed.");
|
|
return;
|
|
} else if (tabLabel == "noname*") {
|
|
fileSaveAs();
|
|
} else if (tabLabel.indexOf("*") > 0) {
|
|
fileSave();
|
|
}
|
|
|
|
QString cmd = fAdmin->getExecPath() + "/musrview";
|
|
QString workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
QStringList arg;
|
|
QString str;
|
|
|
|
// file name
|
|
str = *fFilenames.find( currentEditor() );
|
|
int pos = str.lastIndexOf("/");
|
|
if (pos != -1)
|
|
str.remove(0, pos+1);
|
|
arg << str;
|
|
|
|
// timeout
|
|
str.setNum(fAdmin->getTimeout());
|
|
arg << "--timeout" << str;
|
|
|
|
// start with Fourier?
|
|
if (fAdmin->getMusrviewShowFourierFlag())
|
|
arg << "-f";
|
|
|
|
// start with averaged data/Fourier?
|
|
if (fAdmin->getMusrviewShowAvgFlag())
|
|
arg << "-a";
|
|
|
|
QProcess *proc = new QProcess(this);
|
|
connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(musrViewFinished(int, QProcess::ExitStatus)));
|
|
|
|
// make sure that the system environment variables are properly set
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH"));
|
|
proc->setProcessEnvironment(env);
|
|
proc->setWorkingDirectory(workDir);
|
|
proc->start(cmd, arg);
|
|
if (!proc->waitForStarted()) {
|
|
// error handling
|
|
QString msg(tr("Could not execute the output command: ")+cmd[0]);
|
|
QMessageBox::critical( nullptr,
|
|
tr("Fatal error"),
|
|
msg,
|
|
tr("Quit") );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Checks if musrview terminated with error, and if yes pop up a message box.
|
|
* @param exitCode
|
|
*/
|
|
void PTextEdit::musrViewFinished(int exitCode, QProcess::ExitStatus)
|
|
{
|
|
if (exitCode != 0) {
|
|
QString msg = QString("musrview failed. Possible reasons:\n");
|
|
msg += QString("* corrupted msr-file.\n");
|
|
msg += QString("* cannot read data-file.\n");
|
|
msg += QString("* many more things can go wrong.\n");
|
|
msg += QString("Please check!");
|
|
QMessageBox::critical(nullptr, tr("Fatal Error"), msg, tr("Quit"));
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Calls musrt0 <msr-file>.
|
|
*/
|
|
void PTextEdit::musrT0()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
QString tabLabel = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
if (tabLabel == "noname") {
|
|
QMessageBox::critical(this, "**ERROR**", "For a view a real mlog/msr-file is needed.");
|
|
return;
|
|
} else if (tabLabel == "noname*") {
|
|
fileSaveAs();
|
|
} else if (tabLabel.indexOf("*") > 0) {
|
|
fileSave();
|
|
}
|
|
|
|
QString cmd = fAdmin->getExecPath() + "/musrt0";
|
|
QString workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
QStringList arg;
|
|
QString str;
|
|
|
|
// file name
|
|
str = *fFilenames.find( currentEditor() );
|
|
int pos = str.lastIndexOf("/");
|
|
if (pos != -1)
|
|
str.remove(0, pos+1);
|
|
arg << str;
|
|
|
|
// timeout
|
|
str.setNum(fAdmin->getTimeout());
|
|
arg << "--timeout" << str;
|
|
|
|
QProcess *proc = new QProcess(this);
|
|
|
|
// make sure that the system environment variables are properly set
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH"));
|
|
proc->setProcessEnvironment(env);
|
|
proc->setWorkingDirectory(workDir);
|
|
proc->start(cmd, arg);
|
|
if (!proc->waitForStarted()) {
|
|
// error handling
|
|
QString msg(tr("Could not execute the output command: ")+cmd[0]);
|
|
QMessageBox::critical( nullptr,
|
|
tr("Fatal error"),
|
|
msg,
|
|
tr("Quit") );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Calls musrFT via selection/option dialog. It will ask the user if he/she wants to overwrite some
|
|
* of the default settings.
|
|
*/
|
|
void PTextEdit::musrFT()
|
|
{
|
|
|
|
PGetMusrFTOptionsDialog *dlg = new PGetMusrFTOptionsDialog(*fFilenames.find( currentEditor() ), fMusrFTPrevCmd, fAdmin->getHelpUrl("musrFT"));
|
|
|
|
if (dlg == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR** musrFT", "Couldn't invoke musrFT Options Dialog.");
|
|
return;
|
|
}
|
|
|
|
if (dlg->exec() == QDialog::Accepted) {
|
|
fMusrFTPrevCmd = dlg->getMusrFTOptions();
|
|
QProcess *proc = new QProcess(this);
|
|
proc->setStandardOutputFile("musrFT.log");
|
|
proc->setStandardErrorFile("musrFT.log");
|
|
QString cmd = fAdmin->getExecPath() + "/musrFT";
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH"));
|
|
proc->setProcessEnvironment(env);
|
|
proc->start(cmd, fMusrFTPrevCmd);
|
|
if (!proc->waitForStarted()) {
|
|
// error handling
|
|
QString msg(tr("Could not execute the output command: ")+cmd[0]);
|
|
QMessageBox::critical( nullptr,
|
|
tr("Fatal error"),
|
|
msg,
|
|
tr("Quit") );
|
|
return;
|
|
}
|
|
}
|
|
|
|
delete dlg;
|
|
dlg = nullptr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Calls the preferences dialog which is used to set some global options.
|
|
*/
|
|
void PTextEdit::musrPrefs()
|
|
{
|
|
PPrefsDialog *dlg = new PPrefsDialog(fAdmin);
|
|
|
|
if (dlg == nullptr) {
|
|
QMessageBox::critical(this, "**ERROR** musrPrefs", "Couldn't invoke Preferences Dialog.");
|
|
return;
|
|
}
|
|
|
|
if (dlg->exec() == QDialog::Accepted) {
|
|
fAdmin->setDarkThemeIconsFlag(dlg->getDarkThemeIconsFlag());
|
|
fAdmin->setMusrviewShowFourierFlag(dlg->getMusrviewShowFourierFlag());
|
|
fAdmin->setMusrviewShowAvgFlag(dlg->getMusrviewShowAvgFlag());
|
|
fAdmin->setKeepMinuit2OutputFlag(dlg->getKeepMinuit2OutputFlag());
|
|
fAdmin->setTitleFromDataFileFlag(dlg->getTitleFromDataFileFlag());
|
|
fAdmin->setEnableMusrT0Flag(dlg->getEnableMusrT0Flag());
|
|
fMusrT0Action->setEnabled(fAdmin->getEnableMusrT0Flag());
|
|
if (dlg->getDump() == 1) {
|
|
fAdmin->setDumpAsciiFlag(true);
|
|
fAdmin->setDumpRootFlag(false);
|
|
} else if (dlg->getDump() == 2) {
|
|
fAdmin->setDumpAsciiFlag(false);
|
|
fAdmin->setDumpRootFlag(true);
|
|
} else {
|
|
fAdmin->setDumpAsciiFlag(false);
|
|
fAdmin->setDumpRootFlag(false);
|
|
}
|
|
fAdmin->setTimeout(dlg->getTimeout());
|
|
fAdmin->setChisqPerRunBlockFlag(dlg->getKeepRunPerBlockChisqFlag());
|
|
fAdmin->setEstimateN0Flag(dlg->getEstimateN0Flag());
|
|
}
|
|
|
|
delete dlg;
|
|
dlg = nullptr;
|
|
|
|
// check if the dark theme icons flag has changed
|
|
if (fAdmin->getDarkThemeIconsFlag() != fDarkToolBarIcon) {
|
|
fDarkTheme = !fDarkTheme;
|
|
fDarkToolBarIcon = !fDarkToolBarIcon;
|
|
switchIcons();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::musrSetSteps
|
|
*/
|
|
void PTextEdit::musrSetSteps()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
// make sure I have a saved msr-file to work on
|
|
QString tabLabel = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
if (tabLabel == "noname") {
|
|
QMessageBox::critical(this, "**ERROR**", "For musrStep a real mlog/msr-file is needed.");
|
|
return;
|
|
} else if (tabLabel == "noname*") {
|
|
fileSaveAs();
|
|
} else if (tabLabel.indexOf("*") > 0) {
|
|
fileSave();
|
|
}
|
|
|
|
// fill the command queue
|
|
QString cmd = fAdmin->getExecPath() + "/musrStep";
|
|
#if defined(Q_OS_DARWIN) || defined(Q_OS_MAC)
|
|
cmd = QString("/Applications/musrStep.app/Contents/MacOS/musrStep");
|
|
#endif
|
|
QString workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
QStringList arg;
|
|
QString str;
|
|
|
|
// get file name and feed it to the command queue
|
|
str = *fFilenames.find( currentEditor() );
|
|
int pos = str.lastIndexOf("/");
|
|
if (pos != -1)
|
|
str.remove(0, pos+1);
|
|
arg << str;
|
|
|
|
QProcess *proc = new QProcess(this);
|
|
if (proc == nullptr) {
|
|
QMessageBox::critical(nullptr, "**ERROR**", "Couldn't invoke QProcess!");
|
|
return;
|
|
}
|
|
|
|
// handle return status of musrStep
|
|
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
|
[=](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrSetSteps(exitCode, exitStatus); });
|
|
|
|
// make sure that the system environment variables are properly set
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH"));
|
|
proc->setProcessEnvironment(env);
|
|
proc->setWorkingDirectory(workDir);
|
|
proc->start(cmd, arg);
|
|
if (!proc->waitForStarted()) {
|
|
// error handling
|
|
QString msg(tr("Could not execute the output command: ")+cmd[0]);
|
|
QMessageBox::critical( nullptr,
|
|
tr("Fatal error"),
|
|
msg,
|
|
tr("Quit") );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Swaps the currently open msr-file with its mlog-file (if present) and updates musredit accordingly.
|
|
*/
|
|
void PTextEdit::musrSwapMsrMlog()
|
|
{
|
|
if ( !currentEditor() )
|
|
return;
|
|
|
|
// get current file name
|
|
QString currentFileName = *fFilenames.find( currentEditor() );
|
|
QString swapFileName;
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
QString tempFileName = QString("%1/.musrfit/__swap__.msr").arg(env.value("HOME"));
|
|
|
|
// check if it is a msr-, mlog-, or another file
|
|
int idx;
|
|
if ((idx = currentFileName.indexOf(".msr")) > 0) { // msr-file
|
|
swapFileName = currentFileName;
|
|
swapFileName.replace(idx, 5, ".mlog");
|
|
} else if ((idx = currentFileName.indexOf(".mlog")) > 0) { // mlog-file
|
|
swapFileName = currentFileName;
|
|
swapFileName.replace(idx, 5, ".msr ");
|
|
swapFileName = swapFileName.trimmed();
|
|
} else { // neither a msr- nor a mlog-file
|
|
QMessageBox::information( this, "musrSwapMsrMlog",
|
|
"This is neither a msr- nor a mlog-file, hence nothing to be swapped.\n",
|
|
QMessageBox::Ok );
|
|
return;
|
|
}
|
|
|
|
// check if the swapFile exists
|
|
if (!QFile::exists(swapFileName)) {
|
|
QString msg = "swap file '" + swapFileName + "' doesn't exist.\nCannot swap anything.";
|
|
QMessageBox::warning( this, "musrSwapMsrMlog",
|
|
msg, QMessageBox::Ok, QMessageBox::NoButton );
|
|
return;
|
|
}
|
|
|
|
// check if the file needs to be saved
|
|
if (fTabWidget->tabText(fTabWidget->currentIndex()).indexOf("*") > 0) { // needs to be saved first
|
|
fileSave();
|
|
}
|
|
|
|
QMessageBox::information(nullptr, "INFO", QString("Will now swap files: %1 <-> %2").arg(currentFileName).arg(swapFileName));
|
|
|
|
// swap files
|
|
|
|
// copy currentFile -> tempFile
|
|
if (QFile::exists(tempFileName)) {
|
|
if (!QFile::remove(tempFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to remove %1").arg(tempFileName));
|
|
return;
|
|
}
|
|
}
|
|
if (!QFile::copy(currentFileName, tempFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to copy %1 -> %2").arg(currentFileName).arg(tempFileName));
|
|
return;
|
|
}
|
|
// copy swapFile -> currentFile
|
|
if (!QFile::remove(currentFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to remove %1").arg(currentFileName));
|
|
return;
|
|
}
|
|
if (!QFile::copy(swapFileName, currentFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to copy %1 -> %2").arg(swapFileName).arg(currentFileName));
|
|
return;
|
|
}
|
|
// copy tempFile -> swapFile
|
|
if (!QFile::remove(swapFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to remove %1").arg(swapFileName));
|
|
return;
|
|
}
|
|
if (!QFile::copy(tempFileName, swapFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to copy %1 -> %2").arg(tempFileName).arg(swapFileName));
|
|
return;
|
|
}
|
|
// clean up
|
|
if (!QFile::remove(tempFileName)) {
|
|
QMessageBox::critical(nullptr, "ERROR", QString("failed to remove %1").arg(tempFileName));
|
|
return;
|
|
}
|
|
|
|
int currentIdx = fTabWidget->currentIndex();
|
|
|
|
// reload current file
|
|
fileClose();
|
|
load(currentFileName);
|
|
|
|
// check if swap file is open as well, and if yes, reload it
|
|
idx = -1;
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
if (fTabWidget->tabText(i).indexOf(swapFileName) >= 0) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
if (idx >= 0) { // swap file is open
|
|
fTabWidget->setCurrentIndex(idx);
|
|
fileClose();
|
|
load(swapFileName);
|
|
fTabWidget->setCurrentIndex(currentIdx);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Dumps the run header information of a selected muSR data file.
|
|
*/
|
|
void PTextEdit::musrDump()
|
|
{
|
|
// select a muSR data filename
|
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Select muSR Data File"), "./", tr("muSR Data Files (*.root *.bin *.msr *.nxs)"));
|
|
if (fileName.isEmpty())
|
|
return;
|
|
|
|
QVector<QString> cmd;
|
|
QString str = fAdmin->getExecPath() + "/dump_header";
|
|
cmd.append(str);
|
|
cmd.append("-fn");
|
|
cmd.append(fileName);
|
|
|
|
PDumpOutputHandler dumpOutputHandler(cmd);
|
|
dumpOutputHandler.setModal(false);
|
|
dumpOutputHandler.exec();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::mupp
|
|
* <p>Calls mupp, the muSR parameter plotter.
|
|
*/
|
|
void PTextEdit::mupp()
|
|
{
|
|
QString cmd("");
|
|
cmd = fAdmin->getExecPath() + "/mupp";
|
|
#if defined(Q_OS_DARWIN) || defined(Q_OS_MAC)
|
|
cmd = QString("/Applications/mupp.app/Contents/MacOS/mupp");
|
|
#endif
|
|
|
|
QProcess *proc = new QProcess(this);
|
|
|
|
QString workDir = QFileInfo(*fFilenames.find( currentEditor() )).absolutePath();
|
|
|
|
// make sure that the system environment variables are properly set
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
env.insert("LD_LIBRARY_PATH", env.value("ROOTSYS") + "/lib:" + env.value("LD_LIBRARY_PATH"));
|
|
proc->setProcessEnvironment(env);
|
|
proc->setWorkingDirectory(workDir);
|
|
proc->start(cmd);
|
|
if (!proc->waitForStarted()) {
|
|
// error handling
|
|
QString msg(tr("Could not execute the output command: ")+cmd);
|
|
QMessageBox::critical( nullptr,
|
|
tr("Fatal error"),
|
|
msg,
|
|
tr("Quit") );
|
|
return;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Starts the help content browser.
|
|
*/
|
|
void PTextEdit::helpContents()
|
|
{
|
|
PHelp *help = new PHelp(fAdmin->getHelpUrl("main"), fDarkTheme);
|
|
help->show();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Starts the help about info box.
|
|
*/
|
|
void PTextEdit::helpAbout()
|
|
{
|
|
PMusrEditAbout *about = new PMusrEditAbout();
|
|
about->show();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Starts the help about Qt info box.
|
|
*/
|
|
void PTextEdit::helpAboutQt()
|
|
{
|
|
QMessageBox::aboutQt(this);
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::exitStatusMusrWiz
|
|
* @param exitCode
|
|
* @param exitStatus
|
|
*/
|
|
void PTextEdit::exitStatusMusrWiz(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
if (exitStatus == QProcess::CrashExit) {
|
|
QMessageBox::critical(nullptr, "**FATAL**", "musrWiz returned CrashExit.");
|
|
return;
|
|
}
|
|
|
|
// dialog finished with reject
|
|
if (exitCode == 0)
|
|
return;
|
|
|
|
// read .musrWiz.log
|
|
QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
|
|
QString pathName = procEnv.value("HOME", "");
|
|
pathName += "/.musrfit/musredit/musrWiz.log";
|
|
QString errMsg;
|
|
std::ifstream fin(pathName.toLatin1().data(), std::ifstream::in);
|
|
if (!fin.is_open()) {
|
|
errMsg = QString("PTextEdit::exitStatusMusrWiz: couldn't read %1 file.").arg(pathName);
|
|
QMessageBox::critical(nullptr, "**ERROR**", errMsg);
|
|
return;
|
|
}
|
|
char line[128];
|
|
bool musrT0tag = false;
|
|
QString str, pathFileName("");
|
|
while (fin.good()) {
|
|
fin.getline(line, 128);
|
|
str = line;
|
|
if (str.startsWith("path-file-name:")) {
|
|
pathFileName = str.mid(16);
|
|
} else if (str.startsWith("musrt0-tag: yes")) {
|
|
musrT0tag = true;
|
|
}
|
|
}
|
|
fin.close();
|
|
|
|
load(pathFileName);
|
|
|
|
// in case there is a 1st empty tab "noname", remove it
|
|
QString tabStr = fTabWidget->tabText(0);
|
|
tabStr.remove('&'); // this is needed since the QTabWidget adds short-cut info as '&' to the tab name
|
|
if (tabStr == "noname") { // has to be the first, otherwise do nothing
|
|
fFileSystemWatcher->removePath("noname");
|
|
|
|
delete fTabWidget->widget(0);
|
|
}
|
|
|
|
if (musrT0tag)
|
|
musrT0();
|
|
|
|
// remove musrWiz.log file
|
|
QFile logFile(pathName);
|
|
if (!logFile.remove()) {
|
|
errMsg = QString("PTextEdit::exitStatusMusrWiz: couldn't delete %1 file.").arg(pathName);
|
|
QMessageBox::critical(nullptr, "**ERROR**", errMsg);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::existStatusMusrSetSteps
|
|
* @param exitCode
|
|
* @param exitStatus
|
|
*/
|
|
void PTextEdit::exitStatusMusrSetSteps(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
if (exitStatus == QProcess::CrashExit) {
|
|
QMessageBox::critical(nullptr, "**FATAL**", "musrStep returned CrashExit.");
|
|
return;
|
|
}
|
|
|
|
// dialog finished with reject
|
|
if (exitCode == 0)
|
|
return;
|
|
|
|
// dialog finished with save and quite, i.e. accept, hence reload
|
|
QString fln = *fFilenames.find( currentEditor() );
|
|
int idx = fTabWidget->currentIndex();
|
|
|
|
fileClose();
|
|
load(fln, idx);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: called when the font shall be changed.
|
|
*
|
|
* \param f font object
|
|
*/
|
|
void PTextEdit::fontChanged( const QFont &f )
|
|
{
|
|
fFontChanging = true;
|
|
fComboFont->lineEdit()->setText( f.family() );
|
|
fComboSize->lineEdit()->setText( QString::number( f.pointSize() ) );
|
|
|
|
if (!currentEditor())
|
|
return;
|
|
|
|
currentEditor()->setFont(f);
|
|
currentEditor()->setWindowModified(false);
|
|
currentEditor()->viewport()->setFocus();
|
|
fFontChanging = false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: called when the text of the document has changed. It adds a star to the tab label if the
|
|
* document has been modified.
|
|
*
|
|
* \param forced
|
|
*/
|
|
void PTextEdit::textChanged(const bool forced)
|
|
{
|
|
|
|
if (!currentEditor())
|
|
return;
|
|
|
|
if (fFontChanging)
|
|
return;
|
|
|
|
QString tabLabel = fTabWidget->tabText(fTabWidget->currentIndex());
|
|
|
|
if ((fTabWidget->tabText(fTabWidget->currentIndex()).indexOf("*") > 0) &&
|
|
!currentEditor()->document()->isModified()) {
|
|
tabLabel.truncate(tabLabel.length()-1);
|
|
fTabWidget->setTabText(fTabWidget->currentIndex(), tabLabel);
|
|
}
|
|
|
|
if ((fTabWidget->tabText(fTabWidget->currentIndex()).indexOf("*") < 0) &&
|
|
currentEditor()->document()->isModified()) {
|
|
fTabWidget->setTabText(fTabWidget->currentIndex(), tabLabel+"*");
|
|
}
|
|
|
|
if ((fTabWidget->tabText(fTabWidget->currentIndex()).indexOf("*") < 0) &&
|
|
forced)
|
|
fTabWidget->setTabText(fTabWidget->currentIndex(), tabLabel+"*");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: called when the cursor position has changed. Updates the status bar with the current
|
|
* cursor position.
|
|
*/
|
|
void PTextEdit::currentCursorPosition()
|
|
{
|
|
QString str;
|
|
int line=0, pos=0;
|
|
|
|
pos = currentEditor()->textCursor().columnNumber();
|
|
line = currentEditor()->textCursor().blockNumber();
|
|
|
|
str = QString("cursor pos: %1, %2").arg(line+1).arg(pos+1);
|
|
statusBar()->showMessage(str);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: handles the replaced command.
|
|
*/
|
|
void PTextEdit::replace()
|
|
{
|
|
currentEditor()->insertPlainText(fFindReplaceData->replaceText);
|
|
|
|
editFindNext();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: handles the repalce and close command.
|
|
*/
|
|
void PTextEdit::replaceAndClose()
|
|
{
|
|
currentEditor()->insertPlainText(fFindReplaceData->replaceText);
|
|
|
|
emit close();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: handles the replace all command.
|
|
*/
|
|
void PTextEdit::replaceAll()
|
|
{
|
|
// set the cursor to the start of the document
|
|
currentEditor()->moveCursor(QTextCursor::Start);
|
|
|
|
// construct search flags
|
|
QTextDocument::FindFlags flags = 0;
|
|
if (fFindReplaceData->caseSensitive)
|
|
flags |= QTextDocument::FindCaseSensitively;
|
|
else if (fFindReplaceData->findBackwards)
|
|
flags |= QTextDocument::FindBackward;
|
|
else if (fFindReplaceData->wholeWordsOnly)
|
|
flags |= QTextDocument::FindWholeWords;
|
|
|
|
while (currentEditor()->find(fFindReplaceData->findText, flags)) {
|
|
currentEditor()->insertPlainText(fFindReplaceData->replaceText);
|
|
}
|
|
|
|
emit close();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>SLOT: updates the fonts if the textedit tab has changed.
|
|
*/
|
|
void PTextEdit::applyFontSettings(int)
|
|
{
|
|
QFont font(fAdmin->getFontName(), fAdmin->getFontSize());
|
|
fontChanged(font);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Called when an open file is changing outside the editor (SLOT).
|
|
*
|
|
* \param fileName file name of the changed file.
|
|
*/
|
|
void PTextEdit::fileChanged(const QString &fileName)
|
|
{
|
|
if (!fFileSystemWatcherActive)
|
|
return;
|
|
|
|
fFileSystemWatcherActive = false;
|
|
|
|
QString str = "File '" + fileName + "' changed on the system.\nDo you want to reload it?";
|
|
int result = QMessageBox::question(this, "**INFO**", str, QMessageBox::Yes, QMessageBox::No);
|
|
if (result == QMessageBox::Yes) {
|
|
// find correct file
|
|
int idx = -1;
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
if (fTabWidget->tabText(i) == QFileInfo(fileName).fileName()) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (idx == -1) {
|
|
fileSystemWatcherActivation();
|
|
return;
|
|
}
|
|
|
|
// remove file from file system watcher
|
|
fFileSystemWatcher->removePath(fileName);
|
|
|
|
// close tab
|
|
fTabWidget->removeTab(idx);
|
|
// load it
|
|
load(fileName, idx);
|
|
}
|
|
|
|
fileSystemWatcherActivation();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Delayed reactivation of file system watcher, needed when saving files. At the moment the delay
|
|
* is set to 2000 ms.
|
|
*/
|
|
void PTextEdit::fileSystemWatcherActivation()
|
|
{
|
|
if (fFileSystemWatcherTimeout.isActive())
|
|
return;
|
|
|
|
fFileSystemWatcherTimeout.singleShot(2000, this, SLOT(setFileSystemWatcherActive()));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>slot needed to reactivate the file system watcher. It is called by PTextEdit::fileSystemWatcherActivation()
|
|
* after some given timeout.
|
|
*/
|
|
void PTextEdit::setFileSystemWatcherActive()
|
|
{
|
|
fFileSystemWatcherActive = true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::getTheme
|
|
*/
|
|
void PTextEdit::getTheme()
|
|
{
|
|
fDarkTheme = false; // true if theme is dark
|
|
fDarkToolBarIcon = false; // needed for ubuntu dark since there the menu icons are dark, however the toolbar icons are plain!
|
|
|
|
QString str = QIcon::themeName();
|
|
qDebug() << "debug> theme name=" << str << endl;
|
|
|
|
if (str.isEmpty()) { // this is ugly and eventually needs to be fixed in a more coherent way
|
|
str = QProcessEnvironment::systemEnvironment().value("HOME", QString("??"));
|
|
str += "/.kde4/share/config/kdeglobals";
|
|
if (QFile::exists(str)) {
|
|
QFile fln(str);
|
|
fln.open(QIODevice::ReadOnly | QIODevice::Text);
|
|
QTextStream fin(&fln);
|
|
QString line("");
|
|
bool done = false;
|
|
while (!fin.atEnd() && !done) {
|
|
line = fin.readLine();
|
|
if (line.contains("ColorScheme")) {
|
|
if (line.contains("dark", Qt::CaseInsensitive)) {
|
|
fDarkTheme = true;
|
|
fDarkToolBarIcon = true;
|
|
}
|
|
done = true;
|
|
}
|
|
}
|
|
fln.close();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (str.contains("dark", Qt::CaseInsensitive)) {
|
|
fDarkTheme = true;
|
|
if (str.contains("ubuntu", Qt::CaseInsensitive)) {
|
|
fDarkToolBarIcon = false;
|
|
} else if (str.contains("xfce", Qt::CaseInsensitive)) {
|
|
fDarkTheme = false;
|
|
fDarkToolBarIcon = false;
|
|
} else {
|
|
fDarkToolBarIcon = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>fill the recent file list in the menu.
|
|
*/
|
|
void PTextEdit::fillRecentFiles()
|
|
{
|
|
for (int i=0; i<fAdmin->getNumRecentFiles(); i++) {
|
|
fRecentFilesAction[i]->setText(fAdmin->getRecentFile(i));
|
|
fRecentFilesAction[i]->setVisible(true);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p> run list is split (space separated) and expanded (start-end -> start, start+1, ..., end) to a list
|
|
*
|
|
* \param runListStr list to be split and expanded
|
|
* \param ok true if everything is fine; false if an error has been encountered
|
|
*
|
|
* \return fully expanded run list
|
|
*/
|
|
QStringList PTextEdit::getRunList(QString runListStr, bool &ok)
|
|
{
|
|
QStringList result;
|
|
bool isInt;
|
|
QString str;
|
|
|
|
ok = true;
|
|
|
|
// first split space separated parts
|
|
QStringList tok = runListStr.split(' ', QString::SkipEmptyParts);
|
|
for (int i=0; i<tok.size(); i++) {
|
|
if (tok[i].contains('-')) { // list given, hence need to expand
|
|
QStringList runListTok = tok[i].split('-', QString::SkipEmptyParts);
|
|
if (runListTok.size() != 2) { // error
|
|
ok = false;
|
|
result.clear();
|
|
return result;
|
|
}
|
|
int start=0, end=0;
|
|
start = runListTok[0].toInt(&isInt);
|
|
if (!isInt) {
|
|
ok = false;
|
|
result.clear();
|
|
return result;
|
|
}
|
|
end = runListTok[1].toInt(&isInt);
|
|
if (!isInt) {
|
|
ok = false;
|
|
result.clear();
|
|
return result;
|
|
}
|
|
for (int i=start; i<=end; i++) {
|
|
str = QString("%1").arg(i);
|
|
result << str;
|
|
}
|
|
} else { // keep it
|
|
result << tok[i];
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* @brief PTextEdit::fileAlreadyOpen
|
|
* @param finfo
|
|
* @param idx
|
|
* @return
|
|
*/
|
|
bool PTextEdit::fileAlreadyOpen(QFileInfo &finfo, int &idx)
|
|
{
|
|
bool result = false;
|
|
QFileInfo finfo2;
|
|
QString tabFln;
|
|
|
|
for (int i=0; i<fTabWidget->count(); i++) {
|
|
tabFln = *fFilenames.find( dynamic_cast<PSubTextEdit*>(fTabWidget->widget(i)));
|
|
finfo2.setFile(tabFln);
|
|
if (finfo.absoluteFilePath() == finfo2.absoluteFilePath()) {
|
|
result = true;
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
/**
|
|
* <p>Switch icons according to the fAdmin settings
|
|
*/
|
|
void PTextEdit::switchIcons()
|
|
{
|
|
if (fAdmin->getDarkThemeIconsFlag()) { // dark theme icons
|
|
fActions["New"]->setIcon(QIcon(":/icons/document-new-dark.svg"));
|
|
fActions["Open"]->setIcon(QIcon(":/icons/document-open-dark.svg"));
|
|
fActions["Reload"]->setIcon(QIcon(":/icons/view-refresh-dark.svg"));
|
|
fActions["Save"]->setIcon(QIcon(":/icons/document-save-dark.svg"));
|
|
fActions["Print"]->setIcon(QIcon(":/icons/document-print-dark.svg"));
|
|
fActions["Undo"]->setIcon(QIcon(":/icons/edit-undo-dark.svg"));
|
|
fActions["Redo"]->setIcon(QIcon(":/icons/edit-redo-dark.svg"));
|
|
fActions["Copy"]->setIcon(QIcon(":/icons/edit-copy-dark.svg"));
|
|
fActions["Cut"]->setIcon(QIcon(":/icons/edit-cut-dark.svg"));
|
|
fActions["Paste"]->setIcon(QIcon(":/icons/edit-paste-dark.svg"));
|
|
fActions["Find"]->setIcon(QIcon(":/icons/edit-find-dark.svg"));
|
|
fActions["Find Next"]->setIcon(QIcon(":/icons/go-next-use-dark.svg"));
|
|
fActions["Find Previous"]->setIcon(QIcon(":/icons/go-previous-use-dark.svg"));
|
|
fActions["musrWiz"]->setIcon(QIcon(":/icons/musrWiz-32x32-dark.svg"));
|
|
fActions["calcChisq"]->setIcon(QIcon(":/icons/musrchisq-dark.svg"));
|
|
fActions["musrfit"]->setIcon(QIcon(":/icons/musrfit-dark.svg"));
|
|
fActions["Swap Msr/Mlog"]->setIcon(QIcon(":/icons/musrswap-dark.svg"));
|
|
fActions["musrStep"]->setIcon(QIcon(":/icons/musrStep-32x32-dark.svg"));
|
|
fActions["msr2data"]->setIcon(QIcon(":/icons/msr2data-dark.svg"));
|
|
fActions["mupp"]->setIcon(QIcon(":/icons/mupp-dark.svg"));
|
|
fActions["musrview"]->setIcon(QIcon(":/icons/musrview-dark.svg"));
|
|
fActions["musrt0"]->setIcon(QIcon(":/icons/musrt0-dark.svg"));
|
|
fActions["musrFT"]->setIcon(QIcon(":/icons/musrFT-dark.svg"));
|
|
fActions["musrprefs"]->setIcon(QIcon(":/icons/musrprefs-dark.svg"));
|
|
fActions["musrdump"]->setIcon(QIcon(":/icons/musrdump-dark.svg"));
|
|
} else { // plain theme icons
|
|
fActions["New"]->setIcon(QIcon(":/icons/document-new-plain.svg"));
|
|
fActions["Open"]->setIcon(QIcon(":/icons/document-open-plain.svg"));
|
|
fActions["Reload"]->setIcon(QIcon(":/icons/view-refresh-plain.svg"));
|
|
fActions["Save"]->setIcon(QIcon(":/icons/document-save-plain.svg"));
|
|
fActions["Print"]->setIcon(QIcon(":/icons/document-print-plain.svg"));
|
|
fActions["Undo"]->setIcon(QIcon(":/icons/edit-undo-plain.svg"));
|
|
fActions["Redo"]->setIcon(QIcon(":/icons/edit-redo-plain.svg"));
|
|
fActions["Copy"]->setIcon(QIcon(":/icons/edit-copy-plain.svg"));
|
|
fActions["Cut"]->setIcon(QIcon(":/icons/edit-cut-plain.svg"));
|
|
fActions["Paste"]->setIcon(QIcon(":/icons/edit-paste-plain.svg"));
|
|
fActions["Find"]->setIcon(QIcon(":/icons/edit-find-plain.svg"));
|
|
fActions["Find Next"]->setIcon(QIcon(":/icons/go-next-use-plain.svg"));
|
|
fActions["Find Previous"]->setIcon(QIcon(":/icons/go-previous-use-plain.svg"));
|
|
fActions["musrWiz"]->setIcon(QIcon(":/icons/musrWiz-32x32.svg"));
|
|
fActions["calcChisq"]->setIcon(QIcon(":/icons/musrchisq-plain.svg"));
|
|
fActions["musrfit"]->setIcon(QIcon(":/icons/musrfit-plain.svg"));
|
|
fActions["Swap Msr/Mlog"]->setIcon(QIcon(":/icons/musrswap-plain.svg"));
|
|
fActions["musrStep"]->setIcon(QIcon(":/icons/musrStep-32x32.svg"));
|
|
fActions["msr2data"]->setIcon(QIcon(":/icons/msr2data-plain.svg"));
|
|
fActions["mupp"]->setIcon(QIcon(":/icons/mupp-plain.svg"));
|
|
fActions["musrview"]->setIcon(QIcon(":/icons/musrview-plain.svg"));
|
|
fActions["musrt0"]->setIcon(QIcon(":/icons/musrt0-plain.svg"));
|
|
fActions["musrFT"]->setIcon(QIcon(":/icons/musrFT-plain.svg"));
|
|
fActions["musrprefs"]->setIcon(QIcon(":/icons/musrprefs-plain.svg"));
|
|
fActions["musrdump"]->setIcon(QIcon(":/icons/musrdump-plain.svg"));
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// END
|
|
//----------------------------------------------------------------------------------------------------
|