You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
(2) |
Apr
(3) |
May
|
Jun
(45) |
Jul
(4) |
Aug
|
Sep
(7) |
Oct
(1) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(4) |
Feb
(4) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(1) |
Nov
|
Dec
(7) |
2010 |
Jan
(9) |
Feb
(5) |
Mar
(22) |
Apr
(1) |
May
(5) |
Jun
|
Jul
(2) |
Aug
|
Sep
(22) |
Oct
(6) |
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(17) |
Jul
(5) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sv...@va...> - 2010-03-05 01:18:16
|
Author: cerion Date: 2010-03-05 01:17:52 +0000 (Fri, 05 Mar 2010) New Revision: 482 Log: Tidied code up using 'astyle' Astyle config setup based on 'the one true brace style' No fuctional changes. Added: branches/valkyrie_qt4port/dev/ branches/valkyrie_qt4port/dev/astyle.conf branches/valkyrie_qt4port/dev/beautify_all.sh Modified: branches/valkyrie_qt4port/help/help_about.cpp branches/valkyrie_qt4port/help/help_about.h branches/valkyrie_qt4port/help/help_context.cpp branches/valkyrie_qt4port/help/help_context.h branches/valkyrie_qt4port/help/help_handbook.cpp branches/valkyrie_qt4port/help/help_handbook.h branches/valkyrie_qt4port/help/help_urls.cpp branches/valkyrie_qt4port/help/help_urls.h branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/helgrind_object.cpp branches/valkyrie_qt4port/objects/helgrind_object.h branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/tool_object.cpp branches/valkyrie_qt4port/objects/tool_object.h branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/objects/vk_objects.cpp branches/valkyrie_qt4port/objects/vk_objects.h branches/valkyrie_qt4port/options/helgrind_options_page.cpp branches/valkyrie_qt4port/options/helgrind_options_page.h branches/valkyrie_qt4port/options/memcheck_options_page.cpp branches/valkyrie_qt4port/options/memcheck_options_page.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valgrind_options_page.h branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.h branches/valkyrie_qt4port/options/vk_option.cpp branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/options/vk_options_dialog.h branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.h branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp branches/valkyrie_qt4port/options/vk_popt.cpp branches/valkyrie_qt4port/options/vk_popt.h branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_base_widget.h branches/valkyrie_qt4port/options/widgets/opt_cb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_cb_widget.h branches/valkyrie_qt4port/options/widgets/opt_ck_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_ck_widget.h branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.h branches/valkyrie_qt4port/options/widgets/opt_le_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_le_widget.h branches/valkyrie_qt4port/options/widgets/opt_sp_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_sp_widget.h branches/valkyrie_qt4port/toolview/helgrindview.cpp branches/valkyrie_qt4port/toolview/helgrindview.h branches/valkyrie_qt4port/toolview/memcheckview.cpp branches/valkyrie_qt4port/toolview/memcheckview.h branches/valkyrie_qt4port/toolview/toolview.cpp branches/valkyrie_qt4port/toolview/toolview.h branches/valkyrie_qt4port/toolview/vglogview.cpp branches/valkyrie_qt4port/toolview/vglogview.h branches/valkyrie_qt4port/utils/vglog.cpp branches/valkyrie_qt4port/utils/vglog.h branches/valkyrie_qt4port/utils/vglogreader.cpp branches/valkyrie_qt4port/utils/vglogreader.h branches/valkyrie_qt4port/utils/vk_config.cpp branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/utils/vk_logpoller.cpp branches/valkyrie_qt4port/utils/vk_logpoller.h branches/valkyrie_qt4port/utils/vk_messages.cpp branches/valkyrie_qt4port/utils/vk_messages.h branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h [... diff too large to include ...] |
From: <sv...@va...> - 2010-03-04 22:02:36
|
Author: cerion Date: 2010-03-04 22:02:19 +0000 (Thu, 04 Mar 2010) New Revision: 481 Log: a little cleanup - no functional changes QApplication::translate() -> tr() some spacing, etc. Modified: branches/valkyrie_qt4port/help/help_handbook.cpp branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/options/memcheck_options_page.cpp branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp branches/valkyrie_qt4port/options/vk_popt.cpp branches/valkyrie_qt4port/toolview/helgrindview.cpp branches/valkyrie_qt4port/toolview/memcheckview.cpp Modified: branches/valkyrie_qt4port/help/help_handbook.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/help/help_handbook.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -204,8 +204,9 @@ */ void HandBook::openFile() { - QString fn = QFileDialog::getOpenFileName( this, "Open File", vkConfig->vkDocPath, - "Html Files (*.html *.htm);;All Files (*)" ); + QString fn = QFileDialog::getOpenFileName( + this, "Open File", vkConfig->vkDocPath, + "Html Files (*.html *.htm);;All Files (*)" ); if ( !fn.isEmpty() ) { browser->setSource( fn ); } @@ -293,17 +294,17 @@ // file menu QMenu* fileMenu = new QMenu( menuBar ); fileMenu->setObjectName( QString::fromUtf8("handbook_fileMenu") ); - fileMenu->setTitle( QApplication::translate("MainWindowClass", "&File", 0, QApplication::UnicodeUTF8) ); + fileMenu->setTitle( tr( "&File" ) ); menuBar->addAction( fileMenu->menuAction() ); QAction* actFile_Open = new QAction( this ); actFile_Open->setObjectName( QString::fromUtf8("handbook_actFile_Open") ); - actFile_Open->setText( QApplication::translate("HandBook", "Open File", 0, QApplication::UnicodeUTF8) ); + actFile_Open->setText( tr( "Open File" ) ); connect( actFile_Open, SIGNAL( triggered() ), this, SLOT( openFile() ) ); QAction* actFile_Close = new QAction( this ); actFile_Close->setObjectName( QString::fromUtf8("handbook_actFile_Close") ); - actFile_Close->setText( QApplication::translate("HandBook", "Close", 0, QApplication::UnicodeUTF8) ); + actFile_Close->setText( tr( "Close" ) ); connect( actFile_Close, SIGNAL( triggered() ), this, SLOT( close() ) ); fileMenu->addAction( actFile_Open ); @@ -314,30 +315,30 @@ // go menu QMenu* goMenu = new QMenu( menuBar ); goMenu->setObjectName( QString::fromUtf8("handbook_goMenu") ); - goMenu->setTitle( QApplication::translate("MainWindowClass", "&Go", 0, QApplication::UnicodeUTF8) ); + goMenu->setTitle( tr( "&Go" ) ); menuBar->addAction( goMenu->menuAction() ); QAction* actGo_Backward = new QAction( this ); actGo_Backward->setObjectName( QString::fromUtf8("handbook_actGo_Backward") ); - actGo_Backward->setText( QApplication::translate("HandBook", "Backward", 0, QApplication::UnicodeUTF8) ); + actGo_Backward->setText( tr( "Backward" ) ); actGo_Backward->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_back.xpm") ) ); connect( actGo_Backward, SIGNAL( triggered() ), browser, SLOT( backward() ) ); QAction* actGo_Forward = new QAction( this ); actGo_Forward->setObjectName( QString::fromUtf8("handbook_actGo_Forward") ); - actGo_Forward->setText( QApplication::translate("HandBook", "Forward", 0, QApplication::UnicodeUTF8) ); + actGo_Forward->setText( tr( "Forward" ) ); actGo_Forward->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_forward.xpm") ) ); connect( actGo_Forward, SIGNAL( triggered() ), browser, SLOT( forward() ) ); QAction* actGo_Home = new QAction( this ); actGo_Home->setObjectName( QString::fromUtf8("handbook_actGo_Home") ); - actGo_Home->setText( QApplication::translate("HandBook", "Home", 0, QApplication::UnicodeUTF8) ); + actGo_Home->setText( tr( "Home" ) ); actGo_Home->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_home.xpm") ) ); connect( actGo_Home, SIGNAL( triggered() ), browser, SLOT( home() ) ); QAction* actGo_Reload = new QAction( this ); actGo_Reload->setObjectName( QString::fromUtf8("handbook_actGo_Reload") ); - actGo_Reload->setText( QApplication::translate("HandBook", "Reload", 0, QApplication::UnicodeUTF8) ); + actGo_Reload->setText( tr( "Reload" ) ); actGo_Reload->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_reload.xpm") ) ); connect( actGo_Reload, SIGNAL( triggered() ), browser, SLOT( reload() ) ); @@ -357,7 +358,7 @@ // history menu historyMenu = new QMenu( menuBar ); historyMenu->setObjectName( QString::fromUtf8("handbook_historyMenu") ); - historyMenu->setTitle( QApplication::translate("MainWindowClass", "History", 0, QApplication::UnicodeUTF8) ); + historyMenu->setTitle( tr( "History" ) ); menuBar->addAction( historyMenu->menuAction() ); connect( historyMenu, SIGNAL( triggered( QAction* ) ), this, SLOT( historyChosen( QAction* ) ) ); @@ -367,12 +368,12 @@ // bookmarks menu bookmarkMenu = new QMenu( menuBar ); bookmarkMenu->setObjectName( QString::fromUtf8("handbook_bookmarkMenu") ); - bookmarkMenu->setTitle( QApplication::translate("MainWindowClass", "Bookmark", 0, QApplication::UnicodeUTF8) ); + bookmarkMenu->setTitle( tr( "Bookmark" ) ); menuBar->addAction( bookmarkMenu->menuAction() ); QAction* actBM_AddBM = new QAction( this ); actBM_AddBM->setObjectName( QString::fromUtf8("handbook_actBM_AddBM") ); - actBM_AddBM->setText( QApplication::translate("HandBook", "Add Bookmark", 0, QApplication::UnicodeUTF8) ); + actBM_AddBM->setText( tr( "Add Bookmark" ) ); connect( actBM_AddBM, SIGNAL( triggered() ), this, SLOT( addBookmark() ) ); bookmarkMenu->addAction( actBM_AddBM ); @@ -386,7 +387,7 @@ // dismiss button QAction* act_dismiss = new QAction( this ); act_dismiss->setObjectName( QString::fromUtf8("act_dismiss") ); - act_dismiss->setText( QApplication::translate("HandBook", "Dismiss", 0, QApplication::UnicodeUTF8) ); + act_dismiss->setText( tr( "Dismiss" ) ); connect( act_dismiss, SIGNAL( triggered() ), this, SLOT( close() ) ); Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/main.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -90,7 +90,8 @@ // ------------------------------------------------------------ // Start up the gui vkWin = new MainWindow( &valkyrie ); - if ( vkConfig->value( valkyrie.getOption( VALKYRIE::BINARY )->configKey() ).toString().isEmpty() ) { + if ( vkConfig->value( + valkyrie.getOption( VALKYRIE::BINARY )->configKey() ).toString().isEmpty() ) { vkWin->openOptions(); } vkWin->showToolView( VGTOOL::ID_MEMCHECK ); Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -77,7 +77,8 @@ lastPalette = qApp->palette(); QIcon icon_vk; - icon_vk.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valkyrie.xpm") ), QIcon::Normal, QIcon::Off ); + icon_vk.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valkyrie.xpm") ), + QIcon::Normal, QIcon::Off ); setWindowIcon( icon_vk ); // handbook: init before menubar / toolbar @@ -190,96 +191,103 @@ actFile_NewProj = new QAction( this ); actFile_NewProj->setObjectName( QString::fromUtf8("actFile_NewProj") ); - actFile_NewProj->setText( QApplication::translate("MainWindowClass", "&New Project...", 0, QApplication::UnicodeUTF8) ); + actFile_NewProj->setText( tr( "&New Project..." ) ); actFile_NewProj->setToolTip( tr("Create a project to save your configuration") ); QIcon icon_newproj; - icon_newproj.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/filenew.png") ), QIcon::Normal, QIcon::Off ); + icon_newproj.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/filenew.png") ), + QIcon::Normal, QIcon::Off ); actFile_NewProj->setIcon( icon_newproj ); connect( actFile_NewProj, SIGNAL( triggered() ), this, SLOT( createNewProject() ) ); actFile_OpenProj = new QAction( this ); actFile_OpenProj->setObjectName( QString::fromUtf8("actFile_OpenProj") ); - actFile_OpenProj->setText( QApplication::translate("MainWindowClass", "&Open Project...", 0, QApplication::UnicodeUTF8) ); + actFile_OpenProj->setText( tr( "&Open Project..." ) ); actFile_OpenProj->setToolTip( tr("Open an existing project to load a saved configuration") ); QIcon icon_openproj; - icon_openproj.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/folder_blue.png") ), QIcon::Normal, QIcon::Off ); + icon_openproj.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/folder_blue.png") ), + QIcon::Normal, QIcon::Off ); actFile_OpenProj->setIcon( icon_openproj ); connect( actFile_OpenProj, SIGNAL( triggered() ), this, SLOT( openProject() ) ); actFile_Close = new QAction( this ); actFile_Close->setObjectName( QString::fromUtf8("actFile_Close") ); actFile_Close->setToolTip( tr("Close the currently active tool") ); - actFile_Close->setText( QApplication::translate("MainWindowClass", "&Close Tool", 0, QApplication::UnicodeUTF8) ); + actFile_Close->setText( tr( "&Close Tool" ) ); connect( actFile_Close, SIGNAL( triggered() ), this, SLOT( closeToolView() ) ); actFile_Exit = new QAction( this ); actFile_Exit->setObjectName( QString::fromUtf8("actFile_Exit") ); - actFile_Exit->setText( QApplication::translate("MainWindowClass", "E&xit", 0, QApplication::UnicodeUTF8) ); + actFile_Exit->setText( tr( "E&xit" ) ); actFile_Exit->setToolTip( tr("Exit Valkyrie") ); QIcon icon_exit; - icon_exit.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/exit.png") ), QIcon::Normal, QIcon::Off ); + icon_exit.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/exit.png") ), + QIcon::Normal, QIcon::Off ); actFile_Exit->setIcon( icon_exit ); connect( actFile_Exit, SIGNAL( triggered() ), qApp, SLOT( closeAllWindows() ) ); actEdit_Options = new QAction( this ); actEdit_Options->setObjectName( QString::fromUtf8("actEdit_Options") ); - actEdit_Options->setText( QApplication::translate("MainWindowClass", "O&ptions", 0, QApplication::UnicodeUTF8) ); + actEdit_Options->setText( tr( "O&ptions" ) ); actEdit_Options->setToolTip( tr("Open the options-editing window") ); QIcon icon_options; - icon_options.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/gear.png") ), QIcon::Normal, QIcon::Off ); + icon_options.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/gear.png") ), + QIcon::Normal, QIcon::Off ); actEdit_Options->setIcon( icon_options ); connect( actEdit_Options, SIGNAL( triggered() ), this, SLOT( openOptions() ) ); actProcess_Run = new QAction( this ); actProcess_Run->setObjectName( QString::fromUtf8("actProcess_Run") ); - actProcess_Run->setText( QApplication::translate("MainWindowClass", "&Run", 0, QApplication::UnicodeUTF8) ); + actProcess_Run->setText( tr( "&Run" ) ); actProcess_Run->setToolTip( tr("Run Valgrind with the currently active tool") ); - actProcess_Run->setShortcut( QApplication::translate("MainWindowClass", "Ctrl+R", 0, QApplication::UnicodeUTF8) ); + actProcess_Run->setShortcut( QString::fromUtf8( "Ctrl+R" ) ); QIcon icon_run; - icon_run.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valgrind_run.png") ), QIcon::Normal, QIcon::Off ); + icon_run.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valgrind_run.png") ), + QIcon::Normal, QIcon::Off ); actProcess_Run->setIcon( icon_run ); actProcess_Run->setIconVisibleInMenu( true ); connect( actProcess_Run, SIGNAL( triggered() ), this, SLOT( runValgrind() ) ); actProcess_Stop = new QAction( this ); actProcess_Stop->setObjectName( QString::fromUtf8("actProcess_Stop") ); - actProcess_Stop->setText( QApplication::translate("MainWindowClass", "S&top", 0, QApplication::UnicodeUTF8) ); + actProcess_Stop->setText( tr( "S&top" ) ); actProcess_Stop->setToolTip( tr("Stop Valgrind") ); QIcon icon_stop; - icon_stop.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valgrind_stop.png") ), QIcon::Normal, QIcon::Off ); + icon_stop.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valgrind_stop.png") ), + QIcon::Normal, QIcon::Off ); actProcess_Stop->setIcon( icon_stop ); connect( actProcess_Stop, SIGNAL( triggered() ), this, SLOT( stopTool() ) ); actHelp_Handbook = new QAction( this ); actHelp_Handbook->setObjectName( QString::fromUtf8("actHelp_Handbook") ); - actHelp_Handbook->setText( QApplication::translate("MainWindowClass", "Handbook", 0, QApplication::UnicodeUTF8) ); + actHelp_Handbook->setText( tr( "Handbook" ) ); actHelp_Handbook->setToolTip( tr("Open the Valkyrie Handbook") ); - actHelp_Handbook->setShortcut( QApplication::translate("MainWindowClass", "F1", 0, QApplication::UnicodeUTF8) ); + actHelp_Handbook->setShortcut( QString::fromUtf8( "F1" ) ); QIcon icon_handbook; - icon_handbook.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_help.xpm") ), QIcon::Normal, QIcon::Off ); + icon_handbook.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_help.xpm") ), + QIcon::Normal, QIcon::Off ); actHelp_Handbook->setIcon( icon_handbook ); connect( actHelp_Handbook, SIGNAL( triggered() ), this, SLOT( openHandBook() ) ); actHelp_About_Valkyrie = new QAction( this ); actHelp_About_Valkyrie->setObjectName( QString::fromUtf8("actHelp_About_Valkyrie") ); - actHelp_About_Valkyrie->setText( QApplication::translate("MainWindowClass", "About Valkyrie", 0, QApplication::UnicodeUTF8) ); + actHelp_About_Valkyrie->setText( tr( "About Valkyrie" ) ); // actHelp_About_Valkyrie->setMenuRole( QAction::AboutRole ); connect( actHelp_About_Valkyrie, SIGNAL( triggered() ), this, SLOT( openAboutVk() ) ); actHelp_About_Qt = new QAction( this ); actHelp_About_Qt->setObjectName( QString::fromUtf8("actHelp_About_Qt") ); - actHelp_About_Qt->setText( QApplication::translate("MainWindowClass", "About Qt", 0, QApplication::UnicodeUTF8) ); + actHelp_About_Qt->setText( tr( "About Qt" ) ); // actHelp_About_Qt->setMenuRole( QAction::AboutQtRole ); connect( actHelp_About_Qt, SIGNAL( triggered() ), qApp, SLOT( aboutQt() ) ); actHelp_License = new QAction( this ); actHelp_License->setObjectName( QString::fromUtf8("actHelp_License") ); - actHelp_License->setText( QApplication::translate("MainWindowClass", "License", 0, QApplication::UnicodeUTF8) ); + actHelp_License->setText( tr( "License" ) ); connect( actHelp_License, SIGNAL( triggered() ), this, SLOT( openAboutLicense() ) ); actHelp_Support = new QAction( this ); actHelp_Support->setObjectName( QString::fromUtf8("actHelp_Support") ); - actHelp_Support->setText( QApplication::translate("MainWindowClass", "Support", 0, QApplication::UnicodeUTF8) ); + actHelp_Support->setText( tr( "Support" ) ); connect( actHelp_Support, SIGNAL( triggered() ), this, SLOT( openAboutSupport() ) ); @@ -291,7 +299,8 @@ connect( toolActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( toolGroupTriggered( QAction* ) ) ); QIcon icon_bullet; - icon_bullet.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_mainwin_blackbullet.xpm") ), QIcon::Normal, QIcon::Off ); + icon_bullet.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_mainwin_blackbullet.xpm") ), + QIcon::Normal, QIcon::Off ); ToolObjList tools = valkyrie->valgrind()->getToolObjList(); vk_assert( tools.size() > 0 ); @@ -330,23 +339,23 @@ menuFile = new QMenu( menuBar ); menuFile->setObjectName( QString::fromUtf8("menuFile") ); - menuFile->setTitle( QApplication::translate("MainWindowClass", "&File", 0, QApplication::UnicodeUTF8) ); + menuFile->setTitle( tr( "&File" ) ); menuEdit = new QMenu( menuBar ); menuEdit->setObjectName( QString::fromUtf8("menuEdit") ); - menuEdit->setTitle( QApplication::translate("MainWindowClass", "&Edit", 0, QApplication::UnicodeUTF8) ); + menuEdit->setTitle( tr( "&Edit" ) ); menuProcess = new QMenu( menuBar ); menuProcess->setObjectName( QString::fromUtf8("menuProcess") ); - menuProcess->setTitle( QApplication::translate("MainWindowClass", "&Process", 0, QApplication::UnicodeUTF8) ); + menuProcess->setTitle( tr( "&Process" ) ); menuTools = new QMenu( menuBar ); menuTools->setObjectName( QString::fromUtf8("menuTools") ); - menuTools->setTitle( QApplication::translate("MainWindowClass", "&Tools", 0, QApplication::UnicodeUTF8) ); + menuTools->setTitle( tr( "&Tools" ) ); menuHelp = new QMenu( menuBar ); menuHelp->setObjectName( QString::fromUtf8("menuHelp") ); - menuHelp->setTitle( QApplication::translate("MainWindowClass", "Help", 0, QApplication::UnicodeUTF8) ); + menuHelp->setTitle( tr( "Help" ) ); // application-wide context help button ContextHelpAction* ctxtHlpAction = new ContextHelpAction( this, handBook ); - ctxtHlpAction->setText( QApplication::translate("MainWindowClass", "Context Help", 0, QApplication::UnicodeUTF8) ); + ctxtHlpAction->setText( tr( "Context Help" ) ); // ------------------------------------------------------------ @@ -914,7 +923,6 @@ */ void MainWindow::stopTool() { - cerr << "TODO: MainWindow::stopTool()" << endl; valkyrie->stopTool( toolViewStack->currentToolId() ); } Modified: branches/valkyrie_qt4port/objects/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.h 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-03-04 22:02:19 UTC (rev 481) @@ -58,9 +58,9 @@ SHOW_BELOW, // --show-below-main /* suppressions hackery */ - SUPPS_DIRS, /* list of suppfile dirs - feeds SUPPS_AVAIL list */ - SUPPS_AVAIL, /* fake opt: dyname list of available supp files */ - SUPPS_SEL, /* the currently selected suppression(s) */ + SUPPS_DIRS, // list of suppfile dirs - feeds SUPPS_AVAIL list + SUPPS_AVAIL, // fake opt: dyname list of available supp files + SUPPS_SEL, // the currently selected suppression(s) /* misc */ GEN_SUPP, // --gen-suppressions Modified: branches/valkyrie_qt4port/options/memcheck_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/memcheck_options_page.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/options/memcheck_options_page.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -85,7 +85,7 @@ int i=0; QGridLayout* grid1 = new QGridLayout( group1 ); grid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row -// grid1->setColStretch( 1, 10 ); /* push widgets to the left */ +// grid1->setColStretch( 1, 10 ); // push widgets to the left grid1->addLayout( m_itemList[MEMCHECK::LEAK_CHECK]->hlayout(), i++, 0 ); grid1->addWidget( m_itemList[MEMCHECK::SHOW_REACH]->widget(), i++, 0 ); Modified: branches/valkyrie_qt4port/options/vk_option.h =================================================================== --- branches/valkyrie_qt4port/options/vk_option.h 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/options/vk_option.h 2010-03-04 22:02:19 UTC (rev 481) @@ -78,8 +78,7 @@ #define PERROR_BADNUMBER -17 /* invalid numeric value */ #define PERROR_OUTOFRANGE -18 /* outside min|max values */ #define PERROR_OVERFLOW -19 /* number too large or too small */ -#define PERROR_BADOPERATION -20 /* mutually exclusive logical - operations requested */ +#define PERROR_BADOPERATION -20 /* mutually exclusive logical operations requested */ #define PERROR_NULLARG -21 /* opt->arg should not be NULL */ #define PERROR_MALLOC -22 /* memory allocation failed */ #define PERROR_BADDIR -23 /* dir does not exist */ @@ -89,8 +88,7 @@ #define PERROR_BADFILEWR -27 /* user hasn't got wr permission */ #define PERROR_BADEXEC -28 /* user hasn't got exec permission */ #define PERROR_DB_CONFLICT -29 /* db-attach -v- trace-children */ -#define PERROR_DB_OUTPUT -30 /* using db-attach, but not sending - output to stderr */ +#define PERROR_DB_OUTPUT -30 /* using db-attach, but not sending output to stderr */ #define PERROR_POWER_OF_TWO -31 /* number not a power of two */ #define PERROR_BADVERSION -32 /* bad program version */ Modified: branches/valkyrie_qt4port/options/vk_options_dialog.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_dialog.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/options/vk_options_dialog.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -164,7 +164,8 @@ optionsButtonBox = new QDialogButtonBox( hButtonWidget ); optionsButtonBox->setObjectName(QString::fromUtf8("optionsButtonBox")); optionsButtonBox->setOrientation(Qt::Horizontal); - optionsButtonBox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + optionsButtonBox->setStandardButtons(QDialogButtonBox::Apply| + QDialogButtonBox::Cancel|QDialogButtonBox::Ok); hLayoutButtons->addWidget( optionsButtonBox ); Modified: branches/valkyrie_qt4port/options/vk_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -249,8 +249,9 @@ QString val = vkConfig->value( opt->configKey() ).toString(); int ival = val.toInt(&ok); if ( !ok ) { - cerr << "Error in VkOptionsPage::insertOptionWidget( " << optid << " ): " << - "VkOPT::WDG_SPINBOX: bad int conversion from: '" << val.toLatin1().data() << "'" << endl; + cerr << "Error in VkOptionsPage::insertOptionWidget( " << optid << " ): " + << "VkOPT::WDG_SPINBOX: bad int conversion from: '" + << val.toLatin1().data() << "'" << endl; // soldier on... ival = 0; } Modified: branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -108,16 +108,20 @@ vkopt->shortFlag = opt->shortFlag.toLatin1(); vkopt->optGrp = (char*)malloc( opt->configGrp.length()+1 ); - strncpy( vkopt->optGrp, opt->configGrp.toLatin1().data(), opt->configGrp.length()+1 ); + strncpy( vkopt->optGrp, opt->configGrp.toLatin1().data(), + opt->configGrp.length()+1 ); vkopt->longFlag = (char*)malloc( opt->longFlag.length()+1 ); - strncpy( vkopt->longFlag, opt->longFlag.toLatin1().data(), opt->longFlag.length()+1 ); + strncpy( vkopt->longFlag, opt->longFlag.toLatin1().data(), + opt->longFlag.length()+1 ); vkopt->helptxt = (char*)malloc( opt->longHelp.length()+1 ); - strncpy( vkopt->helptxt, opt->longHelp.toLatin1().data(), opt->longHelp.length()+1 ); + strncpy( vkopt->helptxt, opt->longHelp.toLatin1().data(), + opt->longHelp.length()+1 ); vkopt->helpdesc = (char*)malloc( opt->flagDescr.length()+1 ); - strncpy( vkopt->helpdesc, opt->flagDescr.toLatin1().data(), opt->flagDescr.length()+1 ); + strncpy( vkopt->helpdesc, opt->flagDescr.toLatin1().data(), + opt->flagDescr.length()+1 ); } // null entry terminator vkOpts[idx] = nullOpt(); Modified: branches/valkyrie_qt4port/options/vk_popt.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_popt.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/options/vk_popt.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -101,7 +101,8 @@ if ( opt->arg != NULL ) { // is-a table // recurse on included sub-tables. - const vkPoptOption* opt2 = vkFindOption( opt->arg, longFlag, shortFlag, singleDash ); + const vkPoptOption* opt2 = vkFindOption( opt->arg, longFlag, + shortFlag, singleDash ); if ( opt2 == NULL ) { // no match in sub-table continue; Modified: branches/valkyrie_qt4port/toolview/helgrindview.cpp =================================================================== --- branches/valkyrie_qt4port/toolview/helgrindview.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/toolview/helgrindview.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -116,7 +116,7 @@ QIcon icon_openlog; icon_openlog.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/folder_green.png") ), QIcon::Normal, QIcon::Off ); actFile_OpenLog->setIcon( icon_openlog ); - actFile_OpenLog->setText( QApplication::translate("HelgrindViewClass", "Open Log", 0, QApplication::UnicodeUTF8) ); + actFile_OpenLog->setText( tr( "Open Log" ) ); actFile_OpenLog->setToolTip( tr("Open Helgrind XML log") ); } @@ -136,6 +136,6 @@ // ------------------------------------------------------------ // Helgrind menu toolMenu->setObjectName( QString::fromUtf8("helgrindMenu")); - toolMenu->setTitle( QApplication::translate("HelgrindViewClass", "Helgrind", 0, QApplication::UnicodeUTF8) ); + toolMenu->setTitle( tr( "Helgrind" ) ); toolMenu->addAction( actFile_OpenLog ); } Modified: branches/valkyrie_qt4port/toolview/memcheckview.cpp =================================================================== --- branches/valkyrie_qt4port/toolview/memcheckview.cpp 2010-03-03 22:46:49 UTC (rev 480) +++ branches/valkyrie_qt4port/toolview/memcheckview.cpp 2010-03-04 22:02:19 UTC (rev 481) @@ -188,16 +188,16 @@ // ------------------------------------------------------------ // Text - actMC_OpenClose_item->setText( QApplication::translate("MemcheckViewClass", "Open/Close", 0, QApplication::UnicodeUTF8) ); + actMC_OpenClose_item->setText( tr( "Open/Close" ) ); actMC_OpenClose_item->setToolTip( tr("Open/Close currently selected item") ); - actMC_OpenClose_all->setText ( QApplication::translate("MemcheckViewClass", "Open/Close all", 0, QApplication::UnicodeUTF8) ); + actMC_OpenClose_all->setText ( tr( "Open/Close all" ) ); actMC_OpenClose_all->setToolTip( tr("Open/Close all items") ); - actMC_ShowSrcPaths->setText ( QApplication::translate("MemcheckViewClass", "Display simple", 0, QApplication::UnicodeUTF8) ); + actMC_ShowSrcPaths->setText ( tr( "Display simple" ) ); actMC_ShowSrcPaths->setToolTip( tr("Display complex / simplified view") ); - actFile_OpenLog->setText(QApplication::translate("MemcheckViewClass", "Open Log", 0, QApplication::UnicodeUTF8) ); + actFile_OpenLog->setText(tr( "Open Log" ) ); actFile_OpenLog->setToolTip( tr("Open Memcheck XML log") ); - actFile_SaveLog->setText(QApplication::translate("MemcheckViewClass", "Save Log", 0, QApplication::UnicodeUTF8) ); + actFile_SaveLog->setText(tr( "Save Log" ) ); actFile_SaveLog->setToolTip( tr("Save Valgrind output to an XML log") ); } @@ -221,7 +221,7 @@ // ------------------------------------------------------------ // Memcheck menu (created in base class) toolMenu->setObjectName( QString::fromUtf8("memcheckMenu") ); - toolMenu->setTitle( QApplication::translate("MemcheckViewClass", "Memcheck", 0, QApplication::UnicodeUTF8) ); + toolMenu->setTitle( tr( "Memcheck" ) ); toolMenu->addAction( actMC_OpenClose_item ); toolMenu->addAction( actMC_OpenClose_all ); |
From: <sv...@va...> - 2010-03-03 22:47:12
|
Author: cerion Date: 2010-03-03 22:46:49 +0000 (Wed, 03 Mar 2010) New Revision: 480 Log: added an ascii-art description of the flow of process control & xml log parsing Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-03-03 22:14:50 UTC (rev 479) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-03-03 22:46:49 UTC (rev 480) @@ -18,6 +18,29 @@ ** ****************************************************************************/ +/* +The Valgrind process control & log parsing goes like this: + +=== Happy flow === +start() -> vgproc ->(writes)-> XML_LOG + -> logpoller ->(triggers)-> readVgLog() <-(reads )<- XML_LOG + +vgproc ->(finished/died)-> processDone() ->(if parser done)-> DONE +readVgLog() ->(finished parsing log) ->(if vgproc done)-> DONE + +=== Exceptions === +processDone() ->(parser alive && vgproc error)-> stopProcess() +readVgLog() ->(parser error && vgproc alive)-> stopProcess() +User Input ->(Stop command)-> stop() -> stopProcess() + +stopProcess() + -> cleanup logpoller + -> cleanup vgproc + ->(QProc::terminate)->SIGTERM-> -> processDone() -> DONE + ->(timeout)-> killProc() ->(QtProc::kill)-> processDone() -> DONE +*/ + + //#include "config.h" #include "help/help_urls.h" #include "objects/memcheck_object.h" |
From: <sv...@va...> - 2010-03-03 22:34:38
|
Author: cerion Date: 2010-03-03 22:14:50 +0000 (Wed, 03 Mar 2010) New Revision: 479 Log: Major rework of process control - start/stop valgrind process, reading the generated xml log asyncronously. - process control and log parsing now independent: except for error situations, when each may stop the other by callng the main 'stopProcess() function. - should actually work now, and not just the happy flow. Just need time to write all the unit tests! Fixed a couple of small memory leaks Still TODO's from memcheck_object.cpp: //TODO: mock a valgrind process, and setup some unit tests (and a test framework!) //TODO: have popups called from toolview, not object... maybe. //TODO: make sure not too many popup vkError()'s for any particular state flow. //TODO: ditto for statusMsg()'s //TODO: make sure statusMsg()s always correct with current state. Modified: branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/utils/vglogreader.cpp branches/valkyrie_qt4port/utils/vglogreader.h branches/valkyrie_qt4port/utils/vk_logpoller.cpp branches/valkyrie_qt4port/utils/vk_logpoller.h branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -872,7 +872,10 @@ #endif if ( !valkyrie->runTool( toolViewStack->currentToolId(), procId ) ) { - vkError( this, "Run Tool", "Failed to complete execution." ); + //TODO: make sure all fail cases have given a message to the user already + + VK_DEBUG( "Failed to complete execution for toolId (%d), procId (%d)", + toolViewStack->currentToolId(), procId ); } } @@ -894,7 +897,7 @@ if ( vkConfig->value( "valkyrie/binary").toString().isEmpty() ) { vkInfo( this, "Run Valgrind: No program specified", - "Please specify (via Edit::Options::Binary) the path to the program<br>" + "Please specify (via Options->Valkyrie->Binary) the path to the program<br>" "you wish to run, along with any arguments required"); openOptions(); @@ -912,6 +915,7 @@ void MainWindow::stopTool() { cerr << "TODO: MainWindow::stopTool()" << endl; + valkyrie->stopTool( toolViewStack->currentToolId() ); } Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -33,11 +33,24 @@ #include <QDir> #include <QTimer> +// Waiting for Vg to start: +#define WAIT_VG_START_MAX 1000 // msecs before giving up +#define WAIT_VG_START_SLEEP 100 // msecs to sleep each loop +#define WAIT_VG_START_LOOPS (WAIT_VG_START_MAX / WAIT_VG_START_SLEEP) -#define TIMEOUT_STOPPROC 2000 // msec until stop process -#define TIMEOUT_KILLPROC 2000 // msec until kill process (after tried to stop) +// Waiting for Vg to die: +#define TIMEOUT_KILL_PROC 2000 // msec: 'please stop?' to 'die!' +#define TIMEOUT_WAIT_UNTIL_DONE 5000 // msec: 'half done' to 'advise stop' +//TODO: mock a valgrind process, and setup some unit tests (and a test framework!) +//TODO: have popups called from toolview, not object... maybe. +//TODO: make sure not too many popup vkError()'s for any particular state flow. +//TODO: ditto for statusMsg()'s +//TODO: make sure statusMsg()s always correct with current state. + + + /*! class Memcheck */ @@ -49,6 +62,7 @@ vgproc = 0; vgreader = 0; logpoller = new VkLogPoller( this, "memcheck logpoller" ); + connect( logpoller, SIGNAL(logUpdated()), this, SLOT(readVgLog()) ); @@ -58,7 +72,10 @@ Memcheck::~Memcheck() { + setProcessId( VGTOOL::PROC_NONE ); + if (vgproc) { +// TODO: does this work? vgproc->disconnect(); // so no signal calling processDone() if ( vgproc->state() != QProcess::NotRunning ) { vgproc->terminate(); @@ -67,12 +84,13 @@ delete vgproc; vgproc = 0; } + if (vgreader) { delete vgreader; vgreader = 0; } - // logpoller deleted by it's parent: 'this' + // logpoller auto deleted by Qt when 'this' dies // unsaved log... delete our temp file if (!fileSaved && !saveFname.isEmpty()) @@ -192,7 +210,7 @@ /* check argval for this option, updating if necessary. called by parseCmdArgs() and gui option pages -------------------- */ -int Memcheck::checkOptArg( int optid, QString& argval ) +int Memcheck::checkOptArg( int optid, QString& )//argval ) { vk_assert( optid >= 0 && optid < MEMCHECK::NUM_OPTS ); @@ -245,16 +263,14 @@ connect( this, SIGNAL(running(bool)), toolView, SLOT(setState(bool)) ); - setProcessId( VGTOOL::PROC_NONE ); - return toolView; } /* outputs a message to the status bar. */ -void Memcheck::statusMsg( QString hdr, QString msg ) +void Memcheck::statusMsg( QString msg ) { - emit message( hdr + ": " + msg ); + emit message( "Memcheck: " + msg ); } @@ -273,7 +289,7 @@ "<p>Do you want to abort it ?</p>" ); /* Note: process may have finished while waiting for user */ if ( ok == MsgBox::vkYes ) { - stop(); /* abort */ + stopProcess(); /* abort */ vk_assert( !isRunning() ); } else if ( ok == MsgBox::vkNo ) { return false; /* continue */ @@ -323,9 +339,13 @@ } +/*! + Start a memcheck process + - Slot, called from the Memcheck ToolView +*/ bool Memcheck::start( int procId, QStringList vgflags ) { -cerr << "Memcheck::start(): " << procId << endl; +//cerr << "Memcheck::start(): " << procId << endl; vk_assert( procId > VGTOOL::PROC_NONE ); vk_assert( procId < VGTOOL::PROC_MAX ); @@ -339,8 +359,6 @@ case MEMCHECK::PROC_PARSE_LOG: ok = parseLogFile(); break; -//TODO: maybe someday. -// case merge: ok = mergeLogFiles(); break; default: vk_assert_never_reached(); } @@ -350,78 +368,33 @@ /*! - Stop a process. - Try to be nice, but in case doesn't work, setup timer to guarantee it dies. -//TODO: Perhaps the view want's to hang around and wait until process is dead. but that's up to the view. + Stop a memcheck process + - Slot, called from the Memcheck ToolView + + Note: could take a while (TIMEOUT_KILL_PROC) before we return + - but we do call qApp->processEvents() */ void Memcheck::stop() { - if ( !isRunning() ) - return; +//cerr << "Memcheck::stop() " << endl; - // whatever else we do, stop trying to read from the log. - if ( logpoller ) - logpoller->stop(); - - switch ( getProcessId() ) { - case VGTOOL::PROC_VALGRIND: { - if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) { - vkPrint("Memcheck::stop(): process starting/running: terminate."); - - vgproc->terminate(); // if & when succeeds: signal -> processDone() - - // in case doesn't want to stop, start timer to really kill it off. - QTimer::singleShot( TIMEOUT_KILLPROC, this, SLOT( killProcess() ) ); - } - else { - vkPrint("Memcheck::stop(): process was already stopped."); - } - } break; - - case MEMCHECK::PROC_PARSE_LOG: { // parse log - // TODO - VK_DEBUG("TODO: Memcheck::stop(parse log)" ); - } break; - -#if 0 - case TODO: { // merge logs - if (vgproc && vgproc->isRunning() ) - vgproc->stop(); // signal -> processDone() - } break; -#endif - default: - vk_assert_never_reached(); - } - - return; + // could take a while (TIMEOUT_KILL_PROC) before really done, + stopProcess(); + vk_assert( vgproc == 0 ); + vk_assert( !this->isRunning() ); } /*! - Kills a process immediately - - only called as a result of kill timer timeout -*/ -void Memcheck::killProcess() -{ - if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) { -vkPrint("Memcheck::killProcess(): kill the process"); - vgproc->kill(); // process will die, then signal -> processDone() - } - else { -vkPrint("Memcheck::killProcess(): process already stopped."); - } -} - - -/*! If --vg-opt=<arg> was specified on the cmd-line, called by valkyrie->runTool(); if set via the run-button in the gui, then MainWindow::run() calls valkyrie->runTool(). - Auto-generated logs always saved in hard-coded (configured) log dir + Auto-generated logs always saved in a (configured) temp log dir */ bool Memcheck::runValgrind( QStringList vgflags ) { + VK_DEBUG("Start Vg run"); saveFname = vk_mkstemp( QString( VkConfig::vkTmpDir() ) + "mc_log", "xml" ); vk_assert( !saveFname.isEmpty() ); @@ -430,14 +403,19 @@ setProcessId( VGTOOL::PROC_VALGRIND ); fileSaved = false; - statusMsg( "Memcheck", "Running ... " ); + statusMsg( "Starting Valgrind ..." ); bool ok = startProcess( vgflags ); if (!ok) { - statusMsg( "Memcheck", "Failed" ); + VK_DEBUG("Error: Failed to start Valgrind"); + vk_assert( this->getProcessId() == VGTOOL::PROC_NONE ); + statusMsg( "Error: Failed to start Valgrind" ); fileSaved = true; - setProcessId( VGTOOL::PROC_NONE ); + } else { + VK_DEBUG("Started Valgrind"); + vk_assert( this->getProcessId() == VGTOOL::PROC_VALGRIND ); + statusMsg( "Started Valgrind ..." ); } return ok; @@ -457,7 +435,7 @@ //TODO: pass this via flags from the toolview, or something. VkOption* opt = options.getOption( VALKYRIE::VIEW_LOG ); QString log_file = vkConfig->value( opt->configKey() ).toString(); - statusMsg( "Parsing", log_file ); + statusMsg( "Parsing '" + log_file + "'" ); //TODO: file checks #if 0 @@ -483,101 +461,52 @@ // Parse the log VgLogReader vgLogFileReader( getToolView()->vgLogPtr() ); bool success = vgLogFileReader.parse( log_file ); - if (!success) { + + if (success) { + statusMsg( "Loaded Logfile '" + log_file + "'" ); + saveFname = log_file; + } else { + statusMsg( "Error Parsing Logfile '" + log_file + "'" ); + VgLogHandler* hnd = vgLogFileReader.handler(); - statusMsg( "Parsing", "Error" ); vkError( getToolView(), "XML Parse Error", "<p>%s</p>", qPrintable( escapeEntities(hnd->fatalMsg()) ) ); } - if (success) { - saveFname = log_file; - statusMsg( "Loaded", log_file ); - } else { - statusMsg( "Parse failed", log_file ); - } setProcessId( VGTOOL::PROC_NONE ); - return success; } -/* if --merge=<file_list> was specified on the cmd-line, called by - valkyrie->runTool(); if set via the open-file-dialog in the gui, - called by MemcheckView::openMergeFile(). either way, the value in - [valkyrie:merge] is what we need to know - - Auto-generated logs always saved in hard-coded (configured) log dir +/*! + Run a VKProcess, as given by 'flags'. + - Reads ouput from file, loading this to the listview. */ -bool Memcheck::mergeLogFiles() +bool Memcheck::startProcess( QStringList flags ) { -//TODO. maybe. -#if 0 - QString fname_logList = vkConfig->rdEntry( "merge", "valkyrie" ); - statusMsg( "Merging logs in file-list", fname_logList ); - - saveFname = vk_mkstemp( QString( VkConfig::vkTmpDir() ) - + "mc_merged", "xml" ); - vk_assert( !saveFname.isEmpty() ); + VK_DEBUG("Start VgProcess"); + vk_assert( getToolView() != 0 ); - QStringList flags; - flags << vkConfig->rdEntry( "merge-exec","valkyrie"); - flags << "-f"; - flags << fname_logList; - flags << "-o"; - flags << saveFname; + QString program = flags.at( 0 ); + QStringList args = flags.mid(1); - setProcessId( VkRunState::TOOL2 ); - fileSaved = false; - statusMsg( "Merge Logs", "Running ... " ); - - bool ok = startProcess( flags ); - - if (!ok) { - statusMsg( "Merge Logs", "Failed" ); - fileSaved = true; - setProcessId( VkRunState::STOPPED ); - } - return ok; -#endif - return true; -} - - -/* Run a VKProcess, as given by 'flags'. - Reads ouput from file, loading this to the listview. -*/ -bool Memcheck::startProcess( QStringList flags ) -{ - QString program = flags.at( 0 ); - QStringList args = flags.mid(1); - - // vkPrint("Memcheck::startProcess()"); +#ifdef DEBUG_ON for ( int i=0; i<flags.count(); i++ ) vkPrint("flag[%d] --> %s", i, qPrintable( flags[i] ) ); - vk_assert( getToolView() != 0 ); +#endif // new vgreader - view may have been recreated, so need up-to-date ptr vk_assert( vgreader == 0 ); vgreader = new VgLogReader( getToolView()->vgLogPtr() ); - // start the log parse - nothing written yet tho. - if (!vgreader->parse( saveFname, true )) { - QString errMsg = vgreader->handler()->fatalMsg(); - VK_DEBUG("vgreader failed to start parsing empty log\n"); - vkError( getToolView(), "Process Startup Error", - "<p>Failed to start XML parser:<br>%s</p>", - qPrintable( errMsg ) ); - goto failed_startup; - } - - // start a new process, listening on exit signal + // start a new process, listening on exit signal to call processDone(). + // - once Vg is done, we can read the remainder of the log in one last go. vk_assert( vgproc == 0 ); vgproc = new QProcess( this->toolView ); connect( vgproc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processDone(int, QProcess::ExitStatus)) ); - // forward vg process stdout/err to our stdout/err respectively + // forward vgproc stdout/err to our stdout/err respectively vgproc->setProcessChannelMode( QProcess::ForwardedChannels ); // set working directory @@ -585,193 +514,375 @@ // start running process vgproc->start( program, args ); + VK_DEBUG("Started VgProcess"); -//TODO: call vgproc->waitForStarted(), or sthgn with a timeout, and then error to user... -#if 0 - VK_DEBUG("process failed to start"); + // Make sure Vg started ok before moving further. + // Don't bother using QProcess::start(): + // 1) Vg may have finished already(!) + // 2) QXmlSimpleReader won't start on an empty log: seems to need at least "<?x" + // So just wait for a while until we find the valgrind output log... + int i=0; + while ( i < WAIT_VG_START_LOOPS) { + if ( QFile::exists( saveFname ) ) + break; + usleep( WAIT_VG_START_SLEEP * 1000 ); + i++; + } + + // If no logfile found, we have a problem: + if ( i >= WAIT_VG_START_LOOPS ) { + VK_DEBUG("Valgrind failed to start properly (process not running)"); vkError( getToolView(), "Process Startup Error", - "<p>Failed to start process:<br>%s<br><br>" - "Please verify the path to Valgrind in Options::Valkyrie.</p>", - qPrintable( flags.join(" ") ) ); + "<p>Failed to start valgrind properly.<br>" + "Please verify Valgrind and Binary paths (via Options->Valkyrie).<br>" + "Try running Valgrind (with _exactly_ the same arguments) via the command-line" + "<br><br>%s", + qPrintable( flags.join("<br> ") ) ); goto failed_startup; } -#endif - // poll log for latest data - logpoller->start(); + // poll log regularly to trigger parsing of the latest data via readVgLog() + logpoller->start( 250 ); // msec -vkPrint(" - END MC::startProcess()" ); + statusMsg( "Error Parsing Logfile '" + saveFname + "'" ); + + // doesn't matter if processDone() or readVgLog() gets called first. + VK_DEBUG("Started logpoller"); return true; - failed_startup: +failed_startup: VK_DEBUG("failed_startup: '%s'", qPrintable( flags.join(" ") )); - if (logpoller != 0) { + stopProcess(); + return false; +} + + +/*! + Stop a process. + Try to be nice, but if nice don't get the job done, hire a + one off timer to singleShoot the bugger. + + Note: We may wait around in this function for Vg to die. + - but we do call qApp->processEvents() +*/ +void Memcheck::stopProcess() +{ + // dont try to stop a stopped process. + if ( !isRunning() ) + return; + + VK_DEBUG("Stopping VgProcess"); + statusMsg( "Stopping Valgrind process ..." ); + + // first things first: stop trying to read from the log. + if ( logpoller != 0 && logpoller->isActive() ) { logpoller->stop(); } - if (vgreader != 0) { + if ( vgreader != 0 ) { delete vgreader; vgreader = 0; } - if (vgproc != 0) { - delete vgproc; - vgproc = 0; - } - return false; + + switch ( getProcessId() ) { + case VGTOOL::PROC_VALGRIND: { + // if vgproc is alive, shut it down + if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) { + VK_DEBUG("VgProcess starting/running: Terminate."); + vkPrint("Memcheck::stopProcess(): process starting/running: terminate."); + + vgproc->terminate(); // if & when succeeds: signal -> processDone() + + // in case doesn't want to stop, start timer to really kill it off. + QTimer::singleShot( TIMEOUT_KILL_PROC, this, SLOT( killProcess() ) ); + + // Now it's a race between killProcess() and processDone() + // either way, hang around until vgproc is cleaned up. + + VK_DEBUG("Waiting for VgProcess to die."); + //TODO: some bad joke re waiting for the inheritance. + + int sleepDuration = 100; // msec + int nCycles = (TIMEOUT_KILL_PROC / sleepDuration ) + 1;// +1: ensure Vg gone + for ( int i=0; i<nCycles; i++ ) { + qApp->processEvents( QEventLoop::AllEvents, 10/*max msecs*/ ); + usleep( 1000 * sleepDuration ); + if ( vgproc == 0 ) + break; + } + // all should now be well. + vk_assert( vgproc == 0 ); + vk_assert( !this->isRunning() ); + } + else { + VK_DEBUG("VgProcess already stopped (or never started)."); + if ( vgproc ) { + delete vgproc; + vgproc = 0; + } + setProcessId( VGTOOL::PROC_NONE ); + } + } break; + + case MEMCHECK::PROC_PARSE_LOG: { // parse log + // TODO + VK_DEBUG("TODO: Memcheck::stop(parse log)" ); + setProcessId( VGTOOL::PROC_NONE ); + } break; + + default: + vk_assert_never_reached(); + } } /*! - Process exited: - - self / external signal / user via 'stop()' / - - terminated from readVgLog because of an xml parse error - Stops logfile polling, checks xml parsing for errors, - checks exitstatus, cleans up. + Kills a process immediately + - only called as a result of kill timer timeout from stopProcess() + + If process already stopped, cleans it up. Else kills it, which + signals processDone(), which cleans it up. */ -void Memcheck::processDone( int exitCode, QProcess::ExitStatus exitStatus ) +void Memcheck::killProcess() { - cerr << "Memcheck::processDone( " << exitCode << ", " << exitStatus << " )" << endl; + if ( vgproc == 0 ) { + // vgproc died and called processDone() already + VK_DEBUG("VgProcess already cleaned up."); + return; + } - // vkPrint("Memcheck::processDone()"); - vk_assert( vgproc != 0 ); - vk_assert( vgreader != 0 ); - vk_assert( logpoller != 0 ); - bool runError = false; + if ( vgproc->state() == QProcess::NotRunning ) { + VK_DEBUG("VgProcess already stopped."); - // stop polling logfile ------------------------------------------ - logpoller->stop(); + // cleanup already. + delete vgproc; + vgproc = 0; + setProcessId( VGTOOL::PROC_NONE ); - // deal with log reader ------------------------------------------ - // if not finished && no error, try reading log data one last time - if (!vgreader->handler()->finished() && - vgreader->handler()->fatalMsg().isEmpty()) - readVgLog(); + } else { + VK_DEBUG("VgProcess still running: kill it!"); + vgproc->kill(); + // process will die, signalling processDone(), + // which will cleanup vgproc. + } +} - // did log parsing go ok? - QString fatalMsg = vgreader->handler()->fatalMsg(); - if ( !fatalMsg.isEmpty() ) { - // fatal log error... - runError = true; - // vkPrint(" - Memcheck::processDone(): fatal error"); - if (getProcessId() == VGTOOL::PROC_VALGRIND) { - statusMsg( "Memcheck", "Error parsing output log" ); - vkError( getToolView(), "XML Parse Error", - "<p>Error parsing Valgrind XML output:<br>%s</p>", - qPrintable( str2html( fatalMsg ) ) ); - } else { - vk_assert_never_reached(); -//TODO. maybe -#if 0 - statusMsg( "Merge Logs", "Error parsing output log" ); - vkError( getToolView(), "Parse Error", - "<p>Error parsing output log</p>" ); -#endif - } - } else if ( !vgreader->handler()->finished() ) { - /* no fatal error, but STILL not reached end of log, either: - - valgrind xml output not completed properly - - merge failed */ - runError = true; - // vkPrint(" - Memcheck::processDone(): parsing STILL not finished"); +/*! + Process exited, from one of: + - process finished/died/killed external to valkyrie + - startup failed, and called stopProcess() + - user got bored and called stopProcess() - if (getProcessId() == VGTOOL::PROC_VALGRIND) { - statusMsg( "Memcheck", "Error - incomplete output log" ); - vkError( getToolView(), "XML Parse Error", - "<p>Valgrind XML output is incomplete</p>" ); - } else { - vk_assert_never_reached(); -//TODO. maybe. -#if 0 - statusMsg( "Merge Logs", "Error - incomplete output log" ); - vkError( getToolView(), "Parse Error", - "<p>Failed to parse merge result</p>" ); -#endif - } - } + - stopProcess() called terminate(), which called this directly + - stopProcess() started a timer to call killProcess(), to call kill(), + which called this directly. + Since both processDone() and killProcess() must clean up vgproc, + be careful to check who's cleaned up already. - // check process exit status - valgrind might have bombed - if ( exitStatus == QProcess::NormalExit && exitCode == 0 ) { - // vkPrint(" - Memcheck::processDone(): process exited ok"); - } else { - // vkPrint(" - Memcheck::processDone(): process failed (%d)", exitStatus); - if (getProcessId() == VGTOOL::PROC_VALGRIND) { - vkError( getToolView(), "Run Error", - "<p>Process %s, with return value %d.<br> \ - This is likely to simply be the client program \ - return value. If, however, you suspect Valgrind \ - itself may have crashed, please click 'OK', then \ - 'Save Log' and examine for details.</p>", - (exitStatus == QProcess::NormalExit) ? "exited normally" : "crashed", - exitCode ); - } else { - vk_assert_never_reached(); -//TODO: maybe. -#if 0 - vkError( getToolView(), "Parse Error", - "<p>Merge process exited with return value %d.<br> \ - Please check the terminal for error messages.</p>", - exitStatus); -#endif - } + Don't worry about the parser state: just deal with the Vg process. + - unless Vg quit with an error & parser is still runnning, + in which case, stop the parser too, via stopProcess() +*/ +void Memcheck::processDone( int exitCode, QProcess::ExitStatus exitStatus ) +{ + cerr << "Memcheck::processDone( " << exitCode << ", " << exitStatus << " )" << endl; + vk_assert( getToolView() != 0 ); + if ( vgproc == 0 ) { + // Tiny chance that the timeout called killProcess(), cleaning up vgproc, + // but vgproc already sent an (buffered) call to processDone() directly? + // Don't know if that's even possible with Qt signal/slots, but just in case. + VK_DEBUG("VgProcess already cleaned up."); + return; } - // cleanup ------------------------------------------------------- - delete vgreader; - vgreader = 0; + // cleanup first ------------------------------------------------- delete vgproc; vgproc = 0; + // --------------------------------------------------------------- + // check process exit status - valgrind might have bombed + bool ok = true; + if ( exitStatus == QProcess::NormalExit && exitCode == 0 ) { + VK_DEBUG("Clean VgProcess stop: process exited ok"); + statusMsg( "Finished Valgrind process!" ); - // we're done. --------------------------------------------------- - if (!runError) { // (else we've already set an status error message) - if (getProcessId() == VGTOOL::PROC_VALGRIND) { - statusMsg( "Memcheck", "Finished" ); - } else { - vk_assert_never_reached(); -//TODO: maybe -// statusMsg( "Merge Logs", "Finished" ); + } else { + ok = false; + VK_DEBUG("Error running VgProcess: process failed (%d)", exitStatus); + statusMsg( "Error running Valgrind process" ); + + // Note: when calling a QDialog, qApp still processes events, + // so killProcess() may get called here. + vkError( getToolView(), "Run Error", + "<p>Valgrind process %s, giving return value %d.<br><br>" + "Most likely, you either pressed 'Stop', or the (client)<br>" + "process running under Valgrind died.<br><br>" + "If, however, you suspect Valgrind itself may have crashed,<br>" + "please click 'OK', 'Save Log' and examine for details.</p>", + (exitStatus == QProcess::NormalExit) ? "exited normally" : + "crashed or was killed", + exitCode ); + } + + // if log reader not active anymore, we're done + if ( vgreader == 0 ) { + VK_DEBUG("All done."); + statusMsg( "Finished running Valgrind successfully!" ); + setProcessId( VGTOOL::PROC_NONE ); + } else { + // For a number of reasons, vgreader may continue on a while after + // vgproc has gone (e.g. Vg dies, leaving incomplete xml) + if ( !ok ) { + // process error: stop reader now. + VK_DEBUG("VgProcess finished with error: stop VgReader"); + stopProcess(); } + else { + // Vg finished happily. + // In principle, want pargser also to stop when it's happy, + // but "just in case" Vg doesn't output complete XML (surely not!) + // or the parser is taking too long with too much data, + // wait a while, and, if same state, inform the user what's going on. + + VK_DEBUG("VgProcess finished happy: take another look at " + "VgReader after timeout (%d)", TIMEOUT_WAIT_UNTIL_DONE ); + QTimer::singleShot( TIMEOUT_WAIT_UNTIL_DONE, + this, SLOT( checkParserFinished() ) ); + } } - - setProcessId( VGTOOL::PROC_NONE ); - // vkPrint("Memcheck::processDone(): DONE.\n"); } -/* Read memcheck / logmerge xml output - Called by - - logpoller signals - - processDone() if one last data read needed. + +/*! + Read memcheck / logmerge xml output + - Called by logpoller signals only. + + Don't worry about Valgrind process state: just read the log. + - unless we have a parser error & valgrind is still runnning, + in which case, stop the process too, via stopProcess(). */ void Memcheck::readVgLog() { -vkPrint("Memcheck::readVgLog()"); vk_assert( getToolView() != 0 ); vk_assert( vgreader != 0 ); - vk_assert( vgproc != 0 ); + vk_assert( logpoller != 0 ); + vk_assert( !saveFname.isEmpty() ); - qApp->processEvents(); + // Note: not calling qApp->processEvents(), since parser only + // reads in a limited amount in one go anyway. - // starting or dead -> get out of here. - if ( vgproc->state() != QProcess::Running ) - return; + // try parsing vg xml log ---------------------------------------- + bool ok = true; + QString errHeader; + statusMsg( "Parsing Valgrind XML log..." ); - // Try reading some more data. By failure, stop process. - if ( vgreader && !vgreader->parseContinue()) { -vkPrint("Memcheck::readVgLog(): Parsing Failed. Stopping process after timeout"); + if ( !vgreader->handler()->started() ) { + // first time around... + VK_DEBUG("Start parsing Valgrind XML log"); - // stop trying to read from the log. + ok = vgreader->parse( saveFname, true/*incremental*/ ); + if ( !ok ) { + VK_DEBUG("Error: parse() failed" ); + errHeader = "XML Parse-Startup Error"; + } + } + else { + // we've started, so we'll continue... + VK_DEBUG("Continue parsing Valgrind XML log"); + + ok = vgreader->parseContinue(); + if ( !ok ) { + VK_DEBUG("Error: parseContinue() failed" ); + errHeader = "XML Parse-Continue Error"; + } + } + if ( !vgreader->handler()->fatalMsg().isEmpty() ) { + ok = false; + } + if ( vgreader->handler()->finished() ) { + VK_DEBUG("Reached end of XML log" ); + } + + + // deal with failures -------------------------------------------- + if ( !ok ) { + // parsing failed :-( + VK_DEBUG("Error parsing Valgrind log"); + statusMsg( "Error parsing Valgrind log" ); + + // Failed: print error & stop everything. + QString errMsg = vgreader->handler()->fatalMsg(); + vkError( getToolView(), errHeader, + "<p>Failed to parse Valgrind XML output:<br>%s</p>", + qPrintable( str2html(errMsg) ) ); + } + + // cleanup ------------------------------------------------------- + // if parsing failed, or this was a last call, then cleanup + if ( !ok || vgreader->handler()->finished() ) { + VK_DEBUG("Cleaning up logpoller & reader"); + vk_assert( vgreader != 0 ); + vk_assert( logpoller != 0 ); + vk_assert( logpoller->isActive() ); + + // cleanup. logpoller->stop(); + delete vgreader; + vgreader = 0; -//TODO: necessary? - // give process a little time to finishe before we stop it. - QTimer::singleShot( TIMEOUT_STOPPROC, this, SLOT( stop() ) ); + // if vgproc not active anymore, we're done! + if ( vgproc == 0 ) { + VK_DEBUG("All done."); + statusMsg( "Finished running Valgrind successfully!" ); + setProcessId( VGTOOL::PROC_NONE ); + } + else { + // vgproc is still alive... + if ( !ok ) { + // parse error: stop vgproc now + VK_DEBUG("VgReader finished with error: stop VgProcess"); + stopProcess(); + } + // else: parser finished happily. Allow Vg to stop when it's also happy. + // TODO: Any reason why Vg might need stopping from this state? + // - if any good reason, then dup checkParserFinished() functionality. + } } } /*! + If for some reason Valgrind has finished and the parser still hasn't, + inform the user and remind of option to stopping by hand. + + Notes: + * vgreader->parse() and parseContinue() call QXmlInputSource::fetchData(), + which reads in only a limited amount (512B for Qt3.3.6) from the logfile. + Valgrind, after finishing up, can write a whole bunch of data in one go + to the logfile, which takes some iterations of parserContinue() to read in. + * If Valgrind doesn't write a complete XMLfile (!), this would leave the + parser with incomplete XML, trying to parse it indefinitely. +*/ +void Memcheck::checkParserFinished() +{ + if ( vgproc == 0 && vgreader != 0 ) { + VK_DEBUG("Timeout waiting for parser to finish: Parser _still_ alive."); + vkInfo( getToolView(), "Valgrind finished, but log-reader alive", + "<p>The Valgrind process finished some time ago,<br>" + "but the log reader is still active.<br><br>" + "This could indicate that Valgrind didn't finish<br>" + "writing the XML log properly, or just that" + "there is a huge amount of XML to read.<br><br>" + "Press Stop if you want to force the process to stop.</p>" ); + } else { + VK_DEBUG("Timeout waiting for parser to finish: Parser finished."); + } +} + + +/*! Brings up a fileSaveDialog until successfully saved, or user pressed Cancel. If fname.isEmpty, ask user for a name first. @@ -815,7 +926,7 @@ /* Save to file - we already have everything in saveFname logfile, so just copy that */ -bool Memcheck::saveParsedOutput( QString& fname ) +bool Memcheck::saveParsedOutput( QString& )//fname ) { #if 0 //vkPrint("saveParsedOutput(%s)", fname.latin1() ); Modified: branches/valkyrie_qt4port/objects/memcheck_object.h =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.h 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-03-03 22:14:50 UTC (rev 479) @@ -89,7 +89,7 @@ // overriding to avoid casting everywhere MemcheckView* getToolView() { return (MemcheckView*)toolView; } - void statusMsg( QString hdr, QString msg ); + void statusMsg( QString msg ); bool queryFileSave(); bool saveParsedOutput( QString& fname ); @@ -101,7 +101,9 @@ private slots: void processDone( int exitCode, QProcess::ExitStatus exitStatus ); void readVgLog(); + void stopProcess(); void killProcess(); + void checkParserFinished(); private: QString saveFname; Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -56,8 +56,10 @@ Valgrind::~Valgrind() { - // m_toolObjList.setAutoDelete( true ); - // m_toolObjList.clear(); + // clean up tool list + while (!toolObjList.isEmpty()) { + delete toolObjList.takeFirst(); + } } Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -738,8 +738,7 @@ vk_assert( tool != 0 ); tool->stop(); -//TODO -// vk_assert( !tool->isRunning() ); + vk_assert( !tool->isRunning() ); } Modified: branches/valkyrie_qt4port/utils/vglogreader.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vglogreader.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/utils/vglogreader.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -78,6 +78,7 @@ vglog = alog; node = doc; m_finished = false; + m_started = false; } VgLogHandler::~VgLogHandler() @@ -178,6 +179,7 @@ node = doc; m_fatalMsg = QString(); m_finished = false; + m_started = true; return true; } Modified: branches/valkyrie_qt4port/utils/vglogreader.h =================================================================== --- branches/valkyrie_qt4port/utils/vglogreader.h 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/utils/vglogreader.h 2010-03-03 22:14:50 UTC (rev 479) @@ -82,6 +82,8 @@ QString fatalMsg() { return m_fatalMsg; } /* may have reached end of log even with fatal error */ bool finished() { return m_finished; } + /* let us find out when parsing has been started */ + bool started() { return m_started; } private: QDomDocument doc; @@ -90,6 +92,7 @@ QString m_fatalMsg; bool m_finished; + bool m_started; }; Modified: branches/valkyrie_qt4port/utils/vk_logpoller.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vk_logpoller.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/utils/vk_logpoller.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -39,6 +39,7 @@ } +// start with interval msecs void VkLogPoller::start( int interval ) { timer->start( interval ); Modified: branches/valkyrie_qt4port/utils/vk_logpoller.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_logpoller.h 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/utils/vk_logpoller.h 2010-03-03 22:14:50 UTC (rev 479) @@ -43,7 +43,7 @@ VkLogPoller( QObject * parent, const char * name ); ~VkLogPoller(); - void start( int interval=100 ); + void start( int interval=100 ); // msec void stop(); bool isActive(); int interval(); Modified: branches/valkyrie_qt4port/utils/vk_utils.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vk_utils.cpp 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/utils/vk_utils.cpp 2010-03-03 22:14:50 UTC (rev 479) @@ -48,7 +48,8 @@ /* prints various info msgs to stdout --------------------------------- */ void vkPrint( const char* msg, ... ) { - const char* vkname = vkConfig ? vkConfig->vkName.toLatin1().constData() : ""; + QByteArray ba = vkConfig->vkName.toLatin1(); + const char* vkname = vkConfig ? ba.constData() : ""; va_list ap; va_start( ap, msg ); va_end( ap ); @@ -63,7 +64,8 @@ /* prints error msg -------------------------------------------------- */ void vkPrintErr( const char* msg, ... ) { - const char* vkname = vkConfig ? vkConfig->vkName.toLatin1().constData() : ""; + QByteArray ba = vkConfig->vkName.toLatin1(); + const char* vkname = vkConfig ? ba.constData() : ""; va_list ap; va_start( ap, msg ); va_end( ap ); @@ -79,7 +81,8 @@ void vkDebug( const char* msg, ... ) { #ifdef DEBUG - const char* vkname = vkConfig ? qPrintable( vkConfig->vkName ) : ""; + QByteArray ba = vkConfig->vkName.toLatin1(); + const char* vkname = vkConfig ? ba.constData() : ""; va_list ap; va_start( ap, msg ); va_end( ap ); @@ -107,7 +110,8 @@ unsigned int line, const char* fn ) { - const char* vkname = vkConfig ? vkConfig->vkName.toLatin1().constData() : ""; + QByteArray ba = vkConfig->vkName.toLatin1(); + const char* vkname = vkConfig ? ba.constData() : ""; vkPrintErr("Assertion 'never reached' failed,"); vkPrintErr(" at %s#%u:%s", file, line, fn ); @@ -136,12 +140,12 @@ if ( QFile::exists(unique) ) { /* fall back on mkstemp */ char* tmpname = vk_str_malloc( unique.length() + 10 ); - sprintf( tmpname, "%s.XXXXXX", unique.toLatin1().constData() ); + sprintf( tmpname, "%s.XXXXXX", qPrintable( unique ) ); int fd = mkstemp( tmpname ); if ( fd == -1 ) { /* something went wrong */ VK_DEBUG("failed to create unique filename from '%s'.", - filepath.toLatin1().constData() ); + qPrintable( filepath ) ); return QString::null; } unique = QString( tmpname ); Modified: branches/valkyrie_qt4port/utils/vk_utils.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_utils.h 2010-03-01 20:59:43 UTC (rev 478) +++ branches/valkyrie_qt4port/utils/vk_utils.h 2010-03-03 22:14:50 UTC (rev 479) @@ -73,9 +73,11 @@ #if DEBUG_ON /* print debugging msg with file+line info to stderr ------------------- */ -# define VK_DEBUG(msg, args...) { \ - vkPrintErr("DEBUG: %s#%d:%s:", __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ - vkPrintErr(msg, ## args ); \ +// Not using (fmt, args...), (fmt, ##args), as QtCreator code checker doesn't like it. +// TODO: reintroduce when we start using a proper IDE +# define VK_DEBUG(...) { \ + vkPrintErr("DEBUG: %s#%d: %s:", __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ + vkPrintErr(__VA_ARGS__); \ vkPrintErr(" "); \ } #else |
From: <sv...@va...> - 2010-03-01 21:00:05
|
Author: cerion Date: 2010-03-01 20:59:43 +0000 (Mon, 01 Mar 2010) New Revision: 478 Log: - on startup, if no binary specified, open options page - if try to 'run' with no binary => info_box & open options page - reorder valkyrie option page Modified: branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.cpp Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-02-28 13:33:46 UTC (rev 477) +++ branches/valkyrie_qt4port/main.cpp 2010-03-01 20:59:43 UTC (rev 478) @@ -90,9 +90,13 @@ // ------------------------------------------------------------ // Start up the gui vkWin = new MainWindow( &valkyrie ); + if ( vkConfig->value( valkyrie.getOption( VALKYRIE::BINARY )->configKey() ).toString().isEmpty() ) { + vkWin->openOptions(); + } + vkWin->showToolView( VGTOOL::ID_MEMCHECK ); vkWin->show(); - vkWin->showToolView( VGTOOL::ID_MEMCHECK ); + qApp->processEvents(); // ------------------------------------------------------------ Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-02-28 13:33:46 UTC (rev 477) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-03-01 20:59:43 UTC (rev 478) @@ -498,6 +498,9 @@ // add view to the stack toolViewStack->addView( nextView ); + + // widgets (menubar, toolbar) have been added: update event filters + updateEventFilters( this ); } // make sure the toolview is made visible: @@ -802,9 +805,6 @@ // cerr << "MainWindow::toolGroupTriggered() for toolview " << toolId << endl; - // widgets may have been added: update event filters - updateEventFilters( this ); - showToolView( toolId ); } @@ -885,20 +885,19 @@ cerr << "MainWindow::runValgrind()" << endl; // don't come in here if there's no current view - if ( !toolViewStack->isVisible() ) + if ( !toolViewStack->isVisible() ) { return; + } - /* valkyrie may have been started with no executable - specified. if so, show prefsWindow + msgbox */ + // Valkyrie may have been started with no executable + // specified. If so, show msgbox, then options dialog if ( vkConfig->value( "valkyrie/binary").toString().isEmpty() ) { -//TODO - cerr << "Error: no binary specified!" << endl; -#if 0 - showOptionsWindow( Valkyrie::ID_VALKYRIE ); - vkInfo( optionsWin, "Run Valgrind", - "Please enter the path to the executable " - "you wish to run, together with any arguments"); -#endif + + vkInfo( this, "Run Valgrind: No program specified", + "Please specify (via Edit::Options::Binary) the path to the program<br>" + "you wish to run, along with any arguments required"); + openOptions(); + return; } Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2010-02-28 13:33:46 UTC (rev 477) +++ branches/valkyrie_qt4port/mainwindow.h 2010-03-01 20:59:43 UTC (rev 478) @@ -54,6 +54,7 @@ public slots: void setStatus( QString msg ); void showToolView( VGTOOL::ToolID toolId ); + void openOptions(); private: void setupLayout(); @@ -70,7 +71,6 @@ void createNewProject(); void openProject(); void closeToolView(); - void openOptions(); void runTool( int procId ); void runValgrind(); void stopTool(); Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-02-28 13:33:46 UTC (rev 477) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-03-01 20:59:43 UTC (rev 478) @@ -226,7 +226,7 @@ "", "1|10", "2", - "Extra lines shown above/below the target line:", + "Src Editor: Extra lines shown above/below target line:", "", urlValkyrie::srcLines, VkOPT::NOT_POPT, @@ -256,7 +256,7 @@ "", "", VkConfig::vkTmpDir(), - "Log Dir:", + "Tmp Log Dir:", "", urlValkyrie::logDir, VkOPT::NOT_POPT, Modified: branches/valkyrie_qt4port/options/valkyrie_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2010-02-28 13:33:46 UTC (rev 477) +++ branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2010-03-01 20:59:43 UTC (rev 478) @@ -77,11 +77,43 @@ grid->setColumnStretch(2, 1); grid->setColumnStretch(3, 1); + int i=0; + grid->setRowMinimumHeight( i++, lineHeight/2 ); // blank row + // ------------------------------------------------------------ + // target setup - options + insertOptionWidget( VALKYRIE::BINARY, group1, false ); // ledit + button + LeWidget* binLedit = ((LeWidget*)m_itemList[VALKYRIE::BINARY]); + binLedit->addButton( group1, this, SLOT(getBinary()) ); + connect(binLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); + + insertOptionWidget( VALKYRIE::BIN_FLAGS, group1, true ); // ledit + LeWidget* binFlgsLedit = ((LeWidget*)m_itemList[VALKYRIE::BIN_FLAGS]); + connect(binFlgsLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); + + insertOptionWidget( VALKYRIE::WORKING_DIR, group1, false ); // line edit + button + LeWidget* dirWorking = ((LeWidget*)m_itemList[VALKYRIE::WORKING_DIR]); + dirWorking->addButton( group1, this, SLOT(getWorkingDir()) ); + connect(dirWorking, SIGNAL(returnPressed()), this, SIGNAL(apply())); + + // target setup - layout + grid->addWidget( binLedit->button(), i, 0 ); + grid->addWidget( binLedit->widget(), i++,1, 1,3 ); + grid->addWidget( binFlgsLedit->label(), i, 0 ); + grid->addWidget( binFlgsLedit->widget(), i++,1, 1,3 ); + grid->addWidget( dirWorking->button(), i, 0 ); + grid->addWidget( dirWorking->widget(), i++,1, 1,3 ); + + grid->addWidget( sep(group1), i++,0, 1,4 ); + + + // ------------------------------------------------------------ // general prefs - options - insertOptionWidget( VALKYRIE::TOOLTIP, group1, false ); // checkbox - insertOptionWidget( VALKYRIE::ICONTXT, group1, false ); // checkbox - insertOptionWidget( VALKYRIE::PALETTE, group1, false ); // checkbox + insertOptionWidget( VALKYRIE::SRC_EDITOR, group1, false ); // ledit + button + LeWidget* editLedit = ((LeWidget*)m_itemList[VALKYRIE::SRC_EDITOR]); + editLedit->addButton( group1, this, SLOT(getEditor()) ); + connect(editLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); + insertOptionWidget( VALKYRIE::SRC_LINES, group1, true ); // intspin insertOptionWidget( VALKYRIE::BROWSER, group1, false ); // line edit LeWidget* brwsrLedit = ((LeWidget*)m_itemList[VALKYRIE::BROWSER]); @@ -93,29 +125,32 @@ dirLogSave->addButton( group1, this, SLOT(getDfltLogDir()) ); connect(dirLogSave, SIGNAL(returnPressed()), this, SIGNAL(apply())); - insertOptionWidget( VALKYRIE::WORKING_DIR, group1, false ); // line edit + button - LeWidget* dirWorking = ((LeWidget*)m_itemList[VALKYRIE::WORKING_DIR]); - dirWorking->addButton( group1, this, SLOT(getWorkingDir()) ); - connect(dirWorking, SIGNAL(returnPressed()), this, SIGNAL(apply())); + insertOptionWidget( VALKYRIE::VG_EXEC, group1, false ); // ledit + button + LeWidget* vgbinLedit = ((LeWidget*)m_itemList[VALKYRIE::VG_EXEC]); + vgbinLedit->addButton( group1, this, SLOT(getVgExec()) ); + connect(vgbinLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); // general prefs - layout - int i=0; - grid->setRowMinimumHeight( i++, lineHeight/2 ); // blank row - grid->addWidget( m_itemList[VALKYRIE::TOOLTIP]->widget(), i++,0, 1,2 ); - grid->addWidget( m_itemList[VALKYRIE::ICONTXT]->widget(), i++,0, 1,2 ); - grid->addWidget( m_itemList[VALKYRIE::PALETTE]->widget(), i++,0, 1,2 ); + grid->addWidget( editLedit->button(), i, 0 ); + grid->addWidget( editLedit->widget(), i++,1, 1,3 ); + grid->addLayout( m_itemList[VALKYRIE::SRC_LINES]->hlayout(), i++,0, 1,4 ); + grid->addWidget( brwsrLedit->button(), i, 0 ); grid->addWidget( brwsrLedit->widget(), i++, 1, 1,3 ); grid->addWidget( dirLogSave->button(), i, 0 ); grid->addWidget( dirLogSave->widget(), i++,1, 1,3 ); - grid->addWidget( dirWorking->button(), i, 0 ); - grid->addWidget( dirWorking->widget(), i++,1, 1,3 ); + grid->addWidget( vgbinLedit->button(), i, 0 ); + grid->addWidget( vgbinLedit->widget(), i++,1, 1,3 ); grid->addWidget( sep(group1), i++,0, 1,4 ); // ------------------------------------------------------------ - // fonts - options + // look 'n feel - options + insertOptionWidget( VALKYRIE::TOOLTIP, group1, false ); // checkbox + insertOptionWidget( VALKYRIE::ICONTXT, group1, false ); // checkbox + insertOptionWidget( VALKYRIE::PALETTE, group1, false ); // checkbox + insertOptionWidget( VALKYRIE::FNT_GEN_SYS, group1, false ); // checkbox LeWidget* fontGenSysLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_SYS]); insertOptionWidget( VALKYRIE::FNT_GEN_USR, group1, false ); // line edit @@ -134,55 +169,16 @@ fontToolLedit->addButton( group1, this, SLOT(chooseToolFont()) ); fontToolLedit->setReadOnly( true ); // don't allow direct editing - // fonts - layout + // look 'n feel - layout + grid->addWidget( m_itemList[VALKYRIE::TOOLTIP]->widget(), i++,0, 1,2 ); + grid->addWidget( m_itemList[VALKYRIE::ICONTXT]->widget(), i++,0, 1,2 ); + grid->addWidget( m_itemList[VALKYRIE::PALETTE]->widget(), i++,0, 1,2 ); grid->addWidget( fontGenSysLedit->widget(), i++,0, 1,4 ); - grid->addWidget( fontGenLedit->button(), i, 0 ); - grid->addWidget( fontGenLedit->widget(), i++,1, 1,3 ); - grid->addWidget( fontToolLedit->button(), i, 0 ); - grid->addWidget( fontToolLedit->widget(), i++,1, 1,3 ); + grid->addWidget( fontGenLedit->button(), i, 0 ); + grid->addWidget( fontGenLedit->widget(), i++,1, 1,3 ); + grid->addWidget( fontToolLedit->button(), i, 0 ); + grid->addWidget( fontToolLedit->widget(), i++,1, 1,3 ); - grid->addWidget( sep(group1), i++,0, 1,4 ); - - - // ------------------------------------------------------------ - // core - options - insertOptionWidget( VALKYRIE::SRC_LINES, group1, true ); // intspin - insertOptionWidget( VALKYRIE::SRC_EDITOR, group1, false ); // ledit + button - LeWidget* editLedit = ((LeWidget*)m_itemList[VALKYRIE::SRC_EDITOR]); - editLedit->addButton( group1, this, SLOT(getEditor()) ); - connect(editLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); - - insertOptionWidget( VALKYRIE::BINARY, group1, false ); // ledit + button - LeWidget* binLedit = ((LeWidget*)m_itemList[VALKYRIE::BINARY]); - binLedit->addButton( group1, this, SLOT(getBinary()) ); - connect(binLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); - - insertOptionWidget( VALKYRIE::BIN_FLAGS, group1, true ); // ledit - LeWidget* binFlgsLedit = ((LeWidget*)m_itemList[VALKYRIE::BIN_FLAGS]); - connect(binFlgsLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); - - insertOptionWidget( VALKYRIE::VG_EXEC, group1, false ); // ledit + button - LeWidget* vgbinLedit = ((LeWidget*)m_itemList[VALKYRIE::VG_EXEC]); - vgbinLedit->addButton( group1, this, SLOT(getVgExec()) ); - connect(vgbinLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); - - // core - layout - grid->addLayout( m_itemList[VALKYRIE::SRC_LINES]->hlayout(), i++,0, 1,4 ); - grid->addWidget( editLedit->button(), i, 0 ); - grid->addWidget( editLedit->widget(), i++,1, 1,3 ); - - grid->setRowMinimumHeight( i++, lineHeight ); // blank row - - grid->addWidget( binLedit->button(), i, 0 ); - grid->addWidget( binLedit->widget(), i++,1, 1,3 ); - grid->addWidget( binFlgsLedit->label(), i, 0 ); - grid->addWidget( binFlgsLedit->widget(), i++,1, 1,3 ); - - grid->setRowMinimumHeight( i++, lineHeight ); // blank row - - grid->addWidget( vgbinLedit->button(), i, 0 ); - grid->addWidget( vgbinLedit->widget(), i++,1, 1,3 ); - vk_assert( m_itemList.count() <= VALKYRIE::NUM_OPTS ); } Modified: branches/valkyrie_qt4port/options/vk_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-02-28 13:33:46 UTC (rev 477) +++ branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-03-01 20:59:43 UTC (rev 478) @@ -88,7 +88,7 @@ { QFrame* line = new QFrame( parent ); line->setFrameStyle( QFrame::HLine | QFrame::Sunken ); - line->setMinimumHeight( 4 ); + line->setMinimumHeight( 16 ); return line; } |
From: <sv...@va...> - 2010-02-28 14:11:53
|
Author: cerion Date: 2010-02-28 13:33:46 +0000 (Sun, 28 Feb 2010) New Revision: 477 Log: Reintroduced some more options/cfg funtionality. More refactoring, so less internals are spread around: OptionPages save their edits via the underlying option - that is responsible then for saving to vkConfig, and for signalling to whoever is listening that it's value has changed. This allows us to remove all responsibility of applying the effects of any changes from the option_pages: we just connect to the relevant option->valueChanged() signal. e.g. valkyrie_options_page & vkConfig don't know about MainWindow anymore. Modified: branches/valkyrie_qt4port/help/help_handbook.cpp branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/helgrind_object.h branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/tool_object.cpp branches/valkyrie_qt4port/objects/tool_object.h branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/objects/vk_objects.cpp branches/valkyrie_qt4port/objects/vk_objects.h branches/valkyrie_qt4port/options/helgrind_options_page.cpp branches/valkyrie_qt4port/options/helgrind_options_page.h branches/valkyrie_qt4port/options/memcheck_options_page.cpp branches/valkyrie_qt4port/options/memcheck_options_page.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valgrind_options_page.h branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.h branches/valkyrie_qt4port/options/vk_option.cpp branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.h branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_cb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_ck_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_le_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_sp_widget.cpp branches/valkyrie_qt4port/toolview/helgrindview.cpp branches/valkyrie_qt4port/toolview/memcheckview.cpp branches/valkyrie_qt4port/toolview/toolview.cpp branches/valkyrie_qt4port/toolview/toolview.h branches/valkyrie_qt4port/toolview/vglogview.cpp branches/valkyrie_qt4port/utils/vk_config.cpp branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/utils/vk_messages.cpp Modified: branches/valkyrie_qt4port/help/help_handbook.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/help/help_handbook.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -250,7 +250,7 @@ historyMenu->removeAction( act ); if ( found ) { // found more than once! - VK_DEBUG( "found double entry in historyMenu: ", qPrintable( act->text() ) ); + VK_DEBUG( "found double entry in historyMenu: %s", qPrintable( act->text() ) ); } else { if ( ! historyMenu->actions().isEmpty() ) { historyMenu->insertAction( historyMenu->actions().first(), act ); @@ -438,7 +438,7 @@ foreach( QAction* act, historyMenu->actions() ) { history << act->text(); } - vkConfig->setValue( "handbook/history", history ); + vkConfig->setValue( "valkyrie/handbook_history", history ); int nBookmarks = 0; QStringList bookmarks; @@ -449,7 +449,7 @@ nBookmarks++; } } - vkConfig->setValue( "handbook/bookmarks", bookmarks ); + vkConfig->setValue( "valkyrie/handbook_bookmarks", bookmarks ); vk_assert( nBookmarks <= max_bookmarks ); @@ -494,13 +494,13 @@ void HandBook::readHistory() { bool ok = false; - max_history = vkConfig->value( "valkyrie_handbook/max_history", 20 ).toInt( &ok ); - if (!ok) cerr << "Error: bad value for config::valkyrie_handbook/max_history" << endl; + max_history = vkConfig->value( "valkyrie/handbook_max_history", 20 ).toInt( &ok ); + if (!ok) cerr << "Error: bad value for config::valkyrie/handbook_max_history" << endl; // TODO: do this via vkConfig! #if 0 //TODO: need to write to _global_ config, not project/temp config... - QStringList history = vkConfig->value( "handbook/history" ).toStringList(); + QStringList history = vkConfig->value( "valkyrie/handbook_history" ).toStringList(); int len = history.count() > max_history ? max_history : history.count(); for ( int idx=0; idx < len; idx++ ) { QString link = history.at( idx ); @@ -537,18 +537,18 @@ void HandBook::readBookmarks() { bool ok = false; - max_bookmarks = vkConfig->value( "valkyrie_handbook/max_bookmarks", 20 ).toInt(&ok); - if (!ok) cerr << "Error: bad value for config::valkyrie_handbook/max_bookmarks" << endl; + max_bookmarks = vkConfig->value( "valkyrie/handbook_max_bookmarks", 20 ).toInt(&ok); + if (!ok) cerr << "Error: bad value for config::valkyrie/handbook_max_bookmarks" << endl; // TODO: do this via vkConfig! #if 0 //TODO: need to write to _global_ config, not project/temp config... - QStringList bookmarks = vkConfig->value( "handbook/bookmarks" ).toStringList(); + QStringList bookmarks = vkConfig->value( "valkyrie/handbook_bookmarks" ).toStringList(); int len = bookmarks.count() > max_bookmarks ? max_bookmarks : bookmarks.count(); for ( int idx=0; idx < len; idx++ ) { QString str = bookmarks.at( idx ); - QStringList sl = str.split( vkConfig->vkSepChar ); + QStringList sl = str.split( vkConfig->vkSepChar ); //, QString::SkipEmptyParts QString title = sl.first(); QString url = sl.last(); @@ -568,7 +568,7 @@ QTextStream stream( &aFile ); for ( int idx=0; idx < max_bookmarks && !stream.atEnd(); idx++ ) { // read in one line at a time, and split on vkSepChar - QStringList sl = stream.readLine().split( vkConfig->vkSepChar ); + QStringList sl = stream.readLine().split( vkConfig->vkSepChar, QString::SkipEmptyParts ); QString title = sl.first(); QString url = sl.last(); Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/main.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -52,13 +52,14 @@ // Start turning the engine over app = new QApplication( argc, argv ); - // ------------------------------------------------------------ // Setup application config settings QCoreApplication::setOrganizationName("OpenWorks"); QCoreApplication::setOrganizationDomain("openworks.co.uk"); QCoreApplication::setApplicationName("Valkyrie"); + QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); + VkConfig::createConfig( &valkyrie, &vkConfig ); if ( vkConfig == NULL ) { VK_DEBUG("Failed to initialise config properly: Aborting" ); Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -19,6 +19,9 @@ ****************************************************************************/ #include <QApplication> +#include <QColor> +#include <QColorGroup> +#include <QEvent> #include <QFileDialog> #include <QInputDialog> #include <QMenu> @@ -62,15 +65,16 @@ */ MainWindow::MainWindow( Valkyrie* vk ) : QMainWindow(), - valkyrie( vk ), optionsDialog( 0 ) + valkyrie( vk ), toolViewStack( 0 ), statusLabel( 0 ), + handBook( 0 ), optionsDialog( 0 ) { setObjectName( QString::fromUtf8("MainWindowClass") ); QString title = vkConfig->vkName; title[0] = title[0].toUpper(); setWindowTitle( title ); - // TODO: QtCoreApplication? - //setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom)); + lastAppFont = qApp->font(); + lastPalette = qApp->palette(); QIcon icon_vk; icon_vk.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valkyrie.xpm") ), QIcon::Normal, QIcon::Off ); @@ -85,8 +89,30 @@ setupMenus(); setupToolBars(); setupStatusBar(); - setStatus( "Status message goes here..." ); + + // functions for dealing with config updates + VkOption* opt = valkyrie->getOption( VALKYRIE::ICONTXT ); + connect( opt, SIGNAL( valueChanged() ), this, SLOT( showLabels() ) ); + opt = valkyrie->getOption( VALKYRIE::TOOLTIP ); + connect( opt, SIGNAL( valueChanged() ), this, SLOT( showToolTips() ) ); + opt = valkyrie->getOption( VALKYRIE::FNT_GEN_SYS ); + connect( opt, SIGNAL( valueChanged() ), this, SLOT( setGenFont() ) ); + opt = valkyrie->getOption( VALKYRIE::FNT_GEN_USR ); + connect( opt, SIGNAL( valueChanged() ), this, SLOT( setGenFont() ) ); + opt = valkyrie->getOption( VALKYRIE::FNT_TOOL_USR ); + connect( opt, SIGNAL( valueChanged() ), this, SLOT( setToolFont() ) ); + opt = valkyrie->getOption( VALKYRIE::PALETTE ); + connect( opt, SIGNAL( valueChanged() ), this, SLOT( setPalette() ) ); + + showLabels(); + showToolTips(); + setGenFont(); + setToolFont(); + setPalette(); + + updateEventFilters( this ); + updateEventFilters( handBook ); } @@ -101,8 +127,10 @@ delete toolViewStack; // Save window position to config. - vkConfig->setValue( "valkyrie_mainwindow/size", size() ); - vkConfig->setValue( "valkyrie_mainwindow/pos", pos() ); + VkOption* opt = valkyrie->getOption( VALKYRIE::MW_SIZE ); + opt->updateConfig( size() ); + opt = valkyrie->getOption( VALKYRIE::MW_POS ); + opt->updateConfig( pos() ); vkConfig->sync(); // handbook has no parent, so have to delete it. @@ -112,8 +140,8 @@ /*! - Allow a tool to insert a menu into the main menuBar. - A tool can't do this directly via it's parent pointer, as it needs access + Allow a tool to insert a menu into the main menuBar. + A tool can't do this directly via it's parent pointer, as it needs access to private vars for positioning within the menu. \sa removeToolMenuAction() @@ -142,8 +170,10 @@ */ void MainWindow::setupLayout() { - resize( vkConfig->value( "valkyrie_mainwindow/size", QSize(600, 600)).toSize()); - move( vkConfig->value( "valkyrie_mainwindow/pos", QPoint(400, 0)).toPoint()); + VkOption* opt = valkyrie->getOption( VALKYRIE::MW_SIZE ); + resize( vkConfig->value( opt->configKey(), QSize(600, 600)).toSize() ); + opt = valkyrie->getOption( VALKYRIE::MW_POS ); + move( vkConfig->value( opt->configKey(), QPoint(400, 0)).toPoint() ); toolViewStack = new ToolViewStack( this ); setCentralWidget( toolViewStack ); @@ -155,13 +185,13 @@ */ void MainWindow::setupActions() { - // TODO: shortcuts & tips + // TODO: shortcuts // act->setShortcut( tr("Ctrl+XXX") ); - // act->setStatusTip( tr("here's a tip") ); actFile_NewProj = new QAction( this ); actFile_NewProj->setObjectName( QString::fromUtf8("actFile_NewProj") ); actFile_NewProj->setText( QApplication::translate("MainWindowClass", "&New Project...", 0, QApplication::UnicodeUTF8) ); + actFile_NewProj->setToolTip( tr("Create a project to save your configuration") ); QIcon icon_newproj; icon_newproj.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/filenew.png") ), QIcon::Normal, QIcon::Off ); actFile_NewProj->setIcon( icon_newproj ); @@ -170,6 +200,7 @@ actFile_OpenProj = new QAction( this ); actFile_OpenProj->setObjectName( QString::fromUtf8("actFile_OpenProj") ); actFile_OpenProj->setText( QApplication::translate("MainWindowClass", "&Open Project...", 0, QApplication::UnicodeUTF8) ); + actFile_OpenProj->setToolTip( tr("Open an existing project to load a saved configuration") ); QIcon icon_openproj; icon_openproj.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/folder_blue.png") ), QIcon::Normal, QIcon::Off ); actFile_OpenProj->setIcon( icon_openproj ); @@ -177,12 +208,14 @@ actFile_Close = new QAction( this ); actFile_Close->setObjectName( QString::fromUtf8("actFile_Close") ); + actFile_Close->setToolTip( tr("Close the currently active tool") ); actFile_Close->setText( QApplication::translate("MainWindowClass", "&Close Tool", 0, QApplication::UnicodeUTF8) ); connect( actFile_Close, SIGNAL( triggered() ), this, SLOT( closeToolView() ) ); actFile_Exit = new QAction( this ); actFile_Exit->setObjectName( QString::fromUtf8("actFile_Exit") ); actFile_Exit->setText( QApplication::translate("MainWindowClass", "E&xit", 0, QApplication::UnicodeUTF8) ); + actFile_Exit->setToolTip( tr("Exit Valkyrie") ); QIcon icon_exit; icon_exit.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/exit.png") ), QIcon::Normal, QIcon::Off ); actFile_Exit->setIcon( icon_exit ); @@ -191,6 +224,7 @@ actEdit_Options = new QAction( this ); actEdit_Options->setObjectName( QString::fromUtf8("actEdit_Options") ); actEdit_Options->setText( QApplication::translate("MainWindowClass", "O&ptions", 0, QApplication::UnicodeUTF8) ); + actEdit_Options->setToolTip( tr("Open the options-editing window") ); QIcon icon_options; icon_options.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/gear.png") ), QIcon::Normal, QIcon::Off ); actEdit_Options->setIcon( icon_options ); @@ -199,6 +233,7 @@ actProcess_Run = new QAction( this ); actProcess_Run->setObjectName( QString::fromUtf8("actProcess_Run") ); actProcess_Run->setText( QApplication::translate("MainWindowClass", "&Run", 0, QApplication::UnicodeUTF8) ); + actProcess_Run->setToolTip( tr("Run Valgrind with the currently active tool") ); actProcess_Run->setShortcut( QApplication::translate("MainWindowClass", "Ctrl+R", 0, QApplication::UnicodeUTF8) ); QIcon icon_run; icon_run.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valgrind_run.png") ), QIcon::Normal, QIcon::Off ); @@ -209,6 +244,7 @@ actProcess_Stop = new QAction( this ); actProcess_Stop->setObjectName( QString::fromUtf8("actProcess_Stop") ); actProcess_Stop->setText( QApplication::translate("MainWindowClass", "S&top", 0, QApplication::UnicodeUTF8) ); + actProcess_Stop->setToolTip( tr("Stop Valgrind") ); QIcon icon_stop; icon_stop.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valgrind_stop.png") ), QIcon::Normal, QIcon::Off ); actProcess_Stop->setIcon( icon_stop ); @@ -217,6 +253,7 @@ actHelp_Handbook = new QAction( this ); actHelp_Handbook->setObjectName( QString::fromUtf8("actHelp_Handbook") ); actHelp_Handbook->setText( QApplication::translate("MainWindowClass", "Handbook", 0, QApplication::UnicodeUTF8) ); + actHelp_Handbook->setToolTip( tr("Open the Valkyrie Handbook") ); actHelp_Handbook->setShortcut( QApplication::translate("MainWindowClass", "F1", 0, QApplication::UnicodeUTF8) ); QIcon icon_handbook; icon_handbook.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_help.xpm") ), QIcon::Normal, QIcon::Off ); @@ -356,7 +393,7 @@ mainToolBar = new QToolBar( this ); mainToolBar->setObjectName( QString::fromUtf8("mainToolBar") ); this->addToolBar( Qt::TopToolBarArea, mainToolBar ); - + // ------------------------------------------------------------ // Add actions to toolbar mainToolBar->addAction( actProcess_Run ); @@ -379,8 +416,6 @@ // Basic statusbar setup mainStatusBar = this->statusBar(); mainStatusBar->setObjectName( QString::fromUtf8("mainStatusBar ") ); -//TODO: why disable? -// mainStatusBar->setSizeGripEnabled( false ); statusLabel = new QLabel( mainStatusBar ); statusLabel->setObjectName( QString::fromUtf8("statusLabel ") ); @@ -390,6 +425,35 @@ /*! + Install our eventFilter for given widgets and all its children. + Just to support tooltips suppression - apparently the only way :-( +*/ +void MainWindow::updateEventFilters( QObject* obj ) +{ + foreach( QObject* obj, obj->children() ) { + obj->installEventFilter( this ); + updateEventFilters( obj ); + } +} + + +/*! + EventFilter: installed for all widgets. + If configure option given, suppress all ToolTips +*/ +bool MainWindow::eventFilter( QObject* obj, QEvent* e ) +{ + if ( !fShowToolTips && e->type() == QEvent::ToolTip ) { + // eat tooltip event + return true; + } else { + // pass the event on to the parent class + return QMainWindow::eventFilter( obj, e ); + } +} + + +/*! Show a requested ToolView, from the given \a toolId. The ToolViews are created and shown on demand. @@ -402,7 +466,7 @@ // already loaded and visible. return; } - // else: toolview maybe loaded, but isn't visible... + // else: toolview may still be loaded, but not visible... ToolView* nextView = toolViewStack->findView( toolId ); if ( nextView == 0) { @@ -412,6 +476,7 @@ ToolObject* nextTool = valkyrie->valgrind()->getToolObj( toolId ); vk_assert( nextTool != 0 ); + // Factory Method to create views nextView = nextTool->createView( this ); vk_assert( nextView != 0 ); @@ -419,15 +484,18 @@ this, SLOT(updateVgButtons(bool)) ); connect( nextTool, SIGNAL(message(QString)), this, SLOT(setStatus(QString)) ); -/* TODO - connect( this, SIGNAL(toolbarLabelsToggled(bool)), - nextView, SLOT(toggleToolbarLabels(bool)) ); -*/ - // view starts tool processes via this signal - connect( nextView, SIGNAL(run(int)), - this, SLOT(runTool(int)) ); + // Set a vg logfile. Loading done by tool_object + connect( nextView, SIGNAL(logFileChosen(QString)), + this, SLOT(setLogFile(QString)) ); + //TODO: perhaps bring emcheck::fileSaveDialog() here too... + // + Memcheck::saveParsedOutput() + + // view starts tool processes via this signal + connect( nextView, SIGNAL(run(int)), + this, SLOT(runTool(int)) ); + // add view to the stack toolViewStack->addView( nextView ); } @@ -436,7 +504,6 @@ toolViewStack->raiseView( nextView ); setToggles( toolId ); - updateVgFlags(); } @@ -473,7 +540,6 @@ } else { // at least one toolview found: update state - updateVgFlags(); // enable the relevant action in the tool actiongroup // TODO: nicer way to do this? - maybe connect sig/slot toolview to action? @@ -493,8 +559,137 @@ } +void MainWindow::showLabels() +{ + VkOption* opt = valkyrie->getOption( VALKYRIE::ICONTXT ); + bool show = vkConfig->value( opt->configKey() ).toBool(); + if ( show ) { + setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + } else { + setToolButtonStyle( Qt::ToolButtonIconOnly ); + } +} + +void MainWindow::showToolTips() +{ + VkOption* opt = valkyrie->getOption( VALKYRIE::TOOLTIP ); + fShowToolTips = vkConfig->value( opt->configKey() ).toBool(); +} + + +void MainWindow::setGenFont() +{ + // TODO: qApp->setFont will be called twice if FNT_GEN_USR && FNT_GEN_SYS + // are both modified together - do we care? + + QFont fnt; + VkOption* opt = valkyrie->getOption( VALKYRIE::FNT_GEN_SYS ); + bool useVkSysFont = vkConfig->value( opt->configKey() ).toBool(); + if ( useVkSysFont ) { + fnt = lastAppFont; + } else { + lastAppFont = qApp->font(); + VkOption* opt = valkyrie->getOption( VALKYRIE::FNT_GEN_USR ); + QString str_fnt = vkConfig->value( opt->configKey() ).toString(); + fnt.fromString( str_fnt ); + } + + if ( qApp->font() != fnt ) { + qApp->setFont( fnt ); + } +} + +void MainWindow::setToolFont() +{ + QFont fnt; + VkOption* opt = valkyrie->getOption( VALKYRIE::FNT_TOOL_USR ); + QString str = vkConfig->value( opt->configKey() ).toString(); + fnt.fromString( str ); + + // set font for all tool views + foreach ( ToolObject* tool, valkyrie->valgrind()->getToolObjList() ) { + ToolView* tv = tool->view(); + if (tv != NULL) { + tv->setToolFont( fnt ); + } + } +} + +void MainWindow::setPalette() +{ + QPalette pal; + VkOption* opt = valkyrie->getOption( VALKYRIE::PALETTE ); + bool useVkPalette = vkConfig->value( opt->configKey() ).toBool(); + if ( !useVkPalette ) { + pal = lastPalette; + } else { + lastPalette = qApp->palette(); + + QColor bg = vkConfig->value( "valkyrie/colour_background" ).value<QColor>(); + QColor base = vkConfig->value( "valkyrie/colour_base" ).value<QColor>(); + QColor text = vkConfig->value( "valkyrie/colour_text" ).value<QColor>(); + QColor dkgray = vkConfig->value( "valkyrie/colour_dkgray" ).value<QColor>(); + QColor hilite = vkConfig->value( "valkyrie/colour_highlight" ).value<QColor>(); + + // anything not ok -> return default qApp palette: + if ( bg.isValid() && base.isValid() && text.isValid() && + dkgray.isValid() && hilite.isValid() ) { + + pal = QPalette( bg, bg ); + // 3 colour groups: active, inactive, disabled + // bg colour for text entry widgets + pal.setColor( QPalette::Active, QPalette::Base, base ); + pal.setColor( QPalette::Inactive, QPalette::Base, base ); + pal.setColor( QPalette::Disabled, QPalette::Base, base ); + // general bg colour + pal.setColor( QPalette::Active, QPalette::Window, bg ); + pal.setColor( QPalette::Inactive, QPalette::Window, bg ); + pal.setColor( QPalette::Disabled, QPalette::Window, bg ); + // same as bg + pal.setColor( QPalette::Active, QPalette::Button, bg ); + pal.setColor( QPalette::Inactive, QPalette::Button, bg ); + pal.setColor( QPalette::Disabled, QPalette::Button, bg ); + // general fg colour - same as Text + pal.setColor( QPalette::Active, QPalette::WindowText, text ); + pal.setColor( QPalette::Inactive, QPalette::WindowText, text ); + pal.setColor( QPalette::Disabled, QPalette::WindowText, dkgray ); + // same as fg + pal.setColor( QPalette::Active, QPalette::Text, text ); + pal.setColor( QPalette::Inactive, QPalette::Text, text ); + pal.setColor( QPalette::Disabled, QPalette::Text, dkgray ); + // same as text and fg + pal.setColor( QPalette::Active, QPalette::ButtonText, text ); + pal.setColor( QPalette::Inactive, QPalette::ButtonText, text ); + pal.setColor( QPalette::Disabled, QPalette::ButtonText, dkgray ); + // highlight + pal.setColor( QPalette::Active, QPalette::Highlight, hilite ); + pal.setColor( QPalette::Inactive, QPalette::Highlight, hilite ); + pal.setColor( QPalette::Disabled, QPalette::Highlight, hilite ); + // contrast with highlight + pal.setColor( QPalette::Active, QPalette::HighlightedText, base ); + pal.setColor( QPalette::Inactive, QPalette::HighlightedText, base ); + pal.setColor( QPalette::Disabled, QPalette::HighlightedText, base ); + } + } + + if ( qApp->palette() != pal ) { + qApp->setPalette( pal ); + } +} + + /*! + set logfile name to be loaded +*/ +void MainWindow::setLogFile( QString logFilename ) +{ + VkOption* opt = valkyrie->getOption( VALKYRIE::VIEW_LOG ); + opt->updateConfig( logFilename ); +} + + +/*! Create a new project: Save configuration in a project file. */ @@ -550,7 +745,7 @@ return; } - vkConfig->openProject( proj_filename ); + vkConfig->openProject( valkyrie, proj_filename ); } @@ -590,27 +785,8 @@ } -/*! - Called by this->showToolView(), - and optionsDlg::flagsChanged() signal -*/ -void MainWindow::updateVgFlags() -{ - // update valkyrie's flags: if there's a visible ToolView - if ( toolViewStack->isVisible() ) - valkyrie->updateVgFlags( toolViewStack->currentToolId() ); -//TODO: maybe. -#if 0 - // update flags display - if ( m_flagsLabel->isVisible() ) { - showFlagsWidget( true ); - } -#endif -} - - /*! Calls showToolView() for a chosen valgrind tool. @@ -624,13 +800,15 @@ { VGTOOL::ToolID toolId = (VGTOOL::ToolID)action->property( "toolId" ).toInt(); - cerr << "MainWindow::toolGroupTriggered() for toolview " << toolId << endl; +// cerr << "MainWindow::toolGroupTriggered() for toolview " << toolId << endl; + // widgets may have been added: update event filters + updateEventFilters( this ); + showToolView( toolId ); } - /*! Open the Options dialog. */ @@ -649,9 +827,7 @@ #else VkOptionsDialog optionsDlg( this ); - // let the flags widget know that flags may have been modified - connect( &optionsDlg, SIGNAL(flagsChanged()), - this, SLOT(updateVgFlags()) ); + updateEventFilters( &optionsDlg ); optionsDlg.exec(); #endif Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/mainwindow.h 2010-02-28 13:33:46 UTC (rev 477) @@ -22,10 +22,13 @@ #define __MAINWINDOW_H #include <QActionGroup> +#include <QEvent> +#include <QFont> #include <QLabel> +#include <QMainWindow> +#include <QPalette> #include <QPlainTextEdit> #include <QStatusBar> -#include <QMainWindow> #include <QToolButton> #include <QVBoxLayout> @@ -59,6 +62,8 @@ void setupToolBars(); void setupStatusBar(); void setToggles( VGTOOL::ToolID toolId ); + void updateEventFilters( QObject* obj ); + bool eventFilter( QObject* obj, QEvent* e ); private slots: void toolGroupTriggered( QAction* ); @@ -73,15 +78,19 @@ void openAboutVk(); void openAboutLicense(); void openAboutSupport(); - void updateVgFlags(); void updateVgButtons( bool running ); -private: - Valkyrie* valkyrie; - ToolViewStack* toolViewStack; - QLabel* statusLabel; - HandBook* handBook; + // functions for dealing with config updates + void showLabels(); + void showToolTips(); + void setGenFont(); + void setToolFont(); + void setPalette(); + // functions for dealing with toolview updates + void setLogFile( QString logFilename ); + + private: QAction* actFile_NewProj; QAction* actFile_OpenProj; @@ -108,7 +117,16 @@ QToolBar* mainToolBar; QStatusBar* mainStatusBar; +private: + Valkyrie* valkyrie; + ToolViewStack* toolViewStack; + QLabel* statusLabel; + HandBook* handBook; VkOptionsDialog* optionsDialog; + + bool fShowToolTips; + QFont lastAppFont; + QPalette lastPalette; }; #endif // __MAINWINDOW_H Modified: branches/valkyrie_qt4port/objects/helgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/helgrind_object.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/helgrind_object.h 2010-02-28 13:33:46 UTC (rev 477) @@ -53,6 +53,7 @@ ToolView* createView( QWidget* parent ); unsigned int maxOptId() { return HELGRIND::NUM_OPTS; } int checkOptArg( int optid, QString& argval ); + VkOptionsPage* createVkOptionsPage(); bool start( int procId, QStringList vgflags ) { return false; } Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -231,38 +231,6 @@ } -/* called from Valkyrie::updateVgFlags() whenever flags have been changed */ -QStringList Memcheck::modifiedVgFlags() -{ - QStringList modFlags; -#if 0 - QString defVal, cfgVal, flag; - - Option* opt; - for ( opt = m_optList.first(); opt; opt = m_optList.next() ) { - flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag - : opt->m_longFlag; - defVal = opt->m_defaultValue; /* opt holds the default */ - cfgVal = vkConfig->rdEntry( opt->m_longFlag, name() ); - - switch ( (Memcheck::mcOpts)opt->m_key ) { - - /* when using xml output from valgrind, this option is preset to - 'full' by valgrind, so this option should not be used. */ - case LEAK_CHECK: - /* ignore this opt */ - break; - - default: - if ( defVal != cfgVal ) - modFlags << "--" + opt->m_longFlag + "=" + cfgVal; - } - } -#endif - return modFlags; -} - - /* Creates this tool's ToolView window, and sets up and connections between them */ ToolView* Memcheck::createView( QWidget* parent ) @@ -477,7 +445,7 @@ /*! - Parse log file given by [valkyrie::view-log] entry. + Parse log file given by [VALKYRIE::VIEW_LOG] entry. Called by valkyrie->runTool() if cmdline --view-log=<file> specified. MemcheckView::openLogFile() if gui parse-log selected. If 'checked' == true, file perms/format has already been checked @@ -487,7 +455,8 @@ vk_assert( getToolView() != 0 ); //TODO: pass this via flags from the toolview, or something. - QString log_file = vkConfig->value( "valkyrie/view-log" ).toString(); + VkOption* opt = options.getOption( VALKYRIE::VIEW_LOG ); + QString log_file = vkConfig->value( opt->configKey() ).toString(); statusMsg( "Parsing", log_file ); //TODO: file checks @@ -842,6 +811,7 @@ return true; } + /* Save to file - we already have everything in saveFname logfile, so just copy that */ Modified: branches/valkyrie_qt4port/objects/memcheck_object.h =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-02-28 13:33:46 UTC (rev 477) @@ -81,9 +81,6 @@ VkOptionsPage* createVkOptionsPage(); - // returns a list of non-default flags to pass to valgrind - QStringList modifiedVgFlags(); - public slots: bool fileSaveDialog( QString fname=QString() ); void stop(); Modified: branches/valkyrie_qt4port/objects/tool_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/tool_object.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -86,26 +86,27 @@ m_view->close( true/*alsoDelete*/ ); m_view = 0; } +#endif ToolView* ToolObject::view() { - return m_view; + return toolView; } /* called from Valkyrie::updateVgFlags() whenever flags have been changed */ -QStringList ToolObject::modifiedVgFlags() +QStringList ToolObject::getVgFlags() { QStringList modFlags; - for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { + foreach( VkOption* opt, options.getOptionHash() ) { - QString defVal = opt->m_defaultValue; /* opt holds the default */ - QString cfgVal = vkConfig->rdEntry( opt->m_longFlag, name() ); + QString defVal = opt->dfltValue.toString(); + QString cfgVal = vkConfig->value( opt->configKey() ).toString(); - if ( defVal != cfgVal ) - modFlags << "--" + opt->m_longFlag + "=" + cfgVal; + if ( defVal != cfgVal ) { + modFlags << "--" + opt->longFlag + "=" + cfgVal; + } } return modFlags; } -#endif Modified: branches/valkyrie_qt4port/objects/tool_object.h =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/tool_object.h 2010-02-28 13:33:46 UTC (rev 477) @@ -60,8 +60,9 @@ // called by MainWin::closeToolView() virtual bool queryDone() = 0; virtual void deleteView(); - ToolView* view(); */ + ToolView* view(); + // start a process: may fail virtual bool start( int procId, QStringList vgflags ) = 0; // stop a process: doesn't exit until success @@ -69,12 +70,10 @@ bool isRunning(); -/* - virtual OptionsPage* createOptionsPage( OptionsWindow* parent ) = 0; + virtual VkOptionsPage* createVkOptionsPage() = 0; // returns a list of non-default flags to pass to valgrind - virtual QStringList modifiedVgFlags(); -*/ + virtual QStringList getVgFlags(); signals: void running( bool ); Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -31,7 +31,7 @@ #include "objects/memcheck_object.h" //#include "cachegrind_object.h" //#include "massif_object.h" -//#include "vk_option.h" // PERROR* and friends +#include "options/vk_option.h" #include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc. @@ -70,7 +70,6 @@ */ void Valgrind::setupOptions() { - // ------------------------------------------------------------ // tool options.addOpt( @@ -590,7 +589,7 @@ case VALGRIND::SUPPS_DIRS: { /* not popt: only reaches here from gui */ /* check all entries are valid dirs */ - QStringList dirs = QStringList::split(sep, argval); + QStringList dirs = QStringList::split(sep, argval); //, QString::SkipEmptyParts QStringList::iterator it = dirs.begin(); for (; it != dirs.end(); ++it) { /* check dirs ok */ @@ -603,7 +602,7 @@ case VALGRIND::SUPPS_AVAIL: /* not popt: only reaches here from gui */ case VALGRIND::SUPPS_SEL: { /* is popt: --suppressions */ - QStringList files = QStringList::split(sep, argval); + QStringList files = QStringList::split(sep, argval); //, QString::SkipEmptyParts QStringList::iterator it = files.begin(); for (; it != files.end(); ++it) { /* check files ok & readable */ @@ -704,59 +703,70 @@ } -#if 0 -/* valkyrie hijacks any log-to-file flags; these are not passed to - valgrind, but are used after parsing has finished to save to. */ -QStringList Valgrind::modifiedVgFlags( const ToolObject* tool_obj ) +/*! + Return list of non-default flags, including those for tool_obj. + + Note: Valkyrie hijacks any log-to-file flags; these are not passed to + valgrind, but are used after parsing has finished to save to. +*/ +QStringList Valgrind::getVgFlags( ToolObject* tool_obj ) { QStringList modFlags; - QString defVal, cfgVal, flag; - for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { - flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag - : opt->m_longFlag; - defVal = opt->m_defaultValue; - cfgVal = vkConfig->rdEntry( opt->cfgKey(), name() ); + foreach( VkOption* opt, options.getOptionHash() ) { + QString defVal = opt->dfltValue.toString(); + QString cfgVal = vkConfig->value( opt->configKey() ).toString(); - switch ( (Valgrind::vgOpts)opt->m_key ) { + switch ( (VALGRIND::vgOptId)opt->optid ) { - /* we never want these included */ + // we never want these included case VALGRIND::TOOL: /* tool set by valkyrie */ case VALGRIND::SUPPS_DIRS: /* false option */ case VALGRIND::SUPPS_AVAIL: /* false option */ + // ignore these opts break; - /* only error-reporting tools have suppressions */ + // only error-reporting tools have suppressions case VALGRIND::SUPPS_SEL: { - if ( tool_obj->name() == "memcheck" ) { - /* we need '--suppressions=' before each and every filename */ - QString optEntry = vkConfig->rdEntry( opt->cfgKey(), name() ); - QStringList files = QStringList::split( ",", optEntry ); - for ( unsigned int i=0; i<files.count(); i++ ) { - modFlags << "--" + opt->cfgKey() + "=" + files[i]; + if ( tool_obj->objectName() == "memcheck" ) { + // we need '--suppressions=' before each and every filename + QString optEntry = vkConfig->value( opt->configKey() ).toString(); + QStringList files = optEntry.split( ",", QString::SkipEmptyParts ); + for ( int i=0; i<files.count(); i++ ) { + modFlags << "--" + opt->longFlag + "=" + files[i]; } + } else { + // ignore opt } } break; - /* for memcheck we always need xml=yes */ + // for memcheck we always need xml=yes case VALGRIND::XML_OUTPUT: - if ( tool_obj->name() == "memcheck") - modFlags << "--" + opt->cfgKey() + "=yes"; - else - if ( defVal != cfgVal ) - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + if ( tool_obj->objectName() == "memcheck") { + modFlags << "--" + opt->longFlag + "=yes"; + } else { + if ( defVal != cfgVal ) { + modFlags << "--" + opt->longFlag + "=" + cfgVal; + } + } break; - /* for memcheck we needs this enabled to keep the xml clean */ + // for memcheck we need this enabled to keep the xml clean case VALGRIND::SILENT_CH: - if ( tool_obj->name() == "memcheck") - modFlags << "--" + opt->cfgKey() + "=yes"; - else - if ( defVal != cfgVal ) - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + if ( tool_obj->objectName() == "memcheck") { + modFlags << "--" + opt->longFlag + "=yes"; + } else { + if ( defVal != cfgVal ) { + modFlags << "--" + opt->longFlag + "=" + cfgVal; + } + } break; + // memcheck presets/ignores these options for xml output + // - ignore these opts + // - see valgrind/docs/internals/xml_output.txt + // Note: gui options not disabled: other tools use these options case VALGRIND::VERBOSITY: case VALGRIND::TRACK_FDS: case VALGRIND::TIME_STAMP: @@ -765,38 +775,38 @@ case VALGRIND::ERROR_LIMIT: case VALGRIND::DB_ATTACH: case VALGRIND::DB_COMMAND: - if ( defVal != cfgVal ) { - // disabled for now: /* gui options not disabled: other tools use these options */ - if ( tool_obj->name() == "memcheck") { - /* memcheck presets/ignores these options for xml output - - ignore these opts - - see valgrind/docs/internals/xml_output.txt */ - } else { - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + if ( tool_obj->objectName() == "memcheck") { + // ignore these opts + } else { + if ( defVal != cfgVal ) { + modFlags << "--" + opt->longFlag + "=" + cfgVal; } } break; - /* all tools use an internal logging option, - all logging options should therefore not be used */ + // all tools use an internal logging option, + // so logging options should not be used case VALGRIND::LOG_FILE: case VALGRIND::LOG_FD: case VALGRIND::LOG_SOCKET: - /* ignore these opts */ + // ignore these opts break; + // default: add --option=value default: if ( defVal != cfgVal ) { - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + modFlags << "--" + opt->longFlag + "=" + cfgVal; } break; } } + // Collect non-default tool flags: + modFlags += tool_obj->getVgFlags(); + return modFlags; } -#endif /*! Register tools Modified: branches/valkyrie_qt4port/objects/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-02-28 13:33:46 UTC (rev 477) @@ -80,10 +80,8 @@ Valgrind(); ~Valgrind(); -#if 0 - /* returns a list of non-default flags to pass to valgrind */ - QStringList modifiedVgFlags( const ToolObject* tool_obj ); -#endif + QStringList getVgFlags( ToolObject* tool_obj ); + unsigned int maxOptId() { return VALGRIND::NUM_OPTS; } int checkOptArg( int optid, QString& argval ); Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -26,6 +26,7 @@ #include "utils/vk_utils.h" #include <QFile> +#include <QPoint> #include <QStringList> @@ -62,8 +63,6 @@ } - - /*! Setup the options for this object. */ @@ -91,8 +90,8 @@ 'v', "", "", + PACKAGE_VERSION, "", - "", "display version information and exit", urlNone, VkOPT::ARG_NONE, @@ -151,7 +150,7 @@ '\0', "", "true|false", - "true", + "false", "Show toolbar text labels", "", urlValkyrie::toolLabels, @@ -340,55 +339,118 @@ VkOPT::NOT_POPT, VkOPT::WDG_LEDIT ); -} + options.addOpt( + VALKYRIE::VIEW_LOG, + this->objectName(), + "view-log", + 'v', + "<file>", + "", + "", + "", + "parse and view a valgrind logfile", + urlNone, + VkOPT::ARG_STRING, + VkOPT::WDG_NONE + ); -void Valkyrie::setConfigDefaults() -{ - vkConfig->beginGroup( this->objectName() ); - OptionHash opts = options.getOptionHash(); - for ( Iter_OptionHash it = opts.begin(); it != opts.end(); ++it ) { - VkOption* opt = it.value(); + // Internal configuration + options.addOpt( + VALKYRIE::MW_SIZE, this->objectName(), "mainwindow_size", + '\0', "", "", QSize(600, 600), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); - /* Don't create config entries for these options: - They don't hold persistent data, and have no associated option widget */ - if (opt->optid == VALKYRIE::HELP ) continue; - if (opt->optid == VALKYRIE::VGHELP ) continue; + options.addOpt( + VALKYRIE::MW_POS, this->objectName(), "mainwindow_pos", + '\0', "", "", QPoint(400, 0), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); - vkConfig->setValue( opt->longFlag, opt->dfltValue ); - } + options.addOpt( + VALKYRIE::HB_HIST, this->objectName(), "handbook_history", + '\0', "", "", "", "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); - vkConfig->endGroup(); + options.addOpt( + VALKYRIE::HB_BKMK, this->objectName(), "handbook_bookmarks", + '\0', "", "", "", "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); + options.addOpt( + VALKYRIE::HB_MXHIST, this->objectName(), "handbook_max_history", + '\0', "", "", "20", "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); - // Colour Defaults - vkConfig->beginGroup( this->objectName() + "_colours" ); - vkConfig->setValue( "background", QColor(214,205,187) ); - vkConfig->setValue( "base", QColor(255,255,255) ); - vkConfig->setValue( "dkgray", QColor(128,128,128) ); - vkConfig->setValue( "editColor", QColor(254,222,190) ); - vkConfig->setValue( "highlight", QColor(147, 40, 40) ); - vkConfig->setValue( "nullColor", QColor(239,227,211) ); - vkConfig->setValue( "text", QColor(0, 0, 0) ); - vkConfig->endGroup(); + options.addOpt( + VALKYRIE::HB_MXBKMK, this->objectName(), "handbook_max_bookmarks", + '\0', "", "", "20", "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); - // MainWindow Defaults - vkConfig->beginGroup( this->objectName() + "_mainwindow" ); - vkConfig->setValue( "size", QSize(600, 600) ); - vkConfig->setValue( "pos", QPoint(400, 0) ); - vkConfig->endGroup(); + options.addOpt( + VALKYRIE::COL_BKGD, this->objectName(), "colour_background", + '\0', "", "", QColor(214,205,187), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); - // Handbook defaults - vkConfig->beginGroup( this->objectName() + "_handbook" ); - vkConfig->setValue( "max_bookmarks", "20" ); - vkConfig->setValue( "max_history", "20" ); - vkConfig->endGroup(); + options.addOpt( + VALKYRIE::COL_BASE, this->objectName(), "colour_base", + '\0', "", "", QColor(255,255,255), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); + + options.addOpt( + VALKYRIE::COL_DKGR, this->objectName(), "colour_dkgray", + '\0', "", "", QColor(128,128,128), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); + + options.addOpt( + VALKYRIE::COL_EDIT, this->objectName(), "colour_edit", + '\0', "", "", QColor(254,222,190), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); + + options.addOpt( + VALKYRIE::COL_HILT, this->objectName(), "colour_highlight", + '\0', "", "", QColor(147, 40, 40), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); + + options.addOpt( + VALKYRIE::COL_NULL, this->objectName(), "colour_null", + '\0', "", "", QColor(239,227,211), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); + + options.addOpt( + VALKYRIE::COL_TEXT, this->objectName(), "colour_text", + '\0', "", "", QColor( 0, 0, 0), "", "", + urlNone, VkOPT::NOT_POPT, VkOPT::WDG_NONE + ); } +void Valkyrie::setConfigDefaults() +{ + foreach( VkOption* opt, options.getOptionHash() ) { + // Don't create config entries for these options: + // - They don't hold persistent data, and have no associated option widget + if (opt->optid == VALKYRIE::HELP ) continue; + if (opt->optid == VALKYRIE::VGHELP ) continue; + opt->updateConfig( opt->dfltValue ); + } + } + + /*! Check \a argval for the option given by \a optGrp and \a optid. The \a argval may be updated. @@ -441,7 +503,7 @@ if ( !QFile::exists( proj_filename ) ) { vkConfig->createNewProject( proj_filename ); } else { - vkConfig->openProject( proj_filename ); + vkConfig->openProject( this, proj_filename ); } } @@ -486,11 +548,25 @@ } break; case VALKYRIE::SRC_EDITOR: { - QString ed_file = QStringList::split(" ", argval).first(); + QString ed_file = QStringList::split(" ", argval).first(); //, QString::SkipEmptyParts QString ed = binaryCheck( &errval, ed_file ); argval.replace( ed_file, ed ); } break; +#if 0 //TODO: return ok, but give warning. + + // if no "%n", give warning + if ( argval.indexOf( "%n" ) == -1 ) { + QFileInfo fi( argval.split(" ", QString::SkipEmptyParts).first() ); + if ( !fi.fileName().startsWith("emacs") && !fi.fileName().startsWith("nedit") ) { + vkInfo( this, "Unknown Source Editor", + "If possible, set an editor flag to allow the \ + editor to be opened at a target line-number, \ + where %%n will be replaced with the line-number." ); + } + } +#endif + case VALKYRIE::PROJ_FILE: { #if 0 // TODO: review this @@ -583,12 +659,39 @@ } +/*! + Find the option owner, find option within that owner. + Called from VkConfig::readFromConfigFile(...) + Warning: slow! +*/ +VkOption* Valkyrie::findOption( QString& optKey ) +{ + QStringList parts = optKey.split( "/", QString::SkipEmptyParts ); + vk_assert( parts.count() == 2 ); + QString optGrp = parts.at(0); + QString optFlag = parts.at(1); + VkObjectList objList = this->vkObjList(); + for (int i = 0; i < objList.size(); ++i) { + VkObject* obj = objList.at(i); + if ( obj->objectName() == optGrp ) { + foreach( VkOption* opt, obj->getOptions() ) { + if ( opt->longFlag == optFlag ) { + return opt; + } + } + } + } + return NULL; +} + + +#if 0 /*! Find the option owner, find option within that owner. */ -VkOption* Valkyrie::findOption( QString optGrp, int optid ) +VkOption* Valkyrie::findOption( QString& optGrp, int optid ) { VkObjectList objList = this->vkObjList(); for (int i = 0; i < objList.size(); ++i) { @@ -600,8 +703,10 @@ } return NULL; } +#endif + /*! Return list of all VkObjects */ @@ -649,36 +754,52 @@ ToolObject* activeTool = valgrind()->getToolObj( tId ); vk_assert( activeTool != 0 ); + QStringList vg_flags = getVgFlags( tId ); + return activeTool->start( procId, vg_flags ); } /*! - Update flags for current tool - Called by MainWindow::updateVgFlags() - - which is triggered by optionsWin::flagsChanged signal + Returns valgrind flags for given tool */ -void Valkyrie::updateVgFlags( VGTOOL::ToolID tId ) +QStringList Valkyrie::getVgFlags( VGTOOL::ToolID tId ) { -cerr << "Valkyrie::updateVgFlags( " << tId << ")" << endl; - vk_assert( tId != VGTOOL::ID_NULL ); ToolObject* tool = valgrind()->getToolObj( tId ); vk_assert( tool != 0 ); - QString vg_exec = vkConfig->value( "valkyrie/vg-exec" ).toString(); - if (vg_exec.isEmpty()) - vg_exec = "valgrind"; // hope it's in $PATH + // if we don't find it in config, let's hope it's in $PATH + VkOption* opt = options.getOption( VALKYRIE::VG_EXEC ); + QString vg_exec = vkConfig->value( opt->configKey(), "valgrind" ).toString(); - // modifiedVgFlags() functions return non-default flags - vg_flags.clear(); - vg_flags << vg_exec; // path/to/valgrind - vg_flags << "--tool=" + tool->objectName(); // tool + QStringList vg_flags; + vg_flags << vg_exec; // path/to/valgrind + vg_flags << "--tool=" + tool->objectName(); // active tool (!= valgrind()->TOOL) + vg_flags += valgrind()->getVgFlags( tool ); // valgrind (+ tool) opts + vg_flags += getTargetFlags(); // valkyrie opts -//TODO: - vg_flags << "ls"; -// vg_flags += valgrind()->modifiedVgFlags( tool ); // valgrind opts -// vg_flags += tool->modifiedVgFlags(); // tool opts -// vg_flags += this->modifiedVgFlags(); // valkyrie opts + return vg_flags; } + +/*! + Returns valgrind flags for given tool +*/ +QStringList Valkyrie::getTargetFlags() +{ + QStringList modFlags; + VkOption* opt = options.getOption( VALKYRIE::BINARY ); + QString cfgVal = vkConfig->value( opt->configKey() ).toString(); + + // only add binary & bin_flags if binary present + if ( !cfgVal.isEmpty() ) { + modFlags << cfgVal; + + // add any target binary flags + opt = options.getOption( VALKYRIE::BIN_FLAGS ); + cfgVal = vkConfig->value( opt->configKey() ).toString(); + modFlags += cfgVal.split( " ", QString::SkipEmptyParts ); + } + return modFlags; +} Modified: branches/valkyrie_qt4port/objects/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-02-28 13:33:46 UTC (rev 477) @@ -24,6 +24,7 @@ #include "objects/valgrind_object.h" #include "objects/vk_objects.h" + // ============================================================ namespace VALKYRIE { /*! @@ -48,6 +49,20 @@ VG_EXEC, // path to valgrind executable BINARY, // user-binary to be valgrindised BIN_FLAGS, // flags for user-binary + VIEW_LOG, + MW_SIZE, + MW_POS, + HB_HIST, + HB_BKMK, + HB_MXHIST, + HB_MXBKMK, + COL_BKGD, + COL_BASE, + COL_DKGR, + COL_EDIT, + COL_HILT, + COL_NULL, + COL_TEXT, NUM_OPTS }; } @@ -69,7 +84,6 @@ #if 0 // TODO bool queryToolDone( int tId ); #endif - void updateVgFlags( VGTOOL::ToolID tId ); unsigned int maxOptId() { return VALKYRIE::NUM_OPTS; } @@ -88,18 +102,20 @@ - VkOption* findOption( QString optGrp, int optid ); + VkOption* findOption( QString& optKey ); +// VkOption* findOption( QString& optGrp, int optid ); // list of all objects const VkObjectList vkObjList(); // VkObject* vkObject( int objId ); private: + QStringList getVgFlags( VGTOOL::ToolID tId ); + QStringList getTargetFlags(); void setupOptions(); private: Valgrind* m_valgrind; - QStringList vg_flags; }; Modified: branches/valkyrie_qt4port/objects/vk_objects.cpp =================================================================== --- branches/valkyrie_qt4port/objects/vk_objects.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/vk_objects.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -72,7 +72,7 @@ VkOption* opt = getOption( optid ); vk_assert( opt != NULL ); - vkConfig->setValue( opt->configKey(), argval ); + opt->updateConfig( argval ); } @@ -82,15 +82,7 @@ */ void VkObject::setConfigDefaults() { - vkConfig->beginGroup( this->objectName() ); - - OptionHash opts = options.getOptionHash(); - for ( Iter_OptionHash it = opts.begin(); it != opts.end(); ++it ) { - VkOption* opt = it.value(); - QString config_key = opt->longFlag; - QString config_value = opt->dfltValue; - vkConfig->setValue( config_key, config_value ); - } - - vkConfig->endGroup(); + foreach( VkOption* opt, options.getOptionHash() ) { + opt->updateConfig( opt->dfltValue ); + } } Modified: branches/valkyrie_qt4port/objects/vk_objects.h =================================================================== --- branches/valkyrie_qt4port/objects/vk_objects.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/objects/vk_objects.h 2010-02-28 13:33:46 UTC (rev 477) @@ -47,7 +47,7 @@ virtual unsigned int maxOptId() = 0; - /*! check argval for this option, updating if necessary. + /*! check argval for given option (updating argval if necessary). called by parseCmdArgs() and gui option pages */ virtual int checkOptArg( int optid, QString& argval ) = 0; Modified: branches/valkyrie_qt4port/options/helgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/helgrind_options_page.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/options/helgrind_options_page.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -71,14 +71,3 @@ // sanity checks vk_assert( m_itemList.count() <= HELGRIND::NUM_OPTS ); } - - - - -/*! - called when user clicks "Apply" / "Ok" / "Reset" buttons. -*/ -void HelgrindOptionsPage::applyOption( int ) {} - - - Modified: branches/valkyrie_qt4port/options/helgrind_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/helgrind_options_page.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/options/helgrind_options_page.h 2010-02-28 13:33:46 UTC (rev 477) @@ -32,7 +32,6 @@ public: HelgrindOptionsPage( VkObject* obj ); - void applyOption( int optId ); private: void setupOptions(); Modified: branches/valkyrie_qt4port/options/memcheck_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/memcheck_options_page.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/options/memcheck_options_page.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -113,25 +113,3 @@ // sanity checks vk_assert( m_itemList.count() <= MEMCHECK::NUM_OPTS ); } - - - - -/*! - called when user clicks "Apply" / "Ok" / "Reset" buttons. -*/ -void MemcheckOptionsPage::applyOption( int optId ) -{ - vk_assert( optId >= 0 && optId < MEMCHECK::NUM_OPTS ); - -// QString argval = m_itemList[optId]->currValue(); - - /* apply option */ - switch ( optId ) { - default: - break; - } -} - - - Modified: branches/valkyrie_qt4port/options/memcheck_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/memcheck_options_page.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/options/memcheck_options_page.h 2010-02-28 13:33:46 UTC (rev 477) @@ -32,7 +32,6 @@ public: MemcheckOptionsPage( VkObject* obj ); - void applyOption( int optId ); private: void setupOptions(); Modified: branches/valkyrie_qt4port/options/valgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-02-28 13:33:46 UTC (rev 477) @@ -298,9 +298,9 @@ - update suppDirs, suppsAvail from each path in lbSel */ QChar sep = vkConfig->vkSepChar; LbWidget* lbSel = (LbWidget*)m_itemList[Valgrind::SUPPS_SEL ]; - QStringList currSupps = QStringList::split( sep, lbSel->currValue() ); + QStringList currSupps = QStringList::split( sep, lbSel->currValue() ); //, QString::SkipEmptyParts LbWidget* lbDirs = (LbWidget*)m_itemList[Valgrind::SUPPS_DIRS]; - QStringList suppDirs = QStringList::split( sep, lbDirs->currValue() ); + QStringList suppDirs = QStringList::split( sep, lbDirs->currValue() ); //, QString::SkipEmptyParts for ( unsigned int i=0; i<currSupps.count(); i++ ) { QFileInfo fi( currSupps[i] ); @@ -318,23 +318,7 @@ } #endif -/* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ -void ValgrindOptionsPage::applyOption( int optId ) -{ - vk_assert( optId >= 0 && optId < VALGRIND::NUM_OPTS ); -#if 0 -// QString argval = m_itemList[optId]->currValue(); - - /* apply option */ - switch ( optId ) { - default: - break; - } -#endif -} - - void ValgrindOptionsPage::getDbBin() { vkPrintErr("TODO: ValgrindOptionsPage::getDbBin()\n"); @@ -352,7 +336,7 @@ QChar sep = vkConfig->vkSepChar; /* Get list of dirs from "valgrind::supps-dirs" */ - QStringList suppDirs = lbDirs->currValue().split( sep ); + QStringList suppDirs = lbDirs->currValue().split( sep, QString::SkipEmptyParts ); for ( int i=0; i<suppDirs.count(); i++ ) { /* for each suppDir, find all supp files */ @@ -378,7 +362,7 @@ LbWidget* lbAvail = (LbWidget*)m_itemList[VALGRIND::SUPPS_AVAIL]; LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL ]; QStringList suppsAvail = m_allAvailSuppFiles; - QStringList currSupps = lbSel->currValue().split( sep ); + QStringList currSupps = lbSel->currValue().split( sep, QString::SkipEmptyParts ); for ( int i=0; i<currSupps.count(); i++ ) { int idx = suppsAvail.indexOf( currSupps[i] ); Modified: branches/valkyrie_qt4port/options/valgrind_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.h 2010-02-13 00:27:22 UTC (rev 476) +++ branches/valkyrie_qt4port/options/valgrind_options_page.h 2010-02-28 13:33:46 UTC (re... [truncated message content] |
From: <sv...@va...> - 2010-02-13 01:06:20
|
Author: cerion Date: 2010-02-13 00:27:22 +0000 (Sat, 13 Feb 2010) New Revision: 476 Log: straightened out vkConfig. Modified: branches/valkyrie_qt4port/help/help_handbook.cpp branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/utils/vk_config.cpp branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h Modified: branches/valkyrie_qt4port/help/help_handbook.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/help/help_handbook.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -494,8 +494,8 @@ void HandBook::readHistory() { bool ok = false; - max_history = vkConfig->value( "handbook/max_history", 20 ).toInt( &ok ); - if (!ok) cerr << "Error: bad value for config::handbook/max_history" << endl; + max_history = vkConfig->value( "valkyrie_handbook/max_history", 20 ).toInt( &ok ); + if (!ok) cerr << "Error: bad value for config::valkyrie_handbook/max_history" << endl; // TODO: do this via vkConfig! #if 0 @@ -537,8 +537,8 @@ void HandBook::readBookmarks() { bool ok = false; - max_bookmarks = vkConfig->value( "handbook/max_bookmarks", 20 ).toInt(&ok); - if (!ok) cerr << "Error: bad value for config::handbook/max_bookmarks" << endl; + max_bookmarks = vkConfig->value( "valkyrie_handbook/max_bookmarks", 20 ).toInt(&ok); + if (!ok) cerr << "Error: bad value for config::valkyrie_handbook/max_bookmarks" << endl; // TODO: do this via vkConfig! #if 0 Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/main.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - the program entry point ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -21,15 +21,15 @@ #include <QApplication> +#include "mainwindow.h" #include "objects/valkyrie_object.h" +#include "options/vk_parse_cmdline.h" #include "toolview/toolview.h" -#include "mainwindow.h" - +#include "utils/vk_utils.h" #include "utils/vk_config.h" -#include "options/vk_parse_cmdline.h" -VkConfig* vkConfig = 0; +VkConfig* vkConfig = NULL; @@ -58,17 +58,12 @@ QCoreApplication::setOrganizationName("OpenWorks"); QCoreApplication::setOrganizationDomain("openworks.co.uk"); QCoreApplication::setApplicationName("Valkyrie"); - QString tmp_cfg = VkConfig::vkCfgMakeTempFilename(); - if ( tmp_cfg.isNull() ) { - // TODO: workout what really happens to QSettings. - cerr << "Error: no tmpfile for working config. No guarantees from here!" << endl; + + VkConfig::createConfig( &valkyrie, &vkConfig ); + if ( vkConfig == NULL ) { + VK_DEBUG("Failed to initialise config properly: Aborting" ); + goto cleanup_and_exit; } - vkConfig = new VkConfig( tmp_cfg ); - bool ok = vkConfig->initCfg( &valkyrie ); - if ( !ok ) { - // TODO: deal with this nicely. - cerr << "Error: config not initialised properly: No guarantees from here!" << endl; - } // ------------------------------------------------------------ Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - the top-level application window ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -101,8 +101,8 @@ delete toolViewStack; // Save window position to config. - vkConfig->setValue( "mainwindow/size", size() ); - vkConfig->setValue( "mainwindow/pos", pos() ); + vkConfig->setValue( "valkyrie_mainwindow/size", size() ); + vkConfig->setValue( "valkyrie_mainwindow/pos", pos() ); vkConfig->sync(); // handbook has no parent, so have to delete it. @@ -142,8 +142,8 @@ */ void MainWindow::setupLayout() { - resize( vkConfig->value( "mainwindow/size", QSize(600, 600)).toSize()); - move( vkConfig->value( "mainwindow/pos", QPoint(400, 0)).toPoint()); + resize( vkConfig->value( "valkyrie_mainwindow/size", QSize(600, 600)).toSize()); + move( vkConfig->value( "valkyrie_mainwindow/pos", QPoint(400, 0)).toPoint()); toolViewStack = new ToolViewStack( this ); setCentralWidget( toolViewStack ); Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -454,8 +454,7 @@ */ bool Memcheck::runValgrind( QStringList vgflags ) { -//TODO: saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + "mc_log", "xml" ); - saveFname = "./mc_log.xml"; + saveFname = vk_mkstemp( QString( VkConfig::vkTmpDir() ) + "mc_log", "xml" ); vk_assert( !saveFname.isEmpty() ); vgflags.insert( ++(vgflags.begin()), ("--log-file=" + saveFname) ); @@ -548,7 +547,7 @@ QString fname_logList = vkConfig->rdEntry( "merge", "valkyrie" ); statusMsg( "Merging logs in file-list", fname_logList ); - saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + saveFname = vk_mkstemp( QString( VkConfig::vkTmpDir() ) + "mc_merged", "xml" ); vk_assert( !saveFname.isEmpty() ); Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - Valgrind-specific: options / flags / functionality ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -384,8 +384,6 @@ // ------------------------------------------------------------ - // Can't access vkConfig->suppDir(): config created after us! - QString defSuppDir = QDir::homePath() + "/" + QString(VK_CFG_GLBL_DIR) + VK_SUPPS_DIR; /* list of dirs holding suppression files */ options.addOpt( VALGRIND::SUPPS_DIRS, @@ -394,7 +392,7 @@ '\0', "", "", - defSuppDir, + VkConfig::vkSuppsDir(), "Suppression Dirs:", "", urlValkyrie::suppsTab, Modified: branches/valkyrie_qt4port/objects/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.h 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - Valgrind-specific: options / flags / functionality ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - Valkyrie-specific: options / flags / functionality ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -256,7 +256,7 @@ '\0', "", "", - get_VK_LOGS_DIR(), + VkConfig::vkTmpDir(), "Log Dir:", "", urlValkyrie::logDir, @@ -361,6 +361,30 @@ } vkConfig->endGroup(); + + + // Colour Defaults + vkConfig->beginGroup( this->objectName() + "_colours" ); + vkConfig->setValue( "background", QColor(214,205,187) ); + vkConfig->setValue( "base", QColor(255,255,255) ); + vkConfig->setValue( "dkgray", QColor(128,128,128) ); + vkConfig->setValue( "editColor", QColor(254,222,190) ); + vkConfig->setValue( "highlight", QColor(147, 40, 40) ); + vkConfig->setValue( "nullColor", QColor(239,227,211) ); + vkConfig->setValue( "text", QColor(0, 0, 0) ); + vkConfig->endGroup(); + + // MainWindow Defaults + vkConfig->beginGroup( this->objectName() + "_mainwindow" ); + vkConfig->setValue( "size", QSize(600, 600) ); + vkConfig->setValue( "pos", QPoint(400, 0) ); + vkConfig->endGroup(); + + // Handbook defaults + vkConfig->beginGroup( this->objectName() + "_handbook" ); + vkConfig->setValue( "max_bookmarks", "20" ); + vkConfig->setValue( "max_history", "20" ); + vkConfig->endGroup(); } Modified: branches/valkyrie_qt4port/objects/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - Valkyrie-specific: options / flags / functionality ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. Modified: branches/valkyrie_qt4port/utils/vk_config.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vk_config.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/utils/vk_config.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - Configuration ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -34,6 +34,8 @@ #include <qstylefactory.h> /* vkStyle() */ #endif +#include <pwd.h> // getpwuid + #include <iostream> using namespace std; @@ -89,16 +91,45 @@ } -bool VkConfig::initCfg( Valkyrie* vk ) +/*! + Create yourself: kazam! +*/ +void VkConfig::createConfig( Valkyrie* vk /*in*/, + VkConfig** new_vkConfig /*out*/ ) { + *new_vkConfig = NULL; + + // ------------------------------------------------------------ + // setup file + QString cfgTmpDir = VkConfig::vkTmpDir(); + QDir dir; + if ( ! dir.exists( cfgTmpDir ) ) { + if ( ! dir.mkpath( cfgTmpDir ) ) { + VK_DEBUG( "Failed to create tmpdir: '%s'.", qPrintable( cfgTmpDir ) ); + return; + } + } + QString cfgTmpPath = cfgTmpDir + "/" + VK_CFG_TEMP; + QString working_cfgfile = vk_mkstemp( cfgTmpPath, VK_CFG_EXT ); + + if ( working_cfgfile.isNull() ) { + VK_DEBUG( "failed to create tempfile for working cfg: '%s'", + qPrintable( working_cfgfile ) ); + return; + } + + // ------------------------------------------------------------ + // Create new config: + *new_vkConfig = new VkConfig( working_cfgfile ); + // 1) Check Global config file exists: if not, create one from compiled defailts. if ( ! QFile::exists( vkCfgGlblFilename() ) ) { - writeConfigDefaults( vk ); + (*new_vkConfig)->writeConfigDefaults( vk ); } // 2) Read global config file into RUNTIME settings // check at least owner read/write perms ok - QFile::Permissions perms = QFile::permissions( vkCfgGlblFilename() ); + QFile::Permissions perms = QFile::permissions( VkConfig::vkCfgGlblFilename() ); if ( ( perms & QFile::WriteOwner ) != QFile::WriteOwner || ( perms & QFile::ReadOwner ) != QFile::ReadOwner ) { //TODO @@ -106,8 +137,8 @@ } else { // first clear all current settings, then read in global - this->clear(); - readFromGlblConfigFile(); + (*new_vkConfig)->clear(); + (*new_vkConfig)->readFromGlblConfigFile(); } // 3) If given a Project file on the command line, read and update 'working' config @@ -123,7 +154,6 @@ "config dir '%s', and its files/sub-directories.</p>", m_rcPath.latin1() ); */ - return true; } @@ -429,25 +459,10 @@ /* Create the default global configuration file. ----------------------------- The first time valkyrie is started, vkConfig looks to see if this file is present in the user's home dir. If not, it writes the - relevant data to ~/.PACKAGE/PACKAGErc */ + relevant data to the (user) global configuration file */ void VkConfig::writeConfigDefaults( Valkyrie* vk ) { - // TODO: GET THESE DEFAULTS FROM VK OPTS - - // Colour Defaults - setValue( "colors/background", "214,205,187" ); - setValue( "colors/base", "255,255,255" ); - setValue( "colors/dkgray", "128,128,128" ); - setValue( "colors/editColor", "254,222,190" ); - setValue( "colors/highlight", "147, 40, 40" ); - setValue( "colors/nullColor", "239,227,211" ); - setValue( "colors/text", "0, 0, 0" ); - - // MainWindow Defaults - setValue( "mainwindow/size", QSize(600, 600) ); - setValue( "mainwindow/pos", QPoint(400, 0) ); - - /* Call each object and have it set its config defaults. */ + // Call each object and have it set its config defaults. VkObjectList vkObjectList = vk->vkObjList(); for ( int i = 0; i < vkObjectList.size(); ++i ) { VkObject* obj = vkObjectList.at(i); @@ -461,11 +476,6 @@ // setValue( "valgrind/supps-dirs", suppDir() ); - // Handbook defaults - setValue( "handbook/max_bookmarks", "20" ); - setValue( "handbook/max_history", "20" ); - - // Working config is now the installation default. // Save to GLBL config file saveToGlblConfigFile(); @@ -473,46 +483,8 @@ #if 0 -/* Create the default global configuration file. ----------------------------- - The first time valkyrie is started, vkConfig looks to see if this - file is present in the user's home dir. If not, it writes the - relevant data to ~/.PACKAGE/PACKAGErc */ -bool VkConfig::writeConfigDefaults( Valkyrie* vk ) -{ - QString default_config = mkConfigDefaults( vk ); - QTextStream strm( &default_config, IO_ReadOnly ); - EntryMap rcMap = parseConfigToMap( strm ); - - /* Set valkyrie version: used for rc upgrading */ - rcMap[ EntryKey( "valkyrie", "version" ) ].mValue - = PACKAGE_VERSION; - - /* Set our 'configured' valgrind paths, if we have them */ - { - rcMap[ EntryKey( "valkyrie", "merge-exec" ) ].mValue - = BIN_LOGMERGE; - - rcMap[ EntryKey( "valkyrie", "vg-exec" ) ].mValue - = BIN_VALGRIND; - - rcMap[ EntryKey( "valgrind", "suppressions" )].mValue - = ""; - - rcMap[ EntryKey( "valgrind", "supps-dirs" ) ].mValue - = suppDir(); - } - - /* write out new config */ - if ( !writeConfig( rcMap, true ) ) { - VK_DEBUG( "failed to write default config file" ); - return false; - } - return true; -} - - /* check rc file or dir exists, is read & writeable */ -bool VkConfig::checkRCEntry( QString path, Valkyrie* vk) +bool VkConfig::checkRCEntry( QString path, Valkyrie* vk ) { QFileInfo fi( path ); if ( !fi.exists() ) { @@ -600,15 +572,15 @@ /* run through rc entries, checking existence/permissions and creating them if necessary */ for ( it = entries.begin(); it != entries.end(); ++it) { - if (!checkRCEntry(*it, vk)) { + if ( !checkRCEntry(*it, vk) ) { return false; } } - /* Further, check for temporary log dir (VK_LOGS_DIRP + username), + /* Further, check for temporary log dir (VK_TMP_DIR + username), make if !exists */ - if ( !QFile::exists( get_VK_LOGS_DIR() ) ) { - if ( !checkRCEntry( get_VK_LOGS_DIR(), vk) ) { + if ( !QFile::exists( VkConfig::vkTmpDir() ) ) { + if ( !checkRCEntry( VkConfig::vkTmpDir(), vk) ) { return false; } } @@ -629,24 +601,39 @@ } -// static util functions -QString VkConfig::vkCfgTempFilenameBegin() + +/*! + Get the log directory associated with this user + Just do this once, and cache the results. +*/ +QString VkConfig::vkTmpDir() { - return QString(VK_CFG_TMP_DIR) + "/" + QString(VK_CFG_TEMP); + static QString res = QString::null; + if ( res.isNull() ) { + pid_t me = getuid(); + struct passwd* pw = getpwuid( me ); + vk_assert( pw ); + + res = QString( VK_TMP_DIR ) + QString( pw->pw_name ) + "/"; + vk_assert( !res.isNull() ); + } + return res; } + + + + +// static util functions QString VkConfig::vkCfgGlblFilename() { - return QDir::homePath() + "/" + QString(VK_CFG_GLBL_DIR) + "/" + - QString(VK_CFG_GLBL) + "." + QString(VK_CFG_EXT); + return QDir::homePath() + "/" + VK_CFG_GLBL_DIR + + "/" + QString(VK_CFG_GLBL) + "." + QString(VK_CFG_EXT); } -QString VkConfig::vkCfgMakeTempFilename() -{ - return vk_mkstemp( VK_CFG_TEMP, VK_CFG_EXT ); -} - QString VkConfig::vkSuppsDir() { - return QString(VK_CFG_GLBL_DIR) + "/" + VK_SUPPS_DIR; + return QDir::homePath() + "/" + VK_CFG_GLBL_DIR + + "/" + QString(VK_SUPPS_DIR); } + Modified: branches/valkyrie_qt4port/utils/vk_config.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_config.h 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/utils/vk_config.h 2010-02-13 00:27:22 UTC (rev 476) @@ -3,7 +3,7 @@ ** - Configuration ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -39,13 +39,19 @@ // ============================================================ -#define VK_CFG_TMP_DIR "." -#define VK_CFG_TEMP "cfg_valkyrie_TEMP" // temporary location for 'working' config -#define VK_CFG_GLBL_DIR ".valkyrie" -#define VK_CFG_GLBL "cfg_valkyrie_GLBL" // static location per user -#define VK_CFG_EXT "vk" // valkyrie configuration extension +// Globally available object +class VkConfig; +extern VkConfig* vkConfig; +// ============================================================ +#define VK_TMP_DIR "/tmp/valkyrie_" // temp vk directory. Completed by vkTmpDir() + +#define VK_CFG_TEMP "valkyrie_temp" // temp cfg fname (for the 'working' config) +#define VK_CFG_GLBL_DIR ".valkyrie" // global (user) cfg/data directory +#define VK_CFG_GLBL "valkyrie_global" // global (user) cfg fname +#define VK_CFG_EXT "conf" // valkyrie config file extension + #define PACKAGE "valkyrie" #define PACKAGE_VERSION "2.0.0-SVN" #define PACKAGE_STRING "Valkyrie 1.4.0" @@ -55,7 +61,6 @@ #define VK_DOC_PATH "/doc/" #define VK_DBASE_DIR "dbase/" #define VK_SUPPS_DIR "suppressions/" -#define VK_LOGS_DIRP "/tmp/valkyrie_logs_" #define VK_BIN_VALGRIND "valgrind" #define VK_BIN_EDITOR "vi" #define VK_COPYRIGHT "(c) 2003-2010" @@ -73,7 +78,7 @@ VkConfig( QString& tmp_cfg ); ~VkConfig(); - bool initCfg( Valkyrie* vk ); + static void createConfig( Valkyrie* vk, VkConfig** cfg ); void createNewProject( QString& dir, QString& proj_name ); void createNewProject( QString proj_filename ); @@ -96,10 +101,9 @@ public: // util functions static bool strToBool( QString str ); - static QString vkCfgTempFilenameBegin(); static QString vkCfgGlblFilename(); - static QString vkCfgMakeTempFilename(); static QString vkSuppsDir(); + static QString vkTmpDir(); #if 0 QColor rdColor( const QString &pKey ); @@ -128,7 +132,6 @@ QString vkDocPath; // path to valkyrie docs dir // QString vgCopyright; - #if 0 // valkyrie cfg options -> PUT IN VK OBJECT! QString vkCfgTempPath; // path to run-specific config dir QString vkCfgTempFilePath; // filename for run-specific config @@ -138,12 +141,9 @@ QString vkCfgGlobalFilePath; // filename for global config #endif QString vkCfgProjectFilename; // hold active project filename (may be empty) + +private: + QString vkCfgTmpDir; }; - - -// ============================================================ -/* Globally available object ------------------------------------------- */ -extern VkConfig* vkConfig; - #endif Modified: branches/valkyrie_qt4port/utils/vk_utils.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vk_utils.cpp 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/utils/vk_utils.cpp 2010-02-13 00:27:22 UTC (rev 476) @@ -2,7 +2,7 @@ ** Various utility functions ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -21,7 +21,6 @@ #include "utils/vk_config.h" // vkname() #include <cstdlib> // exit, mkstemp, free/malloc, etc -#include <pwd.h> // getpwuid #include <QDateTime> #include <QFile> @@ -128,9 +127,9 @@ /* Create a unique filename, with an optional extension ---------------- */ QString vk_mkstemp( QString filepath, QString ext/*=QString::null*/ ) { - /* create tempfiles with datetime, so can sort easily if they stay around */ + // create tempfiles with datetime, so can sort easily if they stay around - QString datetime = QDateTime::currentDateTime().toString( "-yyyy.MM.dd-hh.mm.ss"); + QString datetime = QDateTime::currentDateTime().toString( "_yyyy.MM.dd_hh:mm:ss"); QString unique = filepath + datetime; if (!ext.isNull()) unique += "." + ext; @@ -152,24 +151,6 @@ } -/* Get the log directory associated with this user --------------------- */ -// Just do this once, and cache the results. -QString get_VK_LOGS_DIR () -{ - static QString res = QString::null; - if ( res.isNull() ) { - pid_t me = getuid(); - struct passwd* pw = getpwuid( me ); - /* This should never fail. Is it worth trying to continue if it - does? I don't think so. */ - vk_assert( pw ); - res = QString( VK_LOGS_DIRP ) + QString( pw->pw_name ) + "/"; - vk_assert( !res.isNull() ); - } - return res; -} - - /* Version check ------------------------------------------------------- Given version string of "major.minor.patch" (e.g. 3.3.0), hex version = (major << 16) + (minor << 8) + patch Modified: branches/valkyrie_qt4port/utils/vk_utils.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_utils.h 2010-02-13 00:03:03 UTC (rev 475) +++ branches/valkyrie_qt4port/utils/vk_utils.h 2010-02-13 00:27:22 UTC (rev 476) @@ -2,7 +2,7 @@ ** Various utility functions ** -------------------------------------------------------------------------- ** -** Copyright (C) 2000-2009, OpenWorks LLP. All rights reserved. +** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved. ** <in...@op...> ** ** This file is part of Valkyrie, a front-end for Valgrind. @@ -99,9 +99,6 @@ /* create a unique filename -------------------------------------------- */ QString vk_mkstemp( QString filepath, QString ext=QString::null ); -/* Get the log directory associated with this user --------------------- */ -QString get_VK_LOGS_DIR (); - /* "valgrind 3.0.5" --> 0x030005 --------------------------------------- */ int strVersion2hex( QString ver_str ); |
From: <sv...@va...> - 2010-02-13 00:03:14
|
Author: cerion Date: 2010-02-13 00:03:03 +0000 (Sat, 13 Feb 2010) New Revision: 475 Log: fixed help history bug: list with one entry dies. Modified: branches/valkyrie_qt4port/help/help_handbook.cpp Modified: branches/valkyrie_qt4port/help/help_handbook.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.cpp 2010-02-03 00:45:34 UTC (rev 474) +++ branches/valkyrie_qt4port/help/help_handbook.cpp 2010-02-13 00:03:03 UTC (rev 475) @@ -247,13 +247,20 @@ bool found = false; foreach( QAction* act, historyMenu->actions() ) { if ( act->text() == link ) { + historyMenu->removeAction( act ); if ( found ) { - // shouldn't ever get here, but just in case. - historyMenu->removeAction( act ); + // found more than once! + VK_DEBUG( "found double entry in historyMenu: ", qPrintable( act->text() ) ); + } else { + if ( ! historyMenu->actions().isEmpty() ) { + historyMenu->insertAction( historyMenu->actions().first(), act ); + } else { + historyMenu->addAction( act ); + } + found = true; + + // continue looking though the list, to check for double entries. } - historyMenu->removeAction( act ); - historyMenu->insertAction( historyMenu->actions().first(), act ); - found = true; } } if ( !found ) { |
From: <sv...@va...> - 2010-02-03 00:54:13
|
Author: cerion Date: 2010-02-03 00:45:34 +0000 (Wed, 03 Feb 2010) New Revision: 474 Log: simplify some enums - tool-ids, tool-processes Modified: branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/tool_object.cpp branches/valkyrie_qt4port/objects/tool_object.h branches/valkyrie_qt4port/toolview/memcheckview.cpp branches/valkyrie_qt4port/toolview/memcheckview.h branches/valkyrie_qt4port/toolview/toolview.h Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-02-03 00:45:34 UTC (rev 474) @@ -726,7 +726,7 @@ return; } - runTool( TOOL::PROC_VALGRIND ); + runTool( VGTOOL::PROC_VALGRIND ); } Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-02-03 00:45:34 UTC (rev 474) @@ -274,10 +274,10 @@ this, SLOT(fileSaveDialog()) ); // signals tool_obj --> tool_view - connect( this, SIGNAL(running(bool)), + connect( this, SIGNAL(running(bool)), toolView, SLOT(setState(bool)) ); - setProcessId( TOOL::PROC_NONE ); + setProcessId( VGTOOL::PROC_NONE ); return toolView; } @@ -359,13 +359,13 @@ { cerr << "Memcheck::start(): " << procId << endl; - vk_assert( procId > MEMCHECK_VIEW::PROC_NOPROC ); - vk_assert( procId > TOOL::PROC_NONE ); + vk_assert( procId > VGTOOL::PROC_NONE ); + vk_assert( procId < VGTOOL::PROC_MAX ); vk_assert( !isRunning() ); bool ok = false; switch ( procId ) { - case TOOL::PROC_VALGRIND: + case VGTOOL::PROC_VALGRIND: ok = runValgrind( vgflags ); break; case MEMCHECK::PROC_PARSE_LOG: @@ -396,7 +396,7 @@ logpoller->stop(); switch ( getProcessId() ) { - case TOOL::PROC_VALGRIND: { + case VGTOOL::PROC_VALGRIND: { if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) { vkPrint("Memcheck::stop(): process starting/running: terminate."); @@ -461,7 +461,7 @@ vgflags.insert( ++(vgflags.begin()), ("--log-file=" + saveFname) ); vgflags.insert( ++(vgflags.begin()), "--xml=yes" ); - setProcessId( TOOL::PROC_VALGRIND ); + setProcessId( VGTOOL::PROC_VALGRIND ); fileSaved = false; statusMsg( "Memcheck", "Running ... " ); @@ -470,7 +470,7 @@ if (!ok) { statusMsg( "Memcheck", "Failed" ); fileSaved = true; - setProcessId( TOOL::PROC_NONE ); + setProcessId( VGTOOL::PROC_NONE ); } return ok; @@ -528,7 +528,7 @@ } else { statusMsg( "Parse failed", log_file ); } - setProcessId( TOOL::PROC_NONE ); + setProcessId( VGTOOL::PROC_NONE ); return success; } @@ -685,7 +685,7 @@ runError = true; // vkPrint(" - Memcheck::processDone(): fatal error"); - if (getProcessId() == TOOL::PROC_VALGRIND) { + if (getProcessId() == VGTOOL::PROC_VALGRIND) { statusMsg( "Memcheck", "Error parsing output log" ); vkError( getToolView(), "XML Parse Error", "<p>Error parsing Valgrind XML output:<br>%s</p>", @@ -706,7 +706,7 @@ runError = true; // vkPrint(" - Memcheck::processDone(): parsing STILL not finished"); - if (getProcessId() == TOOL::PROC_VALGRIND) { + if (getProcessId() == VGTOOL::PROC_VALGRIND) { statusMsg( "Memcheck", "Error - incomplete output log" ); vkError( getToolView(), "XML Parse Error", "<p>Valgrind XML output is incomplete</p>" ); @@ -727,7 +727,7 @@ // vkPrint(" - Memcheck::processDone(): process exited ok"); } else { // vkPrint(" - Memcheck::processDone(): process failed (%d)", exitStatus); - if (getProcessId() == TOOL::PROC_VALGRIND) { + if (getProcessId() == VGTOOL::PROC_VALGRIND) { vkError( getToolView(), "Run Error", "<p>Process %s, with return value %d.<br> \ This is likely to simply be the client program \ @@ -757,7 +757,7 @@ // we're done. --------------------------------------------------- if (!runError) { // (else we've already set an status error message) - if (getProcessId() == TOOL::PROC_VALGRIND) { + if (getProcessId() == VGTOOL::PROC_VALGRIND) { statusMsg( "Memcheck", "Finished" ); } else { vk_assert_never_reached(); @@ -766,7 +766,7 @@ } } -// setProcessId( TOOL::PROC_NONE ); + setProcessId( VGTOOL::PROC_NONE ); // vkPrint("Memcheck::processDone(): DONE.\n"); } Modified: branches/valkyrie_qt4port/objects/memcheck_object.h =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.h 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-02-03 00:45:34 UTC (rev 474) @@ -51,16 +51,6 @@ ALIGNMENT, NUM_OPTS }; - - -/*! - Tools can run different processes -*/ - enum mcProcessId { - PROC_PARSE_LOG = TOOL::PROC_TOOL_NONE+1, - // Any other process id's go here. - PROC_MAX = TOOL::PROC_MAX - }; } Modified: branches/valkyrie_qt4port/objects/tool_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.cpp 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/objects/tool_object.cpp 2010-02-03 00:45:34 UTC (rev 474) @@ -37,7 +37,7 @@ */ ToolObject::ToolObject( const QString& objectName, VGTOOL::ToolID id ) : VkObject( objectName ), - toolView(0), fileSaved(true), processId(TOOL::PROC_NONE), toolId(id) + toolView(0), fileSaved(true), processId(VGTOOL::PROC_NONE), toolId(id) { } @@ -47,20 +47,19 @@ bool ToolObject::isRunning() { - return (processId > TOOL::PROC_NONE); + return (processId > VGTOOL::PROC_NONE); } /*! Set the process id. - Emits signal for subsequent state: 'running(true|false)' + Emits signal for subsequent state: 'running(true|false)' - updates toolview */ void ToolObject::setProcessId( int procId ) { - vk_assert( procId >= TOOL::PROC_NONE ); - vk_assert( procId != TOOL::PROC_TOOL_NONE ); - vk_assert( procId < TOOL::PROC_MAX); + vk_assert( procId >= VGTOOL::PROC_NONE ); + vk_assert( procId < VGTOOL::PROC_MAX); processId = procId; emit running( isRunning() ); @@ -71,9 +70,8 @@ */ int ToolObject::getProcessId() { - vk_assert( processId >= TOOL::PROC_NONE ); - vk_assert( processId != TOOL::PROC_TOOL_NONE ); - vk_assert( processId < TOOL::PROC_MAX ); + vk_assert( processId >= VGTOOL::PROC_NONE ); + vk_assert( processId < VGTOOL::PROC_MAX ); return processId; } Modified: branches/valkyrie_qt4port/objects/tool_object.h =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.h 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/objects/tool_object.h 2010-02-03 00:45:34 UTC (rev 474) @@ -34,19 +34,8 @@ #include <QList> -namespace TOOL { - // Tools may extend this enum with their own process id's. - enum toolProcessId { - PROC_NONE=-1, // no process running - PROC_VALGRIND=0, // run valgrind for given tool - PROC_TOOL_NONE=1, // tool defined proc id's start here + 1 - // tool defined processes may take up this block - PROC_MAX=4 // reasonable number of processes per tool - }; -} - // ============================================================ // forward decls class ToolView; Modified: branches/valkyrie_qt4port/toolview/memcheckview.cpp =================================================================== --- branches/valkyrie_qt4port/toolview/memcheckview.cpp 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/toolview/memcheckview.cpp 2010-02-03 00:45:34 UTC (rev 474) @@ -100,7 +100,7 @@ return; vkConfig->setValue( "valkyrie/view-log", log_file ); - emit run( MEMCHECK_VIEW::PROC_PARSE_LOGFILE ); + emit run( MEMCHECK::PROC_PARSE_LOG ); } Modified: branches/valkyrie_qt4port/toolview/memcheckview.h =================================================================== --- branches/valkyrie_qt4port/toolview/memcheckview.h 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/toolview/memcheckview.h 2010-02-03 00:45:34 UTC (rev 474) @@ -30,15 +30,13 @@ // ============================================================ -namespace MEMCHECK_VIEW { -/*! - Define the processes this tool can run -*/ - enum mcProcessId { - PROC_NOPROC = -1, - PROC_RUN_VALGRIND, - PROC_PARSE_LOGFILE, - NUM_PROCS +namespace MEMCHECK { + + // Define the processes this tool can run + enum McProcessId { + PROC_PARSE_LOG = VGTOOL::PROC_TOOL_FIRST, + // Any other process id's go here. + PROC_MAX = VGTOOL::PROC_MAX }; } Modified: branches/valkyrie_qt4port/toolview/toolview.h =================================================================== --- branches/valkyrie_qt4port/toolview/toolview.h 2010-02-03 00:34:08 UTC (rev 473) +++ branches/valkyrie_qt4port/toolview/toolview.h 2010-02-03 00:45:34 UTC (rev 474) @@ -37,11 +37,23 @@ // ============================================================ // type definitions namespace VGTOOL { - enum ToolID { ID_NULL=-1, - ID_MEMCHECK=0, - ID_HELGRIND, - NUM_TOOLS - }; + + // Valgrind Tools + enum ToolID { + ID_NULL=-1, + ID_MEMCHECK=0, + ID_HELGRIND, + ID_MAX + }; + + // Tool Processes: Tools may extend this enum with their own process id's. + enum ToolProcessId { + PROC_NONE=-1, // no process running + PROC_VALGRIND=0, // run valgrind for given tool + PROC_TOOL_FIRST=1, // tool defined proc id's start here, + // and fill this block, + PROC_MAX=4 // to a reasonable max number of processes per tool + }; } |
From: <sv...@va...> - 2010-02-03 00:44:13
|
Author: cerion Date: 2010-02-03 00:34:08 +0000 (Wed, 03 Feb 2010) New Revision: 473 Log: Sorted out the actions, and linked them up to the right signals/slots - vg & memcheck Updated some icons - if there's an iconic someone out there who wants to make this pretty, be my guest! Added: branches/valkyrie_qt4port/icons/exit.png branches/valkyrie_qt4port/icons/filenew.png branches/valkyrie_qt4port/icons/filesave.png branches/valkyrie_qt4port/icons/filesaveas.png branches/valkyrie_qt4port/icons/folder_blue.png branches/valkyrie_qt4port/icons/folder_green.png branches/valkyrie_qt4port/icons/gear.png branches/valkyrie_qt4port/icons/item_close.png branches/valkyrie_qt4port/icons/item_open.png branches/valkyrie_qt4port/icons/text_less.png branches/valkyrie_qt4port/icons/text_more.png branches/valkyrie_qt4port/icons/tree_close.png branches/valkyrie_qt4port/icons/tree_open.png branches/valkyrie_qt4port/icons/valgrind_run.png branches/valkyrie_qt4port/icons/valgrind_stop.png Removed: branches/valkyrie_qt4port/icons/memcheck_openallitems.xpm branches/valkyrie_qt4port/icons/memcheck_openitem.xpm branches/valkyrie_qt4port/icons/memcheck_openlog.xpm branches/valkyrie_qt4port/icons/memcheck_run.xpm branches/valkyrie_qt4port/icons/memcheck_savelog.xpm branches/valkyrie_qt4port/icons/memcheck_srcpath.xpm branches/valkyrie_qt4port/icons/memcheck_supp_editor.xpm branches/valkyrie_qt4port/icons/msgbox_fatal.xpm branches/valkyrie_qt4port/icons/msgbox_warn.xpm branches/valkyrie_qt4port/icons/tb_mainwin_filesave2.xpm branches/valkyrie_qt4port/icons/tb_mainwin_help2.xpm branches/valkyrie_qt4port/icons/tb_mainwin_run.xpm branches/valkyrie_qt4port/icons/tb_mainwin_stop.xpm Modified: branches/valkyrie_qt4port/icons.qrc branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/toolview/helgrindview.cpp branches/valkyrie_qt4port/toolview/helgrindview.h branches/valkyrie_qt4port/toolview/memcheckview.cpp branches/valkyrie_qt4port/toolview/memcheckview.h branches/valkyrie_qt4port/toolview/toolview.h Added: branches/valkyrie_qt4port/icons/exit.png =================================================================== --- branches/valkyrie_qt4port/icons/exit.png (rev 0) +++ branches/valkyrie_qt4port/icons/exit.png 2010-02-03 00:34:08 UTC (rev 473) @@ -0,0 +1,25 @@ +PNG + + |
From: <sv...@va...> - 2010-01-27 22:55:06
|
Author: cerion Date: 2010-01-27 22:54:53 +0000 (Wed, 27 Jan 2010) New Revision: 472 Log: Vk now supports running a valgrind process. That process' stdout/err are forwarded to vk's stdout/err respectively. However, stdin is not forwarded. If this is a problem for people, we'll deal with it then. Still needs lots of errorchecks, +++. Added: branches/valkyrie_qt4port/utils/vk_logpoller.cpp branches/valkyrie_qt4port/utils/vk_logpoller.h Modified: branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/helgrind_object.h branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/tool_object.cpp branches/valkyrie_qt4port/objects/tool_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/toolview/vglogview.cpp branches/valkyrie_qt4port/toolview/vglogview.h branches/valkyrie_qt4port/utils/vk_utils.h branches/valkyrie_qt4port/valkyrie.pro Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-27 22:54:53 UTC (rev 472) @@ -33,6 +33,7 @@ #include "help/help_context.h" #include "help/help_urls.h" #include "options/vk_option.h" +#include "objects/tool_object.h" #include "utils/vk_config.h" #include "utils/vk_messages.h" #include "utils/vk_utils.h" @@ -399,12 +400,13 @@ nextView = nextTool->createView( this ); vk_assert( nextView != 0 ); - /* TODO - connect( nextTool, SIGNAL(running(bool)), - this, SLOT(updateButtons(bool)) ); - connect( nextTool, SIGNAL(message(QString)), - this, SLOT(setStatus(QString)) ); + connect( nextTool, SIGNAL(running(bool)), + this, SLOT(updateButtons(bool)) ); +*/ + connect( nextTool, SIGNAL(message(QString)), + this, SLOT(setStatus(QString)) ); +/* TODO connect( this, SIGNAL(toolbarLabelsToggled(bool)), nextView, SLOT(toggleToolbarLabels(bool)) ); */ @@ -421,6 +423,7 @@ toolViewStack->raiseView( nextView ); setToggles( toolId ); + updateVgFlags(); } @@ -567,6 +570,27 @@ /*! + Called by this->showToolView(), + and optionsDlg::flagsChanged() signal +*/ +void MainWindow::updateVgFlags() +{ + // update valkyrie's flags: if there's a visible ToolView + if ( toolViewStack->isVisible() ) + valkyrie->updateVgFlags( toolViewStack->currentToolId() ); + +//TODO: maybe. +#if 0 + // update flags display + if ( m_flagsLabel->isVisible() ) { + showFlagsWidget( true ); + } +#endif +} + + + +/*! Calls showToolView() for a chosen valgrind tool. This slot is called by a trigger of the tool actionGroup, which is @@ -604,12 +628,16 @@ optionsDialog->activateWindow(); #else VkOptionsDialog optionsDlg( this ); + + // let the flags widget know that flags may have been modified + connect( &optionsDlg, SIGNAL(flagsChanged()), + this, SLOT(updateVgFlags()) ); + optionsDlg.exec(); #endif } - /*! Run the valgrind tool process. */ @@ -623,7 +651,7 @@ vk_assert( procId >= 0 ); // don't come in here if there's no current view - if ( toolViewStack->isVisible() == 0 ) { + if ( !toolViewStack->isVisible() ) { //This should never happen... assert? cerr << "Error: No toolview visible!" << endl; return; @@ -666,23 +694,25 @@ actProcess_Run->setEnabled( false ); actProcess_Stop->setEnabled( true ); -#if 0 - /* don't come in here if there's no current view */ - if ( m_viewStack->visible() == 0 ) + // don't come in here if there's no current view + if ( !toolViewStack->isVisible() ) return; /* valkyrie may have been started with no executable specified. if so, show prefsWindow + msgbox */ - if ( vkConfig->rdEntry("binary","valkyrie").isEmpty() ) { + if ( vkConfig->value( "valkyrie/binary").toString().isEmpty() ) { +//TODO + cerr << "Error: no binary specified!" << endl; +#if 0 showOptionsWindow( Valkyrie::ID_VALKYRIE ); - vkInfo( m_optionsWin, "Run Valgrind", + vkInfo( optionsWin, "Run Valgrind", "Please enter the path to the executable " "you wish to run, together with any arguments"); +#endif return; } - run( VkRunState::VALGRIND ); -#endif + runTool( TOOL::PROC_VALGRIND ); } Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/mainwindow.h 2010-01-27 22:54:53 UTC (rev 472) @@ -73,6 +73,7 @@ void openAboutVk(); void openAboutLicense(); void openAboutSupport(); + void updateVgFlags(); private: Valkyrie* valkyrie; Modified: branches/valkyrie_qt4port/objects/helgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/helgrind_object.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/helgrind_object.h 2010-01-27 22:54:53 UTC (rev 472) @@ -55,8 +55,10 @@ int checkOptArg( int optid, QString& argval ); VkOptionsPage* createVkOptionsPage(); - bool start( int procId, QStringList vgflags ) { return true; } + bool start( int procId, QStringList vgflags ) { return false; } void stop() {} + + bool runValgrind( QStringList vgflags ) { return false; } }; Modified: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-01-27 22:54:53 UTC (rev 472) @@ -24,29 +24,33 @@ #include "objects/valkyrie_object.h" #include "utils/vk_config.h" #include "utils/vk_messages.h" +#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc. #include "utils/vglogreader.h" #include "options/vk_option.h" // PERROR* and friends //#include "vk_file_utils.h" // FileCopy() -#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc. #include <QApplication> +#include <QDir> +#include <QTimer> +#define TIMEOUT_STOPPROC 2000 // msec until stop process +#define TIMEOUT_KILLPROC 2000 // msec until kill process (after tried to stop) + + /*! class Memcheck */ Memcheck::Memcheck() : ToolObject( "memcheck", VGTOOL::ID_MEMCHECK ) { -#if 0 /* init vars */ - m_fileSaved = true; - m_vgproc = 0; - m_vgreader = 0; - m_logpoller = new VkLogPoller( this, "memcheck logpoller" ); - connect( m_logpoller, SIGNAL(logUpdated()), + fileSaved = true; + vgproc = 0; + vgreader = 0; + logpoller = new VkLogPoller( this, "memcheck logpoller" ); + connect( logpoller, SIGNAL(logUpdated()), this, SLOT(readVgLog()) ); -#endif setupOptions(); } @@ -54,26 +58,25 @@ Memcheck::~Memcheck() { -#if 0 - if (m_vgproc) { - m_vgproc->disconnect(); /* so no signal calling processDone() */ - if (m_vgproc->isRunning()) { - m_vgproc->stop(); + if (vgproc) { + vgproc->disconnect(); // so no signal calling processDone() + if ( vgproc->state() != QProcess::NotRunning ) { + vgproc->terminate(); + //TODO: wait a short while before deleting? } - delete m_vgproc; - m_vgproc = 0; + delete vgproc; + vgproc = 0; } - if (m_vgreader) { - delete m_vgreader; - m_vgreader = 0; + if (vgreader) { + delete vgreader; + vgreader = 0; } - /* m_logpoller deleted by it's parent: 'this' */ + // logpoller deleted by it's parent: 'this' - /* unsaved log... delete our temp file */ - if (!m_fileSaved && !m_saveFname.isEmpty()) - QDir().remove( m_saveFname ); -#endif + // unsaved log... delete our temp file + if (!fileSaved && !saveFname.isEmpty()) + QDir().remove( saveFname ); } @@ -267,16 +270,16 @@ toolView = new MemcheckView( parent ); #if 0 - /* signals view --> tool */ - connect( m_view, SIGNAL(saveLogFile()), + // signals tool_view --> tool_obj + connect( toolView, SIGNAL(saveLogFile()), this, SLOT(fileSaveDialog()) ); - /* signals tool --> view */ + // signals tool_obj --> tool_view connect( this, SIGNAL(running(bool)), - m_view, SLOT(setState(bool)) ); + toolView, SLOT(setState(bool)) ); +#endif + setProcessId( TOOL::PROC_NONE ); - setRunState( VkRunState::STOPPED ); -#endif return toolView; } @@ -284,8 +287,7 @@ /* outputs a message to the status bar. */ void Memcheck::statusMsg( QString hdr, QString msg ) { -//TODO -// emit message( hdr + ": " + msg ); + emit message( hdr + ": " + msg ); } @@ -299,7 +301,7 @@ /* if current process is not yet finished, ask user if they really want to close */ if ( isRunning() ) { - int ok = vkQuery( view(), "Process Running", "&Abort;&Cancel", + int ok = vkQuery( getToolView(), "Process Running", "&Abort;&Cancel", "<p>The current process is not yet finished.</p>" "<p>Do you want to abort it ?</p>" ); /* Note: process may have finished while waiting for user */ @@ -328,8 +330,8 @@ /* currently loaded / parsed stuff is saved to tmp file - ask user if they want to save it to a 'real' file */ - if ( !m_fileSaved ) { - int ok = vkQuery( view(), "Unsaved File", + if ( !fileSaved ) { + int ok = vkQuery( getToolView(), "Unsaved File", "&Save;&Discard;&Cancel", "<p>The current output is not saved, " " and will be deleted.<br/>" @@ -345,8 +347,8 @@ } else if ( ok == MsgBox::vkCancel ) { /* procrastinate */ return false; } else { /* discard */ - QFile::remove( m_saveFname ); - m_fileSaved = true; + QFile::remove( saveFname ); + fileSaved = true; } } #endif @@ -359,20 +361,18 @@ cerr << "Memcheck::start(): " << procId << endl; vk_assert( procId > MEMCHECK_VIEW::PROC_NOPROC ); - -//TODO -// vk_assert( rs != VkRunState::STOPPED ); -// vk_assert( !isRunning() ); + vk_assert( procId > TOOL::PROC_NONE ); + vk_assert( !isRunning() ); bool ok = false; switch ( procId ) { - case MEMCHECK_VIEW::PROC_RUN_VALGRIND: + case TOOL::PROC_VALGRIND: ok = runValgrind( vgflags ); break; - case MEMCHECK_VIEW::PROC_PARSE_LOGFILE: + case MEMCHECK::PROC_PARSE_LOG: ok = parseLogFile(); break; -//TODO: maybe. +//TODO: maybe someday. // case merge: ok = mergeLogFiles(); break; default: vk_assert_never_reached(); @@ -382,47 +382,70 @@ } -/* stop a process - - doesn't exit until process stopped. - - may take some time for process to respond: too much time and it - just gets terminated. */ +/*! + Stop a process. + Try to be nice, but in case doesn't work, setup timer to guarantee it dies. +//TODO: Perhaps the view want's to hang around and wait until process is dead. but that's up to the view. +*/ void Memcheck::stop() { -#if 0 if ( !isRunning() ) return; - switch ( runState() ) { - case VkRunState::VALGRIND: { - if (m_vgproc && m_vgproc->isRunning() ) - m_vgproc->stop(); /* signal -> processDone() */ + // whatever else we do, stop trying to read from the log. + if ( logpoller ) + logpoller->stop(); + + switch ( getProcessId() ) { + case TOOL::PROC_VALGRIND: { + if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) { + vkPrint("Memcheck::stop(): process starting/running: terminate."); + + vgproc->terminate(); // if & when succeeds: signal -> processDone() + + // in case doesn't want to stop, start timer to really kill it off. + QTimer::singleShot( TIMEOUT_KILLPROC, this, SLOT( killProc() ) ); + } + else { + vkPrint("Memcheck::stop(): process was already stopped."); + } } break; - case VkRunState::TOOL1: { /* parse log */ - /* TODO: make log parsing a VkProcess. This will allow - - valkyrie to stay responsive - - the ability to interrupt the process if taking too long */ + case MEMCHECK::PROC_PARSE_LOG: { // parse log + // TODO VK_DEBUG("TODO: Memcheck::stop(parse log)" ); } break; - case VkRunState::TOOL2: { /* merge logs */ - if (m_vgproc && m_vgproc->isRunning() ) - m_vgproc->stop(); /* signal -> processDone() */ +#if 0 + case TODO: { // merge logs + if (vgproc && vgproc->isRunning() ) + vgproc->stop(); // signal -> processDone() } break; - +#endif default: vk_assert_never_reached(); } - /* spin until done */ - while ( isRunning() ) - qApp->processEvents(); -#endif - return; } +/*! + Kills a process immediately + - only called as a result of kill timer timeout +*/ +void Memcheck::killProcess() +{ + if ( vgproc && ( vgproc->state() != QProcess::NotRunning ) ) { +vkPrint("Memcheck::killProcess(): kill the process"); + vgproc->kill(); // process will die, then signal -> processDone() + } + else { +vkPrint("Memcheck::killProcess(): process already stopped."); + } +} + + /* If --vg-opt=<arg> was specified on the cmd-line, called by valkyrie->runTool(); if set via the run-button in the gui, then MainWindow::run() calls valkyrie->runTool(). @@ -431,41 +454,42 @@ */ bool Memcheck::runValgrind( QStringList vgflags ) { -#if 0 - m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) - + "mc_log", "xml" ); - vk_assert( !m_saveFname.isEmpty() ); +//TODO: saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + "mc_log", "xml" ); + saveFname = "./mc_log.xml"; + vk_assert( !saveFname.isEmpty() ); - vgflags.insert( ++(vgflags.begin()), ("--log-file=" + m_saveFname) ); + vgflags.insert( ++(vgflags.begin()), ("--log-file=" + saveFname) ); + vgflags.insert( ++(vgflags.begin()), "--xml=yes" ); - setRunState( VkRunState::VALGRIND ); - m_fileSaved = false; + setProcessId( TOOL::PROC_VALGRIND ); + fileSaved = false; statusMsg( "Memcheck", "Running ... " ); bool ok = startProcess( vgflags ); if (!ok) { statusMsg( "Memcheck", "Failed" ); - m_fileSaved = true; - setRunState( VkRunState::STOPPED ); + fileSaved = true; + setProcessId( TOOL::PROC_NONE ); } + return ok; -#endif - return true; } -/* Parse log file given by [valkyrie::view-log] entry. - Called by valkyrie->runTool() if cmdline --view-log=<file> specified. - MemcheckView::openLogFile() if gui parse-log selected. - If 'checked' == true, file perms/format has already been checked */ +/*! + Parse log file given by [valkyrie::view-log] entry. + Called by valkyrie->runTool() if cmdline --view-log=<file> specified. + MemcheckView::openLogFile() if gui parse-log selected. + If 'checked' == true, file perms/format has already been checked +*/ bool Memcheck::parseLogFile() { vk_assert( getToolView() != 0 ); //TODO: pass this via flags from the toolview, or something. QString log_file = vkConfig->value( "valkyrie/view-log" ).toString(); -// statusMsg( "Parsing", log_file ); + statusMsg( "Parsing", log_file ); //TODO: file checks #if 0 @@ -473,7 +497,7 @@ int errval = PARSED_OK; QString ret_file = fileCheck( &errval, log_file, true, false ); if ( errval != PARSED_OK ) { - vkError( view(), "File Error", "%s: \n\"%s\"", + vkError( getToolView(), "File Error", "%s: \n\"%s\"", parseErrString(errval), escapeEntities(log_file).latin1() ); return false; @@ -482,8 +506,8 @@ #endif // fileSaved true, 'cos we're just parsing an existing file -// m_fileSaved = true; -// setRunState( VkRunState::TOOL1 ); + fileSaved = true; + setProcessId( MEMCHECK::PROC_PARSE_LOG ); // Could be a very large file, so at least get ui up-to-date now qApp->processEvents( QEventLoop::AllEvents, 1000/*max msecs*/ ); @@ -498,15 +522,14 @@ "<p>%s</p>", qPrintable( escapeEntities(hnd->fatalMsg()) ) ); } -#if 0 if (success) { - m_saveFname = log_file; + saveFname = log_file; statusMsg( "Loaded", log_file ); } else { statusMsg( "Parse failed", log_file ); } - setRunState( VkRunState::STOPPED ); -#endif + setProcessId( TOOL::PROC_NONE ); + return success; } @@ -520,31 +543,32 @@ */ bool Memcheck::mergeLogFiles() { +//TODO. maybe. #if 0 QString fname_logList = vkConfig->rdEntry( "merge", "valkyrie" ); statusMsg( "Merging logs in file-list", fname_logList ); - m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) - + "mc_merged", "xml" ); - vk_assert( !m_saveFname.isEmpty() ); + saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + + "mc_merged", "xml" ); + vk_assert( !saveFname.isEmpty() ); QStringList flags; flags << vkConfig->rdEntry( "merge-exec","valkyrie"); flags << "-f"; flags << fname_logList; flags << "-o"; - flags << m_saveFname; + flags << saveFname; - setRunState( VkRunState::TOOL2 ); - m_fileSaved = false; + setProcessId( VkRunState::TOOL2 ); + fileSaved = false; statusMsg( "Merge Logs", "Running ... " ); bool ok = startProcess( flags ); if (!ok) { statusMsg( "Merge Logs", "Failed" ); - m_fileSaved = true; - setRunState( VkRunState::STOPPED ); + fileSaved = true; + setProcessId( VkRunState::STOPPED ); } return ok; #endif @@ -557,208 +581,225 @@ */ bool Memcheck::startProcess( QStringList flags ) { + QString program = flags.at( 0 ); + QStringList args = flags.mid(1); + // vkPrint("Memcheck::startProcess()"); - // for ( unsigned int i=0; i<flags.count(); i++ ) - // vkPrint("flag[%d] --> %s", i, flags[i].latin1() ); + for ( int i=0; i<flags.count(); i++ ) + vkPrint("flag[%d] --> %s", i, qPrintable( flags[i] ) ); vk_assert( getToolView() != 0 ); -#if 0 - /* new m_vgreader - view() may be recreated, so need up-to-date ptr */ - vk_assert( m_vgreader == 0 ); - m_vgreader = new VgLogReader( view()->vgLogPtr() ); + // new vgreader - view may have been recreated, so need up-to-date ptr + vk_assert( vgreader == 0 ); + vgreader = new VgLogReader( getToolView()->vgLogPtr() ); - /* start the log parse - nothing written yet tho */ - if (!m_vgreader->parse( m_saveFname, true )) { - QString errMsg = m_vgreader->handler()->fatalMsg(); - VK_DEBUG("m_vgreader failed to start parsing empty log\n"); - vkError( view(), "Process Startup Error", + // start the log parse - nothing written yet tho. + if (!vgreader->parse( saveFname, true )) { + QString errMsg = vgreader->handler()->fatalMsg(); + VK_DEBUG("vgreader failed to start parsing empty log\n"); + vkError( getToolView(), "Process Startup Error", "<p>Failed to start XML parser:<br>%s</p>", - errMsg.ascii() ); + qPrintable( errMsg ) ); goto failed_startup; } - /* start a new process, listening on exit signal */ - vk_assert( m_vgproc == 0 ); - m_vgproc = new VKProcess( flags, this ); - connect( m_vgproc, SIGNAL(processExited()), - this, SLOT(processDone()) ); + // start a new process, listening on exit signal + vk_assert( vgproc == 0 ); + vgproc = new QProcess( this->toolView ); + connect( vgproc, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(processDone(int, QProcess::ExitStatus)) ); - /* don't need to talk/listen to forked process, - so don't let it hijack stdin/out/err for socket fd's */ - m_vgproc->setCommunication( 0 ); + // forward vg process stdout/err to our stdout/err respectively + vgproc->setProcessChannelMode( QProcess::ForwardedChannels ); - /* set working directory */ - m_vgproc->setWorkingDirectory( - QDir( vkConfig->rdEntry( "working-dir", "valkyrie" ) ) ); + // set working directory + vgproc->setWorkingDirectory( vkConfig->value( "valkyrie/working-dir" ).toString() ); - if ( !m_vgproc->start() ) { + // start running process + vgproc->start( program, args ); + +//TODO: call vgproc->waitForStarted(), or sthgn with a timeout, and then error to user... +#if 0 VK_DEBUG("process failed to start"); - QString path_errmsg = (runState() == VkRunState::VALGRIND) - ? "Please verify the path to Valgrind in Options::Valkyrie." - : ""; /* TODO: same for vk_logmerge... and provide option widgets to update path... */ - vkError( view(), "Process Startup Error", - "<p>Failed to start process:<br>%s<br><br>%s</p>", - flags.join(" ").latin1(), - path_errmsg.latin1() ); + vkError( getToolView(), "Process Startup Error", + "<p>Failed to start process:<br>%s<br><br>" + "Please verify the path to Valgrind in Options::Valkyrie.</p>", + qPrintable( flags.join(" ") ) ); goto failed_startup; } +#endif - /* poll log for latest data */ - if (!m_logpoller->start()) { - QString errMsg = m_vgreader->handler()->fatalMsg(); - VK_DEBUG("m_logpoller failed to start\n"); - vkError( view(), "Process Startup Error", - "<p>Failed to start log poller.</p>" ); - goto failed_startup; - } + // poll log for latest data + logpoller->start(); - // vkPrint(" - END MC::startProcess()" ); +vkPrint(" - END MC::startProcess()" ); return true; failed_startup: - VK_DEBUG("failed_startup: '%s'", flags.join(" ").latin1()); - if (m_logpoller != 0) { - m_logpoller->stop(); + VK_DEBUG("failed_startup: '%s'", qPrintable( flags.join(" ") )); + if (logpoller != 0) { + logpoller->stop(); } - if (m_vgreader != 0) { - delete m_vgreader; - m_vgreader = 0; + if (vgreader != 0) { + delete vgreader; + vgreader = 0; } - if (m_vgproc != 0) { - delete m_vgproc; - m_vgproc = 0; + if (vgproc != 0) { + delete vgproc; + vgproc = 0; } return false; -#endif - return true; } -/* Process exited: - - self / external signal / user via 'stop()' / - - terminated from readVgLog because of an xml parse error - Stops logfile polling, checks xml parsing for errors, - checks exitstatus, cleans up. +/*! + Process exited: + - self / external signal / user via 'stop()' / + - terminated from readVgLog because of an xml parse error + Stops logfile polling, checks xml parsing for errors, + checks exitstatus, cleans up. */ -void Memcheck::processDone() +void Memcheck::processDone( int exitCode, QProcess::ExitStatus exitStatus ) { -#if 0 + cerr << "Memcheck::processDone( " << exitCode << ", " << exitStatus << " )" << endl; + // vkPrint("Memcheck::processDone()"); - vk_assert( m_vgproc != 0 ); - vk_assert( m_vgreader != 0 ); - vk_assert( m_logpoller != 0 ); + vk_assert( vgproc != 0 ); + vk_assert( vgreader != 0 ); + vk_assert( logpoller != 0 ); bool runError = false; - /* stop polling logfile ------------------------------------------ */ - m_logpoller->stop(); + // stop polling logfile ------------------------------------------ + logpoller->stop(); - /* deal with log reader ------------------------------------------ */ - /* if not finished && no error, try reading log data one last time */ - if (!m_vgreader->handler()->finished() && - m_vgreader->handler()->fatalMsg().isEmpty()) + // deal with log reader ------------------------------------------ + // if not finished && no error, try reading log data one last time + if (!vgreader->handler()->finished() && + vgreader->handler()->fatalMsg().isEmpty()) readVgLog(); - /* did log parsing go ok? */ - QString fatalMsg = m_vgreader->handler()->fatalMsg(); + // did log parsing go ok? + QString fatalMsg = vgreader->handler()->fatalMsg(); if ( !fatalMsg.isEmpty() ) { - /* fatal log error... */ + // fatal log error... runError = true; // vkPrint(" - Memcheck::processDone(): fatal error"); - if (runState() == VkRunState::VALGRIND) { + if (getProcessId() == TOOL::PROC_VALGRIND) { statusMsg( "Memcheck", "Error parsing output log" ); - vkError( view(), "XML Parse Error", + vkError( getToolView(), "XML Parse Error", "<p>Error parsing Valgrind XML output:<br>%s</p>", - str2html( fatalMsg ).latin1() ); + qPrintable( str2html( fatalMsg ) ) ); } else { + vk_assert_never_reached(); +//TODO. maybe +#if 0 statusMsg( "Merge Logs", "Error parsing output log" ); - vkError( view(), "Parse Error", + vkError( getToolView(), "Parse Error", "<p>Error parsing output log</p>" ); +#endif } - } else if ( !m_vgreader->handler()->finished() ) { + } else if ( !vgreader->handler()->finished() ) { /* no fatal error, but STILL not reached end of log, either: - valgrind xml output not completed properly - merge failed */ runError = true; // vkPrint(" - Memcheck::processDone(): parsing STILL not finished"); - - if (runState() == VkRunState::VALGRIND) { + + if (getProcessId() == TOOL::PROC_VALGRIND) { statusMsg( "Memcheck", "Error - incomplete output log" ); - vkError( view(), "XML Parse Error", + vkError( getToolView(), "XML Parse Error", "<p>Valgrind XML output is incomplete</p>" ); } else { + vk_assert_never_reached(); +//TODO. maybe. +#if 0 statusMsg( "Merge Logs", "Error - incomplete output log" ); - vkError( view(), "Parse Error", + vkError( getToolView(), "Parse Error", "<p>Failed to parse merge result</p>" ); +#endif } - } - /* check process exit status - - valgrind might have bombed ---------------------------------- */ - bool exitStatus = m_vgproc->exitStatus(); - if (exitStatus != 0) { + + // check process exit status - valgrind might have bombed + if ( exitStatus == QProcess::NormalExit && exitCode == 0 ) { + // vkPrint(" - Memcheck::processDone(): process exited ok"); + } else { // vkPrint(" - Memcheck::processDone(): process failed (%d)", exitStatus); - if (runState() == VkRunState::VALGRIND) { - vkError( view(), "Run Error", - "<p>Process exited with return value %d.<br> \ + if (getProcessId() == TOOL::PROC_VALGRIND) { + vkError( getToolView(), "Run Error", + "<p>Process %s, with return value %d.<br> \ This is likely to simply be the client program \ return value. If, however, you suspect Valgrind \ itself may have crashed, please click 'OK', then \ - 'Save Log' and examine for details.</p>", exitStatus); + 'Save Log' and examine for details.</p>", + (exitStatus == QProcess::NormalExit) ? "exited normally" : "crashed", + exitCode ); } else { - vkError( view(), "Parse Error", + vk_assert_never_reached(); +//TODO: maybe. +#if 0 + vkError( getToolView(), "Parse Error", "<p>Merge process exited with return value %d.<br> \ Please check the terminal for error messages.</p>", exitStatus); +#endif } - } else { - // vkPrint(" - Memcheck::processDone(): process exited ok"); } - /* cleanup ------------------------------------------------------- */ - delete m_vgreader; - m_vgreader = 0; - delete m_vgproc; - m_vgproc = 0; + // cleanup ------------------------------------------------------- + delete vgreader; + vgreader = 0; + delete vgproc; + vgproc = 0; - /* we're done. --------------------------------------------------- */ - if (!runError) { /* (else we've already set an status error message) */ - if (runState() == VkRunState::VALGRIND) + // we're done. --------------------------------------------------- + if (!runError) { // (else we've already set an status error message) + if (getProcessId() == TOOL::PROC_VALGRIND) { statusMsg( "Memcheck", "Finished" ); - else - statusMsg( "Merge Logs", "Finished" ); + } else { + vk_assert_never_reached(); +//TODO: maybe +// statusMsg( "Merge Logs", "Finished" ); + } } - setRunState( VkRunState::STOPPED ); +// setProcessId( TOOL::PROC_NONE ); // vkPrint("Memcheck::processDone(): DONE.\n"); -#endif } /* Read memcheck / logmerge xml output Called by - - m_logpoller signals + - logpoller signals - processDone() if one last data read needed. */ void Memcheck::readVgLog() { -#if 0 - // vkPrint("Memcheck::readVgLog()"); - vk_assert( view() != 0 ); - vk_assert( m_vgreader != 0 ); - vk_assert( m_vgproc != 0 ); +vkPrint("Memcheck::readVgLog()"); + vk_assert( getToolView() != 0 ); + vk_assert( vgreader != 0 ); + vk_assert( vgproc != 0 ); qApp->processEvents(); - /* Try reading some more data */ - if ( m_vgreader && !m_vgreader->parseContinue()) { - /* Parsing failed: stop m_vgproc, if running */ - if ( m_vgproc && m_vgproc->isRunning()) - m_vgproc->stop(); /* signal -> processDone() */ + // starting or dead -> get out of here. + if ( vgproc->state() != QProcess::Running ) + return; + + // Try reading some more data. By failure, stop process. + if ( vgreader && !vgreader->parseContinue()) { +vkPrint("Memcheck::readVgLog(): Parsing Failed. Stopping process after timeout"); + + // stop trying to read from the log. + logpoller->stop(); + +//TODO: necessary? + // give process a little time to finishe before we stop it. + QTimer::singleShot( TIMEOUT_STOPPROC, this, SLOT( stop() ) ); } -#endif } @@ -783,7 +824,7 @@ if ( fname.isEmpty() ) { /* Start save-dialog in User-configured default log dir*/ QString start_path = vkConfig->rdEntry( "default-logdir", "valkyrie" ); - fname = dlg.getSaveFileName( start_path, flt, view(), "fsdlg", cptn ); + fname = dlg.getSaveFileName( start_path, flt, getToolView(), "fsdlg", cptn ); if ( fname.isEmpty() ) return false; } @@ -791,7 +832,7 @@ /* try to save file until succeed, or user Cancels */ while ( !saveParsedOutput( fname ) ) { QString start_path = QFileInfo( fname ).dirPath(); - fname = dlg.getSaveFileName( start_path, flt, view(), "fsdlg", cptn ); + fname = dlg.getSaveFileName( start_path, flt, getToolView(), "fsdlg", cptn ); if ( fname.isEmpty() ) /* Cancelled */ return false; } @@ -800,13 +841,13 @@ } /* Save to file - - we already have everything in m_saveFname logfile, so just copy that + - we already have everything in saveFname logfile, so just copy that */ bool Memcheck::saveParsedOutput( QString& fname ) { #if 0 //vkPrint("saveParsedOutput(%s)", fname.latin1() ); - vk_assert( view() != 0 ); + vk_assert( getToolView() != 0 ); vk_assert( !fname.isEmpty() ); /* make sure path is absolute */ @@ -814,7 +855,7 @@ /* if this filename already exists, check if we should over-write it */ if ( QFile::exists( fname ) ) { - int ok = vkQuery( view(), 2, "Overwrite File", + int ok = vkQuery( getToolView(), 2, "Overwrite File", "<p>Over-write existing file '%s' ?</p>", fname.latin1() ); if ( ok == MsgBox::vkNo ) { @@ -825,38 +866,38 @@ /* save log (=copy/rename) */ bool ok; - if (!m_fileSaved) { - /* first save after a run, so just rename m_saveFname => fname */ + if (!fileSaved) { + /* first save after a run, so just rename saveFname => fname */ if (0) vkPrint("renaming: '%s' -> '%s'", - m_saveFname.latin1(), fname.latin1() ); - if (m_saveFname != fname) { - ok = FileCopy( m_saveFname, fname ); + saveFname.latin1(), fname.latin1() ); + if (saveFname != fname) { + ok = FileCopy( saveFname, fname ); if (ok) - ok = QDir().remove( m_saveFname ); + ok = QDir().remove( saveFname ); } else { ok = true; // no need to do anything } // OLD: - //ok = QDir().rename( m_saveFname, fname ); + //ok = QDir().rename( saveFname, fname ); // but we can't just rename, because that fails when the src // and dst files are in different partitions. The longwinded // but more reliable solution is to copy and then delete the // original. } else { - /* we've saved once already: must now copy m_saveFname => fname */ + /* we've saved once already: must now copy saveFname => fname */ if (0) vkPrint("copying: '%s' -> '%s'", - m_saveFname.latin1(), fname.latin1() ); - ok = FileCopy( m_saveFname, fname ); + saveFname.latin1(), fname.latin1() ); + ok = FileCopy( saveFname, fname ); } if (ok) { - m_saveFname = fname; - m_fileSaved = true; - statusMsg( "Saved", m_saveFname ); + saveFname = fname; + fileSaved = true; + statusMsg( "Saved", saveFname ); } else { /* nogo: return and try again */ - vkInfo( view(), "Save Failed", + vkInfo( getToolView(), "Save Failed", "<p>Failed to save file to '%s'", fname.latin1() ); - statusMsg( "Failed Save", m_saveFname ); + statusMsg( "Failed Save", saveFname ); } return ok; #endif Modified: branches/valkyrie_qt4port/objects/memcheck_object.h =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-01-27 22:54:53 UTC (rev 472) @@ -21,19 +21,17 @@ #ifndef __MEMCHECK_OBJECT_H #define __MEMCHECK_OBJECT_H - #include "objects/tool_object.h" -#include "toolview/memcheckview.h" #include "options/memcheck_options_page.h" +#include "toolview/memcheckview.h" +#include "utils/vglogreader.h" +#include "utils/vk_logpoller.h" -//#include "vk_logpoller.h" -//#include "vglogreader.h" -//#include "vk_process.h" +#include <QProcess> +#include <QStringList> -//TODO - // ============================================================ namespace MEMCHECK { @@ -59,10 +57,9 @@ Tools can run different processes */ enum mcProcessId { - PROC_NOPROC = -1, - PROC_RUN_VALGRIND, - PROC_PARSE_LOGFILE, - NUM_PROCS + PROC_PARSE_LOG = TOOL::PROC_TOOL_NONE+1, + // Any other process id's go here. + PROC_MAX = TOOL::PROC_MAX }; } @@ -85,7 +82,6 @@ bool queryDone(); bool start( int procId, QStringList vgflags ); - void stop(); unsigned int maxOptId() { return MEMCHECK::NUM_OPTS; } @@ -100,6 +96,7 @@ public slots: bool fileSaveDialog( QString fname=QString() ); + void stop(); private: // overriding to avoid casting everywhere @@ -115,16 +112,15 @@ bool startProcess( QStringList flags ); private slots: - void processDone(); + void processDone( int exitCode, QProcess::ExitStatus exitStatus ); void readVgLog(); + void killProcess(); private: -/* - QString m_saveFname; - VgLogReader* m_vgreader; - VKProcess* m_vgproc; - VkLogPoller* m_logpoller; -*/ + QString saveFname; + VgLogReader* vgreader; + QProcess* vgproc; + VkLogPoller* logpoller; }; Modified: branches/valkyrie_qt4port/objects/tool_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.cpp 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/tool_object.cpp 2010-01-27 22:54:53 UTC (rev 472) @@ -37,7 +37,7 @@ */ ToolObject::ToolObject( const QString& objectName, VGTOOL::ToolID id ) : VkObject( objectName ), - toolView(0), fileSaved(true), runState(VkRunState::STOPPED), toolId(id) + toolView(0), fileSaved(true), processId(TOOL::PROC_NONE), toolId(id) { } @@ -45,20 +45,41 @@ ToolObject::~ToolObject() {} -#if 0 bool ToolObject::isRunning() { - return (m_runState != VkRunState::STOPPED); + return (processId > TOOL::PROC_NONE); } -void ToolObject::setRunState( VkRunState::State rs ) + +/*! + Set the process id. + Emits signal for subsequent state: 'running(true|false)' +*/ +void ToolObject::setProcessId( int procId ) { - m_runState = rs; + vk_assert( procId >= TOOL::PROC_NONE ); + vk_assert( procId != TOOL::PROC_TOOL_NONE ); + vk_assert( procId < TOOL::PROC_MAX); + + processId = procId; emit running( isRunning() ); } +/*! + get the currently-running process id +*/ +int ToolObject::getProcessId() +{ + vk_assert( processId >= TOOL::PROC_NONE ); + vk_assert( processId != TOOL::PROC_TOOL_NONE ); + vk_assert( processId < TOOL::PROC_MAX ); + return processId; +} + + +#if 0 void ToolObject::deleteView() { emit message( "" ); /* clear the status bar */ Modified: branches/valkyrie_qt4port/objects/tool_object.h =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/tool_object.h 2010-01-27 22:54:53 UTC (rev 472) @@ -34,13 +34,15 @@ #include <QList> -/* Own namespace for ease of use */ -namespace VkRunState { - /* STOPPED: no process running - * VALGRIND: running valgrind - * TOOL*: running a tool-defined process - */ - enum State { STOPPED=-1, VALGRIND=0, TOOL1, TOOL2, TOOL3 }; +namespace TOOL { + // Tools may extend this enum with their own process id's. + enum toolProcessId { + PROC_NONE=-1, // no process running + PROC_VALGRIND=0, // run valgrind for given tool + PROC_TOOL_NONE=1, // tool defined proc id's start here + 1 + // tool defined processes may take up this block + PROC_MAX=4 // reasonable number of processes per tool + }; } @@ -76,27 +78,26 @@ // stop a process: doesn't exit until success virtual void stop() = 0; -/* bool isRunning(); +/* virtual OptionsPage* createOptionsPage( OptionsWindow* parent ) = 0; // returns a list of non-default flags to pass to valgrind virtual QStringList modifiedVgFlags(); +*/ signals: void running( bool ); void message( QString ); - void fatal(); +//TODO: needed? +// void fatal(); protected: - // set runstate and emit signal running(bool) - void setRunState( VkRunState::State ); - // get runstate - VkRunState::State runState() { return runState; } + void setProcessId( int procId ); + int getProcessId(); virtual bool runValgrind( QStringList vgflags ) = 0; -*/ public: VGTOOL::ToolID getToolId() { return toolId; } @@ -106,8 +107,8 @@ bool fileSaved; private: - // Keep track of current running state - VkRunState::State runState; + // tools need to add own processId's: classic enum extend problem :-( + int processId; VGTOOL::ToolID toolId; // which tool are we. }; Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-27 22:54:53 UTC (rev 472) @@ -19,6 +19,7 @@ ****************************************************************************/ #include "help/help_urls.h" +#include "objects/tool_object.h" #include "objects/valkyrie_object.h" #include "options/valkyrie_options_page.h" // createVkOptionsPage() #include "utils/vk_config.h" @@ -614,7 +615,7 @@ /*! - Run the tool with given runState + Run the tool with given process id. */ bool Valkyrie::runTool( VGTOOL::ToolID tId, int procId ) { @@ -624,9 +625,36 @@ ToolObject* activeTool = valgrind()->getToolObj( tId ); vk_assert( activeTool != 0 ); - return activeTool->start( procId, QStringList() ); -//TODO -// return activeTool->start( procId, m_flags ); + return activeTool->start( procId, vg_flags ); } +/*! + Update flags for current tool + Called by MainWindow::updateVgFlags() + - which is triggered by optionsWin::flagsChanged signal +*/ +void Valkyrie::updateVgFlags( VGTOOL::ToolID tId ) +{ +cerr << "Valkyrie::updateVgFlags( " << tId << ")" << endl; + + vk_assert( tId != VGTOOL::ID_NULL ); + ToolObject* tool = valgrind()->getToolObj( tId ); + vk_assert( tool != 0 ); + + QString vg_exec = vkConfig->value( "valkyrie/vg-exec" ).toString(); + if (vg_exec.isEmpty()) + vg_exec = "valgrind"; // hope it's in $PATH + + // modifiedVgFlags() functions return non-default flags + vg_flags.clear(); + vg_flags << vg_exec; // path/to/valgrind + vg_flags << "--tool=" + tool->objectName(); // tool + +//TODO: + vg_flags << "ls"; +// vg_flags += valgrind()->modifiedVgFlags( tool ); // valgrind opts +// vg_flags += tool->modifiedVgFlags(); // tool opts +// vg_flags += this->modifiedVgFlags(); // valkyrie opts +} + Modified: branches/valkyrie_qt4port/objects/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-01-27 22:54:53 UTC (rev 472) @@ -69,6 +69,8 @@ #if 0 // TODO bool queryToolDone( int tId ); #endif + void updateVgFlags( VGTOOL::ToolID tId ); + unsigned int maxOptId() { return VALKYRIE::NUM_OPTS; } int checkOptArg( QString optGrp, int optid, QString& argval ); @@ -97,6 +99,7 @@ private: Valgrind* m_valgrind; + QStringList vg_flags; }; Modified: branches/valkyrie_qt4port/toolview/vglogview.cpp =================================================================== --- branches/valkyrie_qt4port/toolview/vglogview.cpp 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/toolview/vglogview.cpp 2010-01-27 22:54:53 UTC (rev 472) @@ -21,7 +21,6 @@ #include "toolview/vglogview.h" #include "utils/vk_utils.h" #include "utils/vk_config.h" -//#include "vglogview_icons.h" #include <QFileInfo> #include <QStringList> @@ -829,8 +828,8 @@ /*! VgLogView: inherits VgLog */ -VgLogView::VgLogView( QTreeWidget* lv ) - : lview(lv), lastChild( 0 ) +VgLogView::VgLogView( QTreeWidget* v ) + : view(v), lastChild( 0 ) { } VgLogView::~VgLogView() @@ -857,7 +856,7 @@ if (state == VgStatus::RUNNING) { VgElement exe = args().getFirstElem( "argv" ).getFirstElem( "exe" ); - topStatus = new TopStatusItem( lview, status, exe, protocol().text() ); + topStatus = new TopStatusItem( view, status, exe, protocol().text() ); topStatus->setOpen( true ); lastChild = new InfoItem( topStatus, docroot() ); lastChild = new PreambleItem( topStatus, lastChild, preamble() ); Modified: branches/valkyrie_qt4port/toolview/vglogview.h =================================================================== --- branches/valkyrie_qt4port/toolview/vglogview.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/toolview/vglogview.h 2010-01-27 22:54:53 UTC (rev 472) @@ -221,7 +221,7 @@ class VgLogView : public VgLog { public: - VgLogView( QTreeWidget* lv ); + VgLogView( QTreeWidget* ); ~VgLogView(); bool appendNode( QDomNode node ); @@ -230,7 +230,7 @@ void updateErrorItems( VgErrCounts ec ); private: - QTreeWidget* lview; // we don't own this: don't delete it + QTreeWidget* view; // we don't own this: don't delete it VgOutputItem* lastChild; TopStatusItem* topStatus; }; Copied: branches/valkyrie_qt4port/utils/vk_logpoller.cpp (from rev 471, trunk/valkyrie/tool_utils/vk_logpoller.cpp) =================================================================== --- branches/valkyrie_qt4port/utils/vk_logpoller.cpp (rev 0) +++ branches/valkyrie_qt4port/utils/vk_logpoller.cpp 2010-01-27 22:54:53 UTC (rev 472) @@ -0,0 +1,59 @@ +/**************************************************************************** +** VkLogPoller implementation +** - polls a log for updates +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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/vk_logpoller.h" + + +VkLogPoller::VkLogPoller ( QObject* parent, const char* name ) + : QObject( parent ) +{ + this->setObjectName( name ); + + timer = new QTimer( this ); + + connect( timer, SIGNAL(timeout()), + this, SIGNAL(logUpdated()) ); +} + + +VkLogPoller::~VkLogPoller() +{ + // timer deleted by it's parent: this +} + + +void VkLogPoller::start( int interval ) +{ + timer->start( interval ); +} + + +void VkLogPoller::stop() +{ + if (timer->isActive()) + timer->stop(); +} + + +bool VkLogPoller::isActive() +{ + return timer->isActive(); +} + Copied: branches/valkyrie_qt4port/utils/vk_logpoller.h (from rev 471, trunk/valkyrie/tool_utils/vk_logpoller.h) =================================================================== --- branches/valkyrie_qt4port/utils/vk_logpoller.h (rev 0) +++ branches/valkyrie_qt4port/utils/vk_logpoller.h 2010-01-27 22:54:53 UTC (rev 472) @@ -0,0 +1,58 @@ +/**************************************************************************** +** VkLogPoller definition +** - polls a log for updates +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 VK_LOGPOLLER_H +#define VK_LOGPOLLER_H + +#include <QObject> +#include <QTimer> + + +/*! + NOTE: + Future intention is to have another thread running select on the + given file, so triggering signal when the file is updated. + Or something... +*/ + +// ============================================================ +/*! + class VkLogPoller +*/ +class VkLogPoller : public QObject +{ + Q_OBJECT +public: + VkLogPoller( QObject * parent, const char * name ); + ~VkLogPoller(); + + void start( int interval=100 ); + void stop(); + bool isActive(); + int interval(); + +signals: + void logUpdated(); + +private: + QTimer* timer; +}; + +#endif // VK_LOGPOLLER_H Modified: branches/valkyrie_qt4port/utils/vk_utils.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_utils.h 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/utils/vk_utils.h 2010-01-27 22:54:53 UTC (rev 472) @@ -73,11 +73,10 @@ #if DEBUG_ON /* print debugging msg with file+line info to stderr ------------------- */ -# define VK_DEBUG(msg, args...) { \ - vkPrintErr("DEBUG: %s#%d:%s:", \ - __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ - vkPrintErr(msg, ## args ); \ - vkPrintErr(" "); \ +# define VK_DEBUG(msg, args...) { \ + vkPrintErr("DEBUG: %s#%d:%s:", __FILE__, __LINE__, __PRETTY_FUNCTION__ ); \ + vkPrintErr(msg, ## args ); \ + vkPrintErr(" "); \ } #else # define VK_DEBUG(msg, args...) /*NOTHING*/ Modified: branches/valkyrie_qt4port/valkyrie.pro =================================================================== --- branches/valkyrie_qt4port/valkyrie.pro 2010-01-24 18:57:15 UTC (rev 471) +++ branches/valkyrie_qt4port/valkyrie.pro 2010-01-27 22:54:53 UTC (rev 472) @@ -37,6 +37,7 @@ utils/vglog.cpp \ utils/vglogreader.cpp \ utils/vk_config.cpp \ + utils/vk_logpoller.cpp \ utils/vk_messages.cpp \ utils/vk_utils.cpp HEADERS += mainwindow.h \ @@ -72,6 +73,7 @@ utils/vglog.h \ utils/vglogreader.h \ utils/vk_config.h \ + utils/vk_logpoller.h \ utils/vk_messages.h \ utils/vk_utils.h RESOURCES += icons.qrc |
From: <sv...@va...> - 2010-01-24 18:57:24
|
Author: cerion Date: 2010-01-24 18:57:15 +0000 (Sun, 24 Jan 2010) New Revision: 471 Log: Basic port of Vg XML log parsing,binding,displaying in a treeview. (for XML files only - starting Vg process and streaming the XML not yet done) Note to self: rem to thank the lord(s) that the xml framework hasn't changed much between Qt3->4! Still plenty work to be done: the old Qt3-QListView is now a Qt4-QTreeWidget, which works somewhat differently :-( Added: branches/valkyrie_qt4port/toolview/vglogview.cpp branches/valkyrie_qt4port/toolview/vglogview.h branches/valkyrie_qt4port/utils/vglog.cpp branches/valkyrie_qt4port/utils/vglog.h branches/valkyrie_qt4port/utils/vglogreader.cpp branches/valkyrie_qt4port/utils/vglogreader.h Modified: branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/helgrind_object.h branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/tool_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/toolview/memcheckview.cpp branches/valkyrie_qt4port/toolview/memcheckview.h branches/valkyrie_qt4port/toolview/toolview.h branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h branches/valkyrie_qt4port/valkyrie.pro [... diff too large to include ...] |
From: <sv...@va...> - 2010-01-23 15:25:20
|
Author: cerion Date: 2010-01-23 15:25:06 +0000 (Sat, 23 Jan 2010) New Revision: 470 Log: added basic tool-object framework added bare memcheck framework incl. options (for vg3.4 still) added bare helgrind framework (just to have a second tool for testing framework) refactored code somewhat to remove general knowledge of tool details. Added: branches/valkyrie_qt4port/objects/helgrind_object.cpp branches/valkyrie_qt4port/objects/helgrind_object.h branches/valkyrie_qt4port/objects/memcheck_object.cpp branches/valkyrie_qt4port/objects/memcheck_object.h branches/valkyrie_qt4port/objects/tool_object.cpp branches/valkyrie_qt4port/objects/tool_object.h branches/valkyrie_qt4port/options/helgrind_options_page.cpp branches/valkyrie_qt4port/options/helgrind_options_page.h branches/valkyrie_qt4port/options/memcheck_options_page.cpp branches/valkyrie_qt4port/options/memcheck_options_page.h Modified: branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/toolview/helgrindview.cpp branches/valkyrie_qt4port/toolview/memcheckview.cpp branches/valkyrie_qt4port/toolview/toolview.cpp branches/valkyrie_qt4port/toolview/toolview.h branches/valkyrie_qt4port/valkyrie.pro Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-01-23 09:40:36 UTC (rev 469) +++ branches/valkyrie_qt4port/main.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -95,7 +95,7 @@ // Start up the gui vkWin = new MainWindow( &valkyrie ); vkWin->show(); - vkWin->showToolView( vk::ID_MEMCHECK ); + vkWin->showToolView( VGTOOL::ID_MEMCHECK ); qApp->processEvents(); Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-01-23 09:40:36 UTC (rev 469) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -35,6 +35,7 @@ #include "options/vk_option.h" #include "utils/vk_config.h" #include "utils/vk_messages.h" +#include "utils/vk_utils.h" /***************************************************************************/ @@ -230,34 +231,32 @@ // ------------------------------------------------------------ - // Tool actions + // Tool actions - exclusive selection group + toolActionGroup = new QActionGroup( this ); +//TODO: if we make it exclusive, then we can't close all toolviews and have none selected... can we? +//toolActionGroup->setExclusive( true ); + connect( toolActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( toolGroupTriggered( QAction* ) ) ); + QIcon icon_bullet; icon_bullet.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_mainwin_blackbullet.xpm") ), QIcon::Normal, QIcon::Off ); - actTool_Memcheck = new QAction( this ); - actTool_Memcheck->setObjectName( QString::fromUtf8("actTool_Memcheck") ); - actTool_Memcheck->setText( QApplication::translate("MainWindowClass", "Memcheck", 0, QApplication::UnicodeUTF8) ); - actTool_Memcheck->setCheckable( true ); - actTool_Memcheck->setIcon( icon_bullet ); - actTool_Memcheck->setIconVisibleInMenu( true ); - actTool_Memcheck->setProperty( "toolview_id", vk::ID_MEMCHECK ); + ToolObjList tools = valkyrie->valgrind()->getToolObjList(); + vk_assert( tools.size() > 0 ); + foreach( ToolObject* tool, tools ) { + QString toolname = tool->objectName(); + toolname[0] = toolname[0].toUpper(); - actTool_Helgrind = new QAction( this ); - actTool_Helgrind->setObjectName( QString::fromUtf8("actTool_Helgrind") ); - actTool_Helgrind->setText( QApplication::translate("MainWindowClass", "Helgrind", 0, QApplication::UnicodeUTF8) ); - actTool_Helgrind->setCheckable( true ); - actTool_Helgrind->setIcon( icon_bullet ); - actTool_Helgrind->setIconVisibleInMenu( true ); - actTool_Helgrind->setProperty( "toolview_id", vk::ID_HELGRIND ); + QAction* actTool = new QAction( this ); + actTool->setObjectName( "actTool_" + toolname ); + actTool->setCheckable( true ); + actTool->setIcon( icon_bullet ); + actTool->setIconVisibleInMenu( true ); + actTool->setText( toolname ); + actTool->setProperty( "toolId", tool->getToolId() ); - // Tool Group: exclusive selection - toolActionGroup = new QActionGroup( this ); - toolActionGroup->addAction( actTool_Memcheck ); - toolActionGroup->addAction( actTool_Helgrind ); - actTool_Memcheck->setChecked( true ); - connect( toolActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( toolGroupTriggered( QAction* ) ) ); + toolActionGroup->addAction( actTool ); + } - // ------------------------------------------------------------ // initial enables/disables actEdit_Options->setEnabled( true ); @@ -319,10 +318,10 @@ menuProcess->addAction( actProcess_Run ); menuProcess->addAction( actProcess_Stop ); + + foreach ( QAction* actTool, toolActionGroup->actions() ) + menuTools->addAction( actTool ); - menuTools->addAction( actTool_Memcheck ); - menuTools->addAction( actTool_Helgrind ); - menuHelp->addAction( actHelp_Handbook ); menuHelp->addSeparator(); menuHelp->addAction( actHelp_About_Valkyrie ); @@ -377,33 +376,43 @@ /*! - Show a requested ToolView, from the given \a toolview_id. + Show a requested ToolView, from the given \a toolId. The ToolViews are created and shown on demand. */ -void MainWindow::showToolView( vk::ToolViewID toolview_id ) +void MainWindow::showToolView( VGTOOL::ToolID toolId ) { - if ( toolViewStack->currentViewId() == toolview_id ) { + if ( toolViewStack->currentToolId() == toolId ) { // already loaded and visible => do nothing return; } // toolview maybe loaded, but isn't visible... - ToolView* nextView = toolViewStack->findView( toolview_id ); + ToolView* nextView = toolViewStack->findView( toolId ); if ( nextView == 0) { // toolview not loaded => load it. - switch ( toolview_id ) { - case vk::ID_MEMCHECK: - nextView = new MemcheckView( this ); - break; - case vk::ID_HELGRIND: - nextView = new HelgrindView( this ); - break; - default: - break; - } + // set up next view + ToolObject* nextTool = valkyrie->valgrind()->getToolObj( toolId ); + vk_assert( nextTool != 0 ); + + nextView = nextTool->createView( this ); + vk_assert( nextView != 0 ); + +/* TODO + connect( nextTool, SIGNAL(running(bool)), + this, SLOT(updateButtons(bool)) ); + connect( nextTool, SIGNAL(message(QString)), + this, SLOT(setStatus(QString)) ); + connect( this, SIGNAL(toolbarLabelsToggled(bool)), + nextView, SLOT(toggleToolbarLabels(bool)) ); + + // view starts tool processes via this signal + connect( nextView, SIGNAL(run(VkRunState::State)), + this, SLOT(run(VkRunState::State)) ); +*/ + // add view to the stack toolViewStack->addView( nextView ); } @@ -411,10 +420,11 @@ // make sure the toolview is made visible: toolViewStack->raiseView( nextView ); - setToggles( toolview_id ); + setToggles( toolId ); } + /*! Toggles the various actions depending on the current toolview and internal state. @@ -422,17 +432,15 @@ is brought forward, the various actions must be updated to correspond with the state of the new ToolView. */ -void MainWindow::setToggles( vk::ToolViewID toolview_id ) +void MainWindow::setToggles( VGTOOL::ToolID toolId ) { - if ( toolview_id == vk::ID_NULL ) { + if ( toolId == VGTOOL::ID_NULL ) { // no more tool views // disable all actions in the tool actiongroup // TODO: nicer way to do this? - maybe connect sig/slot toolview to action? - QList<QAction*> toolActions = toolActionGroup->actions(); - for (int i = 0; i < toolActions.size(); ++i) { - toolActions.at(i)->setChecked( false ); - } + foreach ( QAction* actTool, toolActionGroup->actions() ) + actTool->setChecked( false ); actFile_Close->setEnabled( false ); actProcess_Run->setEnabled( false ); @@ -443,14 +451,14 @@ // enable the relevant action in the tool actiongroup // TODO: nicer way to do this? - maybe connect sig/slot toolview to action? - QList<QAction*> toolActions = toolActionGroup->actions(); - for (int i = 0; i < toolActions.size(); ++i) { - QAction* act = toolActions.at(i); - vk::ToolViewID tvid_action = (vk::ToolViewID)act->property( "toolview_id" ).toInt(); - if ( tvid_action == toolview_id ) { - act->setChecked( true ); - break; - } + foreach ( QAction* actTool, toolActionGroup->actions() ) { + VGTOOL::ToolID toolId_action = + (VGTOOL::ToolID)actTool->property( "toolId" ).toInt(); + if ( toolId_action == toolId ) + actTool->setChecked( true ); + else + actTool->setChecked( false ); +//TODO: review toggle functionality. } actFile_Close->setEnabled( true ); @@ -545,7 +553,7 @@ toolViewStack->removeView( tv ); // current toolview will now have changed (maybe to NULL) - setToggles( toolViewStack->currentViewId() ); + setToggles( toolViewStack->currentToolId() ); } @@ -563,17 +571,17 @@ This slot is called by a trigger of the tool actionGroup, which is setup for the "Tools" menu. - We make use of the QAction::property to store the toolview_id, + We make use of the QAction::property to store the toolId, and when one of the tools is selected, this id is used to call up the corresponding ToolView on the ToolViewStack. */ void MainWindow::toolGroupTriggered( QAction* action ) { - vk::ToolViewID tvid = (vk::ToolViewID)action->property( "toolview_id" ).toInt(); + VGTOOL::ToolID toolId = (VGTOOL::ToolID)action->property( "toolId" ).toInt(); - cerr << "MainWindow::toolGroupTriggered() for toolview " << tvid << endl; + cerr << "MainWindow::toolGroupTriggered() for toolview " << toolId << endl; - showToolView( tvid ); + showToolView( toolId ); } Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2010-01-23 09:40:36 UTC (rev 469) +++ branches/valkyrie_qt4port/mainwindow.h 2010-01-23 15:25:06 UTC (rev 470) @@ -50,7 +50,7 @@ public slots: void setStatus( QString msg ); - void showToolView( vk::ToolViewID tvid ); + void showToolView( VGTOOL::ToolID toolId ); private: void setupLayout(); @@ -58,7 +58,7 @@ void setupMenus(); void setupToolBars(); void setupStatusBar(); - void setToggles( vk::ToolViewID tvid ); + void setToggles( VGTOOL::ToolID toolId ); private slots: void toolGroupTriggered( QAction* ); @@ -88,8 +88,6 @@ QAction* actEdit_Search; QAction* actProcess_Run; QAction* actProcess_Stop; - QAction* actTool_Memcheck; - QAction* actTool_Helgrind; QAction* actHelp_Handbook; QAction* actHelp_About_Valkyrie; QAction* actHelp_About_Qt; Added: branches/valkyrie_qt4port/objects/helgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/helgrind_object.cpp (rev 0) +++ branches/valkyrie_qt4port/objects/helgrind_object.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,83 @@ +/**************************************************************************** +** Helgrind implementation +** - Helgrind-specific options / flags / fns +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "objects/helgrind_object.h" +//#include "utils/vk_config.h" +#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc. + + +/*! + class Helgrind +*/ +Helgrind::Helgrind() + : ToolObject( "helgrind", VGTOOL::ID_HELGRIND ) +{ + setupOptions(); +} + + +Helgrind::~Helgrind() +{ +} + + +/*! + Setup the options for this object. + + Note: These opts should be kept in exactly the same order as valgrind + outputs them, as it makes keeping up-to-date a lot easier. +*/ +void Helgrind::setupOptions() +{ + // ------------------------------------------------------------ + // foobar + options.addOpt( + HELGRIND::FOO, this->objectName(), "foo-bar", + '\0', + "<foo|bar>", "foo|bar", "foo", + "Fubar", + "fubar?", + "", VkOPT::ARG_STRING, VkOPT::WDG_COMBO + ); +} + + + +/* check argval for this option, updating if necessary. + called by parseCmdArgs() and gui option pages -------------------- */ +int Helgrind::checkOptArg( int optid, QString& argval ) +{ + return PARSED_OK; +} + + +/* Creates this tool's ToolView window, + and sets up and connections between them */ +ToolView* Helgrind::createView( QWidget* parent ) +{ + toolView = new HelgrindView( parent ); + return toolView; +} + + +VkOptionsPage* Helgrind::createVkOptionsPage() +{ + return (VkOptionsPage*)new HelgrindOptionsPage( this ); +} Added: branches/valkyrie_qt4port/objects/helgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/helgrind_object.h (rev 0) +++ branches/valkyrie_qt4port/objects/helgrind_object.h 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,60 @@ +/**************************************************************************** +** Helgrind definition +** - Helgrind-specific options / flags / fns +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __HELGRIND_OBJECT_H +#define __HELGRIND_OBJECT_H + + +#include "objects/tool_object.h" +#include "toolview/helgrindview.h" +#include "options/helgrind_options_page.h" + + +// ============================================================ +namespace HELGRIND { +/*! + enum identification of all options for this object +*/ + enum mcOptId { + FOO, + NUM_OPTS + }; +} + + +// ============================================================ +// class Helgrind +class Helgrind : public ToolObject +{ + Q_OBJECT +public: + Helgrind(); + ~Helgrind(); + + void setupOptions(); + + ToolView* createView( QWidget* parent ); + unsigned int maxOptId() { return HELGRIND::NUM_OPTS; } + int checkOptArg( int optid, QString& argval ); + VkOptionsPage* createVkOptionsPage(); +}; + + +#endif // __HELGRIND_OBJECT_H Added: branches/valkyrie_qt4port/objects/memcheck_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.cpp (rev 0) +++ branches/valkyrie_qt4port/objects/memcheck_object.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,856 @@ +/**************************************************************************** +** Memcheck implementation +** - Memcheck-specific options / flags / fns +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "config.h" +#include "objects/memcheck_object.h" +#include "objects/valkyrie_object.h" +#include "utils/vk_config.h" +#include "help/help_urls.h" +#include "utils/vk_messages.h" +#include "options/vk_option.h" // PERROR* and friends +//#include "vk_file_utils.h" // FileCopy() +#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc. + + + +/*! + class Memcheck +*/ +Memcheck::Memcheck() + : ToolObject( "memcheck", VGTOOL::ID_MEMCHECK ) +{ +#if 0 + /* init vars */ + m_fileSaved = true; + m_vgproc = 0; + m_vgreader = 0; + m_logpoller = new VkLogPoller( this, "memcheck logpoller" ); + connect( m_logpoller, SIGNAL(logUpdated()), + this, SLOT(readVgLog()) ); +#endif + + setupOptions(); +} + + +Memcheck::~Memcheck() +{ +#if 0 + if (m_vgproc) { + m_vgproc->disconnect(); /* so no signal calling processDone() */ + if (m_vgproc->isRunning()) { + m_vgproc->stop(); + } + delete m_vgproc; + m_vgproc = 0; + } + if (m_vgreader) { + delete m_vgreader; + m_vgreader = 0; + } + + /* m_logpoller deleted by it's parent: 'this' */ + + /* unsaved log... delete our temp file */ + if (!m_fileSaved && !m_saveFname.isEmpty()) + QDir().remove( m_saveFname ); +#endif +} + + +/*! + Setup the options for this object. + + Note: These opts should be kept in exactly the same order as valgrind + outputs them, as it makes keeping up-to-date a lot easier. +*/ +void Memcheck::setupOptions() +{ + // ------------------------------------------------------------ + // leak-check + options.addOpt( + MEMCHECK::LEAK_CHECK, this->objectName(), "leak-check", + '\0', + "<no|summary|full>", "no|summary|full", "full", + "Search for memory leaks at exit:", + "search for memory leaks at exit?", + urlMemcheck::Leakcheck, VkOPT::ARG_STRING, VkOPT::WDG_COMBO + ); + + // ------------------------------------------------------------ + // leak-resolution + options.addOpt( + MEMCHECK::LEAK_RES, this->objectName(), "leak-resolution", + '\0', + "<low|med|high>", "low|med|high", "low", + "Degree of backtrace merging:", + "how much backtrace merging in leak check", + urlMemcheck::Leakres, VkOPT::ARG_STRING, VkOPT::WDG_COMBO + ); + + // ------------------------------------------------------------ + // leak-resolution + options.addOpt( + MEMCHECK::SHOW_REACH, this->objectName(), "show-reachable", + '\0', + "<yes|no>", "yes|no", "no", + "Show reachable blocks in leak check", + "show reachable blocks in leak check?", + urlMemcheck::Showreach, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK + ); + + // ------------------------------------------------------------ + // undef-value-errors + //options.addOpt( + // MEMCHECK::UNDEF_VAL, this->objectName(), "undef-value-errors", + // '\0', + // "<yes|no>", "yes|no", "yes", + // "Check for undefined value errors", + // "check for undefined value errors?", + // urlMemcheck::UndefVal, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK + // ); + + // ------------------------------------------------------------ + // track-origins + options.addOpt( + MEMCHECK::TRACK_ORI, this->objectName(), "track-origins", + '\0', + "<yes|no>", "yes|no", "no", + "Show the origins of uninitialised values", + "show the origins of uninitialised values?", + urlMemcheck::TrackOri, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK + ); + + // ------------------------------------------------------------ + // partial-loads-ok + options.addOpt( + MEMCHECK::PARTIAL, this->objectName(), "partial-loads-ok", + '\0', + "<yes|no>", "yes|no", "no", + "Ignore errors on partially invalid addresses", + "too hard to explain here; see manual", + urlMemcheck::Partial, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK + ); + + // ------------------------------------------------------------ + // freelist-vol + options.addOpt( + MEMCHECK::FREELIST, this->objectName(), "freelist-vol", + '\0', + "<number>", "0|1000000000", "10000000", + "Volume of freed blocks queue:", + "volume of freed blocks queue", + urlMemcheck::Freelist, VkOPT::ARG_UINT, VkOPT::WDG_LEDIT + ); + + // ------------------------------------------------------------ + // workaround-gcc296-bugs + options.addOpt( + MEMCHECK::GCC_296, this->objectName(), "workaround-gcc296-bugs", + '\0', + "<yes|no>", "yes|no", "no", + "Work around gcc-296 bugs", + "self explanatory", + urlMemcheck::gcc296, VkOPT::ARG_BOOL, VkOPT::WDG_CHECK + ); + + // ------------------------------------------------------------ + // alignment + options.addOpt( + MEMCHECK::ALIGNMENT, this->objectName(), "alignment", + '\0', + "<number>", "8|1048576", "8", + "Minimum alignment of allocations", + "set minimum alignment of allocations", + urlVgCore::Alignment, VkOPT::ARG_PWR2, VkOPT::WDG_SPINBOX + ); +} + + + +/* check argval for this option, updating if necessary. + called by parseCmdArgs() and gui option pages -------------------- */ +int Memcheck::checkOptArg( int optid, QString& argval ) +{ + vk_assert( optid >= 0 && optid < MEMCHECK::NUM_OPTS ); + + int errval = PARSED_OK; +#if 0 + Option* opt = findOption( optid ); + + switch ( (Memcheck::mcOpts)optid ) { + case PARTIAL: + case FREELIST: + case LEAK_RES: + case SHOW_REACH: + //case UNDEF_VAL: + case TRACK_ORI: + case GCC_296: + case ALIGNMENT: + opt->isValidArg( &errval, argval ); + break; + + /* when using xml output from valgrind, this option is preset to + 'full' by valgrind, so this option should not be used. */ + case LEAK_CHECK: + /* Note: gui options disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Memcheck presets this option to 'full' when generating the required xml output."); + vkPrintErr(" - See valgrind/docs/internals/xml_output.txt."); + break; + + default: + vk_assert_never_reached(); + } +#endif + + return errval; +} + + +/* called from Valkyrie::updateVgFlags() whenever flags have been changed */ +QStringList Memcheck::modifiedVgFlags() +{ + QStringList modFlags; +#if 0 + QString defVal, cfgVal, flag; + + Option* opt; + for ( opt = m_optList.first(); opt; opt = m_optList.next() ) { + flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag + : opt->m_longFlag; + defVal = opt->m_defaultValue; /* opt holds the default */ + cfgVal = vkConfig->rdEntry( opt->m_longFlag, name() ); + + switch ( (Memcheck::mcOpts)opt->m_key ) { + + /* when using xml output from valgrind, this option is preset to + 'full' by valgrind, so this option should not be used. */ + case LEAK_CHECK: + /* ignore this opt */ + break; + + default: + if ( defVal != cfgVal ) + modFlags << "--" + opt->m_longFlag + "=" + cfgVal; + } + } +#endif + return modFlags; +} + + +/* Creates this tool's ToolView window, + and sets up and connections between them */ +ToolView* Memcheck::createView( QWidget* parent ) +{ + toolView = new MemcheckView( parent ); + +#if 0 + /* signals view --> tool */ + connect( m_view, SIGNAL(saveLogFile()), + this, SLOT(fileSaveDialog()) ); + + /* signals tool --> view */ + connect( this, SIGNAL(running(bool)), + m_view, SLOT(setState(bool)) ); + + setRunState( VkRunState::STOPPED ); +#endif + return toolView; +} + + +/* outputs a message to the status bar. */ +void Memcheck::statusMsg( QString hdr, QString msg ) +{ +//TODO +// emit message( hdr + ": " + msg ); +} + + +/* are we done and dusted? + anything we need to check/do before being deleted/closed? +*/ +bool Memcheck::queryDone() +{ + vk_assert( getToolView() != 0 ); +#if 0 + /* if current process is not yet finished, ask user if they really + want to close */ + if ( isRunning() ) { + int ok = vkQuery( view(), "Process Running", "&Abort;&Cancel", + "<p>The current process is not yet finished.</p>" + "<p>Do you want to abort it ?</p>" ); + /* Note: process may have finished while waiting for user */ + if ( ok == MsgBox::vkYes ) { + stop(); /* abort */ + vk_assert( !isRunning() ); + } else if ( ok == MsgBox::vkNo ) { + return false; /* continue */ + } + } + + if (!queryFileSave()) + return false; // not saved: procrastinate. +#endif + return true; +} + +/* if current output not saved, ask user if want to save + returns false if not saved, but user wants to procrastinate. +*/ +bool Memcheck::queryFileSave() +{ + vk_assert( getToolView() != 0 ); +#if 0 + vk_assert( !isRunning() ); + + /* currently loaded / parsed stuff is saved to tmp file - ask user + if they want to save it to a 'real' file */ + if ( !m_fileSaved ) { + int ok = vkQuery( view(), "Unsaved File", + "&Save;&Discard;&Cancel", + "<p>The current output is not saved, " + " and will be deleted.<br/>" + "Do you want to save it ?</p>" ); + if ( ok == MsgBox::vkYes ) { /* save */ + + if ( !fileSaveDialog() ) { + /* user clicked Cancel, but we already have the + auto-fname saved anyway, so get outta here. */ + return false; + } + + } else if ( ok == MsgBox::vkCancel ) { /* procrastinate */ + return false; + } else { /* discard */ + QFile::remove( m_saveFname ); + m_fileSaved = true; + } + } +#endif + return true; +} + + +bool Memcheck::start( VkRunState::State rs, QStringList vgflags ) +{ + bool ok = false; +#if 0 + vk_assert( rs != VkRunState::STOPPED ); + vk_assert( !isRunning() ); + + switch ( rs ) { + case VkRunState::VALGRIND: { ok = runValgrind( vgflags ); break; } + case VkRunState::TOOL1: { ok = parseLogFile(); break; } + case VkRunState::TOOL2: { ok = mergeLogFiles(); break; } + default: + vk_assert_never_reached(); + } +#endif + return ok; +} + + +/* stop a process + - doesn't exit until process stopped. + - may take some time for process to respond: too much time and it + just gets terminated. */ +void Memcheck::stop() +{ +#if 0 + if ( !isRunning() ) + return; + + switch ( runState() ) { + case VkRunState::VALGRIND: { + if (m_vgproc && m_vgproc->isRunning() ) + m_vgproc->stop(); /* signal -> processDone() */ + } break; + + case VkRunState::TOOL1: { /* parse log */ + /* TODO: make log parsing a VkProcess. This will allow + - valkyrie to stay responsive + - the ability to interrupt the process if taking too long */ + VK_DEBUG("TODO: Memcheck::stop(parse log)" ); + } break; + + case VkRunState::TOOL2: { /* merge logs */ + if (m_vgproc && m_vgproc->isRunning() ) + m_vgproc->stop(); /* signal -> processDone() */ + } break; + + default: + vk_assert_never_reached(); + } + + /* spin until done */ + while ( isRunning() ) + qApp->processEvents(); +#endif + + return; +} + + +/* If --vg-opt=<arg> was specified on the cmd-line, called by + valkyrie->runTool(); if set via the run-button in the gui, + then MainWindow::run() calls valkyrie->runTool(). + + Auto-generated logs always saved in hard-coded (configured) log dir +*/ +bool Memcheck::runValgrind( QStringList vgflags ) +{ +#if 0 + m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + + "mc_log", "xml" ); + vk_assert( !m_saveFname.isEmpty() ); + + vgflags.insert( ++(vgflags.begin()), ("--log-file=" + m_saveFname) ); + + setRunState( VkRunState::VALGRIND ); + m_fileSaved = false; + statusMsg( "Memcheck", "Running ... " ); + + bool ok = startProcess( vgflags ); + + if (!ok) { + statusMsg( "Memcheck", "Failed" ); + m_fileSaved = true; + setRunState( VkRunState::STOPPED ); + } + return ok; +#endif + return true; +} + + +/* Parse log file given by [valkyrie::view-log] entry. + Called by valkyrie->runTool() if cmdline --view-log=<file> specified. + MemcheckView::openLogFile() if gui parse-log selected. + If 'checked' == true, file perms/format has already been checked */ +bool Memcheck::parseLogFile() +{ + vk_assert( getToolView() != 0 ); +#if 0 + QString log_file = vkConfig->rdEntry( "view-log", "valkyrie" ); + statusMsg( "Parsing", log_file ); + + /* check this is a valid file, and has the right perms */ + int errval = PARSED_OK; + QString ret_file = fileCheck( &errval, log_file, true, false ); + if ( errval != PARSED_OK ) { + vkError( view(), "File Error", "%s: \n\"%s\"", + parseErrString(errval), + escapeEntities(log_file).latin1() ); + return false; + } + log_file = ret_file; + + /* fileSaved is always true here 'cos we are just parsing a file + which already exists on disk */ + m_fileSaved = true; + setRunState( VkRunState::TOOL1 ); + + /* Could be a very large file, so at least get ui up-to-date now */ + qApp->processEvents( 1000/*max msecs*/ ); + + /* Parse the log */ + VgLogReader vgLogFileReader( view()->vgLogPtr() ); + bool success = vgLogFileReader.parse( log_file ); + if (!success) { + VgLogHandler* hnd = vgLogFileReader.handler(); + statusMsg( "Parsing", "Error" ); + vkError( view(), "XML Parse Error", + "<p>%s</p>", escapeEntities(hnd->fatalMsg()).latin1() ); + } + + if (success) { + m_saveFname = log_file; + statusMsg( "Loaded", log_file ); + } else { + statusMsg( "Parse failed", log_file ); + } + setRunState( VkRunState::STOPPED ); + return success; +#endif + return true; +} + + +/* if --merge=<file_list> was specified on the cmd-line, called by + valkyrie->runTool(); if set via the open-file-dialog in the gui, + called by MemcheckView::openMergeFile(). either way, the value in + [valkyrie:merge] is what we need to know + + Auto-generated logs always saved in hard-coded (configured) log dir +*/ +bool Memcheck::mergeLogFiles() +{ +#if 0 + QString fname_logList = vkConfig->rdEntry( "merge", "valkyrie" ); + statusMsg( "Merging logs in file-list", fname_logList ); + + m_saveFname = vk_mkstemp( QString( get_VK_LOGS_DIR() ) + + "mc_merged", "xml" ); + vk_assert( !m_saveFname.isEmpty() ); + + QStringList flags; + flags << vkConfig->rdEntry( "merge-exec","valkyrie"); + flags << "-f"; + flags << fname_logList; + flags << "-o"; + flags << m_saveFname; + + setRunState( VkRunState::TOOL2 ); + m_fileSaved = false; + statusMsg( "Merge Logs", "Running ... " ); + + bool ok = startProcess( flags ); + + if (!ok) { + statusMsg( "Merge Logs", "Failed" ); + m_fileSaved = true; + setRunState( VkRunState::STOPPED ); + } + return ok; +#endif + return true; +} + + +/* Run a VKProcess, as given by 'flags'. + Reads ouput from file, loading this to the listview. +*/ +bool Memcheck::startProcess( QStringList flags ) +{ + // vkPrint("Memcheck::startProcess()"); + // for ( unsigned int i=0; i<flags.count(); i++ ) + // vkPrint("flag[%d] --> %s", i, flags[i].latin1() ); + vk_assert( getToolView() != 0 ); +#if 0 + + /* new m_vgreader - view() may be recreated, so need up-to-date ptr */ + vk_assert( m_vgreader == 0 ); + m_vgreader = new VgLogReader( view()->vgLogPtr() ); + + /* start the log parse - nothing written yet tho */ + if (!m_vgreader->parse( m_saveFname, true )) { + QString errMsg = m_vgreader->handler()->fatalMsg(); + VK_DEBUG("m_vgreader failed to start parsing empty log\n"); + vkError( view(), "Process Startup Error", + "<p>Failed to start XML parser:<br>%s</p>", + errMsg.ascii() ); + goto failed_startup; + } + + /* start a new process, listening on exit signal */ + vk_assert( m_vgproc == 0 ); + m_vgproc = new VKProcess( flags, this ); + connect( m_vgproc, SIGNAL(processExited()), + this, SLOT(processDone()) ); + + /* don't need to talk/listen to forked process, + so don't let it hijack stdin/out/err for socket fd's */ + m_vgproc->setCommunication( 0 ); + + /* set working directory */ + m_vgproc->setWorkingDirectory( + QDir( vkConfig->rdEntry( "working-dir", "valkyrie" ) ) ); + + if ( !m_vgproc->start() ) { + VK_DEBUG("process failed to start"); + QString path_errmsg = (runState() == VkRunState::VALGRIND) + ? "Please verify the path to Valgrind in Options::Valkyrie." + : ""; /* TODO: same for vk_logmerge... and provide option widgets to update path... */ + vkError( view(), "Process Startup Error", + "<p>Failed to start process:<br>%s<br><br>%s</p>", + flags.join(" ").latin1(), + path_errmsg.latin1() ); + goto failed_startup; + } + + /* poll log for latest data */ + if (!m_logpoller->start()) { + QString errMsg = m_vgreader->handler()->fatalMsg(); + VK_DEBUG("m_logpoller failed to start\n"); + vkError( view(), "Process Startup Error", + "<p>Failed to start log poller.</p>" ); + goto failed_startup; + } + + // vkPrint(" - END MC::startProcess()" ); + return true; + + failed_startup: + VK_DEBUG("failed_startup: '%s'", flags.join(" ").latin1()); + if (m_logpoller != 0) { + m_logpoller->stop(); + } + if (m_vgreader != 0) { + delete m_vgreader; + m_vgreader = 0; + } + if (m_vgproc != 0) { + delete m_vgproc; + m_vgproc = 0; + } + return false; +#endif + return true; +} + + +/* Process exited: + - self / external signal / user via 'stop()' / + - terminated from readVgLog because of an xml parse error + Stops logfile polling, checks xml parsing for errors, + checks exitstatus, cleans up. +*/ +void Memcheck::processDone() +{ +#if 0 + // vkPrint("Memcheck::processDone()"); + vk_assert( m_vgproc != 0 ); + vk_assert( m_vgreader != 0 ); + vk_assert( m_logpoller != 0 ); + bool runError = false; + + /* stop polling logfile ------------------------------------------ */ + m_logpoller->stop(); + + /* deal with log reader ------------------------------------------ */ + /* if not finished && no error, try reading log data one last time */ + if (!m_vgreader->handler()->finished() && + m_vgreader->handler()->fatalMsg().isEmpty()) + readVgLog(); + + /* did log parsing go ok? */ + QString fatalMsg = m_vgreader->handler()->fatalMsg(); + if ( !fatalMsg.isEmpty() ) { + /* fatal log error... */ + runError = true; + // vkPrint(" - Memcheck::processDone(): fatal error"); + + if (runState() == VkRunState::VALGRIND) { + statusMsg( "Memcheck", "Error parsing output log" ); + vkError( view(), "XML Parse Error", + "<p>Error parsing Valgrind XML output:<br>%s</p>", + str2html( fatalMsg ).latin1() ); + } else { + statusMsg( "Merge Logs", "Error parsing output log" ); + vkError( view(), "Parse Error", + "<p>Error parsing output log</p>" ); + } + } else if ( !m_vgreader->handler()->finished() ) { + /* no fatal error, but STILL not reached end of log, either: + - valgrind xml output not completed properly + - merge failed */ + runError = true; + // vkPrint(" - Memcheck::processDone(): parsing STILL not finished"); + + if (runState() == VkRunState::VALGRIND) { + statusMsg( "Memcheck", "Error - incomplete output log" ); + vkError( view(), "XML Parse Error", + "<p>Valgrind XML output is incomplete</p>" ); + } else { + statusMsg( "Merge Logs", "Error - incomplete output log" ); + vkError( view(), "Parse Error", + "<p>Failed to parse merge result</p>" ); + } + + } + + /* check process exit status + - valgrind might have bombed ---------------------------------- */ + bool exitStatus = m_vgproc->exitStatus(); + if (exitStatus != 0) { + // vkPrint(" - Memcheck::processDone(): process failed (%d)", exitStatus); + if (runState() == VkRunState::VALGRIND) { + vkError( view(), "Run Error", + "<p>Process exited with return value %d.<br> \ + This is likely to simply be the client program \ + return value. If, however, you suspect Valgrind \ + itself may have crashed, please click 'OK', then \ + 'Save Log' and examine for details.</p>", exitStatus); + } else { + vkError( view(), "Parse Error", + "<p>Merge process exited with return value %d.<br> \ + Please check the terminal for error messages.</p>", + exitStatus); + } + } else { + // vkPrint(" - Memcheck::processDone(): process exited ok"); + } + + /* cleanup ------------------------------------------------------- */ + delete m_vgreader; + m_vgreader = 0; + delete m_vgproc; + m_vgproc = 0; + + + /* we're done. --------------------------------------------------- */ + if (!runError) { /* (else we've already set an status error message) */ + if (runState() == VkRunState::VALGRIND) + statusMsg( "Memcheck", "Finished" ); + else + statusMsg( "Merge Logs", "Finished" ); + } + + setRunState( VkRunState::STOPPED ); + // vkPrint("Memcheck::processDone(): DONE.\n"); +#endif +} + + +/* Read memcheck / logmerge xml output + Called by + - m_logpoller signals + - processDone() if one last data read needed. +*/ +void Memcheck::readVgLog() +{ +#if 0 + // vkPrint("Memcheck::readVgLog()"); + vk_assert( view() != 0 ); + vk_assert( m_vgreader != 0 ); + vk_assert( m_vgproc != 0 ); + + qApp->processEvents(); + + /* Try reading some more data */ + if ( m_vgreader && !m_vgreader->parseContinue()) { + /* Parsing failed: stop m_vgproc, if running */ + if ( m_vgproc && m_vgproc->isRunning()) + m_vgproc->stop(); /* signal -> processDone() */ + } +#endif +} + + +/* Brings up a fileSaveDialog until successfully saved, + or user pressed Cancel. + If fname.isEmpty, ask user for a name first. + returns false on user pressing Cancel, else true. + + Save-dialog started in user-configured default log dir +*/ +bool Memcheck::fileSaveDialog( QString fname/*=QString()*/ ) +{ + vk_assert( getToolView() != 0 ); +#if 0 + + QFileDialog dlg; + dlg.setShowHiddenFiles( true ); + QString flt = "XML Files (*.xml);;Log Files (*.log.*);;All Files (*)"; + QString cptn = "Save Log File As"; + + /* Ask fname if don't have one already */ + if ( fname.isEmpty() ) { + /* Start save-dialog in User-configured default log dir*/ + QString start_path = vkConfig->rdEntry( "default-logdir", "valkyrie" ); + fname = dlg.getSaveFileName( start_path, flt, view(), "fsdlg", cptn ); + if ( fname.isEmpty() ) + return false; + } + + /* try to save file until succeed, or user Cancels */ + while ( !saveParsedOutput( fname ) ) { + QString start_path = QFileInfo( fname ).dirPath(); + fname = dlg.getSaveFileName( start_path, flt, view(), "fsdlg", cptn ); + if ( fname.isEmpty() ) /* Cancelled */ + return false; + } +#endif + return true; +} + +/* Save to file + - we already have everything in m_saveFname logfile, so just copy that +*/ +bool Memcheck::saveParsedOutput( QString& fname ) +{ +#if 0 + //vkPrint("saveParsedOutput(%s)", fname.latin1() ); + vk_assert( view() != 0 ); + vk_assert( !fname.isEmpty() ); + + /* make sure path is absolute */ + fname = QFileInfo( fname ).absFilePath(); + + /* if this filename already exists, check if we should over-write it */ + if ( QFile::exists( fname ) ) { + int ok = vkQuery( view(), 2, "Overwrite File", + "<p>Over-write existing file '%s' ?</p>", + fname.latin1() ); + if ( ok == MsgBox::vkNo ) { + /* nogo: return and try again */ + return false; + } + } + + /* save log (=copy/rename) */ + bool ok; + if (!m_fileSaved) { + /* first save after a run, so just rename m_saveFname => fname */ + if (0) vkPrint("renaming: '%s' -> '%s'", + m_saveFname.latin1(), fname.latin1() ); + if (m_saveFname != fname) { + ok = FileCopy( m_saveFname, fname ); + if (ok) + ok = QDir().remove( m_saveFname ); + } else { + ok = true; // no need to do anything + } + // OLD: + //ok = QDir().rename( m_saveFname, fname ); + // but we can't just rename, because that fails when the src + // and dst files are in different partitions. The longwinded + // but more reliable solution is to copy and then delete the + // original. + } else { + /* we've saved once already: must now copy m_saveFname => fname */ + if (0) vkPrint("copying: '%s' -> '%s'", + m_saveFname.latin1(), fname.latin1() ); + ok = FileCopy( m_saveFname, fname ); + } + if (ok) { + m_saveFname = fname; + m_fileSaved = true; + statusMsg( "Saved", m_saveFname ); + } else { + /* nogo: return and try again */ + vkInfo( view(), "Save Failed", + "<p>Failed to save file to '%s'", fname.latin1() ); + statusMsg( "Failed Save", m_saveFname ); + } + return ok; +#endif + return true; +} + + +VkOptionsPage* Memcheck::createVkOptionsPage() +{ + return (VkOptionsPage*)new MemcheckOptionsPage( this ); +} Added: branches/valkyrie_qt4port/objects/memcheck_object.h =================================================================== --- branches/valkyrie_qt4port/objects/memcheck_object.h (rev 0) +++ branches/valkyrie_qt4port/objects/memcheck_object.h 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,119 @@ +/**************************************************************************** +** Memcheck definition +** - Memcheck-specific options / flags / fns +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __MEMCHECK_OBJECT_H +#define __MEMCHECK_OBJECT_H + + +#include "objects/tool_object.h" +#include "toolview/memcheckview.h" +#include "options/memcheck_options_page.h" + +//#include "vk_logpoller.h" +//#include "vglogreader.h" +//#include "vk_process.h" + + +//TODO + + +// ============================================================ +namespace MEMCHECK { +/*! + enum identification of all options for this object +*/ + enum mcOptId { + TOOL, // --tool + LEAK_CHECK, + LEAK_RES, + SHOW_REACH, + //UNDEF_VAL, + TRACK_ORI, + PARTIAL, + FREELIST, + GCC_296, + ALIGNMENT, + NUM_OPTS + }; +} + + +// ============================================================ +// class Memcheck +class Memcheck : public ToolObject +{ + Q_OBJECT +public: + Memcheck(); + ~Memcheck(); + + void setupOptions(); + + + // returns the ToolView window (memcheckView) for this tool + ToolView* createView( QWidget* parent ); + // called by MainWin::closeToolView() + bool queryDone(); + + bool start( VkRunState::State rm, QStringList vgflags ); + void stop(); + + unsigned int maxOptId() { return MEMCHECK::NUM_OPTS; } + + // check argval for this option, updating if necessary. + // - called by parseCmdArgs() and gui option pages + int checkOptArg( int optid, QString& argval ); + + VkOptionsPage* createVkOptionsPage(); + + // returns a list of non-default flags to pass to valgrind + QStringList modifiedVgFlags(); + +public slots: + bool fileSaveDialog( QString fname=QString() ); + +private: + // overriding to avoid casting everywhere + MemcheckView* getToolView() { return (MemcheckView*)toolView; } + + void statusMsg( QString hdr, QString msg ); + bool queryFileSave(); + bool saveParsedOutput( QString& fname ); + + bool runValgrind( QStringList vgflags ); // RM_Valgrind + bool parseLogFile(); // RM_Tool0 + bool mergeLogFiles(); // RM_Tool1 + bool startProcess( QStringList flags ); + +private slots: + void processDone(); + void readVgLog(); + +private: +/* + QString m_saveFname; + VgLogReader* m_vgreader; + VKProcess* m_vgproc; + VkLogPoller* m_logpoller; +*/ +}; + + +#endif Added: branches/valkyrie_qt4port/objects/tool_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.cpp (rev 0) +++ branches/valkyrie_qt4port/objects/tool_object.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,92 @@ +/**************************************************************************** +** ToolObject class implementation +** +** Essential functionality is contained within a ToolObject. +** Each ToolObject has an associated ToolView for displaying output. +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "objects/tool_object.h" +#include "toolview/toolview.h" +#include "utils/vk_config.h" +#include "utils/vk_utils.h" + +#include <QKeySequence> +#include <QString> +#include <QStringList> + + + +/*! + class ToolObject +*/ +ToolObject::ToolObject( const QString& objectName, VGTOOL::ToolID id ) + : VkObject( objectName ), + toolView(0), fileSaved(true), runState(VkRunState::STOPPED), toolId(id) +{ + +} + +ToolObject::~ToolObject() +{} + +#if 0 +bool ToolObject::isRunning() +{ + return (m_runState != VkRunState::STOPPED); +} + + +void ToolObject::setRunState( VkRunState::State rs ) +{ + m_runState = rs; + emit running( isRunning() ); +} + + +void ToolObject::deleteView() +{ + emit message( "" ); /* clear the status bar */ + vk_assert( m_view != 0 ); + + m_view->close( true/*alsoDelete*/ ); + m_view = 0; +} + +ToolView* ToolObject::view() +{ + return m_view; +} + + +/* called from Valkyrie::updateVgFlags() whenever flags have been changed */ +QStringList ToolObject::modifiedVgFlags() +{ + QStringList modFlags; + + for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { + + QString defVal = opt->m_defaultValue; /* opt holds the default */ + QString cfgVal = vkConfig->rdEntry( opt->m_longFlag, name() ); + + if ( defVal != cfgVal ) + modFlags << "--" + opt->m_longFlag + "=" + cfgVal; + } + return modFlags; +} +#endif Added: branches/valkyrie_qt4port/objects/tool_object.h =================================================================== --- branches/valkyrie_qt4port/objects/tool_object.h (rev 0) +++ branches/valkyrie_qt4port/objects/tool_object.h 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,115 @@ +/**************************************************************************** +** ToolObject class definition +** +** Essential functionality is contained within a ToolObject. +** Each ToolObject has an associated ToolView for displaying output. +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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. +** +****************************************************************************/ + + +/* TODO: don't have enum values for the objOpts; instead, init an int + array in the constructor. This means will have to implement addOpt + somewhat differently, as won't have enums available */ + +#ifndef __TOOL_OBJECT_H +#define __TOOL_OBJECT_H + +#include "objects/vk_objects.h" +#include "toolview/toolview.h" + +#include <QList> + + +/* Own namespace for ease of use */ +namespace VkRunState { + /* STOPPED: no process running + * VALGRIND: running valgrind + * TOOL*: running a tool-defined process + */ + enum State { STOPPED=-1, VALGRIND=0, TOOL1, TOOL2, TOOL3 }; +} + + + +// ============================================================ +// forward decls +class ToolView; +class ToolObject; + +typedef QList<ToolObject*> ToolObjList; + + +// ============================================================ +// class ToolObject +class ToolObject : public VkObject +{ + Q_OBJECT + +public: + ToolObject( const QString& objectName, VGTOOL::ToolID toolId ); + ~ToolObject(); + + // creates and init's this tool's ToolView window + virtual ToolView* createView( QWidget* parent ) = 0; +/* + // called by MainWin::closeToolView() + virtual bool queryDone() = 0; + virtual void deleteView(); + ToolView* view(); + + // start a process: may fail + virtual bool start( VkRunState::State rs, QStringList vgflags ) = 0; + // stop a process: doesn't exit until success + virtual void stop() = 0; + + bool isRunning(); + + virtual OptionsPage* createOptionsPage( OptionsWindow* parent ) = 0; + + // returns a list of non-default flags to pass to valgrind + virtual QStringList modifiedVgFlags(); + +signals: + void running( bool ); + void message( QString ); + void fatal(); + +protected: + // set runstate and emit signal running(bool) + void setRunState( VkRunState::State ); + // get runstate + VkRunState::State runState() { return runState; } + + virtual bool runValgrind( QStringList vgflags ) = 0; +*/ + +public: + VGTOOL::ToolID getToolId() { return toolId; } + +protected: + ToolView* toolView; // the toolview window + bool fileSaved; + +private: + // Keep track of current running state + VkRunState::State runState; + + VGTOOL::ToolID toolId; // which tool are we. +}; + + +#endif // #ifndef __TOOL_OBJECT_H Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-23 09:40:36 UTC (rev 469) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -27,11 +27,12 @@ #include "utils/vk_config.h" //#include "config.h" -//#include "memcheck_object.h" +#include "objects/helgrind_object.h" +#include "objects/memcheck_object.h" //#include "cachegrind_object.h" //#include "massif_object.h" //#include "vk_option.h" // PERROR* and friends -//#include "vk_utils.h" // vk_assert, VK_DEBUG, etc. +#include "utils/vk_utils.h" // vk_assert, VK_DEBUG, etc. //#include <ctype.h> @@ -46,10 +47,8 @@ */ Valgrind::Valgrind() : VkObject( "valgrind" ) - // : VkObject( "Valgrind", "Valgrind", Qt::Key_unknown, VkObject::ID_VALGRIND ) { - // /* init tools */ - // initToolObjects();`` + initToolObjects(); setupOptions(); } @@ -799,59 +798,76 @@ return modFlags; } +#endif - -/* Register tools */ +/*! + Register tools +*/ void Valgrind::initToolObjects() { - int objId = VkObject::ID_TOOL0; - m_toolObjList.append( new Memcheck ( objId++ ) ); + toolObjList.append( new Memcheck() ); + toolObjList.append( new Helgrind() ); // TODO: I need another lifetime! - // m_toolObjList.append( new Cachegrind( objId++ ) ); - // m_toolObjList.append( new Massif ( objId++ ) ); + // toolObjList.append( new Cachegrind() ); + // toolObjList.append( new Massif () ); } -/* ToolObject access -------------------------------------------=---- */ -/* Returns a list of all ptrs to ToolObjects */ -ToolObjList Valgrind::toolObjList() + +/*! + ToolObject access + - Returns a list of all ptrs to ToolObjects +*/ +ToolObjList Valgrind::getToolObjList() { - return m_toolObjList; + return toolObjList; } +#if 0 /* Returns a ToolObject's objectId based on its name */ -int Valgrind::toolObjId( const QString& name ) +int Valgrind::getToolObjId( const QString& name ) { - return toolObj(name)->objId(); + return toolObj( name )->objId(); } +#endif /* Returns a ToolObject based on its objectId */ -ToolObject* Valgrind::toolObj( int tid ) +ToolObject* Valgrind::getToolObj( VGTOOL::ToolID tid ) { // vkPrint("Valgrind::toolObj( int tid=%d )", tid); - vk_assert( tid >= ID_TOOL0 ); - ToolObject* tool = m_toolObjList.at( tid - ID_TOOL0 ); - vk_assert( tool != 0 ); - vk_assert( tool->objId() == tid ); + vk_assert( tid > VGTOOL::ID_NULL ); + + ToolObject* tool = NULL; + for ( int i=0; i< toolObjList.size(); i++ ) { + tool = toolObjList.at( i ); + if ( tool->getToolId() == tid ) + break; + } + vk_assert( tool != NULL ); + vk_assert( tool->getToolId() == tid ); return tool; } +#if 0 /* Returns a ToolObject based on its name */ -ToolObject* Valgrind::toolObj( const QString& name ) { - ToolObject* tool; - for ( tool = m_toolObjList.first(); tool; tool = m_toolObjList.next() ) { +ToolObject* Valgrind::getToolObj( const QString& name ) +{ + ToolObject* tool = NULL; + for ( tool = toolObjList.first(); tool; tool = toolObjList.next() ) { if ( tool->name() == name ) - return tool; + break; } - vk_assert_never_reached(); - return NULL; -} + vk_assert( tool != NULL ); + vk_assert( tool->name() == name ); + return tool; +}getToolId #endif -VkOptionsPage* Valgrind::createVkOptionsPage() { +VkOptionsPage* Valgrind::createVkOptionsPage() +{ return (VkOptionsPage*)new ValgrindOptionsPage( this ); } Modified: branches/valkyrie_qt4port/objects/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-23 09:40:36 UTC (rev 469) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-23 15:25:06 UTC (rev 470) @@ -22,7 +22,7 @@ #define __VALGRIND_OBJECT_H #include "objects/vk_objects.h" -//#include "tool_object.h" +#include "objects/tool_object.h" // ============================================================ @@ -92,24 +92,18 @@ VkOptionsPage* createVkOptionsPage(); -#if 0 public: - /* ToolObject access */ - ToolObjList toolObjList(); - int toolObjId( const QString& name ); - ToolObject* toolObj( int tid ); - ToolObject* toolObj( const QString& name ); -#endif + // ToolObject access + ToolObjList getToolObjList(); +// int getToolObjId( const QString& name ); + ToolObject* getToolObj( VGTOOL::ToolID tid ); +// ToolObject* getToolObj( const QString& name ); private: -#if 0 - /* creates the various VkObjects and initialises their options, - ready for cmd-line parsing (if any). */ + // create & init vg tools, ready for cmdline parsing void initToolObjects(); + ToolObjList toolObjList; // Valgrind Tools - ToolObjList m_toolObjList; /* Tools */ -#endif - private: void setupOptions(); }; Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-23 09:40:36 UTC (rev 469) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -585,12 +585,8 @@ vkObjList.append( this ); vkObjList.append( valgrind() ); - -#if 0 // TODO - ToolObjList tools = valgrind()->toolObjList(); - for ( ToolObject* tool = tools.first(); tool; tool = tools.next() ) + foreach( ToolObject* tool, valgrind()->getToolObjList() ) vkObjList.append( tool ); -#endif return vkObjList; } Added: branches/valkyrie_qt4port/options/helgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/helgrind_options_page.cpp (rev 0) +++ branches/valkyrie_qt4port/options/helgrind_options_page.cpp 2010-01-23 15:25:06 UTC (rev 470) @@ -0,0 +1,84 @@ +/**************************************************************************** +** HelgrindOptionsPage implementation +** - subclass of VkOptionsPage to hold helgrind-specific options +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "helgrind_options_page.h" + +#include "objects/helgrind_object.h" + +#include "help/help_context.h" +#include "help/help_urls.h" +#include "utils/vk_utils.h" + +#include "o... [truncated message content] |
From: <sv...@va...> - 2010-01-23 09:40:48
|
Author: cerion Date: 2010-01-23 09:40:36 +0000 (Sat, 23 Jan 2010) New Revision: 469 Log: reinstated message dialogs - error, info, etc. Added: branches/valkyrie_qt4port/utils/vk_messages.cpp branches/valkyrie_qt4port/utils/vk_messages.h Modified: branches/valkyrie_qt4port/help/help_handbook.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/valkyrie.pro Modified: branches/valkyrie_qt4port/help/help_handbook.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.cpp 2010-01-22 20:09:37 UTC (rev 468) +++ branches/valkyrie_qt4port/help/help_handbook.cpp 2010-01-23 09:40:36 UTC (rev 469) @@ -106,6 +106,7 @@ void HandBook::bookmarkChosen( QAction* act ) { if ( !bookmarkMenu->actions().contains( act ) ) { + cerr << "Error: HandBook::bookmarkChosen: act not in bookmarks!" << endl; //TODO: shouldn't ever happen: vkError return; } @@ -118,7 +119,7 @@ void HandBook::bookmarkHighlighted( QAction* act ) { if ( !bookmarkMenu->actions().contains( act ) ) { - cerr << "Error: act not in bookmarks!" << endl; + cerr << "Error: HandBook::bookmarkHighlighted: act not in bookmarks!" << endl; //TODO: shouldn't ever happen: vkError return; } Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-01-22 20:09:37 UTC (rev 468) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-23 09:40:36 UTC (rev 469) @@ -34,6 +34,7 @@ #include "help/help_urls.h" #include "options/vk_option.h" #include "utils/vk_config.h" +#include "utils/vk_messages.h" /***************************************************************************/ Modified: branches/valkyrie_qt4port/options/valgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-01-22 20:09:37 UTC (rev 468) +++ branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-01-23 09:40:36 UTC (rev 469) @@ -25,7 +25,7 @@ #include "help/help_context.h" #include "help/help_urls.h" #include "utils/vk_config.h" -//#include "vk_messages.h" +#include "utils/vk_messages.h" #include "utils/vk_utils.h" #include "objects/valgrind_object.h" @@ -401,12 +401,9 @@ if (((QListWidget*)lbSel->widget())->count() < VG_CLO_MAX_SFILES) { lbSel->insertItem(suppr); } else { -cerr << "TODO: vkError: Valgrind won't accept more than VG_CLO_MAX_SFILES suppression files" << endl; -#if 0 /* valgrind doesn't accept any more suppression files */ vkError( this, "Error", "Valgrind won't accept more than %d suppression files", VG_CLO_MAX_SFILES ); -#endif } } Modified: branches/valkyrie_qt4port/options/vk_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-01-22 20:09:37 UTC (rev 468) +++ branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-01-23 09:40:36 UTC (rev 469) @@ -36,6 +36,7 @@ #include "options/widgets/opt_le_widget.h" #include "options/widgets/opt_sp_widget.h" #include "utils/vk_config.h" +#include "utils/vk_messages.h" #include <QList> @@ -196,12 +197,11 @@ // Note: argval may be altered by checkOptArg() int errval = m_vkObj->checkOptArg( optId, argval ); if ( errval != PARSED_OK ) { -cerr << "TODO: vkError: Invalid Entry: " << errval << endl; -#if 0 // TODO + vkError( this, "Invalid Entry", "%s:\n\"%s\"", parseErrString(errval), - m_itemList[optId]->currValue().latin1() ); -#endif + qPrintable( m_itemList[optId]->currValue() ) ); + m_itemList[optId]->cancelEdit(); return false; } Modified: branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp =================================================================== --- branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp 2010-01-22 20:09:37 UTC (rev 468) +++ branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp 2010-01-23 09:40:36 UTC (rev 469) @@ -25,8 +25,9 @@ #include "help/help_urls.h" #include "options/widgets/opt_lb_widget.h" #include "options/vk_option.h" -#include "utils/vk_utils.h" #include "utils/vk_config.h" +#include "utils/vk_messages.h" +#include "utils/vk_utils.h" /***************************************************************************/ @@ -323,12 +324,9 @@ // check not a duplicate entry if ( ! m_lbox->findItems( supp_dir, Qt::MatchExactly ).isEmpty() ) { -cerr << "TODO: vkInfo: Duplicate Entry Error" << endl; -/* TODO vkInfo( m_lbox, "Duplicate Entry", - "<p>The entry '%s' is already in the list.</p>", - supp_dir.latin1() ); -*/ + "The entry '%s' is already in the list.", + qPrintable( supp_dir ) ); } else { m_lbox->addItem( supp_dir ); changed = true; Added: branches/valkyrie_qt4port/utils/vk_messages.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vk_messages.cpp (rev 0) +++ branches/valkyrie_qt4port/utils/vk_messages.cpp 2010-01-23 09:40:36 UTC (rev 469) @@ -0,0 +1,285 @@ +/**************************************************************************** +** Definition of class MsgBox +** - various types of messages: Query, Info ... +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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/vk_messages.h" +#include "utils/vk_config.h" +//#include "valkyrie_xpm.h" +//#include "msgbox_icons.h" + +#include <stdarg.h> /* va_start, va_end */ +#include <stdlib.h> /* exit errno */ + +#include <QApplication> +#include <QHBoxLayout> +#include <QKeyEvent> +#include <QObjectList> +#include <QPixmap> +#include <QStyle> + +#include <iostream> + + +/***************************************************************************/ +/*! + message dialogs +*/ +#define VK_BUFLEN 8196 + +/*! + vkQuery: ask user a question + Modal dialog box +*/ +int vkQuery( QWidget* w, int nbutts, QString hdr, + const char* msg, ... ) +{ + // setup message + char buf[VK_BUFLEN]; + va_list ap; + va_start( ap, msg ); + vsnprintf( buf, VK_BUFLEN, msg, ap ); + va_end( ap ); + + // setup and show dialog box + MsgBox mb( w, MsgBox::Query, buf, hdr, nbutts ); + QStringList names; + names << "&Yes" << "&No" << "&Cancel"; + mb.setButtonTexts( names ); + return mb.exec(); +} + + +/*! + vkQuery: ask user a question + set custom button labels + Modal dialog box +*/ +int vkQuery( QWidget* w, QString hdr, + QString labels, const char* msg, ... ) +{ + // setup message + char buf[VK_BUFLEN]; + va_list ap; + va_start( ap, msg ); + vsnprintf( buf, VK_BUFLEN, msg, ap ); + va_end( ap ); + + // setup and show dialog box + QStringList buttonLabels( labels.split( ";" ) ); + int nbutts = buttonLabels.count(); + MsgBox mb( w, MsgBox::Query, buf, hdr, nbutts ); + mb.setButtonTexts( buttonLabels ); + return mb.exec(); +} + + +/*! + vkInfo: show information message + Modal dialog box +*/ +void vkInfo( QWidget* w, QString hdr, const char* msg, ... ) +{ + // setup message + char buf[VK_BUFLEN]; + va_list ap; + va_start( ap, msg ); + vsnprintf( buf, VK_BUFLEN, msg, ap ); + va_end( ap ); + + // setup and show dialog box + MsgBox mb( w, MsgBox::Info, buf, hdr, 1 ); + mb.setButtonTexts( QStringList( "O&K" ) ); + mb.exec(); +} + + +/*! + vkError: error message box + Modal dialog box +*/ +void vkError( QWidget* w, QString hdr, const char* msg, ... ) +{ + // setup message + char buf[VK_BUFLEN]; + va_list ap; + va_start( ap, msg ); + vsnprintf( buf, VK_BUFLEN, msg, ap ); + va_end( ap ); + + // setup and show dialog box + MsgBox mb( w, MsgBox::Error, buf, hdr ); + mb.setButtonTexts( QStringList( "O&K" ) ); + mb.exec(); +} + + + + + +/***************************************************************************/ +/*! + Base dialog box implementation +*/ +MsgBox::MsgBox( QWidget* parent, Icon icon, QString msg, + const QString& hdr, int num_buttons ) + : QDialog( parent ) +{ + setObjectName( QString::fromUtf8("msgbox") ); + + msg = "<p>" + msg + "</p>"; + if ( !hdr.isEmpty() ) { + msg = "<b>" + hdr + "</b>" + msg; + } + + numButtons = num_buttons; + int defButton = 0; + button[0] = MsgBox::vkYes; + + QString caption; + QPixmap pm_file; + switch ( icon ) { + case Query: + caption = "Query"; + defButton = 1; /* No */ + pm_file = QPixmap( QString::fromUtf8(":/vk_icons/icons/msgbox_query.xpm") ); + break; + case Info: + caption = "Information"; + pm_file = QPixmap( QString::fromUtf8(":/vk_icons/icons/msgbox_info.xpm") ); + break; + case Error: + caption = "Error"; + pm_file = QPixmap( QString::fromUtf8(":/vk_icons/icons/msgbox_error.xpm") ); + break; + default: + break; + } + setWindowTitle( caption ); + + switch ( numButtons ) { + case 1: // ok button + escButton = -1; + break; + case 2: // yes + no + button[1] = MsgBox::vkNo; + escButton = 1; + break; + case 3: // yes + no + cancel + button[1] = MsgBox::vkNo; + button[2] = MsgBox::vkCancel; + escButton = 2; + break; + } + + + QVBoxLayout* vLayout = new QVBoxLayout( this ); + vLayout->setObjectName(QString::fromUtf8("vlayout")); + vLayout->setAlignment( Qt::AlignTop ); + + QHBoxLayout* hLayout = new QHBoxLayout(); + hLayout->setObjectName(QString::fromUtf8("hlayout")); + hLayout->setSpacing( 14 ); + vLayout->addLayout( hLayout ); + + iconLabel = new QLabel( this ); + iconLabel->setObjectName( "icon_lbl" ); + iconLabel->setAlignment( Qt::AlignTop ); + iconLabel->setPixmap( pm_file ); + hLayout->addWidget( iconLabel ); + + msgLabel = new QLabel( this ); // default: left aligned, tabs expanded. + msgLabel->setObjectName( "msg_lbl" ); + msgLabel->setText( msg ); + hLayout->addWidget( msgLabel ); + hLayout->addStretch( 1 ); + + + QHBoxLayout* hLayoutButtons = new QHBoxLayout(); + hLayoutButtons->setObjectName(QString::fromUtf8("hLayoutButtons")); + hLayoutButtons->addStretch( 1 ); + vLayout->addSpacing( 18 ); + vLayout->addStretch( 1 ); + vLayout->addLayout( hLayoutButtons ); + + for ( int i=0; i<numButtons; i++ ) { + pb[i] = new QPushButton( this ); + pb[i]->setObjectName( "button" + QString::number( i+1 ) ); + hLayoutButtons->addWidget( pb[i] ); + if ( defButton == i ) { + pb[i]->setDefault( true ); + pb[i]->setFocus(); + } + pb[i]->setAutoDefault( true ); + connect( pb[i], SIGNAL(clicked()), + this, SLOT(pbClicked()) ); + } +} + + + +MsgBox::~MsgBox() +{ } + + + +void MsgBox::setButtonTexts( const QStringList &btexts ) +{ + for ( int i=0; i<numButtons; i++ ) { + pb[i]->setText( btexts[i] ); + } +} + + +void MsgBox::pbClicked() +{ + int result = 0; + const QObject* s = sender(); + for ( int i=0; i<numButtons; i++ ) { + if ( pb[i] == s ) { + result = button[i]; + break; + } + } + done( result ); +} + + +// An escape key triggers the assigned 'default-escape' button +void MsgBox::keyPressEvent( QKeyEvent* e ) +{ + if ( e->key() == Qt::Key_Escape ) { + if ( escButton >= 0 ) { + pb[escButton]->animateClick(); + e->accept(); + return; + } + } + QDialog::keyPressEvent( e ); +} + +// Any close event other than via pbClicked() gives 'default-escape' button result. +void MsgBox::closeEvent( QCloseEvent* ce ) +{ + QDialog::closeEvent( ce ); + if ( escButton != -1 ) + setResult( button[escButton] ); +} + + + + Added: branches/valkyrie_qt4port/utils/vk_messages.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_messages.h (rev 0) +++ branches/valkyrie_qt4port/utils/vk_messages.h 2010-01-23 09:40:36 UTC (rev 469) @@ -0,0 +1,85 @@ +/**************************************************************************** +** Definition of class MsgBox +** - various types of messages: Query, Info ... +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __VK_MESSAGES_H +#define __VK_MESSAGES_H + +#include <QDialog> +#include <QLabel> +#include <QPushButton> +#include <QString> +#include <QWidget> + + + +// ============================================================ +/* ask user a question */ +int vkQuery( QWidget* w, int nbutts, QString hdr, const char*, ... ) + __attribute__ (( format( printf, 4, 5 ) )); + +/* ask user a question, + set custom button labels. + Note button ordering - vkYes : vkNo : vkCancel */ +int vkQuery( QWidget* w, QString hdr, QString butt_labels, const char*, ... ) + __attribute__ (( format( printf, 4, 5 ) )); + +/* show information message box */ +void vkInfo( QWidget* w, QString hdr, const char* format, ...) + __attribute__((__format__ (__printf__, 3, 4))); + +/* error message box */ +void vkError( QWidget* w, QString hdr, const char*, ... ) + __attribute__ (( format( printf, 3, 4 ) )); + + + + +// ============================================================ +// Don't call this class directly: used for standard vkError() etc. functions +class MsgBox : public QDialog +{ + Q_OBJECT +public: + enum Icon { Query, Info, Error }; + enum rVal { vkYes=0, vkNo=1, vkCancel=2 }; + + MsgBox( QWidget* parent, Icon icon, QString msg, + const QString& hdr=QString::null, int num_buttons=1 ); + ~MsgBox(); + + void setButtonTexts( const QStringList &texts ); + +protected: + void closeEvent( QCloseEvent * ); + void keyPressEvent( QKeyEvent * ); + +private slots: + void pbClicked(); + +private: + int button[3]; /* button types */ + int escButton; /* escape button (index) */ + int numButtons; /* number of buttons */ + + QLabel* msgLabel; /* label holding msg text */ + QLabel* iconLabel; /* label holding any icon */ + QPushButton *pb[3]; /* buttons */ +}; + +#endif Modified: branches/valkyrie_qt4port/valkyrie.pro =================================================================== --- branches/valkyrie_qt4port/valkyrie.pro 2010-01-22 20:09:37 UTC (rev 468) +++ branches/valkyrie_qt4port/valkyrie.pro 2010-01-23 09:40:36 UTC (rev 469) @@ -4,12 +4,12 @@ TARGET = valkyrie TEMPLATE = app SOURCES += \ + main.cpp \ + mainwindow.cpp \ help/help_about.cpp \ help/help_context.cpp \ help/help_handbook.cpp \ help/help_urls.cpp \ - main.cpp \ - mainwindow.cpp \ objects/valkyrie_object.cpp \ objects/valgrind_object.cpp \ objects/vk_objects.cpp \ @@ -30,13 +30,14 @@ toolview/memcheckview.cpp \ toolview/toolview.cpp \ utils/vk_config.cpp \ + utils/vk_messages.cpp \ utils/vk_utils.cpp HEADERS += \ + mainwindow.h \ help/help_about.h \ help/help_context.h \ help/help_handbook.h \ help/help_urls.h \ - mainwindow.h \ objects/valkyrie_object.h \ objects/valgrind_object.h \ objects/vk_objects.h \ @@ -57,5 +58,6 @@ toolview/memcheckview.h \ toolview/toolview.h \ utils/vk_config.h \ + utils/vk_messages.h \ utils/vk_utils.h RESOURCES += icons.qrc |
From: <sv...@va...> - 2010-01-22 19:32:40
|
Author: cerion Date: 2010-01-22 19:32:19 +0000 (Fri, 22 Jan 2010) New Revision: 466 Log: should have been committed with r465: doc updates Removed: trunk/doc/about_qt.html trunk/doc/xml/about_qt.xml Modified: trunk/doc/about_vk.html trunk/doc/xml/about_vk.xml Deleted: trunk/doc/about_qt.html =================================================================== --- trunk/doc/about_qt.html 2010-01-13 22:07:17 UTC (rev 465) +++ trunk/doc/about_qt.html 2010-01-22 19:32:19 UTC (rev 466) @@ -1,105 +0,0 @@ -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ASCII"> -<title>Qt</title> -<meta name="generator" content="DocBook XSL Stylesheets V1.65.1"> -<style type="text/css" media="screen">/* valkyrie colours: - #0f5499 dark blue h1, h2, h3, h4 - #336699 medium blue links - #339999 turquoise link hover colour - #202020 almost black general text - #761596 purple md5sum text - #626262 dark gray pre border - #eeeeee very light gray pre background - #f2f2f9 very light blue nav table background - #3366cc medium blue nav table border -*/ - -/* default link colours */ -a, a:link, a:visited, a:active { color: #336699; } -a:hover { color: #339999; } - -body { font: 80%/126% sans-serif; } -h1, h2, h3, h4 { color: #0f5499; } - -dt { color: #336699; font-weight: bold } -dd { - margin-left: 1.5em; - padding-bottom: 0.8em; -} - -/* -- ruler -- */ -div.hr_blue { - height: 3px; - background:#ffffff url("images/hr_blue.png") repeat-x; } -div.hr_blue hr { display:none; } - -/* release styles */ -#release p { margin-top: 0.4em; } -#release .md5sum { color: #761596; } - - -/* ------ styles for manual ------ */ - -/* -- lists -- */ -ul { - margin: 0px 4px 16px 16px; - padding: 0px; - list-style: url("images/li-blue.png"); -} -ul li { - margin-bottom: 10px; -} -ul ul { - list-style-type: none; - list-style-image: none; - margin-left: 0px; -} - -/* header / footer nav tables */ -table.nav { - color: #0f5499; - border: solid 1px #3366cc; - background: #f2f2f9; - background-color: #f2f2f9; - margin-bottom: 0.5em; -} - -/* don't have underlined links in chunked nav menus */ -table.nav a { text-decoration: none; } -table.nav a:hover { text-decoration: underline; } -table.nav td { font-size: 85%; } - -code, tt, pre { font-size: 120%; } -code, tt { color: #761596; } - -pre.programlisting, pre.screen { - color: #000000; - padding: 0.5em; - background: #eeeeee; - border: 1px solid #626262; - background-color: #eeeeee; - margin: 4px 0px 4px 0px; -} -</style> -</head> -<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" lang="en"> -<div class="titlepage"> -<div><div><h1 class="title"> -<a name="id4626123"></a>Qt</h1></div></div> -<div></div> -<hr> -</div> -<p>This program was built using Qt version %1,<br>and is running using Qt version %2.</p> -<p>Qt is a C++ toolkit for multi-platform GUI and application -development. Qt provides single-source portability across MS Windows, -Mac OS, X, Linux, and all major commercial Unix variants. Qt is also -available for embedded devices.</p> -<p>See <a href="http://www.trolltech.com/qt/" target="_top">http://www.trolltech.com/qt/</a> for more information.</p> -<table class="nav" width="100%"><tbody><tr> - <td align="center">Copyright (c) Trolltech<br> - <a href="http://www.trolltech.com" target="_top">www.trolltech.com</a> -</td> -</tr></tbody></table> -</div></body> -</html> Modified: trunk/doc/about_vk.html =================================================================== --- trunk/doc/about_vk.html 2010-01-13 22:07:17 UTC (rev 465) +++ trunk/doc/about_vk.html 2010-01-22 19:32:19 UTC (rev 466) @@ -92,6 +92,7 @@ </div> <p>Valkyrie is a graphical user interface for Valgrind: <a href="http://www.valgrind.org" target="_top">www.valgrind.org</a>.</p> +<p>This program was built using Qt v%1, and is running using Qt v%2.</p> <p>You can download the latest version of Valkyrie from the OpenWorks website: <a href="http://www.open-works.co.uk/projects/valkyrie.html" target="_top">http://www.open-works.co.uk/projects/valkyrie.html</a>.</p> <p>For more information on Valkyrie and/or Valgrind, contact Deleted: trunk/doc/xml/about_qt.xml =================================================================== --- trunk/doc/xml/about_qt.xml 2010-01-13 22:07:17 UTC (rev 465) +++ trunk/doc/xml/about_qt.xml 2010-01-22 19:32:19 UTC (rev 466) @@ -1,26 +0,0 @@ -<?xml version="1.0"?> <!-- -*- sgml -*- --> -<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" - "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> - -<article> - - <artheader><title>Qt</title></artheader> - - -<para>This program was built using Qt version %1,<br/>and is running using Qt version %2.</para> - -<para>Qt is a C++ toolkit for multi-platform GUI and application -development. Qt provides single-source portability across MS Windows, -Mac OS, X, Linux, and all major commercial Unix variants. Qt is also -available for embedded devices.</para> - -<para>See <ulink url="http://www.trolltech.com/qt/">http://www.trolltech.com/qt/</ulink> for more information.</para> - -<informaltable class="nav" width="100%"> -<tbody><tr> - <td align="center">Copyright (c) Trolltech<br/> - <ulink url="http://www.trolltech.com">www.trolltech.com</ulink></td> -</tr></tbody> -</informaltable> - -</article> Modified: trunk/doc/xml/about_vk.xml =================================================================== --- trunk/doc/xml/about_vk.xml 2010-01-13 22:07:17 UTC (rev 465) +++ trunk/doc/xml/about_vk.xml 2010-01-22 19:32:19 UTC (rev 466) @@ -15,6 +15,8 @@ <para>Valkyrie is a graphical user interface for Valgrind: <ulink url="http://www.valgrind.org">www.valgrind.org</ulink>.</para> +<para>This program was built using Qt v%1, and is running using Qt v%2.</para> + <para>You can download the latest version of Valkyrie from the OpenWorks website: <ulink url="http://&vk-url;"></ulink>.</para> |
From: <sv...@va...> - 2010-01-13 22:07:30
|
Author: cerion Date: 2010-01-13 22:07:17 +0000 (Wed, 13 Jan 2010) New Revision: 465 Log: Help (handbook, context help, about) is with us again. Added: branches/valkyrie_qt4port/help/ branches/valkyrie_qt4port/help/help_about.cpp branches/valkyrie_qt4port/help/help_about.h branches/valkyrie_qt4port/help/help_context.cpp branches/valkyrie_qt4port/help/help_context.h branches/valkyrie_qt4port/help/help_handbook.cpp branches/valkyrie_qt4port/help/help_handbook.h branches/valkyrie_qt4port/help/help_urls.cpp branches/valkyrie_qt4port/help/help_urls.h branches/valkyrie_qt4port/icons/context_help.xpm Modified: branches/valkyrie_qt4port/icons.qrc branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_cb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_ck_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_le_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_sp_widget.cpp branches/valkyrie_qt4port/utils/vk_config.cpp branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/valkyrie.pro Added: branches/valkyrie_qt4port/help/help_about.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_about.cpp (rev 0) +++ branches/valkyrie_qt4port/help/help_about.cpp 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,125 @@ +/**************************************************************************** +** HelpAbout implementation +** - small tab dialog showing various information re license etc. +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "help/help_about.h" +#include "utils/vk_config.h" +#include "utils/vk_utils.h" + +#include <QFile> +#include <QLabel> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QPixmap> +#include <QPushButton> +#include <QTextStream> + +/*! + Constructs a HelpAbout dialog with the given \a parent and \a tabid. +*/ +HelpAbout::~HelpAbout() { } + +HelpAbout::HelpAbout( QWidget* parent, HELPABOUT::TabId tabid ) + : QDialog( parent ) +{ + setObjectName(QString::fromUtf8("HelpAbout")); + title = vkConfig->vkName + " Information"; + setWindowTitle( title ); + + // top layout + QVBoxLayout* vbox = new QVBoxLayout( this ); + vbox->setObjectName(QString::fromUtf8("vbox")); + + // widget for the top part + QWidget* hLayoutWidget = new QWidget( this ); + hLayoutWidget->setObjectName(QString::fromUtf8("hLayoutWidget")); + vbox->addWidget( hLayoutWidget ); + + // hbox for pic + appname + QHBoxLayout* hbox = new QHBoxLayout( hLayoutWidget ); + hbox->setObjectName(QString::fromUtf8("hbox")); + + // pic + QLabel* pic = new QLabel( this ); + pic->setPixmap( QPixmap( ":/vk_icons/icons/valkyrie.xpm" ) ); + pic->setFixedSize( pic->sizeHint() ); + hbox->addWidget( pic ); + + // app info + QLabel* appName = new QLabel( this ); + QString str = vkConfig->vkName + " " + vkConfig->vkVersion; + appName->setText( str ); + appName->setFont(QFont( "Times", 18, QFont::Bold) ); + appName->setFixedSize( appName->sizeHint() ); + hbox->addWidget( appName ); + + // push the pix+info over to the left + hbox->addStretch( 10 ); + + // tabwidget + tabParent = new QTabWidget( this ); + tabParent->setObjectName(QString::fromUtf8("tabParent")); + connect( tabParent, SIGNAL(currentChanged( int )), + this, SLOT(showTab( int )) ); + vbox->addWidget( tabParent ); + + // about_vk tab + aboutVk = new QTextBrowser( tabParent ); + aboutVk->setObjectName(QString::fromUtf8("aboutVk")); + str = "About " + vkConfig->vkName; + tabParent->insertTab( HELPABOUT::ABOUT_VK, aboutVk, str ); + + // license tab + license = new QTextBrowser( tabParent ); + license->setObjectName(QString::fromUtf8("license")); + tabParent->insertTab( HELPABOUT::LICENSE, license, "License Agreement" ); + + // support tab + support = new QTextBrowser( tabParent ); + support->setObjectName(QString::fromUtf8("support")); + tabParent->insertTab( HELPABOUT::SUPPORT, support, "Support" ); + + + QPushButton* okButt = new QPushButton( "Close", this); + okButt->setDefault( true ); + okButt->setFixedSize( okButt->sizeHint() ); + connect( okButt, SIGNAL(clicked() ), this, SLOT(accept())); + okButt->setFocus(); + vbox->addWidget( okButt, 0, Qt::AlignRight ); + + // setup text-browsers + license->setSource( vkConfig->vkDocPath + "about_gpl.html" ); + support->setSource( vkConfig->vkDocPath + "support.html" ); + // about_vk source needs version args updating: + QFile file( vkConfig->vkDocPath + "about_vk.html" ); + if ( file.open( QIODevice::ReadOnly ) ) { + QTextStream ts( &file ); + aboutVk->setText( ts.readAll().arg( QT_VERSION_STR ).arg( qVersion() ) ); + } + + // start up with the correct page loaded + tabParent->setCurrentIndex( tabid ); + // and start up at a reasonable size + resize( 600, 380 ); +} + +void HelpAbout::showTab( int idx ) +{ + setWindowTitle( title + " : " + tabParent->tabText( idx ) ); +} Added: branches/valkyrie_qt4port/help/help_about.h =================================================================== --- branches/valkyrie_qt4port/help/help_about.h (rev 0) +++ branches/valkyrie_qt4port/help/help_about.h 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,56 @@ +/**************************************************************************** +** HelpAbout definition +** - small tabbed dialog showing misc. info re license etc. +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __VK_HELP_ABOUT_H +#define __VK_HELP_ABOUT_H + +#include "help/help_handbook.h" // VkTextBrowser + +#include <QDialog> +#include <QTabWidget> + +namespace HELPABOUT { +/*! + enum identification for available help page tabs +*/ + enum TabId { ABOUT_VK=0, LICENSE, SUPPORT, NUM_TABS }; +} + +// ============================================================ +class HelpAbout : public QDialog +{ + Q_OBJECT +public: + HelpAbout( QWidget* parent, HELPABOUT::TabId tabid ); + ~HelpAbout(); + +private slots: + void showTab( int ); + +private: + QString title; + + QTabWidget* tabParent; + QTextBrowser* aboutVk; + QTextBrowser* license; + QTextBrowser* support; +}; + +#endif Added: branches/valkyrie_qt4port/help/help_context.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_context.cpp (rev 0) +++ branches/valkyrie_qt4port/help/help_context.cpp 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,333 @@ +/**************************************************************************** +** ContextHelp implementation +** - context-sensitive help +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 <QApplication> +#include <QDesktopWidget> +#include <QMouseEvent> + + +#include "help/help_context.h" +#include "help/help_handbook.h" +#include "utils/vk_utils.h" // VK_DEBUG + + +// There can be only one. +static ContextHelp* ctxt = 0; + + + +/*! + class ContextHelpAction +*/ +ContextHelpAction::~ContextHelpAction() +{ + if ( ctxt ) { + ctxt->actions.removeAll( this ); // remove widget from list +// TODO: check return value - num removed should only ever be 1. + } +} + + +ContextHelpAction::ContextHelpAction( QWidget* parent, HandBook* book ) + : QAction( parent ) +{ + setObjectName(QString::fromUtf8("ctxt_help_tb")); + + ContextHelp::setupSingleton(); + + ctxt->actions.append( this ); + ctxt->hbook = book; + + setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/context_help.xpm") ) ); + setCheckable( true ); + setIconVisibleInMenu(true); +#if 0 + setAutoRaise( true ); + setFocusPolicy( Qt::NoFocus ); +#endif + this->setToolTip( "This is a <b>Context Help</b> button. Clicking on a widget will open the relevant manual help page" ); + + connect( this, SIGNAL( triggered( bool ) ), + this, SLOT( startListening( bool ) ) ); +} + + +/*! + Action triggered + - start global listen for a left mouse click on a widget +*/ +void ContextHelpAction::startListening( bool checked ) +{ + // if not already active && this button is on... + if ( !ctxt->listeningForEvent && checked ) { + QApplication::setOverrideCursor( Qt::WhatsThisCursor ); + ctxt->listeningForEvent = true; + qApp->installEventFilter( ctxt ); + } +} + + + + + +/*! + class ContextHelp +*/ +static void qContextHelpCleanup() +{ + if ( ctxt ) { + delete ctxt; + ctxt = 0; + } +} + + +ContextHelp::ContextHelp() + : QObject( 0 ) +{ + setObjectName(QString::fromUtf8("ctxt_help_tb")); + ctxt = this; + listeningForEvent = false; +} + + +ContextHelp::~ContextHelp() +{ + if ( listeningForEvent == true && qApp ) + QApplication::restoreOverrideCursor(); + + actions.clear(); + wdict.clear(); + + ctxt = 0; +} + + +/*! + removes the Context help associated with the widget. + this happens automatically if the widget is destroyed. +*/ +void ContextHelp::remove( QWidget* widget ) +{ + vk_assert( widget != NULL ); + + wdict.remove( widget ); +// TODO: check return value - num removed should only ever be 1. +} + + +bool ContextHelp::eventFilter( QObject* obj, QEvent* ev ) +{ + if ( listeningForEvent ) { + + if ( ev->type() == QEvent::MouseButtonPress && obj->isWidgetType() ) { + QWidget* widg = (QWidget*) obj; + if ( ( (QMouseEvent*)ev)->button() == Qt::RightButton ) + return false; // ignore right mouse button + + QString url; + while ( widg && url.isEmpty() ) { + if (widg->inherits("QMenuBar")) { + // If we're a qmenubar, allow event to pass on so menus work... + // TODO: find what menuitem we're sitting on, if any, and get that widget... + return false; + } + url = wdict.value( widg ); + if ( url.isEmpty() ) { + // pos += widg->pos(); + widg = widg->parentWidget(); // 0 if no parent + } + } + cancelHelpEvent(); + + if ( !widg || url.isEmpty() ) { +//TODO: vkMsg? + cerr << "No help found for this widget" << endl; + return true; + } + + showHelp( url ); + return true; + } + else if ( ev->type() == QEvent::MouseButtonRelease ) { + if ( ( (QMouseEvent*)ev)->button() == Qt::RightButton ) + return false; // ignore right mouse button + return !obj->isWidgetType(); + } + else if ( ev->type() == QEvent::MouseMove ) { + return !obj->isWidgetType(); + } + else if ( ev->type() == QEvent::KeyPress ) { + QKeyEvent* kev = (QKeyEvent*)ev; + if ( kev->key() == Qt::Key_Escape ) { + cancelHelpEvent(); + return true; + } + else if ( kev->key() == Qt::Key_Menu || + ( kev->key() == Qt::Key_F10 && + (kev->modifiers() & Qt::ShiftModifier) ) ) { +//TODO: test shift-F10. modifiers() may not be trustworthy. + + // don't react to these keys: they are used for context menus + return false; + } +#if 0 // TODO: how to do this in Qt4? + else if ( kev->state() == kev->stateAfter() && + kev->key() != Qt::Key_Meta ) { + // not a modifier key + cancelHelpEvent(); + } +#endif + } + else if ( ev->type() == QEvent::MouseButtonDblClick ) { + return true; + } + } + + return false; +} + + +void ContextHelp::setupSingleton() +{ + if ( !ctxt ) { + ctxt = new ContextHelp(); + + +//TODO: this really necessary? +// not better to setup a parent, so gets auto-deleted at app close? +// or just create and delete in main()? + + /* it is necessary to use a post routine, because the destructor + deletes pixmaps and other stuff that needs a working X + connection under X11. */ + qAddPostRoutine( qContextHelpCleanup ); + } +} + + +/*! + Cancel the context help + - reset actions, cursor, remove eventfilter +*/ +void ContextHelp::cancelHelpEvent() +{ + if ( listeningForEvent ) { + // set all actions off. + foreach( ContextHelpAction* act, ctxt->actions ) { + act->setChecked( false ); + } + + QApplication::restoreOverrideCursor(); + listeningForEvent = false; + qApp->removeEventFilter( this ); + } +} + + +/*! + Open help at url +*/ +void ContextHelp::showHelp( const QString &text ) +{ + cerr << "ContextHelp::showHelp: '" << text.toLatin1().constData() << "'" << endl; + + if ( text.isEmpty() ) + return; + + if ( !hbook->isVisible() ) { + + // find out where MainWindow is, and park up beside it + QWidget* mw = qApp->activeWindow(); + int scr = QApplication::desktop()->screenNumber( mw ); + QRect screen = QApplication::desktop()->screenGeometry( scr ); + + int x; + int hw = hbook->width(); + + // get the global co-ords of the top-left pixel of MainWin + QPoint pos = mw->mapToGlobal( QPoint( 0,0 ) ); + if ( hw < ( pos.x() - screen.x() ) ) + x = pos.x() - hw; + else + x = pos.x() + mw->width(); + + hbook->move( x, pos.y() ); + hbook->show(); + } + + hbook->raise(); + hbook->openUrl( text ); +} + + +/*! + Only of our registed widgets died: remove it from the list +*/ +void ContextHelp::cleanupWidget() +{ + const QObject* obj = sender(); + if ( !obj->isWidgetType() ) { // sanity check + cerr << "Error: ContextHelp::cleanupWidget(): " + << "signal received from non-widget: " + << qPrintable( obj->objectName() ) << endl; + } else { + remove( (QWidget*)obj ); + } +} + + +/*! + Add help url to widget +*/ +void ContextHelp::newItem( QWidget* widg, const QString& url ) +{ + // in case widg already in our lists, replace it. + if ( wdict.contains( widg ) ) { + cerr << "ContextHelp::newItem(): widg (" + << qPrintable( widg->objectName() ) << ") was registered to: '" + << qPrintable( wdict.value( widg ) ) << "'" << endl + << " - Replacing with: '" << qPrintable( url ) << "'" << endl; + wdict.remove( widg ); + } + + // add to our list + wdict.insert( widg, url ); + + // make sure to remove mappings that no longer exist. + connect( widg, SIGNAL(destroyed()), + this, SLOT(cleanupWidget()) ); +} + + +/*! + Static function: + - Initialise context help singleton if necessary + - Add help url to given widget +*/ +void ContextHelp::addHelp( QWidget* widg, const QString& url ) +{ + vk_assert( widg != NULL ); + if ( !url.isEmpty() ) { + setupSingleton(); + ctxt->newItem( widg, url ); + } +} + Added: branches/valkyrie_qt4port/help/help_context.h =================================================================== --- branches/valkyrie_qt4port/help/help_context.h (rev 0) +++ branches/valkyrie_qt4port/help/help_context.h 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,82 @@ +/**************************************************************************** +** ContextHelp definition +** - context-sensitive help button +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __VK_HELP_CONTEXT_H +#define __VK_HELP_CONTEXT_H + +#include <QAction> +#include <QHash> +#include <QList> +#include <QString> +#include <QToolButton> +#include <QWidget> + + +// Forward decls +class HandBook; + + +// ============================================================ +class ContextHelpAction: public QAction +{ + Q_OBJECT +public: + ContextHelpAction( QWidget* parent, HandBook* book ); + ~ContextHelpAction(); + +public slots: + void startListening( bool checked ); +}; + + + + +// ============================================================ +class ContextHelp: public QObject +{ + Q_OBJECT + friend class ContextHelpAction; + +public: + ContextHelp(); + ~ContextHelp(); + static void addHelp( QWidget*, const QString&); + +private: + static void setupSingleton(); + + bool eventFilter( QObject*, QEvent* ); + void newItem( QWidget* widget, const QString& text ); + void showHelp( const QString& ); + void cancelHelpEvent(); + void remove( QWidget* ); + + HandBook* hbook; // ptr to the application-wide handbook + + QHash<QWidget*, QString> wdict; // mapping widg->url + QList<ContextHelpAction*> actions; // allows turning off all registered ctxt help actions + bool listeningForEvent; + +private slots: + void cleanupWidget(); +}; + + +#endif // #ifndef __VK_HELP_CONTEXT_H Added: branches/valkyrie_qt4port/help/help_handbook.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.cpp (rev 0) +++ branches/valkyrie_qt4port/help/help_handbook.cpp 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,577 @@ +/**************************************************************************** +** HandBook implementation +** - context-sensitive help browser +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "help/help_handbook.h" +//#include "tb_handbook_icons.h" +#include "utils/vk_config.h" +//#include "vk_messages.h" +#include "utils/vk_utils.h" + + +#include "QApplication" +#include "QDockWidget" +#include "QFile" +#include "QFileDialog" +#include "QMenu" +#include "QPrinter" +#include "QProcess" +#include "QString" +#include "QStringList" +#include "QTextStream" +#include "QToolBar" + + + +/*! + class HandBook +*/ +HandBook::~HandBook() +{ + // save history + bookmarks + save(); +} + + +HandBook::HandBook( QWidget* parent ) //, const char* name ) + : QMainWindow( parent ) +//TODO: ? +//, name, WDestructiveClose ) +//? Qt::WA_DeleteOnClose +{ + setObjectName(QString::fromUtf8("handbook")); + + QString VkName = vkConfig->vkName; + VkName.replace( 0, VkName[0].toUpper() ); + + caption = VkName + " HandBook"; + this->setWindowTitle( caption ); + setWindowIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_help.xpm") ) ); + + browser = new QTextBrowser( this ); + setCentralWidget( browser ); + + mkMenuToolBars(); + + browser->setOpenExternalLinks( true ); + browser->setFrameStyle( QFrame::Panel | QFrame::Sunken ); + + // set the list of dirs to search when files are requested + QStringList paths; + paths << vkConfig->vkDocPath; + browser->setSearchPaths( paths ); + + connect( browser, SIGNAL( sourceChanged(const QUrl&) ), + this, SLOT( sourceChanged(const QUrl&) ) ); +// connect( browser, SIGNAL( highlighted(const QString&) ), +// statusBar(), SLOT( showMessage(const QString&)) ); + connect( bookmarkMenu, SIGNAL( hovered(QAction*) ), + this, SLOT( bookmarkHighlighted(QAction*)) ); + + + // default startup is with the index page loaded + QString home = vkConfig->vkDocPath + "/index.html"; + browser->setSource( home ); + +//TODO: vkErrors? hmm. in a constructor... + +//TODO: vkConfig + resize( 560, 600 ); + hide(); +} + + +void HandBook::historyChosen( QAction* act ) +{ + browser->setSource( act->text() ); +} + + +void HandBook::bookmarkChosen( QAction* act ) +{ + if ( !bookmarkMenu->actions().contains( act ) ) { +//TODO: shouldn't ever happen: vkError + return; + } + + QString url = act->data().toString(); +// browser->setSource( url ); +} + + +void HandBook::bookmarkHighlighted( QAction* act ) +{ + if ( !bookmarkMenu->actions().contains( act ) ) { + cerr << "Error: act not in bookmarks!" << endl; +//TODO: shouldn't ever happen: vkError + return; + } + if ( act->objectName() != QString::fromUtf8("handbook_actBookmark") ) { + // other actions besides bookmarks are in the menu -> ignore. + return; + } + + QString link = act->data().toString(); +//TODO: why doesn't this work?! +// appears _very_ briefly and gets cleared => flickers. + statusBar()->showMessage( link, 1000 ); +} + + + +void HandBook::addBookmark() +{ + QString url = browser->source().toString(); + QString title = browser->documentTitle(); + if ( browser->documentTitle().isNull() ) { + title = url; + } + + // just show the page title in the menu, but hold onto the url + QAction* actNew = new QAction( this ); + actNew->setObjectName( QString::fromUtf8("handbook_actBookmark") ); + actNew->setText( title ); + actNew->setData( url ); + bookmarkMenu->addAction( actNew ); + + // Don't let bookmarks grow endlessly + // - find first bookmark action + // - count how many actions from there + // - remove that first action if necessary + int nActsBefore=0; + QAction* actFirst; + foreach( actFirst, bookmarkMenu->actions() ) { + // skip non-bookmark actions + if ( actFirst->objectName() == QString::fromUtf8("handbook_actBookmark") ) { + break; + } + nActsBefore++; + } + if ( (bookmarkMenu->actions().count() - nActsBefore) > max_bookmarks ) { + bookmarkMenu->removeAction( actFirst ); + delete actFirst; + } +} + + +// the handbook is explicitly killed by MainWindow on exit. +void HandBook::closeEvent( QCloseEvent* ) +{ + hide(); +} + + +void HandBook::showYourself() +{ + if ( !isVisible() ) { + show(); + } else if ( isMinimized() ) { + showNormal(); + } else { + raise(); + } +} + + +/*! + Sets the name of the displayed document to url +*/ +void HandBook::openUrl( const QString& url ) +{ + browser->setSource( url ); +} + + +/*! + Open a user-specified html file +*/ +void HandBook::openFile() +{ + QString fn = QFileDialog::getOpenFileName( this, "Open File", vkConfig->vkDocPath, + "Html Files (*.html *.htm);;All Files (*)" ); + if ( !fn.isEmpty() ) { + browser->setSource( fn ); + } +} + + +/*! + source changed (not from pathCombo) + - update pathCombo +*/ +void HandBook::sourceChanged( const QUrl& url ) +{ + QString link = url.toString(); +// vkPrint("CHECKME: sourceChanged() link: '%s'", qPrintable( link ) ); + +//TODO: if link.isEmpty -> 404 + + if ( browser->documentTitle().isNull() ) + setWindowTitle( "VkHelp - " + link ); + else + setWindowTitle( "VkHelp - " + browser->documentTitle() ) ; + + if ( !link.isEmpty() && pathCombo ) { + + // pathCombo is not kept in-sync with history + int idx = pathCombo->findText( link, Qt::MatchFixedString ); // not case-sensitive + if ( idx != -1 ) { + pathCombo->setCurrentIndex( idx ); + } else { + // combobox + pathCombo->insertItem( 0, link ); + pathCombo->setCurrentIndex( 0 ); + if ( pathCombo->count() > max_history ) { + pathCombo->removeItem( max_history ); + } + } + + // history menu: if already in history, move to top. + bool found = false; + foreach( QAction* act, historyMenu->actions() ) { + if ( act->text() == link ) { + if ( found ) { + // shouldn't ever get here, but just in case. + historyMenu->removeAction( act ); + } + historyMenu->removeAction( act ); + historyMenu->insertAction( historyMenu->actions().first(), act ); + found = true; + } + } + if ( !found ) { + // not in history: prepend, and remove last if necessary + QAction* act = new QAction( this ); + act->setObjectName( QString::fromUtf8("handbook_actHistory") ); + act->setText( link ); + if ( ! historyMenu->actions().isEmpty() ) { + historyMenu->insertAction( historyMenu->actions().first(), act ); + } else { + historyMenu->addAction( act ); + } + if ( historyMenu->actions().count() > max_history ) { + QAction* act = historyMenu->actions().last(); + historyMenu->removeAction( act ); + delete act; + } + } + } +} + + +void HandBook::mkMenuToolBars() +{ + menuBar = new QMenuBar( this ); + menuBar->setObjectName(QString::fromUtf8("help_menubar")); + this->setMenuBar( menuBar ); + + // ------------------------------------------------------------ + // file menu + QMenu* fileMenu = new QMenu( menuBar ); + fileMenu->setObjectName( QString::fromUtf8("handbook_fileMenu") ); + fileMenu->setTitle( QApplication::translate("MainWindowClass", "&File", 0, QApplication::UnicodeUTF8) ); + menuBar->addAction( fileMenu->menuAction() ); + + QAction* actFile_Open = new QAction( this ); + actFile_Open->setObjectName( QString::fromUtf8("handbook_actFile_Open") ); + actFile_Open->setText( QApplication::translate("HandBook", "Open File", 0, QApplication::UnicodeUTF8) ); + connect( actFile_Open, SIGNAL( triggered() ), this, SLOT( openFile() ) ); + + QAction* actFile_Close = new QAction( this ); + actFile_Close->setObjectName( QString::fromUtf8("handbook_actFile_Close") ); + actFile_Close->setText( QApplication::translate("HandBook", "Close", 0, QApplication::UnicodeUTF8) ); + connect( actFile_Close, SIGNAL( triggered() ), this, SLOT( close() ) ); + + fileMenu->addAction( actFile_Open ); + fileMenu->addSeparator(); + fileMenu->addAction( actFile_Close ); + + // ------------------------------------------------------------ + // go menu + QMenu* goMenu = new QMenu( menuBar ); + goMenu->setObjectName( QString::fromUtf8("handbook_goMenu") ); + goMenu->setTitle( QApplication::translate("MainWindowClass", "&Go", 0, QApplication::UnicodeUTF8) ); + menuBar->addAction( goMenu->menuAction() ); + + QAction* actGo_Backward = new QAction( this ); + actGo_Backward->setObjectName( QString::fromUtf8("handbook_actGo_Backward") ); + actGo_Backward->setText( QApplication::translate("HandBook", "Backward", 0, QApplication::UnicodeUTF8) ); + actGo_Backward->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_back.xpm") ) ); + connect( actGo_Backward, SIGNAL( triggered() ), browser, SLOT( backward() ) ); + + QAction* actGo_Forward = new QAction( this ); + actGo_Forward->setObjectName( QString::fromUtf8("handbook_actGo_Forward") ); + actGo_Forward->setText( QApplication::translate("HandBook", "Forward", 0, QApplication::UnicodeUTF8) ); + actGo_Forward->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_forward.xpm") ) ); + connect( actGo_Forward, SIGNAL( triggered() ), browser, SLOT( forward() ) ); + + QAction* actGo_Home = new QAction( this ); + actGo_Home->setObjectName( QString::fromUtf8("handbook_actGo_Home") ); + actGo_Home->setText( QApplication::translate("HandBook", "Home", 0, QApplication::UnicodeUTF8) ); + actGo_Home->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_home.xpm") ) ); + connect( actGo_Home, SIGNAL( triggered() ), browser, SLOT( home() ) ); + + QAction* actGo_Reload = new QAction( this ); + actGo_Reload->setObjectName( QString::fromUtf8("handbook_actGo_Reload") ); + actGo_Reload->setText( QApplication::translate("HandBook", "Reload", 0, QApplication::UnicodeUTF8) ); + actGo_Reload->setIcon( QPixmap( QString::fromUtf8(":/vk_icons/icons/tb_handbook_reload.xpm") ) ); + connect( actGo_Reload, SIGNAL( triggered() ), browser, SLOT( reload() ) ); + + goMenu->addAction( actGo_Backward ); + goMenu->addAction( actGo_Forward ); + goMenu->addAction( actGo_Home ); + // Dont add Reload here. + + actGo_Backward->setEnabled( false ); + actGo_Forward->setEnabled( false ); + connect( browser, SIGNAL( backwardAvailable( bool ) ), + actGo_Backward, SLOT( setEnabled( bool ) ) ); + connect( browser, SIGNAL( forwardAvailable( bool ) ), + actGo_Forward, SLOT( setEnabled( bool ) ) ); + + // ------------------------------------------------------------ + // history menu + historyMenu = new QMenu( menuBar ); + historyMenu->setObjectName( QString::fromUtf8("handbook_historyMenu") ); + historyMenu->setTitle( QApplication::translate("MainWindowClass", "History", 0, QApplication::UnicodeUTF8) ); + menuBar->addAction( historyMenu->menuAction() ); + connect( historyMenu, SIGNAL( triggered( QAction* ) ), + this, SLOT( historyChosen( QAction* ) ) ); + readHistory(); + + // ------------------------------------------------------------ + // bookmarks menu + bookmarkMenu = new QMenu( menuBar ); + bookmarkMenu->setObjectName( QString::fromUtf8("handbook_bookmarkMenu") ); + bookmarkMenu->setTitle( QApplication::translate("MainWindowClass", "Bookmark", 0, QApplication::UnicodeUTF8) ); + menuBar->addAction( bookmarkMenu->menuAction() ); + + QAction* actBM_AddBM = new QAction( this ); + actBM_AddBM->setObjectName( QString::fromUtf8("handbook_actBM_AddBM") ); + actBM_AddBM->setText( QApplication::translate("HandBook", "Add Bookmark", 0, QApplication::UnicodeUTF8) ); + connect( actBM_AddBM, SIGNAL( triggered() ), this, SLOT( addBookmark() ) ); + + bookmarkMenu->addAction( actBM_AddBM ); + bookmarkMenu->addSeparator(); + connect( bookmarkMenu, SIGNAL( triggered( QAction* ) ), + this, SLOT( bookmarkChosen( QAction* ) ) ); + readBookmarks(); + + + // ------------------------------------------------------------ + // dismiss button + QAction* act_dismiss = new QAction( this ); + act_dismiss->setObjectName( QString::fromUtf8("act_dismiss") ); + act_dismiss->setText( QApplication::translate("HandBook", "Dismiss", 0, QApplication::UnicodeUTF8) ); + connect( act_dismiss, SIGNAL( triggered() ), + this, SLOT( close() ) ); + + menuBar->addSeparator(); + menuBar->addAction( act_dismiss ); + + + // ------------------------------------------------------------ + // toolbar + QToolBar* toolbar = new QToolBar( this ); + toolbar->setObjectName( QString::fromUtf8("handbook_toolbar") ); + this->addToolBar( Qt::TopToolBarArea, toolbar ); + toolbar->setAllowedAreas( Qt::TopToolBarArea | Qt::BottomToolBarArea); + + toolbar->addAction( actGo_Backward ); + toolbar->addAction( actGo_Forward ); + toolbar->addAction( actGo_Home ); + toolbar->addAction( actGo_Reload ); + toolbar->addSeparator(); + + pathCombo = new QComboBox( toolbar ); + pathCombo->setEditable( true ); + pathCombo->addItem( vkConfig->vkDocPath ); + QSizePolicy sp = pathCombo->sizePolicy(); + sp.setHorizontalPolicy( QSizePolicy::MinimumExpanding ); + pathCombo->setSizePolicy( sp ); + connect( pathCombo, SIGNAL( activated(const QString &) ), + this, SLOT( openUrl(const QString &) ) ); + toolbar->addWidget( pathCombo ); + + + // ------------------------------------------------------------ + // Basic statusbar setup + statusBar()->setObjectName( QString::fromUtf8("helpStatusBar ") ); +//TODO: why disable? +// statusBar()->setSizeGripEnabled( false ); +} + + + +void HandBook::save() +{ + vk_assert( historyMenu->actions().count() <= max_history ); + +//TODO: do this via vkConfig! +#if 0 +//TODO: need to write to _global_ config, not project/temp config... + QStringList history; + foreach( QAction* act, historyMenu->actions() ) { + history << act->text(); + } + vkConfig->setValue( "handbook/history", history ); + + int nBookmarks = 0; + QStringList bookmarks; + foreach( QAction* act, historyMenu->actions() ) { + // skip non-bookmark actions + if ( act->objectName() == QString::fromUtf8("handbook_actBookmark") ) { + bookmarks << act->text() + vkConfig->vkSepChar + act->data().toString(); + nBookmarks++; + } + } + vkConfig->setValue( "handbook/bookmarks", bookmarks ); + + vk_assert( nBookmarks <= max_bookmarks ); + +#else + // save the history + QFile aFile( vkConfig->vkRcDir + "/help.history" ); + if ( aFile.open( QIODevice::WriteOnly ) ) { + QTextStream stream( &aFile ); + + foreach( QAction* act, historyMenu->actions() ) { + stream << act->text() << "\n"; + } + aFile.close(); + } + + // save the bookmarks + aFile.setFileName( vkConfig->vkRcDir + "/help.bookmarks" ); + if ( aFile.open( QIODevice::WriteOnly ) ) { + QTextStream stream( &aFile ); + + int nBookmarks=0; + foreach( QAction* act, bookmarkMenu->actions() ) { + // skip non-bookmark actions + if ( act->objectName() == QString::fromUtf8("handbook_actBookmark") ) { + stream << act->text() + << vkConfig->vkSepChar + << act->data().toString() << "\n"; + nBookmarks++; + } + } + aFile.close(); + + vk_assert( nBookmarks <= max_bookmarks ); + } +#endif +} + + +/*! + load the history from file into the menu +*/ +void HandBook::readHistory() +{ + bool ok = false; + max_history = vkConfig->value( "handbook/max_history", 20 ).toInt( &ok ); + if (!ok) cerr << "Error: bad value for config::handbook/max_history" << endl; + +// TODO: do this via vkConfig! +#if 0 +//TODO: need to write to _global_ config, not project/temp config... + QStringList history = vkConfig->value( "handbook/history" ).toStringList(); + int len = history.count() > max_history ? max_history : history.count(); + for ( int idx=0; idx < len; idx++ ) { + QString link = history.at( idx ); + + QAction* act = new QAction( this ); + act->setObjectName( QString::fromUtf8("handbook_actHistory") ); + act->setText( link ); + historyMenu->addAction( act ); + } +#else + QFile aFile( vkConfig->vkRcDir + "/help.history" ); + + if ( aFile.open( QIODevice::ReadOnly ) ) { + // read in max_history links + QTextStream stream( &aFile ); + for ( int idx=0; idx < max_history && !stream.atEnd(); idx++ ) { + QString link = stream.readLine(); + + QAction* act = new QAction( this ); + act->setObjectName( QString::fromUtf8("handbook_actHistory") ); + act->setText( link ); + historyMenu->addAction( act ); + } + aFile.close(); + } +#endif +} + + + +/*! + load the bookmarks from file into the menu +*/ +void HandBook::readBookmarks() +{ + bool ok = false; + max_bookmarks = vkConfig->value( "handbook/max_bookmarks", 20 ).toInt(&ok); + if (!ok) cerr << "Error: bad value for config::handbook/max_bookmarks" << endl; + +// TODO: do this via vkConfig! +#if 0 +//TODO: need to write to _global_ config, not project/temp config... + QStringList bookmarks = vkConfig->value( "handbook/bookmarks" ).toStringList(); + int len = bookmarks.count() > max_bookmarks ? max_bookmarks : bookmarks.count(); + for ( int idx=0; idx < len; idx++ ) { + QString str = bookmarks.at( idx ); + + QStringList sl = str.split( vkConfig->vkSepChar ); + QString title = sl.first(); + QString url = sl.last(); + + // menu list + QAction* act = new QAction( this ); + act->setObjectName( QString::fromUtf8("handbook_actBookmark") ); + act->setText( title ); + act->setData( url ); + bookmarkMenu->addAction( act ); + } + +#else + QFile aFile( vkConfig->vkRcDir + "/help.bookmarks" ); + + if ( aFile.open( QIODevice::ReadOnly ) ) { + // read in max_bookmarks links + QTextStream stream( &aFile ); + for ( int idx=0; idx < max_bookmarks && !stream.atEnd(); idx++ ) { + // read in one line at a time, and split on vkSepChar + QStringList sl = stream.readLine().split( vkConfig->vkSepChar ); + QString title = sl.first(); + QString url = sl.last(); + + // menu list + QAction* act = new QAction( this ); + act->setObjectName( QString::fromUtf8("handbook_actBookmark") ); + act->setText( title ); + act->setData( url ); + bookmarkMenu->addAction( act ); + } + aFile.close(); + } +#endif +} Added: branches/valkyrie_qt4port/help/help_handbook.h =================================================================== --- branches/valkyrie_qt4port/help/help_handbook.h (rev 0) +++ branches/valkyrie_qt4port/help/help_handbook.h 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,76 @@ +/**************************************************************************** +** HandBook definition +** - Context-sensitive help browser +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __VK_HELP_HANDBOOK_H +#define __VK_HELP_HANDBOOK_H + +#include <QComboBox> +#include <QMainWindow> +#include <QMenu> +#include <QMenuBar> +#include <QStatusBar> +#include <QTextBrowser> + + + +// ============================================================ +class HandBook : public QMainWindow +{ + Q_OBJECT +public: + HandBook( QWidget* parent=0 ); + ~HandBook(); + +public slots: + void openUrl( const QString& url ); + void showYourself(); + +protected: + void closeEvent( QCloseEvent* ce ); + +private slots: + void sourceChanged(const QUrl& url); + void openFile(); + void historyChosen( QAction* act ); + void bookmarkChosen( QAction* act ); + void bookmarkHighlighted( QAction* act ); + void addBookmark(); + +private: + void mkMenuToolBars(); + void save(); + void readHistory(); + void readBookmarks(); + +private: + QString caption; + QTextBrowser* browser; + QComboBox* pathCombo; + QMenuBar* menuBar; + QStatusBar* helpStatusBar; + QMenu* bookmarkMenu; + QMenu* historyMenu; + + int max_history; + int max_bookmarks; +}; + + +#endif // #ifndef __VK_HELP_HANDBOOK_H Added: branches/valkyrie_qt4port/help/help_urls.cpp =================================================================== --- branches/valkyrie_qt4port/help/help_urls.cpp (rev 0) +++ branches/valkyrie_qt4port/help/help_urls.cpp 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,157 @@ +/**************************************************************************** +** URL strings definition +** - placed in one file in an endeavour to minimise +** what is probably going to be a maintenance nightmare. +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "help_urls.h" + + +// not every flag/option has context-sensitive help +const char* urlNone = ""; + + +// ============================================================ +// Valkyrie +namespace urlValkyrie { + + // Mainwindow + const char* menuBar = "mainwindow.html#menu_bar"; + const char* fileMenu = "mainwindow.html#file_menu"; + const char* toolMenu = "mainwindow.html#tools_menu"; + const char* optionsMenu = "mainwindow.html#options_menu"; + const char* runButton = "mainwindow.html#run_button"; + const char* stopButton = "mainwindow.html#stop_button"; + const char* helpMenu = "mainwindow.html#help_menu"; + const char* statusMsg = "mainwindow.status_msg.html"; + const char* flagsWidget = "mainwindow.flags_widget.html"; + + // options dialog + const char* optsDlg = "options_dialog.html"; + + // valkyrie's options page + const char* optsPage = "options_dialog.html#valkyrie"; + const char* toolTips = "options_dialog.html#tool_tips"; + const char* toolLabels = "options_dialog.html#tool_label"; + const char* browser = "options_dialog.html#browser"; + const char* logDir = "options_dialog.html#log_dir"; + const char* workingDir = "options_dialog.html#working_dir"; + const char* userFontGen = "options_dialog.html#user_font_general"; + const char* userFontTool = "options_dialog.html#user_font_tool"; + const char* palette = "options_dialog.html#palette"; + const char* srcLines = "options_dialog.html#src_lines"; + const char* srcEditor = "options_dialog.html#src_editor"; + const char* binary = "options_dialog.html#binary"; + const char* binFlags = "options_dialog.html#bin_flags"; + const char* vgDir = "options_dialog.html#valgrind"; + + // valgrind's options page: tab Suppressions + const char* coreTab = "options_valgrind.html#core_tab"; + const char* errorTab = "options_valgrind.html#error_tab"; + const char* suppsTab = "options_valgrind.html#supps_tab"; + + // MemcheckView toolbuttons + const char* openAllButton = ""; + const char* openOneButton = ""; + const char* srcPathButton = ""; + const char* loadLogButton = ""; + const char* mrgLogButton = ""; + const char* saveLogButton = ""; + const char* suppEdButton = ""; +} + + +// ============================================================ +// Valgrind core +namespace urlVgCore { + // valgrind's options page: tab Core + const char* mainTool = "vg-manual-core.html#tool_name"; + const char* verbosity = "vg-manual-core.html#verbosity"; + const char* traceChild = "vg-manual-core.html#trace_children"; + const char* silentChild = "vg-manual-core.html#silent_child"; + const char* trackFds = "vg-manual-core.html#track_fds"; + const char* timeStamp = "vg-manual-core.html#time_stamp"; + const char* xmlOutput = "vg-manual-core.html#xml_output"; + const char* xmlComment = "vg-manual-core.html#xml_user_comment"; + const char* freeGlibc = "vg-manual-core.html#free_glibc"; + const char* showEmWarns = "vg-manual-core.html#show_emwarns"; + const char* smcSupport = "vg-manual-core.html#smc_support"; + const char* simHints = "vg-manual-core.html#simulation_hints"; + const char* kernelVariant = "vg-manual-core.html#kernel_variant"; + + // valgrind's options page: tab Error Reporting + const char* logToFd = "vg-manual-core.html#log2fd"; + const char* logToFile = "vg-manual-core.html#log2file"; + const char* logToSocket = "vg-manual-core.html#log2socket"; + const char* autoDemangle = "vg-manual-core.html#auto_demangle"; + const char* numCallers = "vg-manual-core.html#num_callers"; + const char* errorLimit = "vg-manual-core.html#error_limit"; + const char* stackTraces = "vg-manual-core.html#stack_traces"; + const char* genSuppressions = "vg-manual-core.html#gen_supps"; + const char* startDebugger = "vg-manual-core.html#attach_debugger"; + const char* whichDebugger = "vg-manual-core.html#which_debugger"; + const char* inputFd = "vg-manual-core.html#input_fd"; + const char* maxSFrames = "vg-manual-core.html#max_frames"; + + // only used by Memcheck and Massif + const char* Alignment = "vg-manual-core.html#alignment"; +} + + +// ============================================================ +// Memcheck +namespace urlMemcheck { + const char* optsMC = "vg-manual-mc.html"; + const char* Leakcheck = "vg-manual-mc.html#leakcheck"; + const char* Showreach = "vg-manual-mc.html#showreach"; + //const char* UndefVal = "vg-manual-mc.html#undefvalerrs"; + const char* TrackOri = "vg-manual-mc.html#undefvalerrs"; + const char* Leakres = "vg-manual-mc.html#leakres"; + const char* Freelist = "vg-manual-mc.html#freelist"; + const char* gcc296 = "vg-manual-mc.html#gcc296"; + const char* Partial = "vg-manual-mc.html#partial"; +} + + +// ============================================================ +// Cachegrind +namespace urlCachegrind { + const char* optsCG = "vg-manual-cg.html"; + const char* Cacheopts = "vg-manual-cg.html#cg-manual.cgopts"; + const char* Pid = "vg-manual-cg.html#pid"; + const char* Sort = "vg-manual-cg.html#sort"; + const char* Show = "vg-manual-cg.html#show"; + const char* Threshold = "vg-manual-cg.html#threshold"; + const char* Auto = "vg-manual-cg.html#auto"; + const char* Context = "vg-manual-cg.html#context"; + const char* Include = "vg-manual-cg.html#include"; +} + + +// ============================================================ +// Massif +namespace urlMassif { + const char* optsMS = "vg-manual-ms.html"; + const char* Heap = "vg-manual-ms.html#heap"; + const char* HeapAdmin = "vg-manual-ms.html#heap-admin"; + const char* Stacks = "vg-manual-ms.html#stacks"; + const char* Depth = "vg-manual-ms.html#depth"; + const char* AllocFn = "vg-manual-ms.html#alloc-fn"; + const char* Format = "vg-manual-ms.html#format"; +} + Added: branches/valkyrie_qt4port/help/help_urls.h =================================================================== --- branches/valkyrie_qt4port/help/help_urls.h (rev 0) +++ branches/valkyrie_qt4port/help/help_urls.h 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,154 @@ +/**************************************************************************** +** URL strings definition +** - placed in one file in an endeavour to minimise +** what is probably going to be a maintenance nightmare. +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __VK_HELP_URLS_H +#define __VK_HELP_URLS_H + + +// not every flag/option has context-sensitive help +extern const char* urlNone; + + +// ============================================================ +// Valkyrie +namespace urlValkyrie { + // Mainwindow + extern const char* menuBar; + extern const char* fileMenu; + extern const char* toolMenu; + extern const char* optionsMenu; + extern const char* runButton; + extern const char* stopButton; + extern const char* helpMenu; + extern const char* statusMsg; + extern const char* flagsWidget; + // options dialog + extern const char* optsDlg; + // valkyrie's options page + extern const char* optsPage; + extern const char* toolTips; + extern const char* toolLabels; + extern const char* browser; + extern const char* logDir; + extern const char* workingDir; + extern const char* userFontGen; + extern const char* userFontTool; + extern const char* palette; + extern const char* srcLines; + extern const char* srcEditor; + extern const char* binary; + extern const char* binFlags; + extern const char* vgDir; + // valgrind's options page + extern const char* coreTab; + extern const char* errorTab; + extern const char* suppsTab; + // MemcheckView tool buttons + extern const char* openAllButton; + extern const char* openOneButton; + extern const char* srcPathButton; + extern const char* loadLogButton; + extern const char* mrgLogButton; + extern const char* saveLogButton; + extern const char* suppEdButton; +} + + +// ============================================================ +// Valgrind core +namespace urlVgCore { + // valgrind's options page: tab Core + extern const char* mainTool; + extern const char* verbosity; + extern const char* xmlOutput; + extern const char* xmlComment; + extern const char* traceChild; + extern const char* silentChild; + extern const char* trackFds; + extern const char* timeStamp; + extern const char* freeGlibc; + extern const char* showEmWarns; + extern const char* smcSupport; + extern const char* simHints; + extern const char* kernelVariant; + // valgrind's options page: tab Error Reporting + extern const char* genSuppressions; + extern const char* autoDemangle; + extern const char* errorLimit; + extern const char* stackTraces; + extern const char* numCallers; + extern const char* maxSFrames; + extern const char* startDebugger; + extern const char* whichDebugger; + extern const char* inputFd; + extern const char* logToFd; + extern const char* logToFile; + extern const char* logToSocket; + // only used by Memcheck and Massif + extern const char* Alignment; +} + + +// ============================================================ +// Memcheck +namespace urlMemcheck { + extern const char* optsMC; + extern const char* Partial; + extern const char* Freelist; + extern const char* Leakcheck; + extern const char* Leakres; + extern const char* Showreach; + //extern const char* UndefVal; + extern const char* TrackOri; + extern const char* gcc296; +} + + +// ============================================================ +// Cachegrind +namespace urlCachegrind { + extern const char* optsCG; + extern const char* Cacheopts; + extern const char* Pid; + extern const char* Sort; + extern const char* Show; + extern const char* Threshold; + extern const char* Auto; + extern const char* Context; + extern const char* Include; +} + + +// ============================================================ +// Massif +namespace urlMassif { + extern const char* optsMS; + extern const char* optsMassif; + extern const char* Heap; + extern const char* HeapAdmin; + extern const char* Stacks; + extern const char* Depth; + extern const char* AllocFn; + extern const char* Format; +} + + +#endif Added: branches/valkyrie_qt4port/icons/context_help.xpm =================================================================== --- branches/valkyrie_qt4port/icons/context_help.xpm (rev 0) +++ branches/valkyrie_qt4port/icons/context_help.xpm 2010-01-13 22:07:17 UTC (rev 465) @@ -0,0 +1,22 @@ +/* XPM */ +static const char* context_help_xpm[] = { + "16 16 3 1", + " c None", + "+ c #000000", + "* c #000080", + "+ ***** ", + "++ *** *** ", + "+++ *** ***", + "++++ ** **", + "+++++ ** **", + "++++++ * ***", + "+++++++ *** ", + "++++++++ *** ", + "+++++++++ *** ", + "+++++ *** ", + "++ +++ ", + "+ +++ *** ", + " +++ *** ", + " +++ ", + " +++ ", + " +++ "}; Modified: branches/valkyrie_qt4port/icons.qrc =================================================================== --- branches/valkyrie_qt4port/icons.qrc 2010-01-08 21:43:43 UTC (rev 464) +++ branches/valkyrie_qt4port/icons.qrc 2010-01-13 22:07:17 UTC (rev 465) @@ -27,5 +27,6 @@ <file>icons/valkyrie.xpm</file> <file>icons/vglogview_read.xpm</file> <file>icons/vglogview_write.xpm</file> + <file>icons/context_help.xpm</file> </qresource> </RCC> Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2010-01-08 21:43:43 UTC (rev 464) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-13 22:07:17 UTC (rev 465) @@ -29,6 +29,9 @@ #include "toolview/memcheckview.h" #include "toolview/helgrindview.h" +#include "help/help_about.h" +#include "help/help_context.h" +#include "help/help_urls.h" #include "options/vk_option.h" #include "utils/vk_config.h" @@ -70,6 +73,9 @@ icon_vk.addPixmap( QPixmap( QString::fromUtf8(":/vk_icons/icons/valkyrie.xpm") ), QIcon::Normal, QIcon::Off ); setWindowIcon( icon_vk ); + // handbook: init before menubar / toolbar + handBook = new HandBook(); + // interface setup setupLayout(); setupActions(); @@ -95,6 +101,10 @@ vkConfig->setValue( "mainwindow/size", size() ); vkConfig->setValue( "mainwindow/pos", pos() ); vkConfig->sync(); + + // handbook has no parent, so have to delete it. + delete handBook; + handBook = 0; } @@ -265,7 +275,8 @@ menuBar = new QMenuBar( this ); menuBar->setObjectName( QString::fromUtf8("menuBar") ); menuBar->setGeometry( QRect(0, 0, 496, 25) ); - + this->setMenuBar( menuBar ); + menuFile = new QMenu( menuBar ); menuFile->setObjectName( QString::fromUtf8("menuFile") ); menuFile->setTitle( QApplication::translate("MainWindowClass", "&File", 0, QApplication::UnicodeUTF8) ); @@ -282,8 +293,10 @@ menuHelp->setObjectName( QString::fromUtf8("menuHelp") ); menuHelp->setTitle( QApplication::translate("MainWindowClass", "Help", 0, QApplication::UnicodeUTF8) ); - this->setMenuBar( menuBar ); + // application-wide context help button + ContextHelpAction* ctxtHlpAction = new ContextHelpAction( this, handBook ); + // ------------------------------------------------------------ // Add actions to menus menuBar->addAction( menuFile->menuAction() ); @@ -291,7 +304,10 @@ menuBar->addAction( menuProcess->menuAction() ); menuBar->addAction( menuTools->menuAction() ); menuBar->addAction( menuHelp->menuAction() ); - +//TODO: right justify + menuBar->addSeparator(); + menuBar->addAction( ctxtHlpAction ); + menuFile->addAction( actFile_NewProj ); menuFile->addAction( actFile_OpenProj ); menuFile->addSeparator(); @@ -348,9 +364,9 @@ // ------------------------------------------------------------ // Basic statusbar setup mainStatusBar = this->statusBar(); - mainStatusBar->setSizeGripEnabled( false ); mainStatusBar->setObjectName( QString::fromUtf8("mainStatusBar ") ); - mainStatusBar->setSizeGripEnabled( false ); +//TODO: why disable? +// mainStatusBar->setSizeGripEnabled( false ); statusLabel = new QLabel( mainStatusBar ); statusLabel->setObjectName( QString::fromUtf8("statusLabel ") ); @@ -613,7 +629,7 @@ */ void MainWindow::openHandBook() { - cerr << "TODO: MainWindow::openHandBook()" << endl; + handBook->showYourself(); } @@ -622,7 +638,8 @@ */ void MainWindow::openAboutVk() { - cerr << "TODO: MainWindow::openAboutVk()" << endl; + HelpAbout dlg( this, HELPABOUT::ABOUT_VK ); + dlg.exec(); } @@ -631,7 +648,8 @@ */ void MainWindow::openAboutLicense() { - cerr << "TODO: MainWindow::openAboutLicense()" << endl; + HelpAbout dlg( this, HELPABOUT::LICENSE ); + dlg.exec(); } @@ -640,5 +658,6 @@ */ void MainWindow::openAboutSupport() { - cerr << "TODO: MainWindow::openAboutSupport()" << endl; + HelpAbout dlg( this, HELPABOUT::SUPPORT ); + dlg.exec(); } Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2010-01-08 21:43:43 UTC (rev 464) +++ branches/valkyrie_qt4port/mainwindow.h 2010-01-13 22:07:17 UTC (rev 465) @@ -29,6 +29,7 @@ #include <QToolButton> #include <QVBoxLayout> +#include "help/help_handbook.h" #include "objects/valkyrie_object.h" #include "options/vk_options_dialog.h" #include "toolview/toolview.h" @@ -76,6 +77,7 @@ Valkyrie* valkyrie; ToolViewStack* toolViewStack; QLabel* statusLabel; + HandBook* handBook; private: QAction* actFile_NewProj; Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-08 21:43:43 UTC (rev 464) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-13 22:07:17 UTC (rev 465) @@ -20,13 +20,13 @@ #include <QDir> +#include "help/help_urls.h" #include "objects/valgrind_object.h" #include "options/valgrind_options_page.h" // createVkOptionsPage() #include "utils/vk_config.h" //#include "config.h" -//#include "html_urls.... [truncated message content] |
From: <sv...@va...> - 2010-01-08 21:43:57
|
Author: cerion Date: 2010-01-08 21:43:43 +0000 (Fri, 08 Jan 2010) New Revision: 464 Log: Finally, command-line parsing is up and running again. good grief. Added: branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp branches/valkyrie_qt4port/options/vk_parse_cmdline.h branches/valkyrie_qt4port/options/vk_popt.cpp branches/valkyrie_qt4port/options/vk_popt.h Modified: branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/objects/vk_objects.cpp branches/valkyrie_qt4port/objects/vk_objects.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/vk_option.cpp branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/utils/vk_config.cpp branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/valkyrie.pro Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/main.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -26,6 +26,7 @@ #include "mainwindow.h" #include "utils/vk_config.h" +#include "options/vk_parse_cmdline.h" VkConfig* vkConfig = 0; @@ -39,7 +40,7 @@ */ int main(int argc, char *argv[]) { - int res = EXIT_SUCCESS; + int exit_status = EXIT_SUCCESS; QApplication* app = 0; MainWindow* vkWin = 0; @@ -69,7 +70,28 @@ cerr << "Error: config not initialised properly: No guarantees from here!" << endl; } + // ------------------------------------------------------------ + // Command-line parsing + // - if a project file is given, the settings will override the initialised vkConfig. + if ( argc > 1 ) { + // parse cmdline args, overwrite vkConfig with any options found. + bool show_help_and_exit; + if ( ! parseCmdArgs( argc, argv, &valkyrie, show_help_and_exit ) ) { + exit_status = EXIT_FAILURE; + goto cleanup_and_exit; + } + if ( show_help_and_exit ) { + goto cleanup_and_exit; + } + } + + // save the working config + vkConfig->sync(); + + + + // ------------------------------------------------------------ // Start up the gui vkWin = new MainWindow( &valkyrie ); vkWin->show(); @@ -79,14 +101,15 @@ // ------------------------------------------------------------ // Hand over to QtApp. - res = app->exec(); + exit_status = app->exec(); +cleanup_and_exit: // ------------------------------------------------------------ // We're done - clean up and return. if ( vkWin ) delete vkWin; if ( vkConfig ) delete vkConfig; if ( app ) delete app; - return res; + return exit_status; } Modified: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -517,8 +517,29 @@ -/* check argval for this option, updating if necessary. - called by parseCmdArgs() and gui option pages -------------------- */ + + + +/*! + Update config - special cases +*/ +void Valgrind::updateConfig( int optid, QString& argval ) +{ + // exception: multiple suppressions are allowed + if ( optid == VALGRIND::SUPPS_SEL ) { +//TODO: concat, don't overwrite + // vkConfig->value( vk_opt->configKey() ); + // argval = cfg_argval + argval + } + + VkObject::updateConfig( optid, argval ); +} + + + +/*! + Check \a argval for the option given by \a optid, updating if necessary. +*/ int Valgrind::checkOptArg( int optid, QString& argval ) { optid = optid; argval = argval; Modified: branches/valkyrie_qt4port/objects/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-08 21:43:43 UTC (rev 464) @@ -88,6 +88,8 @@ int checkOptArg( int optid, QString& argval ); + void updateConfig( int optid, QString& argval ); + VkOptionsPage* createVkOptionsPage(); #if 0 Modified: branches/valkyrie_qt4port/objects/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/objects/valkyrie_object.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -23,7 +23,9 @@ #include "utils/vk_config.h" #include "utils/vk_utils.h" +#include <QFile> + // TODO: put this in a define in the build scripts,or something. // Minimum version of Valgrind required const char* pchVersionVgMin = "3.6.0"; @@ -39,7 +41,7 @@ { setupOptions(); - /* init valgrind */ + // init valgrind m_valgrind = new Valgrind(); } @@ -361,14 +363,74 @@ /*! - Check \a argval for the option given by \a optid, updating if necessary. - Called by parseCmdArgs() and gui option pages + Check \a argval for the option given by \a optGrp and \a optid. + The \a argval may be updated. */ +int Valkyrie::checkOptArg( QString optGrp, int optid, QString& argval ) +{ + VkObjectList objList = this->vkObjList(); + for (int i = 0; i < objList.size(); ++i) { + VkObject* obj = objList.at(i); + + // find the option owner, call checkOptArg for that owner. + if ( obj->objectName() == optGrp ) { + return obj->checkOptArg( optid, argval ); + } + } + return PERROR_BADOPT; +} + + + +/*! + Update config + General access function, when specific object not known +*/ +void Valkyrie::updateConfig( QString optGrp, int optid, QString& argval ) +{ + VkObjectList objList = this->vkObjList(); + for (int i = 0; i < objList.size(); ++i) { + VkObject* obj = objList.at(i); + + // find the option owner, call checkOptArg for that owner. + if ( obj->objectName() == optGrp ) { + return obj->updateConfig( optid, argval ); + } + } +} + + + +/*! + Update config - special cases +*/ +void Valkyrie::updateConfig( int optid, QString& argval ) +{ + // Load config settings from project file + // - load these first before + if ( optid == VALKYRIE::PROJ_FILE ) { + QString proj_filename = argval; + + if ( !QFile::exists( proj_filename ) ) { + vkConfig->createNewProject( proj_filename ); + } else { + vkConfig->openProject( proj_filename ); + } + } + + VkObject::updateConfig( optid, argval ); +} + + + +/*! + Check \a argval for the option given by \a optid, updating if necessary. +*/ int Valkyrie::checkOptArg( int optid, QString& argval ) -{ +{ vk_assert( optid >= 0 && optid < VALKYRIE::NUM_OPTS ); - VkOption* opt = this->options.getOption( optid ); + VkOption* opt = getOption( optid ); #if 0 // TODO int errval = PARSED_OK; @@ -392,7 +454,7 @@ case VALKYRIE::DFLT_LOGDIR: case VALKYRIE::WORKING_DIR: { - /* see if we have an dir with rx permissions */ + // see if we have an dir with rx permissions (void) dirCheck( &errval, argval, true, true ); } break; @@ -402,13 +464,31 @@ argval.replace( ed_file, ed ); } break; + case VALKYRIE::PROJ_FILE: { +#if 0 // TODO: review this + + // TODO: check filname format: ( dir + "/" + proj_name + "." + VK_CFG_EXT ) + + // TODO: check dir exists & perms ok + + // check owner read/write perms ok + if ( QFile::exists( proj_filename ) ) { + QFile::Permissions perms = QFile::permissions( proj_filename ); + if ( ( perms & QFile::WriteOwner ) != QFile::WriteOwner || + ( perms & QFile::ReadOwner ) != QFile::ReadOwner ) { + // TODO: vkError perms + } + } +#endif + } break; + case VALKYRIE::VG_EXEC: { - /* see if we have an executable with rx permissions */ + // see if we have an executable with rx permissions argval = binaryCheck( &errval, argval ); if ( errval != PARSED_OK ) return errval; - /* check the version */ + // check the version QString cmd = argval + " --version 2>&1"; FILE* fp; char line[50]; @@ -428,7 +508,7 @@ if ( !vg_version.startsWith("valgrind") ) { return PERROR_BADFILE; } - /* compare with minimum req'd version: */ + // compare with minimum req'd version int versionVg = strVersion2hex( vg_version ); int versionVgReqd = strVersion2hex( pchVersionVgMin ); if ( versionVg == -1 || versionVgReqd == -1) { @@ -437,7 +517,8 @@ if ( versionVg < versionVgReqd ) { return PERROR_BADVERSION; } - /* looking good... */ + + // if we get here, we're fine. } break; case VALKYRIE::VIEW_LOG: @@ -454,11 +535,12 @@ m_startRunState = VkRunState::VALGRIND; break; - /* can't really test this */ + case VALKYRIE::BIN_FLAGS: + // Can't test this. break; - /* ignore these opts */ + // ignore these opts case VALKYRIE::HELP: case VALKYRIE::VGHELP: case VALKYRIE::OPT_VERSION: @@ -477,6 +559,23 @@ /*! + Find the option owner, find option within that owner. +*/ +VkOption* Valkyrie::findOption( QString optGrp, int optid ) +{ + VkObjectList objList = this->vkObjList(); + for (int i = 0; i < objList.size(); ++i) { + VkObject* obj = objList.at(i); + + if ( obj->objectName() == optGrp ) { + return obj->getOption( optid ); + } + } + return NULL; +} + + +/*! Return list of all VkObjects */ const VkObjectList Valkyrie::vkObjList() Modified: branches/valkyrie_qt4port/objects/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/objects/valkyrie_object.h 2010-01-08 21:43:43 UTC (rev 464) @@ -71,8 +71,12 @@ #endif unsigned int maxOptId() { return VALKYRIE::NUM_OPTS; } + int checkOptArg( QString optGrp, int optid, QString& argval ); int checkOptArg( int optid, QString& argval ); + void updateConfig( QString optGrp, int optid, QString& argval ); + void updateConfig( int optid, QString& argval ); + // Generate own options page VkOptionsPage* createVkOptionsPage(); @@ -80,6 +84,10 @@ virtual void setConfigDefaults(); + + + VkOption* findOption( QString optGrp, int optid ); + // list of all objects const VkObjectList vkObjList(); // VkObject* vkObject( int objId ); Modified: branches/valkyrie_qt4port/objects/vk_objects.cpp =================================================================== --- branches/valkyrie_qt4port/objects/vk_objects.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/objects/vk_objects.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -22,6 +22,7 @@ #include "objects/vk_objects.h" #include "utils/vk_config.h" #include "options/vk_option.h" +#include "utils/vk_utils.h" @@ -52,7 +53,33 @@ } +/*! + Return entire optionhash for this object +*/ +OptionHash& VkObject::getOptions() +{ + return options.getOptionHash(); +} + +/*! + Update config - general case +*/ +void VkObject::updateConfig( int optid, QString& argval ) +{ + vk_assert( optid >= 0 && optid < VALKYRIE::NUM_OPTS ); + + VkOption* opt = getOption( optid ); + vk_assert( opt != NULL ); + + vkConfig->setValue( opt->configKey(), argval ); +} + + + +/*! + Setup factory defaults +*/ void VkObject::setConfigDefaults() { vkConfig->beginGroup( this->objectName() ); Modified: branches/valkyrie_qt4port/objects/vk_objects.h =================================================================== --- branches/valkyrie_qt4port/objects/vk_objects.h 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/objects/vk_objects.h 2010-01-08 21:43:43 UTC (rev 464) @@ -51,6 +51,7 @@ called by parseCmdArgs() and gui option pages */ virtual int checkOptArg( int optid, QString& argval ) = 0; + virtual void updateConfig( int optid, QString& argval ); /*! Set default config entries for thies object */ virtual void setConfigDefaults(); @@ -58,12 +59,11 @@ virtual VkOptionsPage* createVkOptionsPage() = 0; VkOption* getOption( int optid ); + OptionHash& getOptions(); protected: virtual void setupOptions() = 0; VkOptionHash options; - - }; Modified: branches/valkyrie_qt4port/options/valgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -321,9 +321,9 @@ /* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ void ValgrindOptionsPage::applyOption( int optId ) { + vk_assert( optId >= 0 && optId < VALGRIND::NUM_OPTS ); + #if 0 - vk_assert( optId >= 0 && optId < Valgrind::NUM_OPTS ); - // QString argval = m_itemList[optId]->currValue(); /* apply option */ Modified: branches/valkyrie_qt4port/options/valkyrie_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -196,16 +196,15 @@ /* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ void ValkyrieOptionsPage::applyOption( int optId ) { - std::cerr << "vk-applyOption(): 0 (" << optId << ")" << std::endl; +// std::cerr << "vk-applyOption(): 0 (" << optId << ")" << std::endl; + vk_assert( optId >= 0 && optId < VALKYRIE::NUM_OPTS ); - vk_assert( optId >= 0 && optId < VALKYRIE::NUM_OPTS ); - OptionWidget* optWidg = m_itemList[optId]; vk_assert( optWidg != 0 ); QString argval = optWidg->currValue(); - std::cerr << "applyOption(): 1" << std::endl; +// std::cerr << "applyOption(): 1" << std::endl; /* apply option */ switch ( optId ) { Modified: branches/valkyrie_qt4port/options/vk_option.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_option.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/options/vk_option.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -37,6 +37,65 @@ + +/*! + Map error int to error string +*/ +const char* parseErrString( const int error ) +{ + switch ( error ) { + case PERROR_NODASH: + return "Short options do not require a '='"; + case PERROR_NOARG: + return "Missing argument"; + case PERROR_BADARG: + return "Invalid argument"; + case PERROR_BADOPT: + return "Unknown/Disabled option"; + case PERROR_BADOPERATION: + return "Mutually exclusive logical operations requested"; + case PERROR_NULLARG: + return "opt->arg should not be NULL"; + case PERROR_BADQUOTE: + return "Error in parameter quoting"; + case PERROR_BADNUMBER: + return "Invalid numeric value"; + case PERROR_OUTOFRANGE: + return "Numeric value outside valid range"; + case PERROR_OVERFLOW: + return "Number too large or too small"; + case PERROR_MALLOC: + return "Memory allocation failed"; + case PERROR_BADDIR: + return "Invalid directory"; + case PERROR_BADFILE: + return "Invalid file"; + case PERROR_BADNUMFILES: + return "Invalid number of files ( max == 10 )"; + case PERROR_BADFILERD: + return "You do not have read permission"; + case PERROR_BADFILEWR: + return "You do not have write permission"; + case PERROR_BADEXEC: + return "You do not have executable permission"; + case PERROR_DB_CONFLICT: + return "Conflicting argument\n" + "--db-attach=yes conflicts with --trace-children=yes\n" + "Please choose one or the other, but not both."; + case PERROR_DB_OUTPUT: + return "using --db-attach=yes only makes sense " + "when sending output to stderr."; + case PERROR_POWER_OF_TWO: + return "number is not a power of two"; + case PERROR_BADVERSION: + return "Bad program version"; + default: + return "unknown error"; + } +} + + + /***************************************************************************/ /*! Constructs a VkOptionHash Modified: branches/valkyrie_qt4port/options/vk_option.h =================================================================== --- branches/valkyrie_qt4port/options/vk_option.h 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/options/vk_option.h 2010-01-08 21:43:43 UTC (rev 464) @@ -103,9 +103,9 @@ QString binaryCheck( int* err_val, const QString exe_name ); QString dirCheck( int* err_val, const QString fpath, bool rd_perms, bool wr_perms ); +#endif const char* parseErrString( const int error ); -#endif Modified: branches/valkyrie_qt4port/options/vk_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -148,7 +148,7 @@ if ( m_editList.isEmpty() && m_mod == false ) return true; - std::cerr << "applyEDITS(): 2" << std::endl; +// std::cerr << "applyEDITS(): 2" << std::endl; // user clicked Ok/Apply after editing some items @@ -159,9 +159,9 @@ if ( !checkOption( optw->id() ) ) { return false; } - std::cerr << "applyEDITS(): 3 (" << i << ")" << std::endl; +// std::cerr << "applyEDITS(): 3 (" << i << ")" << std::endl; - // update any Valkyrie state dependent on this option + // update any Valkyrie state dependent on this option applyOption( optw->id() ); } std::cerr << "applyEDITS(): 4" << std::endl; Added: branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp (rev 0) +++ branches/valkyrie_qt4port/options/vk_parse_cmdline.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -0,0 +1,293 @@ +/**************************************************************************** +** Parse command-line options implementation +** - Called from main() to parse both valkyrie and valgrind args +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 "objects/vk_objects.h" +#include "objects/valkyrie_object.h" // for VALKYRIE::enums + +#include "utils/vk_utils.h" +#include "options/vk_popt.h" +#include "options/vk_option.h" // namespace VkOPT +#include "utils/vk_config.h" + + +void showHelp( vkPoptContext con, char key, Valkyrie* vk ) +{ + QString VkName = vkConfig->vkName; + VkName.replace( 0, 1, vkConfig->vkName[0].toUpper() ); + + switch ( key ) { + case 'v': + printf("%s-%s\n", vkConfig->vkName.toLatin1().constData(), + vkConfig->vkVersion.toLatin1().constData() ); + break; + + case 'h': + vkPoptPrintHelp( con, stdout, vk->objectName().toLatin1().constData() ); + printf( "\n%s is copyright %s %s\n" + "and licensed under the GNU General Public License, version 2.\n" + "Bug reports, feedback, praise, abuse, etc, to <%s>\n\n", + VkName.toLatin1().constData(), + vkConfig->vkCopyright.toLatin1().constData(), + vkConfig->vkAuthor.toLatin1().constData(), + vkConfig->vkEmail.toLatin1().constData() ); + break; + + case 'V': + vkPoptPrintHelp( con, stdout, NULL ); + printf("\n%s is copyright %s %s\n", + VkName.toLatin1().constData(), + vkConfig->vkCopyright.toLatin1().constData(), + vkConfig->vkAuthor.toLatin1().constData() ); +//TODO +// printf("Valgrind is copyright %s\n\n", vkConfig->vgCopyright.toLatin1().constData() ); + break; + + default: + vk_assert_never_reached(); + } +} + + +void parseError( vkPoptContext con, const int err ) +{ + // don't print anything; sender is dealing with msgs + if ( err != PERROR_DEFAULT ) { + fprintf( stderr, "%s: Parse error [%s] : %s\n", + vkConfig->vkName.toLatin1().constData(), + vkPoptBadOption(con), + parseErrString( err ) ); + fprintf( stderr, "%s: Use --help for more information.\n", + vkConfig->vkName.toLatin1().constData() ); + } +} + + +/*! + getObjOptions() + Determine the total no. of option structs required by counting the + no. of entries in the optList. Note: num_options = optList+1 + because we need a NULL option entry to terminate each option array. +*/ +vkPoptOption* getObjOptions( /*IN */VkObject* obj, + /*OUT*/vkPoptOption* vkOpts ) +{ + vk_assert( obj != NULL ); + vk_assert( vkOpts != NULL ); + + int idx = 0; + OptionHash opthash = obj->getOptions(); + for ( Iter_OptionHash it = opthash.begin(); it != opthash.end(); ++it ) { + VkOption* opt = it.value(); + vk_assert( opt != NULL ); + + // ignore non-popt options + if ( opt->argType == VkOPT::NOT_POPT ) + continue; + + vkPoptOption* vkopt = &vkOpts[idx++]; + vkopt->arg = NULL; + vkopt->optId = opt->optid; + vkopt->argType = opt->argType; + vkopt->shortFlag = opt->shortFlag.toLatin1(); + + vkopt->optGrp = (char*)malloc( opt->configGrp.length()+1 ); + strncpy( vkopt->optGrp, opt->configGrp.toLatin1().data(), opt->configGrp.length()+1 ); + + vkopt->longFlag = (char*)malloc( opt->longFlag.length()+1 ); + strncpy( vkopt->longFlag, opt->longFlag.toLatin1().data(), opt->longFlag.length()+1 ); + + vkopt->helptxt = (char*)malloc( opt->longHelp.length()+1 ); + strncpy( vkopt->helptxt, opt->longHelp.toLatin1().data(), opt->longHelp.length()+1 ); + + vkopt->helpdesc = (char*)malloc( opt->flagDescr.length()+1 ); + strncpy( vkopt->helpdesc, opt->flagDescr.toLatin1().data(), opt->flagDescr.length()+1 ); + } + // null entry terminator + vkOpts[idx] = nullOpt(); + return vkOpts; +} + + +void getAllOptions( /*IN */VkObjectList objList, + /*OUT*/vkPoptOption* allOpts ) +{ + int nopts, idx = 0; + size_t nbytes; + vkPoptOption* vkOpts; + vk_assert( allOpts != NULL ); + + for (int i = 0; i < objList.size(); ++i) { + VkObject* obj = objList.at(i); + + // allocate mem for this object's options + nopts = obj->getOptions().count(); + nbytes = sizeof(vkPoptOption) * (nopts + 1/*null end*/); + vkOpts = (vkPoptOption*)malloc( nbytes ); + + vkPoptOption* tblOpt = &allOpts[idx++]; + *tblOpt = nullOpt(); // init null struct + tblOpt->arg = getObjOptions( obj, vkOpts ); // get this object's options + // set table name to option group name + tblOpt->optGrp = (char*)malloc( obj->objectName().length()+1 ); + strncpy( tblOpt->optGrp, obj->objectName().toLatin1().data(), obj->objectName().length()+1 ); + } + // null entry terminator + allOpts[idx] = nullOpt(); +} + + +void freeOptions( vkPoptOption* opt ) +{ + for (; opt && opt->optGrp; opt++ ) { + // recurse and free the opt tree. + if ( opt->arg != NULL ) { + freeOptions( opt->arg ); + _free( opt->arg ); // Do free non-top level opts + } + _free( opt->optGrp ); + _free( opt->longFlag ); + _free( opt->helptxt ); + _free( opt->helpdesc ); + // Don't free top level opts: allocated on stack. + } +} + + +bool parseCmdArgs( int argc, char** argv, Valkyrie* vk, + bool& show_help_and_exit ) +{ + int rc = PARSED_OK; // check fn return value / err value + bool ret = true; // return value + show_help_and_exit = false; // just quit. + char argVal[512]; // store argument values for checking + + // -------------------------------------------------- + // fetch all object options + VkObjectList objList = vk->vkObjList(); + int num_objs = objList.count(); + vkPoptOption allOpts[num_objs+1/*null end*/]; + getAllOptions( objList, allOpts ); + +#if 0 // TODO: rm when done debugging + cerr << "PRINTOUT" << endl; + for ( int i=0; i<num_objs; i++) { + vkPoptOption* opt = &allOpts[i]; + cerr << "TABLE: " << opt->optGrp << endl; + + opt = opt->arg; + while ( opt && opt->optId != -1 ) { + cerr << opt->optGrp << ", " << opt->optId << ", " << opt->longFlag << endl; + opt++; + } + } +#endif + + + // -------------------------------------------------- + // context for parsing cmd-line opts + vkPoptContext optCon = + vkPoptGetContext( argc, (const char**)argv, allOpts ); + + // -------------------------------------------------- + // process the options + while ( true ) { + const vkPoptOption* opt = NULL; + bool done_vk_flags = false; + rc = vkPoptGetNextOpt( optCon, argVal, &opt, done_vk_flags ); + + if ( rc != PARSED_OK ) { + // an error occurred during option processing + parseError( optCon, rc ); + ret = false; + goto done; + } + + if ( done_vk_flags ) { + // no more vk/vg flags - continue on. + break; + } + + vk_assert(opt); + + // Just show help and exit? + char vk_arg = opt->shortFlag; + // printf("vk_arg: '%c'\n", vk_arg); + if ( vk_arg == 'h' || vk_arg == 'v' || vk_arg == 'V' ) { + showHelp( optCon, vk_arg, vk ); + show_help_and_exit = true; + goto done; + } + + // vkObjects check their own arguments + QString qs_argval = argVal; + rc = vk->checkOptArg( opt->optGrp, opt->optId, qs_argval ); + + if ( rc != PARSED_OK ) { + parseError( optCon, rc ); + ret = false; + goto done; + } + + vk->updateConfig( opt->optGrp, opt->optId, qs_argval ); + + } // end while. + + + // -------------------------------------------------- + // Get the leftovers: should only be 'myprog --myflags'. + // - Check we really do have a valid prog-to-debug here. + // If yes, then assume all subsequent flags belong to it. + if ( vkPoptPeekArg(optCon) != NULL ) { + + // First get myprog + QString qs_argval = vkPoptGetArg(optCon); + rc = vk->checkOptArg( VALKYRIE::BINARY, qs_argval ); + if ( rc != PARSED_OK ) { + parseError( optCon, rc ); + ret = false; + goto done; + } + vk->updateConfig( VALKYRIE::BINARY, qs_argval ); + + // Get myprog's flags, if any + const char **args = vkPoptGetArgs( optCon ); + QStringList aList; + for ( int i=0; args && args[i] != NULL; i++ ) { + aList << args[i]; + } + qs_argval = aList.isEmpty() ? "" : aList.join( " " ); + rc = vk->checkOptArg( vk->objectName(), VALKYRIE::BIN_FLAGS, qs_argval ); + + if ( rc != PARSED_OK ) { + parseError( optCon, rc ); + ret = false; + goto done; + } + vk->updateConfig( VALKYRIE::BIN_FLAGS, qs_argval ); + } + + +done: + // -------------------------------------------------- + // Cleanup + freeOptions( allOpts ); + vkPoptFreeContext( optCon ); + return ret; +} Added: branches/valkyrie_qt4port/options/vk_parse_cmdline.h =================================================================== --- branches/valkyrie_qt4port/options/vk_parse_cmdline.h (rev 0) +++ branches/valkyrie_qt4port/options/vk_parse_cmdline.h 2010-01-08 21:43:43 UTC (rev 464) @@ -0,0 +1,33 @@ +/**************************************************************************** +** Parse command-line options +** - Called from main() to parse both valkyrie and valgrind args +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2010, 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 __VK_PARSE_CMDLINE_H +#define __VK_PARSE_CMDLINE_H + + +/*! + parseCmdArgs() + Command-line args parsing, updates global config settings. +*/ +extern bool parseCmdArgs( int argc, char** argv, Valkyrie* vk, + bool& show_help_and_exit ); + +#endif // #ifndef __VK_PARSE_CMDLINE_H + Added: branches/valkyrie_qt4port/options/vk_popt.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_popt.cpp (rev 0) +++ branches/valkyrie_qt4port/options/vk_popt.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -0,0 +1,640 @@ +/**************************************************************************** +** Implementation of Popt functions +** This is a seriously hacked version of the popt libraries. +** No credit to me, all thanks and many apologies to the Red Hat team +** -------------------------------------------------------------------------- +** popt is Copyright (C) 1998 Red Hat Software and distributed under +** an X11-style license, which is in turn compatible the GNU GPL v.2. +** See the file COPYING for the full license details. +*/ + +#include "options/vk_popt.h" +#include "options/vk_option.h" // namespace VkOPT +#include "utils/vk_utils.h" + + +/*! + return a vkPoptOption initialised to null +*/ +vkPoptOption nullOpt() +{ + vkPoptOption _nullOpt = TABLE_END; + return _nullOpt; +} + +const char * vkPoptPeekArg( vkPoptContext con ) +{ + const char * ret = NULL; + if ( con && con->leftovers != NULL && + con->nextLeftover < con->numLeftovers ) + ret = con->leftovers[con->nextLeftover]; + return ret; +} + + +const char * vkPoptGetArg( vkPoptContext con ) +{ + const char * ret = NULL; + if ( con && con->leftovers != NULL && + con->nextLeftover < con->numLeftovers ) { + ret = con->leftovers[con->nextLeftover++]; + } + return ret; +} + + +const char ** vkPoptGetArgs( vkPoptContext con ) +{ + if ( con == NULL || con->leftovers == NULL || + con->numLeftovers == con->nextLeftover ) + return NULL; + + // some apps like [like RPM ;-) ] need this NULL terminated + con->leftovers[con->numLeftovers] = NULL; + return (con->leftovers + con->nextLeftover); +} + + +vkPoptContext vkPoptGetContext( int argc, const char ** argv, + const vkPoptOption * options ) +{ + vkPoptContext con = (vkPoptContext)malloc( sizeof(*con) ); + + if ( con == NULL ) { + return NULL; + } + + memset( con, 0, sizeof(*con) ); + + con->os = con->optionStack; + con->os->argc = argc; + con->os->argv = argv; + con->os->next = 1; // skip argv[0] + con->leftovers = (const char**)calloc( (argc + 1), sizeof(*con->leftovers) ); + con->options = options; + con->flags = PCONTEXT_POSIXMEHARDER; + con->finalArgvAlloced = argc * 2; + con->finalArgv = (const char**)calloc( con->finalArgvAlloced, + sizeof(*con->finalArgv) ); + + return con; +} + + +static void vkCleanOSE( struct optionStackEntry *os ) +{ + os->nextArg = (const char*)_free( os->nextArg ); + os->argv = (const char**)_free( os->argv ); +} + + +const vkPoptOption * vkFindOption( const vkPoptOption * opt, + const char * longFlag, + char shortFlag, + int singleDash ) +{ + // this happens when a single - is given + if ( singleDash && !shortFlag && (longFlag && *longFlag == '\0') ) + shortFlag = '-'; + + for (; opt->longFlag || opt->shortFlag || opt->arg; opt++) { + + if ( opt->arg != NULL ) { // is-a table + // recurse on included sub-tables. + const vkPoptOption* opt2 = vkFindOption( opt->arg, longFlag, shortFlag, singleDash ); + if ( opt2 == NULL ) { + // no match in sub-table + continue; + } + // found match: return option + return opt2; + } + else { // is-a leaf + if ( longFlag && opt->longFlag && !singleDash && + !strcmp( longFlag, opt->longFlag ) ) { + // longFlag match + break; + } + if (shortFlag && shortFlag == opt->shortFlag) { + // shortFlag match + break; + } + } + } + + if ( !opt->longFlag && !opt->shortFlag ) { + // end of optArr: no match found + return NULL; + } + + // found match + return opt; +} + + +static const char * vkExpandNextArg( const char * s ) +{ + char *t, *te; + size_t tn = strlen(s) + 1; + char c; + + te = t = (char*)malloc(tn);; + if ( t == NULL ) + return NULL; + while ((c = *s++) != '\0') { + *te++ = c; + } + + *te = '\0'; + // memory leak, hard to plug + t = (char*)realloc(t, strlen(t) + 1); + return t; +} + + +/*! + get next option opt_ret + returns 0 on success, PERROR_* on error +*/ +int vkPoptGetNextOpt( vkPoptContext con, + char *arg_val/*OUT*/, + const vkPoptOption** opt_ret/*OUT*/, + bool& done_vk_flags/*OUT*/ ) +{ + const vkPoptOption * opt = NULL; + int done = 0; + + if ( con == NULL ) { + done_vk_flags = true; + return PARSED_OK; + } + + while ( !done ) { + const char * origOptString = NULL; + const char * longArg = NULL; + int shorty = 0; + + while ( !con->os->nextCharArg && + con->os->next == con->os->argc && + con->os > con->optionStack ) { + vkCleanOSE( con->os-- ); + } + + if ( !con->os->nextCharArg && + con->os->next == con->os->argc ) { + done_vk_flags = true; + *opt_ret = opt; + return PARSED_OK; + } + + // process next long option + if ( !con->os->nextCharArg ) { + char * localOptString, * optString; + int thisopt; + thisopt = con->os->next; + if ( con->os->argv != NULL ) + origOptString = con->os->argv[con->os->next++]; + + if ( origOptString == NULL ) { + return PERROR_BADOPT; + } + if ( strcmp(origOptString, "--") == 0 ) { + return PERROR_BADQUOTE; + } + + if ( con->restLeftover || *origOptString != '-' ) { + if ( con->flags & PCONTEXT_POSIXMEHARDER ) + con->restLeftover = 1; + if ( con->leftovers != NULL ) + con->leftovers[con->numLeftovers++] = origOptString; + continue; + } + + // make a copy we can hack at + localOptString = optString = + strcpy((char*)alloca(strlen(origOptString) + 1), origOptString); + + if ( optString[0] == '\0' ) + return PERROR_BADOPT; + + if ( optString[1] == '-' && !optString[2] ) { + con->restLeftover = 1; + continue; + } else { + char *oe; + int singleDash; + optString++; + if ( *optString == '-' ) + singleDash = 0, optString++; + else + singleDash = 1; + + // Check for "--long=arg" option + for ( oe = optString; *oe && *oe != '='; oe++ ) + { }; + if ( *oe == '=' ) { + // FIX: don't use '=' for shortopts + if ( singleDash ) + return PERROR_NODASH; + *oe++ = '\0'; + + // longArg is mapped back to persistent storage. + longArg = origOptString + (oe - localOptString); + + // FIX: catch cases where --longarg=<no-arg> + if ( strlen(longArg) == 0 ) { + printf("1: returning PERROR_NOARG\n"); + return PERROR_NOARG; + } + } +#if 0 + else if ( singleDash == 0 ) { + /* FIX: catch cases where we didn't find an '=', + and this is a --longarg option */ + //printf("2: returning PERROR_NOARG\n"); + return PERROR_NOARG; + } +#endif + + opt = vkFindOption( con->options, optString, + '\0', singleDash ); + if ( !opt && !singleDash ) { + printf("returning PERROR_BADOPT\n"); + return PERROR_BADOPT; + } + } + + if ( !opt ) { + con->os->nextCharArg = origOptString + 1; + } else { + shorty = 0; + } + } + + // process next short option + if ( con->os->nextCharArg ) { + origOptString = con->os->nextCharArg; + con->os->nextCharArg = NULL; + + opt = vkFindOption( con->options, NULL, *origOptString, 0 ); + if ( !opt ) { + return PERROR_BADOPT; + } + shorty = 1; + + origOptString++; + if ( *origOptString != '\0' ) + con->os->nextCharArg = origOptString; + } + + if ( opt == NULL ) + return PERROR_BADOPT; + + if ( opt->argType != VkOPT::ARG_NONE ) { + con->os->nextArg = (const char*)_free(con->os->nextArg); + if ( longArg ) { + longArg = vkExpandNextArg( longArg ); + con->os->nextArg = longArg; + } else if ( con->os->nextCharArg ) { + longArg = vkExpandNextArg( con->os->nextCharArg); + con->os->nextArg = longArg; + con->os->nextCharArg = NULL; + } else { + while ( con->os->next == con->os->argc && + con->os > con->optionStack ) { + vkCleanOSE( con->os-- ); + } + if ( con->os->next == con->os->argc ) { + // FIX: con->os->argv not defined + return PERROR_NOARG; + con->os->nextArg = NULL; + } else { + if ( con->os->argv != NULL ) { + // watch out: subtle side-effects live here. + longArg = con->os->argv[con->os->next++]; + longArg = vkExpandNextArg( longArg ); + con->os->nextArg = longArg; + } + } + } + longArg = NULL; + + // store the argument value for checking + if ( con->os->nextArg ) { + sprintf( arg_val, "%s", con->os->nextArg ); + } + } // end of "if ! VkOPT::ARG_NONE" + + if ( opt->optId >= 0 ) { // is-a leaf + done = 1; + } + + if ( (con->finalArgvCount + 2) >= (con->finalArgvAlloced) ) { + con->finalArgvAlloced += 10; + con->finalArgv = (const char**)realloc(con->finalArgv, + sizeof(*con->finalArgv) * con->finalArgvAlloced); + } + + if ( con->finalArgv != NULL ) { + char *s = (char*)malloc((opt->longFlag ? strlen(opt->longFlag) : 0) + 3); + if ( s != NULL ) { + if ( opt->longFlag ) { + sprintf(s, "--%s", opt->longFlag); + } else { + sprintf(s, "-%c", opt->shortFlag); + } + con->finalArgv[con->finalArgvCount++] = s; + } else + con->finalArgv[con->finalArgvCount++] = NULL; + } + + if ((opt->arg == NULL/* leaf */) && + (opt->argType != VkOPT::ARG_NONE)) { + if (con->finalArgv != NULL && con->os->nextArg) { + char* s = (char*)malloc( strlen(con->os->nextArg)+1 ); + if (s == NULL) { + vkPrintErr("virtual memory exhausted."); + exit(EXIT_FAILURE); + } else { + con->finalArgv[con->finalArgvCount++] = + strcpy( s, con->os->nextArg ); + } + } + } + } // end while ( !done ) + + //vk_assert( opt != NULL ); + *opt_ret = opt; + return PARSED_OK; +} + + +vkPoptContext vkPoptFreeContext( vkPoptContext con ) +{ + if ( con == NULL ) + return con; + + // poptResetContext( con ); + int i; + while ( con->os > con->optionStack ) { + vkCleanOSE(con->os--); + } + con->os->nextCharArg = NULL; + con->os->nextArg = NULL; + con->os->next = 1; // skip argv[0] + con->numLeftovers = 0; + con->nextLeftover = 0; + con->restLeftover = 0; + + if ( con->finalArgv != NULL ) + for (i = 0; i < con->finalArgvCount; i++) + con->finalArgv[i] = (const char*)_free(con->finalArgv[i]); + con->finalArgvCount = 0; + + con->leftovers = (const char**)_free( con->leftovers ); + con->finalArgv = (const char**)_free( con->finalArgv ); + + con = (vkPoptContext)_free( con ); + return con; +} + + +const char * vkPoptBadOption( vkPoptContext con ) +{ + struct optionStackEntry * os = NULL; + + if ( con != NULL ) + os = con->optionStack; + + return ( os && os->argv ? os->argv[os->next - 1] : NULL ); +} + + + +/* ------ help printing stuff --------------------------------*/ +// set in poptPrintHelp +static int leftColWidth = -1; + + +static const char * vkGetHelpDesc( const vkPoptOption * opt ) +{ + // if ARG_NONE: no arguments to describe + if ( opt->argType == VkOPT::ARG_NONE ) + return NULL; + + if ( opt->helpdesc ) + return opt->helpdesc; + + return NULL; +} + + +/*! + vkSingleOptionHelp() + called from vkTableHelp() for leaf table. +*/ +static void vkSingleOptionHelp( FILE * fp, + const vkPoptOption * opt ) +{ + int indentLength = leftColWidth + 2; + int lineLength = 80 - indentLength; + const char* help = opt->helptxt; + const char* helpdesc = vkGetHelpDesc( opt ); + int helpLength; + char * defs = NULL; + char * left; + int nb = leftColWidth + 1; + + // make sure there's more than enough room in target buffer. + if ( opt->longFlag ) + nb += strlen( opt->longFlag ); + if ( helpdesc ) + nb += strlen( helpdesc ); + + left = (char*)malloc( nb ); + if ( left == NULL ) + return; + left[0] = '\0'; + left[leftColWidth] = '\0'; + + if ( opt->longFlag && opt->shortFlag ) { + sprintf( left, "-%c, --%s", opt->shortFlag, opt->longFlag); + } else if (opt->shortFlag != '\0') { + sprintf( left, "-%c", opt->shortFlag); + } else if (opt->longFlag) { + sprintf( left, "--%s", opt->longFlag ); + } + + if ( !*left ) { + goto out; + } + + if ( helpdesc ) { + char * le = left + strlen( left ); + *le++ = ' '; + strcpy( le, helpdesc ); + le += strlen(le); + *le = '\0'; + } + + if ( help ) { + fprintf( fp," %-*s", leftColWidth, left ); + } else { + fprintf( fp," %s\n", left ); + goto out; + } + + left = (char*)_free(left); + if ( defs ) { + help = defs; + defs = NULL; + } + + helpLength = strlen( help ); + while ( helpLength > lineLength ) { + const char * ch; + char format[100]; + + ch = help + lineLength - 1; + while ( ch > help && !isspace(*ch) ) { + ch--; + } + if ( ch == help ) { + break; // give up + } + while ( ch > (help + 1) && isspace(*ch) ) { + ch--; + } + ch++; + + sprintf( format, "%%.%ds\n%%%ds", + (int) (ch - help), indentLength ); + fprintf( fp, format, help, " " ); + help = ch; + while ( isspace(*help) && *help ) { + help++; + } + helpLength = strlen( help ); + } + + if ( helpLength ) + fprintf( fp, "%s\n", help ); + + out: + defs = (char*)_free(defs); + left = (char*)_free(left); +} + + +static int vkMaxArgWidth( const vkPoptOption * opt ) +{ + int max = 0; + int len = 0; + const char * s; + + if ( opt == NULL ) + return 0; + + for (; opt->longFlag || opt->shortFlag || opt->arg; opt++ ) { + + if ( opt->arg != NULL ) { // is-a table + // recurse on included sub-tables. + len = vkMaxArgWidth( opt->arg ); + if ( len > max ) + max = len; + } + else { // is-a leaf + len = sizeof(" ") - 1; + if ( opt->shortFlag != '\0' ) + len += sizeof("-X")-1; + if ( opt->shortFlag != '\0' && opt->longFlag ) + len += sizeof(", ")-1; + if (opt->longFlag) { + len += sizeof("--") - 1; + len += strlen( opt->longFlag ); + } + + s = vkGetHelpDesc( opt ); + if ( s ) + len += sizeof("=") - 1 + strlen( s ); + if ( len > max ) + max = len; + } + } + return max; +} + + +/*! + vkTableHelp() + this version prints nested tables first. swap 'em over if this + isn't the behaviour you want. +*/ +static void vkTableHelp( FILE * fp, const vkPoptOption * opt ) +{ + if ( opt == NULL ) + return; + + // recurse over all tables + for (; opt->longFlag || opt->shortFlag || opt->arg; opt++) { + if ( opt->arg != NULL ) { // is-a table + // print table title + fprintf( fp, "\n%s options:\n", opt->optGrp ); + // recurse on included sub-tables. + vkTableHelp( fp, opt->arg ); + } + else { // is-a leaf + // print options + vkSingleOptionHelp( fp, opt ); + } + } +} + + +/*! + vkPoptPrintHelp() + if tableName == NULL, recurses over all tables; + else just prints contents of the specified table. +*/ +void vkPoptPrintHelp( vkPoptContext con, FILE * fp, + const char * tableName ) +{ + const char * fn; + + fprintf( fp, "\nUsage:" ); + fn = con->optionStack->argv[0]; + if ( fn != NULL ) { + if ( strchr(fn, '/') ) + fn = strrchr( fn, '/' ) + 1; + fprintf( fp, " %s", fn ); + } + + fprintf( fp, " %s", + "[valkyrie-opts] [valgrind-opts] [prog-and-args]\n" ); + + leftColWidth = vkMaxArgWidth( con->options ); + + if ( tableName == NULL ) { + // print all tables + vkTableHelp( fp, con->options ); + } else { + // trawl through con->options till we find the right table + const vkPoptOption * opt; + for ( opt = con->options; (opt != NULL) && + (opt->optGrp != NULL); opt++ ) { + if ( strcmp( opt->optGrp, tableName ) == 0 ) { + break; + } + } + + // print the table: + if ( opt != NULL) { + if ( opt->optGrp != NULL ) + fprintf( fp, "\n%s options:\n", opt->optGrp ); + else + vkPrintErr("Error: vkPoptPrintHelp(): No match found for table '%s'.", tableName); + vkTableHelp( fp, opt->arg ); + } + } + +} Added: branches/valkyrie_qt4port/options/vk_popt.h =================================================================== --- branches/valkyrie_qt4port/options/vk_popt.h (rev 0) +++ branches/valkyrie_qt4port/options/vk_popt.h 2010-01-08 21:43:43 UTC (rev 464) @@ -0,0 +1,129 @@ +/**************************************************************************** +** Definition of Popt functions +** This is a seriously hacked version of the popt libraries. +** No credit to me, all thanks and many apologies to the Red Hat team +** -------------------------------------------------------------------------- +** popt is Copyright (C) 1998 Red Hat Software and distributed under +** an X11-style license, which is in turn compatible the GNU GPL v.2. +** See the file COPYING for the full license details. +*/ + +#ifndef __VK_POPT_H +#define __VK_POPT_H + +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include "options/vk_option.h" + + +#define OPTION_DEPTH 10 + +// options can't follow args +#define PCONTEXT_POSIXMEHARDER (1 << 2) + +/*! + vkPoptOption + This may be one of: + - TABLE_END: none set of: shortFlag && longFlag && arg + - table: arg = array of options, optGrp = table title + - option: arg = NULL, remaining vars filled +*/ +typedef struct _vkPoptOption { + struct _vkPoptOption* arg; // table holds ptr to + char* optGrp; // opt group name: "valgrind" etc. + int optId; // eg. VIEW-LOG + VkOPT::ArgType argType; // option type: ARG_*** + char shortFlag; // '\0' || 'h' + char* longFlag; // NULL || --help + char* helptxt; // help text + char* helpdesc; // eg. <file> +} vkPoptOption; + +#define TABLE_END { NULL, NULL, -1, VkOPT::NOT_POPT, '\0', NULL, NULL, NULL } +vkPoptOption nullOpt(); + + +typedef struct vkPoptContext_s* vkPoptContext; + +#ifdef __cplusplus +extern "C" { +#endif + +/* initialize popt context. + - argc no. of arguments + - argv argument array + - options address of popt option table + - returns initialized popt context */ +vkPoptContext vkPoptGetContext( int argc, const char ** argv, + const vkPoptOption * options ); + +/* get next option opt_ret + returns 0 on success, PERROR_* on error */ +int vkPoptGetNextOpt( vkPoptContext con, char *arg_val, + const vkPoptOption** opt/*OUT*/, + bool& done_vk_flags/*OUT*/ ); + +/* return current option's argument, + or NULL if no more options are available */ +const char * vkPoptGetArg( vkPoptContext con ); + +/* return remaining argument array, terminated with NULL */ +const char ** vkPoptGetArgs( vkPoptContext con ); + +/* peek at current option's argument */ +const char * vkPoptPeekArg( vkPoptContext con ); + +/* return the offending option which caused the most recent error */ +const char * vkPoptBadOption( vkPoptContext con ); + +/* destroy context. return NULL always */ +vkPoptContext vkPoptFreeContext( vkPoptContext con ); + +/* print detailed description of options. + fp == ouput file handle */ +void vkPoptPrintHelp( vkPoptContext con, FILE * fp, + const char * tableName ); + +#ifdef __cplusplus +} +#endif + +/*--------------------------------------------------*/ +/* wrapper to free(3), hides const compilation noise, + permit NULL, return NULL always */ +static inline void * _free( const void * p ) +{ + if ( p != NULL ) + free((void *)p); + return NULL; +} + + +struct optionStackEntry { + int argc; + const char ** argv; + int next; + const char * nextArg; + const char * nextCharArg; +}; + + +struct vkPoptContext_s { + struct optionStackEntry optionStack[OPTION_DEPTH]; + struct optionStackEntry * os; + const char ** leftovers; + int numLeftovers; + int nextLeftover; + const vkPoptOption * options; + int restLeftover; + int flags; + const char ** finalArgv; + int finalArgvCount; + int finalArgvAlloced; +}; + + +#endif Modified: branches/valkyrie_qt4port/utils/vk_config.cpp =================================================================== --- branches/valkyrie_qt4port/utils/vk_config.cpp 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/utils/vk_config.cpp 2010-01-08 21:43:43 UTC (rev 464) @@ -90,45 +90,30 @@ bool VkConfig::initCfg( Valkyrie* vk ) { - // First: check Global config file exists: if not, create one from compiled defailts. + // 1) Check Global config file exists: if not, create one from compiled defailts. if ( ! QFile::exists( vkCfgGlblFilename() ) ) { writeConfigDefaults( vk ); } - // Second: read global config file into RUNTIME settings + // 2) Read global config file into RUNTIME settings // check at least owner read/write perms ok QFile::Permissions perms = QFile::permissions( vkCfgGlblFilename() ); if ( ( perms & QFile::WriteOwner ) != QFile::WriteOwner || ( perms & QFile::ReadOwner ) != QFile::ReadOwner ) { - // TODO: vkError permissions - } else { - // first clear all current settings, then read in global - this->clear(); - readFromGlblConfigFile(); - } +//TODO + cerr << "TODO: vkError permissions on vkCfgGlblFilename" << endl; - // Third: if given a Project file on the command line, read and update 'working' config -#if 0 // TODO: command line args: project file (create if !exist) - get proj_filename - - if ( QFile::exists( proj_filename ) ) { - // check at least owner read/write perms ok - QFile::Permissions perms = QFile::permissions( proj_filename ); - if ( ( perms & QFile::WriteOwner ) != QFile::WriteOwner || - ( perms & QFile::ReadOwner ) != QFile::ReadOwner ) { - // TODO: vkError perms - } else { - vkCfgProjectFilePath = proj_filename; - - // don't clear current settings, just update from project cfg file - readFromProjConfigFile(); - } + } else { + // first clear all current settings, then read in global + this->clear(); + readFromGlblConfigFile(); } -#endif - // Fourth: Command line options update 'working' config - // TODO + // 3) If given a Project file on the command line, read and update 'working' config + // Done by parseCmdArgs() -> vkObj::updateConfig(), called after us. + // 4) Command line options update 'working' config + // Done by parseCmdArgs(), called after us. /* vkFatal( 0, "Initialising Config", @@ -150,10 +135,21 @@ */ void VkConfig::createNewProject( QString& dir, QString& proj_name ) { + createNewProject( dir + "/" + proj_name + "." + VK_CFG_EXT ); +} + + +/*! + VkConfig::createNewProject() + Sets project filename to given (new) project config file. + Writes the current config to the given new project config file. + */ +void VkConfig::createNewProject( QString proj_filename ) +{ // ensure any existing project settings are saved first. vkConfig->sync(); - vkCfgProjectFilename = dir + "/" + proj_name + "." + VK_CFG_EXT; + vkCfgProjectFilename = proj_filename; this->saveToProjConfigFile(); } Modified: branches/valkyrie_qt4port/utils/vk_config.h =================================================================== --- branches/valkyrie_qt4port/utils/vk_config.h 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/utils/vk_config.h 2010-01-08 21:43:43 UTC (rev 464) @@ -74,7 +74,8 @@ bool initCfg( Valkyrie* vk ); void createNewProject( QString& dir, QString& proj_name ); - void openProject( QString& proj_name ); + void createNewProject( QString proj_filename ); + void openProject( QString& proj_filename ); void sync(); void readFromProjConfigFile(); Modified: branches/valkyrie_qt4port/valkyrie.pro =================================================================== --- branches/valkyrie_qt4port/valkyrie.pro 2010-01-08 09:18:57 UTC (rev 463) +++ branches/valkyrie_qt4port/valkyrie.pro 2010-01-08 21:43:43 UTC (rev 464) @@ -5,12 +5,14 @@ TEMPLATE = app SOURCES += main.cpp \ mainwindow.cpp \ - objects/vk_objects.cpp \ objects/valkyrie_object.cpp \ objects/valgrind_object.cpp \ + objects/vk_objects.cpp \ + options/vk_option.cpp \ options/vk_options_dialog.cpp \ - options/vk_option.cpp \ options/vk_options_page.cpp \ + options/vk_parse_cmdline.cpp \ + options/vk_popt.cpp \ options/valgrind_options_page.cpp \ options/valkyrie_options_page.cpp \ options/widgets/opt_base_widget.cpp \ @@ -19,18 +21,20 @@ options/widgets/opt_le_widget.cpp \ options/widgets/opt_sp_widget.cpp \ options/widgets/opt_lb_widget.cpp \ + toolview/helgrindview.cpp \ + toolview/memcheckview.cpp \ toolview/toolview.cpp \ - toolview/memcheckview.cpp \ - toolview/helgrindview.cpp \ - utils/vk_utils.cpp \ - utils/vk_config.cpp + utils/vk_config.cpp \ + utils/vk_utils.cpp HEADERS += mainwindow.h \ - objects/vk_objects.h \ objects/valkyrie_object.h \ objects/valgrind_object.h \ + objects/vk_objects.h \ + options/vk_option.h \ options/vk_options_dialog.h \ - options/vk_option.h \ options/vk_options_page.h \ + options/vk_parse_cmdline.h \ + options/vk_popt.h \ options/valgrind_options_page.h \ options/valkyrie_options_page.h \ options/widgets/opt_base_widget.h \ @@ -39,9 +43,9 @@ options/widgets/opt_le_widget.h \ options/widgets/opt_sp_widget.h \ options/widgets/opt_lb_widget.h \ + toolview/helgrindview.h \ + toolview/memcheckview.h \ toolview/toolview.h \ - toolview/memcheckview.h \ - toolview/helgrindview.h \ - utils/vk_utils.h \ - utils/vk_config.h + utils/vk_config.h \ + utils/vk_utils.h RESOURCES += icons.qrc |
From: <sv...@va...> - 2010-01-08 09:19:06
|
Author: cerion Date: 2010-01-08 09:18:57 +0000 (Fri, 08 Jan 2010) New Revision: 463 Log: moved 'core' dir to 'objects' - else confusion with core dumps etc. Added: branches/valkyrie_qt4port/objects/ branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/objects/vk_objects.cpp branches/valkyrie_qt4port/objects/vk_objects.h Removed: branches/valkyrie_qt4port/core/ branches/valkyrie_qt4port/objects/valgrind_object.cpp branches/valkyrie_qt4port/objects/valgrind_object.h branches/valkyrie_qt4port/objects/valkyrie_object.cpp branches/valkyrie_qt4port/objects/valkyrie_object.h branches/valkyrie_qt4port/objects/vk_objects.cpp branches/valkyrie_qt4port/objects/vk_objects.h Modified: branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/vk_option.cpp branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/options/vk_options_page.h branches/valkyrie_qt4port/utils/vk_config.h branches/valkyrie_qt4port/valkyrie.pro Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2010-01-08 00:46:31 UTC (rev 462) +++ branches/valkyrie_qt4port/main.cpp 2010-01-08 09:18:57 UTC (rev 463) @@ -21,7 +21,7 @@ #include <QtGui/QApplication> -#include "core/valkyrie_object.h" +#include "objects/valkyrie_object.h" #include "toolview/toolview.h" #include "mainwindow.h" Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2010-01-08 00:46:31 UTC (rev 462) +++ branches/valkyrie_qt4port/mainwindow.h 2010-01-08 09:18:57 UTC (rev 463) @@ -29,7 +29,7 @@ #include <QToolButton> #include <QVBoxLayout> -#include "core/valkyrie_object.h" +#include "objects/valkyrie_object.h" #include "options/vk_options_dialog.h" #include "toolview/toolview.h" Copied: branches/valkyrie_qt4port/objects (from rev 461, branches/valkyrie_qt4port/core) Property changes on: branches/valkyrie_qt4port/objects ___________________________________________________________________ Name: svn:mergeinfo + Deleted: branches/valkyrie_qt4port/objects/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-08 09:18:57 UTC (rev 463) @@ -1,838 +0,0 @@ -/**************************************************************************** -** Valgrind implementation -** - Valgrind-specific: options / flags / functionality -** -------------------------------------------------------------------------- -** -** Copyright (C) 2000-2009, 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 <QDir> - -#include "core/valgrind_object.h" -#include "options/valgrind_options_page.h" // createVkOptionsPage() - -//#include "config.h" // VK_CFG_DIR, VK_SUPPS_DIR -//#include "vk_config.h" -//#include "html_urls.h" -//#include "memcheck_object.h" -//#include "cachegrind_object.h" -//#include "massif_object.h" -//#include "vk_option.h" // PERROR* and friends -//#include "vk_utils.h" // vk_assert, VK_DEBUG, etc. - - -//TODO: from config.h -#define VK_CFG_DIR ".valkyrie" -#define VK_SUPPS_DIR "suppressions/" - -//#include <ctype.h> -//#include <stdlib.h> -//#include <string.h> -//#include <stdio.h> - - -/***************************************************************************/ -/*! - Constructs a Valkyrie object -*/ -Valgrind::Valgrind() - : VkObject( "valgrind" ) - // : VkObject( "Valgrind", "Valgrind", Qt::Key_unknown, VkObject::ID_VALGRIND ) -{ - // /* init tools */ - // initToolObjects();`` - - setupOptions(); -} - - -Valgrind::~Valgrind() -{ - // m_toolObjList.setAutoDelete( true ); - // m_toolObjList.clear(); -} - - - -/*! - Setup the options for this object. - - Note: These opts should be kept in exactly the same order as valgrind - outputs them, as it makes keeping up-to-date a lot easier. -*/ -void Valgrind::setupOptions() -{ - - // ------------------------------------------------------------ - // tool - options.addOpt( - VALGRIND::TOOL, - this->objectName(), - "tool", - '\0', - "<name>", - "memcheck|cachegrind|massif", - "memcheck", - "Main tool:", - "use the Valgrind tool named <name>. Available tools are: memcheck, cachegrind, massif", - "",// TODO: urlVgCore::mainTool - VkOPT::ARG_STRING, - VkOPT::WDG_COMBO - ); - - - // ------------------------------------------------------------ - // common options relevant to all tools - options.addOpt( - VALGRIND::VERBOSITY, - this->objectName(), - "verbosity", - '\0', - "<0..4>", - "0|4", - "1", - "Verbosity level:", - "Be more verbose, include counts of errors", - "",// TODO: urlVgCore::verbosity - VkOPT::ARG_UINT, - VkOPT::WDG_SPINBOX - ); - - options.addOpt( - VALGRIND::TRACE_CH, - this->objectName(), - "trace-children", - '\0', - "<yes|no>", - "yes|no", - "no", - "Trace child processes: ", - "Valgrind-ise child processes (follow execve)?", - "",// TODO: urlVgCore::traceChild - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::SILENT_CH, - this->objectName(), - "child-silent-after-fork", - '\0', - "<yes|no>", - "yes|no", - "yes", /* currently necessary for clean XML output */ - "Omit child output between fork and exec: ", - "omit child output between fork & exec?", - "",// TODO: urlVgCore::silentChild - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::TRACK_FDS, - this->objectName(), - "track-fds", - '\0', - "<yes|no>", - "yes|no", - "no", - "Track open file descriptors:", - "track open file descriptors?", - "",// TODO: urlVgCore::trackFds - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::TIME_STAMP, - this->objectName(), - "time-stamp", - '\0', - "<yes|no>", - "yes|no", - "no", - "Add timestamps to log messages:", - "add timestamps to log messages?", - "",// TODO: urlVgCore::timeStamp - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::LOG_FD, - this->objectName(), - "log-fd", - '\0', - "<1..1024>", - "1|1023", - "2", - "Log to file descriptor:", - "log messages to file descriptor (1=stdout, 2=stderr)", - "",// TODO: urlVgCore::logToFd - VkOPT::ARG_UINT, - VkOPT::WDG_SPINBOX - ); - - options.addOpt( - VALGRIND::LOG_FILE, - this->objectName(), - "log-file", - '\0', - "<file>", - "", - "", - "Log to file:", - "log messages to <file>", - "",// TODO: urlVgCore::logToFile - VkOPT::ARG_STRING, - VkOPT::WDG_LEDIT - ); - - options.addOpt( - VALGRIND::LOG_SOCKET, - this->objectName(), - "log-socket", - '\0', - "<ipaddr:port>", - "", - "", - "Log to socket:", - "log messages to socket ipaddr:port", - "",// TODO: urlVgCore::logToSocket - VkOPT::ARG_STRING, - VkOPT::WDG_LEDIT - ); - - - // ------------------------------------------------------------ - // uncommon options relevant to all tools - options.addOpt( - VALGRIND::RUN_LIBC, - this->objectName(), - "run-libc-freeres", - '\0', - "<yes|no>", - "yes|no", - "yes", - "Free glibc memory at exit:", - "Free up glibc memory at exit?", - "",// TODO: urlVgCore::freeGlibc - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::SIM_HINTS, - this->objectName(), - "sim-hints", - '\0', - "<hint1,hint2,...>", - "none|lax-ioctls|enable-outer", - "none", - "Simulation Hints:", - "Slightly modify the simulated behaviour. Recognised hints are: lax-ioctls, enable-outer. Use with caution!", - "",// TODO: urlVgCore::simHints - VkOPT::ARG_STRING, - VkOPT::WDG_COMBO - ); - - options.addOpt( - VALGRIND::KERN_VAR, - this->objectName(), - "kernel-variant", - '\0', - "<variant1,...>", - "none|bproc", - "none", - "Kernel Variants:", - "Handle non-standard kernel variants. Recognised variants are: bproc. Use with caution!", - "",// TODO: urlVgCore::kernelVariant - VkOPT::ARG_STRING, - VkOPT::WDG_COMBO - ); - - options.addOpt( - VALGRIND::EM_WARNS, - this->objectName(), - "show-emwarns", - '\0', - "<yes|no>", - "yes|no", - "no", - "Show warnings about emulation limits:", - "show warnings about emulation limits?", - "",// TODO: urlVgCore::showEmWarns - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::SMC_CHECK, - this->objectName(), - "smc-check", - '\0', - "<none|stack|all>", - "none|stack|all", - "stack", - "Where to check for self-modifying code", - "checks for self-modifying code: none, only for code on the stack, or all", - "",// TODO: urlVgCore::smcSupport - VkOPT::ARG_STRING, - VkOPT::WDG_COMBO - ); - - - // ------------------------------------------------------------ - // options relevant to error-reporting tools - options.addOpt( - VALGRIND::XML_OUTPUT, - this->objectName(), - "xml", - '\0', - "<yes|no>", - "yes|no", - "yes", - "Output in xml format:", - "all output is in XML", - "",// TODO: urlVgCore::xmlOutput - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::XML_COMMENT, - this->objectName(), - "xml-user-comment", - '\0', - "<str>", - "", - "", - "Insert verbatim in xml output", - "copy <str> verbatim to XML output", - "",// TODO: urlVgCore::xmlComment - VkOPT::ARG_STRING, - VkOPT::WDG_NONE - ); - - options.addOpt( - VALGRIND::DEMANGLE, - this->objectName(), - "demangle", - '\0', - "<yes|no>", - "yes|no", - "yes", - "Automatically demangle C++ names", - "automatically demangle C++ names?", - "",// TODO: urlVgCore::autoDemangle - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::NUM_CALLERS, - this->objectName(), - "num-callers", - '\0', - "<1..50>", - "1|50", - "12", - "Number of stack trace callers:", - "show <num> callers in stack traces", - "",// TODO: urlVgCore::numCallers - VkOPT::ARG_UINT, - VkOPT::WDG_SPINBOX - ); - - options.addOpt( - VALGRIND::ERROR_LIMIT, - this->objectName(), - "error-limit", - '\0', - "<yes|no>", - "yes|no", - "yes", - "Limit the number of errors shown", - "Stop showing new errors if too many?", - "",// TODO: urlVgCore::errorLimit - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::SHOW_BELOW, - this->objectName(), - "show-below-main", - '\0', - "<yes|no>", - "yes|no", - "no", - "Continue stack traces below main()", - "continue stack traces below main()", - "",// TODO: urlVgCore::stackTraces - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - - // ------------------------------------------------------------ - // Can't access vkConfig->suppDir(): config created after us! - QString defSuppDir = QDir::homePath() + "/" + VK_CFG_DIR + VK_SUPPS_DIR; - /* list of dirs holding suppression files */ - options.addOpt( - VALGRIND::SUPPS_DIRS, - this->objectName(), - "supps-dirs", - '\0', - "", - "", - defSuppDir, - "Suppression Dirs:", - "", - "",// TODO: urlValkyrie::suppsTab - VkOPT::NOT_POPT, - VkOPT::WDG_LISTBOX - ); - - /* list of all suppression files found in option SUPP_DIRS */ - options.addOpt( - VALGRIND::SUPPS_AVAIL, - this->objectName(), - "supps-avail", - '\0', - "", - "", - "", - "Available error-suppression file(s):", - "", - "",// TODO: urlValkyrie::suppsTab - VkOPT::NOT_POPT, - VkOPT::WDG_LISTBOX - ); - - /* list of selected suppression files */ - options.addOpt( - VALGRIND::SUPPS_SEL, - this->objectName(), - "suppressions", - '\0', - "<file1,...>", - "", - "", - "Selected error-suppression file(s):", - "suppress errors described in suppressions file(s)", - "",// TODO: urlValkyrie::suppsTab - VkOPT::ARG_STRING, - VkOPT::WDG_LISTBOX - ); - - - // ------------------------------------------------------------ - // ... - options.addOpt( - VALGRIND::GEN_SUPP, - this->objectName(), - "gen-suppressions", - '\0', - "<yes|no|all>", - "yes|no|all", - "no", - "Print suppressions for errors", - "print suppressions for errors?", - "",// TODO: urlVgCore::genSuppressions - VkOPT::ARG_STRING, - VkOPT::WDG_COMBO - ); - - options.addOpt( - VALGRIND::DB_ATTACH, - this->objectName(), - "db-attach", - '\0', - "<yes|no>", - "yes|no", - "no", - "Start debugger on error detection", - "start debugger when errors detected?", - "",// TODO: urlVgCore::startDebugger - VkOPT::ARG_BOOL, - VkOPT::WDG_CHECK - ); - - options.addOpt( - VALGRIND::DB_COMMAND, - this->objectName(), - "db-command", - '\0', - "<command>", - "", - "/usr/bin/gdb -nw %f %p", - "Debugger:", - "command to start debugger", - "",// TODO: urlVgCore::whichDebugger - VkOPT::ARG_STRING, - VkOPT::WDG_LEDIT - ); - - options.addOpt( - VALGRIND::INPUT_FD, - this->objectName(), - "input-fd", - '\0', - "<0..1024>", - "0|1023", - "0", - "Input file descriptor:", - - "File descriptor for (db) input (0=stdin, 1=stdout, 2=stderr)", - "",// TODO: urlVgCore::inputFd - VkOPT::ARG_UINT, - VkOPT::WDG_SPINBOX - ); - - options.addOpt( - VALGRIND::MAX_SFRAME, - this->objectName(), - "max-stackframe", - '\0', - "<number>", - "0|2000000", - "2000000", - "Stack switch on SP changes at:", - "assume stack switch for stack pointer changes larger than <number> bytes", - "",// TODO: urlVgCore::maxSFrames - VkOPT::ARG_UINT, - VkOPT::WDG_SPINBOX - ); -} - - -/* check argval for this option, updating if necessary. - called by parseCmdArgs() and gui option pages -------------------- */ -int Valgrind::checkOptArg( int optid, QString& argval ) -{ -optid = optid; argval = argval; -// vk_assert( optid >= 0 && optid < NUM_OPTS ); - - int errval = PARSED_OK; - -#if 0 - Option* opt = findOption( optid ); - QString sep = vkConfig->sepChar(); - - switch ( (Valgrind::vgOpts)optid ) { - - case VALGRIND::TOOL: - /* Note: gui option disabled, so only reaches here from cmdline */ - errval = PERROR_BADOPT; - vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); - vkPrintErr(" - Valkyrie currently only supports Memcheck."); - break; - - case VALGRIND::SIM_HINTS: - case VALGRIND::RUN_LIBC: - case VALGRIND::NUM_CALLERS: - case VALGRIND::DEMANGLE: - // case VALGRIND::INPUT_FD: // TODO - case VALGRIND::SHOW_BELOW: - case VALGRIND::MAX_SFRAME: - case VALGRIND::SMC_CHECK: - opt->isValidArg( &errval, argval ); - break; - - case VALGRIND::VERBOSITY: - case VALGRIND::TRACK_FDS: - case VALGRIND::TIME_STAMP: - case VALGRIND::EM_WARNS: - case VALGRIND::GEN_SUPP: - case VALGRIND::ERROR_LIMIT: - case VALGRIND::DB_COMMAND: - case VALGRIND::DB_ATTACH: - /* Note: gui option disabled, so only reaches here from cmdline */ - errval = PERROR_BADOPT; - vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); - vkPrintErr(" - Valgrind presets these options for XML output."); - vkPrintErr(" - See valgrind/docs/internals/xml_output.txt."); - break; - - case VALGRIND::XML_COMMENT: - /* don't wan't xml in comment: escape '<','&',etc */ - argval = escapeEntities( argval ); - break; - - case VALGRIND::SUPPS_DIRS: { /* not popt: only reaches here from gui */ - /* check all entries are valid dirs */ - QStringList dirs = QStringList::split(sep, argval); - QStringList::iterator it = dirs.begin(); - for (; it != dirs.end(); ++it) { - /* check dirs ok */ - *it = dirCheck( &errval, *it, true, false ); - if ( errval != PARSED_OK ) - break; - } - argval = dirs.join(sep); - } break; - - case VALGRIND::SUPPS_AVAIL: /* not popt: only reaches here from gui */ - case VALGRIND::SUPPS_SEL: { /* is popt: --suppressions */ - QStringList files = QStringList::split(sep, argval); - QStringList::iterator it = files.begin(); - for (; it != files.end(); ++it) { - /* check files ok & readable */ - *it = fileCheck( &errval, *it, true, false ); - if ( errval != PARSED_OK ) - break; - /* TODO: do we care if it doesn't end in .supp? - - breaks the suppression widgets a little, as only lists those ending in .supp ... */ - - /* TODO: ? check valid suppression files */ - } - argval = files.join(sep); - } break; - - case VALGRIND::TRACE_CH: { -#if 0 - if ( opt->isValidArg( &errval, argval ) ) { - if ( argval == "yes" ) { - if ( vkConfig->rdBool( "db-attach", "valgrind" ) ) - errval = PERROR_DB_CONFLICT; - } - } -#else - /* Disabled for now - can't deal with the multiple xml files this generates */ - /* Note: Also disabled in ValgrindOptionsPage() */ - errval = PERROR_BADOPT; -// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); -// vkPrintErr(" - Valkyrie can't yet handle the multiple xml files this generates."); -#endif - } break; - - case VALGRIND::SILENT_CH: { - /* Disabled for now - output between fork and exec is confusing for the XML output */ - /* Note: Also disabled in ValgrindOptionsPage() */ - errval = PERROR_BADOPT; -// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); -// vkPrintErr(" - Necessary, to get clean XML output from Valgrind."); - } break; - - case VALGRIND::XML_OUTPUT: - /* Note: gui option disabled, so only reaches here from cmdline */ - errval = PERROR_BADOPT; -// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); -// vkPrintErr(" - Valkyrie always requires xml output from Valgrind."); - break; - - -#if 0 // TODO: Fix Valgrind to allow gdb attaching with XML output - case VALGRIND::DB_COMMAND: { /* gdb -nw %f %p */ - int pos = argval.find( ' ' ); - QString tmp = argval.left( pos ); - argval = binaryCheck( &errval, tmp ); - argval += tmp.right( tmp.length() - pos+1 ); - // vkPrint("db_command: %s", argval.latin1() ); - } break; - - /* check for conflict with --trace-children */ - case VALGRIND::DB_ATTACH: - if ( opt->isValidArg( &errval, argval ) ) { - if ( argval == "yes" ) { - if ( vkConfig->rdBool( "trace-children","valgrind" ) ) - errval = PERROR_DB_CONFLICT; - } - } break; -#endif - - case VALGRIND::KERN_VAR: - break; - - /* logging options */ - /* all tools use an internal logging option, - all logging options are therefore ignored */ - case VALGRIND::LOG_FILE: - case VALGRIND::LOG_FD: - case VALGRIND::LOG_SOCKET: - /* Note: gui options disabled, so only reaches here from cmdline */ - errval = PERROR_BADOPT; - vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); - vkPrintErr(" - Valkyrie sets its own logging options to gather data from Valgrind."); - break; - - - /* Not yet implemented */ - case VALGRIND::INPUT_FD: - /* Note: gui option disabled, so only reaches here from cmdline */ - errval = PERROR_BADOPT; -// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); -// vkPrintErr(" - Not yet implemented."); - break; - - default: - assert( true ); -// vk_assert_never_reached(); - } -#endif - - return errval; -} - - -#if 0 -/* valkyrie hijacks any log-to-file flags; these are not passed to - valgrind, but are used after parsing has finished to save to. */ -QStringList Valgrind::modifiedVgFlags( const ToolObject* tool_obj ) -{ - QStringList modFlags; - QString defVal, cfgVal, flag; - - for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { - flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag - : opt->m_longFlag; - defVal = opt->m_defaultValue; - cfgVal = vkConfig->rdEntry( opt->cfgKey(), name() ); - - switch ( (Valgrind::vgOpts)opt->m_key ) { - - /* we never want these included */ - case VALGRIND::TOOL: /* tool set by valkyrie */ - case VALGRIND::SUPPS_DIRS: /* false option */ - case VALGRIND::SUPPS_AVAIL: /* false option */ - break; - - /* only error-reporting tools have suppressions */ - case VALGRIND::SUPPS_SEL: { - if ( tool_obj->name() == "memcheck" ) { - /* we need '--suppressions=' before each and every filename */ - QString optEntry = vkConfig->rdEntry( opt->cfgKey(), name() ); - QStringList files = QStringList::split( ",", optEntry ); - for ( unsigned int i=0; i<files.count(); i++ ) { - modFlags << "--" + opt->cfgKey() + "=" + files[i]; - } - } - } break; - - - /* for memcheck we always need xml=yes */ - case VALGRIND::XML_OUTPUT: - if ( tool_obj->name() == "memcheck") - modFlags << "--" + opt->cfgKey() + "=yes"; - else - if ( defVal != cfgVal ) - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; - break; - - /* for memcheck we needs this enabled to keep the xml clean */ - case VALGRIND::SILENT_CH: - if ( tool_obj->name() == "memcheck") - modFlags << "--" + opt->cfgKey() + "=yes"; - else - if ( defVal != cfgVal ) - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; - break; - - case VALGRIND::VERBOSITY: - case VALGRIND::TRACK_FDS: - case VALGRIND::TIME_STAMP: - case VALGRIND::EM_WARNS: - case VALGRIND::GEN_SUPP: - case VALGRIND::ERROR_LIMIT: - case VALGRIND::DB_ATTACH: - case VALGRIND::DB_COMMAND: - if ( defVal != cfgVal ) { - // disabled for now: /* gui options not disabled: other tools use these options */ - if ( tool_obj->name() == "memcheck") { - /* memcheck presets/ignores these options for xml output - - ignore these opts - - see valgrind/docs/internals/xml_output.txt */ - } else { - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; - } - } - break; - - /* all tools use an internal logging option, - all logging options should therefore not be used */ - case VALGRIND::LOG_FILE: - case VALGRIND::LOG_FD: - case VALGRIND::LOG_SOCKET: - /* ignore these opts */ - break; - - default: - if ( defVal != cfgVal ) { - modFlags << "--" + opt->cfgKey() + "=" + cfgVal; - } - break; - } - } - - return modFlags; -} - - - -/* Register tools */ -void Valgrind::initToolObjects() -{ - int objId = VkObject::ID_TOOL0; - m_toolObjList.append( new Memcheck ( objId++ ) ); - - // TODO: I need another lifetime! - // m_toolObjList.append( new Cachegrind( objId++ ) ); - // m_toolObjList.append( new Massif ( objId++ ) ); -} - - -/* ToolObject access -------------------------------------------=---- */ - -/* Returns a list of all ptrs to ToolObjects */ -ToolObjList Valgrind::toolObjList() -{ - return m_toolObjList; -} - -/* Returns a ToolObject's objectId based on its name */ -int Valgrind::toolObjId( const QString& name ) -{ - return toolObj(name)->objId(); -} - -/* Returns a ToolObject based on its objectId */ -ToolObject* Valgrind::toolObj( int tid ) -{ - // vkPrint("Valgrind::toolObj( int tid=%d )", tid); - vk_assert( tid >= ID_TOOL0 ); - ToolObject* tool = m_toolObjList.at( tid - ID_TOOL0 ); - vk_assert( tool != 0 ); - vk_assert( tool->objId() == tid ); - return tool; -} - -/* Returns a ToolObject based on its name */ -ToolObject* Valgrind::toolObj( const QString& name ) { - ToolObject* tool; - for ( tool = m_toolObjList.first(); tool; tool = m_toolObjList.next() ) { - if ( tool->name() == name ) - return tool; - } - vk_assert_never_reached(); - return NULL; -} -#endif - - - -VkOptionsPage* Valgrind::createVkOptionsPage() { - return (VkOptionsPage*)new ValgrindOptionsPage( this ); -} Copied: branches/valkyrie_qt4port/objects/valgrind_object.cpp (from rev 462, branches/valkyrie_qt4port/core/valgrind_object.cpp) =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.cpp (rev 0) +++ branches/valkyrie_qt4port/objects/valgrind_object.cpp 2010-01-08 09:18:57 UTC (rev 463) @@ -0,0 +1,836 @@ +/**************************************************************************** +** Valgrind implementation +** - Valgrind-specific: options / flags / functionality +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 <QDir> + +#include "objects/valgrind_object.h" +#include "options/valgrind_options_page.h" // createVkOptionsPage() + +#include "utils/vk_config.h" + +//#include "config.h" +//#include "html_urls.h" +//#include "memcheck_object.h" +//#include "cachegrind_object.h" +//#include "massif_object.h" +//#include "vk_option.h" // PERROR* and friends +//#include "vk_utils.h" // vk_assert, VK_DEBUG, etc. + + +//#include <ctype.h> +//#include <stdlib.h> +//#include <string.h> +//#include <stdio.h> + + +/***************************************************************************/ +/*! + Constructs a Valkyrie object +*/ +Valgrind::Valgrind() + : VkObject( "valgrind" ) + // : VkObject( "Valgrind", "Valgrind", Qt::Key_unknown, VkObject::ID_VALGRIND ) +{ + // /* init tools */ + // initToolObjects();`` + + setupOptions(); +} + + +Valgrind::~Valgrind() +{ + // m_toolObjList.setAutoDelete( true ); + // m_toolObjList.clear(); +} + + + +/*! + Setup the options for this object. + + Note: These opts should be kept in exactly the same order as valgrind + outputs them, as it makes keeping up-to-date a lot easier. +*/ +void Valgrind::setupOptions() +{ + + // ------------------------------------------------------------ + // tool + options.addOpt( + VALGRIND::TOOL, + this->objectName(), + "tool", + '\0', + "<name>", + "memcheck|cachegrind|massif", + "memcheck", + "Main tool:", + "use the Valgrind tool named <name>. Available tools are: memcheck, cachegrind, massif", + "",// TODO: urlVgCore::mainTool + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + + // ------------------------------------------------------------ + // common options relevant to all tools + options.addOpt( + VALGRIND::VERBOSITY, + this->objectName(), + "verbosity", + '\0', + "<0..4>", + "0|4", + "1", + "Verbosity level:", + "Be more verbose, include counts of errors", + "",// TODO: urlVgCore::verbosity + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::TRACE_CH, + this->objectName(), + "trace-children", + '\0', + "<yes|no>", + "yes|no", + "no", + "Trace child processes: ", + "Valgrind-ise child processes (follow execve)?", + "",// TODO: urlVgCore::traceChild + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SILENT_CH, + this->objectName(), + "child-silent-after-fork", + '\0', + "<yes|no>", + "yes|no", + "yes", /* currently necessary for clean XML output */ + "Omit child output between fork and exec: ", + "omit child output between fork & exec?", + "",// TODO: urlVgCore::silentChild + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::TRACK_FDS, + this->objectName(), + "track-fds", + '\0', + "<yes|no>", + "yes|no", + "no", + "Track open file descriptors:", + "track open file descriptors?", + "",// TODO: urlVgCore::trackFds + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::TIME_STAMP, + this->objectName(), + "time-stamp", + '\0', + "<yes|no>", + "yes|no", + "no", + "Add timestamps to log messages:", + "add timestamps to log messages?", + "",// TODO: urlVgCore::timeStamp + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::LOG_FD, + this->objectName(), + "log-fd", + '\0', + "<1..1024>", + "1|1023", + "2", + "Log to file descriptor:", + "log messages to file descriptor (1=stdout, 2=stderr)", + "",// TODO: urlVgCore::logToFd + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::LOG_FILE, + this->objectName(), + "log-file", + '\0', + "<file>", + "", + "", + "Log to file:", + "log messages to <file>", + "",// TODO: urlVgCore::logToFile + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + options.addOpt( + VALGRIND::LOG_SOCKET, + this->objectName(), + "log-socket", + '\0', + "<ipaddr:port>", + "", + "", + "Log to socket:", + "log messages to socket ipaddr:port", + "",// TODO: urlVgCore::logToSocket + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + + // ------------------------------------------------------------ + // uncommon options relevant to all tools + options.addOpt( + VALGRIND::RUN_LIBC, + this->objectName(), + "run-libc-freeres", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Free glibc memory at exit:", + "Free up glibc memory at exit?", + "",// TODO: urlVgCore::freeGlibc + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SIM_HINTS, + this->objectName(), + "sim-hints", + '\0', + "<hint1,hint2,...>", + "none|lax-ioctls|enable-outer", + "none", + "Simulation Hints:", + "Slightly modify the simulated behaviour. Recognised hints are: lax-ioctls, enable-outer. Use with caution!", + "",// TODO: urlVgCore::simHints + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::KERN_VAR, + this->objectName(), + "kernel-variant", + '\0', + "<variant1,...>", + "none|bproc", + "none", + "Kernel Variants:", + "Handle non-standard kernel variants. Recognised variants are: bproc. Use with caution!", + "",// TODO: urlVgCore::kernelVariant + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::EM_WARNS, + this->objectName(), + "show-emwarns", + '\0', + "<yes|no>", + "yes|no", + "no", + "Show warnings about emulation limits:", + "show warnings about emulation limits?", + "",// TODO: urlVgCore::showEmWarns + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SMC_CHECK, + this->objectName(), + "smc-check", + '\0', + "<none|stack|all>", + "none|stack|all", + "stack", + "Where to check for self-modifying code", + "checks for self-modifying code: none, only for code on the stack, or all", + "",// TODO: urlVgCore::smcSupport + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + + // ------------------------------------------------------------ + // options relevant to error-reporting tools + options.addOpt( + VALGRIND::XML_OUTPUT, + this->objectName(), + "xml", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Output in xml format:", + "all output is in XML", + "",// TODO: urlVgCore::xmlOutput + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::XML_COMMENT, + this->objectName(), + "xml-user-comment", + '\0', + "<str>", + "", + "", + "Insert verbatim in xml output", + "copy <str> verbatim to XML output", + "",// TODO: urlVgCore::xmlComment + VkOPT::ARG_STRING, + VkOPT::WDG_NONE + ); + + options.addOpt( + VALGRIND::DEMANGLE, + this->objectName(), + "demangle", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Automatically demangle C++ names", + "automatically demangle C++ names?", + "",// TODO: urlVgCore::autoDemangle + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::NUM_CALLERS, + this->objectName(), + "num-callers", + '\0', + "<1..50>", + "1|50", + "12", + "Number of stack trace callers:", + "show <num> callers in stack traces", + "",// TODO: urlVgCore::numCallers + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::ERROR_LIMIT, + this->objectName(), + "error-limit", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Limit the number of errors shown", + "Stop showing new errors if too many?", + "",// TODO: urlVgCore::errorLimit + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SHOW_BELOW, + this->objectName(), + "show-below-main", + '\0', + "<yes|no>", + "yes|no", + "no", + "Continue stack traces below main()", + "continue stack traces below main()", + "",// TODO: urlVgCore::stackTraces + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + + // ------------------------------------------------------------ + // Can't access vkConfig->suppDir(): config created after us! + QString defSuppDir = QDir::homePath() + "/" + QString(VK_CFG_GLBL_DIR) + VK_SUPPS_DIR; + /* list of dirs holding suppression files */ + options.addOpt( + VALGRIND::SUPPS_DIRS, + this->objectName(), + "supps-dirs", + '\0', + "", + "", + defSuppDir, + "Suppression Dirs:", + "", + "",// TODO: urlValkyrie::suppsTab + VkOPT::NOT_POPT, + VkOPT::WDG_LISTBOX + ); + + /* list of all suppression files found in option SUPP_DIRS */ + options.addOpt( + VALGRIND::SUPPS_AVAIL, + this->objectName(), + "supps-avail", + '\0', + "", + "", + "", + "Available error-suppression file(s):", + "", + "",// TODO: urlValkyrie::suppsTab + VkOPT::NOT_POPT, + VkOPT::WDG_LISTBOX + ); + + /* list of selected suppression files */ + options.addOpt( + VALGRIND::SUPPS_SEL, + this->objectName(), + "suppressions", + '\0', + "<file1,...>", + "", + "", + "Selected error-suppression file(s):", + "suppress errors described in suppressions file(s)", + "",// TODO: urlValkyrie::suppsTab + VkOPT::ARG_STRING, + VkOPT::WDG_LISTBOX + ); + + + // ------------------------------------------------------------ + // ... + options.addOpt( + VALGRIND::GEN_SUPP, + this->objectName(), + "gen-suppressions", + '\0', + "<yes|no|all>", + "yes|no|all", + "no", + "Print suppressions for errors", + "print suppressions for errors?", + "",// TODO: urlVgCore::genSuppressions + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::DB_ATTACH, + this->objectName(), + "db-attach", + '\0', + "<yes|no>", + "yes|no", + "no", + "Start debugger on error detection", + "start debugger when errors detected?", + "",// TODO: urlVgCore::startDebugger + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::DB_COMMAND, + this->objectName(), + "db-command", + '\0', + "<command>", + "", + "/usr/bin/gdb -nw %f %p", + "Debugger:", + "command to start debugger", + "",// TODO: urlVgCore::whichDebugger + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + options.addOpt( + VALGRIND::INPUT_FD, + this->objectName(), + "input-fd", + '\0', + "<0..1024>", + "0|1023", + "0", + "Input file descriptor:", + + "File descriptor for (db) input (0=stdin, 1=stdout, 2=stderr)", + "",// TODO: urlVgCore::inputFd + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::MAX_SFRAME, + this->objectName(), + "max-stackframe", + '\0', + "<number>", + "0|2000000", + "2000000", + "Stack switch on SP changes at:", + "assume stack switch for stack pointer changes larger than <number> bytes", + "",// TODO: urlVgCore::maxSFrames + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); +} + + + +/* check argval for this option, updating if necessary. + called by parseCmdArgs() and gui option pages -------------------- */ +int Valgrind::checkOptArg( int optid, QString& argval ) +{ +optid = optid; argval = argval; +// vk_assert( optid >= 0 && optid < NUM_OPTS ); + + int errval = PARSED_OK; + +#if 0 + Option* opt = findOption( optid ); + QString sep = vkConfig->sepChar(); + + switch ( (Valgrind::vgOpts)optid ) { + + case VALGRIND::TOOL: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valkyrie currently only supports Memcheck."); + break; + + case VALGRIND::SIM_HINTS: + case VALGRIND::RUN_LIBC: + case VALGRIND::NUM_CALLERS: + case VALGRIND::DEMANGLE: + // case VALGRIND::INPUT_FD: // TODO + case VALGRIND::SHOW_BELOW: + case VALGRIND::MAX_SFRAME: + case VALGRIND::SMC_CHECK: + opt->isValidArg( &errval, argval ); + break; + + case VALGRIND::VERBOSITY: + case VALGRIND::TRACK_FDS: + case VALGRIND::TIME_STAMP: + case VALGRIND::EM_WARNS: + case VALGRIND::GEN_SUPP: + case VALGRIND::ERROR_LIMIT: + case VALGRIND::DB_COMMAND: + case VALGRIND::DB_ATTACH: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valgrind presets these options for XML output."); + vkPrintErr(" - See valgrind/docs/internals/xml_output.txt."); + break; + + case VALGRIND::XML_COMMENT: + /* don't wan't xml in comment: escape '<','&',etc */ + argval = escapeEntities( argval ); + break; + + case VALGRIND::SUPPS_DIRS: { /* not popt: only reaches here from gui */ + /* check all entries are valid dirs */ + QStringList dirs = QStringList::split(sep, argval); + QStringList::iterator it = dirs.begin(); + for (; it != dirs.end(); ++it) { + /* check dirs ok */ + *it = dirCheck( &errval, *it, true, false ); + if ( errval != PARSED_OK ) + break; + } + argval = dirs.join(sep); + } break; + + case VALGRIND::SUPPS_AVAIL: /* not popt: only reaches here from gui */ + case VALGRIND::SUPPS_SEL: { /* is popt: --suppressions */ + QStringList files = QStringList::split(sep, argval); + QStringList::iterator it = files.begin(); + for (; it != files.end(); ++it) { + /* check files ok & readable */ + *it = fileCheck( &errval, *it, true, false ); + if ( errval != PARSED_OK ) + break; + /* TODO: do we care if it doesn't end in .supp? + - breaks the suppression widgets a little, as only lists those ending in .supp ... */ + + /* TODO: ? check valid suppression files */ + } + argval = files.join(sep); + } break; + + case VALGRIND::TRACE_CH: { +#if 0 + if ( opt->isValidArg( &errval, argval ) ) { + if ( argval == "yes" ) { + if ( vkConfig->rdBool( "db-attach", "valgrind" ) ) + errval = PERROR_DB_CONFLICT; + } + } +#else + /* Disabled for now - can't deal with the multiple xml files this generates */ + /* Note: Also disabled in ValgrindOptionsPage() */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Valkyrie can't yet handle the multiple xml files this generates."); +#endif + } break; + + case VALGRIND::SILENT_CH: { + /* Disabled for now - output between fork and exec is confusing for the XML output */ + /* Note: Also disabled in ValgrindOptionsPage() */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Necessary, to get clean XML output from Valgrind."); + } break; + + case VALGRIND::XML_OUTPUT: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Valkyrie always requires xml output from Valgrind."); + break; + + +#if 0 // TODO: Fix Valgrind to allow gdb attaching with XML output + case VALGRIND::DB_COMMAND: { /* gdb -nw %f %p */ + int pos = argval.find( ' ' ); + QString tmp = argval.left( pos ); + argval = binaryCheck( &errval, tmp ); + argval += tmp.right( tmp.length() - pos+1 ); + // vkPrint("db_command: %s", argval.latin1() ); + } break; + + /* check for conflict with --trace-children */ + case VALGRIND::DB_ATTACH: + if ( opt->isValidArg( &errval, argval ) ) { + if ( argval == "yes" ) { + if ( vkConfig->rdBool( "trace-children","valgrind" ) ) + errval = PERROR_DB_CONFLICT; + } + } break; +#endif + + case VALGRIND::KERN_VAR: + break; + + /* logging options */ + /* all tools use an internal logging option, + all logging options are therefore ignored */ + case VALGRIND::LOG_FILE: + case VALGRIND::LOG_FD: + case VALGRIND::LOG_SOCKET: + /* Note: gui options disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valkyrie sets its own logging options to gather data from Valgrind."); + break; + + + /* Not yet implemented */ + case VALGRIND::INPUT_FD: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Not yet implemented."); + break; + + default: + assert( true ); +// vk_assert_never_reached(); + } +#endif + + return errval; +} + + +#if 0 +/* valkyrie hijacks any log-to-file flags; these are not passed to + valgrind, but are used after parsing has finished to save to. */ +QStringList Valgrind::modifiedVgFlags( const ToolObject* tool_obj ) +{ + QStringList modFlags; + QString defVal, cfgVal, flag; + + for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { + flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag + : opt->m_longFlag; + defVal = opt->m_defaultValue; + cfgVal = vkConfig->rdEntry( opt->cfgKey(), name() ); + + switch ( (Valgrind::vgOpts)opt->m_key ) { + + /* we never want these included */ + case VALGRIND::TOOL: /* tool set by valkyrie */ + case VALGRIND::SUPPS_DIRS: /* false option */ + case VALGRIND::SUPPS_AVAIL: /* false option */ + break; + + /* only error-reporting tools have suppressions */ + case VALGRIND::SUPPS_SEL: { + if ( tool_obj->name() == "memcheck" ) { + /* we need '--suppressions=' before each and every filename */ + QString optEntry = vkConfig->rdEntry( opt->cfgKey(), name() ); + QStringList files = QStringList::split( ",", optEntry ); + for ( unsigned int i=0; i<files.count(); i++ ) { + modFlags << "--" + opt->cfgKey() + "=" + files[i]; + } + } + } break; + + + /* for memcheck we always need xml=yes */ + case VALGRIND::XML_OUTPUT: + if ( tool_obj->name() == "memcheck") + modFlags << "--" + opt->cfgKey() + "=yes"; + else + if ( defVal != cfgVal ) + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + break; + + /* for memcheck we needs this enabled to keep the xml clean */ + case VALGRIND::SILENT_CH: + if ( tool_obj->name() == "memcheck") + modFlags << "--" + opt->cfgKey() + "=yes"; + else + if ( defVal != cfgVal ) + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + break; + + case VALGRIND::VERBOSITY: + case VALGRIND::TRACK_FDS: + case VALGRIND::TIME_STAMP: + case VALGRIND::EM_WARNS: + case VALGRIND::GEN_SUPP: + case VALGRIND::ERROR_LIMIT: + case VALGRIND::DB_ATTACH: + case VALGRIND::DB_COMMAND: + if ( defVal != cfgVal ) { + // disabled for now: /* gui options not disabled: other tools use these options */ + if ( tool_obj->name() == "memcheck") { + /* memcheck presets/ignores these options for xml output + - ignore these opts + - see valgrind/docs/internals/xml_output.txt */ + } else { + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + } + } + break; + + /* all tools use an internal logging option, + all logging options should therefore not be used */ + case VALGRIND::LOG_FILE: + case VALGRIND::LOG_FD: + case VALGRIND::LOG_SOCKET: + /* ignore these opts */ + break; + + default: + if ( defVal != cfgVal ) { + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + } + break; + } + } + + return modFlags; +} + + + +/* Register tools */ +void Valgrind::initToolObjects() +{ + int objId = VkObject::ID_TOOL0; + m_toolObjList.append( new Memcheck ( objId++ ) ); + + // TODO: I need another lifetime! + // m_toolObjList.append( new Cachegrind( objId++ ) ); + // m_toolObjList.append( new Massif ( objId++ ) ); +} + + +/* ToolObject access -------------------------------------------=---- */ + +/* Returns a list of all ptrs to ToolObjects */ +ToolObjList Valgrind::toolObjList() +{ + return m_toolObjList; +} + +/* Returns a ToolObject's objectId based on its name */ +int Valgrind::toolObjId( const QString& name ) +{ + return toolObj(name)->objId(); +} + +/* Returns a ToolObject based on its objectId */ +ToolObject* Valgrind::toolObj( int tid ) +{ + // vkPrint("Valgrind::toolObj( int tid=%d )", tid); + vk_assert( tid >= ID_TOOL0 ); + ToolObject* tool = m_toolObjList.at( tid - ID_TOOL0 ); + vk_assert( tool != 0 ); + vk_assert( tool->objId() == tid ); + return tool; +} + +/* Returns a ToolObject based on its name */ +ToolObject* Valgrind::toolObj( const QString& name ) { + ToolObject* tool; + for ( tool = m_toolObjList.first(); tool; tool = m_toolObjList.next() ) { + if ( tool->name() == name ) + return tool; + } + vk_assert_never_reached(); + return NULL; +} +#endif + + + +VkOptionsPage* Valgrind::createVkOptionsPage() { + return (VkOptionsPage*)new ValgrindOptionsPage( this ); +} Deleted: branches/valkyrie_qt4port/objects/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-08 09:18:57 UTC (rev 463) @@ -1,115 +0,0 @@ -/**************************************************************************** -** Valgrind object class definition -** - Valgrind-specific: options / flags / functionality -** -------------------------------------------------------------------------- -** -** Copyright (C) 2000-2009, 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 __VALGRIND_OBJECT_H -#define __VALGRIND_OBJECT_H - -#include "core/vk_objects.h" -//#include "tool_object.h" - - -// ============================================================ -namespace VALGRIND { -/*! - enum identification of all options for this object -*/ - enum vgOptId { - TOOL, // --tool - /* common options relevant to all tools */ - VERBOSITY, // --verbosity - TRACE_CH, // --trace-children - SILENT_CH, // --child-silent-after-fork - TRACK_FDS, // --track-fds - TIME_STAMP, // --time-stamp - LOG_FD, // --log-fd - LOG_FILE, // --log-file - LOG_SOCKET, // --log-socket - - /* uncommon options relevant to all tools */ - RUN_LIBC, // --run-libc-freeres - SIM_HINTS, // --sim-hints - KERN_VAR, // --kernel-variant - EM_WARNS, // --show-emwarns - SMC_CHECK, // --smc-check - - /* options relevant to error-reporting tools */ - XML_OUTPUT, // --xml - XML_COMMENT, // -- xml-user-comment - DEMANGLE, // --demangle - NUM_CALLERS, // --num-callers - ERROR_LIMIT, // --error-limit - SHOW_BELOW, // --show-below-main - - /* suppressions hackery */ - SUPPS_DIRS, /* list of suppfile dirs - feeds SUPPS_AVAIL list */ - SUPPS_AVAIL, /* fake opt: dyname list of available supp files */ - SUPPS_SEL, /* the currently selected suppression(s) */ - - /* misc */ - GEN_SUPP, // --gen-suppressions - DB_ATTACH, // --db-attach - DB_COMMAND, // --db-command - INPUT_FD, // --input-fd - MAX_SFRAME, // --max-stackframe - NUM_OPTS - }; -} - - -// ============================================================ -class Valgrind : public VkObject -{ -public: - Valgrind(); - ~Valgrind(); - -#if 0 - /* returns a list of non-default flags to pass to valgrind */ - QStringList modifiedVgFlags( const ToolObject* tool_obj ); - unsigned int maxOptId() { return NUM_OPTS; } -#endif - - int checkOptArg( int optid, QString& argval ); - - VkOptionsPage* createVkOptionsPage(); - -#if 0 -public: - /* ToolObject access */ - ToolObjList toolObjList(); - int toolObjId( const QString& name ); - ToolObject* toolObj( int tid ); - ToolObject* toolObj( const QString& name ); -#endif - -private: -#if 0 - /* creates the various VkObjects and initialises their options, - ready for cmd-line parsing (if any). */ - void initToolObjects(); - - ToolObjList m_toolObjList; /* Tools */ -#endif - -private: - void setupOptions(); -}; - -#endif Copied: branches/valkyrie_qt4port/objects/valgrind_object.h (from rev 462, branches/valkyrie_qt4port/core/valgrind_object.h) =================================================================== --- branches/valkyrie_qt4port/objects/valgrind_object.h (rev 0) +++ branches/valkyrie_qt4port/objects/valgrind_object.h 2010-01-08 09:18:57 UTC (rev 463) @@ -0,0 +1,115 @@ +/**************************************************************************** +** Valgrind object class definition +** - Valgrind-specific: options / flags / functionality +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 __VALGRIND_OBJECT_H +#define __VALGRIND_OBJECT_H + +#include "objects/vk_objects.h" +//#include "tool_object.h" + + +// ============================================================ +namespace VALGRIND { +/*! + enum identification of all options for this object +*/ + enum vgOptId { + TOOL, // --tool + /* common options relevant to all tools */ + VERBOSITY, // --verbosity + TRACE_CH, // --trace-children + SILENT_CH, // --child-silent-after-fork + TRACK_FDS, // --track-fds + TIME_STAMP, // --time-stamp + LOG_FD, // --log-fd + LOG_FILE, // --log-file + LOG_SOCKET, // --log-socket + + /* uncommon options relevant to all tools */ + RUN_LIBC, // --run-libc-freeres + SIM_HINTS, // --sim-hints + KERN_VAR, // --kernel-variant + EM_WARNS, // --show-emwarns + SMC_CHECK, // --smc-check + + /* options relevant to error-reporting tools */ + XML_OUTPUT, // --xml + XML_COMMENT, // -- xml-user-comment + DEMANGLE, // --demangle + NUM_CALLERS, // --num-callers + ERROR_LIMIT, // --error-limit + SHOW_BELOW, // --show-below-main + + /* suppressions hackery */ + SUPPS_DIRS, /* list of suppfile dirs - feeds SUPPS_AVAIL list */ + SUPPS_AVAIL, /* fake opt: dyname list of available supp files */ + SUPPS_SEL, /* the currently selected suppression(s) */ + + /* misc */ + GEN_SUPP, // --gen-suppressions + DB_ATTACH, // --db-attach + DB_COMMAND, // --db-command + INPUT_FD, // --input-fd + MAX_SFRAME, // --max-stackframe + NUM_OPTS + }; +} + + +// ============================================================ +class Valgrind : public VkObject +{ +public: + Valgrind(); + ~Valgrind(); + +#if 0 + /* returns a list of non-default flags to pass to valgrind */ + QStringList modifiedVgFlags( const ToolObject* tool_obj ); +#endif + unsigned int maxOptId() { return VALGRIND::NUM_OPTS; } + + int checkOptArg( int optid, QString& argval ); + + VkOptionsPage* createVkOptionsPage(); + +#if 0 +public: + /* ToolObject access */ + ToolObjList toolObjList(); + int toolObjId( const QString& name ); + ToolObject* toolObj( int tid ); + ToolObject* toolObj( const QString& name ); +#endif + +private: +#if 0 + /* creates the various VkObjects and initialises their options, + ... [truncated message content] |
From: <sv...@va...> - 2010-01-08 00:46:58
|
Author: cerion Date: 2010-01-08 00:46:31 +0000 (Fri, 08 Jan 2010) New Revision: 462 Log: Sorted out the config settings some more: - Used QSettings: Creates a 'working' config, which is temporarily saved to disc (tmp_cfg, deleted upon exit) - Introduced 'projects' abstraction: A user works either within or outside of a project: - If no project is in use, any configuration changes made (via either the command line arguments or the GUI) will be used for the 'working' config, but will be discarded upon application exit. - If a project is in use (created/opened), config settings are transparently saved to that project file (no more 'saving'). - Config settings are read in in order from 3 sources, each overriding the last: 1. Global configuration file (static location per user) 2. Project configuration file 3. Command line arguments (when these are working again, anyway :-) Plus the usual: Cleaned up, fixed bugs, etc. Added: branches/valkyrie_qt4port/utils/vk_config.cpp branches/valkyrie_qt4port/utils/vk_config.h Modified: branches/valkyrie_qt4port/core/valgrind_object.cpp branches/valkyrie_qt4port/core/valgrind_object.h branches/valkyrie_qt4port/core/valkyrie_object.cpp branches/valkyrie_qt4port/core/valkyrie_object.h branches/valkyrie_qt4port/core/vk_objects.cpp branches/valkyrie_qt4port/core/vk_objects.h branches/valkyrie_qt4port/main.cpp branches/valkyrie_qt4port/mainwindow.cpp branches/valkyrie_qt4port/mainwindow.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valgrind_options_page.h branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.h branches/valkyrie_qt4port/options/vk_option.cpp branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_dialog.cpp branches/valkyrie_qt4port/options/vk_options_dialog.h branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.h branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_cb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_ck_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_le_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_sp_widget.cpp branches/valkyrie_qt4port/toolview/helgrindview.cpp branches/valkyrie_qt4port/toolview/toolview.cpp branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h branches/valkyrie_qt4port/valkyrie.pro Modified: branches/valkyrie_qt4port/core/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/core/valgrind_object.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -23,8 +23,9 @@ #include "core/valgrind_object.h" #include "options/valgrind_options_page.h" // createVkOptionsPage() -//#include "config.h" // VK_CFG_DIR, VK_SUPPS_DIR -//#include "vk_config.h" +#include "utils/vk_config.h" + +//#include "config.h" //#include "html_urls.h" //#include "memcheck_object.h" //#include "cachegrind_object.h" @@ -33,10 +34,6 @@ //#include "vk_utils.h" // vk_assert, VK_DEBUG, etc. -//TODO: from config.h -#define VK_CFG_DIR ".valkyrie" -#define VK_SUPPS_DIR "suppressions/" - //#include <ctype.h> //#include <stdlib.h> //#include <string.h> @@ -389,7 +386,7 @@ // ------------------------------------------------------------ // Can't access vkConfig->suppDir(): config created after us! - QString defSuppDir = QDir::homePath() + "/" + VK_CFG_DIR + VK_SUPPS_DIR; + QString defSuppDir = QDir::homePath() + "/" + QString(VK_CFG_GLBL_DIR) + VK_SUPPS_DIR; /* list of dirs holding suppression files */ options.addOpt( VALGRIND::SUPPS_DIRS, @@ -519,6 +516,7 @@ } + /* check argval for this option, updating if necessary. called by parseCmdArgs() and gui option pages -------------------- */ int Valgrind::checkOptArg( int optid, QString& argval ) Modified: branches/valkyrie_qt4port/core/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/core/valgrind_object.h 2010-01-08 00:46:31 UTC (rev 462) @@ -83,8 +83,8 @@ #if 0 /* returns a list of non-default flags to pass to valgrind */ QStringList modifiedVgFlags( const ToolObject* tool_obj ); - unsigned int maxOptId() { return NUM_OPTS; } #endif + unsigned int maxOptId() { return VALGRIND::NUM_OPTS; } int checkOptArg( int optid, QString& argval ); Modified: branches/valkyrie_qt4port/core/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valkyrie_object.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/core/valkyrie_object.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -20,6 +20,8 @@ #include "core/valkyrie_object.h" #include "options/valkyrie_options_page.h" // createVkOptionsPage() +#include "utils/vk_config.h" +#include "utils/vk_utils.h" // TODO: put this in a define in the build scripts,or something. @@ -204,7 +206,7 @@ '\0', "", "", - "", // TODO: BIN_EDITOR, + VK_BIN_EDITOR, "Src Editor:", "", "", // TODO: urlValkyrie::srcEditor @@ -249,7 +251,7 @@ '\0', "", "", - "", //TODO: get_VK_LOGS_DIR(), + get_VK_LOGS_DIR(), "Log Dir:", "", "", // TODO: urlValkyrie::logDir @@ -272,7 +274,22 @@ VkOPT::WDG_LEDIT ); + options.addOpt( + VALKYRIE::PROJ_FILE, + this->objectName(), + "proj-file", + 'f', + "<project.vk>", + "", + "", + "", + "use settings from project file", + "", // TODO: urlValkyrie::workingDir + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + /* path to valgrind executable (maybe found by configure) */ options.addOpt( VALKYRIE::VG_EXEC, @@ -281,7 +298,7 @@ '\0', "", "", - "", // TODO: BIN_VALGRIND, + VK_BIN_VALGRIND, "Valgrind:", "", "", // TODO: urlValkyrie::vgDir @@ -322,19 +339,38 @@ +void Valkyrie::setConfigDefaults() +{ + vkConfig->beginGroup( this->objectName() ); + OptionHash opts = options.getOptionHash(); + for ( Iter_OptionHash it = opts.begin(); it != opts.end(); ++it ) { + VkOption* opt = it.value(); + + /* Don't create config entries for these options: + They don't hold persistent data, and have no associated option widget */ + if (opt->optid == VALKYRIE::HELP ) continue; + if (opt->optid == VALKYRIE::VGHELP ) continue; + + vkConfig->setValue( opt->longFlag, opt->dfltValue ); + } + + vkConfig->endGroup(); +} + + + /*! Check \a argval for the option given by \a optid, updating if necessary. Called by parseCmdArgs() and gui option pages */ -//int Valkyrie::checkOptArg( int optid, QString& argval ) -int Valkyrie::checkOptArg( int, QString& ) +int Valkyrie::checkOptArg( int optid, QString& argval ) { - // VkOption* opt = this->options.getOption( optid ); + vk_assert( optid >= 0 && optid < VALKYRIE::NUM_OPTS ); + VkOption* opt = this->options.getOption( optid ); + #if 0 // TODO - vk_assert( optid >= 0 && optid < NUM_OPTS ); - int errval = PARSED_OK; // Option* opt = findOption( optid ); @@ -442,15 +478,13 @@ /*! Return list of all VkObjects - - TODO: const. */ -VkObjectList Valkyrie::vkObjList() +const VkObjectList Valkyrie::vkObjList() { VkObjectList vkObjList; vkObjList.append( this ); - vkObjList.append( this->valgrind() ); + vkObjList.append( valgrind() ); #if 0 // TODO ToolObjList tools = valgrind()->toolObjList(); Modified: branches/valkyrie_qt4port/core/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/core/valkyrie_object.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/core/valkyrie_object.h 2010-01-08 00:46:31 UTC (rev 462) @@ -44,6 +44,7 @@ BROWSER, DFLT_LOGDIR, WORKING_DIR, + PROJ_FILE, VG_EXEC, // path to valgrind executable BINARY, // user-binary to be valgrindised BIN_FLAGS, // flags for user-binary @@ -68,6 +69,7 @@ void stopTool( int tId ); bool queryToolDone( int tId ); #endif + unsigned int maxOptId() { return VALKYRIE::NUM_OPTS; } int checkOptArg( int optid, QString& argval ); @@ -76,8 +78,10 @@ Valgrind* valgrind() { return m_valgrind; } - /* for simplicity */ - VkObjectList vkObjList(); + virtual void setConfigDefaults(); + + // list of all objects + const VkObjectList vkObjList(); // VkObject* vkObject( int objId ); private: Modified: branches/valkyrie_qt4port/core/vk_objects.cpp =================================================================== --- branches/valkyrie_qt4port/core/vk_objects.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/core/vk_objects.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -19,16 +19,17 @@ ****************************************************************************/ #include "core/vk_objects.h" +#include "core/vk_objects.h" +#include "utils/vk_config.h" +#include "options/vk_option.h" - /***************************************************************************/ /*! Constructs a VkObject */ VkObject::VkObject( QString objName ) - // : QObject( 0, capt ) { this->setObjectName( objName ); } @@ -49,3 +50,20 @@ { return options.getOption( optid ); } + + + +void VkObject::setConfigDefaults() +{ + vkConfig->beginGroup( this->objectName() ); + + OptionHash opts = options.getOptionHash(); + for ( Iter_OptionHash it = opts.begin(); it != opts.end(); ++it ) { + VkOption* opt = it.value(); + QString config_key = opt->longFlag; + QString config_value = opt->dfltValue; + vkConfig->setValue( config_key, config_value ); + } + + vkConfig->endGroup(); +} Modified: branches/valkyrie_qt4port/core/vk_objects.h =================================================================== --- branches/valkyrie_qt4port/core/vk_objects.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/core/vk_objects.h 2010-01-08 00:46:31 UTC (rev 462) @@ -45,10 +45,16 @@ VkObject( QString objectName ); ~VkObject(); + virtual unsigned int maxOptId() = 0; + /*! check argval for this option, updating if necessary. called by parseCmdArgs() and gui option pages */ virtual int checkOptArg( int optid, QString& argval ) = 0; + + /*! Set default config entries for thies object */ + virtual void setConfigDefaults(); + virtual VkOptionsPage* createVkOptionsPage() = 0; VkOption* getOption( int optid ); @@ -56,6 +62,8 @@ protected: virtual void setupOptions() = 0; VkOptionHash options; + + }; Modified: branches/valkyrie_qt4port/main.cpp =================================================================== --- branches/valkyrie_qt4port/main.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/main.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -25,8 +25,14 @@ #include "toolview/toolview.h" #include "mainwindow.h" +#include "utils/vk_config.h" +VkConfig* vkConfig = 0; + + + + /*! Main program entry point arguments parsed, Qt setup, application setup, the ball set rolling. @@ -42,11 +48,29 @@ Valkyrie valkyrie; // ------------------------------------------------------------ - // start turning the engine over + // Start turning the engine over app = new QApplication( argc, argv ); + // ------------------------------------------------------------ - // start up the gui + // Setup application config settings + QCoreApplication::setOrganizationName("OpenWorks"); + QCoreApplication::setOrganizationDomain("openworks.co.uk"); + QCoreApplication::setApplicationName("Valkyrie"); + QString tmp_cfg = VkConfig::vkCfgMakeTempFilename(); + if ( tmp_cfg.isNull() ) { + // TODO: workout what really happens to QSettings. + cerr << "Error: no tmpfile for working config. No guarantees from here!" << endl; + } + vkConfig = new VkConfig( tmp_cfg ); + bool ok = vkConfig->initCfg( &valkyrie ); + if ( !ok ) { + // TODO: deal with this nicely. + cerr << "Error: config not initialised properly: No guarantees from here!" << endl; + } + + // ------------------------------------------------------------ + // Start up the gui vkWin = new MainWindow( &valkyrie ); vkWin->show(); vkWin->showToolView( vk::ID_MEMCHECK ); @@ -54,13 +78,15 @@ qApp->processEvents(); // ------------------------------------------------------------ - // hand over to QtApp. + // Hand over to QtApp. res = app->exec(); + // ------------------------------------------------------------ - // we're done. - if ( vkWin ) delete vkWin; - if ( app ) delete app; + // We're done - clean up and return. + if ( vkWin ) delete vkWin; + if ( vkConfig ) delete vkConfig; + if ( app ) delete app; return res; } Modified: branches/valkyrie_qt4port/mainwindow.cpp =================================================================== --- branches/valkyrie_qt4port/mainwindow.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/mainwindow.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -19,6 +19,8 @@ ****************************************************************************/ #include <QApplication> +#include <QFileDialog> +#include <QInputDialog> #include <QMenu> #include <QMenuBar> #include <QToolBar> @@ -28,6 +30,7 @@ #include "toolview/helgrindview.h" #include "options/vk_option.h" +#include "utils/vk_config.h" /***************************************************************************/ @@ -55,11 +58,11 @@ : QMainWindow(), valkyrie( vk ), optionsDialog( 0 ) { - setObjectName(QString::fromUtf8("MainWindowClass")); + setObjectName( QString::fromUtf8("MainWindowClass") ); + QString title = vkConfig->vkName; + title[0] = title[0].toUpper(); + setWindowTitle( title ); - // TODO: vkConfig->vkName() instead of Valkyrie - setWindowTitle( QApplication::translate("MainWindowClass", "Valkyrie", 0, QApplication::UnicodeUTF8) ); - // TODO: QtCoreApplication? //setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom)); @@ -83,8 +86,15 @@ */ MainWindow::~MainWindow() { - cerr << "MainWindow::~MainWindow()" << endl; - cerr << "TODO: write windows attributes to config" << endl; +// cerr << "MainWindow::~MainWindow()" << endl; + + // cleanup toolviews + delete toolViewStack; + + // Save window position to config. + vkConfig->setValue( "mainwindow/size", size() ); + vkConfig->setValue( "mainwindow/pos", pos() ); + vkConfig->sync(); } @@ -104,7 +114,7 @@ /*! Allow a tool to remove a (previously inserted) menu from the main menuBar. A tool could do this directly via 'parent', but insert can't be - done directly, so user this function for consistency. + done directly, so use this function for consistency. \sa insertToolMenuAction() */ @@ -119,9 +129,9 @@ */ void MainWindow::setupLayout() { - // TODO: size from config. - resize(500, 500); - + resize( vkConfig->value( "mainwindow/size", QSize(600, 600)).toSize()); + move( vkConfig->value( "mainwindow/pos", QPoint(400, 0)).toPoint()); + toolViewStack = new ToolViewStack( this ); setCentralWidget( toolViewStack ); } @@ -132,13 +142,23 @@ */ void MainWindow::setupActions() { - // TODO: + // TODO: shortcuts & tips // act->setShortcut( tr("Ctrl+XXX") ); // act->setStatusTip( tr("here's a tip") ); + actFile_NewProj = new QAction( this ); + actFile_NewProj->setObjectName( QString::fromUtf8("actFile_NewProj") ); + actFile_NewProj->setText( QApplication::translate("MainWindowClass", "&New Project...", 0, QApplication::UnicodeUTF8) ); + connect( actFile_NewProj, SIGNAL( triggered() ), this, SLOT( createNewProject() ) ); + + actFile_OpenProj = new QAction( this ); + actFile_OpenProj->setObjectName( QString::fromUtf8("actFile_OpenProj") ); + actFile_OpenProj->setText( QApplication::translate("MainWindowClass", "&Open Project...", 0, QApplication::UnicodeUTF8) ); + connect( actFile_OpenProj, SIGNAL( triggered() ), this, SLOT( openProject() ) ); + actFile_Close = new QAction( this ); actFile_Close->setObjectName( QString::fromUtf8("actFile_Close") ); - actFile_Close->setText( QApplication::translate("MainWindowClass", "&Close", 0, QApplication::UnicodeUTF8) ); + actFile_Close->setText( QApplication::translate("MainWindowClass", "&Close Tool", 0, QApplication::UnicodeUTF8) ); connect( actFile_Close, SIGNAL( triggered() ), this, SLOT( closeToolView() ) ); actFile_Exit = new QAction( this ); @@ -272,6 +292,8 @@ menuBar->addAction( menuTools->menuAction() ); menuBar->addAction( menuHelp->menuAction() ); + menuFile->addAction( actFile_NewProj ); + menuFile->addAction( actFile_OpenProj ); menuFile->addSeparator(); menuFile->addAction( actFile_Close ); menuFile->addAction( actFile_Exit ); @@ -422,7 +444,69 @@ } + /*! + Create a new project: + Save configuration in a project file. +*/ +void MainWindow::createNewProject() +{ + // ensure any existing project settings are saved first. + vkConfig->sync(); + + // 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; + } + + // 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... + + vkConfig->createNewProject( dir, proj_name ); +} + + +/*! + Open an existing project. +*/ +void MainWindow::openProject() +{ + // ensure any existing project settings are saved first. + vkConfig->sync(); + + QString proj_filename = QFileDialog::getOpenFileName( this, "Open Valkyrie Project", + "./", "Valkyrie Projects (*.vk)" ); + if ( proj_filename.isEmpty() || proj_filename.isNull() ) { + // Cancelled + return; + } + + vkConfig->openProject( proj_filename ); +} + + + +/*! Close the currently-shown ToolView. Calls the ToolViewStack to remove the toolview from the stack, @@ -483,25 +567,18 @@ void MainWindow::openOptions() { // TODO: decide whether really want a modeless dialog: is this functionality useful/used? - // - easier to deal with a modal dialog: plus it's clearer what settings are actually being used (saved vs. non-saved settings) - + // if non-modal, rem to reinit all opt widgets when a project is created/opened +#if 0 if (!optionsDialog) { - optionsDialog = new VkOptionsDialog(this); + optionsDialog = new VkOptionsDialog( this ); } optionsDialog->show(); optionsDialog->raise(); optionsDialog->activateWindow(); - - - // TODO: something like this... -#if 0 - QSettings *settings = new QSettings(optionsDialog->format(), - optionsDialog->scope(), - optionsDialog->organization(), - optionsDialog->application()); - setSettingsObject(settings); - fallbacksAct->setEnabled(true); +#else + VkOptionsDialog optionsDlg( this ); + optionsDlg.exec(); #endif } Modified: branches/valkyrie_qt4port/mainwindow.h =================================================================== --- branches/valkyrie_qt4port/mainwindow.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/mainwindow.h 2010-01-08 00:46:31 UTC (rev 462) @@ -61,6 +61,8 @@ private slots: void toolGroupTriggered( QAction* ); + void createNewProject(); + void openProject(); void closeToolView(); void openOptions(); void runTool(); @@ -76,6 +78,8 @@ QLabel* statusLabel; private: + QAction* actFile_NewProj; + QAction* actFile_OpenProj; QAction* actFile_Exit; QAction* actFile_Close; QAction* actEdit_Options; Modified: branches/valkyrie_qt4port/options/valgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -22,7 +22,7 @@ #include <QListWidget> #include <QTabWidget> -//#include "vk_config.h" +#include "utils/vk_config.h" //#include "vk_messages.h" #include "utils/vk_utils.h" //#include "context_help.h" @@ -296,7 +296,7 @@ { /* if usr gave suppfile on cmdline (updating lbSel) - update suppDirs, suppsAvail from each path in lbSel */ - QChar sep = vkConfig->sepChar(); + QChar sep = vkConfig->vkSepChar; LbWidget* lbSel = (LbWidget*)m_itemList[Valgrind::SUPPS_SEL ]; QStringList currSupps = QStringList::split( sep, lbSel->currValue() ); LbWidget* lbDirs = (LbWidget*)m_itemList[Valgrind::SUPPS_DIRS]; @@ -316,12 +316,13 @@ /* init suppsAvail */ suppDirsChanged(); } +#endif - /* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ void ValgrindOptionsPage::applyOption( int optId ) { - vk_assert( optId >= 0 && optId < Valgrind::NUM_OPTS ); +#if 0 + vk_assert( optId >= 0 && optId < Valgrind::NUM_OPTS ); // QString argval = m_itemList[optId]->currValue(); @@ -330,8 +331,8 @@ default: break; } -} #endif +} void ValgrindOptionsPage::getDbBin() @@ -348,12 +349,10 @@ { m_allAvailSuppFiles = QStringList(); LbWidget* lbDirs = (LbWidget*)m_itemList[VALGRIND::SUPPS_DIRS]; -//TODO -// QChar m_sep = vkConfig->sepChar(); - QChar m_sep = ':'; + QChar sep = vkConfig->vkSepChar; /* Get list of dirs from "valgrind::supps-dirs" */ - QStringList suppDirs = lbDirs->currValue().split( m_sep ); + QStringList suppDirs = lbDirs->currValue().split( sep ); for ( int i=0; i<suppDirs.count(); i++ ) { /* for each suppDir, find all supp files */ @@ -375,13 +374,11 @@ */ void ValgrindOptionsPage::updateSuppsAvail() { -//TODO -// QChar m_sep = vkConfig->sepChar(); -QChar m_sep = ':'; + QChar sep = vkConfig->vkSepChar; LbWidget* lbAvail = (LbWidget*)m_itemList[VALGRIND::SUPPS_AVAIL]; LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL ]; QStringList suppsAvail = m_allAvailSuppFiles; - QStringList currSupps = lbSel->currValue().split( m_sep ); + QStringList currSupps = lbSel->currValue().split( sep ); for ( int i=0; i<currSupps.count(); i++ ) { int idx = suppsAvail.indexOf( currSupps[i] ); @@ -390,7 +387,7 @@ } } - lbAvail->setCurrValue( suppsAvail.join( m_sep ) ); + lbAvail->setCurrValue( suppsAvail.join( sep ) ); } @@ -404,8 +401,7 @@ if (((QListWidget*)lbSel->widget())->count() < VG_CLO_MAX_SFILES) { lbSel->insertItem(suppr); } else { -//TODO - cerr << "FIXME: Valgrind won't accept more than %d suppression files" << endl; +cerr << "TODO: vkError: Valgrind won't accept more than VG_CLO_MAX_SFILES suppression files" << endl; #if 0 /* valgrind doesn't accept any more suppression files */ vkError( this, "Error", Modified: branches/valkyrie_qt4port/options/valgrind_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/valgrind_options_page.h 2010-01-08 00:46:31 UTC (rev 462) @@ -34,8 +34,8 @@ public: ValgrindOptionsPage( VkObject* obj ); + void applyOption( int optId ); #if 0 - void applyOption( int optId ); void init(); #endif Modified: branches/valkyrie_qt4port/options/valkyrie_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -23,10 +23,12 @@ #include <QLabel> #include "utils/vk_utils.h" +#include "utils/vk_config.h" +#include "options/widgets/opt_ck_widget.h" + #if 0 #include "vk_objects.h" -#include "vk_config.h" #include "main_window.h" #include "vk_messages.h" #include "context_help.h" @@ -126,9 +128,7 @@ fontGenLedit->setReadOnly( true ); // don't allow direct editing // start up in correct state -//TODO -// bool use_sys_font = vkConfig->rdBool("font-gen-sys", "valkyrie"); - bool use_sys_font = true; + bool use_sys_font = vkConfig->value( "valkyrie/font-gen-sys" ).toBool(); fontGenLedit->setDisabled( use_sys_font ); connect( fontGenSysLedit, SIGNAL(changed(bool)), fontGenLedit, SLOT(setDisabled(bool)) ); @@ -194,17 +194,22 @@ /* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ -void ValkyrieOptionsPage::applyOption( int ) //optId ) +void ValkyrieOptionsPage::applyOption( int optId ) { -#if 0 // TODO - vk_assert( optId >= 0 && optId < VALKYRIE::NUM_OPTS ); + std::cerr << "vk-applyOption(): 0 (" << optId << ")" << std::endl; + + vk_assert( optId >= 0 && optId < VALKYRIE::NUM_OPTS ); + OptionWidget* optWidg = m_itemList[optId]; vk_assert( optWidg != 0 ); QString argval = optWidg->currValue(); - /* apply option */ + std::cerr << "applyOption(): 1" << std::endl; + + /* apply option */ switch ( optId ) { +#if 0 case VALKYRIE::TOOLTIP: { MainWindow* vkWin = (MainWindow*)qApp->mainWidget(); vkWin->toggleToolTips(); @@ -262,17 +267,19 @@ } } } break; +#endif default: break; } -#endif } + /* called by pbFont: conjures up a QFontDialog */ void ValkyrieOptionsPage::chooseGenFont() { + cerr << "TODO: ValkyrieOptionsPage::chooseGenFont()" << endl; #if 0 // TODO LeWidget* fontLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_USR]); @@ -292,6 +299,7 @@ /* called by pbFont: conjures up a QFontDialog */ void ValkyrieOptionsPage::chooseToolFont() { + cerr << "TODO: ValkyrieOptionsPage::chooseToolFont()" << endl; #if 0 // TODO LeWidget* fontLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_TOOL_USR]); @@ -308,6 +316,7 @@ void ValkyrieOptionsPage::getEditor() { + cerr << "TODO: ValkyrieOptionsPage::getEditor()" << endl; #if 0 // TODO /* try and start up somewhere sensible */ QString ed = m_itemList[VALKYRIE::SRC_EDITOR]->currValue(); @@ -339,6 +348,7 @@ /* allows user to select executable-to-debug */ void ValkyrieOptionsPage::getBinary() { + cerr << "TODO: ValkyrieOptionsPage::getBinary()" << endl; #if 0 // TODO QString binfile = QFileDialog::getOpenFileName( QString::null, "All Files (*)", @@ -354,6 +364,7 @@ /* allows user to select default browser */ void ValkyrieOptionsPage::getBrowser() { + cerr << "TODO: ValkyrieOptionsPage::getBrowser()" << endl; #if 0 // TODO QString brwsr = QFileDialog::getOpenFileName( QString::null, "All Files (*)", @@ -370,6 +381,7 @@ of this fn are essentially the same as the one in config.tests/valgrind.test */ void ValkyrieOptionsPage::getVgExec() { + cerr << "TODO: ValkyrieOptionsPage::getVgExec()" << endl; #if 0 // TODO QString vg_exec_path = QFileDialog::getOpenFileName( QString::null, "All Files (*)", @@ -385,6 +397,7 @@ /* RM: allows user to specify which default log dir to use */ void ValkyrieOptionsPage::getDfltLogDir() { + cerr << "TODO: ValkyrieOptionsPage::getDfltLogDir()" << endl; #if 0 // TODO QString currdir = m_itemList[VALKYRIE::DFLT_LOGDIR]->currValue(); QString dir_logsave = @@ -401,6 +414,7 @@ /* RM: allows user to specify which default log dir to use */ void ValkyrieOptionsPage::getWorkingDir() { + cerr << "TODO: ValkyrieOptionsPage::getWorkingDir()" << endl; #if 0 // TODO QString currdir = m_itemList[VALKYRIE::WORKING_DIR]->currValue(); QString dir_working = Modified: branches/valkyrie_qt4port/options/valkyrie_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/valkyrie_options_page.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/valkyrie_options_page.h 2010-01-08 00:46:31 UTC (rev 462) @@ -35,6 +35,9 @@ void applyOption( int optId ); + bool saveToProjectCfg(); + + private slots: void chooseGenFont(); void chooseToolFont(); Modified: branches/valkyrie_qt4port/options/vk_option.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_option.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/vk_option.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -100,7 +100,7 @@ */ VkOption* VkOptionHash::getOption( int optid ) { - // TODO: check for non-existant options + // TODO: check for non-existent options return optionHash.value( optid ); } Modified: branches/valkyrie_qt4port/options/vk_option.h =================================================================== --- branches/valkyrie_qt4port/options/vk_option.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/vk_option.h 2010-01-08 00:46:31 UTC (rev 462) @@ -25,15 +25,7 @@ #include <QStringList> -// TODO: remove once done with cerr's etc. -#include <iostream> -using namespace std; - -// TODO: perhaps better to replace this class with QSetting? -// TODO: const everywhere where possible. - - // ============================================================ class VkOption; @@ -126,6 +118,9 @@ VkOption* getOption( int optid ); + OptionHash& getOptionHash() { return optionHash; } + + void addOpt( int optid, QString cfg_group, QString long_flag, @@ -170,13 +165,16 @@ QString longFlag; // eg. --leak-resolution QChar shortFlag; // eg. --l QString flagDescr; // eg. <file> + QStringList possValues; // eg. low | med | high + QString dfltValue; // eg. [low] QString shortHelp; // txt for OptionsWindow QString longHelp; // txt for help --> stdout QString urlAddress; // context help url - QString dfltValue; // eg. [low] - QStringList possValues; // eg. low | med | high VkOPT::ArgType argType; // eg. ARG_UINT VkOPT::WidgType widgType; // eg. VkOPTION::WDG_LEDIT + + // configuration settings key: + QString configKey() { return configGrp + "/" + longFlag; } }; #endif // __VK_OPTION_H Modified: branches/valkyrie_qt4port/options/vk_options_dialog.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_dialog.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/vk_options_dialog.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -23,12 +23,14 @@ #include <QLabel> #include <QPushButton> +#include "utils/vk_config.h" +#include "utils/vk_utils.h" + #if 0 #include "html_urls.h" #include "context_help.h" #include "vk_utils.h" #include "vk_objects.h" -#include "vk_config.h" #include "main_window.h" #include "vk_messages.h" #endif @@ -55,26 +57,18 @@ // ------------------------------------------------------------ // basic dialog setup setObjectName(QString::fromUtf8("VkOptionsDialog[*]")); // Note: "[*]" placeholder for 'windowModified' -// TODO: get values from config - setWindowTitle( QApplication::translate("VkOptionsDialog", "Valkyrie Options Dialog", 0, QApplication::UnicodeUTF8) ); - + setWindowTitle( "Valkyrie Options Dialog" ); setupLayout(); // ------------------------------------------------------------ // setup default state // TODO: find out more how Qt4 does this stuff. // they have a '*' for the window title, too, to indicate changes... -// REM: vkConfig->isDirty() -/* - QPushButton* restoreButton = optionsButtonBox->button( QDialogButtonBox::RestoreDefaults ); + QPushButton* applyButton = optionsButtonBox->button( QDialogButtonBox::Apply ); QPushButton* cancelButton = optionsButtonBox->button( QDialogButtonBox::Cancel ); - QPushButton* okButton = optionsButtonBox->button( QDialogButtonBox::Ok ); - restoreButton->setEnabled( true ); - applyButton->setEnabled( false ); // nothing to apply yet - cancelButton->setEnabled( true ); - okButton->setEnabled( false ); -*/ + applyButton->setEnabled( false ); + cancelButton->setEnabled( false ); // ------------------------------------------------------------ // Add categories, and the default page (other pages loaded on demand) @@ -85,20 +79,11 @@ // Pass 'this' so constructor widgets auto-size correctly. VkObject* obj = objList.at(i); VkOptionsPage* page = obj->createVkOptionsPage(); + vk_assert( page != 0 ); + connect( page, SIGNAL(modified()), this, SLOT(pageModified()) ); + // handle e.g. user pressing return in an ledit + connect( page, SIGNAL(apply()), this, SLOT(apply()) ); -//TODO -// vk_assert( page != 0 ); -// connect( page, SIGNAL(modified()), this, SLOT(modified()) ); -// /* handle e.g. user pressing return in an ledit */ -// connect( page, SIGNAL(apply()), this, SLOT(apply()) ); - - if ( page == 0 ) { - // TODO: on-screen error? -// VK_DEBUG("cit->text = %s", cit->text().latin1() ); - cerr << "*** page == 0" << endl; - return; - } - // Set list item entry QListWidgetItem *item = new QListWidgetItem( contentsListWidget ); QString itemName = obj->objectName(); @@ -131,30 +116,21 @@ { // ------------------------------------------------------------ // top layout - vLayout = new QVBoxLayout( this ); + QVBoxLayout* vLayout = new QVBoxLayout( this ); vLayout->setObjectName(QString::fromUtf8("vlayout")); // ------------------------------------------------------------ // parent widget for the contents + pages - hLayoutWidget = new QWidget( this ); + QWidget* hLayoutWidget = new QWidget( this ); + hLayoutWidget->setObjectName(QString::fromUtf8("hLayoutWidget")); vLayout->addWidget( hLayoutWidget ); // ------------------------------------------------------------ - // The button box - optionsButtonBox = new QDialogButtonBox( this ); - optionsButtonBox->setObjectName(QString::fromUtf8("optionsButtonBox")); - optionsButtonBox->setOrientation(Qt::Horizontal); - optionsButtonBox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults); - vLayout->addWidget( optionsButtonBox ); - - - // ------------------------------------------------------------ // contents + pages layout - hLayout = new QHBoxLayout( hLayoutWidget ); + QHBoxLayout* hLayout = new QHBoxLayout( hLayoutWidget ); hLayout->setObjectName(QString::fromUtf8("hLayout")); hLayout->setContentsMargins( 0, 0, 0, 0 ); - // ------------------------------------------------------------ // The contents list // Note: give this its maximum width once filled with items @@ -164,6 +140,7 @@ contentsListWidget->setSortingEnabled(false); QSizePolicy sizePolicyContents(QSizePolicy::Maximum, QSizePolicy::Expanding); contentsListWidget->setSizePolicy( sizePolicyContents ); + contentsListWidget->setSelectionMode( QAbstractItemView::SingleSelection ); hLayout->addWidget( contentsListWidget ); optionPages = new QStackedWidget( hLayoutWidget ); @@ -173,274 +150,147 @@ hLayout->addWidget( optionPages ); + // ------------------------------------------------------------ + // parent widget for the buttons + QWidget* hButtonWidget = new QWidget( this ); + hButtonWidget->setObjectName(QString::fromUtf8("hButtonWidget")); + vLayout->addWidget( hButtonWidget ); // ------------------------------------------------------------ - // signals / slots - QPushButton* restoreButton = optionsButtonBox->button( QDialogButtonBox::RestoreDefaults ); - QPushButton* applyButton = optionsButtonBox->button( QDialogButtonBox::Apply ); - connect(restoreButton, SIGNAL(released()), this, SLOT(restoreDefaults())); - connect(applyButton, SIGNAL(released()), this, SLOT(apply())); - connect(optionsButtonBox, SIGNAL(rejected()), this, SLOT(reject())); - connect(optionsButtonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(contentsListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - this, SLOT(showPage(QListWidgetItem*,QListWidgetItem*))); -} + // options button box + QHBoxLayout* hLayoutButtons = new QHBoxLayout( hButtonWidget ); + hLayoutButtons->setObjectName(QString::fromUtf8("hLayoutButtons")); + saveGlblButton = new QPushButton( QPixmap( ":/vk_icons/icons/tb_mainwin_filesave2.xpm" ), + "Save To Global Config" ); + hLayoutButtons->addWidget( saveGlblButton ); + hLayoutButtons->addStretch( 1 ); -#if 0 // TODO -void VkOptionsDialog::addCategory( VkObject* obj ) -{ - /* to look up object later to call obj->createVkOptionsPage() */ - int catId = obj->objId(); - VkOptionsPage* page = NULL; + optionsButtonBox = new QDialogButtonBox( hButtonWidget ); + optionsButtonBox->setObjectName(QString::fromUtf8("optionsButtonBox")); + optionsButtonBox->setOrientation(Qt::Horizontal); + optionsButtonBox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok); + hLayoutButtons->addWidget( optionsButtonBox ); - wStack->addWidget( page, catid ); - new CategItem( categories, page, obj->title(), catid ); -} -#endif + // ------------------------------------------------------------ + // signals / slots + connect(contentsListWidget, SIGNAL(itemClicked(QListWidgetItem*)), + this, SLOT(showPage(QListWidgetItem*))); + QPushButton* applyButton = optionsButtonBox->button( QDialogButtonBox::Apply ); + connect(applyButton, SIGNAL(released()), this, SLOT(apply())); // Apply + connect(optionsButtonBox, SIGNAL(rejected()), this, SLOT(reject())); // Cancel + connect(optionsButtonBox, SIGNAL(accepted()), this, SLOT(accept())); // Ok + connect(saveGlblButton, SIGNAL(released()), this, SLOT(saveToGlobalConfig())); +} -/* we make the widgets on demand here */ -void VkOptionsDialog::showPage( QListWidgetItem* currItem, - QListWidgetItem* prevItem ) +/*! + Show the chosen options page +*/ +void VkOptionsDialog::showPage( QListWidgetItem* nextItem ) { - int nextIdx = contentsListWidget->row( currItem ); - int prevIdx = contentsListWidget->row( prevItem ); + int nextIdx = contentsListWidget->row( nextItem ); - std::cerr << "showPage( " << prevIdx << " -> " << nextIdx << " )" << std::endl; +// std::cerr << "showPage( " << nextIdx << " )" << std::endl; -// TODO: check last page edits saved/rejected -// optionPages->currentWidget(); +// TODO: check no uncommited edits in last page +// proper way to do this is subclass contentsListWidget to catch click events... - // all well => change to next page +//TODO? setWindowTitle( capt + item->text() ); optionPages->setCurrentIndex( nextIdx ); - - -#if 0 // TODO - if ( item ) { - CategItem* cit = (CategItem*)item; - - /* check no uncommited edits in last page */ - VkOptionsPage* last_page = (VkOptionsPage*)wStack->visibleWidget(); - - if (last_page != 0 && /* moving from previous */ - last_page != cit->page()) { /* prev not same as next */ - /* first pull back to the right item selection */ - categories->setSelected( last_page->optId(), true ); - - if (applyButton->isEnabled()) { - /* choose to apply/reset edits */ - CategItem* last_cit = (CategItem*)categories->item( last_page->optId()); - int ok = vkQuery( this, "Apply/Reset Edits", - "&Apply;&Reset;&Cancel", - "<p>There are non-committed edits in option page %s.<br/>" - "Would you like to Apply or Reset these edits?</p>", - last_cit->text().latin1() ); - switch ( ok ) { - case MsgBox::vkYes: apply(); break; - case MsgBox::vkNo: reject(); break; - case MsgBox::vkCancel: return; /* jump back to last page */ - default: - vk_assert_never_reached(); - } - } - } - - setCaption( capt + item->text() ); - - /* first time this item has been selected */ - if ( cit->page() == 0 ) { - VkOptionsPage* page = mkVkOptionsPage( cit->catId() ); - if ( page == 0 ) { - VK_DEBUG("cit->text = %s", cit->text().latin1() ); - return; - } - cit->setWidget( page ); - wStack->addWidget( page, cit->catId() ); - } - - /* make sure the item seletion is sync'd */ - categories->setSelected( cit->catId(), true ); - wStack->raiseWidget( cit->page() ); - cit->page()->init(); - } -#endif } -#if 0 // TODO -VkOptionsPage* VkOptionsDialog::mkVkOptionsPage( int catid ) -{ - VkObject* obj = ((MainWindow*)parent())->valkyrie()->vkObject( catid ); - VkOptionsPage* page = obj->createVkOptionsPage( this ); - vk_assert( page != 0 ); - - optPages.append( page ); - connect( page, SIGNAL(modified()), this, SLOT(modified()) ); - - /* handle e.g. user pressing return in an ledit */ - connect( page, SIGNAL(apply()), this, SLOT(apply()) ); - - return page; -} - - -void VkOptionsDialog::showPage( int catid ) -{ - if ( isMinimized() ) { - setCategory( catid ); - showNormal(); - return; - } - - /* been there, done that ... */ - if ( xpos != -1 && ypos != -1 ) { - setCategory( catid ); - show(); - return; - } - - /* first time we've been shown */ - if ( !isVisible() ) { -// adjustSize(); - setCategory( catid ); - show(); - } -} - - -/* save edits to disk - - applies current page edits - - saves all changes to disk. - - Need a 'save' because we're not auto-saving 'applied' edits. - 'Apply' just means check edits and update Valkyrie. - 'Save' means save changes to disk for next startup. - This is because Vk accepts cmdline values... if started with option - values xyz, don't necessarily want those saved to disk for next run. - This needs some clear thinking... -*/ -void VkOptionsDialog::save() -{ - if (!apply()) - return; - - /* save opts to disk... */ - if ( vkConfig->isDirty() ) - vkConfig->sync( ((MainWindow*)parent())->valkyrie() ); - - saveButton->setEnabled( vkConfig->isDirty() ); -} - -#endif - - - /* reject edits - only current page can be in an edited state. - don't emit flagsChanged - only 'changed' once they're 'applied'. */ void VkOptionsDialog::reject() { - std::cerr << "reject()" << std::endl; - QDialog::reject(); +// std::cerr << "VkOptionsDialog::reject()" << std::endl; -#if 0 // TODO - VkOptionsPage* page = (VkOptionsPage*)wStack->visibleWidget(); + VkOptionsPage* page = (VkOptionsPage*)optionPages->currentWidget(); vk_assert( page ); if ( !page->rejectEdits() ) { VK_DEBUG("Failed to reject edits"); } -#endif + + QDialog::reject(); } -// TODO: really want this? -// - because now non-modal dlg, only conceivable use is -// to make look'n'feel changes directly visible... + /*! Apply edits - - only current page can be in an edited state. + The 'apply' button is important for look and feel options to be tried out + Only current page can be in an edited state. */ -void VkOptionsDialog::apply() +bool VkOptionsDialog::apply() { - std::cerr << "apply()" << std::endl; +// std::cerr << "VkOptionsDialog::apply()" << std::endl; -#if 0 // TODO - VkOptionsPage* page = (VkOptionsPage*)wStack->visibleWidget(); + VkOptionsPage* page = (VkOptionsPage*)optionPages->currentWidget(); vk_assert( page ); if ( !page->applyEdits() ) { VK_DEBUG("Failed to apply edits"); return false; } - /* let the toolviews know that the flags (may) have changed */ + // ensure changes saved to disc + vkConfig->sync(); + + // let the toolviews know that the flags (may) have changed emit flagsChanged(); return true; -#endif } -/* apply edits and quit if no problems */ + +/*! + apply edits and quit if no problems + - save the settings to the Project cfg file if specified +*/ void VkOptionsDialog::accept() { -#if 0 // TODO - if ( apply() ) - close(); -#endif +// std::cerr << "VkOptionsDialog::apply()" << std::endl; - std::cerr << "accept()" << std::endl; - - // TODO: save() - - QDialog::accept(); + if ( apply() ) { + QDialog::accept(); + } + // Else, we have a problem. + // Best to let the user know changes didn't get committed, and let them cancel. } -void VkOptionsDialog::restoreDefaults() -{ - std::cerr << "restoreDefaults" << std::endl; -} - - - -#if 0 // TODO -/* reset to installation defaults - - only reset current page +/*! + save applied edits to global config file + - only enabled when no edits outstanding, to prevent any confusion. */ -void VkOptionsDialog::resetDefaults() +void VkOptionsDialog::saveToGlobalConfig() { - VkOptionsPage* page = (VkOptionsPage*)wStack->visibleWidget(); - vk_assert( page ); - page->resetDefaults(); + vkConfig->saveToGlblConfigFile(); } -void VkOptionsDialog::moveEvent( QMoveEvent* me ) -{ - xpos = me->pos().x(); - ypos = me->pos().y(); -} -void VkOptionsDialog::closeEvent( QCloseEvent * ) -{ hide(); } - - -/* slot called by page->modified() signal - - only current page can have been modified. +/*! + Enable/disable buttons. + This slot is called by page->modified() signal + - only current page can have been modified. */ -void VkOptionsDialog::modified() +void VkOptionsDialog::pageModified() { - bool edited = false; - VkOptionsPage* page = (VkOptionsPage*)wStack->visibleWidget(); + VkOptionsPage* page = (VkOptionsPage*)optionPages->currentWidget(); vk_assert( page ); - edited = page->isModified(); + bool modified = page->isModified(); - applyButton->setEnabled( edited ); - resetButton->setEnabled( edited ); - saveButton->setEnabled( edited || vkConfig->isDirty() ); + QPushButton* applyButton = optionsButtonBox->button( QDialogButtonBox::Apply ); + QPushButton* cancelButton = optionsButtonBox->button( QDialogButtonBox::Cancel ); + applyButton->setEnabled( modified ); + cancelButton->setEnabled( modified ); + // enable save only when no edits + saveGlblButton->setEnabled( !modified ); } -#endif Modified: branches/valkyrie_qt4port/options/vk_options_dialog.h =================================================================== --- branches/valkyrie_qt4port/options/vk_options_dialog.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/vk_options_dialog.h 2010-01-08 00:46:31 UTC (rev 462) @@ -24,55 +24,38 @@ #include <QDialog> #include <QDialogButtonBox> -#include <QFrame> -#include <QHBoxLayout> #include <QListWidget> #include <QStackedWidget> #include <QWidget> // ============================================================ -class VkObject; -class VkOptionsPage; - - -// ============================================================ class VkOptionsDialog : public QDialog { Q_OBJECT public: - VkOptionsDialog( QWidget* parent=0 ); + VkOptionsDialog( QWidget* ); ~VkOptionsDialog(); private: void setupLayout(); private slots: - void restoreDefaults(); - void apply(); + bool apply(); void accept(); void reject(); - void showPage( QListWidgetItem* prev, QListWidgetItem* curr ); -// TODO -// void pageModified(); + void showPage( QListWidgetItem* ); + void pageModified(); + void saveToGlobalConfig(); -private: - void addPage( VkObject* obj ); - VkOptionsPage* createPage(); -// TODO -// void save(); +signals: + void flagsChanged(); -// TODO -//signals: void flagsChanged(); - private: - QVBoxLayout* vLayout; - QWidget* hLayoutWidget; - QHBoxLayout* hLayout; QListWidget* contentsListWidget; - QFrame* pagesFrame; QStackedWidget* optionPages; QDialogButtonBox* optionsButtonBox; + QPushButton* saveGlblButton; }; Modified: branches/valkyrie_qt4port/options/vk_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/vk_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/vk_options_page.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -20,6 +20,8 @@ ** ****************************************************************************/ +#include "utils/vk_utils.h" + #if 0 #include "vk_utils.h" #include "vk_config.h" @@ -34,8 +36,11 @@ #include "options/widgets/opt_lb_widget.h" #include "options/widgets/opt_le_widget.h" #include "options/widgets/opt_sp_widget.h" +#include "utils/vk_config.h" +#include <QList> + /***************************************************************************/ /*! Constructs an Categories @@ -45,8 +50,7 @@ { this->setObjectName( obj->objectName() + "OptPage" ); -//TODO -// m_mod = false; + m_mod = false; lineHeight = fontMetrics().height(); pageTopVLayout = new QVBoxLayout( this ); @@ -60,11 +64,14 @@ */ VkOptionsPage::~VkOptionsPage() { -#if 0// TODO m_editList.clear(); - m_itemList.setAutoDelete( true ); + + // cleanup all option widgets + foreach ( OptionWidget* optw, m_itemList) { + delete optw; + optw = 0; + } m_itemList.clear(); -#endif } @@ -86,61 +93,41 @@ } -#if 0 // TODO -void VkOptionsPage::resetDefaults() -{ - int ok = vkQuery( this, 2, "Reset Defaults", - "<p>This will reset <b>all</b> options for the " - "option page %s to the installation defaults.<br/>" - "(Other option pages will be unaffected).</p>" - "<p>Continue ?</p>", m_vkObj->title().latin1() ); - if ( ok == MsgBox::vkYes ) { - QIntDictIterator<OptionWidget> it( m_itemList ); - for ( ; it.current(); ++it ) { - it.current()->resetDefault(); - } - } -} -#endif - +/*! + updateEditList + Only here is m_editList managed. +*/ void VkOptionsPage::updateEditList( bool edstate, OptionWidget* optw ) { -edstate = edstate; optw = optw; -#if 0 // TODO - /* check this widget isn't already in the list */ - int indx = m_editList.findRef( optw ); + // check this widget isn't already in the list + int indx = m_editList.indexOf( optw ); - /* widget has been edited and is not already in the list */ + // widget has been edited and is not already in the list if ( edstate == true && indx == -1 ) { m_editList.append( optw ); } else if ( edstate == false && indx != -1 ) { - /* widget was reset and is already in the list */ - m_editList.remove( indx ); + // widget was reset and is already in the list + m_editList.removeAt( indx ); } m_mod = m_editList.isEmpty() ? false : true; emit modified(); -#endif } -#if 0 // TODO /* reset button clicked */ bool VkOptionsPage::rejectEdits() { if ( m_editList.count() != 0 ) { - OptionWidget* optw; - QPtrList<OptionWidget> tmpList; + // first copy the list: the list is managed by this->updateEditList(). + QList<OptionWidget*> tmpList = m_editList; - for ( optw=m_editList.first(); optw; optw=m_editList.next() ) { - tmpList.append( optw ); + // now remove all the items from m_editList: + // signal is emitted for by each optw, calls this->updateEditList() + for (int i = 0; i < tmpList.size(); ++i) { + tmpList.at(i)->cancelEdit(); } - /* now remove all the items from m_editList: signal is emitted */ - for ( optw=tmpList.first(); optw; optw=tmpList.next() ) { - optw->cancelEdit(); - } - tmpList.clear(); } vk_assert( m_mod == false ); @@ -150,34 +137,47 @@ } -/* called from OptionsWindow::apply(), accept() */ +/*! + applyEdits() + Called from OptionsWindow::apply(), accept() +*/ bool VkOptionsPage::applyEdits() { - if ( m_editList.isEmpty() && m_mod == false ) +// std::cerr << "applyEDITS()" << std::endl; + + if ( m_editList.isEmpty() && m_mod == false ) return true; - /* user clicked Ok/Apply after editing some items */ + std::cerr << "applyEDITS(): 2" << std::endl; + + // user clicked Ok/Apply after editing some items + + // verify entries before committing them OptionWidget* optw; - QPtrList<OptionWidget> tmpList; + for (int i = 0; i < m_editList.size(); ++i) { + optw = m_editList.at(i); + if ( !checkOption( optw->id() ) ) { + return false; + } + std::cerr << "applyEDITS(): 3 (" << i << ")" << std::endl; - /* verify entries before committing them */ - for ( optw=m_editList.first(); optw; optw=m_editList.next() ) { - if ( !checkOption( optw->id() ) ) - return false; - /* update any Valkyrie state dependent on this option */ + // update any Valkyrie state dependent on this option applyOption( optw->id() ); } - - /* if we got to here, then we passed all checks */ - for ( optw=m_editList.first(); optw; optw=m_editList.next() ) { - /* no signal emitted: optw is still in m_editList */ + std::cerr << "applyEDITS(): 4" << std::endl; + + // if we got to here, then we passed all checks -> save the edits + QList<OptionWidget*> tmpList; + for (int i = 0; i < m_editList.size(); ++i) { + optw = m_editList.at(i); + // no signal emitted: optw is still in m_editList optw->saveEdit(); tmpList.append( optw ); } - /* now remove all the saved items from m_editList */ - for ( optw=tmpList.first(); optw; optw=tmpList.next() ) - updateEditList( false, optw ); - tmpList.clear(); + // now remove all the saved items from m_editList + for (int i = 0; i < tmpList.size(); ++i) { + updateEditList( false, tmpList.at(i) ); + } vk_assert( m_mod == false ); vk_assert( m_editList.isEmpty() == true ); @@ -185,33 +185,38 @@ } -/* check valid option via VkObject - argval may be altered by checks, so return it */ +/*! + checkOption() + Check valid option via VkObject +*/ bool VkOptionsPage::checkOption( unsigned int optId ) { vk_assert( optId < m_vkObj->maxOptId() ); QString argval = m_itemList[optId]->currValue(); - /* argval may be altered by checkOptArg() */ + // Note: argval may be altered by checkOptArg() int errval = m_vkObj->checkOptArg( optId, argval ); if ( errval != PARSED_OK ) { +cerr << "TODO: vkError: Invalid Entry: " << errval << endl; +#if 0 // TODO vkError( this, "Invalid Entry", "%s:\n\"%s\"", parseErrString(errval), m_itemList[optId]->currValue().latin1() ); +#endif m_itemList[optId]->cancelEdit(); return false; } - /* argval may have been altered by checkOptArg(), e.g. a file path - - only applies to line-edit widgets. */ + // argval may have been altered by checkOptArg(), e.g. a file path + // - only applies to line-edit widgets. if ( argval != m_itemList[optId]->currValue() ) { - if ( m_itemList[optId]->isA("LeWidget") ) + if ( m_itemList[optId]->inherits( "LeWidget" ) ) ((LeWidget*)m_itemList[optId])->setCurrValue( argval ); } return true; } -#endif + OptionWidget* VkOptionsPage::insertOptionWidget( int optid, QWidget* parent, bool mklabel ) @@ -221,8 +226,7 @@ switch ( opt->widgType ) { case VkOPT::WDG_NONE: - // TODO -// vk_assert_never_reached(); + vk_assert_never_reached(); break; case VkOPT::WDG_CHECK: optWidget = (OptionWidget*)new CkWidget( parent, opt, mklabel ); @@ -244,15 +248,21 @@ case VkOPT::WDG_SPINBOX: { SpWidget* spinw = new SpWidget( parent, opt, mklabel, 1 ); + bool ok; int step = (opt->argType == VkOPT::ARG_PWR2) ? 0 : 1; -// TODO -// QString ival = vkConfig->rdEntry( opt->cfgKey(), opt->cfgGroup() ); - QString ival = "1"; + QString val = vkConfig->value( opt->configKey() ).toString(); + int ival = val.toInt(&ok); + if ( !ok ) { + cerr << "Error in VkOptionsPage::insertOptionWidget( " << optid << " ): " << + "VkOPT::WDG_SPINBOX: bad int conversion from: '" << val.toLatin1().data() << "'" << endl; + // soldier on... + ival = 0; + } spinw->addSection( opt->possValues[0].toInt(), // min opt->possValues[1].toInt(), // max - ival.toInt(), // def - step ); // step (if 0: pwr2) + ival, // default + step ); // step (if 0: pwr2) optWidget = (OptionWidget*)spinw; } Modified: branches/valkyrie_qt4port/options/vk_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/vk_options_page.h 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/vk_options_page.h 2010-01-08 00:46:31 UTC (rev 462) @@ -62,13 +62,12 @@ VkOptionsPage( VkObject* obj ); ~VkOptionsPage(); -#if 0 // TODO bool rejectEdits(); bool applyEdits(); bool isModified() { return m_mod; } - void resetDefaults(); - /* init page on open */ +#if 0 // TODO + // init page on open virtual void init() { /*do nothing*/ } int optId(); @@ -87,14 +86,13 @@ OptionWidget* insertOptionWidget( int optid, QWidget* parent, bool mklabel ); QFrame* sep( QWidget* parent ); -#if 0 // TODO bool checkOption( unsigned int optId ); - /* apply option: update Valkyrie state dependent on this option */ + + // apply option: update Valkyrie state dependent on this option virtual void applyOption( int id ) = 0; -#endif protected: -// bool m_mod; + bool m_mod; int lineHeight; QVBoxLayout *pageTopVLayout; Modified: branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp =================================================================== --- branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp 2009-12-19 23:12:34 UTC (rev 461) +++ branches/valkyrie_qt4port/options/widgets/opt_base_widget.cpp 2010-01-08 00:46:31 UTC (rev 462) @@ -20,10 +20,10 @@ #include "options/widgets/opt_base_widget.h" #include "options/vk_option.h" // for listbox fileCheck() +#include "utils/vk_config.h" #if 0 #include "vk_utils.h" -#include "vk_config.h" #include "v... [truncated message content] |
From: <sv...@va...> - 2009-12-19 23:12:54
|
Author: cerion Date: 2009-12-19 23:12:34 +0000 (Sat, 19 Dec 2009) New Revision: 461 Log: Lots more Options stuff ported. Not (at all) well tested, but it builds. Added: branches/valkyrie_qt4port/core/valgrind_object.cpp branches/valkyrie_qt4port/core/valgrind_object.h branches/valkyrie_qt4port/options/valgrind_options_page.cpp branches/valkyrie_qt4port/options/valgrind_options_page.h branches/valkyrie_qt4port/options/widgets/opt_lb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_lb_widget.h branches/valkyrie_qt4port/utils/vk_utils.cpp branches/valkyrie_qt4port/utils/vk_utils.h Modified: branches/valkyrie_qt4port/core/valkyrie_object.cpp branches/valkyrie_qt4port/core/valkyrie_object.h branches/valkyrie_qt4port/options/valkyrie_options_page.cpp branches/valkyrie_qt4port/options/valkyrie_options_page.h branches/valkyrie_qt4port/options/vk_option.h branches/valkyrie_qt4port/options/vk_options_page.cpp branches/valkyrie_qt4port/options/vk_options_page.h branches/valkyrie_qt4port/options/widgets/opt_cb_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_cb_widget.h branches/valkyrie_qt4port/options/widgets/opt_ck_widget.h branches/valkyrie_qt4port/options/widgets/opt_le_widget.cpp branches/valkyrie_qt4port/options/widgets/opt_le_widget.h branches/valkyrie_qt4port/options/widgets/opt_sp_widget.cpp branches/valkyrie_qt4port/valkyrie.pro Added: branches/valkyrie_qt4port/core/valgrind_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.cpp (rev 0) +++ branches/valkyrie_qt4port/core/valgrind_object.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,838 @@ +/**************************************************************************** +** Valgrind implementation +** - Valgrind-specific: options / flags / functionality +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 <QDir> + +#include "core/valgrind_object.h" +#include "options/valgrind_options_page.h" // createVkOptionsPage() + +//#include "config.h" // VK_CFG_DIR, VK_SUPPS_DIR +//#include "vk_config.h" +//#include "html_urls.h" +//#include "memcheck_object.h" +//#include "cachegrind_object.h" +//#include "massif_object.h" +//#include "vk_option.h" // PERROR* and friends +//#include "vk_utils.h" // vk_assert, VK_DEBUG, etc. + + +//TODO: from config.h +#define VK_CFG_DIR ".valkyrie" +#define VK_SUPPS_DIR "suppressions/" + +//#include <ctype.h> +//#include <stdlib.h> +//#include <string.h> +//#include <stdio.h> + + +/***************************************************************************/ +/*! + Constructs a Valkyrie object +*/ +Valgrind::Valgrind() + : VkObject( "valgrind" ) + // : VkObject( "Valgrind", "Valgrind", Qt::Key_unknown, VkObject::ID_VALGRIND ) +{ + // /* init tools */ + // initToolObjects();`` + + setupOptions(); +} + + +Valgrind::~Valgrind() +{ + // m_toolObjList.setAutoDelete( true ); + // m_toolObjList.clear(); +} + + + +/*! + Setup the options for this object. + + Note: These opts should be kept in exactly the same order as valgrind + outputs them, as it makes keeping up-to-date a lot easier. +*/ +void Valgrind::setupOptions() +{ + + // ------------------------------------------------------------ + // tool + options.addOpt( + VALGRIND::TOOL, + this->objectName(), + "tool", + '\0', + "<name>", + "memcheck|cachegrind|massif", + "memcheck", + "Main tool:", + "use the Valgrind tool named <name>. Available tools are: memcheck, cachegrind, massif", + "",// TODO: urlVgCore::mainTool + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + + // ------------------------------------------------------------ + // common options relevant to all tools + options.addOpt( + VALGRIND::VERBOSITY, + this->objectName(), + "verbosity", + '\0', + "<0..4>", + "0|4", + "1", + "Verbosity level:", + "Be more verbose, include counts of errors", + "",// TODO: urlVgCore::verbosity + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::TRACE_CH, + this->objectName(), + "trace-children", + '\0', + "<yes|no>", + "yes|no", + "no", + "Trace child processes: ", + "Valgrind-ise child processes (follow execve)?", + "",// TODO: urlVgCore::traceChild + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SILENT_CH, + this->objectName(), + "child-silent-after-fork", + '\0', + "<yes|no>", + "yes|no", + "yes", /* currently necessary for clean XML output */ + "Omit child output between fork and exec: ", + "omit child output between fork & exec?", + "",// TODO: urlVgCore::silentChild + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::TRACK_FDS, + this->objectName(), + "track-fds", + '\0', + "<yes|no>", + "yes|no", + "no", + "Track open file descriptors:", + "track open file descriptors?", + "",// TODO: urlVgCore::trackFds + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::TIME_STAMP, + this->objectName(), + "time-stamp", + '\0', + "<yes|no>", + "yes|no", + "no", + "Add timestamps to log messages:", + "add timestamps to log messages?", + "",// TODO: urlVgCore::timeStamp + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::LOG_FD, + this->objectName(), + "log-fd", + '\0', + "<1..1024>", + "1|1023", + "2", + "Log to file descriptor:", + "log messages to file descriptor (1=stdout, 2=stderr)", + "",// TODO: urlVgCore::logToFd + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::LOG_FILE, + this->objectName(), + "log-file", + '\0', + "<file>", + "", + "", + "Log to file:", + "log messages to <file>", + "",// TODO: urlVgCore::logToFile + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + options.addOpt( + VALGRIND::LOG_SOCKET, + this->objectName(), + "log-socket", + '\0', + "<ipaddr:port>", + "", + "", + "Log to socket:", + "log messages to socket ipaddr:port", + "",// TODO: urlVgCore::logToSocket + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + + // ------------------------------------------------------------ + // uncommon options relevant to all tools + options.addOpt( + VALGRIND::RUN_LIBC, + this->objectName(), + "run-libc-freeres", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Free glibc memory at exit:", + "Free up glibc memory at exit?", + "",// TODO: urlVgCore::freeGlibc + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SIM_HINTS, + this->objectName(), + "sim-hints", + '\0', + "<hint1,hint2,...>", + "none|lax-ioctls|enable-outer", + "none", + "Simulation Hints:", + "Slightly modify the simulated behaviour. Recognised hints are: lax-ioctls, enable-outer. Use with caution!", + "",// TODO: urlVgCore::simHints + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::KERN_VAR, + this->objectName(), + "kernel-variant", + '\0', + "<variant1,...>", + "none|bproc", + "none", + "Kernel Variants:", + "Handle non-standard kernel variants. Recognised variants are: bproc. Use with caution!", + "",// TODO: urlVgCore::kernelVariant + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::EM_WARNS, + this->objectName(), + "show-emwarns", + '\0', + "<yes|no>", + "yes|no", + "no", + "Show warnings about emulation limits:", + "show warnings about emulation limits?", + "",// TODO: urlVgCore::showEmWarns + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SMC_CHECK, + this->objectName(), + "smc-check", + '\0', + "<none|stack|all>", + "none|stack|all", + "stack", + "Where to check for self-modifying code", + "checks for self-modifying code: none, only for code on the stack, or all", + "",// TODO: urlVgCore::smcSupport + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + + // ------------------------------------------------------------ + // options relevant to error-reporting tools + options.addOpt( + VALGRIND::XML_OUTPUT, + this->objectName(), + "xml", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Output in xml format:", + "all output is in XML", + "",// TODO: urlVgCore::xmlOutput + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::XML_COMMENT, + this->objectName(), + "xml-user-comment", + '\0', + "<str>", + "", + "", + "Insert verbatim in xml output", + "copy <str> verbatim to XML output", + "",// TODO: urlVgCore::xmlComment + VkOPT::ARG_STRING, + VkOPT::WDG_NONE + ); + + options.addOpt( + VALGRIND::DEMANGLE, + this->objectName(), + "demangle", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Automatically demangle C++ names", + "automatically demangle C++ names?", + "",// TODO: urlVgCore::autoDemangle + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::NUM_CALLERS, + this->objectName(), + "num-callers", + '\0', + "<1..50>", + "1|50", + "12", + "Number of stack trace callers:", + "show <num> callers in stack traces", + "",// TODO: urlVgCore::numCallers + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::ERROR_LIMIT, + this->objectName(), + "error-limit", + '\0', + "<yes|no>", + "yes|no", + "yes", + "Limit the number of errors shown", + "Stop showing new errors if too many?", + "",// TODO: urlVgCore::errorLimit + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::SHOW_BELOW, + this->objectName(), + "show-below-main", + '\0', + "<yes|no>", + "yes|no", + "no", + "Continue stack traces below main()", + "continue stack traces below main()", + "",// TODO: urlVgCore::stackTraces + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + + // ------------------------------------------------------------ + // Can't access vkConfig->suppDir(): config created after us! + QString defSuppDir = QDir::homePath() + "/" + VK_CFG_DIR + VK_SUPPS_DIR; + /* list of dirs holding suppression files */ + options.addOpt( + VALGRIND::SUPPS_DIRS, + this->objectName(), + "supps-dirs", + '\0', + "", + "", + defSuppDir, + "Suppression Dirs:", + "", + "",// TODO: urlValkyrie::suppsTab + VkOPT::NOT_POPT, + VkOPT::WDG_LISTBOX + ); + + /* list of all suppression files found in option SUPP_DIRS */ + options.addOpt( + VALGRIND::SUPPS_AVAIL, + this->objectName(), + "supps-avail", + '\0', + "", + "", + "", + "Available error-suppression file(s):", + "", + "",// TODO: urlValkyrie::suppsTab + VkOPT::NOT_POPT, + VkOPT::WDG_LISTBOX + ); + + /* list of selected suppression files */ + options.addOpt( + VALGRIND::SUPPS_SEL, + this->objectName(), + "suppressions", + '\0', + "<file1,...>", + "", + "", + "Selected error-suppression file(s):", + "suppress errors described in suppressions file(s)", + "",// TODO: urlValkyrie::suppsTab + VkOPT::ARG_STRING, + VkOPT::WDG_LISTBOX + ); + + + // ------------------------------------------------------------ + // ... + options.addOpt( + VALGRIND::GEN_SUPP, + this->objectName(), + "gen-suppressions", + '\0', + "<yes|no|all>", + "yes|no|all", + "no", + "Print suppressions for errors", + "print suppressions for errors?", + "",// TODO: urlVgCore::genSuppressions + VkOPT::ARG_STRING, + VkOPT::WDG_COMBO + ); + + options.addOpt( + VALGRIND::DB_ATTACH, + this->objectName(), + "db-attach", + '\0', + "<yes|no>", + "yes|no", + "no", + "Start debugger on error detection", + "start debugger when errors detected?", + "",// TODO: urlVgCore::startDebugger + VkOPT::ARG_BOOL, + VkOPT::WDG_CHECK + ); + + options.addOpt( + VALGRIND::DB_COMMAND, + this->objectName(), + "db-command", + '\0', + "<command>", + "", + "/usr/bin/gdb -nw %f %p", + "Debugger:", + "command to start debugger", + "",// TODO: urlVgCore::whichDebugger + VkOPT::ARG_STRING, + VkOPT::WDG_LEDIT + ); + + options.addOpt( + VALGRIND::INPUT_FD, + this->objectName(), + "input-fd", + '\0', + "<0..1024>", + "0|1023", + "0", + "Input file descriptor:", + + "File descriptor for (db) input (0=stdin, 1=stdout, 2=stderr)", + "",// TODO: urlVgCore::inputFd + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); + + options.addOpt( + VALGRIND::MAX_SFRAME, + this->objectName(), + "max-stackframe", + '\0', + "<number>", + "0|2000000", + "2000000", + "Stack switch on SP changes at:", + "assume stack switch for stack pointer changes larger than <number> bytes", + "",// TODO: urlVgCore::maxSFrames + VkOPT::ARG_UINT, + VkOPT::WDG_SPINBOX + ); +} + + +/* check argval for this option, updating if necessary. + called by parseCmdArgs() and gui option pages -------------------- */ +int Valgrind::checkOptArg( int optid, QString& argval ) +{ +optid = optid; argval = argval; +// vk_assert( optid >= 0 && optid < NUM_OPTS ); + + int errval = PARSED_OK; + +#if 0 + Option* opt = findOption( optid ); + QString sep = vkConfig->sepChar(); + + switch ( (Valgrind::vgOpts)optid ) { + + case VALGRIND::TOOL: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valkyrie currently only supports Memcheck."); + break; + + case VALGRIND::SIM_HINTS: + case VALGRIND::RUN_LIBC: + case VALGRIND::NUM_CALLERS: + case VALGRIND::DEMANGLE: + // case VALGRIND::INPUT_FD: // TODO + case VALGRIND::SHOW_BELOW: + case VALGRIND::MAX_SFRAME: + case VALGRIND::SMC_CHECK: + opt->isValidArg( &errval, argval ); + break; + + case VALGRIND::VERBOSITY: + case VALGRIND::TRACK_FDS: + case VALGRIND::TIME_STAMP: + case VALGRIND::EM_WARNS: + case VALGRIND::GEN_SUPP: + case VALGRIND::ERROR_LIMIT: + case VALGRIND::DB_COMMAND: + case VALGRIND::DB_ATTACH: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valgrind presets these options for XML output."); + vkPrintErr(" - See valgrind/docs/internals/xml_output.txt."); + break; + + case VALGRIND::XML_COMMENT: + /* don't wan't xml in comment: escape '<','&',etc */ + argval = escapeEntities( argval ); + break; + + case VALGRIND::SUPPS_DIRS: { /* not popt: only reaches here from gui */ + /* check all entries are valid dirs */ + QStringList dirs = QStringList::split(sep, argval); + QStringList::iterator it = dirs.begin(); + for (; it != dirs.end(); ++it) { + /* check dirs ok */ + *it = dirCheck( &errval, *it, true, false ); + if ( errval != PARSED_OK ) + break; + } + argval = dirs.join(sep); + } break; + + case VALGRIND::SUPPS_AVAIL: /* not popt: only reaches here from gui */ + case VALGRIND::SUPPS_SEL: { /* is popt: --suppressions */ + QStringList files = QStringList::split(sep, argval); + QStringList::iterator it = files.begin(); + for (; it != files.end(); ++it) { + /* check files ok & readable */ + *it = fileCheck( &errval, *it, true, false ); + if ( errval != PARSED_OK ) + break; + /* TODO: do we care if it doesn't end in .supp? + - breaks the suppression widgets a little, as only lists those ending in .supp ... */ + + /* TODO: ? check valid suppression files */ + } + argval = files.join(sep); + } break; + + case VALGRIND::TRACE_CH: { +#if 0 + if ( opt->isValidArg( &errval, argval ) ) { + if ( argval == "yes" ) { + if ( vkConfig->rdBool( "db-attach", "valgrind" ) ) + errval = PERROR_DB_CONFLICT; + } + } +#else + /* Disabled for now - can't deal with the multiple xml files this generates */ + /* Note: Also disabled in ValgrindOptionsPage() */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Valkyrie can't yet handle the multiple xml files this generates."); +#endif + } break; + + case VALGRIND::SILENT_CH: { + /* Disabled for now - output between fork and exec is confusing for the XML output */ + /* Note: Also disabled in ValgrindOptionsPage() */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Necessary, to get clean XML output from Valgrind."); + } break; + + case VALGRIND::XML_OUTPUT: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Valkyrie always requires xml output from Valgrind."); + break; + + +#if 0 // TODO: Fix Valgrind to allow gdb attaching with XML output + case VALGRIND::DB_COMMAND: { /* gdb -nw %f %p */ + int pos = argval.find( ' ' ); + QString tmp = argval.left( pos ); + argval = binaryCheck( &errval, tmp ); + argval += tmp.right( tmp.length() - pos+1 ); + // vkPrint("db_command: %s", argval.latin1() ); + } break; + + /* check for conflict with --trace-children */ + case VALGRIND::DB_ATTACH: + if ( opt->isValidArg( &errval, argval ) ) { + if ( argval == "yes" ) { + if ( vkConfig->rdBool( "trace-children","valgrind" ) ) + errval = PERROR_DB_CONFLICT; + } + } break; +#endif + + case VALGRIND::KERN_VAR: + break; + + /* logging options */ + /* all tools use an internal logging option, + all logging options are therefore ignored */ + case VALGRIND::LOG_FILE: + case VALGRIND::LOG_FD: + case VALGRIND::LOG_SOCKET: + /* Note: gui options disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; + vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); + vkPrintErr(" - Valkyrie sets its own logging options to gather data from Valgrind."); + break; + + + /* Not yet implemented */ + case VALGRIND::INPUT_FD: + /* Note: gui option disabled, so only reaches here from cmdline */ + errval = PERROR_BADOPT; +// vkPrintErr("Option disabled '--%s'", opt->m_longFlag.latin1()); +// vkPrintErr(" - Not yet implemented."); + break; + + default: + assert( true ); +// vk_assert_never_reached(); + } +#endif + + return errval; +} + + +#if 0 +/* valkyrie hijacks any log-to-file flags; these are not passed to + valgrind, but are used after parsing has finished to save to. */ +QStringList Valgrind::modifiedVgFlags( const ToolObject* tool_obj ) +{ + QStringList modFlags; + QString defVal, cfgVal, flag; + + for ( Option* opt = m_optList.first(); opt; opt = m_optList.next() ) { + flag = opt->m_longFlag.isEmpty() ? opt->m_shortFlag + : opt->m_longFlag; + defVal = opt->m_defaultValue; + cfgVal = vkConfig->rdEntry( opt->cfgKey(), name() ); + + switch ( (Valgrind::vgOpts)opt->m_key ) { + + /* we never want these included */ + case VALGRIND::TOOL: /* tool set by valkyrie */ + case VALGRIND::SUPPS_DIRS: /* false option */ + case VALGRIND::SUPPS_AVAIL: /* false option */ + break; + + /* only error-reporting tools have suppressions */ + case VALGRIND::SUPPS_SEL: { + if ( tool_obj->name() == "memcheck" ) { + /* we need '--suppressions=' before each and every filename */ + QString optEntry = vkConfig->rdEntry( opt->cfgKey(), name() ); + QStringList files = QStringList::split( ",", optEntry ); + for ( unsigned int i=0; i<files.count(); i++ ) { + modFlags << "--" + opt->cfgKey() + "=" + files[i]; + } + } + } break; + + + /* for memcheck we always need xml=yes */ + case VALGRIND::XML_OUTPUT: + if ( tool_obj->name() == "memcheck") + modFlags << "--" + opt->cfgKey() + "=yes"; + else + if ( defVal != cfgVal ) + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + break; + + /* for memcheck we needs this enabled to keep the xml clean */ + case VALGRIND::SILENT_CH: + if ( tool_obj->name() == "memcheck") + modFlags << "--" + opt->cfgKey() + "=yes"; + else + if ( defVal != cfgVal ) + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + break; + + case VALGRIND::VERBOSITY: + case VALGRIND::TRACK_FDS: + case VALGRIND::TIME_STAMP: + case VALGRIND::EM_WARNS: + case VALGRIND::GEN_SUPP: + case VALGRIND::ERROR_LIMIT: + case VALGRIND::DB_ATTACH: + case VALGRIND::DB_COMMAND: + if ( defVal != cfgVal ) { + // disabled for now: /* gui options not disabled: other tools use these options */ + if ( tool_obj->name() == "memcheck") { + /* memcheck presets/ignores these options for xml output + - ignore these opts + - see valgrind/docs/internals/xml_output.txt */ + } else { + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + } + } + break; + + /* all tools use an internal logging option, + all logging options should therefore not be used */ + case VALGRIND::LOG_FILE: + case VALGRIND::LOG_FD: + case VALGRIND::LOG_SOCKET: + /* ignore these opts */ + break; + + default: + if ( defVal != cfgVal ) { + modFlags << "--" + opt->cfgKey() + "=" + cfgVal; + } + break; + } + } + + return modFlags; +} + + + +/* Register tools */ +void Valgrind::initToolObjects() +{ + int objId = VkObject::ID_TOOL0; + m_toolObjList.append( new Memcheck ( objId++ ) ); + + // TODO: I need another lifetime! + // m_toolObjList.append( new Cachegrind( objId++ ) ); + // m_toolObjList.append( new Massif ( objId++ ) ); +} + + +/* ToolObject access -------------------------------------------=---- */ + +/* Returns a list of all ptrs to ToolObjects */ +ToolObjList Valgrind::toolObjList() +{ + return m_toolObjList; +} + +/* Returns a ToolObject's objectId based on its name */ +int Valgrind::toolObjId( const QString& name ) +{ + return toolObj(name)->objId(); +} + +/* Returns a ToolObject based on its objectId */ +ToolObject* Valgrind::toolObj( int tid ) +{ + // vkPrint("Valgrind::toolObj( int tid=%d )", tid); + vk_assert( tid >= ID_TOOL0 ); + ToolObject* tool = m_toolObjList.at( tid - ID_TOOL0 ); + vk_assert( tool != 0 ); + vk_assert( tool->objId() == tid ); + return tool; +} + +/* Returns a ToolObject based on its name */ +ToolObject* Valgrind::toolObj( const QString& name ) { + ToolObject* tool; + for ( tool = m_toolObjList.first(); tool; tool = m_toolObjList.next() ) { + if ( tool->name() == name ) + return tool; + } + vk_assert_never_reached(); + return NULL; +} +#endif + + + +VkOptionsPage* Valgrind::createVkOptionsPage() { + return (VkOptionsPage*)new ValgrindOptionsPage( this ); +} Added: branches/valkyrie_qt4port/core/valgrind_object.h =================================================================== --- branches/valkyrie_qt4port/core/valgrind_object.h (rev 0) +++ branches/valkyrie_qt4port/core/valgrind_object.h 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,115 @@ +/**************************************************************************** +** Valgrind object class definition +** - Valgrind-specific: options / flags / functionality +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 __VALGRIND_OBJECT_H +#define __VALGRIND_OBJECT_H + +#include "core/vk_objects.h" +//#include "tool_object.h" + + +// ============================================================ +namespace VALGRIND { +/*! + enum identification of all options for this object +*/ + enum vgOptId { + TOOL, // --tool + /* common options relevant to all tools */ + VERBOSITY, // --verbosity + TRACE_CH, // --trace-children + SILENT_CH, // --child-silent-after-fork + TRACK_FDS, // --track-fds + TIME_STAMP, // --time-stamp + LOG_FD, // --log-fd + LOG_FILE, // --log-file + LOG_SOCKET, // --log-socket + + /* uncommon options relevant to all tools */ + RUN_LIBC, // --run-libc-freeres + SIM_HINTS, // --sim-hints + KERN_VAR, // --kernel-variant + EM_WARNS, // --show-emwarns + SMC_CHECK, // --smc-check + + /* options relevant to error-reporting tools */ + XML_OUTPUT, // --xml + XML_COMMENT, // -- xml-user-comment + DEMANGLE, // --demangle + NUM_CALLERS, // --num-callers + ERROR_LIMIT, // --error-limit + SHOW_BELOW, // --show-below-main + + /* suppressions hackery */ + SUPPS_DIRS, /* list of suppfile dirs - feeds SUPPS_AVAIL list */ + SUPPS_AVAIL, /* fake opt: dyname list of available supp files */ + SUPPS_SEL, /* the currently selected suppression(s) */ + + /* misc */ + GEN_SUPP, // --gen-suppressions + DB_ATTACH, // --db-attach + DB_COMMAND, // --db-command + INPUT_FD, // --input-fd + MAX_SFRAME, // --max-stackframe + NUM_OPTS + }; +} + + +// ============================================================ +class Valgrind : public VkObject +{ +public: + Valgrind(); + ~Valgrind(); + +#if 0 + /* returns a list of non-default flags to pass to valgrind */ + QStringList modifiedVgFlags( const ToolObject* tool_obj ); + unsigned int maxOptId() { return NUM_OPTS; } +#endif + + int checkOptArg( int optid, QString& argval ); + + VkOptionsPage* createVkOptionsPage(); + +#if 0 +public: + /* ToolObject access */ + ToolObjList toolObjList(); + int toolObjId( const QString& name ); + ToolObject* toolObj( int tid ); + ToolObject* toolObj( const QString& name ); +#endif + +private: +#if 0 + /* creates the various VkObjects and initialises their options, + ready for cmd-line parsing (if any). */ + void initToolObjects(); + + ToolObjList m_toolObjList; /* Tools */ +#endif + +private: + void setupOptions(); +}; + +#endif Modified: branches/valkyrie_qt4port/core/valkyrie_object.cpp =================================================================== --- branches/valkyrie_qt4port/core/valkyrie_object.cpp 2009-11-01 20:23:02 UTC (rev 460) +++ branches/valkyrie_qt4port/core/valkyrie_object.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -36,6 +36,9 @@ : VkObject( "valkyrie" ) { setupOptions(); + + /* init valgrind */ + m_valgrind = new Valgrind(); } @@ -44,6 +47,11 @@ */ Valkyrie:: ~Valkyrie() { + if ( m_valgrind != 0 ) { + delete m_valgrind; + m_valgrind = 0; + } + } @@ -322,7 +330,7 @@ //int Valkyrie::checkOptArg( int optid, QString& argval ) int Valkyrie::checkOptArg( int, QString& ) { -// VkOption* opt = this->options.getOption( optid ); + // VkOption* opt = this->options.getOption( optid ); #if 0 // TODO vk_assert( optid >= 0 && optid < NUM_OPTS ); @@ -432,16 +440,19 @@ -/* Return list of all VkObjects */ +/*! + Return list of all VkObjects + + TODO: const. +*/ VkObjectList Valkyrie::vkObjList() { - VkObjectList vkObjList; // don't delete contents! + VkObjectList vkObjList; vkObjList.append( this ); + vkObjList.append( this->valgrind() ); #if 0 // TODO - vkObjList.append(m_valgrind); - ToolObjList tools = valgrind()->toolObjList(); for ( ToolObject* tool = tools.first(); tool; tool = tools.next() ) vkObjList.append( tool ); Modified: branches/valkyrie_qt4port/core/valkyrie_object.h =================================================================== --- branches/valkyrie_qt4port/core/valkyrie_object.h 2009-11-01 20:23:02 UTC (rev 460) +++ branches/valkyrie_qt4port/core/valkyrie_object.h 2009-12-19 23:12:34 UTC (rev 461) @@ -21,6 +21,7 @@ #ifndef __VALKYRIE_OBJECT_H #define __VALKYRIE_OBJECT_H +#include "core/valgrind_object.h" #include "core/vk_objects.h" // ============================================================ @@ -73,14 +74,17 @@ // Generate own options page VkOptionsPage* createVkOptionsPage(); -// TODO -// Valgrind* valgrind() { return m_valgrind; } -// /* for simplicity */ + Valgrind* valgrind() { return m_valgrind; } + + /* for simplicity */ VkObjectList vkObjList(); // VkObject* vkObject( int objId ); private: void setupOptions(); + +private: + Valgrind* m_valgrind; }; Added: branches/valkyrie_qt4port/options/valgrind_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.cpp (rev 0) +++ branches/valkyrie_qt4port/options/valgrind_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,416 @@ +/**************************************************************************** +** ValgrindOptionsPage implementation +** - subclass of VkOptionsPage to hold valgrind-specific options +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 <QDir> +#include <QListWidget> +#include <QTabWidget> + +//#include "vk_config.h" +//#include "vk_messages.h" +#include "utils/vk_utils.h" +//#include "context_help.h" +//#include "html_urls.h" + +#include "core/valgrind_object.h" +#include "options/widgets/opt_base_widget.h" +#include "options/widgets/opt_le_widget.h" +#include "options/widgets/opt_lb_widget.h" +#include "options/valgrind_options_page.h" + + + +/* from valgrind/coregrind/pub_core_options.h + = maximum number of suppression files */ +#define VG_CLO_MAX_SFILES 10 + + +/***************************************************************************/ +/*! + Valgrind Options Page + This page is different from the others in that it uses three tabs + because there are just too many options to put on one page. + (a) general core options, + (b) error-reporting options, and + (c) suppression-related options +*/ +ValgrindOptionsPage::ValgrindOptionsPage( VkObject* obj ) + : VkOptionsPage( obj ) +{ + this->setObjectName(QString::fromUtf8("valgrind_options_page")); + + // setup the widgets & layout + setupOptions(); + + // setup edit signals/slots + It_OptWidgHash it = m_itemList.begin(); + while ( it != m_itemList.constEnd() ) { + OptionWidget* widg = it.value(); + connect( widg, SIGNAL(valueChanged( bool, OptionWidget* )), + this, SLOT(updateEditList( bool, OptionWidget* )) ); + ++it; + } +} + + +void ValgrindOptionsPage::setupOptions() +{ + group1 = new QGroupBox( " Valgrind Options ", this ); + group1->setObjectName(QString::fromUtf8("ValgrindOptionsPage_group1")); + pageTopVLayout->addWidget( group1 ); + + QTabWidget* tabWidget = new QTabWidget( this ); + tabWidget->setObjectName(QString::fromUtf8("ValgrindOptionsPage_tabWidget")); + pageTopVLayout->addWidget( tabWidget ); + + // ============================================================ + // tabCore - tab 1: core options + QWidget* tabCore = new QWidget( tabWidget ); + tabCore->setObjectName(QString::fromUtf8("tab_core")); + tabWidget->addTab( tabCore, " Core " ); +// ContextHelp::add( tabCore, urlValkyrie::coreTab ); + + // tabCore - vbox + QVBoxLayout* core_vbox = new QVBoxLayout( tabCore ); + core_vbox->setObjectName(QString::fromUtf8("core_vbox")); + + // ------------------------------------------------------------ + // tabCore - group box 1 + QGroupBox* cgroup1 = new QGroupBox(" Common Options ", tabCore ); + cgroup1->setObjectName(QString::fromUtf8("cgroup1")); + core_vbox->addWidget( cgroup1 ); // , m_space + + // tabCore - group box 1 - options + insertOptionWidget( VALGRIND::TOOL, cgroup1, true ); // combobox + insertOptionWidget( VALGRIND::VERBOSITY, cgroup1, true ); // spinbox + insertOptionWidget( VALGRIND::XML_OUTPUT, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::TRACE_CH, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::SILENT_CH, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::TRACK_FDS, cgroup1, false ); // checkbox + insertOptionWidget( VALGRIND::TIME_STAMP, cgroup1, false ); // checkbox + + // tabCore - group box 1 - layout + int i=0; + QGridLayout* cgrid1 = new QGridLayout( cgroup1 ); + cgrid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row + cgrid1->addLayout( m_itemList[VALGRIND::TOOL ]->hlayout(), i++, 0 ); + cgrid1->addLayout( m_itemList[VALGRIND::VERBOSITY ]->hlayout(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::XML_OUTPUT]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::TRACE_CH ]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::SILENT_CH ]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::TRACK_FDS ]->widget(), i++, 0 ); + cgrid1->addWidget( m_itemList[VALGRIND::TIME_STAMP]->widget(), i++, 0 ); + + + // ------------------------------------------------------------ + // tabCore - group box 2 + QGroupBox* cgroup2 = new QGroupBox(" Less Common Options ", tabCore ); + cgroup2->setObjectName(QString::fromUtf8("cgroup2")); + core_vbox->addWidget( cgroup2 ); // , m_space + + // tabCore - group box 2 - options + insertOptionWidget( VALGRIND::RUN_LIBC, cgroup2, false ); // checkbox + insertOptionWidget( VALGRIND::EM_WARNS, cgroup2, false ); // checkbox + insertOptionWidget( VALGRIND::SMC_CHECK, cgroup2, true ); // combobox + insertOptionWidget( VALGRIND::SIM_HINTS, cgroup2, true ); // combobox + insertOptionWidget( VALGRIND::KERN_VAR, cgroup2, true ); // combobox + + // tabCore - group box 2 - layout + i=0; + QGridLayout* cgrid2 = new QGridLayout( cgroup2 ); + cgrid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row + cgrid2->addWidget( m_itemList[VALGRIND::RUN_LIBC ]->widget(), i++, 0 ); + cgrid2->addWidget( m_itemList[VALGRIND::EM_WARNS ]->widget(), i++, 0 ); + cgrid2->addLayout( m_itemList[VALGRIND::SMC_CHECK]->hlayout(), i++, 0 ); + cgrid2->addLayout( m_itemList[VALGRIND::SIM_HINTS]->hlayout(), i++, 0 ); + cgrid2->addLayout( m_itemList[VALGRIND::KERN_VAR ]->hlayout(), i++, 0 ); + + // v. stretch at bottom + core_vbox->addStretch( 1 ); + + + // ============================================================ + // tabErep - tab 2: error-reporting + QWidget* tabErep = new QWidget( tabWidget ); + tabErep->setObjectName(QString::fromUtf8("tab_erep")); + tabWidget->addTab( tabErep, " Error Reporting " ); +// ContextHelp::add( tabErep, urlValkyrie::errorTab ); + + // tabErep - vbox + QVBoxLayout* erep_vbox = new QVBoxLayout( tabErep ); + erep_vbox->setObjectName(QString::fromUtf8("erep_vbox")); + + // ------------------------------------------------------------ + // tabErep - group box 1 + QGroupBox* egroup1 = new QGroupBox(" Options ", tabErep ); + egroup1->setObjectName(QString::fromUtf8("egroup1")); + erep_vbox->addWidget( egroup1 ); // , m_space + + // tabErep - group box 1 - options + insertOptionWidget( VALGRIND::GEN_SUPP, egroup1, true ); // combobox + insertOptionWidget( VALGRIND::DEMANGLE, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::ERROR_LIMIT, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::SHOW_BELOW, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::NUM_CALLERS, egroup1, true ); // intspin + insertOptionWidget( VALGRIND::MAX_SFRAME, egroup1, true ); // spinbox + + insertOptionWidget( VALGRIND::DB_ATTACH, egroup1, false ); // checkbox + insertOptionWidget( VALGRIND::DB_COMMAND, egroup1, false ); // ledit+button + LeWidget* dbLedit = ((LeWidget*)m_itemList[VALGRIND::DB_COMMAND]); + dbLedit->addButton( egroup1, this, SLOT(getDbBin()) ); + connect(dbLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); + + insertOptionWidget( VALGRIND::INPUT_FD, egroup1, true ); // spinbox + insertOptionWidget( VALGRIND::LOG_FD, egroup1, true ); // spinbox + insertOptionWidget( VALGRIND::LOG_FILE, egroup1, true ); // ledit + insertOptionWidget( VALGRIND::LOG_SOCKET, egroup1, true ); // ledit + + // tabErep - group box 1 - layout + i=0; + QGridLayout* egrid1 = new QGridLayout( egroup1 ); + egrid1->setRowMinimumHeight( i++, lineHeight/2 ); // blank top row + egrid1->addLayout( m_itemList[VALGRIND::GEN_SUPP ]->hlayout(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::DEMANGLE ]->widget(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::ERROR_LIMIT]->widget(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::SHOW_BELOW ]->widget(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::NUM_CALLERS]->hlayout(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::MAX_SFRAME ]->hlayout(), i++, 0 ); + egrid1->addWidget( m_itemList[VALGRIND::DB_ATTACH ]->widget(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::DB_COMMAND ]->hlayout(), i++, 0 ); + + egrid1->addWidget( sep(egroup1), i++,0, 1,2 ); + + QHBoxLayout* hBox = new QHBoxLayout(); + hBox->addLayout( m_itemList[VALGRIND::INPUT_FD]->hlayout() ); + hBox->addLayout( m_itemList[VALGRIND::LOG_FD]->hlayout() ); + egrid1->addLayout( hBox, i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::LOG_FILE ]->hlayout(), i++, 0 ); + egrid1->addLayout( m_itemList[VALGRIND::LOG_SOCKET ]->hlayout(), i++, 0 ); + + // v. stretch at bottom + erep_vbox->addStretch( 1 ); + + + + // ============================================================ + // tabSupps - tab 3: suppressions + QWidget* tabSupps = new QWidget( tabWidget ); + tabSupps->setObjectName(QString::fromUtf8("tab_supps")); + tabWidget->addTab( tabSupps, " Suppressions " ); +// ContextHelp::add( tabSupps, urlValkyrie::suppsTab ); + + // tabErep - vbox + QVBoxLayout* supp_vbox = new QVBoxLayout( tabSupps ); + supp_vbox->setObjectName(QString::fromUtf8("supp_vbox")); + + // tabErep - options + insertOptionWidget( VALGRIND::SUPPS_DIRS, tabSupps, true ); // listbox + insertOptionWidget( VALGRIND::SUPPS_AVAIL, tabSupps, true ); // listbox + insertOptionWidget( VALGRIND::SUPPS_SEL, tabSupps, true ); // listbox + + /* FIXME: suppression listbox widgets have far too much knowledge + about what they're used for. */ + LbWidget* lbDirs = (LbWidget*)m_itemList[VALGRIND::SUPPS_DIRS]; + LbWidget* lbAvail = (LbWidget*)m_itemList[VALGRIND::SUPPS_AVAIL]; + LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL]; + + // lbDirs updates lbAvail + connect( lbDirs, SIGNAL(listChanged()), + this, SLOT(suppDirsChanged()) ); + + // lbSel and lbAvail update each other + connect( lbAvail, SIGNAL(itemSelected(const QString&)), + this, SLOT(updateSuppsSel(const QString&)) ); + connect( lbSel, SIGNAL(listChanged()), + this, SLOT(updateSuppsAvail()) ); + + supp_vbox->addLayout( m_itemList[VALGRIND::SUPPS_DIRS ]->vlayout(), 1 ); + supp_vbox->addLayout( m_itemList[VALGRIND::SUPPS_AVAIL]->vlayout(), 2 ); + supp_vbox->addLayout( m_itemList[VALGRIND::SUPPS_SEL ]->vlayout(), 1 ); + + + + // ============================================================ + // Disabled Widgets + /* These widgets are disabled because Valkyrie uses + --log-file-exactly internally: logging options would interfere + with this. */ + // error reporting tab + m_itemList[VALGRIND::LOG_FD ]->setEnabled( false ); + m_itemList[VALGRIND::LOG_FILE ]->setEnabled( false ); + m_itemList[VALGRIND::LOG_SOCKET ]->setEnabled( false ); + + /* Disabled because Valkyrie always requires xml output from Valgrind */ + m_itemList[VALGRIND::XML_OUTPUT ]->setEnabled( false ); + + /* Disabled for now: Only supporting memcheck so far. */ + m_itemList[VALGRIND::TOOL ]->setEnabled( false ); + + /* Disabled for now - can't deal with the multiple xml files this generates */ + /* Note: Also disabled in Valgrind::checkOptArg() */ + m_itemList[VALGRIND::TRACE_CH ]->setEnabled( false ); + + /* Disabled - must be left on to generate clean XML */ + /* Note: Also disabled in Valgrind::checkOptArg() */ + m_itemList[VALGRIND::SILENT_CH ]->setEnabled( false ); + + /* Disabled for now - not yet implemented */ + m_itemList[VALGRIND::INPUT_FD ]->setEnabled( false ); + + /* Disabled for now - Valgrind presets these options for XML output + - See valgrind/docs/internals/xml_output.txt */ + m_itemList[VALGRIND::VERBOSITY ]->setEnabled( false ); + m_itemList[VALGRIND::TRACK_FDS ]->setEnabled( false ); + m_itemList[VALGRIND::EM_WARNS ]->setEnabled( false ); + m_itemList[VALGRIND::GEN_SUPP ]->setEnabled( false ); + m_itemList[VALGRIND::ERROR_LIMIT]->setEnabled( false ); + m_itemList[VALGRIND::DB_ATTACH ]->setEnabled( false ); + m_itemList[VALGRIND::DB_COMMAND ]->setEnabled( false ); + dbLedit->button()->setEnabled( false ); + + vk_assert( m_itemList.count() <= VALGRIND::NUM_OPTS ); +} + + + + +#if 0 +/* Called from OptionsWindow::categoryClicked() */ +void ValgrindOptionsPage::init() +{ + /* if usr gave suppfile on cmdline (updating lbSel) + - update suppDirs, suppsAvail from each path in lbSel */ + QChar sep = vkConfig->sepChar(); + LbWidget* lbSel = (LbWidget*)m_itemList[Valgrind::SUPPS_SEL ]; + QStringList currSupps = QStringList::split( sep, lbSel->currValue() ); + LbWidget* lbDirs = (LbWidget*)m_itemList[Valgrind::SUPPS_DIRS]; + QStringList suppDirs = QStringList::split( sep, lbDirs->currValue() ); + + for ( unsigned int i=0; i<currSupps.count(); i++ ) { + QFileInfo fi( currSupps[i] ); + QString path = fi.dirPath(); + if ( suppDirs.find( path ) == suppDirs.end() ) + suppDirs << path; + } + lbDirs->setCurrValue( suppDirs.join( sep ) ); + + /* apply changes to lbDirs */ + applyEdits(); + + /* init suppsAvail */ + suppDirsChanged(); +} + + +/* called when user clicks "Apply" / "Ok" / "Reset" buttons. */ +void ValgrindOptionsPage::applyOption( int optId ) +{ + vk_assert( optId >= 0 && optId < Valgrind::NUM_OPTS ); + +// QString argval = m_itemList[optId]->currValue(); + + /* apply option */ + switch ( optId ) { + default: + break; + } +} +#endif + + +void ValgrindOptionsPage::getDbBin() +{ + vkPrintErr("TODO: ValgrindOptionsPage::getDbBin()\n"); +} + + +/* Scan dirs set in option "valgrind::supps-dirs" for available + suppression files. + Update other widgets with result. +*/ +void ValgrindOptionsPage::suppDirsChanged() +{ + m_allAvailSuppFiles = QStringList(); + LbWidget* lbDirs = (LbWidget*)m_itemList[VALGRIND::SUPPS_DIRS]; +//TODO +// QChar m_sep = vkConfig->sepChar(); + QChar m_sep = ':'; + + /* Get list of dirs from "valgrind::supps-dirs" */ + QStringList suppDirs = lbDirs->currValue().split( m_sep ); + for ( int i=0; i<suppDirs.count(); i++ ) { + + /* for each suppDir, find all supp files */ + QDir suppDir( suppDirs[i] ); + QString path = suppDir.absolutePath() + '/'; + QStringList entries = suppDir.entryList( QStringList( "*.supp" ), QDir::Files ); + for ( int i=0; i<entries.count(); i++) { + m_allAvailSuppFiles += (path + entries[i]); + } + } + + updateSuppsAvail(); +} + + +/* Given available suppfiles from dirscan, + remove those already selected in option "valgrind::supps-sel" + Set suppsAvail list with result. +*/ +void ValgrindOptionsPage::updateSuppsAvail() +{ +//TODO +// QChar m_sep = vkConfig->sepChar(); +QChar m_sep = ':'; + LbWidget* lbAvail = (LbWidget*)m_itemList[VALGRIND::SUPPS_AVAIL]; + LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL ]; + QStringList suppsAvail = m_allAvailSuppFiles; + QStringList currSupps = lbSel->currValue().split( m_sep ); + + for ( int i=0; i<currSupps.count(); i++ ) { + int idx = suppsAvail.indexOf( currSupps[i] ); + if ( idx != -1 ) { + suppsAvail.removeAt( idx ); + } + } + + lbAvail->setCurrValue( suppsAvail.join( m_sep ) ); +} + + +/* Called by selecting an item in suppsAvail listbox. + Adds item to selected supps listbox (up to limit) +*/ +void ValgrindOptionsPage::updateSuppsSel(const QString& suppr) +{ + LbWidget* lbSel = (LbWidget*)m_itemList[VALGRIND::SUPPS_SEL]; + + if (((QListWidget*)lbSel->widget())->count() < VG_CLO_MAX_SFILES) { + lbSel->insertItem(suppr); + } else { +//TODO + cerr << "FIXME: Valgrind won't accept more than %d suppression files" << endl; +#if 0 + /* valgrind doesn't accept any more suppression files */ + vkError( this, "Error", + "Valgrind won't accept more than %d suppression files", + VG_CLO_MAX_SFILES ); +#endif + } +} Added: branches/valkyrie_qt4port/options/valgrind_options_page.h =================================================================== --- branches/valkyrie_qt4port/options/valgrind_options_page.h (rev 0) +++ branches/valkyrie_qt4port/options/valgrind_options_page.h 2009-12-19 23:12:34 UTC (rev 461) @@ -0,0 +1,62 @@ +/**************************************************************************** +** ValgrindOptionsPage definition +** - subclass of VkOptionsPage to hold valgrind-specific options +** -------------------------------------------------------------------------- +** +** Copyright (C) 2000-2009, 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 __VALGRIND_OPTIONS_PAGE_H +#define __VALGRIND_OPTIONS_PAGE_H + +#include <QGroupBox> +#include <QStringList> + +#include "options/vk_options_page.h" + + +// ============================================================ +class ValgrindOptionsPage : public VkOptionsPage +{ + Q_OBJECT +public: + ValgrindOptionsPage( VkObject* obj ); + +#if 0 + void applyOption( int optId ); + + void init(); +#endif + +private slots: + void getDbBin(); + void suppDirsChanged(); + void updateSuppsAvail(); + void updateSuppsSel(const QString&); + +private: + // hold on to these, so don't have to rescan dirs all the time + QStringList m_allAvailSuppFiles; + +private: + void setupOptions(); + +private: + QGroupBox* group1; + +}; + + +#endif Modified: branches/valkyrie_qt4port/options/valkyrie_options_page.cpp =================================================================== --- branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2009-11-01 20:23:02 UTC (rev 460) +++ branches/valkyrie_qt4port/options/valkyrie_options_page.cpp 2009-12-19 23:12:34 UTC (rev 461) @@ -22,28 +22,34 @@ //QGroupBox #include <QLabel> +#include "utils/vk_utils.h" + #if 0 #include "vk_objects.h" #include "vk_config.h" -#include "vk_utils.h" #include "main_window.h" #include "vk_messages.h" #include "context_help.h" #include "html_urls.h" #endif -#include "core/valkyrie_object.h" // access to valkyrie object +#include "core/valkyrie_object.h" // access to valkyrie object #include "options/widgets/opt_base_widget.h" #include "options/widgets/opt_le_widget.h" #include "options/valkyrie_options_page.h" +/***************************************************************************/ +/*! + Valkyrie Options Page +*/ ValkyrieOptionsPage::ValkyrieOptionsPage( VkObject* obj ) : VkOptionsPage( obj ) { + this->setObjectName(QString::fromUtf8("valkyrie_options_page")); + // setup the widgets & layout setupOptions(); - setupLayout(); // setup edit signals/slots It_OptWidgHash it = m_itemList.begin(); @@ -66,9 +72,15 @@ //TODO //ContextHelp::add( group1, urlVALKYRIE::optsPage ); + // Note: not using opt_widget->hlayout()'s as button width won't match qlabel width. + QGridLayout* grid = new QGridLayout( group1 ); + grid->setColumnStretch(0, 0); + grid->setColumnStretch(1, 1); + grid->setColumnStretch(2, 1); + grid->setColumnStretch(3, 1); // ------------------------------------------------------------ - // general prefs + // general prefs - options insertOptionWidget( VALKYRIE::TOOLTIP, group1, false ); // checkbox insertOptionWidget( VALKYRIE::ICONTXT, group1, false ); // checkbox insertOptionWidget( VALKYRIE::PALETTE, group1, false ); // checkbox @@ -88,10 +100,26 @@ dirWorking->addButton( group1, this, SLOT(getWorkingDir()) ); connect(dirWorking, SIGNAL(returnPressed()), this, SIGNAL(apply())); + // general prefs - layout + int i=0; + grid->setRowMinimumHeight( i++, lineHeight/2 ); // blank row + grid->addWidget( m_itemList[VALKYRIE::TOOLTIP]->widget(), i++,0, 1,2 ); + grid->addWidget( m_itemList[VALKYRIE::ICONTXT]->widget(), i++,0, 1,2 ); + grid->addWidget( m_itemList[VALKYRIE::PALETTE]->widget(), i++,0, 1,2 ); + grid->addWidget( brwsrLedit->button(), i, 0 ); + grid->addWidget( brwsrLedit->widget(), i++, 1, 1,3 ); + grid->addWidget( dirLogSave->button(), i, 0 ); + grid->addWidget( dirLogSave->widget(), i++,1, 1,3 ); + grid->addWidget( dirWorking->button(), i, 0 ); + grid->addWidget( dirWorking->widget(), i++,1, 1,3 ); + grid->addWidget( sep(group1), i++,0, 1,4 ); + + // ------------------------------------------------------------ - // fonts + // fonts - options insertOptionWidget( VALKYRIE::FNT_GEN_SYS, group1, false ); // checkbox + LeWidget* fontGenSysLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_SYS]); insertOptionWidget( VALKYRIE::FNT_GEN_USR, group1, false ); // line edit LeWidget* fontGenLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_USR]); fontGenLedit->addButton( group1, this, SLOT(chooseGenFont()) ); @@ -102,17 +130,26 @@ // bool use_sys_font = vkConfig->rdBool("font-gen-sys", "valkyrie"); bool use_sys_font = true; fontGenLedit->setDisabled( use_sys_font ); - connect( m_itemList[VALKYRIE::FNT_GEN_SYS], SIGNAL(changed(bool)), - m_itemList[VALKYRIE::FNT_GEN_USR], SLOT(setDisabled(bool)) ); + connect( fontGenSysLedit, SIGNAL(changed(bool)), + fontGenLedit, SLOT(setDisabled(bool)) ); insertOptionWidget( VALKYRIE::FNT_TOOL_USR, group1, false ); // line edit LeWidget* fontToolLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_TOOL_USR]); fontToolLedit->addButton( group1, this, SLOT(chooseToolFont()) ); fontToolLedit->setReadOnly( true ); // don't allow direct editing + // fonts - layout + grid->addWidget( fontGenSysLedit->widget(), i++,0, 1,4 ); + grid->addWidget( fontGenLedit->button(), i, 0 ); + grid->addWidget( fontGenLedit->widget(), i++,1, 1,3 ); + grid->addWidget( fontToolLedit->button(), i, 0 ); + grid->addWidget( fontToolLedit->widget(), i++,1, 1,3 ); + grid->addWidget( sep(group1), i++,0, 1,4 ); + + // ------------------------------------------------------------ - // core + // core - options insertOptionWidget( VALKYRIE::SRC_LINES, group1, true ); // intspin insertOptionWidget( VALKYRIE::SRC_EDITOR, group1, false ); // ledit + button LeWidget* editLedit = ((LeWidget*)m_itemList[VALKYRIE::SRC_EDITOR]); @@ -133,105 +170,29 @@ vgbinLedit->addButton( group1, this, SLOT(getVgExec()) ); connect(vgbinLedit, SIGNAL(returnPressed()), this, SIGNAL(apply())); -//TODO -// vk_assert( m_itemList.count() <= VALKYRIE::NUM_OPTS ); -} - - -void ValkyrieOptionsPage::setupLayout() -{ - // Note: not using opt_widget->hlayout()'s as button width won't match qlabel width. - int i=0; - QGridLayout* grid = new QGridLayout( group1 ); - grid->setColumnStretch(0, 0); - grid->setColumnStretch(1, 1); - grid->setColumnStretch(2, 1); - grid->setColumnStretch(3, 1); - - grid->setRowMinimumHeight( i, lineHeight/2 ); // blank row - i++; - - // ------------------------------------------------------------ - // general prefs - grid->addWidget( m_itemList[VALKYRIE::TOOLTIP]->widget(), i,0, 1,2 ); - i++; - grid->addWidget( m_itemList[VALKYRIE::ICONTXT]->widget(), i,0, 1,2 ); - i++; - grid->addWidget( m_itemList[VALKYRIE::PALETTE]->widget(), i,0, 1,2 ); - i++; - - LeWidget* brwsrLedit = ((LeWidget*)m_itemList[VALKYRIE::BROWSER]); - grid->addWidget( brwsrLedit->button(), i, 0 ); - grid->addWidget( brwsrLedit->widget(), i, 1, 1,3 ); - i++; - - LeWidget* dirLogSave = ((LeWidget*)m_itemList[VALKYRIE::DFLT_LOGDIR]); - grid->addWidget( dirLogSave->button(), i, 0 ); - grid->addWidget( dirLogSave->widget(), i,1, 1,3 ); - i++; - - LeWidget* dirWorking = ((LeWidget*)m_itemList[VALKYRIE::WORKING_DIR]); - grid->addWidget( dirWorking->button(), i, 0 ); - grid->addWidget( dirWorking->widget(), i,1, 1,3 ); - i++; - - grid->addWidget( sep(group1), i,0, 1,4 ); - i++; - - - // ------------------------------------------------------------ - // fonts - LeWidget* fontGenSysLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_SYS]); - grid->addWidget( fontGenSysLedit->widget(), i,0, 1,4 ); - i++; - - LeWidget* fontGenLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_GEN_USR]); - grid->addWidget( fontGenLedit->button(), i, 0 ); - grid->addWidget( fontGenLedit->widget(), i,1, 1,3 ); - i++; - - LeWidget* fontToolLedit = ((LeWidget*)m_itemList[VALKYRIE::FNT_TOOL_USR]); - grid->addWidget( fontToolLedit->button(), i, 0 ); - grid->addWidget( fontToolLedit->widget(), i,1, 1,3 ); - i++; - - grid->addWidget( sep(group1), i,0, 1,4 ); - i++; - - - // ------------------------------------------------------------ - // core - grid->addLayout( m_itemList[VALKYRIE::SRC_LINES]->hlayout(), i,0, 1,4 ); - i++; - LeWidget* editLedit = ((LeWidget*)m_itemList[VALKYRIE::SRC_EDITOR]); + // core - layout + grid->addLayout( m_itemList[VALKYRIE::SRC_LINES]->hlayout(), i++,0, 1,4 ); grid->addWidget( editLedit->button(), i, 0 ); - grid->addWidget( editLedit->widget(), i,1, 1,3 ); - i++; + grid->addWidget( editLedit->widget(), i++,1, 1,3 ); - grid->setRowMinimumHeight( i, lineHeight ); // blank row - i++; + grid->setRowMinimumHeight( i++, lineHeight ); // blank row - LeWidget* binLedit = ((LeWidget*)m_itemList[VALKYRIE::BINARY]); - grid->addWidget( binLedit->button(), i, 0 ); - grid->addWidget( binLedit->widget(), i,1, 1,3 ); - i++; + grid->addWidget( binLedit->button(), i, 0 ); + grid->addWidget( binLedit->widget(), i++,1, 1,3 ); + grid->addWidget( binFlgsLedit->label(), i, 0 ); + grid->addWidget( binFlgsLedit->widget(), i++,1, 1,3 ); - LeWidget* binFlgsLedit = ((LeWidget*)m_itemList[VALKYRIE::BIN_FLAGS]); - grid->addWidget( binFlgsLedit->label(), i, 0 ); - grid->addWidget( binFlgsLedit->widget(), i,1, 1,3 ); - i++; + grid->setRowMinimumHeight( i++, lineHeight ); // blank row - grid->setRowMinimumHeight( i, lineHeight ); // blank row - i++; - - LeWidget* vgbinLedit = ((LeWidget*)m_itemList[VALKYRIE::VG_EXEC]); grid->addWidget( vgbinLedit->button(), i, 0 ); - grid->addWidget( vgbinLedit->widget(), i,1, 1,3 ); - i++; + grid->addWidget( vgbinLedit->widget(), i++,1, 1,3 ... [truncated message content] |
From: Zaar H. <ha...@ha...> - 2009-12-14 09:13:45
|
On Mon, Dec 14, 2009 at 11:01 AM, Fathi Boudra <fb...@gm...> wrote: >>> How's your Qt4? :-) > > hopefully, I'll find time to take a look ;) > >> I just hope it will made it until Debian freeze (I'm >> maintaining Valkyrie for Debian). > > You coud use Qt 4.5.3 from Sid or Qt 4.6.0 from experimental. > (I'm maintaining Qt for Debian :D ) By "it" in "it will made" I meant Valkyrie and not Qt4 :) > > cheers, > > Fathi > -- Zaar |
From: Fathi B. <fb...@gm...> - 2009-12-14 09:01:17
|
>> How's your Qt4? :-) hopefully, I'll find time to take a look ;) > I just hope it will made it until Debian freeze (I'm > maintaining Valkyrie for Debian). You coud use Qt 4.5.3 from Sid or Qt 4.6.0 from experimental. (I'm maintaining Qt for Debian :D ) cheers, Fathi |
From: Zaar H. <ha...@ha...> - 2009-12-14 07:46:41
|
On Mon, Dec 14, 2009 at 4:02 AM, Cerion Armour-Brown <ce...@ke...> wrote: > See below. > How's your Qt4? :-) Awful :-) I guess we'll have to wait until full-blown Qt4 version of Valkyrie, aren't we? I just hope it will made it until Debian freeze (I'm maintaining Valkyrie for Debian). > Cerion > > Zaar Hai wrote: >> >> Good day? Are there any plans for valkyrie to support valgring 3.5.x? >> Current 1.4.0 version does not seem to support it. >> >> > > > > > -------- Original Message -------- > Subject: Re: [Valgrind-users] Unable to install valkyrie-1.4.0 on > Ubuntu > Date: Wed, 09 Dec 2009 19:06:58 +0100 > From: Cerion Armour-Brown <ce...@ke...> > To: fb...@gm... > CC: val...@li... > References: <d81...@ma...> > <4B1...@va...> > <6a2...@ma...> > > > > Hi Fathi, > > I've moved this thread to the valgrind-valkyrie-dev list. > > Basic app framework is done, but still plenty to do: > - options processing: commandline, read/write to config file. > - static xml log parsing > - internal xml model > - xml view setup > - valgrind process driver > - incremental xml parsing -> feeding the internal xml model > > And all that x3 for the tools: memcheck | helgrind | ptrcheck. > > Am considering using XSD for the xml parsing and internal model, but that > may be more work than it's worth. > > How's your Qt4? ;-) > > Regards, > Cerion > > > Fathi Boudra wrote: >> >> On Mon, Dec 7, 2009 at 11:37 AM, Cerion <ce...@va...> wrote: >> >>> >>> Valkyrie currently only supports Qt3. I'm working on the port to Qt4, >>> but it's taking a while. >>> >> >> nice. The work seems done in branches/valkyrie_qt4port. >> what's the current status and what's missing ? >> >> >> ------------------------------------------------------------------------------ >> Join us December 9, 2009 for the Red Hat Virtual Experience, >> a free event focused on virtualization and cloud computing. Attend >> in-depth sessions from your desk. Your couch. Anywhere. >> http://p.sf.net/sfu/redhat-sfdev2dev >> _______________________________________________ >> Valgrind-users mailing list >> Val...@li... >> https://lists.sourceforge.net/lists/listinfo/valgrind-users >> >> > > > > -- Zaar |
From: Cerion Armour-B. <ce...@ke...> - 2009-12-14 02:03:05
|
See below. How's your Qt4? :-) Cerion Zaar Hai wrote: > Good day? Are there any plans for valkyrie to support valgring 3.5.x? > Current 1.4.0 version does not seem to support it. > > -------- Original Message -------- Subject: Re: [Valgrind-users] Unable to install valkyrie-1.4.0 on Ubuntu Date: Wed, 09 Dec 2009 19:06:58 +0100 From: Cerion Armour-Brown <ce...@ke...> To: fb...@gm... CC: val...@li... References: <d81...@ma...> <4B1...@va...> <6a2...@ma...> Hi Fathi, I've moved this thread to the valgrind-valkyrie-dev list. Basic app framework is done, but still plenty to do: - options processing: commandline, read/write to config file. - static xml log parsing - internal xml model - xml view setup - valgrind process driver - incremental xml parsing -> feeding the internal xml model And all that x3 for the tools: memcheck | helgrind | ptrcheck. Am considering using XSD for the xml parsing and internal model, but that may be more work than it's worth. How's your Qt4? ;-) Regards, Cerion Fathi Boudra wrote: > On Mon, Dec 7, 2009 at 11:37 AM, Cerion <ce...@va...> wrote: > >> Valkyrie currently only supports Qt3. I'm working on the port to Qt4, >> but it's taking a while. >> > > nice. The work seems done in branches/valkyrie_qt4port. > what's the current status and what's missing ? > > ------------------------------------------------------------------------------ > Join us December 9, 2009 for the Red Hat Virtual Experience, > a free event focused on virtualization and cloud computing. > Attend in-depth sessions from your desk. Your couch. Anywhere. > http://p.sf.net/sfu/redhat-sfdev2dev > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > > |
From: Zaar H. <ha...@ha...> - 2009-12-13 17:36:16
|
Good day? Are there any plans for valkyrie to support valgring 3.5.x? Current 1.4.0 version does not seem to support it. -- Zaar |