Part 13: New and Quit

Part 13: New and Quit


[<< Contents] [<< Prev] [Next >>]

Adding two new File menu options and a toolbar

In this part we will add two more File menu options, one to start a new simulation and another to quit the application. To help the user prevent losing work, both the options will offer the user the chance to save their current simulation data before proceeding. We will also add a toolbar giving quick access to the main user actions.

We only need to make enhancements to our MainWindow class to implement these changes. The toolbar will be implemented using QToolBar and to save effort instead of designing and drawing our own icons we will use some standard pixmaps provided by QStyle.

Enhancing the MainWindow

mainwindow.h

Add a public slot to receive the signal when user selects the menu action to start a new simulation.

  void fileNew();                     // start new simulation

And we will reimplement the virtual protected QMainWindow closeEvent function to check what should be done when our application receives a request to close.

protected:
  void closeEvent( QCloseEvent* );    // check if user really wants to exit

mainwindow.cpp

Include the header files for the QCloseEvent, QMessageBox, and QToolBar functionality.

#include <QCloseEvent>
#include <QMessageBox>
#include <QToolBar>

In the constructor above adding the open and save actions to the File menu, we add an action to start a new simulation.

  QAction* newAction     = fileMenu->addAction( "&New",              this, SLOT(fileNew()) );

And below adding the preview and print actions to the File menu, we add a separator and an action to quit the application. The quit action calls the QMainWindow slot close(). We also set the keyboard shortcut for the start a new simulation action.

  fileMenu->addSeparator();
                           fileMenu->addAction( "&Quit",             this, SLOT(close()) );
  newAction->setShortcut( QKeySequence::New );

In the constructor after we have created the undo stack we also create and populate the our application toolbar. As mentioned previously, to save ourselves time and effort, we use some standard QStyle pixmaps for our action icons. As the QStyle pixmaps are of different sizes, we get the size of one of the smaller standard pixmaps and set the toolbar to display all the icons at this size.

  // create toolbar, set icon size, and add actions
  QToolBar*   toolBar = addToolBar( "Standard" );
  QStyle*     style   = this->style();
  QSize       size    = style->standardIcon(QStyle::SP_DesktopIcon).actualSize( QSize(99,99) );
  toolBar->setIconSize( size );
  newAction->setIcon( style->standardIcon(QStyle::SP_DesktopIcon) );
  openAction->setIcon( style->standardIcon(QStyle::SP_DialogOpenButton) );
  saveAction->setIcon( style->standardIcon(QStyle::SP_DialogSaveButton) );
  previewAction->setIcon( style->standardIcon(QStyle::SP_FileDialogContentsView) );
  printAction->setIcon( style->standardIcon(QStyle::SP_ComputerIcon) );
  undoAction->setIcon( style->standardIcon(QStyle::SP_ArrowBack) );
  redoAction->setIcon( style->standardIcon(QStyle::SP_ArrowForward) );
  toolBar->addAction( newAction );
  toolBar->addAction( openAction );
  toolBar->addAction( saveAction );
  toolBar->addSeparator();
  toolBar->addAction( previewAction );
  toolBar->addAction( printAction );
  toolBar->addSeparator();
  toolBar->addAction( undoAction );
  toolBar->addAction( redoAction );

Now we can add the code for the start new simulation functionality. If there are no stations we are done already. Otherwise using a QMessageBox we give the user the chance to save their simulation data before creating a new blank scene.

/************************************** fileNew **************************************/

void  MainWindow::fileNew()
{
  // if no stations (only default top-left scene anchor) then nothing to do
  if ( m_scene->items().count() <= 1 ) return;

  // check if user wants to save before starting new simulation
  while (true)
    switch ( QMessageBox::warning( this, "QSimulate",
        "Do you want to save before starting new?",
        QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel ) )
    {
      case QMessageBox::Save:
        // if save not successful ask again
        if ( !fileSaveAs() ) break;

      case QMessageBox::Discard:
        // start new simulation
        {
          m_undoStack->clear();
          Scene*          newScene = new Scene( m_undoStack );
          QGraphicsView*  view     = dynamic_cast<QGraphicsView*>( centralWidget() );
          view->setScene( newScene );
          delete m_scene;
          m_scene = newScene;
        }
        return;

      default:    // "Cancel"
        return;
    }
}

We also add similar code for the reimplementation of the "closeEvent" virtual QMainWindow function. If there are no stations we can quit immediately. Otherwise using a QMessageBox we give the user the chance to save their simulation data before the application closes.

/************************************ closeEvent *************************************/

void  MainWindow::closeEvent( QCloseEvent* event )
{
  // if no stations (only default top-left scene anchor) exists then accept close event
  if ( m_scene->items().count() <= 1 )
  {
    event->accept();
    return;
  }

  // check if user wants to save before quitting
  while (true)
    switch ( QMessageBox::warning( this, "QSimulate",
        "Do you want to save before you quit?",
        QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel ) )
    {
      case QMessageBox::Save:
        // if save not successful ask again
        if ( !fileSaveAs() ) break;

      case QMessageBox::Discard:
        event->accept();
        return;

      default:    // "Cancel"
        event->ignore();
        return;
    }
}

Compile and run

The new code will automatically re-compile when you attempt to run the application. Play with the application and investigate the new functionality.


[<< Contents] [<< Prev] [Next >>]


Last updated 16-Aug-2008