/**********************************************************************
 This file is based on TQt Designer, Copyright (C) 2000 Trolltech AS. All rights reserved.

 This file may be distributed and/or modified under the terms of the
 GNU General Public License version 2 as published by the Free Software
 Foundation and appearing in the file LICENSE.GPL included in the
 packaging of this file.

 This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

 See http://www.trolltech.com/gpl/ for GPL licensing information.

 Modified for Kommander:
  (C) 2002-2003 Marc Britton <consume@optusnet.com.au>
  (C) 2004      Michal Rudolf <mrudolf@kdewebdev.org>

**********************************************************************/

#include "mainwindow.h"

#include <tqapplication.h>
#include <tqclipboard.h>
#include <tqfileinfo.h>
#include <tqlineedit.h>
#include <tqlistbox.h>
#include <tqsignalmapper.h>
#include <tqspinbox.h>
#include <statusbar.h>
#include <tqstylefactory.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>
#include <tqworkspace.h>

#include "defs.h"
#include "widgetdatabase.h"
#include "widgetfactory.h"
#include "preferences.h"
#include "formwindow.h"
#include "newformimpl.h"
#include "resource.h"
#include "workspace.h"
#include "createtemplate.h"
#include "hierarchyview.h"
#include "formsettingsimpl.h"
#include "styledbutton.h"
#include "connectioneditorimpl.h"
#include "actioneditorimpl.h"
#include "formfile.h"
#ifndef TQT_NO_SQL
#include "dbconnectionsimpl.h"
#include "dbconnectionimpl.h"
#endif
#include "command.h"


#include <tdeaction.h>
#include <tdeapplication.h>
#include <tdefiledialog.h>
#include <tdeglobal.h>
#include <kiconloader.h>
#include <kkeydialog.h>
#include <tdelocale.h>
#include <tdemenubar.h>
#include <tdemessagebox.h>
#include <tdepopupmenu.h>
#include <kprocess.h>
#include <kstandarddirs.h>
#include <kstatusbar.h>
#include <kstdguiitem.h>
#include <kurl.h>

#include <tdetexteditor/document.h>
#include <tdetexteditor/view.h>
#include <tdetexteditor/configinterface.h>

#include <stdlib.h>

const TQString toolbarHelp = "<p>Toolbars contain a number of buttons to "
"provide quick access to often used functions.%1"
"<br>Click on the toolbar handle to hide the toolbar, "
"or drag and place the toolbar to a different location.</p>";

static TQIconSet createIconSet( const TQString &name )
{
  TQIconSet ic( PixmapChooser::loadPixmap( name, PixmapChooser::Small ) );
  ic.setPixmap( PixmapChooser::loadPixmap( name, PixmapChooser::Disabled ), TQIconSet::Small, TQIconSet::Disabled );
  return ic;
}

int forms = 0;

void MainWindow::setupEditActions()
{
  actionEditUndo = KStdAction::undo(this, TQ_SLOT(editUndo()), actionCollection());
  actionEditUndo->setText(i18n("&Undo: Not Available"));
  actionEditUndo->setToolTip(i18n("Undoes the last action"));
  actionEditUndo->setWhatsThis(whatsThisFrom("Edit|Undo"));
  actionEditUndo->setEnabled(false);

  actionEditRedo = KStdAction::redo(this, TQ_SLOT(editRedo()), actionCollection());
  actionEditRedo->setText(i18n("&Redo: Not Available"));
  actionEditRedo->setToolTip(i18n("Redoes the last undone operation"));
  actionEditRedo->setWhatsThis(whatsThisFrom("Edit|Redo"));
  actionEditRedo->setEnabled(false);

  actionEditCut = KStdAction::cut(this, TQ_SLOT(editCut()), actionCollection());
  actionEditCut->setToolTip(i18n("Cuts the selected widgets and puts them on the clipboard"));
  actionEditCut->setWhatsThis(whatsThisFrom("Edit|Cut"));
  actionEditCut->setEnabled(false);

  actionEditCopy = KStdAction::copy(this, TQ_SLOT(editCopy()), actionCollection());
  actionEditCopy->setToolTip(i18n("Copies the selected widgets to the clipboard"));
  actionEditCopy->setWhatsThis(whatsThisFrom("Edit|Copy"));
  actionEditCopy->setEnabled(false);

  actionEditPaste = KStdAction::paste(this, TQ_SLOT(editPaste()), actionCollection());
  actionEditPaste->setToolTip(i18n("Pastes the clipboard's contents"));
  actionEditPaste->setWhatsThis(whatsThisFrom("Edit|Paste"));
  actionEditPaste->setEnabled(false);

  actionEditDelete = new TDEAction(i18n("Delete"), Key_Delete, this, TQ_SLOT(editDelete()),
                                 actionCollection(), "edit_delete");
  actionEditDelete->setToolTip(i18n("Deletes the selected widgets"));
  actionEditDelete->setWhatsThis(whatsThisFrom("Edit|Delete"));
  actionEditDelete->setEnabled(false);

  actionEditSelectAll = KStdAction::selectAll(this, TQ_SLOT(editSelectAll()), actionCollection());
  actionEditSelectAll->setToolTip(i18n("Selects all widgets"));
  actionEditSelectAll->setWhatsThis(whatsThisFrom("Edit|Select All"));

  actionEditRaise = new TDEAction(i18n("Bring to Front"), createIconSet("editraise.xpm"),
                                TDEShortcut::null(), this, TQ_SLOT(editRaise()), actionCollection(), "edit_raise");
  actionEditRaise->setToolTip(i18n("Raises the selected widgets"));
  actionEditRaise->setEnabled(false);

  actionEditLower = new TDEAction(i18n("Send to Back"), createIconSet("editlower.xpm"),
                                TDEShortcut::null(), this, TQ_SLOT(editLower()), actionCollection(), "edit_lower");
  actionEditLower->setToolTip(i18n("Lowers the selected widgets"));
  actionEditLower->setWhatsThis(i18n("Lowers the selected widgets"));
  actionEditLower->setEnabled(false);

  actionEditFindGlobal = new TDEAction(i18n("Find in Form..."), CTRL + ALT + Key_F, this, TQ_SLOT(editFindGlobal()), actionCollection(), "edit_find_global");
  actionEditFindGlobal->setToolTip(i18n("Search for a text in the whole form."));
  actionEditFindGlobal->setWhatsThis(whatsThisFrom("Edit|Find in Form"));
  connect(this, TQ_SIGNAL(hasActiveForm(bool)), actionEditFindGlobal, TQ_SLOT(setEnabled(bool)));

  actionEditAccels = new TDEAction(i18n("Check Accelerators"), ALT + Key_R, this, TQ_SLOT(editAccels()),
                                 actionCollection(), "edit_check_accel");
  actionEditAccels->setToolTip(i18n("Checks if the accelerators used in the form are unique"));
  actionEditAccels->setWhatsThis(whatsThisFrom("Edit|Check Accelerator"));
  connect(this, TQ_SIGNAL(hasActiveForm(bool)), actionEditAccels, TQ_SLOT(setEnabled(bool)));

  actionEditConnections = new TDEAction(i18n("Connections"), createIconSet("connecttool.xpm"),
                                      TDEShortcut::null(), this, TQ_SLOT(editConnections()), actionCollection(),
                                      "edit_connections");
  actionEditConnections->setToolTip(i18n("Opens a dialog for editing connections"));
  actionEditConnections->setWhatsThis(whatsThisFrom("Edit|Connections"));
  connect(this, TQ_SIGNAL(hasActiveForm(bool)), actionEditConnections, TQ_SLOT(setEnabled(bool)));

  actionEditFormSettings = new TDEAction(i18n("Form Settings..."), TDEShortcut::null(),
                                       this, TQ_SLOT(editFormSettings()), actionCollection(), "edit_form");
  actionEditFormSettings->setToolTip(i18n("Opens a dialog to change the form's settings"));
  actionEditFormSettings->setWhatsThis(whatsThisFrom("Edit|Form Settings"));
  connect(this, TQ_SIGNAL(hasActiveForm(bool)), actionEditFormSettings, TQ_SLOT(setEnabled(bool)));

  TDEToolBar *tb = new TDEToolBar(this, "Edit");
  tb->setFullSize(false);
  TQWhatsThis::add(tb, i18n("<b>The Edit toolbar</b>%1").arg(toolbarHelp));
  addToolBar(tb, i18n("Edit"));
  actionEditUndo->plug(tb);
  actionEditRedo->plug(tb);
  tb->addSeparator();
  actionEditCut->plug(tb);
  actionEditCopy->plug(tb);
  actionEditPaste->plug(tb);

  TQPopupMenu *menu = new TQPopupMenu(this, "Edit");
  menuBar()->insertItem(i18n("&Edit"), menu);
  actionEditUndo->plug(menu);
  actionEditRedo->plug(menu);
  menu->insertSeparator();
  actionEditCut->plug(menu);
  actionEditCopy->plug(menu);
  actionEditPaste->plug(menu);
  actionEditDelete->plug(menu);
  actionEditSelectAll->plug(menu);
  actionEditAccels->plug(menu);
  menu->insertSeparator();
//   actionEditFindGlobal->plug(menu); //enable when implemented
  actionEditConnections->plug(menu);
  actionEditFormSettings->plug(menu);
  menu->insertSeparator();

}


void MainWindow::setupLayoutActions()
{
  actionEditAdjustSize = new TDEAction(i18n("Adjust Size"), createIconSet("adjustsize.xpm"),
                                     CTRL + Key_J, this, TQ_SLOT(editAdjustSize()), actionCollection(), "edit_adjust_size");
  actionEditAdjustSize->setToolTip(i18n("Adjusts the size of the selected widget"));
  actionEditAdjustSize->setWhatsThis(whatsThisFrom("Layout|Adjust Size"));
  actionEditAdjustSize->setEnabled(false);

  actionEditHLayout = new TDEAction(i18n("Lay Out Horizontally"), createIconSet("edithlayout.xpm"),
                                  CTRL + Key_H, this, TQ_SLOT(editLayoutHorizontal()), actionCollection(), "edit_layout_h");
  actionEditHLayout->setToolTip(i18n("Lays out the selected widgets horizontally"));
  actionEditHLayout->setWhatsThis(whatsThisFrom("Layout|Lay Out Horizontally"));
  actionEditHLayout->setEnabled(false);

  actionEditVLayout = new TDEAction(i18n("Lay Out Vertically"), createIconSet("editvlayout.xpm"),
                                  CTRL + Key_L, this, TQ_SLOT(editLayoutVertical()), actionCollection(), "edit_layout_v");
  actionEditVLayout->setToolTip(i18n("Lays out the selected widgets vertically"));
  actionEditVLayout->setWhatsThis(whatsThisFrom("Layout|Lay Out Vertically"));
  actionEditVLayout->setEnabled(false);

  actionEditGridLayout = new TDEAction(i18n("Lay Out in a Grid"), createIconSet("editgrid.xpm"),
                                     CTRL + Key_G, this, TQ_SLOT(editLayoutGrid()), actionCollection(), "edit_layout_grid");
  actionEditGridLayout->setToolTip(i18n("Lays out the selected widgets in a grid"));
  actionEditGridLayout->setWhatsThis(whatsThisFrom("Layout|Lay Out in a Grid"));
  actionEditGridLayout->setEnabled(false);

  actionEditSplitHorizontal = new TDEAction(i18n("Lay Out Horizontally in Splitter"), createIconSet("editvlayoutsplit.xpm"),
                                          TDEShortcut::null(), this, TQ_SLOT(editLayoutHorizontalSplit()), actionCollection(),
                                          "edit_split_h");
  actionEditSplitHorizontal->setToolTip(i18n("Lays out the selected widgets horizontally in a splitter"));
  actionEditSplitHorizontal->setWhatsThis(whatsThisFrom("Layout|Lay Out Horizontally in Splitter"));
  actionEditSplitHorizontal->setEnabled(false);

  actionEditSplitVertical = new TDEAction(i18n("Lay Out Vertically in Splitter"), createIconSet("edithlayoutsplit.xpm"),
                                        TDEShortcut::null(), this, TQ_SLOT(editLayoutVerticalSplit()), actionCollection(),
                                        "edit_split_v");
  actionEditSplitVertical->setToolTip(i18n("Lays out the selected widgets vertically in a splitter"));
  actionEditSplitVertical->setWhatsThis(whatsThisFrom("Layout|Lay Out Vertically (in Splitter)"));
  actionEditSplitVertical->setEnabled(false);

  actionEditBreakLayout = new TDEAction(i18n("Break Layout"), createIconSet("editbreaklayout.xpm"),
                                      CTRL + Key_B, this, TQ_SLOT(editBreakLayout()), actionCollection(), "edit_break_layout");
  actionEditBreakLayout->setToolTip(i18n("Breaks the selected layout"));
  actionEditBreakLayout->setWhatsThis(whatsThisFrom("Layout|Break Layout"));

  int id = WidgetDatabase::idFromClassName("Spacer");
  TDEToggleAction *a = new TDEToggleAction(i18n("Spacer"), createIconSet("spacer.xpm"), TDEShortcut::null(), this, TQ_SLOT(toolSelected()),
                                       actionCollection(), TQString::number(id).latin1());
  a->setExclusiveGroup("tool");
  a->setText(i18n("Add ") + WidgetDatabase::className(id));
  a->setToolTip(i18n("Insert a %1").arg(WidgetDatabase::toolTip(id)));
  a->setWhatsThis(i18n("<b>A %1</b><p>%2</p>"
      "<p>Click to insert a single %3,"
      "or double click to keep the tool selected.").arg(WidgetDatabase::toolTip(id)).
      arg(WidgetDatabase::whatsThis(id)).arg(WidgetDatabase::toolTip(id)));

  TQWhatsThis::add(layoutToolBar, i18n("<b>The Layout toolbar</b>%1").arg(toolbarHelp));
  actionEditAdjustSize->plug(layoutToolBar);
  layoutToolBar->addSeparator();
  actionEditHLayout->plug(layoutToolBar);
  actionEditVLayout->plug(layoutToolBar);
  actionEditGridLayout->plug(layoutToolBar);
  actionEditSplitHorizontal->plug(layoutToolBar);
  actionEditSplitVertical->plug(layoutToolBar);
  actionEditBreakLayout->plug(layoutToolBar);
  layoutToolBar->addSeparator();
  a->plug(layoutToolBar);

  TQPopupMenu *menu = new TQPopupMenu(this, "Layout");
  menuBar()->insertItem(i18n("&Layout"), menu);
  actionEditAdjustSize->plug(menu);
  menu->insertSeparator();
  actionEditHLayout->plug(menu);
  actionEditVLayout->plug(menu);
  actionEditGridLayout->plug(menu);
  actionEditSplitHorizontal->plug(menu);
  actionEditSplitVertical->plug(menu);
  actionEditBreakLayout->plug(menu);
  menu->insertSeparator();
  a->plug(menu);
}

void MainWindow::setupToolActions()
{
  actionPointerTool = new TDEToggleAction(i18n("Pointer"), "arrow", Key_F2,
                                        this, TQ_SLOT(toolSelected()), actionCollection(),
                                        TQString::number(POINTER_TOOL).latin1());
  actionPointerTool->setToolTip(i18n("Selects the pointer tool"));
  actionPointerTool->setWhatsThis(whatsThisFrom("Tools|Pointer"));
  actionPointerTool->setExclusiveGroup("tool");

  actionConnectTool = new TDEToggleAction(i18n("Connect Signal/Slots"), createIconSet("connecttool.xpm"),
                                        Key_F3, this, TQ_SLOT(toolSelected()), actionCollection(),
                                        TQString::number(CONNECT_TOOL).latin1());
  actionConnectTool->setToolTip(i18n("Selects the connection tool"));
  actionConnectTool->setWhatsThis(whatsThisFrom("Tools|Connect Signals and Slots"));
  actionConnectTool->setExclusiveGroup("tool");

  actionOrderTool = new TDEToggleAction(i18n("Tab Order"), createIconSet("ordertool.xpm"),
                                      Key_F4, this, TQ_SLOT(toolSelected()), actionCollection(),
                                      TQString::number(ORDER_TOOL).latin1());
  actionOrderTool->setToolTip(i18n("Selects the tab order tool"));
  actionOrderTool->setWhatsThis(whatsThisFrom("Tools|Tab Order"));
  actionOrderTool->setExclusiveGroup("tool");

  TDEToolBar *tb = new TDEToolBar(this, "Tools");
  tb->setFullSize(false);
  TQWhatsThis::add(tb, i18n("<b>The Tools toolbar</b>%1").arg(toolbarHelp));

  addToolBar(tb, i18n("Tools"), TQMainWindow::DockTop, true);
  actionPointerTool->plug(tb);
  actionConnectTool->plug(tb);
  actionOrderTool->plug(tb);

  TQPopupMenu *mmenu = new TQPopupMenu(this, "Tools");
  menuBar()->insertItem(i18n("&Tools"), mmenu);
  actionPointerTool->plug(mmenu);
  actionConnectTool->plug(mmenu);
  actionOrderTool->plug(mmenu);
  mmenu->insertSeparator();

  for (int j = 0; j < WidgetDatabase::numWidgetGroups(); ++j)
  {
    TQString grp = WidgetDatabase::widgetGroup(j);
    if (!WidgetDatabase::isGroupVisible(grp) || WidgetDatabase::isGroupEmpty(grp))
      continue;
    TDEToolBar *tb = new TDEToolBar(this, grp.latin1());
    tb->setFullSize(false);
    bool plural = grp[(int) grp.length() - 1] == 's';
    if (plural)
    {
      TQWhatsThis::add(tb, i18n("<b>The %1</b>%2").arg(grp).arg(toolbarHelp).
          arg(i18n(" Click on a button to insert a single widget, "
              "or double click to insert multiple %1.")).arg(grp));
    } else
    {
      TQWhatsThis::add(tb, i18n("<b>The %1 Widgets</b>%2").arg(grp).arg(toolbarHelp).
          arg(i18n(" Click on a button to insert a single %1 widget, "
              "or double click to insert multiple widgets.")).arg(grp));
    }
    addToolBar(tb, grp);
    TQPopupMenu *menu = new TQPopupMenu(this, grp.latin1());
    mmenu->insertItem(grp, menu);

    for (int i = 0; i < WidgetDatabase::count(); ++i)
    {
      if (WidgetDatabase::group(i) != grp)
        continue;               // only widgets, i.e. not forms and temp stuff
      TDEToggleAction *a = new TDEToggleAction(WidgetDatabase::className(i), TDEShortcut::null(),
                                           this, TQ_SLOT(toolSelected()), actionCollection(), TQString::number(i).latin1());
      a->setExclusiveGroup("tool");
      TQString atext = WidgetDatabase::className(i);
      if (atext[0] == 'Q')
        atext = atext.mid(1);
      while (atext.length() && atext[0] >= 'a' && atext[0] <= 'z')
        atext = atext.mid(1);
      if (atext.isEmpty())
        atext = WidgetDatabase::className(i);
      a->setText(atext);
      TQString ttip = WidgetDatabase::toolTip(i);
      a->setIconSet(WidgetDatabase::iconSet(i));
      a->setToolTip(ttip);
      if (!WidgetDatabase::isWhatsThisLoaded())
        WidgetDatabase::loadWhatsThis(documentationPath());
      a->setToolTip(i18n("Insert a %1").arg(WidgetDatabase::className(i)));

      TQString whats = i18n("<b>A %1</b>").arg(WidgetDatabase::className(i));
      if (!WidgetDatabase::whatsThis(i).isEmpty())
        whats += TQString("<p>%1</p>").arg(WidgetDatabase::whatsThis(i));
      a->setWhatsThis(whats + i18n("<p>Double click on this tool to keep it selected.</p>"));

      if (grp != "KDE")
        a->plug(tb);
      a->plug(menu);
    }
  }

  // add external Kommander dialogs for Editor
  m_editorTools.clear();
  TQPopupMenu* editMenu = new TQPopupMenu(this);
  TQStringList searchPaths = TDEGlobal::dirs()->findDirs("data", "kmdr-editor/editor");
  for (TQStringList::ConstIterator it = searchPaths.begin(); it != searchPaths.end(); ++it)
  {
    if (!TQFile::exists(*it))
      continue;
    TQDir dir(*it);
    const TQFileInfoList* fileList = dir.entryInfoList(TQDir::DefaultFilter, TQDir::DirsFirst | TQDir::Name);
    if (fileList)
      for (TQFileInfoListIterator fit(*fileList); fit.current(); ++fit)
      {
        TQFileInfo* fi = fit.current();
        if (!fi->isFile() || fi->extension() != "kmdr")
          continue;
        TQString name = fi->baseName();
        name = name.replace("_", " ");
        editMenu->insertItem(name, this, TQ_SLOT(editExternalTool(int)), 0, m_editorTools.count());
        m_editorTools.append(fi->filePath());
      }
  }
  if (editMenu->count())
    mmenu->insertItem(i18n("Editor"), editMenu);

  resetTool();
}

void MainWindow::setupFileActions()
{
  fileTb = new TDEToolBar(this, "File");
  fileTb->setFullSize(false);

  TQWhatsThis::add(fileTb, i18n("<b>The File toolbar</b>%1").arg(toolbarHelp));
  addToolBar(fileTb, i18n("File"));
  fileMenu = new TQPopupMenu(this, "File");
  menuBar()->insertItem(i18n("&File"), fileMenu);

  TDEAction *a = KStdAction::openNew(this, TQ_SLOT(fileNew()), actionCollection());
  a->setToolTip(i18n("Creates a new dialog"));
  a->setWhatsThis(whatsThisFrom("File|New"));
  a->plug(fileTb);
  a->plug(fileMenu);

  a = KStdAction::open(this, TQ_SLOT(fileOpen()), actionCollection());
  a->setToolTip(i18n("Opens an existing dialog"));
  a->setWhatsThis(whatsThisFrom("File|Open"));
  a->plug(fileTb);
  a->plug(fileMenu);

  actionRecent = KStdAction::openRecent(this,  TQ_SLOT(fileOpenRecent(const KURL&)), actionCollection());
  actionRecent->setToolTip(i18n("Opens recently open file"));
  actionRecent->plug(fileMenu);

  fileMenu->insertSeparator();
  a = KStdAction::close(this, TQ_SLOT(fileClose()), actionCollection());
  a->setToolTip(i18n("Closes the current dialog"));
  a->setWhatsThis(whatsThisFrom("File|Close"));
  connect(this, TQ_SIGNAL(hasActiveWindow(bool)), a, TQ_SLOT(setEnabled(bool)));
  a->plug(fileMenu);

  fileMenu->insertSeparator();

  a = KStdAction::save(this, TQ_SLOT(fileSave()), actionCollection());
  a->setToolTip(i18n("Saves the current dialog"));
  a->setWhatsThis(whatsThisFrom("File|Save"));
  connect(this, TQ_SIGNAL(hasActiveWindow(bool)), a, TQ_SLOT(setEnabled(bool)));
  a->plug(fileTb);
  a->plug(fileMenu);

  a = KStdAction::saveAs(this, TQ_SLOT(fileSaveAs()), actionCollection());
  a->setToolTip(i18n("Saves the current dialog with a new filename"));
  a->setWhatsThis(whatsThisFrom("File|Save As"));
  connect(this, TQ_SIGNAL(hasActiveWindow(bool)), a, TQ_SLOT(setEnabled(bool)));
  a->plug(fileMenu);

  a = new TDEAction(i18n("Save All"), "save_all", TDEShortcut::null(), this, TQ_SLOT(fileSaveAll()),
                  actionCollection(), "file_close_all");
  a->setToolTip(i18n("Saves all open dialogs"));
  a->setWhatsThis(whatsThisFrom("File|Save All"));
  connect(this, TQ_SIGNAL(hasActiveWindow(bool)), a, TQ_SLOT(setEnabled(bool)));
  a->plug(fileMenu);

  fileMenu->insertSeparator();

  a = KStdAction::quit(kapp, TQ_SLOT(closeAllWindows()), actionCollection());
  a->setToolTip(i18n("Quits the application and prompts to save any changed dialogs"));
  a->setWhatsThis(whatsThisFrom("File|Exit"));
  a->plug(fileMenu);
}


void MainWindow::setupRunActions()
{
  TQPopupMenu *menu = new TQPopupMenu(this, "Run");
  menuBar()->insertItem(i18n("&Run"), menu);

  TDEAction* a = new TDEAction(i18n("Run Dialog"), "system-run", CTRL + Key_R,
                           this, TQ_SLOT(runForm()), actionCollection(), "run");
  a->setToolTip(i18n("Executes dialog"));
  a->setWhatsThis(whatsThisFrom("Run|Run dialog"));
  connect(this, TQ_SIGNAL(hasActiveForm(bool)), a, TQ_SLOT(setEnabled(bool)));
  a->plug(fileTb);
  a->plug(menu);
}

void MainWindow::setupWindowActions()
{
  static bool windowActionsSetup = false;
  if (!windowActionsSetup)
  {
    windowActionsSetup = true;

    TDEAction* actionWindowTile = new TDEAction(i18n("Tile"), TDEShortcut::null(), qworkspace,  TQ_SLOT(tile()),
                                   actionCollection(), "window_tile");
    actionWindowTile->setToolTip(i18n("Tiles the windows so that they are all visible"));
    actionWindowTile->setWhatsThis(whatsThisFrom("Window|Tile"));

    TDEAction* actionWindowCascade = new TDEAction(i18n("Cascade"), TDEShortcut::null(), qworkspace,  TQ_SLOT(cascade()),
                                      actionCollection(), "window_cascade");
    actionWindowCascade->setToolTip(i18n("Cascades the windows so that all their title bars are visible"));
    actionWindowCascade->setWhatsThis(whatsThisFrom("Window|Cascade"));

    TDEAction* actionWindowClose = new TDEAction(i18n("Cascade"), TDEShortcut::null(), qworkspace,  TQ_SLOT(closeActiveWindow()),
                                    actionCollection(), "window_close");
    actionWindowClose->setToolTip(i18n("Closes the active window"));
    actionWindowClose->setWhatsThis(whatsThisFrom("Window|Close"));

    TDEAction* actionWindowCloseAll = new TDEAction(i18n("Close All"), TDEShortcut::null(), qworkspace, 
                                       TQ_SLOT(closeAllWindows()), actionCollection(), "window_close_all");
    actionWindowCloseAll->setToolTip(i18n("Closes all form windows"));
    actionWindowCloseAll->setWhatsThis(whatsThisFrom("Window|Close All"));

    TDEAction* actionWindowNext = new TDEAction(i18n("Next"), Key_F6, qworkspace, 
                                   TQ_SLOT(activateNextWindow()), actionCollection(), "window_next");
    actionWindowNext->setToolTip(i18n("Activates the next window"));
    actionWindowNext->setWhatsThis(whatsThisFrom("Window|Next"));

    TDEAction* actionWindowPrevious = new TDEAction(i18n("Previous"), CTRL + SHIFT + Key_F6, qworkspace, 
                                       TQ_SLOT(activatePreviousWindow()), actionCollection(), "window_prev");
    actionWindowPrevious->setToolTip(i18n("Activates the previous window"));
    actionWindowPrevious->setWhatsThis(whatsThisFrom("Window|Previous"));

    windowMenu = new TDEPopupMenu(this, "Window");
    menuBar()->insertItem(i18n("&Window"), windowMenu);
    connect(windowMenu, TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(setupWindowActions()));

    actionWindowClose->plug(windowMenu);
    actionWindowCloseAll->plug(windowMenu);
    windowMenu->insertSeparator();
    actionWindowNext->plug(windowMenu);
    actionWindowPrevious->plug(windowMenu);
    windowMenu->insertSeparator();
    actionWindowTile->plug(windowMenu);
    actionWindowCascade->plug(windowMenu);
    windowMenu->insertSeparator();
    windowMenu->insertItem(i18n("Vie&ws"), dockHideShowMenu());
    windowMenu->insertItem(i18n("Tool&bars"), createDockWindowMenu(OnlyToolBars));
  }

  //FIXME  find a better way to remove only menu items linked to dialogs/forms
  while (windowMenu->count() > 11)
    windowMenu->removeItemAt(windowMenu->count() - 1);

  TQWidgetList windows = qworkspace->windowList();
  if (windows.count() && formWindow())
    windowMenu->insertSeparator();
  int j = 0;
  for (int i = 0; i < int (windows.count()); ++i)
  {
    TQWidget *w = windows.at(i);
    if (!w->inherits("FormWindow") && !w->inherits("SourceEditor"))
      continue;
    j++;
    TQString itemText;
    if (j < 10)
      itemText = TQString("&%1 ").arg(j);
    if (w->inherits("FormWindow"))
      itemText += w->name();
    else
      itemText += w->caption();

    int id = windowMenu->insertItem(itemText, this, TQ_SLOT(windowsMenuActivated(int)));
    windowMenu->setItemParameter(id, i);
    windowMenu->setItemChecked(id, qworkspace->activeWindow() == windows.at(i));
  }
}


void MainWindow::setupSettingsActions()
{
  TDEPopupMenu *settings = new TDEPopupMenu(this, "Settings");
  TDEAction* a = KStdAction::keyBindings(this, TQ_SLOT(editShortcuts()), actionCollection());
  a->setToolTip(i18n("Opens a dialog to change shortcuts"));
  a->plug(settings);

  a = new TDEAction(i18n("Configure &Plugins..."), TDEShortcut::null(), this, TQ_SLOT(editPlugins()),
                  actionCollection(), "configure_plugins");
  a->setToolTip(i18n("Opens a dialog to configure plugins"));
  a->plug(settings);

  a = new TDEAction(i18n("&Configure Editor..."), TDEShortcut::null(), this, TQ_SLOT(configureEditor()),
                  actionCollection(), "configure_editor");
  a->setToolTip(i18n("Configure various aspects of this editor."));
  a->plug(settings);

  a = KStdAction::preferences(this, TQ_SLOT(editPreferences()), actionCollection());
  a->setToolTip(i18n("Opens a dialog to change preferences"));
  a->setWhatsThis(whatsThisFrom("Edit|Preferences"));
  a->plug(settings);

  menuBar()->insertItem( i18n("&Settings"), settings);
}

void MainWindow::setupHelpActions()
{
  TDEPopupMenu *help = helpMenu();
  menuBar()->insertItem( i18n("&Help"), help);
}


void MainWindow::fileNew()
{
  statusBar()->message(i18n("Create a new dialog..."));
  NewForm dlg(this, TQString());
  dlg.exec();
  statusBar()->clear();
}

void MainWindow::fileClose()
{
  TQWidget *w = qworkspace->activeWindow();
  if (w->inherits("FormWindow"))
  {
    emit removedFormFile(((FormWindow *) w)->formFile());
    ((FormWindow *) w)->formFile()->close();
  }
}

void MainWindow::fileOpen()     // as called by the menu
{
  fileOpen("");
}

void MainWindow::fileOpen(const TQString & fn)
{
  statusBar()->message(i18n("Open a file..."));
  TQStringList additionalSources;

  TQStringList filenames;
  if (fn.isEmpty())
    filenames = KFileDialog::getOpenFileNames(TQString(), i18n("*.kmdr|Kommander Files"), this, i18n("Open Files"));
  else
    filenames << fn;
  for (TQStringList::ConstIterator fit = filenames.constBegin(); fit != filenames.constEnd(); ++fit)
  {
    TQString filename = *fit;
    if (!filename.isEmpty())
    {
      TQFileInfo fi(filename);
      if (fi.exists() && openFormWindow(filename))
        actionRecent->addURL(filename);
    }
  }
}



FormWindow *MainWindow::openFormWindow(const TQString &filename, bool validFileName, FormFile *ff)
{
  if (filename.isEmpty())
    return 0;

  bool makeNew = false;

  if (!TQFile::exists(filename))
  {
    makeNew = true;
  } else
  {
    TQFile f(filename);
    f.open(IO_ReadOnly);
    TQTextStream ts(&f);
    makeNew = ts.read().length() < 2;
  }
  if (!makeNew)
  {
    statusBar()->message(i18n("Reading file '%1'...").arg(filename));
    if (TQFile::exists(filename))
    {
      TQApplication::setOverrideCursor(WaitCursor);
      Resource resource(this);
      if (!ff)
        ff = new FormFile(filename, false);
      bool b = resource.load(ff) && (FormWindow *) resource.widget();
      if (!validFileName && resource.widget())
        ((FormWindow *) resource.widget())->setFileName(TQString());
      TQApplication::restoreOverrideCursor();
      if (b)
      {
        statusBar()->message(i18n("Loaded file '%1'").arg(filename), 3000);
      } else
      {
 	emit removedFormFile(ff);
	ff->close();
        delete ff;
        statusBar()->message(i18n("Could not load file '%1'").arg(filename), 5000);
        KMessageBox::information(this, i18n("Could not load file '%1'").arg(filename), i18n("Load File"));
      }
      return (FormWindow *) resource.widget();
    } else
    {
      statusBar()->clear();
    }
  } else
  {
    fileNew();
    if (formWindow())
      formWindow()->setFileName(filename);
    return formWindow();
  }
  return 0;
}

bool MainWindow::fileSave()
{
  return fileSaveForm();
}

bool MainWindow::fileSaveForm()
{
  FormWindow* fw = 0;
  if (!fw)
    fw = formWindow();
  if (!fw || !fw->formFile()->save())
    return false;
  TQApplication::restoreOverrideCursor();
  return true;
}

bool MainWindow::fileSaveAs()
{
  statusBar()->message(i18n("Enter a filename..."));

  TQWidget *w = qworkspace->activeWindow();
  if (!w)
    return true;
  if (w->inherits("FormWindow"))
    return ((FormWindow *) w)->formFile()->saveAs();
  return false;
}

void MainWindow::fileSaveAll()
{
  TQWidgetList windows = qworkspace->windowList(TQWorkspace::StackingOrder);
  for (int i = 0; i < (int)windows.count(); ++i)
  {
    FormWindow* fw = dynamic_cast<FormWindow*>(windows.at(i));
    if (fw)
      fw->formFile()->save();
  }
}

static bool inSaveAllTemp = false;

void MainWindow::saveAllTemp()
{
  if (inSaveAllTemp)
    return;
  inSaveAllTemp = true;
  statusBar()->message(i18n("TQt Designer is crashing. Attempting to save files..."));
  TQWidgetList windows = qWorkspace()->windowList();
  TQString baseName = TQDir::homeDirPath() + "/.designer/saved-form-";
  int i = 1;
  for (TQWidget * w = windows.first(); w; w = windows.next())
  {
    if (!w->inherits("FormWindow"))
      continue;

    TQString fn = baseName + TQString::number(i++) + ".kmdr";
    ((FormWindow *) w)->setFileName(fn);
    ((FormWindow *) w)->formFile()->save();
  }
  inSaveAllTemp = false;
}

void MainWindow::fileCreateTemplate()
{
  CreateTemplate dia(this, 0, true);

  int i = 0;
  for (i = 0; i < WidgetDatabase::count(); ++i)
  {
    if (WidgetDatabase::isForm(i) && WidgetDatabase::widgetGroup(i) != "Temp")
    {
      dia.listClass->insertItem(WidgetDatabase::className(i));
    }
  }
  for (i = 0; i < WidgetDatabase::count(); ++i)
  {
    if (WidgetDatabase::isContainer(i) && !WidgetDatabase::isForm(i) &&
        WidgetDatabase::className(i) != "TQTabWidget" && WidgetDatabase::widgetGroup(i) != "Temp")
    {
      dia.listClass->insertItem(WidgetDatabase::className(i));
    }
  }

  dia.editName->setText(i18n("NewTemplate"));
  connect(dia.buttonCreate, TQ_SIGNAL(clicked()), this, TQ_SLOT(createNewTemplate()));
  dia.exec();
}

void MainWindow::createNewTemplate()
{
  CreateTemplate *dia = (CreateTemplate *) sender()->parent();
  TQString fn = dia->editName->text();
  TQString cn = dia->listClass->currentText();
  if (fn.isEmpty() || cn.isEmpty())
  {
    KMessageBox::information(this, i18n("Could not create the template"), i18n("Create Template"));
    return;
  }

  TQStringList templRoots;
  const char *qtdir = getenv("TQTDIR");
  if (qtdir)
    templRoots << qtdir;
#ifdef TQT_INSTALL_PREFIX
  templRoots << TQT_INSTALL_PREFIX;
#endif
#ifdef TQT_INSTALL_DATA
  templRoots << TQT_INSTALL_DATA;
#endif
  if (qtdir)                    //try the tools/designer directory last!
    templRoots << TQString(qtdir) + "/tools/designer";
  TQFile f;
  for (TQStringList::Iterator it = templRoots.begin(); it != templRoots.end(); ++it)
  {
    if (TQFile::exists((*it) + "/templates/"))
    {
      TQString tmpfn = (*it) + "/templates/" + fn + ".kmdr";
      f.setName(tmpfn);
      if (f.open(IO_WriteOnly))
        break;
    }
  }
  if (!f.isOpen())
  {
    KMessageBox::information(this, i18n("Could not create the template"), i18n("Create Template"));
    return;
  }
  TQTextStream ts(&f);

  ts << "<!DOCTYPE UI><UI>" << endl;
  ts << "<widget>" << endl;
  ts << "<class>" << cn << "</class>" << endl;
  ts << "<property stdset=\"1\">" << endl;
  ts << "    <name>name</name>" << endl;
  ts << "    <cstring>" << cn << "Form</cstring>" << endl;
  ts << "</property>" << endl;
  ts << "<property stdset=\"1\">" << endl;
  ts << "    <name>geometry</name>" << endl;
  ts << "    <rect>" << endl;
  ts << "        <width>300</width>" << endl;
  ts << "        <height>400</height>" << endl;
  ts << "    </rect>" << endl;
  ts << "</property>" << endl;
  ts << "</widget>" << endl;
  ts << "</UI>" << endl;

  dia->editName->setText(i18n("NewTemplate"));

  f.close();
}

void MainWindow::editUndo()
{
  if (formWindow())
    formWindow()->undo();
}

void MainWindow::editRedo()
{
  if (formWindow())
    formWindow()->redo();
}

void MainWindow::editCut()
{
  editCopy();
  editDelete();
}

void MainWindow::editCopy()
{
  if (formWindow())
    tqApp->clipboard()->setText(formWindow()->copy());
}

void MainWindow::editPaste()
{
  if (!formWindow())
    return;

  TQWidget *w = formWindow()->mainContainer();
  TQWidgetList l(formWindow()->selectedWidgets());
  if (l.count() == 1)
  {
    w = l.first();
    if (WidgetFactory::layoutType(w) != WidgetFactory::NoLayout ||
        (!WidgetDatabase::isContainer(WidgetDatabase::idFromClassName(WidgetFactory::
                    classNameOf(w))) && w != formWindow()->mainContainer()))
      w = formWindow()->mainContainer();
  }

  if (w && WidgetFactory::layoutType(w) == WidgetFactory::NoLayout)
  {
    formWindow()->paste(tqApp->clipboard()->text(), WidgetFactory::containerOfWidget(w));
    hierarchyView->widgetInserted(0);
    formWindow()->commandHistory()->setModified(true);
  } else
  {
    KMessageBox::information(this, i18n("Cannot paste widgets. Designer could not find a container\n"
            "to paste into which does not contain a layout. Break the layout\n"
            "of the container you want to paste into and select this container\n"
                "and then paste again."), i18n("Paste Error"));
  }
}

void MainWindow::editDelete()
{
  if (formWindow())
    formWindow()->deleteWidgets();
}

void MainWindow::editSelectAll()
{
  if (formWindow())
    formWindow()->selectAll();
}

void MainWindow::editLower()
{
  if (formWindow())
    formWindow()->lowerWidgets();
}

void MainWindow::editRaise()
{
  if (formWindow())
    formWindow()->raiseWidgets();
}

void MainWindow::editAdjustSize()
{
  if (formWindow())
    formWindow()->editAdjustSize();
}

void MainWindow::editLayoutHorizontal()
{
  if (layoutChilds)
    editLayoutContainerHorizontal();
  else if (layoutSelected && formWindow())
    formWindow()->layoutHorizontal();
}

void MainWindow::editLayoutVertical()
{
  if (layoutChilds)
    editLayoutContainerVertical();
  else if (layoutSelected && formWindow())
    formWindow()->layoutVertical();
}

void MainWindow::editLayoutHorizontalSplit()
{
  if (layoutChilds)
    ;                           // no way to do that
  else if (layoutSelected && formWindow())
    formWindow()->layoutHorizontalSplit();
}

void MainWindow::editLayoutVerticalSplit()
{
  if (layoutChilds)
    ;                           // no way to do that
  else if (layoutSelected && formWindow())
    formWindow()->layoutVerticalSplit();
}

void MainWindow::editLayoutGrid()
{
  if (layoutChilds)
    editLayoutContainerGrid();
  else if (layoutSelected && formWindow())
    formWindow()->layoutGrid();
}

void MainWindow::editLayoutContainerVertical()
{
  if (!formWindow())
    return;
  TQWidget *w = formWindow()->mainContainer();
  TQWidgetList l(formWindow()->selectedWidgets());
  if (l.count() == 1)
    w = l.first();
  if (w)
    formWindow()->layoutVerticalContainer(w);
}

void MainWindow::editLayoutContainerHorizontal()
{
  if (!formWindow())
    return;
  TQWidget *w = formWindow()->mainContainer();
  TQWidgetList l(formWindow()->selectedWidgets());
  if (l.count() == 1)
    w = l.first();
  if (w)
    formWindow()->layoutHorizontalContainer(w);
}

void MainWindow::editLayoutContainerGrid()
{
  if (!formWindow())
    return;
  TQWidget *w = formWindow()->mainContainer();
  TQWidgetList l(formWindow()->selectedWidgets());
  if (l.count() == 1)
    w = l.first();
  if (w)
    formWindow()->layoutGridContainer(w);
}


void MainWindow::editBreakLayout()
{
  if (!formWindow() || !breakLayout)
  {
    return;
  }
  TQWidget *w = formWindow()->mainContainer();
  if (formWindow()->currentWidget())
    w = formWindow()->currentWidget();
  if (WidgetFactory::layoutType(w) != WidgetFactory::NoLayout ||
      w->parentWidget() && WidgetFactory::layoutType(w->parentWidget()) != WidgetFactory::NoLayout)
  {
    formWindow()->breakLayout(w);
    return;
  }
  else
  {
    TQWidgetList widgets = formWindow()->selectedWidgets();
    for (w = widgets.first(); w; w = widgets.next())
    {
      if (WidgetFactory::layoutType(w) != WidgetFactory::NoLayout ||
          w->parentWidget()
          && WidgetFactory::layoutType(w->parentWidget()) != WidgetFactory::NoLayout)
        break;
    }
    if (w)
    {
      formWindow()->breakLayout(w);
      return;
    }
  }

  w = formWindow()->mainContainer();
  if (WidgetFactory::layoutType(w) != WidgetFactory::NoLayout ||
      w->parentWidget() && WidgetFactory::layoutType(w->parentWidget()) != WidgetFactory::NoLayout)
  {
    formWindow()->breakLayout(w);
  }
}

void MainWindow::editAccels()
{
  if (formWindow())
    formWindow()->checkAccels();
}


void MainWindow::editConnections()
{
  if (!formWindow())
    return;

  statusBar()->message(i18n("Edit connections..."));
  ConnectionEditor editor(this, 0, 0, formWindow());
  editor.exec();
  statusBar()->clear();
}

void MainWindow::editFindGlobal()
{
  if (!formWindow())
    return;
  
}


void MainWindow::editFormSettings()
{
  if (!formWindow())
    return;

  statusBar()->message(i18n("Edit the current form's settings..."));
  FormSettings dlg(this, formWindow());
  dlg.exec();
  statusBar()->clear();
}

void MainWindow::editPreferences()
{
  statusBar()->message(i18n("Edit preferences..."));
  Preferences *dia = new Preferences(this, 0, true);
  prefDia = dia;
  connect(dia->helpButton, TQ_SIGNAL(clicked()), MainWindow::self, TQ_SLOT(showDialogHelp()));
  dia->buttonColor->setEditor(StyledButton::ColorEditor);
  dia->buttonPixmap->setEditor(StyledButton::PixmapEditor);
  dia->checkBoxShowGrid->setChecked(sGrid);
  dia->checkBoxGrid->setChecked(snGrid);
  dia->spinGridX->setValue(grid().x());
  dia->spinGridY->setValue(grid().y());
  dia->checkBoxWorkspace->setChecked(restoreConfig);
  dia->checkBoxBigIcons->setChecked(usesBigPixmaps());
  dia->checkBoxBigIcons->hide();  // ##### disabled for now
  dia->checkBoxTextLabels->setChecked(usesTextLabel());
  dia->buttonColor->setColor(qworkspace->backgroundColor());
  if (qworkspace->backgroundPixmap())
    dia->buttonPixmap->setPixmap(*qworkspace->backgroundPixmap());
  if (backPix)
    dia->radioPixmap->setChecked(true);
  else
    dia->radioColor->setChecked(true);
  dia->checkBoxSplash->setChecked(splashScreen);
  dia->editDocPath->setText(docPath);
  dia->checkAutoEdit->setChecked(!databaseAutoEdit);
  connect(dia->buttonDocPath, TQ_SIGNAL(clicked()), this, TQ_SLOT(chooseDocPath()));

  if (dia->exec() == TQDialog::Accepted)
  {
    setSnapGrid(dia->checkBoxGrid->isChecked());
    setShowGrid(dia->checkBoxShowGrid->isChecked());
    setGrid(TQPoint(dia->spinGridX->value(), dia->spinGridY->value()));
    restoreConfig = dia->checkBoxWorkspace->isChecked();
    setUsesBigPixmaps(false /*dia->checkBoxBigIcons->isChecked() */ );  // ### disable for now
    setUsesTextLabel(dia->checkBoxTextLabels->isChecked());
    if (dia->radioPixmap->isChecked() && dia->buttonPixmap->pixmap())
    {
      qworkspace->setBackgroundPixmap(*dia->buttonPixmap->pixmap());
      backPix = true;
    } else
    {
      qworkspace->setBackgroundColor(dia->buttonColor->color());
      backPix = false;
    }
    splashScreen = dia->checkBoxSplash->isChecked();
    docPath = dia->editDocPath->text();
    databaseAutoEdit = !dia->checkAutoEdit->isChecked();
  }
  delete dia;
  prefDia = 0;
  statusBar()->clear();
}

void MainWindow::editShortcuts()
{
  KKeyDialog K(false);
  K.configure(actionCollection());
}

void MainWindow::editPlugins()
{
  TDEProcess process;
  process << "kmdr-plugins";
  process.start(TDEProcess::Block);
}

void MainWindow::configureEditor()
{
  KTextEditor::Document *doc = KTextEditor::createDocument ("libkatepart", 0L, "KTextEditor::Document");
  KTextEditor::View *view = doc->createView(0);
  KTextEditor::ConfigInterface *configIf = KTextEditor::configInterface(doc);
  configIf->configDialog();
  delete doc;
}

void MainWindow::editExternalTool(int id)
{
  TDEProcess* process = new TDEProcess;
  (*process) << "kmdr-executor" << m_editorTools[id];
  connect(process, TQ_SIGNAL(processExited(TDEProcess*)), TQ_SLOT(editToolExited(TDEProcess*)));
  connect(process, TQ_SIGNAL(receivedStdout(TDEProcess*, char*, int)), TQ_SLOT(editToolOutput(TDEProcess*, char*, int)));
  m_toolOutput = '\0';
  process->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout);
}

void MainWindow::editToolExited(TDEProcess* process)
{
  delete process;
}

void MainWindow::editToolOutput(TDEProcess*, char* buffer, int buflen)
{
  m_toolOutput += TQString::fromLocal8Bit(buffer, buflen);
}

void MainWindow::chooseDocPath()
{
  if (!prefDia)
    return;
  TQString fn = KFileDialog::getExistingDirectory(TQString(), this);
  if (!fn.isEmpty())
    prefDia->editDocPath->setText(fn);
}


