From: <sv...@va...> - 2011-07-01 14:07:47
|
Author: cerion Date: 2011-07-01 15:02:54 +0100 (Fri, 01 Jul 2011) New Revision: 543 Log: 1) abstracted get-file/dir dialogs - simplifies a lot of code - persistent caching of last-used filter (via global QSettings) - option to update project config for chosen path (don't always want this, e.g. option pages) 2) integrated the cached filters & chosen dir/files for the get-file/dir dialogs for: - new/open/recent/save projects - save/open logs 3) new dialog to create new projects - leverages abstract get-dir dialog - simplifies user interface: no worries about suffix, interactive validation on project name & dir 4) set mainwindow title with project name 5) hide project suffix in recent-projects list Added: trunk/src/utils/vknewprojectdialog.cpp trunk/src/utils/vknewprojectdialog.h Modified: trunk/src/help/help_handbook.cpp trunk/src/mainwindow.cpp trunk/src/objects/tool_object.cpp trunk/src/options/valkyrie_options_page.cpp trunk/src/options/vk_suppressions_dialog.cpp trunk/src/options/vk_suppressions_dialog.h trunk/src/src.pro trunk/src/toolview/helgrindview.cpp trunk/src/toolview/helgrindview.h trunk/src/toolview/memcheckview.cpp trunk/src/toolview/memcheckview.h trunk/src/toolview/toolview.cpp trunk/src/toolview/toolview.h trunk/src/utils/vk_config.cpp trunk/src/utils/vk_config.h trunk/src/utils/vk_utils.cpp trunk/src/utils/vk_utils.h Modified: trunk/src/help/help_handbook.cpp =================================================================== --- trunk/src/help/help_handbook.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/help/help_handbook.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -213,10 +213,8 @@ */ void HandBook::openFile() { - QString fn = QFileDialog::getOpenFileName( - this, "Open File", VkCfg::docDir(), - "Html Files (*.html *.htm);;All Files (*)" ); - + QString fn = vkDlgCfgGetFile( this, "handbook_docdir" ); + if ( !fn.isEmpty() ) { browser->setSource( fn ); } Modified: trunk/src/mainwindow.cpp =================================================================== --- trunk/src/mainwindow.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/mainwindow.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -23,6 +23,7 @@ #include <QColorGroup> #include <QEvent> #include <QFileDialog> +#include <QGroupBox> #include <QInputDialog> #include <QMenu> #include <QMenuBar> @@ -40,6 +41,7 @@ #include "utils/vk_config.h" #include "utils/vk_messages.h" #include "utils/vk_utils.h" +#include "utils/vknewprojectdialog.h" /***************************************************************************/ @@ -69,9 +71,7 @@ handBook( 0 ), optionsDialog( 0 ) { setObjectName( QString::fromUtf8( "MainWindowClass" ) ); - QString title = VkCfg::appName(); - title.replace( 0, 1, title[0].toUpper() ); - setWindowTitle( title ); + setWindowTitle( VkCfg::appTitle() + " - <no project>" ); lastAppFont = qApp->font(); lastPalette = qApp->palette(); @@ -756,43 +756,17 @@ */ void MainWindow::createNewProject() { - // TODO: put dir & name choice in one dialog. - - // Choose project directory - QString dir = QFileDialog::getExistingDirectory( this, "Choose Project Directory", "./", - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks ); - - if ( dir.isEmpty() || dir.isNull() ) { + VkNewProjectDialog dlg( this ); + + if ( dlg.exec() == QDialog::Rejected ) { return; } + + QString proj_path = dlg.getProjectPath(); - // Choose project name - QString proj_name; - - while ( true ) { - bool ok = true; - proj_name = QInputDialog::getText( this, "Choose New Project Name", - "Project Name:", QLineEdit::Normal, - "", &ok ); - - if ( !ok ) { // User chaged their minds. - return; - } - - if ( !proj_name.isEmpty() ) { // loop if empty name. - break; - } - } - - // TODO: check if exists, may overwrite, etc... + vkCfgProj->createNewProject( proj_path ); - QString proj_fname = dir + "/" + proj_name + "." + VkCfg::filetype(); - vkCfgProj->createNewProject( proj_fname ); - - // TODO: ok/cancel? - - setCurrentProject( proj_fname ); + setCurrentProject( proj_path ); } @@ -801,19 +775,14 @@ */ void MainWindow::openProject() { - QString filter = QString("*.") + VkCfg::filetype(); - QString proj_fname = QFileDialog::getOpenFileName( this, "Open Valkyrie Project", - "./", "Valkyrie Projects (" + filter + ")" ); - - if ( proj_fname.isEmpty() || proj_fname.isNull() ) { - // Cancelled - return; + QString proj_fname = vkDlgCfgGetFile( this, "project_path" ); + + if ( proj_fname.isEmpty() ) { + return; // cancelled } vkCfgProj->openProject( proj_fname ); - // TODO: ok/cancel? - setCurrentProject( proj_fname ); } @@ -826,11 +795,20 @@ QAction *action = qobject_cast<QAction *>(sender()); if (action) { QString proj_fname = action->data().toString(); - vkCfgProj->openProject( proj_fname ); + + QFileInfo fi( proj_fname ); + if ( fi.exists() && fi.isFile() ) { + // cache project path + vkCfgGlbl->setValue( "project_path", proj_fname ); - // TODO: ok/cancel? - - setCurrentProject( proj_fname ); + // open project + vkCfgProj->openProject( proj_fname ); + setCurrentProject( proj_fname ); + } + else { + vkError( this, "Open Recent Project", + "<p>Project not found:<br>%s</p>", qPrintable( proj_fname ) ); + } } } @@ -840,42 +818,14 @@ */ void MainWindow::saveAsProject() { - // TODO: put dir & name choice in one dialog. - - // Choose project directory - QString dir = QFileDialog::getExistingDirectory( this, "Choose Project Directory", "./", - QFileDialog::ShowDirsOnly | - QFileDialog::DontResolveSymlinks ); - - if ( dir.isEmpty() || dir.isNull() ) { - return; + QString proj_fname = vkDlgCfgGetFile( this, "project_path", + QFileDialog::AcceptSave ); + if ( proj_fname.isEmpty() ) { + return; // cancelled } - - // Choose project name - QString proj_name; - - while ( true ) { - bool ok = true; - proj_name = QInputDialog::getText( this, "Enter Project Name", - "Project Name:", QLineEdit::Normal, - "", &ok ); - - if ( !ok ) { // User chaged their minds. - return; - } - - if ( !proj_name.isEmpty() ) { // loop if empty name. - break; - } - } - - - // TODO: check if exists may overwrite, etc... - QString proj_fname = dir + "/" + proj_name + "." + VkCfg::filetype(); + vkCfgProj->saveProjectAs( proj_fname ); - // TODO: ok/cancel? - setCurrentProject( proj_fname ); } @@ -885,21 +835,16 @@ - update the config with the new project name - update the actions to keep in sync. */ -void MainWindow::setCurrentProject(const QString &projName) +void MainWindow::setCurrentProject(const QString &projPath ) { -#if 0 // TODO: maybe future, but then do consistently everywhere... - curFile = fileName; - if (curFile.isEmpty()) - setWindowTitle(tr("Recent Files")); - else - setWindowTitle(tr("%1 - %2").arg(strippedName(curFile)) - .arg(tr("Recent Files"))); -#endif - + QString projName = QFileInfo( projPath ).baseName(); + projName.replace( 0, 1, projName[0].toUpper() ); + setWindowTitle( VkCfg::appTitle() + " - " + projName ); + QStringList files = vkCfgGlbl->value( "recent_projects" ) .toString().split( VkCfg::sepChar(), QString::SkipEmptyParts ); - files.removeAll( projName ); - files.prepend( projName ); + files.removeAll( projPath ); + files.prepend( projPath ); while (files.size() > MaxRecentProjs) { files.removeLast(); } @@ -921,7 +866,7 @@ int numRecentProjs = qMin(files.size(), (int)MaxRecentProjs); for (int i = 0; i < numRecentProjs; ++i) { - QString text = QFileInfo( files[i] ).fileName(); + QString text = QFileInfo( files[i] ).baseName(); actFile_RecentProjs[i]->setText(text); actFile_RecentProjs[i]->setData(files[i]); actFile_RecentProjs[i]->setVisible(true); Modified: trunk/src/objects/tool_object.cpp =================================================================== --- trunk/src/objects/tool_object.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/objects/tool_object.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -836,15 +836,9 @@ cerr << "ToolObject::fileSaveDialog()" << endl; vk_assert( toolView != 0 ); - // --- Get filename to save to - QString flt = "XML Files (*.xml);;Log Files (*.log.*);;All Files (*)"; - QString cptn = "Save Log File As"; - // use dir used by view-log as most-likely starting point - QFileInfo fi( vkCfgProj->value( "valkyrie/view-log" ).toString() ); - QString start_path = fi.exists() ? fi.absolutePath() : "./"; + QString fname = vkDlgCfgGetFile( toolView, "valkyrie/view-log", + QFileDialog::AcceptSave ); - // get filename to save to: asks for overwrite confirmation - QString fname = QFileDialog::getSaveFileName( toolView, cptn, start_path, flt); if ( fname.isEmpty() ) { // Cancelled return false; } Modified: trunk/src/options/valkyrie_options_page.cpp =================================================================== --- trunk/src/options/valkyrie_options_page.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/options/valkyrie_options_page.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -224,27 +224,15 @@ */ void ValkyrieOptionsPage::getEditor() { - // try and start up somewhere sensible - QString start_dir = "/"; - - // get current dir of current editor - LeWidget* editLedit = (( LeWidget* )m_itemList[VALKYRIE::SRC_EDITOR] ); - QString ed = editLedit->currValue(); - if ( !ed.isEmpty() ) { - QString ed_file = ed.split( " ", QString::SkipEmptyParts ).first(); - int err_val; - ed_file = fileCheck( &err_val, ed_file, false, false, true ); - - QFileInfo fi( ed_file ); - start_dir = fi.absolutePath(); - } + // get path of current editor + QString ed_curr = m_itemList[VALKYRIE::SRC_EDITOR]->currValue(); + if ( !ed_curr.isEmpty() ) + ed_curr = ed_curr.split( " ", QString::SkipEmptyParts ).first(); - QString editor = - QFileDialog::getOpenFileName( this, tr("Select Source Editor"), - start_dir, tr("All Files (*)")); - - if ( !editor.isEmpty() ) { // user might have clicked Cancel - editLedit->setValue( editor ); + QString ed_new = vkDlgGetFile( this, ed_curr ); + + if ( !ed_new.isEmpty() ) { // user might have clicked Cancel + (( LeWidget* )m_itemList[VALKYRIE::SRC_EDITOR] )->setValue( ed_new ); // update triggers checkOption() } } @@ -255,19 +243,12 @@ */ void ValkyrieOptionsPage::getBinary() { - QString currbin = m_itemList[VALKYRIE::BINARY]->currValue(); - QString currdir = "./"; - if ( !currbin.isEmpty() ) { - QFileInfo fi( currbin ); - currdir = fi.absolutePath(); - } + QString bin_curr = m_itemList[VALKYRIE::BINARY]->currValue(); - QString binfile = - QFileDialog::getOpenFileName( this, tr("Select Executable To Debug"), - currdir, tr("All Files (*)")); - - if ( !binfile.isEmpty() ) { // user might have clicked Cancel - (( LeWidget* )m_itemList[VALKYRIE::BINARY] )->setValue( binfile ); + QString bin_new = vkDlgGetFile( this, bin_curr ); + + if ( !bin_new.isEmpty() ) { // user might have clicked Cancel + (( LeWidget* )m_itemList[VALKYRIE::BINARY] )->setValue( bin_new ); // update triggers checkOption() } } @@ -278,12 +259,12 @@ */ void ValkyrieOptionsPage::getBrowser() { - QString brwsr = - QFileDialog::getOpenFileName( this, tr("Select Browser"), - "./", tr("All Files (*)")); + QString browser_curr = m_itemList[VALKYRIE::BINARY]->currValue(); - if ( !brwsr.isEmpty() ) { // user might have clicked Cancel - (( LeWidget* )m_itemList[VALKYRIE::BROWSER] )->setValue( brwsr ); + QString browser_new = vkDlgGetFile( this, browser_curr ); + + if ( !browser_new.isEmpty() ) { // user might have clicked Cancel + (( LeWidget* )m_itemList[VALKYRIE::BROWSER] )->setValue( browser_new ); // update triggers checkOption() } } @@ -294,12 +275,12 @@ */ void ValkyrieOptionsPage::getVgExec() { - QString vg_exec = - QFileDialog::getOpenFileName( this, tr("Select Valgrind"), - "./", tr("All Files (*)")); + QString vg_curr = m_itemList[VALKYRIE::VG_EXEC]->currValue(); + + QString vg_new = vkDlgGetFile( this, vg_curr ); - if ( !vg_exec.isEmpty() ) { // user might have clicked Cancel - (( LeWidget* )m_itemList[VALKYRIE::VG_EXEC] )->setValue( vg_exec ); + if ( !vg_new.isEmpty() ) { // user might have clicked Cancel + (( LeWidget* )m_itemList[VALKYRIE::VG_EXEC] )->setValue( vg_new ); // update triggers checkOption() } } @@ -310,16 +291,12 @@ */ void ValkyrieOptionsPage::getDfltLogDir() { - QString currdir = m_itemList[VALKYRIE::DFLT_LOGDIR]->currValue(); + QString dir_curr = m_itemList[VALKYRIE::DFLT_LOGDIR]->currValue(); - QString dir_logsave = - QFileDialog::getExistingDirectory( this, - tr("Choose Directory"), - currdir, - QFileDialog::ShowDirsOnly ); - - if ( !dir_logsave.isEmpty() ) { // user might have clicked Cancel - (( LeWidget* )m_itemList[VALKYRIE::DFLT_LOGDIR] )->setValue( dir_logsave ); + QString dir_new = vkDlgGetDir( this, dir_curr ); + + if ( !dir_new.isEmpty() ) { // user might have clicked Cancel + (( LeWidget* )m_itemList[VALKYRIE::DFLT_LOGDIR] )->setValue( dir_new ); // update triggers checkOption() } } @@ -329,16 +306,12 @@ */ void ValkyrieOptionsPage::getWorkingDir() { - QString currdir = m_itemList[VALKYRIE::WORKING_DIR]->currValue(); + QString dir_curr = m_itemList[VALKYRIE::WORKING_DIR]->currValue(); - QString dir_working = - QFileDialog::getExistingDirectory( this, - tr("Choose Directory"), - currdir, - QFileDialog::ShowDirsOnly ); - - if ( !dir_working.isEmpty() ) { // user might have clicked Cancel - (( LeWidget* )m_itemList[VALKYRIE::WORKING_DIR] )->setValue( dir_working ); + QString dir_new = vkDlgGetDir( this, dir_curr ); + + if ( !dir_new.isEmpty() ) { // user might have clicked Cancel + (( LeWidget* )m_itemList[VALKYRIE::WORKING_DIR] )->setValue( dir_new ); // update triggers checkOption() } } Modified: trunk/src/options/vk_suppressions_dialog.cpp =================================================================== --- trunk/src/options/vk_suppressions_dialog.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/options/vk_suppressions_dialog.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -2,7 +2,7 @@ ** VkSuppressionsDialog implementation ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2011, OpenWorks LLP. All rights reserved. +** Copyright (C) 2011-2011, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. Modified: trunk/src/options/vk_suppressions_dialog.h =================================================================== --- trunk/src/options/vk_suppressions_dialog.h 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/options/vk_suppressions_dialog.h 2011-07-01 14:02:54 UTC (rev 543) @@ -2,7 +2,7 @@ ** VkSuppressionsDialog definition ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2011, OpenWorks LLP. All rights reserved. +** Copyright (C) 2011-2011, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. Modified: trunk/src/src.pro =================================================================== --- trunk/src/src.pro 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/src.pro 2011-07-01 14:02:54 UTC (rev 543) @@ -77,7 +77,8 @@ utils/vk_config.cpp \ utils/vk_logpoller.cpp \ utils/vk_messages.cpp \ - utils/vk_utils.cpp + utils/vk_utils.cpp \ + utils/vknewprojectdialog.cpp HEADERS += \ mainwindow.h \ @@ -119,7 +120,8 @@ utils/vk_defines.h \ utils/vk_logpoller.h \ utils/vk_messages.h \ - utils/vk_utils.h + utils/vk_utils.h \ + utils/vknewprojectdialog.h RESOURCES += $${VK_ROOT}/icons.qrc Modified: trunk/src/toolview/helgrindview.cpp =================================================================== --- trunk/src/toolview/helgrindview.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/toolview/helgrindview.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -26,7 +26,6 @@ #include <QAction> #include <QApplication> -#include <QFileDialog> #include <QLabel> #include <QMenuBar> #include <QProcess> @@ -119,36 +118,7 @@ } -/*! - Parse and load an xml logfile. - TODO: fix. This starts a new 'run', so we should - trigger vk's "check last run over" before anything else... -*/ -void HelgrindView::openLogFile() -{ - //vkDebug( "HelgrindView::openLogFile()\n" ); - - QString last_file = vkCfgProj->value( "valkyrie/view-log" ).toString(); - if ( last_file.isEmpty() ) last_file = "./"; - - QString captn = "Select Log File"; - QString filt = "XML Files (*.xml);;Log Files (*.log.*);;All Files (*)"; - QString log_file = QFileDialog::getOpenFileName( this, captn, last_file, filt ); - - // user might have clicked Cancel - if ( log_file.isEmpty() ) { - return; - } - - // updates config (as does cmd line --view-cfg...) - emit logFileChosen( log_file ); - - // informs tool_object to load the log_file given in config - emit run( VGTOOL::PROC_PARSE_LOG ); -} - - /*! Setup the interface layout */ Modified: trunk/src/toolview/helgrindview.h =================================================================== --- trunk/src/toolview/helgrindview.h 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/toolview/helgrindview.h 2011-07-01 14:02:54 UTC (rev 543) @@ -48,7 +48,6 @@ void setupToolBar(); private slots: - void openLogFile(); void opencloseAllItems(); void opencloseOneItem(); void showSrcPath(); Modified: trunk/src/toolview/memcheckview.cpp =================================================================== --- trunk/src/toolview/memcheckview.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/toolview/memcheckview.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -32,7 +32,6 @@ #include <QAction> #include <QApplication> #include <QClipboard> -#include <QFileDialog> #include <QHeaderView> #include <QLabel> #include <QMenuBar> @@ -125,36 +124,7 @@ } -/*! - Parse and load a memcheck xml logfile. - TODO: fix. This starts a new 'run', so we should - trigger vk's "check last run over" before anything else... -*/ -void MemcheckView::openLogFile() -{ - //vkDebug( "MemcheckView::openLogFile()" ); - - QString last_file = vkCfgProj->value( "valkyrie/view-log" ).toString(); - if ( last_file.isEmpty() ) last_file = "./"; - - QString captn = "Select Log File"; - QString filt = "XML Files (*.xml);;Log Files (*.log.*);;All Files (*)"; - QString log_file = QFileDialog::getOpenFileName( this, captn, last_file, filt ); - - // user might have clicked Cancel - if ( log_file.isEmpty() ) { - return; - } - - // updates config (as does cmd line --view-cfg...) - emit logFileChosen( log_file ); - - // informs tool_object to load the log_file given in config - emit run( VGTOOL::PROC_PARSE_LOG ); -} - - /*! Setup the interface layout */ Modified: trunk/src/toolview/memcheckview.h =================================================================== --- trunk/src/toolview/memcheckview.h 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/toolview/memcheckview.h 2011-07-01 14:02:54 UTC (rev 543) @@ -48,7 +48,6 @@ void setupToolBar(); private slots: - void openLogFile(); void opencloseAllItems(); void opencloseOneItem(); void showSrcPath(); Modified: trunk/src/toolview/toolview.cpp =================================================================== --- trunk/src/toolview/toolview.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/toolview/toolview.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -18,11 +18,13 @@ ** ****************************************************************************/ +#include <QFileDialog> #include <QMenuBar> #include <QToolBar> #include "toolview/toolview.h" #include "mainwindow.h" +#include "utils/vk_config.h" #include "utils/vk_utils.h" @@ -133,8 +135,32 @@ } +/*! + Parse and load a valgrind xml logfile. + TODO: fix. This starts a new 'run', so we should + trigger vk's "check last run over" before anything else... +*/ +void ToolView::openLogFile() +{ + //vkDebug( "ToolView::openLogFile()" ); + + QString log_file = vkDlgCfgGetFile( this, "valkyrie/view-log" ); + + // user might have clicked Cancel + if ( log_file.isEmpty() ) { + return; + } + + // updates config (as does cmd line --view-cfg...) + emit logFileChosen( log_file ); + // informs tool_object to load the log_file given in config + emit run( VGTOOL::PROC_PARSE_LOG ); +} + + + /***************************************************************************/ /*! \class ToolViewStack Modified: trunk/src/toolview/toolview.h =================================================================== --- trunk/src/toolview/toolview.h 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/toolview/toolview.h 2011-07-01 14:02:54 UTC (rev 543) @@ -90,6 +90,9 @@ return toolId; } +protected slots: + void openLogFile(); + public slots: // called by the view's object virtual void setState( bool run ) = 0; Modified: trunk/src/utils/vk_config.cpp =================================================================== --- trunk/src/utils/vk_config.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/utils/vk_config.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -29,6 +29,7 @@ #include <QColor> #include <QDir> #include <QFile> +#include <QFileDialog> #include <QFileInfo> #include <QFileInfoList> #include <QPoint> @@ -42,10 +43,10 @@ Initialise static data: Basic configuration setup */ const unsigned int VkCfg::_projCfgVersion = 1; // @@@ increment if project config keys change @@@ -const unsigned int VkCfg::_glblCfgVersion = 1; // @@@ increment if global config keys change @@@ +const unsigned int VkCfg::_glblCfgVersion = 2; // @@@ increment if global config keys change @@@ const QString VkCfg::_email = "in...@op..."; // bug-reports -const QString VkCfg::_copyright = "Valkyrie is Copyright (C) 2003-2010 by OpenWorks GbR"; +const QString VkCfg::_copyright = "Valkyrie is Copyright (C) 2003-2011 by OpenWorks GbR"; const QString VkCfg::_vgCopyright = "Valgrind is Copyright (C) 2000-2010, and GNU GPL'd, by Julian Seward et al."; const QString VkCfg::_vgVersion = "3.6.0"; // supports this major Vg release const QString VkCfg::_name = VK_NAME; // application name @@ -101,6 +102,15 @@ const QString& VkCfg::appName() { return _name; } /*! + Valkyrie application title +*/ +const QString VkCfg::appTitle() +{ + QString title = _name; + return title.replace( 0, 1, title[0].toUpper() ); +} + +/*! Valkyrie application release version */ const QString& VkCfg::appVersion() { return _version; } @@ -381,13 +391,18 @@ clear(); vk_assert( allKeys().count() == 0 ); +//TODO: switch to using sections, and figure out backwards-compatibility issues... + setValue( "config_glbl_version", VkCfg::glblCfgVersion() ); setValue( "mainwindow_size", QSize( 600, 600 ) ); setValue( "mainwindow_pos", QPoint( 400, 0 ) ); + setValue( "handbook_history", QString() ); setValue( "handbook_bookmarks", QString() ); setValue( "handbook_max_history", 20 ); setValue( "handbook_max_bookmarks", 20 ); + setValue( "handbook_docdir", VkCfg::docDir() ); + setValue( "colour_background", QColor( 214, 205, 187 ) ); setValue( "colour_base", QColor( 255, 255, 255 ) ); setValue( "colour_dkgray", QColor( 128, 128, 128 ) ); @@ -395,8 +410,21 @@ setValue( "colour_highlight", QColor( 147, 40, 40 ) ); setValue( "colour_null", QColor( 239, 227, 211 ) ); setValue( "colour_text", QColor( 0, 0, 0 ) ); + setValue( "recent_projects", QString() ); + setValue( "project_path", "./" ); + // filefilters + // These are settings/caches for file/dir-dialogs: filterlist + default filter to use + // - list key = filefilters/<proj or glbl key, with all '/' replaced by '_'> + // - dflt key = <list key>-default + setValue( "filefilters/valkyrie_view-log", "XML Files (*.xml);;Log Files (*.log.*);;All Files (*)" ); + setValue( "filefilters/valkyrie_view-log-default", "" ); + setValue( "filefilters/handbook_docdir", "Html Files (*.html *.htm);;All Files (*)" ); + setValue( "filefilters/handbook_docdir-default", "" ); + setValue( "filefilters/project_path", "Valkyrie Projects (*." + VkCfg::filetype() + ")" ); + setValue( "filefilters/project_path-default", "" ); + sync(); } Modified: trunk/src/utils/vk_config.h =================================================================== --- trunk/src/utils/vk_config.h 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/utils/vk_config.h 2011-07-01 14:02:54 UTC (rev 543) @@ -48,6 +48,7 @@ static const QString& vgCopyright(); static const QString& vgVersion(); static const QString& appName(); + static const QString appTitle(); static const QString& appVersion(); static const QString& appPackage(); static const QString& tmpDir(); Modified: trunk/src/utils/vk_utils.cpp =================================================================== --- trunk/src/utils/vk_utils.cpp 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/utils/vk_utils.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -17,7 +17,7 @@ ** ****************************************************************************/ -#include "vk_utils.h" +#include "utils/vk_utils.h" #include "options/vk_option.h" #include "utils/vk_config.h" // vkname() @@ -25,6 +25,7 @@ #include <QDateTime> #include <QFile> +#include <QFileDialog> #include <QFileInfo> #include <QRegExp> #include <QString> @@ -351,6 +352,7 @@ QString absPath = QString::null; if ( QFile::exists( file_name ) ) { + // true for (good) directories, too. // file_name exists: get its absolute path. absPath = QFileInfo( file_name ).absoluteFilePath(); } @@ -474,3 +476,210 @@ bye: return absPath; } + + + +/*! + Dialog to choose a file + - start_path gives the path to first show (default: current dir) + - cfg_key_path is the (proj/glbl) cfg key for the item's path. + This is used to find the 'filefilter/<cfg_key_path>' setting. + If no key is given, default (and only) filter is "All files (*)". + - mode indicates save / open (changes QFileDialog) + Returns: chosen file path +*/ +QString vkDlgGetFile( QWidget* parent, + const QString& start_path/*="./"*/, + const QString& cfg_key_path/*=QString()*/, + QFileDialog::AcceptMode mode/*=QFileDialog::AcceptOpen*/ ) +{ + // defaults + QString filterlist = "All Files (*)"; // default filter list + QString filter = ""; // default filter + QString cfg_key_filterlist = ""; // glbl key, built from key_path + QString cfg_key_filter = ""; // glbl key, built from key_path + QString start_dir = start_path; + + if ( start_dir.isEmpty() ) { + start_dir = "./"; + } + else { + // start_dir may be a path-less file, a bad dir, or who knows what. + // try to resolve: first through given path, then via $PATH env var. + start_dir = getFileAbsPath( start_dir ); + } + + // setup filters + if ( !cfg_key_path.isEmpty() ){ + // check the global cfg (derive key from key_path) + cfg_key_filterlist = cfg_key_path; + cfg_key_filterlist = "filefilters/" + cfg_key_filterlist.replace("/", "_"); + cfg_key_filter = cfg_key_filterlist + "-default"; + + QString cfg_filterlist = vkCfgGlbl->value( cfg_key_filterlist ).toString(); + QString cfg_filter = vkCfgGlbl->value( cfg_key_filter ).toString(); + + if ( !cfg_filterlist.isEmpty() ) { + filterlist = cfg_filterlist; + if ( cfg_filterlist.contains( cfg_filter ) ) { + filter = cfg_filter; + } + } + } + + // Setup dialog + QString caption = "Choose File"; + if ( mode == QFileDialog::AcceptSave ) + caption = "Save As"; + + QFileDialog dlg( parent, caption, start_dir, filterlist ); + dlg.setFileMode(QFileDialog::AnyFile); + dlg.setViewMode(QFileDialog::Detail); + dlg.setAcceptMode( mode ); + dlg.selectFilter( filter ); + + // Run dialog - get filename to save to: asks for overwrite confirmation + QString fname; + if ( dlg.exec() ) { + QStringList fileNames = dlg.selectedFiles(); + if ( !fileNames.isEmpty() ) + fname = fileNames.first(); + } + + // save chosen filter (if changed) for next time + if ( !cfg_key_path.isEmpty() ) { + QString filter_new = dlg.selectedNameFilter(); + + if ( filter_new != filter ) { + vkCfgGlbl->setValue( cfg_key_filter, filter_new ); + } + } + + return fname; +} + + +/*! + Dialog to choose a file, using cached start_paths and filters + - start_path gives the directory to first show (default: current dir) + - cfg_key_path is the (proj/glbl) cfg key for the item's path. + This is used to get: + 1) the directory to open the dialog in (default: currentdir) + 2) the filter settings (default: "All files (*)") + - mode indicates save / open (changes QFileDialog) + Returns: chosen file path + + Note: don't use from options pages: they save to cache already. +*/ +QString vkDlgCfgGetFile( QWidget* parent, + const QString& cfg_key_path/*=QString()*/, + QFileDialog::AcceptMode mode/*=QFileDialog::AcceptOpen*/ ) +{ + // defaults + QString start_path = "./"; // default dir + bool pathIsDir = true; + bool isProjKey = true; // is key_path a project key + + // setup start directory + if ( !cfg_key_path.isEmpty() ){ + QFileInfo fi; + // check first project cfg then glbl cfg for the path key + if ( vkCfgProj->contains( cfg_key_path ) ) { + fi = vkCfgProj->value( cfg_key_path ).toString(); + } + else if ( vkCfgGlbl->contains( cfg_key_path ) ) { + fi = vkCfgGlbl->value( cfg_key_path ).toString(); + isProjKey = false; + } + else { + vkPrintErr( "Cfg key not found: '%s'. This shouldn't happen!", + qPrintable( cfg_key_path ) ); + } + + if ( fi.exists() ) { + pathIsDir = fi.isDir(); + // looks like a bug in Qt: if dir, absolutePath still takes off the last dir! + start_path = pathIsDir ? fi.absoluteFilePath() : fi.absolutePath(); + } + else { + vkDebug( "Bad path: '%s'", qPrintable( fi.absoluteFilePath() ) ); + // ignore a bad path. + } + } + + QString fname = vkDlgGetFile( parent, start_path, cfg_key_path, mode ); + + // save chosen path to cfg for next time + if ( !cfg_key_path.isEmpty() && !fname.isEmpty() ) { + QString path = fname; + QFileInfo fi( path ); + path = pathIsDir ? fi.absolutePath() : fi.absoluteFilePath(); + if ( isProjKey ) + vkCfgProj->setValue( cfg_key_path, path ); + else + vkCfgGlbl->setValue( cfg_key_path, path ); + } + + return fname; +} + + + + +/*! + Dialog to choose a directory + - default start_dir is current directory + Returns: chosen directory path +*/ +QString vkDlgGetDir( QWidget* parent, const QString& start_dir/*="./"*/ ) +{ + // Setup dialog + QFileDialog dlg( parent, "Choose Directory", start_dir ); + dlg.setFileMode( QFileDialog::Directory ); + dlg.setViewMode( QFileDialog::Detail ); + dlg.setAcceptMode( QFileDialog::AcceptOpen ); + dlg.setOption( QFileDialog::ShowDirsOnly ); + + // Run dialog - get filename to save to: asks for overwrite confirmation + QString dir_selected; + if ( dlg.exec() ) { + QStringList fileNames = dlg.selectedFiles(); + if ( !fileNames.isEmpty() ) + dir_selected = fileNames.first(); + } + + return dir_selected; +} + + +#if 0 // As-yet unused, untested... +/*! + Dialog to choose a directory + - cfg_key_path is the (proj/glbl) cfg key for the start directory + The cfg is updated if a directory is chosen. + Returns: chosen directory path + + Note: don't use from options pages: they save to cache already.// - careful: don't use in options pages: don't want to save cfg before our turn! +*/ +QString vkDirCfgDialog( QWidget* parent, + const QString& cfg_key_dir/*=QString()*/ ) +{ + // setup start directory + QString start_dir = "./"; + if ( !cfg_key_dir.isEmpty() ) { + QFileInfo fi( vkCfgProj->value( cfg_key_dir ).toString() ); + start_dir = fi.exists() ? fi.absolutePath() : "./"; + } + + QString dirname = vkDlgGetDir( parent, start_dir ); + + // save chosen directory for next time + if ( !cfg_key_dir.isEmpty() && !dirname.isEmpty() ) { + vkCfgProj->setValue( cfg_key_dir, dirname ); + } + + return dirname; +} +#endif + + Modified: trunk/src/utils/vk_utils.h =================================================================== --- trunk/src/utils/vk_utils.h 2011-07-01 07:29:48 UTC (rev 542) +++ trunk/src/utils/vk_utils.h 2011-07-01 14:02:54 UTC (rev 543) @@ -24,6 +24,7 @@ #include <iostream> #include <QString> +#include <QFileDialog> using namespace std; @@ -145,4 +146,21 @@ bool check_exe=false ); +// ============================================================ +// file/dir dialogs, +QString vkDlgGetFile( QWidget* parent, + const QString& start_dir = "./", + const QString& cfg_key_path = QString(), + QFileDialog::AcceptMode mode = QFileDialog::AcceptOpen ); + +QString vkDlgCfgGetFile( QWidget* parent, + const QString& cfg_key_path = QString(), + QFileDialog::AcceptMode mode = QFileDialog::AcceptOpen ); + +QString vkDlgGetDir( QWidget* parent, + const QString& start_dir = "./" ); + + + + #endif Added: trunk/src/utils/vknewprojectdialog.cpp =================================================================== --- trunk/src/utils/vknewprojectdialog.cpp (rev 0) +++ trunk/src/utils/vknewprojectdialog.cpp 2011-07-01 14:02:54 UTC (rev 543) @@ -0,0 +1,184 @@ +/**************************************************************************** +** VkNewProjectDialog implementation +** -------------------------------------------------------------------------- +** +** Copyright (C) 2011-2011, OpenWorks LLP. All rights reserved. +** <in...@op...> +** +** This file is part of Valkyrie, a front-end for Valgrind. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file COPYING included in the packaging of +** this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "utils/vknewprojectdialog.h" +#include "utils/vk_messages.h" +#include "utils/vk_utils.h" +#include "utils/vk_config.h" + +#include <QDir> +#include <QGroupBox> +#include <QLabel> +#include <QPushButton> +#include <QVBoxLayout> + +#define LBL_STYLE_WARN "QLabel { background-color : red; color : black; }" +#define EDIT_STYLE_WARN "QLineEdit { color: red }" + + +VkNewProjectDialog::VkNewProjectDialog( QWidget* parent ) + : QDialog( parent ) +{ + // ------------------------------------------------------------ + setObjectName( QString::fromUtf8( "VkNewProjectDialog" ) ); + setWindowTitle( "Create New Valkyrie Project" ); + + QVBoxLayout* topVLayout = new QVBoxLayout( this ); + + // top text + QLabel* topText = new QLabel( this ); + topText->setText( "Enter a new project name and the directory under which it should be created." ); + topVLayout->addWidget( topText ); + + // ------------------------------------------------------------ + // group box + QGroupBox* groupbox = new QGroupBox( this ); + groupbox->setObjectName( QString::fromUtf8( "groupbox" ) ); + topVLayout->addWidget( groupbox ); + + // ------------------------------------------------------------ + // grid + QGridLayout* grid = new QGridLayout( groupbox ); + grid->setObjectName( QString::fromUtf8( "grid" )); + + // ------------------------------------------------------------ + // content + QLabel* lbl_name = new QLabel( "Name: ", groupbox ); + edit_name = new QLineEdit( groupbox ); + connect( edit_name, SIGNAL(textEdited(QString)), this, SLOT( checkInput() ) ); + + QLabel* lbl_dir = new QLabel( "Create in: ", groupbox ); + edit_dir = new QLineEdit( groupbox ); + connect( edit_dir, SIGNAL(textEdited(QString)), this, SLOT( checkInput() ) ); + + QPushButton* butt_dir = new QPushButton( "Browse...", groupbox ); + connect( butt_dir, SIGNAL( clicked() ), this, SLOT( browseDir() ) ); + + lbl_warn = new QLabel( groupbox ); + + grid->addWidget( lbl_name, 0, 0, 1, 1 ); + grid->addWidget( edit_name, 0, 1, 1, 2 ); + grid->addWidget( lbl_dir, 1, 0, 1, 1 ); + grid->addWidget( edit_dir, 1, 1, 1, 1 ); + grid->addWidget( butt_dir, 1, 2, 1, 1 ); + grid->addWidget( lbl_warn, 2, 0, 1, 3 ); + + // ------------------------------------------------------------ + // buttons + buttonBox = new QDialogButtonBox( this ); + buttonBox->setObjectName( QString::fromUtf8( "buttonBox" ) ); + buttonBox->setOrientation( Qt::Horizontal ); + buttonBox->setStandardButtons( QDialogButtonBox::Cancel | QDialogButtonBox::Ok ); + connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) ); // Cancel + connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) ); // Ok + topVLayout->addWidget( buttonBox ); + + + // ------------------------------------------------------------ + // defaults + QFileInfo fi( vkCfgGlbl->value( "project_path" ).toString() ); + QString start_dir = QDir::currentPath(); + if ( fi.exists() ) { + // looks like a bug in Qt: if dir, absolutePath still takes off the last dir! + start_dir = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); + } + edit_dir->setText( start_dir ); + + edit_name->setText( "untitled" ); + + edit_style_normal = edit_dir->styleSheet(); + lbl_style_normal = lbl_warn->styleSheet(); +} + +void VkNewProjectDialog::accept() +{ + QFileInfo fi( getProjectPath() ); + if ( fi.exists() ) { + int ok = vkQuery( this, "Project already exists", "&Yes;&No", + "<p>A project with the same name was found in the given directory.</p>" + "<p>Do you want to overwrite it?</p>" ); + + if ( ok == MsgBox::vkNo ) { + return; // try again + } + + } + + // save chosen path to cfg + vkCfgGlbl->setValue( "project_path", getProjectPath() ); + + QDialog::accept(); +} + +void VkNewProjectDialog::checkInput() +{ + QString warning = ""; + bool name_ok = true; + bool dir_ok = true; + + // check name + QString name = edit_name->text(); + if ( name.isEmpty() ) { + warning = QString( "Name is empty."); + name_ok = false; + } + else { + int idx = name.lastIndexOf( QRegExp("[^a-zA-Z0-9_-]") ); + if ( idx != -1 ) { + warning = QString( "invalid character: '%1'").arg( name.at( idx ) ); + name_ok = false; + } + } + + // check path - overrides projectname warning. + QString path = edit_dir->text(); + QFileInfo fi( path ); + if ( !fi.exists() ) { + warning = QString( "The path '%1' does not exist." ).arg( path ); + dir_ok = false; + } + + // based on warning string, set the warnings on/off + edit_dir->setStyleSheet( dir_ok ? edit_style_normal : EDIT_STYLE_WARN ); + edit_name->setStyleSheet( name_ok ? edit_style_normal : EDIT_STYLE_WARN ); + if ( dir_ok && name_ok ) { + lbl_warn->setStyleSheet( lbl_style_normal ); + lbl_warn->setText( "" ); + buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true ); + } + else { + lbl_warn->setStyleSheet( LBL_STYLE_WARN ); + lbl_warn->setText( warning ); + buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); + } +} + +void VkNewProjectDialog::browseDir() +{ + QString dir_new = vkDlgGetDir( this, edit_dir->text() ); + + if ( !dir_new.isEmpty() ) { // user might have clicked Cancel + edit_dir->setText( dir_new ); + } +} + +QString VkNewProjectDialog::getProjectPath() +{ + return edit_dir->text() + "/" + edit_name->text() + "." + VkCfg::filetype(); +} Added: trunk/src/utils/vknewprojectdialog.h =================================================================== --- trunk/src/utils/vknewprojectdialog.h (rev 0) +++ trunk/src/utils/vknewprojectdialog.h 2011-07-01 14:02:54 UTC (rev 543) @@ -0,0 +1,53 @@ +/**************************************************************************** +** VkNewProjectDialog definition +** -------------------------------------------------------------------------- +** +** Copyright (C) 2011-2011, OpenWorks LLP. All rights reserved. +** <in...@op...> +** +** This file is part of Valkyrie, a front-end for Valgrind. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file COPYING included in the packaging of +** this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef VKNEWPROJECTDIALOG_H +#define VKNEWPROJECTDIALOG_H + +#include <QDialog> +#include <QDialogButtonBox> +#include <QString> +#include <QLabel> +#include <QLineEdit> + + +class VkNewProjectDialog : public QDialog +{ + Q_OBJECT +public: + VkNewProjectDialog( QWidget *parent = 0 ); + + + QString getProjectPath(); + + private slots: + void accept(); + void browseDir(); + void checkInput(); + + private: + QLineEdit* edit_name; + QLineEdit* edit_dir; + QLabel* lbl_warn; + QString lbl_style_normal; + QString edit_style_normal; + QDialogButtonBox* buttonBox; +}; + +#endif // VKNEWPROJECTDIALOG_H |