# A.4. kscribble.cpp

       1 /***************************************************************************
       2                           kscribble.cpp  -  description
       3                              -------------------
       4     begin                : Mon Jan 31 11:05:05 CET 2000
       5     copyright            : (C) 2000 by Ralf Nolden
       6     email                : Ralf.Nolden@post.rwth-aachen.de
       7  ***************************************************************************/
       8
       9 /***************************************************************************
      10  *                                                                         *
      11  *   This program is free software; you can redistribute it and/or modify  *
      12  *   it under the terms of the GNU General Public License as published by  *
      13  *   the Free Software Foundation; either version 2 of the License, or     *
      14  *   (at your option) any later version.                                   *
      15  *                                                                         *
      16  ***************************************************************************/
      17
      18 // include files for QT
      19 #include <qdir.h>
      20 #include <qprinter.h>
      21 #include <qvbox.h>
      22 #include <qwhatsthis.h>
      23 #include <qtooltip.h>
      24 #include <qtoolbutton.h>
      25 #include <qimage.h>
      26 #include <qdragobject.h>
      27
      28
      29 // include files for KDE
      30 #include <kiconloader.h>
      31 #include <kmessagebox.h>
      32 #include <kfiledialog.h>
      33 #include <kcolordlg.h>
      34 #include <kmenubar.h>
      35 #include <klocale.h>
      36 #include <kconfig.h>
      37
      38 // application specific includes
      39 #include "kscribble.h"
      40 #include "kscribbleview.h"
      41 #include "kscribbledoc.h"
      42 #include "resource.h"
      43 #include "kpenbrushdlg.h"
      44
      45
      46 KScribbleApp::KScribbleApp()
      47 {
      48   config=kapp->config();
      49   printer = new QPrinter;
      50   untitledCount=0;
      51   pDocList = new QList<KScribbleDoc>();
      52   pDocList->setAutoDelete(true);
      53   setAcceptDrops(true);
      54
      55   ///////////////////////////////////////////////////////////////////
      56   // call inits to invoke all other construction parts
      57   initMenuBar();
      58   initToolBar();
      59   initStatusBar();
      60   initKeyAccel();
      61   initView();
      62
      63   readOptions();
      64
      65   ///////////////////////////////////////////////////////////////////
      66   // disable menu and toolbar items at startup
      67   disableCommand(ID_EDIT_UNDO);
      68 }
      69
      70 KScribbleApp::~KScribbleApp()
      71 {
      72   delete printer;
      73 }
      74
      75 void KScribbleApp::initKeyAccel()
      76 {
      77   keyAccel = new KAccel(this);
      78
      79   // fileMenu accelerators
      80   keyAccel->connectItem(KStdAccel::New, this, SLOT(slotFileNew()));
      81   keyAccel->connectItem(KStdAccel::Open, this, SLOT(slotFileOpen()));
      82   keyAccel->connectItem(KStdAccel::Save, this, SLOT(slotFileSave()));
      83   keyAccel->connectItem(KStdAccel::Close, this, SLOT(slotFileClose()));
      84   keyAccel->connectItem(KStdAccel::Print, this, SLOT(slotFilePrint()));
      85   keyAccel->connectItem(KStdAccel::Quit, this, SLOT(slotFileQuit()));
      86   // editMenu accelerators
      87   keyAccel->connectItem(KStdAccel::Cut, this, SLOT(slotEditCut()));
      88   keyAccel->connectItem(KStdAccel::Copy, this, SLOT(slotEditCopy()));
      89   keyAccel->connectItem(KStdAccel::Paste, this, SLOT(slotEditPaste()));
      90
      91   keyAccel->connectItem(KStdAccel::Help, this, SLOT(appHelpActivated()));
      92
      93   keyAccel->changeMenuAccel(pFileMenu, ID_FILE_NEW, KStdAccel::New);
      94   keyAccel->changeMenuAccel(pFileMenu, ID_FILE_OPEN, KStdAccel::Open);
      95   keyAccel->changeMenuAccel(pFileMenu, ID_FILE_SAVE, KStdAccel::Save);
      96   keyAccel->changeMenuAccel(pFileMenu, ID_FILE_CLOSE, KStdAccel::Close);
      97   keyAccel->changeMenuAccel(pFileMenu, ID_FILE_PRINT, KStdAccel::Print);
      98   keyAccel->changeMenuAccel(pFileMenu, ID_FILE_QUIT, KStdAccel::Quit);
      99
     100   keyAccel->changeMenuAccel(pEditMenu, ID_EDIT_CUT, KStdAccel::Cut);
     101   keyAccel->changeMenuAccel(pEditMenu, ID_EDIT_COPY, KStdAccel::Copy);
     102   keyAccel->changeMenuAccel(pEditMenu, ID_EDIT_PASTE, KStdAccel::Paste);
     103
     104   keyAccel->readSettings();
     105 }
     106
     107 void KScribbleApp::initMenuBar()
     108 {
     109   ///////////////////////////////////////////////////////////////////
     110   // MENUBAR
     111   pRecentFileMenu = new QPopupMenu(this);
     112   connect(pRecentFileMenu, SIGNAL(activated(int)), SLOT(slotFileOpenRecent(int)));
     113
     114   ///////////////////////////////////////////////////////////////////
     115   // menuBar entry file-Menu
     116   pFileMenu = new QPopupMenu(this);
     117   pFileMenu->insertItem(BarIcon("filenew"), i18n("&&;New"), ID_FILE_NEW);
     118   pFileMenu->insertItem(BarIcon("fileopen"), i18n("&&;Open..."), ID_FILE_OPEN);
     119   pFileMenu->insertItem(i18n("Open &&;recent"), pRecentFileMenu, ID_FILE_OPEN_RECENT);
     120
     121   pFileMenu->insertItem(i18n("&&;Close"), ID_FILE_CLOSE);
     122   pFileMenu->insertSeparator();
     123   pFileMenu->insertItem(BarIcon("filefloppy") ,i18n("&&;Save"), ID_FILE_SAVE);
     124   pFileMenu->insertItem(i18n("Save &&;As..."), ID_FILE_SAVE_AS);
     125   pFileMenu->insertSeparator();
     126   pFileMenu->insertItem(BarIcon("fileprint"), i18n("&&;Print..."), ID_FILE_PRINT);
     127   pFileMenu->insertSeparator();
     128   pFileMenu->insertItem(i18n("E&&;xit"), ID_FILE_QUIT);
     129
     130   ///////////////////////////////////////////////////////////////////
     131   // menuBar entry edit-Menu
     132   pEditMenu = new QPopupMenu(this);
     133   pEditMenu->insertItem(BarIcon("undo"), i18n("&&;Undo"), ID_EDIT_UNDO);
     134   pEditMenu->insertSeparator();
     135   pEditMenu->insertItem(BarIcon("editcut"), i18n("Cu&&;t"), ID_EDIT_CUT);
     136   pEditMenu->insertItem(BarIcon("editcopy"), i18n("&&;Copy"), ID_EDIT_COPY);
     137   pEditMenu->insertItem(BarIcon("editpaste"), i18n("&&;Paste"), ID_EDIT_PASTE);
     138   pEditMenu->insertItem(BarIcon("delete"),i18n("&&;Clear All"), ID_EDIT_CLEAR_ALL);
     139
     140   ///////////////////////////////////////////////////////////////////
     141   // menuBar entry pen-Menu
     142   pPenMenu = new QPopupMenu();
     143   pPenMenu->insertItem(i18n("&&;Color"), ID_PEN_COLOR);
     144   pPenMenu->insertItem(i18n("&&;Brush"), ID_PEN_BRUSH);
     145
     146   ///////////////////////////////////////////////////////////////////
     147   // menuBar entry view-Menu
     148   pViewMenu = new QPopupMenu(this);
     149   pViewMenu->setCheckable(true);
     150   pViewMenu->insertItem(i18n("&&;Toolbar"), ID_VIEW_TOOLBAR);
     151   pViewMenu->insertItem(i18n("&&;Statusbar"), ID_VIEW_STATUSBAR);
     152
     153   ///////////////////////////////////////////////////////////////////
     154   // menuBar entry window-Menu
     155   pWindowMenu = new QPopupMenu(this);
     156   pWindowMenu->setCheckable(true);
     157
     158
     159   ///////////////////////////////////////////////////////////////////
     160   // menuBar entry helpMenu
     161   QPopupMenu* pHelpMenu = helpMenu(i18n("KScribble" VERSION "\n\n(c) 2000 by\n"
     162                                   "Ralf Nolden\nRalf.Nolden@post.rwth-aachen.de"));
     163
     164   ///////////////////////////////////////////////////////////////////
     165   // MENUBAR CONFIGURATION
     166   // insert your popup menus with the according menubar entries in the order
     167   // they will appear later from left to right
     168   menuBar()->insertItem(i18n("&&;File"), pFileMenu);
     169   menuBar()->insertItem(i18n("&&;Edit"), pEditMenu);
     170   menuBar()->insertItem(i18n("&&;Pen"), pPenMenu);
     171   menuBar()->insertItem(i18n("&&;View"), pViewMenu);
     172   menuBar()->insertItem(i18n("&&;Window"), pWindowMenu );
     173   menuBar()->insertItem(i18n("&&;Help"), pHelpMenu);
     174
     175   ///////////////////////////////////////////////////////////////////
     176   // CONNECT THE MENU SLOTS WITH SIGNALS
     177   // for execution slots and statusbar messages
     178   connect(pFileMenu, SIGNAL(activated(int)), SLOT(commandCallback(int)));
     179   connect(pFileMenu, SIGNAL(highlighted(int)), SLOT(statusCallback(int)));
     180
     181   connect(pEditMenu, SIGNAL(activated(int)), SLOT(commandCallback(int)));
     182   connect(pEditMenu, SIGNAL(highlighted(int)), SLOT(statusCallback(int)));
     183
     184   connect(pPenMenu, SIGNAL(activated(int)), SLOT(commandCallback(int)));
     185   connect(pPenMenu, SIGNAL(highlighted(int)), SLOT(statusCallback(int)));
     186
     187   connect(pViewMenu, SIGNAL(activated(int)), SLOT(commandCallback(int)));
     188   connect(pViewMenu, SIGNAL(highlighted(int)), SLOT(statusCallback(int)));
     189
     190   connect(pWindowMenu, SIGNAL(aboutToShow() ), SLOT( windowMenuAboutToShow() ) );
     191   connect(pWindowMenu, SIGNAL(activated(int)), SLOT(commandCallback(int)));
     192   connect(pWindowMenu, SIGNAL(highlighted(int)), SLOT(statusCallback(int)));
     193
     194 }
     195
     196 void KScribbleApp::initToolBar()
     197 {
     198
     199   ///////////////////////////////////////////////////////////////////
     200   // TOOLBAR
     201   toolBar()->insertButton(BarIcon("filenew"), ID_FILE_NEW, true, i18n("New File"));
     202   toolBar()->insertButton(BarIcon("fileopen"), ID_FILE_OPEN, true, i18n("Open File"));
     203   toolBar()->insertButton(BarIcon("filefloppy"), ID_FILE_SAVE, true, i18n("Save File"));
     204   toolBar()->insertButton(BarIcon("fileprint"), ID_FILE_PRINT, true, i18n("Print"));
     205   toolBar()->insertSeparator();
     206   toolBar()->insertButton(BarIcon("editcut"), ID_EDIT_CUT, true, i18n("Cut"));
     207   toolBar()->insertButton(BarIcon("editcopy"), ID_EDIT_COPY, true, i18n("Copy"));
     208   toolBar()->insertButton(BarIcon("editpaste"), ID_EDIT_PASTE, true, i18n("Paste"));
     209   toolBar()->insertSeparator();
     210   toolBar()->insertButton(BarIcon("pencolor"), ID_PEN_COLOR, true, i18n("Color") );
     211   toolBar()->insertButton(BarIcon("penwidth"), ID_PEN_BRUSH, true, i18n("Width") );
     212   toolBar()->insertSeparator();
     213   toolBar()->insertButton(BarIcon("help"), ID_HELP_CONTENTS, SIGNAL(clicked()),
     214           this, SLOT(appHelpActivated()), true,i18n("Help"));
     215
     216   QToolButton *btnwhat = QWhatsThis::whatsThisButton(toolBar());
     217   QToolTip::add(btnwhat, i18n("What's this...?"));
     218   toolBar()->insertWidget(ID_HELP_WHATS_THIS, btnwhat->sizeHint().width(), btnwhat);
     219
     220   ///////////////////////////////////////////////////////////////////
     221   // INSERT YOUR APPLICATION SPECIFIC TOOLBARS HERE WITH toolBar(n)
     222
     223
     224   ///////////////////////////////////////////////////////////////////
     225   // CONNECT THE TOOLBAR SLOTS WITH SIGNALS - add new created toolbars by their according number
     226   // connect for invoking the slot actions
     227   connect(toolBar(), SIGNAL(clicked(int)), SLOT(commandCallback(int)));
     228   // connect for the status help on holing icons pressed with the mouse button
     229   connect(toolBar(), SIGNAL(pressed(int)), SLOT(statusCallback(int)));
     230
     231 }
     232
     233 void KScribbleApp::initStatusBar()
     234 {
     235   ///////////////////////////////////////////////////////////////////
     236   // STATUSBAR
     237   // TODO: add your own items you need for displaying current application status.
     238   statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
     239 }
     240
     241
     242 void KScribbleApp::initView()
     243 {
     244   ////////////////////////////////////////////////////////////////////
     245   // here the main view of the KTMainWindow is created by a background box and
     246   // the QWorkspace instance for MDI view.
     247   QVBox* view_back = new QVBox( this );
     248   view_back->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
     249   pWorkspace = new QWorkspace( view_back );
     250   connect(pWorkspace, SIGNAL(windowActivated(QWidget*)), this, SLOT(setWndTitle(QWidget*)));
     251   setView(view_back);
     252 }
     253
     254 void KScribbleApp::setWndTitle(QWidget*){
     255   setCaption(pWorkspace->activeWindow()->caption());
     256 }
     257
     258 void KScribbleApp::enableCommand(int id_)
     259 {
     260   ///////////////////////////////////////////////////////////////////
     261   // enable menu and toolbar functions by their ID's
     262   menuBar()->setItemEnabled(id_, true);
     263   toolBar()->setItemEnabled(id_, true);
     264 }
     265
     266 void KScribbleApp::disableCommand(int id_)
     267 {
     268   ///////////////////////////////////////////////////////////////////
     269   // disable menu and toolbar functions by their ID's
     270   menuBar()->setItemEnabled(id_, false);
     271   toolBar()->setItemEnabled(id_, false);
     272 }
     273
     274 void KScribbleApp::addRecentFile(const QString &&;file)
     275 {
     276   if(recentFiles.contains(file))
     277     return; // it's already there
     278
     279   if( recentFiles.count() < 5)
     280     recentFiles.prepend(file);
     281   else{
     282     recentFiles.remove(recentFiles.last());
     283     recentFiles.prepend(file);
     284   }
     285
     286   pRecentFileMenu->clear();
     287
     288   for ( int i =0 ; i < (int)recentFiles.count(); i++){
     289     pRecentFileMenu->insertItem(recentFiles.at(i));
     290   }
     291
     292 }
     293
     294 void KScribbleApp::createClient(KScribbleDoc* doc)
     295 {
     296   KScribbleView* w = new KScribbleView(doc, pWorkspace,0,WDestructiveClose);
     297   w->installEventFilter(this);
     298   doc->addView(w);
     299   w->setIcon(kapp->miniIcon());
     300   if ( pWorkspace->windowList().isEmpty() ) // show the very first window in maximized mode
     301     w->showMaximized();
     302   else
     303     w->show();
     304 }
     305
     306 void KScribbleApp::openDocumentFile(const char* file)
     307 {
     308   slotStatusMsg(i18n("Opening file..."));
     309   KScribbleDoc* doc;
     310   // check, if document already open. If yes, set the focus to the first view
     311   for(doc=pDocList->first(); doc > 0; doc=pDocList->next())
     312   {
     313     if(doc->pathName()==file)
     314     {
     315        KScribbleView* view=doc->firstView();
     316        view->setFocus();
     317        return;
     318      }
     319   }
     320   doc = new KScribbleDoc();
     321   pDocList->append(doc);
     322   doc->newDocument();
     323   // Creates an untitled window if file is 0
     324   if(!file)
     325   {
     326     untitledCount+=1;
     327     QString fileName=QString(i18n("Untitled%1")).arg(untitledCount);
     328     doc->setPathName(fileName);
     329     doc->setTitle(fileName);
     330   }
     331   // Open the file
     332   else
     333   {
     334     QString format=QImageIO::imageFormat(file);
     335     if(!doc->openDocument(file,format))
     336       KMessageBox::error (this,i18n("Could not open document !"), i18n("Error !"));
     337     addRecentFile(file);
     338   }
     339   // create the window
     340   createClient(doc);
     341
     342   slotStatusMsg(i18n("Ready."));
     343 }
     344
     345
     346 void KScribbleApp::saveOptions()
     347 {
     348   config->setGroup("General Options");
     349   config->writeEntry("Geometry", size());
     350   config->writeEntry("Show Toolbar", toolBar()->isVisible());
     351   config->writeEntry("Show Statusbar",statusBar()->isVisible());
     352   config->writeEntry("ToolBarPos", (int) toolBar()->barPos());
     353   config->writeEntry("Recent Files", recentFiles);
     354 }
     355
     356
     357 void KScribbleApp::readOptions()
     358 {
     359
     360   config->setGroup("General Options");
     361
     362   // bar status settings
     363   bool bViewToolbar = config->readBoolEntry("Show Toolbar", true);
     364   menuBar()->setItemChecked(ID_VIEW_TOOLBAR, bViewToolbar);
     365   if(!bViewToolbar)
     366   {
     367      enableToolBar(KToolBar::Hide);
     368   }
     369
     370   bool bViewStatusbar = config->readBoolEntry("Show Statusbar", true);
     371   menuBar()->setItemChecked(ID_VIEW_STATUSBAR, bViewStatusbar);
     372   if(!bViewStatusbar)
     373   {
     374     enableStatusBar(KStatusBar::Hide);
     375   }
     376
     377   // bar position settings
     378   KToolBar::BarPosition toolBarPos;
     379   toolBarPos=(KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top);
     380   toolBar()->setBarPos(toolBarPos);
     381
     382   // initialize the recent file list
     383   config->readListEntry("Recent Files",recentFiles);
     384
     385   for (int i=0; i < (int) recentFiles.count(); i++)
     386   {
     387     pRecentFileMenu->insertItem(recentFiles.at(i));
     388   }
     389
     390   QSize size=config->readSizeEntry("Geometry");
     391   if(!size.isEmpty())
     392   {
     393     resize(size);
     394   }
     395   else
     396     resize(400,350);
     397
     398 }
     399
     400 void KScribbleApp::saveProperties(KConfig *_cfg)
     401 {
     402
     403 }
     404
     405
     406 void KScribbleApp::readProperties(KConfig* _cfg)
     407 {
     408 }
     409
     410 bool KScribbleApp::queryClose()
     411 {
     412
     413   QStringList saveFiles;
     414   KScribbleDoc* doc;
     415   if(pDocList->isEmpty())
     416     return true;
     417
     418   for(doc=pDocList->first(); doc!=0;doc=pDocList->next()){
     419     if(doc->isModified())
     420       saveFiles.append(doc->title());
     421   }
     422   if(saveFiles.isEmpty())
     423     return true;
     424
     425   switch (KMessageBox::questionYesNoList(this,
     426       i18n("One or more documents have been modified.\nSave changes before exiting?"),saveFiles))
     427   {
     428     case KMessageBox::Yes:
     429       for(doc=pDocList->first(); doc!=0;doc=pDocList->next()){
     430         if(doc->title().contains(i18n("Untitled")))
     431           slotFileSaveAs();
     432         else
     433         {
     434           if(!doc->saveDocument(doc->pathName())){
     435             KMessageBox::error (this,i18n("Could not save the current document !"), i18n("I/O Error !"));
     436             return false;
     437           }
     438         }
     439        }
     440       return true;
     441     case KMessageBox::No:
     442     default:
     443       return true;
     444   }
     445 }
     446
     447 bool KScribbleApp::queryExit()
     448 {
     449   saveOptions();
     450   return true;
     451 }
     452
     453 bool KScribbleApp::eventFilter(QObject* object, QEvent* event){
     454   if(event->type() == QEvent::Close)
     455   {
     456     QCloseEvent* e=(QCloseEvent*)event;
     457     KScribbleView* pView=(KScribbleView*)object;
     458     KScribbleDoc* pDoc=pView->getDocument();
     459     if(pDoc->canCloseFrame(pView))
     460     {
     461        pDoc->removeView(pView);
     462        if(!pDoc->firstView())
     463          pDocList->remove(pDoc);
     464
     465       e->accept();
     466       //////////////
     467       if(pWorkspace->windowList().count()==1)
     468         setPlainCaption(kapp->caption());
     469       else
     470         setCaption(pWorkspace->activeWindow()->caption());
     471       //////////////
     472     }
     473     else
     474       e->ignore();
     475   }
     476   return QWidget::eventFilter( object, event );    // standard event processing
     477 }
     478
     479 /////////////////////////////////////////////////////////////////////
     480 // SLOT IMPLEMENTATION
     481 /////////////////////////////////////////////////////////////////////
     482
     483
     484 void KScribbleApp::slotFileNew()
     485 {
     486   slotStatusMsg(i18n("Creating new document..."));
     487
     488   openDocumentFile();
     489
     490   slotStatusMsg(i18n("Ready."));
     491 }
     492
     493 void KScribbleApp::slotFileOpen()
     494 {
     495   slotStatusMsg(i18n("Opening file..."));
     496
     497   QString fileToOpen=KFileDialog::getOpenFileName(QDir::currentDirPath(),
     498             KImageIO::pattern(KImageIO::Reading), this, i18n("Open File..."));
     499   if(!fileToOpen.isEmpty())
     500   {
     501     openDocumentFile(fileToOpen);
     502   }
     503
     504   slotStatusMsg(i18n("Ready."));
     505 }
     506
     507 void KScribbleApp::slotFileOpenRecent(int id_)
     508 {
     509   slotStatusMsg(i18n("Opening file..."));
     510
     511   openDocumentFile(pRecentFileMenu->text(id_));
     512
     513   slotStatusMsg(i18n("Ready."));
     514 }
     515
     516 void KScribbleApp::slotFileSave()
     517 {
     518   slotStatusMsg(i18n("Saving file..."));
     519   KScribbleView* m = (KScribbleView*)pWorkspace->activeWindow();
     520   if( m )
     521   {
     522     KScribbleDoc* doc =  m->getDocument();
     523     if(doc->title().contains(i18n("Untitled")))
     524      slotFileSaveAs();
     525     else
     526       if(!doc->saveDocument(doc->pathName()))
     527         KMessageBox::error (this,i18n("Could not save the current document !"), i18n("I/O Error !"));
     528   }
     529
     530
     531   slotStatusMsg(i18n("Ready."));
     532 }
     533
     534 void KScribbleApp::slotFileSaveAs()
     535 {
     536   slotStatusMsg(i18n("Saving file with a new filename..."));
     537
     538   QString newName=KFileDialog::getSaveFileName(QDir::currentDirPath(),
     539                                KImageIO::pattern(KImageIO::Writing), this, i18n("Save as..."));
     540   if(!newName.isEmpty())
     541   {
     542     KScribbleView* m = (KScribbleView*)pWorkspace->activeWindow();
     543     if( m )
     544     {
     545       KScribbleDoc* doc =  m->getDocument();
     546       QString format=QFileInfo(newName).extension();
     547       format=format.upper();
     548       if(!doc->saveDocument(newName,format))
     549       {
     550         KMessageBox::error (this,i18n("Could not save the current document !"), i18n("I/O Error !"));
     551         return;
     552       }
     553       doc->changedViewList();
     554       setWndTitle(m);
     555     }
     556
     557   }
     558
     559   slotStatusMsg(i18n("Ready."));
     560 }
     561
     562 void KScribbleApp::slotFileClose()
     563 {
     564   slotStatusMsg(i18n("Closing file..."));
     565
     566   KScribbleView* m = (KScribbleView*)pWorkspace->activeWindow();
     567   if( m )
     568   {
     569     KScribbleDoc* doc=m->getDocument();
     570     doc->closeDocument();
     571   }
     572
     573
     574   slotStatusMsg(i18n("Ready."));
     575 }
     576
     577 void KScribbleApp::slotFilePrint()
     578 {
     579   slotStatusMsg(i18n("Printing..."));
     580
     581   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     582   if ( m )
     583     m->print( printer );
     584
     585   slotStatusMsg(i18n("Ready."));
     586 }
     587
     588 void KScribbleApp::slotFileQuit()
     589 {
     590   slotStatusMsg(i18n("Exiting..."));
     591   saveOptions();
     592   // close the first window, the list makes the next one the first again.
     593   // This ensures that queryClose() is called on each window to ask for closing
     594   KTMainWindow* w;
     595   if(memberList)
     596   {
     597     for(w=memberList->first(); w!=0; w=memberList->first())
     598     {
     599       // only close the window if the closeEvent is accepted. If the user
     600       // presses Cancel on the saveModified() dialog,
     601       // the window and the application stay open.
     602       if(!w->close())
     603       break;
     604     }
     605   }
     606   slotStatusMsg(i18n("Ready."));
     607 }
     608
     609 void KScribbleApp::slotEditUndo()
     610 {
     611   slotStatusMsg(i18n("Reverting last action..."));
     612
     613   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     614   if ( m )
     615 //    m->undo();
     616
     617   slotStatusMsg(i18n("Ready."));
     618 }
     619
     620 void KScribbleApp::slotEditCut()
     621 {
     622   slotStatusMsg(i18n("Cutting selection..."));
     623
     624   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     625   if ( m )
     626     m->cutSelection();
     627
     628   slotStatusMsg(i18n("Ready."));
     629 }
     630
     631 void KScribbleApp::slotEditCopy()
     632 {
     633   slotStatusMsg(i18n("Copying selection to clipboard..."));
     634
     635   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     636   if ( m )
     637     m->copySelection();
     638
     639   slotStatusMsg(i18n("Ready."));
     640 }
     641
     642 void KScribbleApp::slotEditPaste()
     643 {
     644   slotStatusMsg(i18n("Inserting clipboard contents..."));
     645
     646   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     647   if ( m )
     648     m->pasteSelection();
     649
     650   slotStatusMsg(i18n("Ready."));
     651 }
     652
     653 void KScribbleApp::slotEditClearAll()
     654 {
     655   slotStatusMsg(i18n("Clearing the document contents..."));
     656
     657   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     658   if ( m ){
     659     KScribbleDoc* pDoc = m->getDocument();
     660     pDoc->editClearAll();
     661   }
     662   slotStatusMsg(i18n("Ready."));
     663 }
     664
     665 void KScribbleApp::slotPenBrush()
     666 {
     667   slotStatusMsg(i18n("Setting brush width..."));
     668
     669   // get one window with document for a current pen width
     670   QWidgetList windows = pWorkspace->windowList();
     671   KScribbleView* m = (KScribbleView*)windows.at(0);
     672   KScribbleDoc* pDoc = m->getDocument();
     673   int curr_width=pDoc->penWidth();
     674
     675   // create the dialog, get the new width and set the pen width for all documents
     676   KPenBrushDlg* dlg= new KPenBrushDlg(curr_width,this);
     677   if(dlg->exec()){
     678     int width=dlg->width();
     679     for ( int i = 0; i < int(windows.count()); ++i )
     680     {
     681       m = (KScribbleView*)windows.at(i);
     682       if ( m )
     683       {
     684         pDoc = m->getDocument();
     685         pDoc->setPenWidth(width);
     686       }
     687     }
     688   }
     689   slotStatusMsg(i18n("Ready."));
     690 }
     691
     692 void KScribbleApp::slotPenColor()
     693 {
     694   slotStatusMsg(i18n("Selecting pen color..."));
     695
     696   QColor myColor;
     697   int result = KColorDialog::getColor( myColor, this );
     698   if ( result == KColorDialog::Accepted )
     699   {
     700     QWidgetList windows = pWorkspace->windowList();
     701     KScribbleDoc* pDoc;
     702     KScribbleView* m;
     703     for ( int i = 0; i < int(windows.count()); ++i )
     704     {
     705       m = (KScribbleView*)windows.at(i);
     706       if ( m )
     707       {
     708         pDoc = m->getDocument();
     709         pDoc->setPenColor(myColor);
     710       }
     711     }
     712   }
     713   slotStatusMsg(i18n("Ready."));
     714 }
     715
     716
     717 void KScribbleApp::slotViewToolBar()
     718 {
     719   slotStatusMsg(i18n("Toggle the toolbar..."));
     720   ///////////////////////////////////////////////////////////////////
     721   // turn Toolbar on or off
     722   if( menuBar()->isItemChecked(ID_VIEW_TOOLBAR))
     723   {
     724     menuBar()->setItemChecked(ID_VIEW_TOOLBAR, false);
     725     enableToolBar(KToolBar::Hide);
     726   }
     727   else
     728   {
     729     menuBar()->setItemChecked(ID_VIEW_TOOLBAR, true);
     730     enableToolBar(KToolBar::Show);
     731   }
     732
     733   slotStatusMsg(i18n("Ready."));
     734 }
     735
     736 void KScribbleApp::slotViewStatusBar()
     737 {
     738   slotStatusMsg(i18n("Toggle the statusbar..."));
     739   ///////////////////////////////////////////////////////////////////
     740   //turn Statusbar on or off
     741   if( menuBar()->isItemChecked(ID_VIEW_STATUSBAR))
     742   {
     743     menuBar()->setItemChecked(ID_VIEW_STATUSBAR, false);
     744     enableStatusBar(KStatusBar::Hide);
     745   }
     746   else
     747   {
     748     menuBar()->setItemChecked(ID_VIEW_STATUSBAR, true);
     749     enableStatusBar(KStatusBar::Show);
     750   }
     751
     752   slotStatusMsg(i18n("Ready."));
     753 }
     754
     755 void KScribbleApp::slotWindowNewWindow()
     756 {
     757   slotStatusMsg(i18n("Opening a new application window..."));
     758
     759   KScribbleView* m = (KScribbleView*) pWorkspace->activeWindow();
     760   if ( m ){
     761      KScribbleDoc* doc = m->getDocument();
     762     createClient(doc);
     763   }
     764
     765   slotStatusMsg(i18n("Ready."));
     766 }
     767
     768 void KScribbleApp::slotStatusMsg(const QString &&;text)
     769 {
     770   ///////////////////////////////////////////////////////////////////
     771   // change status message permanently
     772   statusBar()->clear();
     773   statusBar()->changeItem(text, ID_STATUS_MSG);
     774 }
     775
     776
     777 void KScribbleApp::slotStatusHelpMsg(const QString &&;text)
     778 {
     779   ///////////////////////////////////////////////////////////////////
     780   // change status message of whole statusbar temporary (text, msec)
     781   statusBar()->message(text, 2000);
     782 }
     783
     784 void KScribbleApp::windowMenuAboutToShow()
     785 {
     786   pWindowMenu->clear();
     787
     788   pWindowMenu->insertItem(i18n("&&;New Window"), ID_WINDOW_NEW_WINDOW);
     789   pWindowMenu->insertItem(i18n("&&;Cascade"),
     790                           pWorkspace, SLOT(cascade() ),0 , ID_WINDOW_CASCADE );
     791   pWindowMenu->insertItem(i18n("&&;Tile"),
     792                           pWorkspace, SLOT(tile() ),0 , ID_WINDOW_TILE );
     793
     794   if ( pWorkspace->windowList().isEmpty() ) {
     795     disableCommand(ID_WINDOW_NEW_WINDOW);
     796     disableCommand(ID_WINDOW_CASCADE);
     797     disableCommand(ID_WINDOW_TILE);
     798   }
     799
     800   pWindowMenu->insertSeparator();
     801
     802   QWidgetList windows = pWorkspace->windowList();
     803   for ( int i = 0; i < int(windows.count()); ++i ) {
     804     int id = pWindowMenu->insertItem(QString("&&;%1 ").arg(i+1)+windows.at(i)->caption(),
     805                                      this, SLOT( windowMenuActivated( int ) ) );
     806     pWindowMenu->setItemParameter( id, i );
     807     pWindowMenu->setItemChecked( id, pWorkspace->activeWindow() == windows.at(i) );
     808   }
     809 }
     810
     811 void KScribbleApp::windowMenuActivated( int id )
     812 {
     813   QWidget* w = pWorkspace->windowList().at( id );
     814   if ( w )
     815     w->setFocus();
     816 }
     817
     818
     819 void KScribbleApp::commandCallback(int id_)
     820 {
     821   switch (id_)
     822   {
     823     case ID_FILE_NEW:
     824        slotFileNew();
     825          break;
     826
     827     case ID_FILE_OPEN:
     828          slotFileOpen();
     829          break;
     830
     831     case ID_FILE_SAVE:
     832          slotFileSave();
     833          break;
     834
     835     case ID_FILE_SAVE_AS:
     836          slotFileSaveAs();
     837          break;
     838
     839     case ID_FILE_CLOSE:
     840          slotFileClose();
     841          break;
     842
     843     case ID_FILE_PRINT:
     844          slotFilePrint();
     845          break;
     846
     847     case ID_FILE_QUIT:
     848          slotFileQuit();
     849          break;
     850
     851     case ID_EDIT_CUT:
     852          slotEditCut();
     853          break;
     854
     855     case ID_EDIT_COPY:
     856          slotEditCopy();
     857          break;
     858
     859     case ID_EDIT_PASTE:
     860          slotEditPaste();
     861          break;
     862
     863     case ID_EDIT_CLEAR_ALL:
     864          slotEditClearAll();
     865          break;
     866
     867     case ID_PEN_BRUSH:
     868          slotPenBrush();
     869          break;
     870
     871     case ID_PEN_COLOR:
     872          slotPenColor();
     873          break;
     874
     875     case ID_VIEW_TOOLBAR:
     876          slotViewToolBar();
     877          break;
     878
     879     case ID_VIEW_STATUSBAR:
     880          slotViewStatusBar();
     881          break;
     882
     883     case ID_WINDOW_NEW_WINDOW:
     884          slotWindowNewWindow();
     885        break;
     886
     887     default:
     888          break;
     889   }
     890 }
     891
     892 void KScribbleApp::statusCallback(int id_)
     893 {
     894   switch (id_)
     895   {
     896     case ID_FILE_NEW:
     897          slotStatusHelpMsg(i18n("Creates a new document"));
     898          break;
     899
     900     case ID_FILE_OPEN:
     901          slotStatusHelpMsg(i18n("Opens an existing document"));
     902          break;
     903
     904     case ID_FILE_OPEN_RECENT:
     905          slotStatusHelpMsg(i18n("Opens a recently used file"));
     906          break;
     907
     908     case ID_FILE_SAVE:
     909          slotStatusHelpMsg(i18n("Saves the currently active document"));
     910          break;
     911
     912     case ID_FILE_SAVE_AS:
     913          slotStatusHelpMsg(i18n("Saves the currently active document as under a new filename"));
     914          break;
     915
     916     case ID_FILE_CLOSE:
     917          slotStatusHelpMsg(i18n("Closes the currently active document"));
     918          break;
     919
     920     case ID_FILE_PRINT:
     921          slotStatusHelpMsg(i18n("Prints out the actual document"));
     922          break;
     923
     924     case ID_FILE_QUIT:
     925          slotStatusHelpMsg(i18n("Quits the application"));
     926          break;
     927
     928     case ID_EDIT_UNDO:
     929          slotStatusHelpMsg(i18n("Reverts the last editing action"));
     930          break;
     931
     932     case ID_EDIT_CUT:
     933          slotStatusHelpMsg(i18n("Cuts the selected section and puts it to the clipboard"));
     934          break;
     935
     936     case ID_EDIT_COPY:
     937          slotStatusHelpMsg(i18n("Copies the selected section to the clipboard"));
     938          break;
     939
     940     case ID_EDIT_PASTE:
     941          slotStatusHelpMsg(i18n("Pastes the clipboard contents to actual position"));
     942          break;
     943
     944     case ID_EDIT_CLEAR_ALL:
     945          slotStatusHelpMsg(i18n("Clears the document contents"));
     946          break;
     947
     948     case ID_PEN_BRUSH:
     949          slotStatusHelpMsg(i18n("Sets the pen width"));
     950          break;
     951
     952     case ID_PEN_COLOR:
     953          slotStatusHelpMsg(i18n("Sets the current pen color"));
     954          break;
     955
     956     case ID_VIEW_TOOLBAR:
     957          slotStatusHelpMsg(i18n("Enables/disables the toolbar"));
     958          break;
     959
     960     case ID_VIEW_STATUSBAR:
     961          slotStatusHelpMsg(i18n("Enables/disables the statusbar"));
     962          break;
     963
     964     case ID_WINDOW_NEW_WINDOW:
     965          slotStatusHelpMsg(i18n("Opens a new view for the current document"));
     966          break;
     967
     968     case ID_WINDOW_CASCADE:
     969          slotStatusHelpMsg(i18n("Cascades all windows"));
     970          break;
     971
     972     case ID_WINDOW_TILE:
     973          slotStatusHelpMsg(i18n("Tiles all windows"));
     974          break;
     975
     976     default:
     977          break;
     978   }
     979 }
     980 /** accepts drops and opens a new document
     981 for each drop */
     982 void KScribbleApp::dropEvent( QDropEvent* e){
     983
     984   QImage img;
     985   if ( QImageDrag::decode(e, img) )
     986   {
     987     KScribbleDoc* doc = new KScribbleDoc();
     988     untitledCount+=1;
     989     QString fileName=QString(i18n("Untitled%1")).arg(untitledCount);
     990     doc->setPathName(fileName);
     991     doc->setTitle(fileName);
     992     doc->newDocument();
     993     pDocList->append(doc);
     994     KPixmap tmp;
     995     tmp.resize(img.size());
     996     tmp.convertFromImage(img);
     997     doc->setPixmap(tmp);
     998     doc->resizeDocument(tmp.size());
     999     doc->setModified();
     1000     createClient(doc);
     1001   }
     1002 }
     1003 /** accepts drag events for images */
     1004 void KScribbleApp::dragEnterEvent( QDragEnterEvent* e){
     1005   e->accept(QImageDrag::canDecode(e));
     1006 }