/**********************************************************************
 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>

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

// TQt includes
#include <tqaccel.h>
#include <tqapplication.h>
#include <tqbitmap.h>
#include <tqevent.h>
#include <tqfeatures.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqmap.h>
#include <tqmetaobject.h>
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqpalette.h>
#include <tqpen.h>
#include <tqpixmapcache.h>
#include <tqpopupmenu.h>
#include <tqpushbutton.h>
#include <tqsizegrip.h>
#include <tqspinbox.h>
#include <statusbar.h>
#include <tqtimer.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>

// KDE includes
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kstatusbar.h>

// Other includes
#include "formwindow.h"
#include "defs.h"
#include "mainwindow.h"
#include "widgetfactory.h"
#include "sizehandle.h"
#include "metadatabase.h"
#include "resource.h"
#include "tqlayout.h"
#include "connectioneditorimpl.h"
#include "widgetdatabase.h"
#include "pixmapchooser.h"
#include "orderindicator.h"
#include "hierarchyview.h"

#include "globaldefs.h"
#include "formfile.h"

#include <stdlib.h>


static void setCursorToAll(const TQCursor &c, TQWidget *start)
{
  start->setCursor(c);
  TQObjectList l = start->childrenListObject();
  if (!l.isEmpty())
    for (TQObject *o = l.first(); o; o = l.next())
    {
      if (o->isWidgetType() && !o->inherits("SizeHandle"))
        setCursorToAll(c, ((TQWidget*)o));
    }
}

static void restoreCursors(TQWidget *start, FormWindow *fw)
{
  if (fw->widgets()->find(start))
    start->setCursor(MetaDataBase::cursor(start));
  else
    start->setCursor(TQt::ArrowCursor);
  TQObjectList l = start->childrenListObject();
  if (!l.isEmpty())
    for (TQObject *o = l.first(); o; o = l.next())
    {
      if (o->isWidgetType() && !o->inherits("SizeHandle"))
        restoreCursors(((TQWidget*)o), fw);
    }
}


/*
  The FormWindow is the widget which is used as editor for forms. It
  handles inserting, deleting, moving, resizing, etc. of widgets.

  Normally multiple formwindows are used at the same time in the
  Designer. So each formwindow has its own undo/redo buffer, etc.

  Also the formwindow has some signals to inform e.g. about selection
  changes which is interesting for the PropertyEditor.

  For handling the events of the child widgets (moving, etc.) the
  handleMousePress(), etc. functions are called from the application
  event filter which is implemented in MainWindow::eventFilter().
*/

FormWindow::FormWindow(FormFile *f, MainWindow *mw, TQWidget *parent, const char *name)
    : TQWidget(parent, name, WDestructiveClose), mainwindow(mw),
      commands(100), pixInline(true)
{
  ff = f;
  init();
  initSlots();
}

FormWindow::FormWindow(FormFile *f, TQWidget *parent, const char *name)
    : TQWidget(parent, name, WDestructiveClose), mainwindow(0),
      commands(100), pixInline(true)
{
  ff = f;
  init();
}

void FormWindow::init()
{
  MetaDataBase::addEntry(TQT_TQOBJECT(this));
  ff->setFormWindow(this);
  propertyWidget = 0;
  toolFixed = false;
  checkedSelectionsForMove = false;
  mContainer = 0;
  connectSender = connectReceiver = 0;
  currTool = POINTER_TOOL;
  unclippedPainter = 0;
  widgetPressed = false;
  drawRubber = false;
  setFocusPolicy(TQ_ClickFocus);
  sizePreviewLabel = 0;
  checkSelectionsTimer = new TQTimer(this, "checkSelectionsTimer");
  connect(checkSelectionsTimer, TQT_SIGNAL(timeout()),
      this, TQT_SLOT(invalidCheckedSelections()));
  updatePropertiesTimer = new TQTimer(this);
  connect(updatePropertiesTimer, TQT_SIGNAL(timeout()),
      this, TQT_SLOT(updatePropertiesTimerDone()));
  showPropertiesTimer = new TQTimer(this);
  connect(showPropertiesTimer, TQT_SIGNAL(timeout()),
      this, TQT_SLOT(showPropertiesTimerDone()));
  selectionChangedTimer = new TQTimer(this);
  connect(selectionChangedTimer, TQT_SIGNAL(timeout()),
      this, TQT_SLOT(selectionChangedTimerDone()));
  insertParent = 0;
  connect(&commands, TQT_SIGNAL(undoRedoChanged(bool, bool, const TQString &, const TQString &)),
      this, TQT_SIGNAL(undoRedoChanged(bool, bool, const TQString &, const TQString &)));
  propShowBlocked = false;

  setIcon(PixmapChooser::loadPixmap("form.xpm", PixmapChooser::Mini));

  connect(&commands, TQT_SIGNAL(modificationChanged(bool)),
      this, TQT_SLOT(modificationChanged(bool)));
  buffer = 0;

  TQWidget *w = WidgetFactory::create(WidgetDatabase::idFromClassName(TQFRAME_OBJECT_NAME_STRING), this);
  setMainContainer(w);
  propertyWidget = TQT_TQOBJECT(w);
  targetContainer = 0;
  hadOwnPalette = false;

  defSpacing = BOXLAYOUT_DEFAULT_SPACING;
  defMargin = BOXLAYOUT_DEFAULT_MARGIN;
}

void FormWindow::setMainWindow(MainWindow *w)
{
  mainwindow = w;
  MetaDataBase::addEntry(TQT_TQOBJECT(this));
  initSlots();
}

void FormWindow::initSlots()
{
}

FormWindow::~FormWindow()
{
  if (MainWindow::self->objectHierarchy()->formWindow() == this)
    MainWindow::self->objectHierarchy()->setFormWindow(0, 0);
  MetaDataBase::clear(TQT_TQOBJECT(this));
  if (ff)
    ff->setFormWindow(0);
}

void FormWindow::closeEvent(TQCloseEvent *e)
{
  if (ff->closeEvent() && mainwindow->unregisterClient(this))
    e->accept();
  else
    e->ignore();
}

void FormWindow::paintGrid(TQWidget *w, TQPaintEvent *e)
{
  if (!mainWindow()->showGrid())
    return;
  TQPixmap grid;
  TQString grid_name;
  grid_name.sprintf("FormWindowGrid_%d_%d", mainWindow()->grid().x(), mainWindow()->grid().y());
  if(!TQPixmapCache::find(grid_name, grid)) {
    grid = TQPixmap(350 + (350 % mainWindow()->grid().x()), 350 + (350 % mainWindow()->grid().y()));
    grid.fill(colorGroup().color(TQColorGroup::Foreground));
    TQBitmap mask(grid.width(), grid.height());
    mask.fill(color0);
    TQPainter p(&mask);
    p.setPen(color1);
    for (int y = 0; y < grid.width(); y += mainWindow()->grid().y())
      for (int x = 0; x < grid.height(); x += mainWindow()->grid().x())
        p.drawPoint(x, y);
    grid.setMask(mask);
    TQPixmapCache::insert(grid_name, grid);
  }
  TQPainter p(w);
  p.setClipRegion(e->rect());
  p.drawTiledPixmap(TQRect(0, 0, width(), height()), grid);
}


/*For operations like drawing a rubber band or drawing the rect
  when inserting a new widget, a unclipped painter (which draws also
  on child widgets) is needed. This method does all the initialization.
*/

void FormWindow::beginUnclippedPainter(bool doNot)
{
  endUnclippedPainter();
  bool unclipped = testWFlags(WPaintUnclipped);
  setWFlags(WPaintUnclipped);
  unclippedPainter = new TQPainter;
  unclippedPainter->begin(this);
  if (!unclipped)
    clearWFlags(WPaintUnclipped);
  if (doNot)
  {
    unclippedPainter->setPen(TQPen(color0, 2));
    unclippedPainter->setRasterOp(NotROP);
  }
}

void FormWindow::endUnclippedPainter()
{
  if (unclippedPainter)
    unclippedPainter->end();
  delete unclippedPainter;
  unclippedPainter = 0;
}

TQPoint FormWindow::gridPoint(const TQPoint &p)
{
  return TQPoint((p.x() / grid().x()) * grid().x(),
      (p.y() / grid().y()) * grid().y());
}

void FormWindow::drawSizePreview(const TQPoint &pos, const TQString& text)
{
  unclippedPainter->save();
  unclippedPainter->setPen(TQPen(colorGroup().foreground(), 1 ));
  unclippedPainter->setRasterOp(CopyROP);
  if (!sizePreviewPixmap.isNull())
    unclippedPainter->drawPixmap(sizePreviewPos, sizePreviewPixmap);
  if (text.isNull()) {
    sizePreviewPixmap = TQPixmap(); // set null again
    unclippedPainter->restore();
    return;
  }
  TQRect r  =  fontMetrics().boundingRect(0, 0, 0, 0, AlignCenter, text);
  r = TQRect(pos + TQPoint(10, 10), r.size() + TQSize(5, 5));

  checkPreviewGeometry(r);

  sizePreviewPos = r.topLeft();
  sizePreviewPixmap = TQPixmap::grabWindow(winId(), r.x(), r.y(), r.width(), r.height());
  unclippedPainter->setBrush(TQColor(255, 255, 128));
  unclippedPainter->drawRect(r);
  unclippedPainter->drawText(r, AlignCenter, text);
  unclippedPainter->restore();
}

void FormWindow::insertWidget()
{
  if (!insertParent || currTool == POINTER_TOOL)
    return;

  bool useSizeHint = !oldRectValid || (currRect.width() < 2 && currRect.height() < 2);
  Qt::Orientation orient =Qt::Horizontal;
  TQString n = WidgetDatabase::className(currTool);
  if (useSizeHint && (n == "Spacer" || n == TQSLIDER_OBJECT_NAME_STRING || n == "Line" || n == TQSCROLLBAR_OBJECT_NAME_STRING)) {
    TQPopupMenu m(mainWindow());
    m.insertItem(i18n("&Horizontal"));
    int ver = m.insertItem(i18n("&Vertical"));
    int r = m.exec(TQCursor::pos());
    if (r == ver)
        orient =Qt::Vertical;
  }

  TQWidget *w = WidgetFactory::create(currTool, insertParent, 0, true, &currRect, orient);
  if (!w)
    return;

  if (!savePixmapInline() && currTool == WidgetDatabase::idFromClassName("PixmapLabel"))
    ((TQLabel*)w)->setPixmap(PixmapChooser::loadPixmap("image.xpm"));
  int id = WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(TQT_TQOBJECT(w)));
  if (WidgetDatabase::isCustomWidget(id)) {
    TQWhatsThis::add(w, i18n("<b>A %1 (custom widget)</b> "
          "<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> "
          "menu to add and change custom widgets. You can add "
          "properties as well as signals and slots to integrate custom widgets into "
          "<i>TQt Designer</i>, and provide a pixmap which will be used to represent "
          "the widget on the form.</p>")
          .arg(WidgetDatabase::toolTip(id)));
    TQToolTip::add(w, i18n("A %1 (custom widget)").arg(WidgetDatabase::toolTip(id)));
    }
  else
  {
    TQString tt = WidgetDatabase::toolTip(id);
    TQString wt = WidgetDatabase::whatsThis(id);
    if (!wt.isEmpty() && !tt.isEmpty())
        TQWhatsThis::add(w, i18n("<b>A %1</b><p>%2</p>").arg(tt).arg(wt));
  }

  TQString s = w->name();
  unify(TQT_TQOBJECT(w), s, true);
  w->setName(s);
  insertWidget(w);
  TQRect r(currRect);
  if (!oldRectValid || (currRect.width() < 2 && currRect.height() < 2))
    r = TQRect(rectAnchor, TQSize(0, 0));

  TQPoint p = r.topLeft();
  p = mapToGlobal(p);
  p = insertParent->mapFromGlobal(p);
  r = TQRect(p, r.size());
  if (useSizeHint)
  {
    r.setWidth(w->sizeHint().width());
    r.setHeight(w->sizeHint().height());
  }

  if (r.width() < 2 * grid().x())
    r.setWidth(2 * grid().x());
  if (r.height() < 2 * grid().y())
    r.setHeight(2 * grid().y());

  const TQObjectList l = insertParent->childrenListObject();
  TQObjectListIt it(l);
  TQWidgetList lst;
  if (WidgetDatabase::isContainer(WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(TQT_TQOBJECT(w)))))
    for (; it.current();) {
      TQObject *o = it.current();
      ++it;
      if (o->isWidgetType() && ((TQWidget*)o)->isVisibleTo(this) &&
          insertedWidgets.find((TQWidget*)o) && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(w))
      {
        TQRect r2(((TQWidget*)o)->pos(), ((TQWidget*)o)->size());
        if (r.contains(r2))
          lst.append((TQWidget*)o);
      }
    }

  if (!lst.isEmpty())
  {
    TQWidget *pw = WidgetFactory::containerOfWidget(w);
    TQValueList<TQPoint> op, np;
    for (TQWidget *i = lst.first(); i; i = lst.next())
    {
      op.append(i->pos());
      TQPoint pos = pw->mapFromGlobal(i->mapToGlobal(TQPoint(0, 0)));
      pos -= r.topLeft();
      np.append(pos);
    }
    MoveCommand *mv = new MoveCommand(i18n("Reparent Widgets"), this, lst, op, np, insertParent, pw);
    if (!toolFixed)
      mainwindow->resetTool();
    else
      setCursorToAll(CrossCursor, w);

    InsertCommand *cmd = new InsertCommand(i18n("Insert %1").arg(w->name()), this, w, r);

    TQPtrList<Command> commands;
    commands.append(mv);
    commands.append(cmd);

    MacroCommand *mc = new MacroCommand(i18n("Insert %1").arg(w->name()), this, commands);
    commandHistory()->addCommand(mc);
    mc->execute();
  }
  else
  {
    if (!toolFixed)
      mainwindow->resetTool();
    else
      setCursorToAll(CrossCursor, w);

    InsertCommand *cmd = new InsertCommand(i18n("Insert %1").arg(w->name()), this, w, r);
    commandHistory()->addCommand(cmd);
    cmd->execute();
  }
}

void FormWindow::insertWidget(TQWidget *w, bool checkName)
{
  if (checkName) {
    TQString s = w->name();
    unify(TQT_TQOBJECT(w), s, true);
    w->setName(s);
  }

  MetaDataBase::addEntry(TQT_TQOBJECT(w));
  int id = WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(TQT_TQOBJECT(w)));
  if (WidgetDatabase::isCustomWidget(id))
  {
    TQWhatsThis::add(w, i18n("<b>A %1 (custom widget)</b> "
            "<p>Click <b>Edit Custom Widgets...</b> in the <b>Tools|Custom</b> "
            "menu to add and change custom widgets. You can add "
            "properties as well as signals and slots to integrate custom widgets into "
            "<i>TQt Designer</i>, and provide a pixmap which will be used to represent "
            "the widget on the form.</p>")
            .arg(WidgetDatabase::toolTip(id)));
    TQToolTip::add(w, i18n("A %1 (custom widget)").arg(WidgetDatabase::toolTip(id)));
  }
  else
  {
    TQString tt = WidgetDatabase::toolTip(id);
    TQString wt = WidgetDatabase::whatsThis(id);
    if (!wt.isEmpty() && !tt.isEmpty())
      TQWhatsThis::add(w, i18n("<b>A %1</b><p>%2</p>").arg(tt).arg(wt));
  }

  restoreCursors(w, this);
  widgets()->insert(w, w);
  w->show();
}

void FormWindow::removeWidget(TQWidget *w)
{
  MetaDataBase::removeEntry(TQT_TQOBJECT(w));
  widgets()->take(w);
}

void FormWindow::handleContextMenu(TQContextMenuEvent *e, TQWidget *w)
{
  switch (currTool) {
    case POINTER_TOOL:
      if (!isMainContainer(TQT_TQOBJECT(w)) && qstrcmp(w->name(), "central widget"))
      { // press on a child widget
        raiseChildSelections(w); // raise selections and select widget
        selectWidget(TQT_TQOBJECT(w));
        // if widget is laid out, find the first non-laid out super-widget
        TQWidget *realWidget = w; // but store the original one
        while (w->parentWidget() &&  (WidgetFactory::layoutType(w->parentWidget()) !=
           WidgetFactory::NoLayout || !insertedWidgets.find(w)))
          w = w->parentWidget();
        if (mainContainer()->inherits(TQMAINWINDOW_OBJECT_NAME_STRING) &&
          ((TQMainWindow*)mainContainer())->centralWidget() == realWidget)
        {
          e->accept();
          mainwindow->popupFormWindowMenu(e->globalPos(), this);
        }
        else
        {
          e->accept();
          mainwindow->popupWidgetMenu(e->globalPos(), this, realWidget);
        }
      }
      else
      {
        e->accept();
        clearSelection();
        mainwindow->popupFormWindowMenu(e->globalPos(), this);
      }
    break;
  default:
    break;
  }
}

void FormWindow::handleMousePress(TQMouseEvent *e, TQWidget *w)
{
  checkedSelectionsForMove = false;
  checkSelectionsTimer->stop();
  if (!sizePreviewLabel) {
    sizePreviewLabel = new TQLabel(this);
    sizePreviewLabel->hide();
    sizePreviewLabel->setBackgroundColor(TQColor(255, 255, 128));
    sizePreviewLabel->setFrameStyle(TQFrame::Plain | TQFrame::Box);
  }

  switch (currTool) {
    case POINTER_TOOL:
        if (!isMainContainer(TQT_TQOBJECT(w)) && qstrcmp(w->name(), "central widget") != 0)
        { // press on a child widget
            // if the clicked widget is not in a layout, raise it
          if (!w->parentWidget() || WidgetFactory::layoutType(w->parentWidget()) == WidgetFactory::NoLayout)
            w->raise();
          if ((e->state() & ControlButton))
          { // with control pressed, always start rubber band selection
            drawRubber = true;
            currRect = TQRect(0, 0, -1, -1);
            startRectDraw(mapFromGlobal(e->globalPos()), e->globalPos(), this, Rubber);
            break;
          }

          bool sel = isWidgetSelected(TQT_TQOBJECT(w));
          if (!((e->state() & ControlButton) || (e->state() & ShiftButton)))
          { // control not pressed...
            if (!sel)  // ...and widget no selectted: unselect all
                clearSelection(false);
            else
            { // ...widget selected
              // only if widget has a layout (it is a layout meta widget or a laid out container!),
              // unselect its childs
              if (WidgetFactory::layoutType(w) != WidgetFactory::NoLayout)
              {
                TQObjectList *l = w->queryList(TQWIDGET_OBJECT_NAME_STRING);
                setPropertyShowingBlocked(true);
                for (TQObject *o = l->first(); o; o = l->next())
                {
                  if (!o->isWidgetType())
                    continue;
                  if (insertedWidgets.find((TQWidget*)o))
                    selectWidget(TQT_TQOBJECT(o), false);
                }
                setPropertyShowingBlocked(false);
                delete l;
              }
            }
            tqApp->processEvents();
          }
          if (((e->state() & ControlButton) || (e->state() & ShiftButton)) &&
            sel && e->button() == Qt::LeftButton)
          { // control pressed and selected, unselect widget
            selectWidget(TQT_TQOBJECT(w), false);
            break;
          }

          raiseChildSelections(w); // raise selections and select widget
          selectWidget(TQT_TQOBJECT(w));

          // if widget is laid out, find the first non-laid out super-widget
          while (w->parentWidget() &&
            (WidgetFactory::layoutType(w->parentWidget()) != WidgetFactory::NoLayout
                || !insertedWidgets.find(w)))
            w = w->parentWidget();

          if (e->button() == Qt::LeftButton)
          { // left button: store original geometry and more as the widget might start moving
            widgetPressed = true;
            widgetGeom = TQRect(w->pos(), w->size());
            oldPressPos = w->mapFromGlobal(e->globalPos());
            origPressPos = oldPressPos;
            checkedSelectionsForMove = false;
            moving.clear();
            if (w->parentWidget() && !isMainContainer(TQT_TQOBJECT(w->parentWidget())) &&
               !isCentralWidget(TQT_TQOBJECT(w->parentWidget())))
            {
              targetContainer = w->parentWidget();
              hadOwnPalette = w->parentWidget()->ownPalette();
              restorePalette = w->parentWidget()->palette();
            }
          }
        }
        else
        { // press was on the formwindow
          if (e->button() == Qt::LeftButton)
          { // left button: start rubber selection and show formwindow properties
            drawRubber = true;
            if (!((e->state() & ControlButton) || (e->state() & ShiftButton)))
            {
              clearSelection(false);
              TQObject *opw = propertyWidget;
              propertyWidget = TQT_TQOBJECT(mainContainer());
              if (opw->isWidgetType())
                repaintSelection((TQWidget*)opw);
            }
            currRect = TQRect(0, 0, -1, -1);
            startRectDraw(mapFromGlobal(e->globalPos()), e->globalPos(), this, Rubber);
          }
        }
        break;
    case CONNECT_TOOL:
        if (e->button() != Qt::LeftButton)
          break;
        saveBackground();
        mainWindow()->statusBar()->message(i18n("Connect '%1' with...").arg(w->name()));
        connectStartPos = mapFromGlobal(e->globalPos());
        currentConnectPos = mapFromGlobal(e->globalPos());
        connectSender = TQT_TQOBJECT(designerWidget(TQT_TQOBJECT(w)));
        connectReceiver = connectableObject(TQT_TQOBJECT(designerWidget(TQT_TQOBJECT(w))), connectReceiver);
        beginUnclippedPainter(false);
        drawConnectLine();
        break;
    case ORDER_TOOL:
        if (!isMainContainer(TQT_TQOBJECT(w)))
        { // press on a child widget
          orderedWidgets.removeRef(w);
          orderedWidgets.append(w);
          for (TQWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev())
          {
            int i = stackedWidgets.findRef(wid);
            if (i != -1)
            {
              stackedWidgets.removeRef(wid);
              stackedWidgets.insert(0, wid);
            }
          }
          TQWidgetList oldl = MetaDataBase::tabOrder(this);
          TabOrderCommand *cmd = new TabOrderCommand(i18n("Change Tab Order"), this,
              oldl, stackedWidgets);
          cmd->execute();
          commandHistory()->addCommand(cmd, true);
          updateOrderIndicators();
        }
        break;
    default: // any insert widget tool
        if (e->button() == Qt::LeftButton)
        {
          insertParent = WidgetFactory::containerOfWidget(mainContainer());
          // default parent for new widget is the formwindow
          if (!isMainContainer(TQT_TQOBJECT(w)))
          { // press was not on formwindow, check if we can find another parent
            TQWidget *wid = w;
            for (;;)
            {
              int id = WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(TQT_TQOBJECT(wid)));
              if ((WidgetDatabase::isContainer(id) || wid == mainContainer()) &&
                !wid->inherits(TQLAYOUTWIDGET_OBJECT_NAME_STRING) && !wid->inherits(TQSPLITTER_OBJECT_NAME_STRING))
              {
                insertParent = WidgetFactory::containerOfWidget(wid); // found another parent, store it
                break;
              }
              else
              {
                wid = wid->parentWidget();
                if (!wid)
                  break;
              }
            }
          }
          startRectDraw(w->mapFromGlobal(e->globalPos()), e->globalPos(), w, Insert);
        }
        break;
  }
}

void FormWindow::handleMouseDblClick(TQMouseEvent *, TQWidget *w)
{
  switch (currTool) {
    case ORDER_TOOL:
      if (!isMainContainer(TQT_TQOBJECT(w)))
      { // press on a child widget
        orderedWidgets.clear();
        orderedWidgets.append(w);
        for (TQWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev())
        {
          int i = stackedWidgets.findRef(wid);
          if (i != -1)
          {
            stackedWidgets.removeRef(wid);
            stackedWidgets.insert(0, wid);
          }
        }
        TQWidgetList oldl = MetaDataBase::tabOrder(this);
        TabOrderCommand *cmd = new TabOrderCommand(i18n("Change Tab Order"), this, oldl, stackedWidgets);
        cmd->execute();
        commandHistory()->addCommand(cmd, true);
        updateOrderIndicators();
        }
        default:
          break;
  }
}

void FormWindow::handleMouseMove(TQMouseEvent *e, TQWidget *w)
{
  if ((e->state() & Qt::LeftButton) != Qt::LeftButton)
    return;

  TQWidget *newReceiver = (TQWidget*)connectReceiver, *oldReceiver = (TQWidget*)connectReceiver, *wid;
  bool drawRecRect;
  switch (currTool) {
    case POINTER_TOOL:
      if (widgetPressed && allowMove(w))
      { // we are prepated for a move
        // if widget is laid out, find the first non-laid out super-widget
        while (w->parentWidget() && (WidgetFactory::layoutType(w->parentWidget()) !=
           WidgetFactory::NoLayout || !insertedWidgets.find(w)))
          w = w->parentWidget();
        // calc correct position
        TQPoint pos = w->mapFromGlobal(e->globalPos());
        // calc move distance and store it
        TQPoint d = oldPressPos - pos;
        if (TQABS(d.x()) < grid().x())
          d.setX(0);
        if (TQABS(d.y()) < grid().y())
          d.setY(0);
        if (d.x() == 0)
          pos.setX(oldPressPos.x());
        if (d.y() == 0)
          pos.setY(oldPressPos.y());
        oldPressPos = pos;
        // snap to grid
        int x = widgetGeom.x() - d.x();
        widgetGeom.setX(x);
        x = (x / grid().x()) * grid().x();
        int y = widgetGeom.y() - d.y();
        widgetGeom.setY(y);
        y = (y / grid().y()) * grid().y();
        TQPoint p = w->pos();

        if (x - p.x() || y - p.y())
        { // if we actually have to move
          if (!checkedSelectionsForMove)
          { // if not checked yet, check if the correct widget are selected...
            if (!isWidgetSelected(TQT_TQOBJECT(w)))
            { // and unselect others. Only siblings can be moved at the same time
              setPropertyShowingBlocked(true);
              selectWidget(TQT_TQOBJECT(w));
              setPropertyShowingBlocked(false);
            }
            checkSelectionsForMove(w);
          }
          // check whether we would have to reparent the selection and
          // highlight the possible new parent container
          TQMapConstIterator<ulong, TQPoint> it = moving.begin();
          TQWidget* wa = containerAt(e->globalPos(), ((TQWidget*)it.key()));
          if (wa  && !isMainContainer(TQT_TQOBJECT(wa)) && !isCentralWidget(TQT_TQOBJECT(wa)))
          {
            wa = WidgetFactory::containerOfWidget(wa);
            // ok, looks like we moved onto a container

            if (wa != targetContainer)
            {
              if (targetContainer)
              {
                if (hadOwnPalette)
                  targetContainer->setPalette(restorePalette);
                else
                  targetContainer->unsetPalette();
              }
              targetContainer = wa;
              hadOwnPalette = wa->ownPalette();
              restorePalette = wa->palette();
              wa->setPaletteBackgroundColor(wa->colorGroup().midlight());
            }
          }
          else if (targetContainer)
          {
            if(hadOwnPalette)
              targetContainer->setPalette(restorePalette);
            else
              targetContainer->unsetPalette();
            targetContainer = 0;
          }

          // finally move the selected widgets and show/update preview label
          moveSelectedWidgets(x - p.x(), y - p.y());
          sizePreviewLabel->setText(TQString("%1/%2").arg(w->pos().x()).arg(w->pos().y()));
          sizePreviewLabel->adjustSize();
          TQRect lg(mapFromGlobal(e->globalPos()) + TQPoint(16, 16), sizePreviewLabel->size());
          checkPreviewGeometry(lg);
          sizePreviewLabel->setGeometry(lg);
          sizePreviewLabel->raise();
          sizePreviewLabel->show();
      }
      else
      { // if we don't need to move, do some indication
        TQRect lg(mapFromGlobal(e->globalPos()) + TQPoint(16, 16), sizePreviewLabel->size());
        checkPreviewGeometry(lg);
        sizePreviewLabel->move(lg.x(), lg.y());
      }

      oldPressPos += (p - w->pos());
    }
    else if (drawRubber)
      // draw rubber if we are in rubber-selection mode
      continueRectDraw(mapFromGlobal(e->globalPos()), e->globalPos(), this, Rubber);
    break;
  case CONNECT_TOOL:
    restoreConnectionLine();
    wid = tqApp->widgetAt(e->globalPos(), true);
    if (wid)
      wid = designerWidget(TQT_TQOBJECT(wid));
    if (wid && (isMainContainer(TQT_TQOBJECT(wid)) || insertedWidgets.find(wid)) && wid->isVisibleTo(this))
      newReceiver = wid;
    if (newReceiver && (newReceiver->inherits(TQLAYOUTWIDGET_OBJECT_NAME_STRING)
        || newReceiver->inherits("Spacer")))
      newReceiver = (TQWidget*)connectReceiver;
    drawRecRect = TQT_BASE_OBJECT(newReceiver) != TQT_BASE_OBJECT(connectReceiver);
    currentConnectPos = mapFromGlobal(e->globalPos());
    if (newReceiver && (isMainContainer(TQT_TQOBJECT(newReceiver))
        || insertedWidgets.find(newReceiver)) && !isCentralWidget(TQT_TQOBJECT(newReceiver)))
      connectReceiver = connectableObject(TQT_TQOBJECT(newReceiver), TQT_TQOBJECT(connectReceiver));
    mainWindow()->statusBar()->message(i18n("Connect '%1' to '%2'").arg(connectSender->name()).
        arg(connectReceiver->name()));
    tqApp->processEvents();
    if (drawRecRect)
      restoreRect(TQRect(mapToForm(((TQWidget*)oldReceiver)->parentWidget(),
          ((TQWidget*)oldReceiver)->pos()), ((TQWidget*)oldReceiver)->size()));
    drawConnectLine();
    break;
  case ORDER_TOOL:
    break;
  default: // we are in an insert-widget tool
    if (insertParent) // draw insert rect
        continueRectDraw(w->mapFromGlobal(e->globalPos()), e->globalPos(), w, Insert);
    break;
  }
}

void FormWindow::handleMouseRelease(TQMouseEvent * e, TQWidget * w)
{
  if (e->button() != Qt::LeftButton)
    return;

  switch (currTool)
  {
  case POINTER_TOOL:
    if (widgetPressed && allowMove(w))
    {                           // we moved the widget
      sizePreviewLabel->hide();

      if (moving.isEmpty() || w->pos() == *moving.find((ulong) w))
        break;

      // restore targetContainer
      if (targetContainer)
      {
        if (hadOwnPalette)
          targetContainer->setPalette(restorePalette);
        else
          targetContainer->unsetPalette();
      }
      // tell property editor to update
      if (propertyWidget && propertyWidget->isWidgetType() && !isMainContainer(propertyWidget))
        emitUpdateProperties(propertyWidget);

      TQMapConstIterator < ulong, TQPoint > it = moving.begin();
      TQWidget *oldParent = ((TQWidget *) it.key())->parentWidget();
      TQWidget *newParent = oldParent;
      // check whether we have to reparent the selection
      TQWidget *wa = containerAt(e->globalPos(), ((TQWidget *) it.key()));
      if (wa)
      {
        wa = WidgetFactory::containerOfWidget(wa);
        // ok, looks like we moved onto a container

        // check whether we really have different parents.
        if (wa == ((TQWidget *) it.key())->parentWidget())
          goto make_move_command;

        // break layout if necessary
        if (WidgetFactory::layoutType(wa) != WidgetFactory::NoLayout)
        {
          if (KMessageBox::questionYesNo(mainWindow(),
                  i18n("You tried to insert a widget into the "
                      "layout Container Widget '%1'.\n"
                      "This is not possible. "
                      "In order to insert the widget, the layout of '%1'\n"
                      "must first be broken.\n"
                      "Break the layout or cancel the operation?").
                  arg(wa->name()).arg(wa->name()), i18n("Inserting Widget"),
                  i18n("&Break Layout"), KStdGuiItem::cancel()) == KMessageBox::No)
            goto make_move_command; // cancel
          breakLayout(wa);
        }
        // doesn't need to be a command, the MoveCommand does reparenting too
        bool emitSelChanged = false;
        for (TQMap < ulong, TQPoint >::Iterator it = moving.begin(); it != moving.end(); ++it)
        {
          TQWidget *i = (TQWidget *) it.key();
          if (!emitSelChanged && i->inherits(TQBUTTON_OBJECT_NAME_STRING))
          {
            if (i->parentWidget() && i->parentWidget()->inherits(TQBUTTONGROUP_OBJECT_NAME_STRING) ||
                wa->inherits(TQBUTTONGROUP_OBJECT_NAME_STRING))
              emitSelChanged = true;
            if (!wa->inherits(TQBUTTONGROUP_OBJECT_NAME_STRING))
            {
              MetaDataBase::setPropertyChanged(TQT_TQOBJECT(i), "buttonGroupId", false);
              if (i->parentWidget() && i->parentWidget()->inherits(TQBUTTONGROUP_OBJECT_NAME_STRING))
                ((TQButtonGroup *) i->parentWidget())->remove((TQButton *) i);
            }
          }
          TQPoint pos = wa->mapFromGlobal(i->mapToGlobal(TQPoint(0, 0)));
          i->reparent(wa, pos, true);
          raiseSelection(i);
          raiseChildSelections(i);
          widgetChanged(TQT_TQOBJECT(i));
          mainWindow()->objectHierarchy()->widgetRemoved(i);
          mainWindow()->objectHierarchy()->widgetInserted(i);
        }
        if (emitSelChanged)
        {
          emit showProperties(TQT_TQOBJECT(wa));
          emit showProperties(propertyWidget);
        }
        newParent = wa;
      }

    make_move_command:
      TQWidgetList widgets;      // collect the widgets and its old and new positions which have been moved
      TQValueList < TQPoint > oldPos, newPos;
      for (it = moving.begin(); it != moving.end(); ++it)
      {
        widgets.append((TQWidget *) it.key());
        oldPos.append(*it);
        newPos.append(((TQWidget *) it.key())->pos());
      }
      // add move command, don't execute it, this is just a summary of the operations we did during the move-event handling
      commandHistory()->addCommand(new MoveCommand(i18n("Move"),
              this, widgets, oldPos, newPos, oldParent, newParent));
    } else if (drawRubber)
    {                           // we were drawing a rubber selection
      endRectDraw();            // get rid of the rectangle
      blockSignals(true);
      selectWidgets();          // select widgets which intersect the rect
      blockSignals(false);
      emitSelectionChanged();   // inform about selection changes
      if (propertyWidget)
        emitShowProperties(propertyWidget);
    }
    break;
  case CONNECT_TOOL:
    restoreConnectionLine();
    if (connectSender)
      restoreRect(TQRect(mapToForm(((TQWidget *) connectSender)->parentWidget(),
                  ((TQWidget *) connectSender)->pos()), ((TQWidget *) connectSender)->size()));
    if (connectReceiver)
      restoreRect(TQRect(mapToForm(((TQWidget *) connectReceiver)->parentWidget(),
                  ((TQWidget *) connectReceiver)->pos()), ((TQWidget *) connectReceiver)->size()));
    endUnclippedPainter();
    tqApp->processEvents();
    if (connectSender && connectReceiver)
      editConnections();
    break;
  case ORDER_TOOL:
    break;
  default:                     // any insert widget tool is active
    if (insertParent)
    {                           // we should insert the new widget now
      endRectDraw();
      if (WidgetFactory::layoutType(insertParent) != WidgetFactory::NoLayout)
      {
        if (KMessageBox::questionYesNo(mainWindow(),
                i18n("You tried to insert a widget into the "
                    "layout Container Widget '%1'.\n"
                    "This is not possible. "
                    "In order to insert the widget, the layout of '%1'\n"
                    "must first be broken.\n"
                    "Break the layout or cancel the operation?").
                arg(insertParent->name()).
                arg(insertParent->name()), i18n("Inserting Widget"),
                i18n("&Break Layout"), KStdGuiItem::cancel()) == KMessageBox::Yes)
        {
          breakLayout(insertParent);
        } else
        {
          if (!toolFixed)
            mainWindow()->resetTool();
          break;
        }
      }
      insertWidget();           // so do it
    }
    break;
  }
  widgetPressed = false;
  drawRubber = false;
  insertParent = 0;
  delete buffer;
  buffer = 0;
}

void FormWindow::handleKeyPress(TQKeyEvent * e, TQWidget * w)
{
  e->ignore();
  checkSelectionsTimer->stop();
  if (!checkedSelectionsForMove &&
      (e->key() == Key_Left ||
          e->key() == Key_Right ||
          e->key() == Key_Up || e->key() == Key_Down) && propertyWidget->isWidgetType())
    checkSelectionsForMove((TQWidget *) propertyWidget);
  checkSelectionsTimer->start(1000, true);
  if (e->key() == Key_Left || e->key() == Key_Right || e->key() == Key_Up || e->key() == Key_Down)
  {
    TQWidgetList widgets;
    TQValueList < TQPoint > oldPos, newPos;
    for (WidgetSelection * s = selections.first(); s; s = selections.next())
    {
      if (s->isUsed())
      {
        int dx = 0, dy = 0;
        bool control = e->state() & ControlButton;

        switch (e->key())
        {
        case Key_Left:
          {
            e->accept();
            if (control)
              dx = -1;
            else
              dx = -grid().x();
          }
          break;
        case Key_Right:
          {
            e->accept();
            if (control)
              dx = 1;
            else
              dx = grid().x();
          }
          break;
        case Key_Up:
          {
            e->accept();
            if (control)
              dy = -1;
            else
              dy = -grid().y();
          }
          break;
        case Key_Down:
          {
            e->accept();
            if (control)
              dy = 1;
            else
              dy = grid().y();
          }
          break;
        default:
          break;
        }

        widgets.append(s->widget());
        oldPos.append(s->widget()->pos());
        newPos.append(s->widget()->pos() + TQPoint(dx, dy));
      }
    }
    if (!widgets.isEmpty())
    {
      MoveCommand *cmd = new MoveCommand(i18n("Move"), this,
          widgets, oldPos, newPos, 0, 0);
      commandHistory()->addCommand(cmd, true);
      cmd->execute();
    }
  }
  if (!e->isAccepted())
  {
    TQObjectList *l = queryList(TQWIDGET_OBJECT_NAME_STRING);
    if (!l)
      return;
    if (l->find(TQT_TQOBJECT(w)) != -1)
      e->accept();
    delete l;
  }

}

void FormWindow::handleKeyRelease(TQKeyEvent * e, TQWidget *)
{
  e->ignore();
}

void FormWindow::selectWidget(TQObject * o, bool select)
{
  if (!o->isWidgetType())
  {
    // ########### do TQObject stuff
    return;
  }

  TQWidget *w = (TQWidget *) o;

  if (isMainContainer(TQT_TQOBJECT(w)))
  {
    TQObject *opw = propertyWidget;
    propertyWidget = TQT_TQOBJECT(mainContainer());
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
    emitShowProperties(propertyWidget);
    return;
  }

  if (mainContainer()->inherits(TQMAINWINDOW_OBJECT_NAME_STRING) &&
      w == ((TQMainWindow *) mainContainer())->centralWidget())
  {
    TQObject *opw = propertyWidget;
    propertyWidget = TQT_TQOBJECT(mainContainer());
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
    emitShowProperties(propertyWidget);
    return;
  }

  if (o->inherits("QDesignerToolBar") || o->inherits("QDesignerMenuBar"))
    return;

  if (select)
  {
    TQObject *opw = propertyWidget;
    propertyWidget = TQT_TQOBJECT(w);
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
    if (!isPropertyShowingBlocked())
      emitShowProperties(propertyWidget);
    WidgetSelection *s = usedSelections.find(w);
    if (s)
    {
      s->show();
      return;
    }

    for (WidgetSelection * s2 = selections.first(); s2; s2 = selections.next())
    {
      if (!s2->isUsed())
      {
        s = s2;
      }
    }

    if (!s)
    {
      s = new WidgetSelection(this, &usedSelections);
      selections.append(s);
    }

    s->setWidget(w);
    emitSelectionChanged();
  } else
  {
    WidgetSelection *s = usedSelections.find(w);
    if (s)
      s->setWidget(0);
    TQObject *opw = propertyWidget;
    if (!usedSelections.isEmpty())
      propertyWidget = TQT_TQOBJECT(TQPtrDictIterator < WidgetSelection > (usedSelections).current()->widget());
    else
      propertyWidget = TQT_TQOBJECT(mainContainer());
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
    if (!isPropertyShowingBlocked())
      emitShowProperties(propertyWidget);
    emitSelectionChanged();
  }
}

TQPoint FormWindow::grid() const
{
  if (!mainWindow()->snapGrid())
    return TQPoint(1, 1);
  return mainWindow()->grid();
}

void FormWindow::updateSelection(TQWidget * w)
{
  WidgetSelection *s = usedSelections.find(w);
  if (!w->isVisibleTo(this))
    selectWidget(TQT_TQOBJECT(w), false);
  else if (s)
    s->updateGeometry();
}

void FormWindow::raiseSelection(TQWidget * w)
{
  WidgetSelection *s = usedSelections.find(w);
  if (s)
    s->show();
}

void FormWindow::repaintSelection(TQWidget * w)
{
  WidgetSelection *s = usedSelections.find(w);
  if (s)
    s->update();
}

void FormWindow::clearSelection(bool changePropertyDisplay)
{
  TQPtrDictIterator < WidgetSelection > it(usedSelections);
  for (; it.current(); ++it)
    it.current()->setWidget(0, false);

  usedSelections.clear();
  if (changePropertyDisplay)
  {
    TQObject *opw = propertyWidget;
    propertyWidget = TQT_TQOBJECT(mainContainer());
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
    emitShowProperties(propertyWidget);
  }
  emitSelectionChanged();
}

void FormWindow::startRectDraw(const TQPoint & p, const TQPoint & global, TQWidget *, RectType t)
{
  TQPoint pos(p);
  pos = mapFromGlobal(global);
  oldRectValid = false;
  beginUnclippedPainter(true);
  if (t == Rubber)
    unclippedPainter->setPen(TQPen(color0, 1));
  if (t == Insert)
    rectAnchor = gridPoint(pos);
  else if (t == Rubber)
    rectAnchor = pos;
  currRect = TQRect(rectAnchor, TQPoint(0, 0));
  if (t == Insert)
    drawSizePreview(pos, i18n("Use Size Hint"));
}

void FormWindow::continueRectDraw(const TQPoint & p, const TQPoint & global, TQWidget *, RectType t)
{
  TQPoint pos = p;
  pos = mapFromGlobal(global);
  TQPoint p2;
  if (t == Insert)
    p2 = gridPoint(pos);
  else if (t == Rubber)
    p2 = pos;
  TQRect r(rectAnchor, p2);
  r = r.normalize();

  if (currRect == r)
  {
    TQString t("%1/%2");
    t = t.arg(r.width() - 1).arg(r.height() - 1);
    drawSizePreview(pos, t);
    return;
  }

  if (oldRectValid)
    unclippedPainter->drawRect(currRect);
  if (r.width() > 1 || r.height() > 1)
  {
    oldRectValid = true;
    currRect = r;
    if (t == Insert)
    {
      TQString t("%1/%2");
      t = t.arg(r.width() - 1).arg(r.height() - 1);
      drawSizePreview(pos, t);
    }
    unclippedPainter->setClipRegion(TQRegion(rect()).subtract(TQRect(sizePreviewPos,
                sizePreviewPixmap.size())));
    unclippedPainter->drawRect(currRect);
    unclippedPainter->setClipping(false);
  } else
  {
    oldRectValid = false;
    if (t == Insert)
      drawSizePreview(pos, i18n("Use Size Hint"));
  }
}

void FormWindow::endRectDraw()
{
  if (!unclippedPainter)
    return;

  if (oldRectValid)
    unclippedPainter->drawRect(currRect);
  drawSizePreview(TQPoint(-1, -1), TQString());
  endUnclippedPainter();
}

void FormWindow::selectWidgets()
{
  TQObjectList *l = mainContainer()->queryList(TQWIDGET_OBJECT_NAME_STRING);
  if (l)
  {
    for (TQObject * o = l->first(); o; o = l->next())
    {
      if (((TQWidget *) o)->isVisibleTo(this) && insertedWidgets[(void *) o])
      {
        TQPoint p = ((TQWidget *) o)->mapToGlobal(TQPoint(0, 0));
        p = mapFromGlobal(p);
        TQRect r(p, ((TQWidget *) o)->size());
        if (r.intersects(currRect) && !r.contains(currRect))
          selectWidget(TQT_TQOBJECT(o));
      }
    }
    delete l;
  }
  emitSelectionChanged();
}

bool FormWindow::isWidgetSelected(TQObject * w)
{
  if (w->isWidgetType())
    return usedSelections.find((TQWidget *) w) != 0;
  return false;                 // #### do stuff for TQObjects
}

void FormWindow::moveSelectedWidgets(int dx, int dy)
{
  TQPtrDictIterator < WidgetSelection > it(usedSelections);
  for (; it.current(); ++it)
  {
    WidgetSelection *s = it.current();
    TQWidget *w = s->widget();
    if (w->parentWidget()
        && WidgetFactory::layoutType(w->parentWidget()) != WidgetFactory::NoLayout)
      continue;
    w->move(w->x() + dx, w->y() + dy);
    s->updateGeometry();
    updateChildSelections(w);
  }
}

CommandHistory *FormWindow::commandHistory()
{
  return &commands;
}

void FormWindow::undo()
{
  commandHistory()->undo();
}

void FormWindow::redo()
{
  commandHistory()->redo();
}

void FormWindow::raiseChildSelections(TQWidget * w)
{
  TQObjectList *l = w->queryList(TQWIDGET_OBJECT_NAME_STRING);
  if (!l || !l->first())
  {
    delete l;
    return;
  }

  TQPtrDictIterator < WidgetSelection > it(usedSelections);
  for (; it.current(); ++it)
  {
    if (l->findRef(TQT_TQOBJECT(it.current()->widget())) != -1)
      it.current()->show();
  }
  delete l;
}

void FormWindow::updateChildSelections(TQWidget * w)
{
  TQObjectList *l = w->queryList(TQWIDGET_OBJECT_NAME_STRING);
  if (l)
  {
    for (TQObject * o = l->first(); o; o = l->next())
    {
      if (o->isWidgetType() && insertedWidgets.find((TQWidget *) o))
        updateSelection((TQWidget *) o);
    }
    delete l;
  }
}

void FormWindow::checkSelectionsForMove(TQWidget * w)
{
  checkedSelectionsForMove = true;

  TQObjectList *l = w->parentWidget()->queryList(TQWIDGET_OBJECT_NAME_STRING, 0, false, false);
  moving.clear();
  if (l)
  {
    TQPtrDictIterator < WidgetSelection > it(usedSelections);
    WidgetSelection *sel;
    while ((sel = it.current()) != 0)
    {
      if (it.current()->widget() == mainContainer())
        continue;
      ++it;
      if (l->find(TQT_TQOBJECT(sel->widget())) == -1)
      {
        if (WidgetFactory::layoutType(w) == WidgetFactory::NoLayout)
          sel->setWidget(0);
      } else
      {
        if (WidgetFactory::layoutType(sel->widget()->parentWidget()) == WidgetFactory::NoLayout)
        {
          moving.insert((ulong) sel->widget(), sel->widget()->pos());
          sel->widget()->raise();
          raiseChildSelections(sel->widget());
          raiseSelection(sel->widget());
        }
      }
    }
    delete l;
  }
}

void FormWindow::deleteWidgets()
{
  TQWidgetList widgets;
  TQPtrDictIterator < WidgetSelection > it(usedSelections);
  for (; it.current(); ++it)
  {
    TQWidget *tb = 0;
    if (!(tb = mainWindow()->isAToolBarChild(TQT_TQOBJECT(it.current()->widget()))))
      widgets.append(it.current()->widget());
    else
      ((QDesignerToolBar *) tb)->removeWidget(it.current()->widget());
  }

  if (widgets.isEmpty())
    return;

  DeleteCommand *cmd = new DeleteCommand(i18n("Delete"), this, widgets);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::editAdjustSize()
{
  TQPtrList < Command > commands;
  TQWidgetList widgets = selectedWidgets();
  if (widgets.isEmpty())
  {
    TQRect oldr = geometry();
    mainContainer()->adjustSize();
    resize(mainContainer()->size());
    // check whether our own size constraint hit us
    if (size() != mainContainer()->size())
      mainContainer()->resize(size());
    TQRect nr = geometry();
    if (oldr != nr)
    {
      ResizeCommand *cmd = new ResizeCommand(i18n("Adjust Size"), this, this, oldr, nr);
      commandHistory()->addCommand(cmd);
    }
    return;
  }
  for (TQWidget * w = widgets.first(); w; w = widgets.next())
  {
    if (w->parentWidget()
        && WidgetFactory::layoutType(w->parentWidget()) != WidgetFactory::NoLayout)
      continue;
    TQRect oldr = w->geometry();
    w->adjustSize();
    TQRect nr = w->geometry();
    if (oldr != nr)
      commands.append(new ResizeCommand(i18n("Adjust Size"), this, w, oldr, nr));
  }

  if (commands.isEmpty())
    return;
  for (WidgetSelection * s = selections.first(); s; s = selections.next())
    s->updateGeometry();

  MacroCommand *cmd = new MacroCommand(i18n("Adjust Size"), this, commands);
  commandHistory()->addCommand(cmd);
}


TQWidgetList FormWindow::selectedWidgets() const
{
  TQWidgetList widgets;
  for (TQPtrDictIterator<WidgetSelection> it(usedSelections); it.current(); ++it)
    widgets.append(it.current()->widget());
  return widgets;
}

void FormWindow::widgetChanged(TQObject *w)
{
  if (w->isWidgetType())
    updateSelection((TQWidget*)w);
}

TQLabel *FormWindow::sizePreview() const
{
  if (!sizePreviewLabel)
  {
    ((FormWindow*)this)->sizePreviewLabel = new TQLabel((FormWindow*)this);
    ((FormWindow*)this)->sizePreviewLabel->hide();
    ((FormWindow*)this)->sizePreviewLabel->setBackgroundColor(TQColor(255, 255, 128));
    ((FormWindow*)this)->sizePreviewLabel->setFrameStyle(TQFrame::Plain | TQFrame::Box);
  }
  return sizePreviewLabel;
}

void FormWindow::invalidCheckedSelections()
{
  checkedSelectionsForMove = false;
}

void FormWindow::checkPreviewGeometry(TQRect & r)
{
  if (TQT_TQRECT_OBJECT(rect()).contains(r))
    return;
  if (r.left() < rect().left())
    r.moveTopLeft(TQPoint(0, r.top()));
  if (r.right() > rect().right())
    r.moveBottomRight(TQPoint(rect().right(), r.bottom()));
  if (r.top() < rect().top())
    r.moveTopLeft(TQPoint(r.left(), rect().top()));
  if (r.bottom() > rect().bottom())
    r.moveBottomRight(TQPoint(r.right(), rect().bottom()));
}

void FormWindow::focusInEvent(TQFocusEvent *)
{
  if (mContainer)
  {
    TQVariant prop = mContainer->property("useInternalParser");
    KommanderWidget::useInternalParser = prop.toBool();
    
  }
}

void FormWindow::focusOutEvent(TQFocusEvent *)
{
  if (propertyWidget && !isMainContainer(propertyWidget) && !isWidgetSelected(propertyWidget))
  {
    TQObject *opw = propertyWidget;
    propertyWidget = TQT_TQOBJECT(mainContainer());
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
  }
}

void FormWindow::resizeEvent(TQResizeEvent * e)
{
  TQWidget::resizeEvent(e);
  if (currTool == ORDER_TOOL)
    repositionOrderIndicators();
  if (isVisible())
    formFile()->setModified(true);
}

TQPtrDict < TQWidget > *FormWindow::widgets()
{
  return &insertedWidgets;
}

TQWidget *FormWindow::designerWidget(TQObject * o) const
{
  if (!o || !o->isWidgetType())
    return 0;
  TQWidget *w = (TQWidget *) o;
  while (w && !isMainContainer(TQT_TQOBJECT(w)) && !insertedWidgets[(void *) w] || isCentralWidget(TQT_TQOBJECT(w)))
    w = (TQWidget *) w->parent();
  return w;
}

void FormWindow::emitShowProperties(TQObject * w)
{
  if (w)
  {
    TQObject *opw = propertyWidget;
    propertyWidget = w;
    if (opw->isWidgetType())
      repaintSelection((TQWidget *) opw);
  }
  showPropertiesTimer->stop();
  showPropertiesTimer->start(0, true);
}

void FormWindow::emitUpdateProperties(TQObject * w)
{
  if (w == propertyWidget)
  {
    updatePropertiesTimer->stop();
    updatePropertiesTimer->start(0, true);
  }
}

void FormWindow::emitSelectionChanged()
{
  selectionChangedTimer->stop();
  selectionChangedTimer->start(0, true);
}

void FormWindow::updatePropertiesTimerDone()
{
  if (propertyWidget && mainWindow()->formWindow() == this)
    emit updateProperties(propertyWidget);
}

void FormWindow::showPropertiesTimerDone()
{
  if (propertyWidget && mainWindow()->formWindow() == this)
    emit showProperties(propertyWidget);
}

void FormWindow::selectionChangedTimerDone()
{
  emit selectionChanged();
}

void FormWindow::currentToolChanged()
{
  toolFixed = false;
  int t = mainwindow->currentTool();
  if (currTool == t && t != ORDER_TOOL)
    return;

  // tool cleanup
  switch (currTool)
  {
  case ORDER_TOOL:
    hideOrderIndicators();
    break;
  case CONNECT_TOOL:
    restoreConnectionLine();
    if (connectSender)
      restoreRect(TQRect(mapToForm(((TQWidget *) connectSender)->parentWidget(),
                  ((TQWidget *) connectSender)->pos()), ((TQWidget *) connectSender)->size()));
    if (connectReceiver)
      restoreRect(TQRect(mapToForm(((TQWidget *) connectReceiver)->parentWidget(),
                  ((TQWidget *) connectReceiver)->pos()), ((TQWidget *) connectReceiver)->size()));
    endUnclippedPainter();
    break;
  case POINTER_TOOL:
    break;
  default:
    if (insertParent)
      endRectDraw();
    break;
  }

  connectSender = connectReceiver = 0;
  widgetPressed = false;
  drawRubber = false;
  insertParent = 0;
  delete buffer;
  buffer = 0;

  currTool = t;

  if (hasFocus())
    clearSelection(false);

  mainWindow()->statusBar()->clear();

  // tool setup
  switch (currTool)
  {
  case POINTER_TOOL:
    if (propertyWidget && !isMainContainer(propertyWidget) && !isWidgetSelected(propertyWidget))
      emitShowProperties(TQT_TQOBJECT(mainContainer()));
    restoreCursors(this, this);
    break;
  case ORDER_TOOL:
    if (mainWindow()->formWindow() == this)
    {
      mainWindow()->statusBar()->message(i18n("Click widgets to change the tab order..."));
      orderedWidgets.clear();
      showOrderIndicators();
      if (mainWindow()->formWindow() == this)
        emitShowProperties(TQT_TQOBJECT(mainContainer()));
      setCursorToAll(ArrowCursor, this);
    }
    break;
  case CONNECT_TOOL:
    mainWindow()->statusBar()->message(i18n("Drag a line to create a connection..."));
    setCursorToAll(CrossCursor, this);
    if (mainWindow()->formWindow() == this)
      emitShowProperties(TQT_TQOBJECT(mainContainer()));
    break;
  default:
    mainWindow()->statusBar()->message(i18n("Click on the form to insert a %1...").
        arg(WidgetDatabase::toolTip(currTool).lower()));
    setCursorToAll(CrossCursor, this);
    if (mainWindow()->formWindow() == this)
      emitShowProperties(TQT_TQOBJECT(mainContainer()));
    break;
  }
}

void FormWindow::showOrderIndicators()
{
  hideOrderIndicators();
  orderIndicators.setAutoDelete(true);
  TQObjectList *l = mainContainer()->queryList(TQWIDGET_OBJECT_NAME_STRING);
  stackedWidgets = MetaDataBase::tabOrder(this);
  if (l)
  {
    int order = 1;
    for (TQObject * o = l->first(); o; o = l->next())
    {
      TQWidget *w = (TQWidget *) o;
      if (w->isVisibleTo(w->parentWidget()) &&
          insertedWidgets[(void *) w] && w->focusPolicy() != TQ_NoFocus)
      {
        OrderIndicator *ind = new OrderIndicator(order++, w, this);
        orderIndicators.append(ind);
        if (stackedWidgets.findRef(w) == -1)
          stackedWidgets.append(w);
      }
    }
    delete l;
  }
  updateOrderIndicators();
}

void FormWindow::hideOrderIndicators()
{
  orderIndicators.clear();
}

void FormWindow::updateOrderIndicators()
{
  int order = 1;
  for (TQWidget * w = stackedWidgets.first(); w; w = stackedWidgets.next())
  {
    for (OrderIndicator * i = orderIndicators.first(); i; i = orderIndicators.next())
      i->setOrder(order, w);
    order++;
  }
}

void FormWindow::repositionOrderIndicators()
{
  for (OrderIndicator * i = orderIndicators.first(); i; i = orderIndicators.next())
    i->reposition();
}

void FormWindow::updateUndoInfo()
{
  commandHistory()->emitUndoRedo();
}

bool FormWindow::checkCustomWidgets()
{
  TQStringList missingCustomWidgets;
  TQPtrDictIterator < TQWidget > it(insertedWidgets);
  for (; it.current(); ++it)
  {
    if (it.current()->isA("CustomWidget"))
    {
      TQString className = WidgetFactory::classNameOf(TQT_TQOBJECT(it.current()));
      if (!MetaDataBase::hasCustomWidget(className))
        missingCustomWidgets << className;
    }
  }
  return true;
}

void FormWindow::setPropertyShowingBlocked(bool b)
{
  propShowBlocked = b;
}

bool FormWindow::isPropertyShowingBlocked() const
{
  return propShowBlocked;
}


int FormWindow::numSelectedWidgets() const
{
  return usedSelections.count();
}

TQString FormWindow::copy()
{
  Resource resource(mainWindow());
  resource.setWidget(this);
  return resource.copy();
}

void FormWindow::lowerWidgets()
{
  TQWidgetList widgets;
  TQPtrDictIterator < WidgetSelection > it(usedSelections);
  for (; it.current(); ++it)
    widgets.append(it.current()->widget());

  LowerCommand *cmd = new LowerCommand(i18n("Lower"), this, widgets);
  cmd->execute();
  commandHistory()->addCommand(cmd);
}

static void find_accel(const TQString & txt, TQMap < TQChar, TQWidgetList > &accels, TQWidget * w)
{
  int i = txt.find("&");
  if (i == -1)
    return;
  TQChar c = txt[i + 1];
  if (c.isNull() || c == '&')
    return;
  c = c.lower();
  TQMap < TQChar, TQWidgetList >::Iterator it = accels.find(c);
  if (it == accels.end())
  {
    TQWidgetList wl;
    wl.append(w);
    accels.insert(c, wl);
  } else
  {
    TQWidgetList *wl = &*it;
    wl->append(w);
  }
}

void FormWindow::checkAccels()
{
  TQMap < TQChar, TQWidgetList > accels;
  TQObjectList *l = mainContainer()->queryList(TQWIDGET_OBJECT_NAME_STRING);
  if (l)
  {
    for (TQObject * o = l->first(); o; o = l->next())
    {
      if (((TQWidget *) o)->isVisibleTo(this) && insertedWidgets[(void *) o])
      {
        TQWidget *w = (TQWidget *) o;
        const TQMetaProperty *text =
            w->metaObject()->property(w->metaObject()->findProperty("text", true), true);
        const TQMetaProperty *title =
            w->metaObject()->property(w->metaObject()->findProperty("title", true), true);
        const TQMetaProperty *pageTitle =
            w->metaObject()->property(w->metaObject()->findProperty("pageTitle", true), true);
        if (text)
          find_accel(w->property("text").toString(), accels, w);
        if (title)
          find_accel(w->property("title").toString(), accels, w);
        if (pageTitle)
          find_accel(w->property("pageTitle").toString(), accels, w);
      }
    }
    delete l;
  }

  bool ok = true;
  TQWidget *wid;
  for (TQMap < TQChar, TQWidgetList >::Iterator it = accels.begin(); it != accels.end(); ++it)
  {
    if ((*it).count() > 1)
    {
      ok = false;
      if (KMessageBox::questionYesNo(mainWindow(),
              i18n("Accelerator '%1' is used %2 times.").arg(it.key().upper()).arg((*it).count()),
              i18n("Check Accelerators"), i18n("&Select"), KStdGuiItem::cancel()) == KMessageBox::Yes)
      {
        clearSelection(false);
        for (wid = (*it).first(); wid; wid = (*it).next())
          selectWidget(TQT_TQOBJECT(wid), true);
      }
      return;
    }
  }

  if (ok)
    KMessageBox::information(mainWindow(), i18n("No accelerator is used more than once."),
      i18n("Check Accelerators"));
}

void FormWindow::raiseWidgets()
{
  TQWidgetList widgets;
  TQPtrDictIterator < WidgetSelection > it(usedSelections);
  for (; it.current(); ++it)
    widgets.append(it.current()->widget());

  RaiseCommand *cmd = new RaiseCommand(i18n("Raise"), this, widgets);
  cmd->execute();
  commandHistory()->addCommand(cmd);
}

void FormWindow::paste(const TQString & cb, TQWidget * parent)
{
  Resource resource(mainWindow());
  resource.setWidget(this);
  resource.paste(cb, parent);
}

void FormWindow::selectAll()
{
  checkedSelectionsForMove = false;
  blockSignals(true);
  TQObjectList *l = mainContainer()->queryList(TQWIDGET_OBJECT_NAME_STRING);
  if (l)
  {
    for (TQObject * o = l->first(); o; o = l->next())
    {
      if (((TQWidget *) o)->isVisibleTo(this) && insertedWidgets[(void *) o])
      {
        selectWidget(TQT_TQOBJECT(o));
      }
    }
    delete l;
  }

  blockSignals(false);
  emitSelectionChanged();
  if (propertyWidget)
    emitShowProperties(propertyWidget);
  emitSelectionChanged();
}

void FormWindow::layoutHorizontal()
{
  TQWidgetList widgets(selectedWidgets());
  LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand(i18n("Lay OutQt::Horizontally"),
      this, mainContainer(), 0, widgets);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutVertical()
{
  TQWidgetList widgets(selectedWidgets());
  LayoutVerticalCommand *cmd = new LayoutVerticalCommand(i18n("Lay OutQt::Vertically"),
      this, mainContainer(), 0, widgets);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutHorizontalSplit()
{
  TQWidgetList widgets(selectedWidgets());
  LayoutHorizontalSplitCommand *cmd =
      new LayoutHorizontalSplitCommand(i18n("Lay OutQt::Horizontally (in splitter)"),
      this, mainContainer(), 0, widgets);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutVerticalSplit()
{
  TQWidgetList widgets(selectedWidgets());
  LayoutVerticalSplitCommand *cmd =
      new LayoutVerticalSplitCommand(i18n("Lay OutQt::Vertically (in splitter)"),
      this, mainContainer(), 0, widgets);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutGrid()
{
  int xres = grid().x();
  int yres = grid().y();

  TQWidgetList widgets(selectedWidgets());
  LayoutGridCommand *cmd = new LayoutGridCommand(i18n("Lay Out in a Grid"),
      this, mainContainer(), 0, widgets, xres, yres);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutHorizontalContainer(TQWidget * w)
{
  if (w == this)
    w = mainContainer();
  TQObjectList l = WidgetFactory::containerOfWidget(w)->childrenListObject();
  if (l.isEmpty())
    return;
  TQWidgetList widgets;
  for (TQObject * o = l.first(); o; o = l.next())
  {
    if (o->isWidgetType() &&
        ((TQWidget *) o)->isVisibleTo(this) && insertedWidgets.find((TQWidget *) o))
      widgets.append((TQWidget *) o);
  }
  LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand(i18n("Lay Out ChildrenQt::Horizontally"),
      this, mainContainer(), w, widgets);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutVerticalContainer(TQWidget * w)
{
  if (w == this)
    w = mainContainer();
  TQObjectList l = WidgetFactory::containerOfWidget(w)->childrenListObject();
  if (l.isEmpty())
    return;
  TQWidgetList widgets;
  for (TQObject * o = l.first(); o; o = l.next())
  {
    if (o->isWidgetType() &&
        ((TQWidget *) o)->isVisibleTo(this) && insertedWidgets.find((TQWidget *) o))
      widgets.append((TQWidget *) o);
  }
  LayoutVerticalCommand *cmd = new LayoutVerticalCommand(i18n("Lay Out ChildrenQt::Vertically"),
      this, mainContainer(), w, widgets);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::layoutGridContainer(TQWidget * w)
{
  if (w == this)
    w = mainContainer();
  int xres = grid().x();
  int yres = grid().y();

  TQObjectList l = WidgetFactory::containerOfWidget(w)->childrenListObject();
  if (l.isEmpty())
    return;
  TQWidgetList widgets;
  for (TQObject * o = l.first(); o; o = l.next())
  {
    if (o->isWidgetType() &&
        ((TQWidget *) o)->isVisibleTo(this) && insertedWidgets.find((TQWidget *) o))
      widgets.append((TQWidget *) o);
  }
  LayoutGridCommand *cmd = new LayoutGridCommand(i18n("Lay Out Children in a Grid"),
      this, mainContainer(), w, widgets, xres, yres);
  clearSelection(false);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

void FormWindow::breakLayout(TQWidget * w)
{
  if (w == this)
    w = mainContainer();
  w = WidgetFactory::containerOfWidget(w);
  TQPtrList < Command > commands;

  for (;;)
  {
    if (!w || w == this)
      break;
    if (WidgetFactory::layoutType(w) != WidgetFactory::NoLayout &&
        WidgetDatabase::isContainer(WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(TQT_TQOBJECT(w)))))
    {
      Command *cmd = breakLayoutCommand(w);
      if (cmd)
        commands.insert(0, cmd);
      if (!w->inherits(TQLAYOUTWIDGET_OBJECT_NAME_STRING) && !w->inherits(TQSPLITTER_OBJECT_NAME_STRING))
        break;
    }
    w = w->parentWidget();
  }

  if (commands.isEmpty())
    return;

  clearSelection(false);
  MacroCommand *cmd = new MacroCommand(i18n("Break Layout"), this, commands);
  commandHistory()->addCommand(cmd);
  cmd->execute();
}

BreakLayoutCommand *FormWindow::breakLayoutCommand(TQWidget * w)
{
  TQObjectList l = w->childrenListObject();
  if (l.isEmpty())
    return 0;

  TQWidgetList widgets;
  for (TQObject * o = l.first(); o; o = l.next())
  {
    if (o->isWidgetType() &&
        !mainWindow()->isAToolBarChild(TQT_TQOBJECT(o)) &&
        ((TQWidget *) o)->isVisibleTo(this) && insertedWidgets.find((TQWidget *) o))
      widgets.append((TQWidget *) o);
  }
  return new BreakLayoutCommand(i18n("Break Layout"), this,
      WidgetFactory::widgetOfContainer(w), widgets);
}

int FormWindow::numVisibleWidgets() const
{
  TQPtrDictIterator < TQWidget > it(insertedWidgets);
  int visible = 0;
  for (; it.current(); ++it)
  {
    if (it.current()->isVisibleTo((FormWindow *) this))
      visible++;
  }
  return visible;
}

bool FormWindow::hasInsertedChildren(TQWidget *w) const
{
  if (!w)
    return false;
  w = WidgetFactory::containerOfWidget(w);
  if (!w)
    return false;
  TQObjectList *l = w->queryList(TQWIDGET_OBJECT_NAME_STRING);
  if (!l || !l->first())
  {
    delete l;
    return false;
  }

  for (TQObject *o = l->first(); o; o = l->next())
    if (o->isWidgetType() && ((TQWidget*)o)->isVisibleTo((FormWindow*)this) &&
        insertedWidgets.find((TQWidget*)o))
    {
      delete l;
      return true;
    }
  delete l;
  return false;
}

bool FormWindow::allowMove(TQWidget *w)
{
  w = w->parentWidget();
  while (w)
  {
    if ((isMainContainer(TQT_TQOBJECT(w)) || insertedWidgets.find(w)) && WidgetFactory::layoutType(w) ==
        WidgetFactory::NoLayout)
      return true;
    w = w->parentWidget();
  }
  return false;
}


void FormWindow::editConnections()
{
  buffer = 0;
  if (!connectSender || !connectReceiver)
    return;
  mainWindow()->statusBar()->clear();
  ConnectionEditor editor(mainwindow, connectSender, connectReceiver, this);
  mainWindow()->statusBar()->message(i18n("Edit connections..."));
  editor.exec();
  mainWindow()->statusBar()->clear();
  if (!toolFixed)
    mainwindow->resetTool();
  connectSender = connectReceiver = 0;
}

void FormWindow::saveBackground()
{
  delete buffer;
  buffer = new TQPixmap(width(), height());
  *buffer = TQPixmap::grabWindow(winId());
}

void FormWindow::restoreConnectionLine()
{
  if (!unclippedPainter || !buffer)
    return;

  int a =TQABS(connectStartPos.x() - currentConnectPos.x());
  int b = TQABS(connectStartPos.y() - currentConnectPos.y());
  TQRect r(connectStartPos, currentConnectPos);

  if (a < 32 || b < 32)
  { // special case: vertical or horizontal line
    r = r.normalize();
    unclippedPainter->drawPixmap(r.x() - 2, r.y() - 2, *buffer,
                r.x() - 2, r.y() - 2, r.width() + 4, r.height() + 4);
    return;
  }

  if (a <= 0)
    a = 1;
  if (b <= 0)
    b = 1;
  int w, h;
  if (b > a)
  {
    h = 64;
    w = (a * h) / b;
  }
  else
  {
    w = 64;
    h = (b * w) / a;
  }
  int dx = 2 * w / 3;
  int dy = 2 * h / 3;
  TQPoint p(connectStartPos);

  if (r.x() > r.right())
  {
    dx = dx * -1;
    p.setX(p.x() - 64);
    r.moveBy(-64, 0);
  }
  if (r.y() > r.bottom()) {
    dy = dy * -1;
    p.setY(p.y() - 64);
    r.moveBy(0, -64);
  }

  w = h = 64;
  r = r.normalize();
  while (r.contains(p))
  {
    unclippedPainter->drawPixmap(p, *buffer, TQRect(p, TQSize(w, h)));
    unclippedPainter->setPen(red);
    p.setX(p.x() + dx);
    p.setY(p.y() + dy);
  }

  unclippedPainter->drawPixmap(connectStartPos.x() - 10, connectStartPos.y() - 10, *buffer,
      connectStartPos.x() - 10, connectStartPos.y() - 10, 20, 20);
}

void FormWindow::restoreRect(const TQRect &rect)
{
  if (!unclippedPainter)
    return;
  TQRect r(rect);
  r = r.normalize();
  r = TQRect(r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4);
  unclippedPainter->drawPixmap(r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, r.width() + 4, 4);
  unclippedPainter->drawPixmap(r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, 4, r.height() + 4);
  unclippedPainter->drawPixmap(r.x() - 2, r.y() + r.height() - 3, *buffer, r.x() - 2,
    r.y() + r.height() - 3, r.width() + 4, 5);
  unclippedPainter->drawPixmap(r.x() + r.width() - 2, r.y(), *buffer, r.x() + r.width() - 2,
    r.y(), 4, r.height() + 4);
}

void FormWindow::drawConnectLine()
{
  if (!unclippedPainter)
    return;
  unclippedPainter->setPen(TQPen(white, 2));
  unclippedPainter->drawLine(connectStartPos, currentConnectPos);
  unclippedPainter->setPen(TQPen(darkCyan, 1));
  unclippedPainter->drawLine(connectStartPos, currentConnectPos);

  unclippedPainter->setPen(TQPen(magenta, 1));
  if (connectSender)
  {
    TQWidget *w = (TQWidget*)connectSender;
    TQPoint p = mapToForm(w, TQPoint(0,0));
    unclippedPainter->drawRect(TQRect(p + TQPoint(2, 2), w->size() - TQSize(4, 4)));
  }
  if (connectReceiver)
  {
    TQWidget *w = (TQWidget*)connectReceiver;
    TQPoint p = mapToForm(w, TQPoint(0,0));
    unclippedPainter->drawRect(TQRect(p + TQPoint(2, 2), w->size() - TQSize(4, 4)));
  }
}

TQString FormWindow::fileName() const
{
  return ff->absFileName();
}

void FormWindow::setFileName(const TQString &fn)
{
  ff->setFileName(fn);
  emit fileNameChanged(ff->fileName(), this);
}

void FormWindow::modificationChanged(bool m)
{
  emit modificationChanged(m, this);
  emit modificationChanged(m, ff->fileName());
}

bool FormWindow::unify(TQObject *w, TQString &s, bool changeIt)
{
  bool found = !isMainContainer(w) && !qstrcmp(name(), s.latin1());
  if (!found)
  {
    TQString orig = s;
    int num  = 1;
    TQPtrDictIterator<TQWidget> it(insertedWidgets);
    for (; it.current();)
      if (TQT_BASE_OBJECT(it.current()) != TQT_BASE_OBJECT(w) && !qstrcmp(it.current()->name(), s.latin1()))
      {
        found = true;
        if (!changeIt)
          break;
        s = orig + "_" + TQString::number(++num);
        it.toFirst();
      }
      else
        ++it;

    if (!found)
    {
      TQPtrList<TQAction> al;
      TQAction *a = 0;
      for (a = actions.first(); a; a = actions.next())
      {
        TQObjectList *l = a->queryList(TQACTION_OBJECT_NAME_STRING);
        al.append(a);
        for (TQObject *ao = l->first(); ao; ao = l->next())
          al.append((TQAction*)ao);
        delete l;
      }
      for (a = al.first(); a; a = al.next())
      {
        if (a != w && !qstrcmp(a->name(), s.latin1()))
        {
          found = true;
          if (!changeIt)
            break;
          s = orig + "_" + TQString::number(++num);
          a = actions.first();
        }
      }
    }

    if (mainContainer()->inherits(TQMAINWINDOW_OBJECT_NAME_STRING))
    {
      if (!found)
      {
        TQObjectList *l = mainContainer()->queryList(TQDOCKWINDOW_OBJECT_NAME_STRING, 0, true);
        for (TQObject *o = l->first(); o; o = l->next())
          if (o != w && !qstrcmp(o->name(), s.latin1()))
          {
            found = true;
            if (!changeIt)
              break;
            s = orig + "_" + TQString::number(++num);
            o = l->first();
          }
      delete l;
      }
      if (!found)
      {
        TQObjectList *l = mainContainer()->queryList("QDesignerPopupMenu", 0, true);
        for (TQObject *o = l->first(); o; o = l->next())
          if (o != w && !qstrcmp(o->name(), s.latin1()))
          {
            found = true;
            if (!changeIt)
              break;
            s = orig + "_" + TQString::number(++num);
            o = l->first();
          }
        delete l;
      }
    }
  }
  if (!found)
    return true;
  return false;
}

bool FormWindow::isCustomWidgetUsed(MetaDataBase::CustomWidget *w)
{
  TQPtrDictIterator<TQWidget> it(insertedWidgets);
  for (; it.current(); ++it)
    if (it.current()->isA("CustomWidget") && !qstrcmp(WidgetFactory::classNameOf(TQT_TQOBJECT(it.current())),
        w->className.utf8()))
      return true;
  return false;
}

bool FormWindow::isDatabaseWidgetUsed() const
{
#ifndef TQT_NO_SQL
  TQStringList dbClasses;
  dbClasses << TQDATATABLE_OBJECT_NAME_STRING; // add more here
  TQPtrDictIterator<TQWidget> it(insertedWidgets);
  for (; it.current(); ++it)
  {
    TQString c(it.current()->className());
    if (dbClasses.contains(c) > 0)
      return true;
  }
#endif
  return false;
}

bool FormWindow::isDatabaseAware() const
{
#ifndef TQT_NO_SQL
  if (TQString(mContainer->className()) == "QDesignerDataBrowser" ||
      TQString(mContainer->className()) == "QDesignerDataView")
    return true;
  return isDatabaseWidgetUsed();
#else
  return false;
#endif
}

void FormWindow::visibilityChanged()
{
  if (currTool != ORDER_TOOL)
    emitUpdateProperties(TQT_TQOBJECT(currentWidget()));
  else
  {
    updateOrderIndicators();
    repositionOrderIndicators();
  }
}


/*
  Maps a pos in a w's coordinates to the form's coordinate system.

  This is the equivalent to mapFromGlobal(w->mapToGlobal(pos)) but
  avoids the two roundtrips to the X-Server on Unix/X11.
 */
TQPoint FormWindow::mapToForm(const TQWidget* w, const TQPoint&  pos) const
{
  TQPoint p = pos;
  const TQWidget* i = w;
  while (i && !i->isTopLevel() && !isMainContainer(TQT_TQOBJECT(const_cast<TQWidget*>(i))))
  {
    p = i->mapToParent(p);
    i = i->parentWidget();
  }
  return mapFromGlobal(w->mapToGlobal(pos));
}

static int widgetDepth(TQWidget *w)
{
  int d = -1;
  while (w && !w->isTopLevel())
  {
    d++;
    w = w->parentWidget();
  }

  return d;
}

static bool isChildOf(TQWidget *c, TQWidget *p)
{
  while (c && !c->isTopLevel())
  {
    if (c == p)
      return true;
    c = c->parentWidget();
  }
  return false;
}

TQWidget *FormWindow::containerAt(const TQPoint &pos, TQWidget *notParentOf)
{
  TQPtrDictIterator<TQWidget> it(insertedWidgets);
  TQWidget *container = 0;
  int depth = -1;
  TQWidgetList selected = selectedWidgets();
  if (TQT_TQRECT_OBJECT(rect()).contains(mapFromGlobal(pos)))
  {
    container = mainContainer();
    depth = widgetDepth(container);
  }

  for (; it.current(); ++it) {
    if (it.current()->inherits(TQLAYOUTWIDGET_OBJECT_NAME_STRING))
      continue;
    if (it.current()->inherits(TQSPLITTER_OBJECT_NAME_STRING))
      continue;
    if (!it.current()->isVisibleTo(this))
      continue;
    if (selected.find(it.current()) != -1)
      continue;
    if (!WidgetDatabase::isContainer(WidgetDatabase::idFromClassName(
      WidgetFactory::classNameOf(TQT_TQOBJECT(it.current())))) && it.current() != mainContainer())
      continue;

    // the rectangles of all ancestors of the container must contain the insert position
    TQWidget *w = it.current();
    while (w && !w->isTopLevel())
    {
      if (!TQT_TQRECT_OBJECT(w->rect()).contains((w->mapFromGlobal(pos))))
        break;
      w = w->parentWidget();
    }
    if (w && !w->isTopLevel()) continue; // we did not get through the full while loop

    int wd = widgetDepth(it.current());
    if (wd == depth && container &&  (it.current()->parentWidget()->
      childrenListObject()).find(TQT_TQOBJECT(it.current())) >
      (container->parentWidget()->childrenListObject()).find(TQT_TQOBJECT(container)))
      wd++;
    if (wd > depth && !isChildOf(it.current(), notParentOf)) {
      depth = wd;
      container = it.current();
    }
  }

  return container;
}

bool FormWindow::isMainContainer(TQObject *w) const
{
  return w && w->isWidgetType() && (TQT_BASE_OBJECT(w) == this || TQT_BASE_OBJECT(w) == TQT_BASE_OBJECT(mainContainer()));
}

void FormWindow::setMainContainer(TQWidget *w)
{
  bool resetPropertyWidget = isMainContainer(propertyWidget);
  if (mContainer)
    insertedWidgets.remove(mContainer);
  if (TQT_BASE_OBJECT(propertyWidget) == TQT_BASE_OBJECT(mContainer))
    propertyWidget = 0;
  delete mContainer;
  mContainer = w;
  insertedWidgets.insert(mContainer, mContainer);
  delete layout();
  TQHBoxLayout *l = new TQHBoxLayout(this);
  l->addWidget(w);
  if (resetPropertyWidget)
  {
    TQObject *opw = propertyWidget;
    propertyWidget = TQT_TQOBJECT(mContainer);
    if (opw && opw->isWidgetType())
      repaintSelection((TQWidget*)opw);
  }
}

bool FormWindow::savePixmapInline() const
{
  return pixInline;
}

TQString FormWindow::pixmapLoaderFunction() const
{
  return pixLoader;
}

void FormWindow::setSavePixmapInline(bool b)
{
  pixInline = b;
}

void FormWindow::setPixmapLoaderFunction(const TQString &func)
{
  pixLoader = func;
}

void FormWindow::setActiveObject(TQObject *o)
{
  emitShowProperties(o);
  propertyWidget = o;
}

TQAction *FormWindow::findAction(const TQString &name)
{
  for (TQAction *a = actionList().first(); a; a = actionList().next())
  {
    if (TQString(a->name()) == name)
      return a;
    TQAction *ac = (TQAction*)a->child(name.latin1(), TQACTION_OBJECT_NAME_STRING);
    if (ac)
      return ac;
  }
  return 0;
}

void FormWindow::killAccels(TQObject *top)
{
  TQObjectList *l = top->queryList(TQACCEL_OBJECT_NAME_STRING);
  if (!l)
    return;
  for (TQObject *o = l->first(); o; o = l->next())
    ((TQAccel*)o)->setEnabled(false);
  delete l;
}

bool FormWindow::isCentralWidget(TQObject *w) const
{
  if (!mainContainer()->inherits(TQMAINWINDOW_OBJECT_NAME_STRING))
    return false;
  return TQT_BASE_OBJECT(w) == TQT_BASE_OBJECT(((TQMainWindow*)mainContainer())->centralWidget());
}

TQObject *FormWindow::connectableObject(TQObject *w, TQObject *)
{
  return w;
}

int FormWindow::layoutDefaultSpacing() const
{
  return defSpacing;
}

int FormWindow::layoutDefaultMargin() const
{
  return defMargin;
}

void FormWindow::setLayoutDefaultSpacing(int s)
{
  defSpacing = s;
}

void FormWindow::setLayoutDefaultMargin(int s)
{
  defMargin = s;
}

FormFile *FormWindow::formFile() const
{
  return ff;
}

void FormWindow::setFormFile(FormFile *f)
{
  ff = f;
  if (ff)
  connect(this, TQT_SIGNAL(modificationChanged(bool, const TQString&)), ff, TQT_SLOT(formWindowChangedSomehow()));
}
#include "formwindow.moc"
