import java.util.*;
import org.kde.qt.*;
import org.kde.koala.*;

/**
  * The base class for KScribble application windows. It sets up the main
  * window and reads the config file as well as providing a menubar, toolbar
  * and statusbar. In initView(), your main view is created as the MDI child window manager.
  * Child windows are created in createClient(), which gets a document instance as it's document to
  * display whereby one document can have several views.The MDI child is an instance of KScribbleView,
  * the document an instance of KScribbleDoc.
  * KScribbleApp reimplements the methods that KMainWindow provides for main window handling and supports
  * full session management as well as keyboard accelerator configuration by using KAccel.
  * @see KMainWindow
  * @see KApplication
  * @see KConfig
  * @see KAccel
  *
  * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team.
  * @version KDevelop version 1.1 code generation
  */
public class KScribbleApp extends KMainWindow implements Resource {

   /** the configuration object of the application */
   private KConfig config;
   /** view is the main widget which represents your working area. The View
   * class should handle all events of the view widget.  It is kept empty so
   * you can create your view according to your application's needs by
   * changing the view class.
   */
   private KScribbleView view;
   /** doc represents your actual document and is created only once. It keeps
   * information such as filename and does the serialization of your files.
   */
   private KScribbleDoc doc;

   /** contains the recently used filenames */
   ArrayList recentFiles = new ArrayList();

   // menus
   private QPopupMenu pFileMenu;
   private QPopupMenu pEditMenu;
   private QPopupMenu pPenMenu;
   private QPopupMenu pViewMenu;
   private QPopupMenu pWindowMenu;
   private QPopupMenu pHelpMenu;
   private QPopupMenu pRecentFileMenu;

   private QWorkspace pWorkspace;
   private QPrinter printer;
   private int untitledCount = 0;
   private ArrayList pDocList;
   private KApplication kapp;
   private KIconLoader k = new KIconLoader();

    /** construtor of KScribbleApp, calls all init functions to create the application.
     */
   public KScribbleApp(QWidget parent, String name)  {
      super(parent,name, 0);
      kapp = KApplication.kApplication();
      config=kapp.config();

      printer = new QPrinter();
      untitledCount=0;
      pDocList = new ArrayList();
      setAcceptDrops(true);
      ///////////////////////////////////////////////////////////////////
      // call inits to invoke all other construction parts
      initMenuBar();
      initToolBar();
      initStatusBar();
      initKeyAccel();
      initView();

      readOptions();

      ///////////////////////////////////////////////////////////////////
      // disable menu and toolbar items at startup
      disableCommand(ID_EDIT_UNDO);

   }

   public KScribbleApp() {
	   this(null, null);
   }

   /** initializes the KActions of the application */
   protected void initKeyAccel() {

      KAccel keyAccel = new KAccel(this);

      // fileMenu accelerators
      keyAccel.connectItem(KStdAccel.New,this,SLOT("slotFileNew()"));
      keyAccel.connectItem(KStdAccel.Open,this,SLOT("slotFileOpen()"));
      keyAccel.connectItem(KStdAccel.Save,this,SLOT("slotFileSave()"));
      keyAccel.connectItem(KStdAccel.Close,this,SLOT("slotFileClose()"));
      keyAccel.connectItem(KStdAccel.Print,this,SLOT("slotFilePrint()"));
      keyAccel.connectItem(KStdAccel.Quit,this,SLOT("slotFileQuit()"));

      keyAccel.changeMenuAccel(pFileMenu, ID_FILE_NEW, KStdAccel.New);
      keyAccel.changeMenuAccel(pFileMenu, ID_FILE_OPEN, KStdAccel.Open);
      keyAccel.changeMenuAccel(pFileMenu, ID_FILE_SAVE, KStdAccel.Save);
      keyAccel.changeMenuAccel(pFileMenu, ID_FILE_CLOSE, KStdAccel.Close);
      keyAccel.changeMenuAccel(pFileMenu, ID_FILE_PRINT, KStdAccel.Print);
      keyAccel.changeMenuAccel(pFileMenu, ID_FILE_QUIT, KStdAccel.Quit);

      // editMenu accelerators
      keyAccel.connectItem(KStdAccel.Cut,this,SLOT("slotEditCut()"));
      keyAccel.connectItem(KStdAccel.Copy,this,SLOT("slotEditCopy()"));
      keyAccel.connectItem(KStdAccel.Paste,this,SLOT("slotEditPaste()"));

      // help accelerator
      keyAccel.connectItem(KStdAccel.Help,this,SLOT("appHelpActivated()"));

      keyAccel.changeMenuAccel(pEditMenu, ID_EDIT_CUT, KStdAccel.Cut);
      keyAccel.changeMenuAccel(pEditMenu, ID_EDIT_COPY, KStdAccel.Copy);
      keyAccel.changeMenuAccel(pEditMenu, ID_EDIT_PASTE, KStdAccel.Paste);

      keyAccel.readSettings();

   }


   void initMenuBar() {
     ///////////////////////////////////////////////////////////////////
     // MENUBAR

     pRecentFileMenu = new QPopupMenu(this);
     connect(pRecentFileMenu, SIGNAL("activated(int)"), SLOT("slotFileOpenRecent(int)"));


     ///////////////////////////////////////////////////////////////////
     // menuBar entry file-Menu
     pFileMenu = new QPopupMenu(this);


     pFileMenu.insertItem(KIconLoader.BarIconSet("filenew"),i18n("&New"), ID_FILE_NEW,-1);
     pFileMenu.insertItem(KIconLoader.BarIconSet("fileopen"),i18n("&Open..."), ID_FILE_OPEN,-1);
     pFileMenu.insertItem(i18n("Open &recent"), pRecentFileMenu, ID_FILE_OPEN_RECENT,-1);

     pFileMenu.insertItem(i18n("&Close"), ID_FILE_CLOSE,-1);
     pFileMenu.insertSeparator();
     pFileMenu.insertItem(KIconLoader.BarIconSet("filefloppy") ,i18n("&Save"), ID_FILE_SAVE,-1);
     pFileMenu.insertItem(i18n("Save &As..."), ID_FILE_SAVE_AS,-1);
     pFileMenu.insertSeparator();
     pFileMenu.insertItem(KIconLoader.BarIconSet("fileprint"), i18n("&Print..."), ID_FILE_PRINT,-1);
     pFileMenu.insertSeparator();
     pFileMenu.insertItem(i18n("E&xit"), ID_FILE_QUIT,-1);

     ///////////////////////////////////////////////////////////////////
     // menuBar entry edit-Menu
     pEditMenu = new QPopupMenu(this);
     pEditMenu.insertItem(KIconLoader.BarIconSet("undo"), i18n("&Undo"), ID_EDIT_UNDO,-1);
     pEditMenu.insertSeparator();
     pEditMenu.insertItem(KIconLoader.BarIconSet("editcut"), i18n("Cu&t"), ID_EDIT_CUT,-1);
     pEditMenu.insertItem(KIconLoader.BarIconSet("editcopy"), i18n("&Copy"), ID_EDIT_COPY,-1);
     pEditMenu.insertItem(KIconLoader.BarIconSet("editpaste"), i18n("&Paste"), ID_EDIT_PASTE,-1);
     pEditMenu.insertItem(KIconLoader.BarIconSet("delete"),i18n("&Clear All"), ID_EDIT_CLEAR_ALL,-1);

     ///////////////////////////////////////////////////////////////////
     // menuBar entry pen-Menu
     pPenMenu = new QPopupMenu();
     pPenMenu.insertItem(i18n("&Color"), ID_PEN_COLOR,-1);
     pPenMenu.insertItem(i18n("&Brush"), ID_PEN_BRUSH,-1);

     ///////////////////////////////////////////////////////////////////
     // menuBar entry view-Menu
     pViewMenu = new QPopupMenu(this);
     pViewMenu.setCheckable(true);
     pViewMenu.insertItem(i18n("&Toolbar"), ID_VIEW_TOOLBAR,-1);
     pViewMenu.insertItem(i18n("&Statusbar"), ID_VIEW_STATUSBAR,-1);

     ///////////////////////////////////////////////////////////////////
     // menuBar entry window-Menu
     pWindowMenu = new QPopupMenu(this);
     pWindowMenu.setCheckable(true);


     ///////////////////////////////////////////////////////////////////
     // menuBar entry helpMenu

      QPopupMenu pHelpMenu = helpMenu(i18n("Java KScribble " + Main.VERSION + "\n\n(c) 2002 by\n" +
                                     "Ralf Nolden\nRalf.Nolden@post.rwth-aachen.de"),true);

     ///////////////////////////////////////////////////////////////////
     // MENUBAR CONFIGURATION
     // insert your popup menus with the according menubar entries in the order
     // they will appear later from left to right
     menuBar().insertItem(i18n("&File"), pFileMenu);
     menuBar().insertItem(i18n("&Edit"), pEditMenu);
     menuBar().insertItem(i18n("&Pen"), pPenMenu);
     menuBar().insertItem(i18n("&View"), pViewMenu);
     menuBar().insertItem(i18n("&Window"), pWindowMenu );
     menuBar().insertItem(i18n("&Help"), pHelpMenu);

     ///////////////////////////////////////////////////////////////////
     // CONNECT THE MENU SLOTS WITH SIGNALS
     // for execution slots and statusbar messages
     connect(pFileMenu, SIGNAL("activated(int)"), SLOT("commandCallback(int)"));
     connect(pFileMenu, SIGNAL("highlighted(int)"), SLOT("statusCallback(int)"));

     connect(pEditMenu, SIGNAL("activated(int)"), SLOT("commandCallback(int)"));
     connect(pEditMenu, SIGNAL("highlighted(int)"), SLOT("statusCallback(int)"));

     connect(pPenMenu, SIGNAL("activated(int)"), SLOT("commandCallback(int)"));
     connect(pPenMenu, SIGNAL("highlighted(int)"), SLOT("statusCallback(int)"));

     connect(pViewMenu, SIGNAL("activated(int)"), SLOT("commandCallback(int)"));
     connect(pViewMenu, SIGNAL("highlighted(int)"), SLOT("statusCallback(int)"));

     connect(pWindowMenu, SIGNAL("aboutToShow()" ), SLOT( "windowMenuAboutToShow()" ) );
     connect(pWindowMenu, SIGNAL("activated(int)"), SLOT("commandCallback(int)"));
     connect(pWindowMenu, SIGNAL("highlighted(int)"), SLOT("statusCallback(int)"));

   }


   private void initToolBar() {

      ///////////////////////////////////////////////////////////////////
      // TOOLBAR

      toolBar().insertButton(KIconLoader.BarIcon("filenew"), ID_FILE_NEW, true, i18n("New File"),-1);
      toolBar().insertButton(KIconLoader.BarIcon("fileopen"), ID_FILE_OPEN, true, i18n("Open File"),-1);
      toolBar().insertButton(KIconLoader.BarIcon("filefloppy"), ID_FILE_SAVE, true, i18n("Save File"),-1);
      toolBar().insertButton(KIconLoader.BarIcon("fileprint"), ID_FILE_PRINT, true, i18n("Print"),-1);
      toolBar().insertSeparator();
      toolBar().insertButton(KIconLoader.BarIcon("editcut"), ID_EDIT_CUT, true, i18n("Cut"),-1);
      toolBar().insertButton(KIconLoader.BarIcon("editcopy"), ID_EDIT_COPY, true, i18n("Copy"),-1);
      toolBar().insertButton(KIconLoader.BarIcon("editpaste"), ID_EDIT_PASTE, true, i18n("Paste"),-1);
      toolBar().insertSeparator();
      toolBar().insertButton(KIconLoader.BarIcon("pencolor"), ID_PEN_COLOR, true, i18n("Color"),-1 );
      toolBar().insertButton(KIconLoader.BarIcon("penwidth"), ID_PEN_BRUSH, true, i18n("Width"),-1 );
      toolBar().insertSeparator();
      toolBar().insertButton(KIconLoader.BarIcon("help"), ID_HELP_CONTENTS, SIGNAL("clicked()"),
             this, SLOT("appHelpActivated()"), true,i18n("Help"),-1);

      QToolButton btnwhat = QWhatsThis.whatsThisButton(toolBar());
      QToolTip.add(btnwhat, i18n("What's this...?"));
      toolBar().insertWidget(ID_HELP_WHATS_THIS, btnwhat.sizeHint().width(), btnwhat);

      ///////////////////////////////////////////////////////////////////
      // INSERT YOUR APPLICATION SPECIFIC TOOLBARS HERE WITH toolBar(n)


      ///////////////////////////////////////////////////////////////////
      // CONNECT THE TOOLBAR SLOTS WITH SIGNALS - add new created toolbars by their according number
      // connect for invoking the slot actions
      connect(toolBar(), SIGNAL("clicked(int)"), SLOT("commandCallback(int)"));
      // connect for the status help on holing icons pressed with the mouse button
      connect(toolBar(), SIGNAL("pressed(int)"), SLOT("statusCallback(int)"));

   }


    /** sets up the kstatusBar for the main window by initialzing a statuslabel.
     */
   protected void initStatusBar() {
      ///////////////////////////////////////////////////////////////////
      // STATUSBAR
      // TODO: add your own items you need for displaying current application status.
      ((KStatusBar)statusBar()).insertItem(i18n("Ready."), ID_STATUS_MSG);
   }

    /** creates the centerwidget of the KTMainWindow instance and sets it as the view
     */
   protected void initView() {

      ////////////////////////////////////////////////////////////////////
      // here the main view of the KTMainWindow is created by a background box and
      // the QWorkspace instance for MDI view.
      QVBox view_back = new QVBox( this );
      view_back.setFrameStyle( QFrame.StyledPanel | QFrame.Sunken );
      pWorkspace = new QWorkspace( view_back, "" );
      connect(pWorkspace, SIGNAL("windowActivated(QWidget)"), this, SLOT("setWndTitle(QWidget)"));
//     setView(view_back);
      setCentralWidget(view_back);
   }

   void createClient(KScribbleDoc doc) {
     KScribbleView w = new KScribbleView(doc, pWorkspace,null,WDestructiveClose);
     w.installEventFilter(this);
     doc.addView(w);
     w.setIcon(kapp.miniIcon());
     if ( pWorkspace.windowList().isEmpty() ) // show the very first window in maximized mode
       w.showMaximized();
     else
       w.show();
   }

   void addRecentFile(String file) {


      if(recentFiles != null && recentFiles.contains(file))
       return; // it's already there

      if( recentFiles.size() < 5)
         recentFiles.add(0,file);
      else{
         recentFiles.remove(recentFiles.remove(recentFiles.size()-1));
         recentFiles.add(0,file);
      }

      pRecentFileMenu.clear();

      Iterator it = recentFiles.iterator();
      while (it.hasNext()) {
         pRecentFileMenu.insertItem((String)it.next());
      }

   }

    /** opens a file specified by commandline option
     */
   public void openDocumentFile(KURL url) {
      slotStatusMsg(i18n("Opening file..."));

      KScribbleDoc doc;
      String file = url.directory(false,true) + url.fileName();

      Iterator it = pDocList.iterator();

      while (it.hasNext()) {

         doc = (KScribbleDoc)it.next();
         // check, if document already open. If yes, set the focus to the first view
         if(doc.pathName().equals(file)) {

             KScribbleView view=doc.firstView();
             view.setFocus();
             return;
         }
      }
      doc = new KScribbleDoc();
      pDocList.add(doc);
      doc.newDocument();
      // Creates an untitled window if file is 0
      if(file == null || file.length() == 0) {
         untitledCount+=1;
         String fileName= i18n("Untitled" +untitledCount);
         doc.setPathName(fileName);
         doc.setTitle(fileName);
      }
      // Open the file
      else {

       String format= QImageIO.imageFormat(file);
       if(!doc.openDocument(file,format))
         KMessageBox.error (this,i18n("Could not open document !"), i18n("Error !"),KMessageBox.Notify);
       addRecentFile(file);
      }
      // create the window
      createClient(doc);
      slotStatusMsg(i18n("Ready."));

   }


   public void openDocumentFile() {
   	openDocumentFile(new KURL());
	   return;
   }

   void windowMenuAboutToShow() {
      pWindowMenu.clear();

      pWindowMenu.insertItem(i18n("&New Window"), ID_WINDOW_NEW_WINDOW);
      pWindowMenu.insertItem(i18n("&Cascade"),
                             pWorkspace, SLOT("cascade()" ),new QKeySequence(0) , ID_WINDOW_CASCADE );
      pWindowMenu.insertItem(i18n("&Tile"),
                             pWorkspace, SLOT("tile()" ),new QKeySequence(0) , ID_WINDOW_TILE );

      if ( pWorkspace.windowList().isEmpty() ) {

         disableCommand(ID_WINDOW_NEW_WINDOW);
         disableCommand(ID_WINDOW_CASCADE);
         disableCommand(ID_WINDOW_TILE);
      }

      pWindowMenu.insertSeparator();

      ArrayList windows = pWorkspace.windowList();

      for ( int i = 0; i < windows.size(); ++i ) {
          int id = pWindowMenu.insertItem((i+1)+ ((QWidget)windows.get(i)).caption(),
                                           this, SLOT( "windowMenuActivated( int )" ) );
          pWindowMenu.setItemParameter( id, i );
          pWindowMenu.setItemChecked( id, pWorkspace.activeWindow() == (QWidget)windows.get(i) );
      }
   }

   void windowMenuActivated( int id ) {
      QWidget w = (QWidget)pWorkspace.windowList().get( id );
      if ( w != null )
         w.setFocus();
   }

   void setWndTitle(QWidget qw){
      setCaption(pWorkspace.activeWindow().caption());
   }

   void enableCommand(int id_) {
     ///////////////////////////////////////////////////////////////////
     // enable menu and toolbar functions by their ID's
     menuBar().setItemEnabled(id_, true);
     toolBar().setItemEnabled(id_, true);
   }

   void disableCommand(int id_) {
     ///////////////////////////////////////////////////////////////////
     // disable menu and toolbar functions by their ID's
     menuBar().setItemEnabled(id_, false);
     toolBar().setItemEnabled(id_, false);
   }

   void commandCallback(int id_) {
      switch (id_) {
       case ID_FILE_NEW:
          slotFileNew();
            break;

       case ID_FILE_OPEN:
            slotFileOpen();
            break;

       case ID_FILE_SAVE:
            slotFileSave();
            break;

       case ID_FILE_SAVE_AS:
            slotFileSaveAs();
            break;

       case ID_FILE_CLOSE:
            slotFileClose();
            break;

       case ID_FILE_PRINT:
            slotFilePrint();
            break;

       case ID_FILE_QUIT:
            slotFileQuit();
            break;

       case ID_EDIT_CUT:
            slotEditCut();
            break;

       case ID_EDIT_COPY:
            slotEditCopy();
            break;

       case ID_EDIT_PASTE:
            slotEditPaste();
            break;

       case ID_EDIT_CLEAR_ALL:
            slotEditClearAll();
            break;

       case ID_PEN_BRUSH:
            slotPenBrush();
            break;

       case ID_PEN_COLOR:
            slotPenColor();
            break;

       case ID_VIEW_TOOLBAR:
            slotViewToolBar();
            break;

       case ID_VIEW_STATUSBAR:
            slotViewStatusBar();
            break;

       case ID_WINDOW_NEW_WINDOW:
          slotWindowNewWindow();
          break;

       default:
            break;
      }
   }

   void statusCallback(int id_) {
      switch (id_) {
         case ID_FILE_NEW:
            slotStatusHelpMsg(i18n("Creates a new document"));
            break;

         case ID_FILE_OPEN:
            slotStatusHelpMsg(i18n("Opens an existing document"));
            break;

         case ID_FILE_OPEN_RECENT:
            slotStatusHelpMsg(i18n("Opens a recently used file"));
            break;

         case ID_FILE_SAVE:
            slotStatusHelpMsg(i18n("Saves the currently active document"));
            break;

         case ID_FILE_SAVE_AS:
            slotStatusHelpMsg(i18n("Saves the currently active document as under a new filename"));
            break;

         case ID_FILE_CLOSE:
            slotStatusHelpMsg(i18n("Closes the currently active document"));
            break;

         case ID_FILE_PRINT:
            slotStatusHelpMsg(i18n("Prints out the actual document"));
            break;

         case ID_FILE_QUIT:
            slotStatusHelpMsg(i18n("Quits the application"));
            break;

         case ID_EDIT_UNDO:
            slotStatusHelpMsg(i18n("Reverts the last editing action"));
            break;

         case ID_EDIT_CUT:
            slotStatusHelpMsg(i18n("Cuts the selected section and puts it to the clipboard"));
            break;

         case ID_EDIT_COPY:
            slotStatusHelpMsg(i18n("Copies the selected section to the clipboard"));
            break;

         case ID_EDIT_PASTE:
            slotStatusHelpMsg(i18n("Pastes the clipboard contents to actual position"));
            break;

         case ID_EDIT_CLEAR_ALL:
            slotStatusHelpMsg(i18n("Clears the document contents"));
            break;

         case ID_PEN_BRUSH:
            slotStatusHelpMsg(i18n("Sets the pen width"));
            break;

         case ID_PEN_COLOR:
            slotStatusHelpMsg(i18n("Sets the current pen color"));
            break;

         case ID_VIEW_TOOLBAR:
            slotStatusHelpMsg(i18n("Enables/disables the toolbar"));
            break;

         case ID_VIEW_STATUSBAR:
            slotStatusHelpMsg(i18n("Enables/disables the statusbar"));
            break;

         case ID_WINDOW_NEW_WINDOW:
            slotStatusHelpMsg(i18n("Opens a new view for the current document"));
            break;

         case ID_WINDOW_CASCADE:
            slotStatusHelpMsg(i18n("Cascades all windows"));
            break;

         case ID_WINDOW_TILE:
            slotStatusHelpMsg(i18n("Tiles all windows"));
            break;

         default:
            break;
      }
   }

   void slotStatusHelpMsg(String text) {
      ///////////////////////////////////////////////////////////////////
      // change status message of whole statusbar temporary (text, msec)
      statusBar().message(text, 2000);
   }


    /** returns a pointer to the current document connected to the KTMainWindow instance and is used by
     * the View class to access the document object's methods
     */
   public KScribbleDoc getDocument() {
      return doc;
   }

    /** save general Options like all bar positions and status as well as the geometry and the recent file list to the configuration
     * file
     */
   protected void saveOptions() {
      config.setGroup("General Options");
      config.writeEntry("Geometry", size());
      config.writeEntry("Show Toolbar", toolBar().isVisible());
      config.writeEntry("Show Statusbar",statusBar().isVisible());
      config.writeEntry("ToolBarPos", (int) toolBar().barPos());
      String[] rf = new String[recentFiles.size()];
      rf = (String[]) recentFiles.toArray(rf);
      if (rf != null)
        config.writeEntry("Recent Files", rf);
   }



    /** read general Options again and initialize all variables like the recent file list
     */
   private void readOptions() {

      config.setGroup("General Options");

      // bar status settings
      boolean bViewToolbar = config.readBoolEntry("Show Toolbar", true);
      menuBar().setItemChecked(ID_VIEW_TOOLBAR, bViewToolbar);
      if(!bViewToolbar) {
         toolBar("mainToolBar").hide();
      }

      boolean bViewStatusbar = config.readBoolEntry("Show Statusbar", true);
      menuBar().setItemChecked(ID_VIEW_STATUSBAR, bViewStatusbar);
      if(!bViewStatusbar) {
         toolBar("mainToolBar").hide();
      }

      // bar position settings
      int toolBarPos = KToolBar.Top;
      toolBarPos = config.readUnsignedNumEntry("ToolBarPos", KToolBar.Top);
      toolBar().setBarPos(toolBarPos);

     // initialize the recent file list
     //  commented out until fix is applied.
     config.readListEntry("Recent Files",recentFiles);
     Iterator it = recentFiles.iterator();
	 while (it.hasNext()) {
       pRecentFileMenu.insertItem((String) it.next());
	 }

      // Read the size information and resize from settings.
      QSize size = new QSize();
      config.readSizeEntry("Geometry",size);
      if(!size.isEmpty()) {
         resize(size);
      }
      else
         resize(400,350);

   }

    /** saves the window properties for each open window during session end to the session config file, including saving the currently
     * opened file by a temporary filename provided by KApplication.
     * @see KTMainWindow#saveProperties
     */
   protected void saveProperties(KConfig _cfg) {

   }


    /** reads the session config file and restores the application's state including the last opened files and documents by reading the
     * temporary files saved by saveProperties()
     * @see KTMainWindow#readProperties
     */
   protected void readProperties(KConfig _cfg) {
   }

    /** queryClose is called by KTMainWindow on each closeEvent of a window. Against the
     * default implementation (only returns true), this calles saveModified() on the document object to ask if the document shall
     * be saved if Modified; on cancel the closeEvent is rejected.
     * @see KTMainWindow#queryClose
     * @see KTMainWindow#closeEvent
     */
   protected boolean queryClose() {

      ArrayList saveFiles = new ArrayList();
      KScribbleDoc doc;

      if(pDocList.isEmpty())
         return true;

      Iterator it = pDocList.iterator();

      while (it.hasNext()) {
         doc = (KScribbleDoc)it.next();
         if(doc.isModified())
            saveFiles.add(doc.title());

      }

      if(saveFiles.isEmpty())
         return true;

      // lets load up a String array with the documents to save.
      String[] sf = new String[saveFiles.size()];
      for (int x = 0; x < saveFiles.size(); x++) {
         sf[x] = (String)saveFiles.get(x);
      }
      switch (KMessageBox.questionYesNoList(this,
         i18n("One or more documents have been modified.\nSave changes before exiting?"),sf))
      {
         case KMessageBox.Yes:

            Iterator itr = pDocList.iterator();

            while (itr.hasNext()) {
               doc = (KScribbleDoc)itr.next();
               if(doc.title().indexOf(i18n("Untitled")) > 0) {

                  slotFileSaveAs();
               }
               else {
                  if(!doc.saveDocument(doc.pathName())){
                     KMessageBox.error (this,i18n("Could not save the current document !"), i18n("I/O Error !"),KMessageBox.Notify);
                     return false;
                  }

               }


            }
            return true;
         case KMessageBox.No:
         default:
            return true;
      }

   }

    /** queryExit is called by KTMainWindow when the last window of the application is going to be closed during the closeEvent().
     * Against the default implementation that just returns true, this calls saveOptions() to save the settings of the last window's
     * properties.
     * @see KTMainWindow#queryExit
     * @see KTMainWindow#closeEvent
     */
   protected boolean queryExit() {
      saveOptions();
      return true;
   }

/////////////////////////////////////////////////////////////////////
// SLOT IMPLEMENTATION
/////////////////////////////////////////////////////////////////////


   void slotFileNew() {
      slotStatusMsg(i18n("Creating new document..."));

      openDocumentFile();

      slotStatusMsg(i18n("Ready."));
   }

   void slotFileOpen() {
      slotStatusMsg(i18n("Opening file..."));

      String fileToOpen=KFileDialog.getOpenFileName(QDir.currentDirPath(),
               KImageIO.pattern(KImageIO.Reading), this, i18n("Open File..."));
      if(fileToOpen != null && fileToOpen.length() > 0) {
         openDocumentFile(new KURL(fileToOpen));
      }

      slotStatusMsg(i18n("Ready."));
   }


   void slotFileSave() {
      slotStatusMsg(i18n("Saving file..."));
      KScribbleView m = (KScribbleView)pWorkspace.activeWindow();
      if( m != null)  {
         KScribbleDoc doc =  m.getDocument();
         if(doc.title().indexOf(i18n("Untitled")) > 0)
            slotFileSaveAs();
         else
            if(!doc.saveDocument(doc.pathName()))
               KMessageBox.error (this,i18n("Could not save the current document !"), i18n("I/O Error !"),KMessageBox.Notify);      }


      slotStatusMsg(i18n("Ready."));
   }

   void slotFileSaveAs() {
      slotStatusMsg(i18n("Saving file with a new filename..."));

      String newName=KFileDialog.getSaveFileName(QDir.currentDirPath(),
                                  KImageIO.pattern(KImageIO.Writing), this, i18n("Save as..."));

	  if(newName != null) {
         KScribbleView m = (KScribbleView)pWorkspace.activeWindow();
         if( m != null ) {
            KScribbleDoc doc =  m.getDocument();

            String format=new QFileInfo(newName).extension();
            format=format.toUpperCase();

			if(!doc.saveDocument(newName,format)) {
              KMessageBox.error (this,i18n("Could not save the current document !"), i18n("I/O Error !"),KMessageBox.Notify);
              return;
            }
            doc.changedViewList();
            setWndTitle(m);
         }

      }

      slotStatusMsg(i18n("Ready."));
   }

   void slotFileClose() {
      slotStatusMsg(i18n("Closing file..."));

      KScribbleView m = (KScribbleView)pWorkspace.activeWindow();
      if( m != null ) {
         KScribbleDoc doc=m.getDocument();
         doc.closeDocument();
      }


      slotStatusMsg(i18n("Ready."));
   }

   void slotFilePrint() {
      slotStatusMsg(i18n("Printing..."));

      KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
      if ( m != null)
         m.print( printer );

      slotStatusMsg(i18n("Ready."));
   }

   void slotFileQuit() {
      slotStatusMsg(i18n("Exiting..."));
      saveOptions();
      // close the first window, the list makes the next one the first again.
      // This ensures that queryClose() is called on each window to ask for closing
      KMainWindow w;

      ArrayList memberlist = memberList();
      if(memberlist != null) {
         Iterator it = memberlist.iterator();
         while (it.hasNext()) {
            w = (KMainWindow)it.next();
            // only close the window if the closeEvent is accepted. If the user
            // presses Cancel on the saveModified() dialog,
            // the window and the application stay open.
            if(!w.close())
               break;
         }
      }
      slotStatusMsg(i18n("Ready."));
   }

   void slotFileOpenRecent(int id_) {
      slotStatusMsg(i18n("Opening file..."));

      KURL kurl = new KURL(pRecentFileMenu.text(id_));
//      openDocumentFile(pRecentFileMenu.text(id_));
      openDocumentFile(kurl);
      slotStatusMsg(i18n("Ready."));
   }

   void slotEditClearAll() {
     slotStatusMsg(i18n("Clearing the document contents..."));

     KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
     if ( m != null ){
       KScribbleDoc pDoc = m.getDocument();
       pDoc.editClearAll();
     }
     slotStatusMsg(i18n("Ready."));
   }

   void slotPenBrush() {
     slotStatusMsg(i18n("Setting brush width..."));

     // get one window with document for a current pen width
     ArrayList windows = pWorkspace.windowList();
     KScribbleView m = (KScribbleView)windows.get(0);
     KScribbleDoc pDoc = m.getDocument();
     int curr_width=pDoc.penWidth();

     // create the dialog, get the new width and set the pen width for all documents
     KPenBrushDlg dlg= new KPenBrushDlg(curr_width,this,"");
     if(dlg.exec() > 0){
       int width=dlg.getPenWidth();
       for ( int i = 0; i < windows.size(); ++i ) {
         m = (KScribbleView)windows.get(i);
         if ( m != null ) {
           pDoc = m.getDocument();
           pDoc.setPenWidth(width);
         }
       }
     }
     slotStatusMsg(i18n("Ready."));
   }

   void slotPenColor() {
     slotStatusMsg(i18n("Selecting pen color..."));

     QColor myColor = new QColor();
     int result = KColorDialog.getColor( myColor, this );
     if ( result == KColorDialog.Accepted )
     {
       ArrayList windows = pWorkspace.windowList();
       KScribbleDoc pDoc;
       KScribbleView m;
       for ( int i = 0; i < windows.size(); ++i )  {
         m = (KScribbleView)windows.get(i);
         if ( m != null) {
           pDoc = m.getDocument();
           pDoc.setPenColor(myColor);
         }
       }
     }
     slotStatusMsg(i18n("Ready."));
   }

   void slotEditUndo() {
      slotStatusMsg(i18n("Reverting last action..."));

      KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
//      if ( m != null )
//          m.undo();

      slotStatusMsg(i18n("Ready."));
   }

    /** put the marked object into the clipboard and remove
     *	it from the document
     */
   void slotEditCut() {
      slotStatusMsg(i18n("Cutting selection..."));

      KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
      if ( m != null )
         m.cutSelection();

      slotStatusMsg(i18n("Ready."));
   }

    /** put the marked text/object into the clipboard
     */
   public void slotEditCopy() {
      slotStatusMsg(i18n("Copying selection to clipboard..."));

      KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
      if ( m != null)
         m.copySelection();

      slotStatusMsg(i18n("Ready."));
   }

    /** paste the clipboard into the document
     */
   public void slotEditPaste() {
      slotStatusMsg(i18n("Inserting clipboard contents..."));

      KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
      if ( m != null ) {
         m.pasteSelection();
      }
      slotStatusMsg(i18n("Ready."));
   }

    /** toggles the toolbar
     */

   void slotViewToolBar() {
      slotStatusMsg(i18n("Toggle the toolbar..."));
      ///////////////////////////////////////////////////////////////////
      // turn Toolbar on or off
      if( menuBar().isItemChecked(ID_VIEW_TOOLBAR)) {
         menuBar().setItemChecked(ID_VIEW_TOOLBAR, false);
         toolBar("mainToolBar").hide();

      }
      else {
         menuBar().setItemChecked(ID_VIEW_TOOLBAR, true);
         toolBar("mainToolBar").show();
      }

      slotStatusMsg(i18n("Ready."));
   }

    /** toggles the statusbar
     */
   void slotViewStatusBar() {
      slotStatusMsg(i18n("Toggle the statusbar..."));
      ///////////////////////////////////////////////////////////////////
      //turn Statusbar on or off
      if( menuBar().isItemChecked(ID_VIEW_STATUSBAR)) {
         menuBar().setItemChecked(ID_VIEW_STATUSBAR, false);
         ((KStatusBar) statusBar()).hide();

      }
      else {
         menuBar().setItemChecked(ID_VIEW_STATUSBAR, true);
         ((KStatusBar) statusBar()).show();
      }

      slotStatusMsg(i18n("Ready."));
   }

   void slotWindowNewWindow() {
      slotStatusMsg(i18n("Opening a new application window..."));

      KScribbleView m = (KScribbleView) pWorkspace.activeWindow();
      if ( m != null ){
         KScribbleDoc doc = m.getDocument();
          createClient(doc);
      }

      slotStatusMsg(i18n("Ready."));
   }

    /** changes the statusbar contents for the standard label permanently, used to indicate current actions.
     * @param text the text that is displayed in the statusbar
     */
   public void slotStatusMsg(String text) {
      ///////////////////////////////////////////////////////////////////
      // change status message permanently
      ((KStatusBar) statusBar()).clear();
      ((KStatusBar) statusBar()).changeItem(text, ID_STATUS_MSG);
   }

   /** accepts drops and opens a new document
   for each drop */
   void dropEvent( QDropEvent e){
      QImage img = new QImage();
      if ( QImageDrag.decode(e, img) ) {
         KScribbleDoc doc = new KScribbleDoc();
         untitledCount+=1;
         String fileName= i18n("Untitled") + untitledCount;
         doc.setPathName(fileName);
         doc.setTitle(fileName);
         doc.newDocument();
         pDocList.add(doc);
         KPixmap tmp = new KPixmap();
         tmp.resize(img.size());
         tmp.convertFromImage(img);
         doc.setPixmap(tmp);
         doc.resizeDocument(tmp.size());
         doc.setModified();
         createClient(doc);
      }
   }
   /** accepts drag events for images */
   void dragEnterEvent( QDragEnterEvent e){
     e.accept(QImageDrag.canDecode(e));
   }


}
