1
/****************************************************************************
2
** MainWindow implementation
3
** - the top-level application window
4
** --------------------------------------------------------------------------
6
** Copyright (C) 2000-2010, OpenWorks LLP. All rights reserved.
7
** <info@open-works.co.uk>
9
** This file is part of Valkyrie, a front-end for Valgrind.
11
** This file may be used under the terms of the GNU General Public
12
** License version 2.0 as published by the Free Software Foundation
13
** and appearing in the file COPYING included in the packaging of
16
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
17
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
****************************************************************************/
21
#include <QApplication>
23
#include <QColorGroup>
25
#include <QFileDialog>
26
#include <QInputDialog>
31
#include "mainwindow.h"
32
#include "toolview/memcheckview.h"
33
#include "toolview/helgrindview.h"
35
#include "help/help_about.h"
36
#include "help/help_context.h"
37
#include "help/help_urls.h"
38
#include "options/vk_option.h"
39
#include "objects/tool_object.h"
40
#include "utils/vk_config.h"
41
#include "utils/vk_messages.h"
42
#include "utils/vk_utils.h"
45
/***************************************************************************/
48
\brief This provides the core QMainWindow class for the application.
50
This class provides the basis for the application, and defines the
51
layout which is extended upon by the ToolViews.
53
The centralWidget is a ToolViewStack, which provides a stack of ToolViews.
54
Multiple ToolViews (one for each valgrind tool-type) can thus be opened,
55
without interfering with each other.
57
Basic functionality is provided in the menus and toolbars, and this is
58
extended upon by the (valgrind tool) ToolView interfaces.
60
\sa ToolViewStack, ToolView
64
Constructs a MainWindow with the given parent.
66
MainWindow::MainWindow( Valkyrie* vk )
68
valkyrie( vk ), toolViewStack( 0 ), statusLabel( 0 ),
69
handBook( 0 ), optionsDialog( 0 )
71
setObjectName( QString::fromUtf8( "MainWindowClass" ) );
72
QString title = VkCfg::appName();
73
title.replace( 0, 1, title[0].toUpper() );
74
setWindowTitle( title );
76
lastAppFont = qApp->font();
77
lastPalette = qApp->palette();
80
icon_vk.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/valkyrie.xpm" ) ), QIcon::Normal, QIcon::Off );
81
setWindowIcon( icon_vk );
83
// handbook: init before menubar / toolbar
84
handBook = new HandBook();
92
setStatus( "Status message goes here..." );
94
// functions for dealing with config updates
95
VkOption* opt = valkyrie->getOption( VALKYRIE::ICONTXT );
96
connect( opt, SIGNAL( valueChanged() ), this, SLOT( showLabels() ) );
97
opt = valkyrie->getOption( VALKYRIE::TOOLTIP );
98
connect( opt, SIGNAL( valueChanged() ), this, SLOT( showToolTips() ) );
99
opt = valkyrie->getOption( VALKYRIE::FNT_GEN_SYS );
100
connect( opt, SIGNAL( valueChanged() ), this, SLOT( setGenFont() ) );
101
opt = valkyrie->getOption( VALKYRIE::FNT_GEN_USR );
102
connect( opt, SIGNAL( valueChanged() ), this, SLOT( setGenFont() ) );
103
opt = valkyrie->getOption( VALKYRIE::FNT_TOOL_USR );
104
connect( opt, SIGNAL( valueChanged() ), this, SLOT( setToolFont() ) );
105
opt = valkyrie->getOption( VALKYRIE::PALETTE );
106
connect( opt, SIGNAL( valueChanged() ), this, SLOT( setPalette() ) );
114
updateEventFilters( this );
115
updateEventFilters( handBook );
120
Destroys this widget, and frees any allocated resources.
122
MainWindow::~MainWindow()
124
// cerr << "MainWindow::~MainWindow()" << endl;
127
delete toolViewStack;
129
// Save window position to config.
130
vkCfgGlbl->setValue( "mainwindow_size", size() );
131
vkCfgGlbl->setValue( "mainwindow_pos", pos() );
134
// handbook has no parent, so have to delete it.
141
Allow a tool to insert a menu into the main menuBar.
142
A tool can't do this directly via it's parent pointer, as it needs access
143
to private vars for positioning within the menu.
145
\sa removeToolMenuAction()
147
void MainWindow::insertToolMenuAction( QAction* action )
149
menuBar->insertAction( menuHelp->menuAction(), action );
154
Allow a tool to remove a (previously inserted) menu from the main menuBar.
155
A tool could do this directly via 'parent', but insert can't be
156
done directly, so use this function for consistency.
158
\sa insertToolMenuAction()
160
void MainWindow::removeToolMenuAction( QAction* action )
162
menuBar->removeAction( action );
167
Setup the basic interface layout.
169
void MainWindow::setupLayout()
171
resize( vkCfgGlbl->value( "mainwindow_size", QSize( 600, 600 ) ).toSize() );
172
move( vkCfgGlbl->value( "mainwindow_pos", QPoint( 400, 0 ) ).toPoint() );
174
toolViewStack = new ToolViewStack( this );
175
setCentralWidget( toolViewStack );
180
Setup the top-level actions.
182
void MainWindow::setupActions()
185
// act->setShortcut( tr("Ctrl+XXX") );
187
actFile_NewProj = new QAction( this );
188
actFile_NewProj->setObjectName( QString::fromUtf8( "actFile_NewProj" ) );
189
actFile_NewProj->setText( tr( "&New Project..." ) );
190
actFile_NewProj->setToolTip( tr( "Create a project to save your configuration" ) );
192
icon_newproj.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/filenew.png" ) ),
193
QIcon::Normal, QIcon::Off );
194
actFile_NewProj->setIcon( icon_newproj );
195
connect( actFile_NewProj, SIGNAL( triggered() ), this, SLOT( createNewProject() ) );
197
actFile_OpenProj = new QAction( this );
198
actFile_OpenProj->setObjectName( QString::fromUtf8( "actFile_OpenProj" ) );
199
actFile_OpenProj->setText( tr( "&Open Project..." ) );
200
actFile_OpenProj->setToolTip( tr( "Open an existing project to load a saved configuration" ) );
202
icon_openproj.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/folder_blue.png" ) ),
203
QIcon::Normal, QIcon::Off );
204
actFile_OpenProj->setIcon( icon_openproj );
205
connect( actFile_OpenProj, SIGNAL( triggered() ), this, SLOT( openProject() ) );
207
for (int i = 0; i < MaxRecentProjs; ++i) {
208
actFile_RecentProjs[i] = new QAction(this);
209
actFile_RecentProjs[i]->setVisible(false);
210
connect(actFile_RecentProjs[i], SIGNAL(triggered()), this, SLOT( openRecentProject() ));
213
actFile_SaveAs = new QAction( this );
214
actFile_SaveAs->setObjectName( QString::fromUtf8( "actFile_SaveAs" ) );
215
actFile_SaveAs->setText( tr( "Save &As..." ) );
216
actFile_SaveAs->setToolTip( tr( "Save current configuration to a new project" ) );
218
icon_saveas.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/filesaveas.png" ) ),
219
QIcon::Normal, QIcon::Off );
220
actFile_SaveAs->setIcon( icon_saveas );
221
connect( actFile_SaveAs, SIGNAL( triggered() ), this, SLOT( saveAsProject() ) );
223
actFile_Close = new QAction( this );
224
actFile_Close->setObjectName( QString::fromUtf8( "actFile_Close" ) );
225
actFile_Close->setToolTip( tr( "Close the currently active tool" ) );
226
actFile_Close->setText( tr( "&Close Tool" ) );
227
connect( actFile_Close, SIGNAL( triggered() ), this, SLOT( closeToolView() ) );
229
actFile_Exit = new QAction( this );
230
actFile_Exit->setObjectName( QString::fromUtf8( "actFile_Exit" ) );
231
actFile_Exit->setText( tr( "E&xit" ) );
232
actFile_Exit->setToolTip( tr( "Exit Valkyrie" ) );
234
icon_exit.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/exit.png" ) ),
235
QIcon::Normal, QIcon::Off );
236
actFile_Exit->setIcon( icon_exit );
237
connect( actFile_Exit, SIGNAL( triggered() ), qApp, SLOT( closeAllWindows() ) );
239
actEdit_Options = new QAction( this );
240
actEdit_Options->setObjectName( QString::fromUtf8( "actEdit_Options" ) );
241
actEdit_Options->setText( tr( "O&ptions" ) );
242
actEdit_Options->setToolTip( tr( "Open the options-editing window" ) );
244
icon_options.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/gear.png" ) ),
245
QIcon::Normal, QIcon::Off );
246
actEdit_Options->setIcon( icon_options );
247
connect( actEdit_Options, SIGNAL( triggered() ), this, SLOT( openOptions() ) );
249
actProcess_Run = new QAction( this );
250
actProcess_Run->setObjectName( QString::fromUtf8( "actProcess_Run" ) );
251
actProcess_Run->setText( tr( "&Run" ) );
252
actProcess_Run->setToolTip( tr( "Run Valgrind with the currently active tool" ) );
253
actProcess_Run->setShortcut( QString::fromUtf8( "Ctrl+R" ) );
255
icon_run.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/valgrind_run.png" ) ),
256
QIcon::Normal, QIcon::Off );
257
actProcess_Run->setIcon( icon_run );
258
actProcess_Run->setIconVisibleInMenu( true );
259
connect( actProcess_Run, SIGNAL( triggered() ), this, SLOT( runValgrind() ) );
261
actProcess_Stop = new QAction( this );
262
actProcess_Stop->setObjectName( QString::fromUtf8( "actProcess_Stop" ) );
263
actProcess_Stop->setText( tr( "S&top" ) );
264
actProcess_Stop->setToolTip( tr( "Stop Valgrind" ) );
266
icon_stop.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/valgrind_stop.png" ) ),
267
QIcon::Normal, QIcon::Off );
268
actProcess_Stop->setIcon( icon_stop );
269
connect( actProcess_Stop, SIGNAL( triggered() ), this, SLOT( stopTool() ) );
271
actHelp_Handbook = new QAction( this );
272
actHelp_Handbook->setObjectName( QString::fromUtf8( "actHelp_Handbook" ) );
273
actHelp_Handbook->setText( tr( "Handbook" ) );
274
actHelp_Handbook->setToolTip( tr( "Open the Valkyrie Handbook" ) );
275
actHelp_Handbook->setShortcut( QString::fromUtf8( "F1" ) );
277
icon_handbook.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/tb_handbook_help.xpm" ) ), QIcon::Normal, QIcon::Off );
278
actHelp_Handbook->setIcon( icon_handbook );
279
connect( actHelp_Handbook, SIGNAL( triggered() ), this, SLOT( openHandBook() ) );
281
actHelp_About_Valkyrie = new QAction( this );
282
actHelp_About_Valkyrie->setObjectName( QString::fromUtf8( "actHelp_About_Valkyrie" ) );
283
actHelp_About_Valkyrie->setText( tr( "About Valkyrie" ) );
284
// actHelp_About_Valkyrie->setMenuRole( QAction::AboutRole );
285
connect( actHelp_About_Valkyrie, SIGNAL( triggered() ), this, SLOT( openAboutVk() ) );
287
actHelp_About_Qt = new QAction( this );
288
actHelp_About_Qt->setObjectName( QString::fromUtf8( "actHelp_About_Qt" ) );
289
actHelp_About_Qt->setText( tr( "About Qt" ) );
290
// actHelp_About_Qt->setMenuRole( QAction::AboutQtRole );
291
connect( actHelp_About_Qt, SIGNAL( triggered() ), qApp, SLOT( aboutQt() ) );
293
actHelp_License = new QAction( this );
294
actHelp_License->setObjectName( QString::fromUtf8( "actHelp_License" ) );
295
actHelp_License->setText( tr( "License" ) );
296
connect( actHelp_License, SIGNAL( triggered() ), this, SLOT( openAboutLicense() ) );
298
actHelp_Support = new QAction( this );
299
actHelp_Support->setObjectName( QString::fromUtf8( "actHelp_Support" ) );
300
actHelp_Support->setText( tr( "Support" ) );
301
connect( actHelp_Support, SIGNAL( triggered() ), this, SLOT( openAboutSupport() ) );
304
// ------------------------------------------------------------
305
// Tool actions - exclusive selection group
306
toolActionGroup = new QActionGroup( this );
307
//TODO: if we make it exclusive, then we can't close all toolviews and have none selected... can we?
308
//toolActionGroup->setExclusive( true );
309
connect( toolActionGroup, SIGNAL( triggered( QAction* ) ),
310
this, SLOT( toolGroupTriggered( QAction* ) ) );
313
icon_bullet.addPixmap( QPixmap( QString::fromUtf8( ":/vk_icons/icons/tb_mainwin_blackbullet.xpm" ) ),
314
QIcon::Normal, QIcon::Off );
316
ToolObjList tools = valkyrie->valgrind()->getToolObjList();
317
vk_assert( tools.size() > 0 );
318
foreach( ToolObject * tool, tools ) {
319
QString toolname = tool->objectName();
320
toolname[0] = toolname[0].toUpper();
322
QAction* actTool = new QAction( this );
323
actTool->setObjectName( "actTool_" + toolname );
324
actTool->setCheckable( true );
325
actTool->setIcon( icon_bullet );
326
actTool->setIconVisibleInMenu( true );
327
actTool->setText( toolname );
328
actTool->setProperty( "toolId", tool->getToolId() );
330
toolActionGroup->addAction( actTool );
333
// ------------------------------------------------------------
334
// initial enables/disables
335
updateVgButtons( false );
342
void MainWindow::setupMenus()
344
// ------------------------------------------------------------
346
menuBar = new QMenuBar( this );
347
menuBar->setObjectName( QString::fromUtf8( "menuBar" ) );
348
menuBar->setGeometry( QRect( 0, 0, 496, 25 ) );
349
this->setMenuBar( menuBar );
351
menuFile = new QMenu( menuBar );
352
menuFile->setObjectName( QString::fromUtf8( "menuFile" ) );
353
menuFile->setTitle( tr( "&File" ) );
354
menuRecentProjs = new QMenu( menuBar );
355
menuRecentProjs->setObjectName( QString::fromUtf8( "menuRecentProjs" ) );
356
menuRecentProjs->setTitle( tr( "Recent Projects" ) );
357
menuEdit = new QMenu( menuBar );
358
menuEdit->setObjectName( QString::fromUtf8( "menuEdit" ) );
359
menuEdit->setTitle( tr( "&Edit" ) );
360
menuProcess = new QMenu( menuBar );
361
menuProcess->setObjectName( QString::fromUtf8( "menuProcess" ) );
362
menuProcess->setTitle( tr( "&Process" ) );
363
menuTools = new QMenu( menuBar );
364
menuTools->setObjectName( QString::fromUtf8( "menuTools" ) );
365
menuTools->setTitle( tr( "&Tools" ) );
366
menuHelp = new QMenu( menuBar );
367
menuHelp->setObjectName( QString::fromUtf8( "menuHelp" ) );
368
menuHelp->setTitle( tr( "Help" ) );
370
// application-wide context help button
371
ContextHelpAction* ctxtHlpAction = new ContextHelpAction( this, handBook );
372
ctxtHlpAction->setText( tr( "Context Help" ) );
375
// ------------------------------------------------------------
376
// Add actions to menus
377
menuBar->addAction( menuFile->menuAction() );
378
menuBar->addAction( menuEdit->menuAction() );
379
menuBar->addAction( menuProcess->menuAction() );
380
menuBar->addAction( menuTools->menuAction() );
381
menuBar->addAction( menuHelp->menuAction() );
383
menuFile->addAction( actFile_NewProj );
384
menuFile->addAction( actFile_OpenProj );
385
menuFile->addMenu( menuRecentProjs );
386
menuFile->addAction( actFile_SaveAs );
387
menuFile->addSeparator();
388
menuFile->addAction( actFile_Close );
389
menuFile->addSeparator();
390
menuFile->addAction( actFile_Exit );
392
for (int i = 0; i < MaxRecentProjs; ++i) {
393
menuRecentProjs->addAction( actFile_RecentProjs[i]);
395
updateActionsRecentProjs();
397
menuEdit->addAction( actEdit_Options );
399
menuProcess->addAction( actProcess_Run );
400
menuProcess->addAction( actProcess_Stop );
402
foreach( QAction * actTool, toolActionGroup->actions() )
403
menuTools->addAction( actTool );
405
menuHelp->addAction( ctxtHlpAction );
406
menuHelp->addSeparator();
407
menuHelp->addAction( actHelp_Handbook );
408
menuHelp->addSeparator();
409
menuHelp->addAction( actHelp_About_Valkyrie );
410
menuHelp->addAction( actHelp_About_Qt );
411
menuHelp->addSeparator();
412
menuHelp->addAction( actHelp_License );
413
menuHelp->addAction( actHelp_Support );
418
Setup the main toolbars
420
void MainWindow::setupToolBars()
422
// ------------------------------------------------------------
423
// Basic toolbar setup
424
mainToolBar = new QToolBar( this );
425
mainToolBar->setObjectName( QString::fromUtf8( "mainToolBar" ) );
426
this->addToolBar( Qt::TopToolBarArea, mainToolBar );
428
// ------------------------------------------------------------
429
// Add actions to toolbar
430
mainToolBar->addAction( actProcess_Run );
431
mainToolBar->addAction( actProcess_Stop );
433
// Ensures further toolbars are added underneath.
434
// TODO: hmm. if add & remove & add toolbars, the toolbar gets added to the side, not under.
435
// addToolBarBreak();
440
Setup the bottom status bar.
441
This shows status messages from all interfaces: both the main interface
442
and tool-specific interfaces
444
void MainWindow::setupStatusBar()
446
// ------------------------------------------------------------
447
// Basic statusbar setup
448
mainStatusBar = this->statusBar();
449
mainStatusBar->setObjectName( QString::fromUtf8( "mainStatusBar " ) );
451
statusLabel = new QLabel( mainStatusBar );
452
statusLabel->setObjectName( QString::fromUtf8( "statusLabel " ) );
453
// statusLabel->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
454
mainStatusBar->addPermanentWidget( statusLabel, 10 );
459
Install our eventFilter for given widgets and all its children.
460
Just to support tooltips suppression - apparently the only way :-(
462
void MainWindow::updateEventFilters( QObject* obj )
464
foreach( QObject * obj, obj->children() ) {
465
obj->installEventFilter( this );
466
updateEventFilters( obj );
472
EventFilter: installed for all widgets.
473
If configure option given, suppress all ToolTips
475
bool MainWindow::eventFilter( QObject* obj, QEvent* e )
477
if ( !fShowToolTips && e->type() == QEvent::ToolTip ) {
482
// pass the event on to the parent class
483
return QMainWindow::eventFilter( obj, e );
489
Show a requested ToolView, from the given \a toolId.
491
The ToolViews are created and shown on demand.
493
void MainWindow::showToolView( VGTOOL::ToolID toolId )
495
vk_assert( toolId > VGTOOL::ID_NULL );
497
if ( toolViewStack->currentToolId() == toolId ) {
498
// already loaded and visible.
502
// else: toolview may still be loaded, but not visible...
504
ToolView* nextView = toolViewStack->findView( toolId );
506
if ( nextView == 0 ) {
507
// toolview not loaded => load it.
510
ToolObject* nextTool = valkyrie->valgrind()->getToolObj( toolId );
511
vk_assert( nextTool != 0 );
513
// Factory Method to create views
514
nextView = nextTool->createView( this );
515
vk_assert( nextView != 0 );
517
connect( nextTool, SIGNAL( running( bool ) ),
518
this, SLOT( updateVgButtons( bool ) ) );
519
connect( nextTool, SIGNAL( message( QString ) ),
520
this, SLOT( setStatus( QString ) ) );
522
// Set a vg logfile. Loading done by tool_object
523
connect( nextView, SIGNAL( logFileChosen( QString ) ),
524
this, SLOT( setLogFile( QString ) ) );
526
//TODO: perhaps bring ToolObject::fileSaveDialog() here too...
527
// + ToolObject::saveParsedOutput()...
529
// view starts tool processes via this signal
530
connect( nextView, SIGNAL( run( VGTOOL::ToolProcessId ) ),
531
this, SLOT( runTool( VGTOOL::ToolProcessId ) ) );
533
// add view to the stack
534
toolViewStack->addView( nextView );
536
// widgets (menubar, toolbar) have been added: update event filters
537
updateEventFilters( this );
540
// make sure the toolview is made visible:
542
toolViewStack->raiseView( nextView );
543
setToggles( toolId );
548
slot, connected to a tool object's signal running(bool)
550
void MainWindow::updateVgButtons( bool running )
552
actProcess_Run->setEnabled( !running );
553
actProcess_Stop->setEnabled( running );
558
Toggles the various actions depending on the current toolview and internal state.
560
For example, if a ToolView is closed, and another on the ToolViewStack
561
is brought forward, the various actions must be updated to correspond
562
with the state of the new ToolView.
564
void MainWindow::setToggles( VGTOOL::ToolID toolId )
566
if ( toolId == VGTOOL::ID_NULL ) {
567
// no more tool views
569
// disable all actions in the tool actiongroup
570
// TODO: nicer way to do this? - maybe connect sig/slot toolview to action?
571
foreach( QAction * actTool, toolActionGroup->actions() )
572
actTool->setChecked( false );
574
actFile_Close->setEnabled( false );
575
actProcess_Run->setEnabled( false );
576
actProcess_Stop->setEnabled( false );
579
// at least one toolview found: update state
581
// enable the relevant action in the tool actiongroup
582
// TODO: nicer way to do this? - maybe connect sig/slot toolview to action?
583
foreach( QAction * actTool, toolActionGroup->actions() ) {
584
VGTOOL::ToolID toolId_action =
585
( VGTOOL::ToolID )actTool->property( "toolId" ).toInt();
587
if ( toolId_action == toolId ) {
588
actTool->setChecked( true );
591
actTool->setChecked( false );
594
//TODO: review toggle functionality.
597
actFile_Close->setEnabled( true );
598
updateVgButtons( false );
603
void MainWindow::showLabels()
605
VkOption* opt = valkyrie->getOption( VALKYRIE::ICONTXT );
606
bool show = vkCfgProj->value( opt->configKey() ).toBool();
609
setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
612
setToolButtonStyle( Qt::ToolButtonIconOnly );
617
void MainWindow::showToolTips()
619
VkOption* opt = valkyrie->getOption( VALKYRIE::TOOLTIP );
620
fShowToolTips = vkCfgProj->value( opt->configKey() ).toBool();
624
void MainWindow::setGenFont()
626
// TODO: qApp->setFont will be called twice if FNT_GEN_USR && FNT_GEN_SYS
627
// are both modified together - do we care?
630
VkOption* opt = valkyrie->getOption( VALKYRIE::FNT_GEN_SYS );
631
bool useVkSysFont = vkCfgProj->value( opt->configKey() ).toBool();
633
if ( useVkSysFont ) {
637
lastAppFont = qApp->font();
638
VkOption* opt = valkyrie->getOption( VALKYRIE::FNT_GEN_USR );
639
QString str_fnt = vkCfgProj->value( opt->configKey() ).toString();
640
fnt.fromString( str_fnt );
643
if ( qApp->font() != fnt ) {
644
qApp->setFont( fnt );
648
void MainWindow::setToolFont()
651
VkOption* opt = valkyrie->getOption( VALKYRIE::FNT_TOOL_USR );
652
QString str = vkCfgProj->value( opt->configKey() ).toString();
653
fnt.fromString( str );
655
// set font for all tool views
656
foreach( ToolObject * tool, valkyrie->valgrind()->getToolObjList() ) {
657
ToolView* tv = tool->view();
660
tv->setToolFont( fnt );
665
void MainWindow::setPalette()
668
VkOption* opt = valkyrie->getOption( VALKYRIE::PALETTE );
669
bool useVkPalette = vkCfgProj->value( opt->configKey() ).toBool();
671
if ( !useVkPalette ) {
675
lastPalette = qApp->palette();
677
QColor bg = vkCfgGlbl->value( "colour_background" ).value<QColor>();
678
QColor base = vkCfgGlbl->value( "colour_base" ).value<QColor>();
679
QColor text = vkCfgGlbl->value( "colour_text" ).value<QColor>();
680
QColor dkgray = vkCfgGlbl->value( "colour_dkgray" ).value<QColor>();
681
QColor hilite = vkCfgGlbl->value( "colour_highlight" ).value<QColor>();
683
// anything not ok -> return default qApp palette:
684
if ( bg.isValid() && base.isValid() && text.isValid() &&
685
dkgray.isValid() && hilite.isValid() ) {
687
pal = QPalette( bg, bg );
688
// 3 colour groups: active, inactive, disabled
689
// bg colour for text entry widgets
690
pal.setColor( QPalette::Active, QPalette::Base, base );
691
pal.setColor( QPalette::Inactive, QPalette::Base, base );
692
pal.setColor( QPalette::Disabled, QPalette::Base, base );
694
pal.setColor( QPalette::Active, QPalette::Window, bg );
695
pal.setColor( QPalette::Inactive, QPalette::Window, bg );
696
pal.setColor( QPalette::Disabled, QPalette::Window, bg );
698
pal.setColor( QPalette::Active, QPalette::Button, bg );
699
pal.setColor( QPalette::Inactive, QPalette::Button, bg );
700
pal.setColor( QPalette::Disabled, QPalette::Button, bg );
701
// general fg colour - same as Text
702
pal.setColor( QPalette::Active, QPalette::WindowText, text );
703
pal.setColor( QPalette::Inactive, QPalette::WindowText, text );
704
pal.setColor( QPalette::Disabled, QPalette::WindowText, dkgray );
706
pal.setColor( QPalette::Active, QPalette::Text, text );
707
pal.setColor( QPalette::Inactive, QPalette::Text, text );
708
pal.setColor( QPalette::Disabled, QPalette::Text, dkgray );
709
// same as text and fg
710
pal.setColor( QPalette::Active, QPalette::ButtonText, text );
711
pal.setColor( QPalette::Inactive, QPalette::ButtonText, text );
712
pal.setColor( QPalette::Disabled, QPalette::ButtonText, dkgray );
714
pal.setColor( QPalette::Active, QPalette::Highlight, hilite );
715
pal.setColor( QPalette::Inactive, QPalette::Highlight, hilite );
716
pal.setColor( QPalette::Disabled, QPalette::Highlight, hilite );
717
// contrast with highlight
718
pal.setColor( QPalette::Active, QPalette::HighlightedText, base );
719
pal.setColor( QPalette::Inactive, QPalette::HighlightedText, base );
720
pal.setColor( QPalette::Disabled, QPalette::HighlightedText, base );
724
if ( qApp->palette() != pal ) {
725
qApp->setPalette( pal );
731
set logfile name to be loaded
733
void MainWindow::setLogFile( QString logFilename )
735
VkOption* opt = valkyrie->getOption( VALKYRIE::VIEW_LOG );
736
opt->updateConfig( logFilename );
741
Create a new project based on the default-project settings.
742
Save configuration in a new project file.
743
Previous settings are discarded.
745
void MainWindow::createNewProject()
747
// TODO: put dir & name choice in one dialog.
749
// Choose project directory
750
QString dir = QFileDialog::getExistingDirectory( this, "Choose Project Directory", "./",
751
QFileDialog::ShowDirsOnly |
752
QFileDialog::DontResolveSymlinks );
754
if ( dir.isEmpty() || dir.isNull() ) {
758
// Choose project name
763
proj_name = QInputDialog::getText( this, "Choose New Project Name",
764
"Project Name:", QLineEdit::Normal,
767
if ( !ok ) { // User chaged their minds.
771
if ( !proj_name.isEmpty() ) { // loop if empty name.
776
// TODO: check if exists, may overwrite, etc...
778
QString proj_fname = dir + "/" + proj_name + "." + VkCfg::filetype();
779
vkCfgProj->createNewProject( proj_fname );
783
setCurrentProject( proj_fname );
788
Open an existing project.
790
void MainWindow::openProject()
792
QString filter = QString("*.") + VkCfg::filetype();
793
QString proj_fname = QFileDialog::getOpenFileName( this, "Open Valkyrie Project",
794
"./", "Valkyrie Projects (" + filter + ")" );
796
if ( proj_fname.isEmpty() || proj_fname.isNull() ) {
801
vkCfgProj->openProject( proj_fname );
805
setCurrentProject( proj_fname );
810
Open a recent existing project.
812
void MainWindow::openRecentProject()
814
QAction *action = qobject_cast<QAction *>(sender());
816
QString proj_fname = action->data().toString();
817
vkCfgProj->openProject( proj_fname );
821
setCurrentProject( proj_fname );
827
Save current settings to a new project.
829
void MainWindow::saveAsProject()
831
// TODO: put dir & name choice in one dialog.
833
// Choose project directory
834
QString dir = QFileDialog::getExistingDirectory( this, "Choose Project Directory", "./",
835
QFileDialog::ShowDirsOnly |
836
QFileDialog::DontResolveSymlinks );
838
if ( dir.isEmpty() || dir.isNull() ) {
842
// Choose project name
847
proj_name = QInputDialog::getText( this, "Enter Project Name",
848
"Project Name:", QLineEdit::Normal,
851
if ( !ok ) { // User chaged their minds.
855
if ( !proj_name.isEmpty() ) { // loop if empty name.
861
// TODO: check if exists may overwrite, etc...
862
QString proj_fname = dir + "/" + proj_name + "." + VkCfg::filetype();
863
vkCfgProj->saveProjectAs( proj_fname );
867
setCurrentProject( proj_fname );
873
- update the config with the new project name
874
- update the actions to keep in sync.
876
void MainWindow::setCurrentProject(const QString &projName)
878
#if 0 // TODO: maybe future, but then do consistently everywhere...
880
if (curFile.isEmpty())
881
setWindowTitle(tr("Recent Files"));
883
setWindowTitle(tr("%1 - %2").arg(strippedName(curFile))
884
.arg(tr("Recent Files")));
887
QStringList files = vkCfgGlbl->value( "recent_projects" )
888
.toString().split( VkCfg::sepChar(), QString::SkipEmptyParts );
889
files.removeAll( projName );
890
files.prepend( projName );
891
while (files.size() > MaxRecentProjs) {
895
vkCfgGlbl->setValue( "recent_projects", files.join( VkCfg::sepChar() ) );
898
updateActionsRecentProjs();
903
Update the actions for the list of recent projects
905
void MainWindow::updateActionsRecentProjs()
907
QStringList files = vkCfgGlbl->value( "recent_projects" )
908
.toString().split( VkCfg::sepChar(), QString::SkipEmptyParts );
909
int numRecentProjs = qMin(files.size(), (int)MaxRecentProjs);
911
for (int i = 0; i < numRecentProjs; ++i) {
912
QString text = tr("&%1 %2").arg( i+1 )
913
.arg( QFileInfo( files[i] ).fileName() );
914
actFile_RecentProjs[i]->setText(text);
915
actFile_RecentProjs[i]->setData(files[i]);
916
actFile_RecentProjs[i]->setVisible(true);
918
for (int j = numRecentProjs; j < MaxRecentProjs; ++j) {
919
actFile_RecentProjs[j]->setVisible(false);
925
Close the currently-shown ToolView.
927
Calls the ToolViewStack to remove the toolview from the stack,
928
and clean up after it (update the menus, etc).
930
void MainWindow::closeToolView()
932
ToolView* tv = toolViewStack->currentView();
934
// if there ain't no toolview, we cain't do much
936
cerr << "MainWindow::closeToolView(): No toolview!" << endl;
940
cerr << "MainWindow::closeToolView(): " <<
941
tv->objectName().toLatin1().data() << endl;
943
toolViewStack->removeView( tv );
945
// current toolview will now have changed (maybe to NULL)
946
setToggles( toolViewStack->currentToolId() );
951
Set the status message for the main status bar
953
void MainWindow::setStatus( QString msg )
955
statusLabel->setText( "Vk: " + msg );
962
Calls showToolView() for a chosen valgrind tool.
964
This slot is called by a trigger of the tool actionGroup, which is
965
setup for the "Tools" menu.
966
We make use of the QAction::property to store the toolId,
967
and when one of the tools is selected, this id is used to call up
968
the corresponding ToolView on the TooObject.
970
void MainWindow::toolGroupTriggered( QAction* action )
972
VGTOOL::ToolID toolId = ( VGTOOL::ToolID )action->property( "toolId" ).toInt();
974
// cerr << "MainWindow::toolGroupTriggered() for toolview " << toolId << endl;
976
showToolView( toolId );
981
Open the Options dialog.
983
void MainWindow::openOptions()
985
// TODO: decide whether really want a modeless dialog: is this functionality useful/used?
986
// if non-modal, rem to reinit all opt widgets when a project is created/opened
988
if ( !optionsDialog ) {
989
optionsDialog = new VkOptionsDialog( this );
992
optionsDialog->show();
993
optionsDialog->raise();
994
optionsDialog->activateWindow();
996
VkOptionsDialog optionsDlg( this );
998
updateEventFilters( &optionsDlg );
1006
Run the valgrind tool process.
1008
void MainWindow::runTool( VGTOOL::ToolProcessId procId )
1010
VGTOOL::ToolID tId = toolViewStack->currentToolId();
1011
cerr << "MainWindow::runTool( tool: " << tId
1012
<< ", proc: " << procId << " )" << endl;
1014
vk_assert( procId > VGTOOL::PROC_NONE );
1016
// don't come in here if there's no current view
1017
if ( !toolViewStack->isVisible() ) {
1018
//This should never happen... assert?
1019
cerr << "Error: No toolview visible!" << endl;
1023
if ( procId == VGTOOL::PROC_VALGRIND ) {
1024
// Valkyrie may have been started with no executable
1025
// specified. If so, show msgbox, then options dialog
1026
if ( vkCfgProj->value( "valkyrie/binary" ).toString().isEmpty() ) {
1028
vkInfo( this, "Run Valgrind: No program specified",
1029
"Please specify (via Options->Valkyrie->Binary)<br>"
1030
"the path to the program you wish to run, along<br>"
1031
"with any arguments required" );
1038
// last process might not be done ...
1039
if ( !valkyrie->queryToolDone( tId ) ) {
1040
cerr << "Warning: Last process not finished" << endl;
1044
if ( !valkyrie->runTool( tId, procId ) ) {
1045
//TODO: make sure all fail cases have given a message to the user already
1047
VK_DEBUG( "Failed to complete execution for toolId (%d), procId (%d)",
1054
run valgrind --tool=<current_tool> + flags + executable
1056
void MainWindow::runValgrind()
1058
runTool( VGTOOL::PROC_VALGRIND );
1064
Stop the valgrind tool process.
1066
void MainWindow::stopTool()
1068
valkyrie->stopTool( toolViewStack->currentToolId() );
1073
Open the application handbook.
1075
void MainWindow::openHandBook()
1077
handBook->showYourself();
1082
Open the application About dialog.
1084
void MainWindow::openAboutVk()
1086
HelpAbout dlg( this, HELPABOUT::ABOUT_VK );
1092
Open the About-License dialog.
1094
void MainWindow::openAboutLicense()
1096
HelpAbout dlg( this, HELPABOUT::LICENSE );
1102
Open the About-Support dialog.
1104
void MainWindow::openAboutSupport()
1106
HelpAbout dlg( this, HELPABOUT::SUPPORT );