kexi

formmanager.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <kdebug.h>
00022 
00023 #include <qworkspace.h>
00024 #include <qcursor.h>
00025 #include <qstring.h>
00026 #include <qlabel.h>
00027 #include <qobjectlist.h>
00028 #include <qstylefactory.h>
00029 #include <qmetaobject.h>
00030 #include <qregexp.h>
00031 #include <qvaluevector.h>
00032 #include <qvbox.h>
00033 
00034 #include <klocale.h>
00035 #include <kiconloader.h>
00036 #include <kpopupmenu.h>
00037 #include <kstdaction.h>
00038 #include <kaction.h>
00039 #include <kxmlguiclient.h>
00040 #include <kmainwindow.h>
00041 #include <kmessagebox.h>
00042 #include <kconfig.h>
00043 #include <kstyle.h>
00044 #include <kactionclasses.h>
00045 #include <kapplication.h>
00046 #include <kglobal.h>
00047 #include <kglobalsettings.h>
00048 #include <kdialogbase.h>
00049 #include <ktextedit.h>
00050 #include <ktabwidget.h>
00051 #include <kfontdialog.h>
00052 
00053 #include <kdeversion.h>
00054 #if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9) && !defined(Q_WS_WIN)
00055 # include <kactioncollection.h>
00056 #endif
00057 
00058 #include "widgetpropertyset.h"
00059 #include "objecttree.h"
00060 #include "widgetlibrary.h"
00061 #include "form.h"
00062 #include "container.h"
00063 #include "formIO.h"
00064 #include "objecttreeview.h"
00065 #include "commands.h"
00066 #include "tabstopdialog.h"
00067 #include "connectiondialog.h"
00068 #include "pixmapcollection.h"
00069 #include "events.h"
00070 #include "utils.h"
00071 #include "kfdpixmapedit.h"
00072 #include <koproperty/editor.h>
00073 #include <koproperty/property.h>
00074 #include <koproperty/factory.h>
00075 
00076 #include "formmanager.h"
00077 
00078 #define KFD_NO_STYLES //disables; styles support needs improvements
00079 
00080 namespace KFormDesigner {
00081 
00083 class PropertyFactory : public KoProperty::CustomPropertyFactory
00084 {
00085     public:
00086         PropertyFactory(QObject *parent) 
00087         : KoProperty::CustomPropertyFactory(parent)
00088 //          m_manager(manager)
00089         {
00090         }
00091         virtual ~PropertyFactory() {}
00092 
00093         KoProperty::CustomProperty* createCustomProperty(KoProperty::Property *) { return 0;}
00094 
00095         KoProperty::Widget* createCustomWidget(KoProperty::Property *prop)
00096         {
00097             return new KFDPixmapEdit(prop);
00098         }
00099 };
00100 
00101 }
00102 
00103 using namespace KFormDesigner;
00104 
00105 static KStaticDeleter<FormManager> m_managerDeleter;
00106 FormManager* FormManager::_self = 0L;
00107 
00108 FormManager::FormManager(QObject *parent, int options, const char *name)
00109    : QObject(parent, name)
00110 #ifdef KEXI_SHOW_DEBUG_ACTIONS
00111    , m_uiCodeDialog(0)
00112    , m_options(options)
00113 #endif
00114    , m_objectBlockingPropertyEditorUpdating(0)
00115    , m_isRedoing(false)
00116 {
00117     Q_UNUSED(options);
00118 #ifdef KEXI_STANDALONE
00119     KGlobal::locale()->insertCatalogue("standalone_kformdesigner");
00120 #else
00121     KGlobal::locale()->insertCatalogue("kformdesigner");
00122 #endif
00123 
00124     connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) );
00125     slotSettingsChanged(KApplication::SETTINGS_SHORTCUTS);
00126 
00127 //moved to createWidgetLibrary()    m_lib = new WidgetLibrary(this, supportedFactoryGroups);
00128     m_propSet = new WidgetPropertySet(this);
00129 
00130     m_editor = 0;
00131     m_active = 0;
00132     m_inserting = false;
00133     m_drawingSlot = false;
00134     m_collection = 0;
00135     m_connection = 0;
00136     m_popup = 0;
00137     m_treeview = 0;
00138     m_editor = 0;
00139     m_domDoc.appendChild(m_domDoc.createElement("UI"));
00140 
00141     m_deleteWidgetLater_list.setAutoDelete(true);
00142     connect( &m_deleteWidgetLater_timer, SIGNAL(timeout()), this, SLOT(deleteWidgetLaterTimeout()));
00143     connect( this, SIGNAL(connectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&)),
00144         this, SLOT(slotConnectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&)));
00145 
00146     // register kfd custom editors
00147     KoProperty::FactoryManager::self()->registerFactoryForEditor(KoProperty::Pixmap, 
00148         new PropertyFactory(KoProperty::FactoryManager::self()));
00149 }
00150 
00151 FormManager::~FormManager()
00152 {
00153     m_managerDeleter.setObject(_self, 0, false); //safe
00154     delete m_popup;
00155     delete m_connection;
00156 #ifdef KEXI_SHOW_DEBUG_ACTIONS
00157     delete m_uiCodeDialog;
00158 #endif
00159 //  delete m_propFactory;
00160 }
00161 
00162 
00163 FormManager* FormManager::self()
00164 {
00165     return _self;
00166 }
00167 
00168 WidgetLibrary* 
00169 FormManager::createWidgetLibrary(FormManager* m, const QStringList& supportedFactoryGroups)
00170 {
00171     if(!_self)
00172         m_managerDeleter.setObject( _self, m );
00173     return new WidgetLibrary(_self, supportedFactoryGroups);
00174 }
00175 
00176 void
00177 FormManager::setEditor(KoProperty::Editor *editor)
00178 {
00179     m_editor = editor;
00180 
00181     if(editor)
00182         editor->changeSet(m_propSet->set());
00183 }
00184 
00185 void
00186 FormManager::setObjectTreeView(ObjectTreeView *treeview)
00187 {
00188     m_treeview = treeview;
00189     if (m_treeview)
00190         connect(m_propSet, SIGNAL(widgetNameChanged(const QCString&, const QCString&)),
00191             m_treeview, SLOT(renameItem(const QCString&, const QCString&)));
00192 }
00193 
00194 ActionList
00195 FormManager::createActions(WidgetLibrary *lib, KActionCollection *parent)
00196 {
00197     m_collection = parent;
00198 
00199     ActionList actions = lib->addCreateWidgetActions(parent, this, SLOT(insertWidget(const QCString &)));
00200 
00201     if (m_options & HideSignalSlotConnections)
00202         m_dragConnection = 0;
00203     else {
00204         m_dragConnection = new KToggleAction(i18n("Connect Signals/Slots"),
00205             "signalslot", KShortcut(0), this, SLOT(startCreatingConnection()), parent,
00206             "drag_connection");
00207         //to be exclusive with any 'widget' action
00208         m_dragConnection->setExclusiveGroup("LibActionWidgets");
00209         m_dragConnection->setChecked(false);
00210         actions.append(m_dragConnection);
00211     }
00212 
00213     m_pointer = new KToggleAction(i18n("Pointer"), "mouse_pointer", KShortcut(0), this, SLOT(slotPointerClicked()), parent, "pointer");
00214     m_pointer->setExclusiveGroup("LibActionWidgets"); //to be exclusive with any 'widget' action
00215     m_pointer->setChecked(true);
00216     actions.append(m_pointer);
00217 
00218     m_snapToGrid = new KToggleAction(i18n("Snap to Grid"), QString::null, KShortcut(0), 0, 0, parent, "snap_to_grid");
00219     m_snapToGrid->setChecked(true);
00220     actions.append(m_snapToGrid);
00221 
00222     // Create the Style selection action (with a combo box in toolbar and submenu items)
00223     KSelectAction *m_style = new KSelectAction( i18n("Style"), CTRL + Key_S, this, SLOT(slotStyle()), parent, "change_style");
00224     m_style->setEditable(false);
00225 
00226     KGlobal::config()->setGroup("General");
00227     QString currentStyle = QString::fromLatin1(kapp->style().name()).lower();
00228     const QStringList styles = QStyleFactory::keys();
00229     m_style->setItems(styles);
00230     m_style->setCurrentItem(0);
00231 
00232     QStringList::ConstIterator endIt = styles.constEnd();
00233     int idx = 0;
00234     for (QStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx)
00235     {
00236         if ((*it).lower() == currentStyle) {
00237             m_style->setCurrentItem(idx);
00238             break;
00239         }
00240     }
00241 
00242     m_style->setToolTip(i18n("Set the current view style."));
00243     m_style->setMenuAccelsEnabled(true);
00244     actions.append(m_style);
00245 
00246     lib->addCustomWidgetActions( parent );
00247 
00248     return actions;
00249 }
00250 
00251 bool
00252 FormManager::isPasteEnabled()
00253 {
00254     return m_domDoc.namedItem("UI").hasChildNodes();
00255 }
00256 
00257 void
00258 FormManager::undo()
00259 {
00260     if(!activeForm() || !activeForm()->objectTree())
00261         return;
00262 
00263     activeForm()->commandHistory()->undo();
00264 }
00265 
00266 void
00267 FormManager::redo()
00268 {
00269     if(!activeForm() || !activeForm()->objectTree())
00270         return;
00271 
00272     m_isRedoing = true;
00273     activeForm()->commandHistory()->redo();
00274     m_isRedoing = false;
00275 }
00276 
00277 void
00278 FormManager::insertWidget(const QCString &classname)
00279 {
00280     if(m_drawingSlot)
00281         stopCreatingConnection();
00282 
00283     m_inserting = true;
00284 
00285     Form *form;
00286     for(form = m_forms.first(); form; form = m_forms.next())
00287     {
00288 //      form->d->cursors = new QMap<QString, QCursor>();
00289         if (form->toplevelContainer())
00290             form->widget()->setCursor(QCursor(CrossCursor));
00291         QObjectList *l = form->widget()->queryList( "QWidget" );
00292         for(QObject *o = l->first(); o; o = l->next())
00293         {
00294             if( ((QWidget*)o)->ownCursor() )
00295             {
00296 //              form->d->cursors->insert(o->name(), ((QWidget*)o)->cursor());
00297                 form->d->cursors.insert(o, static_cast<QWidget*>(o)->cursor());
00298                 static_cast<QWidget*>(o)->setCursor(QCursor(Qt::CrossCursor));
00299             }
00300 
00301         }
00302         delete l;
00303     }
00304 
00305     m_selectedClass = classname;
00306     m_pointer->setChecked(false);
00307 }
00308 
00309 void
00310 FormManager::stopInsert()
00311 {
00312     if(m_drawingSlot)
00313         stopCreatingConnection();
00314     if(!m_inserting)
00315         return;
00316 
00317 //#ifndef KEXI_NO_CURSOR_PROPERTY
00318     Form *form;
00319     for(form = m_forms.first(); form; form = m_forms.next())
00320     {
00321         form->widget()->unsetCursor();
00322         QObjectList *l = form->widget()->queryList( "QWidget" );
00323         for(QObject *o = l->first(); o; o = l->next())
00324         {
00325             static_cast<QWidget*>(o)->unsetCursor();
00326 #if 0
00327             if( ((QWidget*)o)->ownCursor()) {
00328                 QMap<QObject*,QCursor>::ConstIterator curIt( form->d->cursors.find(o) );
00329                 if (curIt!=form->d->cursors.constEnd())
00330                     static_cast<QWidget*>(o)->setCursor( *curIt );
00331 //              ((QWidget*)o)->setCursor( (*(form->d->cursors))[o->name()] ) ;
00332             }
00333 #endif
00334         }
00335         delete l;
00336 //      delete (form->d->cursors);
00337 //      form->d->cursors = 0;
00338     }
00339 //#endif
00340     m_inserting = false;
00341     m_pointer->setChecked(true);
00342 }
00343 
00344 void
00345 FormManager::slotPointerClicked()
00346 {
00347     if(m_inserting)
00348         stopInsert();
00349     else if(m_dragConnection)
00350         stopCreatingConnection();
00351 }
00352 
00353 void
00354 FormManager::startCreatingConnection()
00355 {
00356     if (m_options & HideSignalSlotConnections)
00357         return;
00358 
00359     if(m_inserting)
00360         stopInsert();
00361 
00362     // We set a Pointing hand cursor while drawing the connection
00363     Form *form;
00364     for(form = m_forms.first(); form; form = m_forms.next())
00365     {
00366 //      form->d->cursors = new QMap<QString, QCursor>();
00367         form->d->mouseTrackers = new QStringList();
00368         if (form->toplevelContainer())
00369         {
00370             form->widget()->setCursor(QCursor(PointingHandCursor));
00371             form->widget()->setMouseTracking(true);
00372         }
00373         QObjectList *l = form->widget()->queryList( "QWidget" );
00374         for(QObject *o = l->first(); o; o = l->next())
00375         {
00376             QWidget *w = static_cast<QWidget*>(o);
00377             if( w->ownCursor() )
00378             {
00379                 form->d->cursors.insert(w, w->cursor());
00380 //              form->d->cursors->insert(w->name(), w->cursor());
00381                 w->setCursor(QCursor(PointingHandCursor ));
00382             }
00383             if(w->hasMouseTracking())
00384                 form->d->mouseTrackers->append(w->name());
00385             w->setMouseTracking(true);
00386         }
00387         delete l;
00388     }
00389     delete m_connection;
00390     m_connection = new Connection();
00391     m_drawingSlot = true;
00392     if (m_dragConnection)
00393         m_dragConnection->setChecked(true);
00394 }
00395 
00396 void
00397 FormManager::resetCreatedConnection()
00398 {
00399     if (m_options & HideSignalSlotConnections)
00400         return;
00401 
00402     delete m_connection;
00403     m_connection = new Connection();
00404 
00405     if(m_active && m_active->formWidget()) {
00406         Form *ff = (Form*)m_active;
00407         FormWidget *fw = 0;
00408         if (ff)
00409             fw = ff->formWidget();
00410         m_active->formWidget()->clearForm();
00411     }
00412     if (m_active && m_active->widget())
00413         m_active->widget()->repaint();
00414 }
00415 
00416 void
00417 FormManager::stopCreatingConnection()
00418 {
00419     if (m_options & HideSignalSlotConnections)
00420         return;
00421     if(!m_drawingSlot)
00422         return;
00423 
00424     if(m_active && m_active->formWidget())
00425         m_active->formWidget()->clearForm();
00426 
00427     Form *form;
00428     for(form = m_forms.first(); form; form = m_forms.next())
00429     {
00430         form->widget()->unsetCursor();
00431         form->widget()->setMouseTracking(false);
00432         QObjectList *l = form->widget()->queryList( "QWidget" );
00433         for(QObject *o = l->first(); o; o = l->next())
00434         {
00435             QWidget *w = (QWidget*)o;
00436             if( w->ownCursor()) {
00437                 QMap<QObject*,QCursor>::ConstIterator curIt( form->d->cursors.find(o) );
00438                 if (curIt!=form->d->cursors.constEnd())
00439                     static_cast<QWidget*>(o)->setCursor( *curIt );
00440             }
00441 //              w->setCursor( (*(form->d->cursors))[o->name()] ) ;
00442             w->setMouseTracking( !form->d->mouseTrackers->grep(w->name()).isEmpty() );
00443         }
00444         delete l;
00445 //      delete (form->d->cursors);
00446 //      form->d->cursors = 0;
00447         delete (form->d->mouseTrackers);
00448         form->d->mouseTrackers = 0;
00449     }
00450 
00451     if(m_connection->slot().isNull())
00452         emit connectionAborted(activeForm());
00453     delete m_connection;
00454     m_connection = 0;
00455     m_drawingSlot = false;
00456     m_pointer->setChecked(true);
00457 }
00458 
00459 bool
00460 FormManager::snapWidgetsToGrid()
00461 {
00462     return m_snapToGrid->isChecked();
00463 }
00464 
00465 void
00466 FormManager::windowChanged(QWidget *w)
00467 {
00468     kdDebug() << "FormManager::windowChanged(" 
00469         << (w ? (QString(w->className())+" "+w->name()) : QString("0")) << ")" << endl;
00470 
00471     if(!w)
00472     {
00473         m_active = 0;
00474         if(m_treeview)
00475             m_treeview->setForm(0);
00476         emit propertySetSwitched(0);
00477         if(isCreatingConnection())
00478             stopCreatingConnection();
00479 
00480         emitNoFormSelected();
00481         return;
00482     }
00483 
00484     Form *previousActive = m_active;
00485     Form *form;
00486     for(form = m_forms.first(); form; form = m_forms.next())
00487     {
00488         if(form->toplevelContainer() && form->widget() == w)
00489         {
00490             if(m_treeview)
00491                 m_treeview->setForm(form);
00492             //if(m_propSet)
00493             //  m_propList->setCollection(form->pixmapCollection());
00494 
00495             kdDebug() << "FormManager::windowChanged() active form is " << form->objectTree()->name() << endl;
00496 
00497             if(m_collection)
00498             {
00499 #ifndef KFD_NO_STYLES
00500                 // update the 'style' action
00501                 KSelectAction *m_style = (KSelectAction*)m_collection->action("change_style", "KSelectAction");
00502                 const QString currentStyle = form->widget()->style().name();
00503                 const QStringList styles = m_style->items();
00504 
00505                 int idx = 0;
00506                 QStringList::ConstIterator endIt = styles.constEnd();
00507                 for (QStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx)
00508                 {
00509                     if ((*it).lower() == currentStyle) {
00510                         kdDebug() << "Updating the style to " << currentStyle << endl;
00511                         m_style->setCurrentItem(idx);
00512                         break;
00513                     }
00514                 }
00515 #endif
00516             }
00517 
00518             if((form != previousActive) && isCreatingConnection())
00519                 resetCreatedConnection();
00520 
00521             m_active = form;
00522 
00523             emit  dirty(form, form->isModified());
00524             // update actions state
00525             m_active->emitActionSignals();
00526             //update the buffer too
00527             form->emitSelectionSignals();
00528 
00529             showPropertySet( propertySet(), true );
00530             return;
00531         }
00532     }
00533 
00534     for(form = m_preview.first(); form; form = m_preview.next())
00535     {
00536         kdDebug() << (form->widget() ? form->widget()->name() : "") << endl;
00537         if(form->toplevelContainer() && form->widget() == w) {
00538             kdDebug() << "FormManager::windowChanged() active preview form is " << form->widget()->name() << endl;
00539 
00540             if(m_collection)
00541             {
00542 #ifndef KFD_NO_STYLES
00543                 // update the 'style' action
00544                 KSelectAction *m_style = (KSelectAction*)m_collection->action("change_style", "KSelectAction");
00545                 const QString currentStyle = form->widget()->style().name();
00546                 const QStringList styles = m_style->items();
00547 
00548                 int idx = 0;
00549                 QStringList::ConstIterator endIt = styles.constEnd();
00550                 for (QStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx)
00551                 {
00552                     if ((*it).lower() == currentStyle) {
00553                         kdDebug() << "Updating the style to " << currentStyle << endl;
00554                         m_style->setCurrentItem(idx);
00555                         break;
00556                     }
00557                 }
00558 #endif
00559 
00560                 resetCreatedConnection();
00561                 m_active = form;
00562 
00563                 emit dirty(form, false);
00564                 emitNoFormSelected();
00565                 showPropertySet(0);
00566                 return;
00567             }
00568         }
00569     }
00570     //m_active = 0;
00571 }
00572 
00573 Form*
00574 FormManager::activeForm() const
00575 {
00576     return m_active;
00577 }
00578 
00579 Form*
00580 FormManager::formForWidget(QWidget *w)
00581 {
00582     for(Form *form = m_forms.first(); form; form = m_forms.next())  {
00583         if(form->toplevelContainer() && form->widget() == w)
00584             return form;
00585     }
00586 
00587     return 0; // not one of toplevel widgets
00588 }
00589 
00590 void
00591 FormManager::deleteForm(Form *form)
00592 {
00593     if (!form)
00594         return;
00595     if(m_forms.find(form) == -1)
00596         m_preview.remove(form);
00597     else
00598         m_forms.remove(form);
00599 
00600     if(m_forms.count() == 0) {
00601         m_active = 0;
00602         emit propertySetSwitched(0);
00603     }
00604 }
00605 
00606 void
00607 FormManager::importForm(Form *form, bool preview)
00608 {
00609     if(!preview)
00610         initForm(form);
00611     else
00612     {
00613         m_preview.append(form);
00614         form->setDesignMode(false);
00615     }
00616 }
00617 
00618 void
00619 FormManager::initForm(Form *form)
00620 {
00621     m_forms.append(form);
00622 
00623     if(m_treeview)
00624         m_treeview->setForm(form);
00625 
00626     m_active = form;
00627 
00628     connect(form, SIGNAL(selectionChanged(QWidget*, bool)), m_propSet, SLOT(setSelectedWidget(QWidget*, bool)));
00629     if(m_treeview)
00630     {
00631         connect(form, SIGNAL(selectionChanged(QWidget*, bool)), m_treeview, SLOT(setSelectedWidget(QWidget*, bool)));
00632         connect(form, SIGNAL(childAdded(ObjectTreeItem* )), m_treeview, SLOT(addItem(ObjectTreeItem*)));
00633         connect(form, SIGNAL(childRemoved(ObjectTreeItem* )), m_treeview, SLOT(removeItem(ObjectTreeItem*)));
00634     }
00635     connect(m_propSet, SIGNAL(widgetNameChanged(const QCString&, const QCString&)),
00636         form, SLOT(changeName(const QCString&, const QCString&)));
00637 
00638     form->setSelectedWidget(form->widget());
00639     windowChanged(form->widget());
00640 }
00641 
00642 void
00643 FormManager::previewForm(Form *form, QWidget *container, Form *toForm)
00644 {
00645     if(!form || !container || !form->objectTree())
00646         return;
00647     QDomDocument domDoc;
00648     if (!FormIO::saveFormToDom(form, domDoc))
00649         return;
00650 
00651     Form *myform;
00652     if(!toForm)
00653         myform = new Form(form->library(), form->objectTree()->name().latin1(), 
00654             false);
00655     else
00656         myform = toForm;
00657     myform->createToplevel(container);
00658     container->setStyle( &(form->widget()->style()) );
00659 
00660     if (!FormIO::loadFormFromDom(myform, container, domDoc)) {
00661         delete myform;
00662         return;
00663     }
00664 
00665     myform->setDesignMode(false);
00666     m_preview.append(myform);
00667     container->show();
00668 }
00669 
00670 /*
00671 bool
00672 FormManager::loadFormFromDomInternal(Form *form, QWidget *container, QDomDocument &inBuf)
00673 {
00674     return FormIO::loadFormFromDom(myform, container, domDoc);
00675 }
00676 
00677 bool
00678 FormManager::saveFormToStringInternal(Form *form, QString &dest, int indent)
00679 {
00680     return KFormDesigner::FormIO::saveFormToString(form, dest, indent);
00681 }*/
00682 
00683 bool
00684 FormManager::isTopLevel(QWidget *w)
00685 {
00686     if(!activeForm() || !activeForm()->objectTree())
00687         return false;
00688 
00689 //  kdDebug() << "FormManager::isTopLevel(): for: " << w->name() << " = "
00690 //      << activeForm()->objectTree()->lookup(w->name())<< endl;
00691 
00692     ObjectTreeItem *item = activeForm()->objectTree()->lookup(w->name());
00693     if(!item)
00694         return true;
00695 
00696     return (!item->parent());
00697 }
00698 
00699 void
00700 FormManager::deleteWidget()
00701 {
00702     if(!activeForm() || !activeForm()->objectTree())
00703         return;
00704 
00705     QPtrList<QWidget> *list = activeForm()->selectedWidgets();
00706     if(list->isEmpty())
00707         return;
00708 
00709     if (activeForm()->widget() == list->first()) {
00710         //toplevel form is selected, cannot delete it
00711         return;
00712     }
00713 
00714     KCommand *com = new DeleteWidgetCommand(*list, activeForm());
00715     activeForm()->addCommand(com, true);
00716 }
00717 
00718 void
00719 FormManager::copyWidget()
00720 {
00721     if (!activeForm() || !activeForm()->objectTree())
00722         return;
00723 
00724     QPtrList<QWidget> *list = activeForm()->selectedWidgets();
00725     if(list->isEmpty())
00726         return;
00727 
00728     removeChildrenFromList(*list);
00729 
00730     // We clear the current clipboard
00731     m_domDoc.setContent(QString(), true);
00732     QDomElement parent = m_domDoc.createElement("UI");
00733     m_domDoc.appendChild(parent);
00734 
00735     QWidget *w;
00736     for(w = list->first(); w; w = list->next())
00737     {
00738         ObjectTreeItem *it = activeForm()->objectTree()->lookup(w->name());
00739         if (!it)
00740             continue;
00741 
00742         FormIO::saveWidget(it, parent, m_domDoc);
00743     }
00744 
00745     FormIO::cleanClipboard(parent);
00746 
00747     activeForm()->emitActionSignals(); // to update 'Paste' item state
00748 }
00749 
00750 void
00751 FormManager::cutWidget()
00752 {
00753     if(!activeForm() || !activeForm()->objectTree())
00754         return;
00755 
00756     QPtrList<QWidget> *list = activeForm()->selectedWidgets();
00757     if(list->isEmpty())
00758         return;
00759 
00760     KCommand *com = new CutWidgetCommand(*list, activeForm());
00761     activeForm()->addCommand(com, true);
00762 }
00763 
00764 void
00765 FormManager::pasteWidget()
00766 {
00767     if(!m_domDoc.namedItem("UI").hasChildNodes())
00768         return;
00769     if(!activeForm() || !activeForm()->objectTree())
00770         return;
00771 
00772     KCommand *com = new PasteWidgetCommand(m_domDoc, activeForm()->activeContainer(), m_insertPoint);
00773     activeForm()->addCommand(com, true);
00774 }
00775 
00776 void
00777 FormManager::setInsertPoint(const QPoint &p)
00778 {
00779     m_insertPoint = p;
00780 }
00781 
00782 void
00783 FormManager::createSignalMenu(QWidget *w)
00784 {
00785     m_sigSlotMenu = new KPopupMenu();
00786     m_sigSlotMenu->insertTitle(SmallIcon("connection"), i18n("Signals"));
00787 
00788     QStrList list = w->metaObject()->signalNames(true);
00789     QStrListIterator it(list);
00790     for(; it.current() != 0; ++it)
00791         m_sigSlotMenu->insertItem(*it);
00792 
00793     int result = m_sigSlotMenu->exec(QCursor::pos());
00794     if(result == -1)
00795         resetCreatedConnection();
00796     else
00797         menuSignalChoosed(result);
00798 
00799     delete m_sigSlotMenu;
00800     m_sigSlotMenu = 0;
00801 }
00802 
00803 void
00804 FormManager::createSlotMenu(QWidget *w)
00805 {
00806     m_sigSlotMenu = new KPopupMenu();
00807     m_sigSlotMenu->insertTitle(SmallIcon("connection"), i18n("Slots"));
00808 
00809     QString signalArg( m_connection->signal().remove( QRegExp(".*[(]|[)]") ) );
00810 
00811     QStrList list = w->metaObject()->slotNames(true);
00812     QStrListIterator it(list);
00813     for(; it.current() != 0; ++it)
00814     {
00815         // we add the slot only if it is compatible with the signal
00816         QString slotArg(*it);
00817         slotArg = slotArg.remove( QRegExp(".*[(]|[)]") );
00818         if(!signalArg.startsWith(slotArg, true)) // args not compatible
00819             continue;
00820 
00821         m_sigSlotMenu->insertItem(*it);
00822     }
00823 
00824     int result = m_sigSlotMenu->exec(QCursor::pos());
00825     if(result == -1)
00826         resetCreatedConnection();
00827     else
00828         menuSignalChoosed(result);
00829 
00830     delete m_sigSlotMenu;
00831     m_sigSlotMenu = 0;
00832 }
00833 
00834 void
00835 FormManager::createContextMenu(QWidget *w, Container *container, bool popupAtCursor)
00836 {
00837     if(!activeForm() || !activeForm()->widget())
00838         return;
00839     const bool toplevelWidgetSelected = activeForm()->widget() == w;
00840     const uint widgetsCount = container->form()->selectedWidgets()->count();
00841     const bool multiple = widgetsCount > 1;
00842     //const bool enableRemove = w != m_active->widget();
00843     // We only enablelayout creation if more than one widget with the same parent are selected
00844     const bool enableLayout = multiple || w == container->widget();
00845 
00846     m_menuWidget = w;
00847     QString n = container->form()->library()->displayName(w->className());
00848 //  QValueVector<int> menuIds();
00849 
00850     if (!m_popup) {
00851         m_popup = new KPopupMenu();
00852     }
00853     else {
00854         m_popup->clear();
00855     }
00856 
00857     //set title
00858     if(!multiple)
00859     {
00860         if(w == container->form()->widget())
00861             m_popup->insertTitle(SmallIcon("form"), i18n("Form: ") + w->name());
00862         else
00863             m_popup->insertTitle( SmallIcon(
00864                 container->form()->library()->iconName(w->className())), n + ": " + w->name() );
00865     }
00866     else
00867         m_popup->insertTitle(SmallIcon("multiple_obj"), i18n("Multiple Widgets")
00868         + QString(" (%1)").arg(widgetsCount));
00869 
00870     KAction *a;
00871 #define PLUG_ACTION(_name, forceVisible) \
00872     { a = action(_name); \
00873     if (a && (forceVisible || a->isEnabled())) { \
00874         if (separatorNeeded) \
00875             m_popup->insertSeparator(); \
00876         separatorNeeded = false; \
00877         a->plug(m_popup); \
00878     } \
00879     }
00880 
00881     bool separatorNeeded = false;
00882 
00883     PLUG_ACTION("edit_cut", !toplevelWidgetSelected);
00884     PLUG_ACTION("edit_copy", !toplevelWidgetSelected);
00885     PLUG_ACTION("edit_paste", true);
00886     PLUG_ACTION("edit_delete", !toplevelWidgetSelected);
00887     separatorNeeded = true;
00888     PLUG_ACTION("layout_menu", enableLayout);
00889     PLUG_ACTION("break_layout", enableLayout);
00890     separatorNeeded = true;
00891     PLUG_ACTION("align_menu", !toplevelWidgetSelected);
00892     PLUG_ACTION("adjust_size_menu", !toplevelWidgetSelected);
00893     separatorNeeded = true;
00894 
00895     // We create the buddy menu
00896     if(!multiple && w->inherits("QLabel") && ((QLabel*)w)->text().contains("&") && (((QLabel*)w)->textFormat() != RichText))
00897     {
00898         if (separatorNeeded)
00899             m_popup->insertSeparator();
00900 
00901         KPopupMenu *sub = new KPopupMenu(w);
00902         QWidget *buddy = ((QLabel*)w)->buddy();
00903 
00904         sub->insertItem(i18n("No Buddy"), MenuNoBuddy);
00905         if(!buddy)
00906             sub->setItemChecked(MenuNoBuddy, true);
00907         sub->insertSeparator();
00908 
00909         // add all the widgets that can have focus
00910         for(ObjectTreeListIterator it( container->form()->tabStopsIterator() ); it.current(); ++it)
00911         {
00912             int index = sub->insertItem( 
00913                 SmallIcon(container->form()->library()->iconName(it.current()->className().latin1())),
00914                 it.current()->name());
00915             if(it.current()->widget() == buddy)
00916                 sub->setItemChecked(index, true);
00917         }
00918 
00919         /*int id =*/ m_popup->insertItem(i18n("Choose Buddy..."), sub);
00920 //      menuIds->append(id);
00921         connect(sub, SIGNAL(activated(int)), this, SLOT(buddyChoosed(int)));
00922 
00923         separatorNeeded = true;
00924     }
00925 
00926     //int sigid=0;
00927 #ifdef KEXI_SHOW_DEBUG_ACTIONS
00928     if(!multiple && !(m_options & HideEventsInPopupMenu))
00929     {
00930         if (separatorNeeded)
00931             m_popup->insertSeparator();
00932 
00933         // We create the signals menu
00934         KPopupMenu *sigMenu = new KPopupMenu();
00935         QStrList list = w->metaObject()->signalNames(true);
00936         QStrListIterator it(list);
00937         for(; it.current() != 0; ++it)
00938             sigMenu->insertItem(*it);
00939 
00940         int id = m_popup->insertItem(SmallIconSet(""), i18n("Events"), sigMenu);
00941 //      menuIds->append(id);
00942         if(list.isEmpty())
00943             m_popup->setItemEnabled(id, false);
00944         connect(sigMenu, SIGNAL(activated(int)), this, SLOT(menuSignalChoosed(int)));
00945         separatorNeeded = true;
00946     }
00947 #endif
00948 
00949     // Other items
00950     if(!multiple)
00951     {
00952         int lastID = -1;
00953         if (separatorNeeded) {
00954             lastID = m_popup->insertSeparator();
00955         }
00956         const uint oldIndex = m_popup->count()-1;
00957         container->form()->library()->createMenuActions(w->className(), w, m_popup, container);
00958         if (oldIndex == (m_popup->count()-1)) {
00959 //          for (uint i=oldIndex; i<m_popup->count(); i++) {
00960 //              int id = m_popup->idAt( i );
00961 //              if (id!=-1)
00962 //                  menuIds->append( id );
00963 //          }
00964             //nothing added
00965             if (separatorNeeded) {
00966                 m_popup->removeItem( lastID );
00967 //              menuIds->pop_back();
00968             }
00969         }
00970     }
00971 
00972     //show the popup at the selected widget
00973     QPoint popupPos;
00974     if (popupAtCursor) {
00975         popupPos = QCursor::pos();
00976     }
00977     else {
00978         WidgetList *lst = container->form()->selectedWidgets();
00979         QWidget * sel_w = lst ? lst->first() : container->form()->selectedWidget();
00980         popupPos = sel_w ? sel_w->mapToGlobal(QPoint(sel_w->width()/2, sel_w->height()/2)) : QCursor::pos();
00981     }
00982     m_insertPoint = container->widget()->mapFromGlobal(popupPos);
00983     m_popup->exec(popupPos);//QCursor::pos());
00984     m_insertPoint = QPoint();
00985 
00986 //  QValueVector<int>::iterator it;
00987 //  for(it = menuIds->begin(); it != menuIds->end(); ++it)
00988 //      m_popup->removeItem(*it);
00989 }
00990 
00991 void
00992 FormManager::buddyChoosed(int id)
00993 {
00994     if(!m_menuWidget)
00995         return;
00996     QLabel *label = static_cast<QLabel*>((QWidget*)m_menuWidget);
00997 
00998     if(id == MenuNoBuddy)
00999     {
01000         label->setBuddy(0);
01001         return;
01002     }
01003 
01004     ObjectTreeItem *item = activeForm()->objectTree()->lookup(m_popup->text(id));
01005     if(!item || !item->widget())
01006         return;
01007     label->setBuddy(item->widget());
01008 }
01009 
01010 void
01011 FormManager::menuSignalChoosed(int id)
01012 {
01013     if (m_options & HideSignalSlotConnections)
01014         return;
01015 
01016     //if(!m_menuWidget)
01017     //  return;
01018     if(m_drawingSlot && m_sigSlotMenu)
01019     {
01020         if( m_connection->receiver().isNull() )
01021             m_connection->setSignal(m_sigSlotMenu->text(id));
01022         else
01023         {
01024             m_connection->setSlot(m_sigSlotMenu->text(id));
01025             kdDebug() << "Finished creating the connection: sender=" << m_connection->sender() << "; signal=" << m_connection->signal() <<
01026               "; receiver=" << m_connection->receiver() << "; slot=" << m_connection->slot() << endl;
01027             emit connectionCreated(activeForm(), *m_connection);
01028             stopCreatingConnection();
01029         }
01030     }
01031     else if(m_menuWidget)
01032         emit(createFormSlot(m_active, m_menuWidget->name(), m_popup->text(id)));
01033 }
01034 
01035 void
01036 FormManager::slotConnectionCreated(Form *form, Connection &connection)
01037 {
01038     if (m_options & HideSignalSlotConnections)
01039         return;
01040     if(!form)
01041         return;
01042 
01043     Connection *c = new Connection(connection);
01044     form->connectionBuffer()->append(c);
01045 }
01046 
01047 void
01048 FormManager::layoutHBox()
01049 {
01050     createLayout(Container::HBox);
01051 }
01052 
01053 void
01054 FormManager::layoutVBox()
01055 {
01056     createLayout(Container::VBox);
01057 }
01058 
01059 void
01060 FormManager::layoutGrid()
01061 {
01062     createLayout(Container::Grid);
01063 }
01064 
01065 void
01066 FormManager::layoutHSplitter()
01067 {
01068     createLayout(Container::HSplitter);
01069 }
01070 
01071 void
01072 FormManager::layoutVSplitter()
01073 {
01074     createLayout(Container::VSplitter);
01075 }
01076 
01077 void
01078 FormManager::layoutHFlow()
01079 {
01080     createLayout(Container::HFlow);
01081 }
01082 
01083 void
01084 FormManager::layoutVFlow()
01085 {
01086     createLayout(Container::VFlow);
01087 }
01088 
01089 void
01090 FormManager::createLayout(int layoutType)
01091 {
01092     WidgetList *list = m_active->selectedWidgets();
01093     // if only one widget is selected (a container), we modify its layout
01094     if (list->isEmpty()) {//sanity check
01095         kdWarning() << "FormManager::createLayout(): list is empty!" << endl;
01096         return;
01097     }
01098     if(list->count() == 1)
01099     {
01100         ObjectTreeItem *item = m_active->objectTree()->lookup(list->first()->name());
01101         if(!item || !item->container() || !m_propSet->contains("layout"))
01102             return;
01103         (*m_propSet)["layout"] = Container::layoutTypeToString(layoutType);
01104         return;
01105     }
01106 
01107     QWidget *parent = list->first()->parentWidget();
01108     for(QWidget *w = list->first(); w; w = list->next())
01109     {
01110         kdDebug() << "comparing widget " << w->name() << " whose parent is " << w->parentWidget()->name() << " insteaed of " << parent->name() << endl;
01111         if(w->parentWidget() != parent)
01112         {
01113             KMessageBox::sorry(m_active->widget()->topLevelWidget(), i18n("<b>Cannot create the layout.</b>\n"
01114            "All selected widgets must have the same parent."));
01115             kdDebug() << "FormManager::createLayout() widgets don't have the same parent widget" << endl;
01116             return;
01117         }
01118     }
01119 
01120     KCommand *com = new CreateLayoutCommand(layoutType, *list, m_active);
01121     m_active->addCommand(com, true);
01122 }
01123 
01124 void
01125 FormManager::breakLayout()
01126 {
01127     if(!activeForm() || !activeForm()->objectTree())
01128         return;
01129 
01130     Container *container = activeForm()->activeContainer();
01131     QCString c( container->widget()->className() );
01132 
01133     if((c == "Grid") || (c == "VBox") || (c == "HBox") || (c == "HFlow") || (c == "VFlow"))
01134     {
01135         KCommand *com = new BreakLayoutCommand(container);
01136         m_active->addCommand(com, true);
01137     }
01138     else // normal container
01139     {
01140         if(activeForm()->selectedWidgets()->count() == 1)
01141             (*m_propSet)["layout"] = "NoLayout";
01142         else
01143             container->setLayout(Container::NoLayout);
01144     }
01145 }
01146 
01147 void
01148 FormManager::showPropertySet(WidgetPropertySet *propSet, bool forceReload)
01149 {
01150     if (m_objectBlockingPropertyEditorUpdating)
01151         return;
01152 
01153     if(m_editor)
01154         m_editor->changeSet(propSet ? propSet->set() : 0);
01155 
01156     emit propertySetSwitched(propSet ? propSet->set(): 0, forceReload);
01157 }
01158 
01159 void
01160 FormManager::blockPropertyEditorUpdating(void *blockingObject)
01161 {
01162     if (!blockingObject || m_objectBlockingPropertyEditorUpdating)
01163         return;
01164     m_objectBlockingPropertyEditorUpdating = blockingObject;
01165 }
01166 
01167 void
01168 FormManager::unblockPropertyEditorUpdating(void *blockingObject, WidgetPropertySet *propSet)
01169 {
01170     if (!blockingObject || m_objectBlockingPropertyEditorUpdating!=blockingObject)
01171         return;
01172 
01173     m_objectBlockingPropertyEditorUpdating = 0;
01174     showPropertySet(propSet, true/*forceReload*/);
01175 }
01176 
01177 void
01178 FormManager::editTabOrder()
01179 {
01180     if(!activeForm() || !activeForm()->objectTree())
01181         return;
01182     QWidget *topLevel = m_active->widget()->topLevelWidget();
01183     TabStopDialog dlg(topLevel);
01184     //const bool oldAutoTabStops = m_active->autoTabStops();
01185     if (dlg.exec(m_active) == QDialog::Accepted) {
01186         //inform about changing "autoTabStop" property
01187         // -- this will be received eg. by Kexi, so custom "autoTabStop" property can be updated
01188         emit autoTabStopsSet(m_active, dlg.autoTabStops());
01189         //force set dirty
01190         emit dirty(m_active, true);
01191     }
01192 }
01193 
01194 void
01195 FormManager::slotStyle()
01196 {
01197     if(!activeForm())
01198         return;
01199 
01200     KSelectAction *m_style = (KSelectAction*)m_collection->action("change_style", "KSelectAction");
01201     QString style = m_style->currentText();
01202     activeForm()->widget()->setStyle( style);
01203 
01204     QObjectList *l = activeForm()->widget()->queryList( "QWidget" );
01205     for(QObject *o = l->first(); o; o = l->next())
01206         (static_cast<QWidget*>(o))->setStyle( style );
01207     delete l;
01208 }
01209 
01210 void
01211 FormManager::editFormPixmapCollection()
01212 {
01213     if(!activeForm() || !activeForm()->objectTree())
01214         return;
01215 
01216     PixmapCollectionEditor dialog(activeForm()->pixmapCollection(), activeForm()->widget()->topLevelWidget());
01217     dialog.exec();
01218 }
01219 
01220 void
01221 FormManager::editConnections()
01222 {
01223     if (m_options & HideSignalSlotConnections)
01224         return;
01225     if(!activeForm() || !activeForm()->objectTree())
01226         return;
01227 
01228     ConnectionDialog dialog(activeForm()->widget()->topLevelWidget());
01229     dialog.exec(activeForm());
01230 }
01231 
01232 void
01233 FormManager::alignWidgets(int type)
01234 {
01235     if(!activeForm() || !activeForm()->objectTree() || (activeForm()->selectedWidgets()->count() < 2))
01236         return;
01237 
01238     QWidget *parentWidget = activeForm()->selectedWidgets()->first()->parentWidget();
01239 
01240     for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
01241     {
01242         if(w->parentWidget() != parentWidget)
01243         {
01244             kdDebug() << "FormManager::alignWidgets() type ==" << type <<  " widgets don't have the same parent widget" << endl;
01245             return;
01246         }
01247     }
01248 
01249     KCommand *com = new AlignWidgetsCommand(type, *(activeForm()->selectedWidgets()), activeForm());
01250     activeForm()->addCommand(com, true);
01251 }
01252 
01253 void
01254 FormManager::alignWidgetsToLeft()
01255 {
01256     alignWidgets(AlignWidgetsCommand::AlignToLeft);
01257 }
01258 
01259 void
01260 FormManager::alignWidgetsToRight()
01261 {
01262     alignWidgets(AlignWidgetsCommand::AlignToRight);
01263 }
01264 
01265 void
01266 FormManager::alignWidgetsToTop()
01267 {
01268     alignWidgets(AlignWidgetsCommand::AlignToTop);
01269 }
01270 
01271 void
01272 FormManager::alignWidgetsToBottom()
01273 {
01274     alignWidgets(AlignWidgetsCommand::AlignToBottom);
01275 }
01276 
01277 void
01278 FormManager::adjustWidgetSize()
01279 {
01280     if(!activeForm() || !activeForm()->objectTree())
01281         return;
01282 
01283     KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToFit, *(activeForm()->selectedWidgets()), activeForm());
01284     activeForm()->addCommand(com, true);
01285 }
01286 
01287 void
01288 FormManager::alignWidgetsToGrid()
01289 {
01290     if(!activeForm() || !activeForm()->objectTree())
01291         return;
01292 
01293     KCommand *com = new AlignWidgetsCommand(AlignWidgetsCommand::AlignToGrid, *(activeForm()->selectedWidgets()), activeForm());
01294     activeForm()->addCommand(com, true);
01295 }
01296 
01297 void
01298 FormManager::adjustSizeToGrid()
01299 {
01300     if(!activeForm() || !activeForm()->objectTree())
01301         return;
01302 
01303     KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToGrid, *(activeForm()->selectedWidgets()), activeForm());
01304     activeForm()->addCommand(com, true);
01305 }
01306 
01307 void
01308 FormManager::adjustWidthToSmall()
01309 {
01310     if(!activeForm() || !activeForm()->objectTree())
01311         return;
01312 
01313     KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToSmallWidth, *(activeForm()->selectedWidgets()), activeForm());
01314     activeForm()->addCommand(com, true);
01315 }
01316 
01317 void
01318 FormManager::adjustWidthToBig()
01319 {
01320     if(!activeForm() || !activeForm()->objectTree())
01321         return;
01322 
01323     KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToBigWidth, *(activeForm()->selectedWidgets()), activeForm());
01324     activeForm()->addCommand(com, true);
01325 }
01326 
01327 void
01328 FormManager::adjustHeightToSmall()
01329 {
01330     if(!activeForm() || !activeForm()->objectTree())
01331         return;
01332 
01333     KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToSmallHeight, *(activeForm()->selectedWidgets()), activeForm());
01334     activeForm()->addCommand(com, true);
01335 }
01336 
01337 void
01338 FormManager::adjustHeightToBig()
01339 {
01340     if(!activeForm() || !activeForm()->objectTree())
01341         return;
01342 
01343     KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToBigHeight, *(activeForm()->selectedWidgets()), activeForm());
01344     activeForm()->addCommand(com, true);
01345 }
01346 
01347 void
01348 FormManager::bringWidgetToFront()
01349 {
01350     if(!activeForm() || !activeForm()->objectTree())
01351         return;
01352 
01353     for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
01354         w->raise();
01355 }
01356 
01357 void
01358 FormManager::sendWidgetToBack()
01359 {
01360     if(!activeForm() || !activeForm()->objectTree())
01361         return;
01362 
01363     for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
01364         w->lower();
01365 }
01366 
01367 void
01368 FormManager::selectAll()
01369 {
01370     if(!activeForm() || !activeForm()->objectTree())
01371         return;
01372 
01373     activeForm()->selectFormWidget();
01374     for(ObjectTreeItem *it = activeForm()->objectTree()->children()->first(); it; it = activeForm()->objectTree()->children()->next())
01375         activeForm()->setSelectedWidget(it->widget(), true);
01376 }
01377 
01378 void
01379 FormManager::clearWidgetContent()
01380 {
01381     if(!activeForm() || !activeForm()->objectTree())
01382         return;
01383 
01384     for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next())
01385         activeForm()->library()->clearWidgetContent(w->className(), w);
01386 }
01387 
01388 void
01389 FormManager::deleteWidgetLater( QWidget *w )
01390 {
01391     w->hide();
01392     w->reparent(0, WType_TopLevel, QPoint(0,0));
01393     m_deleteWidgetLater_list.append( w );
01394     m_deleteWidgetLater_timer.start( 100, true );
01395 }
01396 
01397 void
01398 FormManager::deleteWidgetLaterTimeout()
01399 {
01400     m_deleteWidgetLater_list.clear();
01401 }
01402 
01403 void
01404 FormManager::showFormUICode()
01405 {
01406 #ifdef KEXI_SHOW_DEBUG_ACTIONS
01407     if(!activeForm())
01408         return;
01409 
01410     QString uiCode;
01411     if (!FormIO::saveFormToString(activeForm(), uiCode, 3)) {
01413         return;
01414     }
01415 
01416     if (!m_uiCodeDialog) {
01417         m_uiCodeDialog = new KDialogBase(0, "uiwindow", true, i18n("Form's UI Code"),
01418                 KDialogBase::Close, KDialogBase::Close);
01419         m_uiCodeDialog->resize(700, 600);
01420         QVBox *box = m_uiCodeDialog->makeVBoxMainWidget();
01421         KTabWidget* tab = new KTabWidget(box);
01422 
01423         m_currentUICodeDialogEditor = new KTextEdit(QString::null, QString::null, tab);
01424         tab->addTab( m_currentUICodeDialogEditor, i18n("Current"));
01425         m_currentUICodeDialogEditor->setReadOnly(true);
01426         QFont f( m_currentUICodeDialogEditor->font() );
01427         f.setFamily("courier");
01428         m_currentUICodeDialogEditor->setFont(f);
01429         m_currentUICodeDialogEditor->setTextFormat(Qt::PlainText);
01430 
01431         m_originalUICodeDialogEditor = new KTextEdit(QString::null, QString::null, tab);
01432         tab->addTab( m_originalUICodeDialogEditor, i18n("Original"));
01433         m_originalUICodeDialogEditor->setReadOnly(true);
01434         m_originalUICodeDialogEditor->setFont(f);
01435         m_originalUICodeDialogEditor->setTextFormat(Qt::PlainText);
01436     }
01437     m_currentUICodeDialogEditor->setText( uiCode );
01438     //indent and set our original doc as well:
01439     QDomDocument doc;
01440     doc.setContent( activeForm()->m_recentlyLoadedUICode );
01441     m_originalUICodeDialogEditor->setText( doc.toString( 3 ) );
01442     m_uiCodeDialog->show();
01443 #endif
01444 }
01445 
01446 void
01447 FormManager::slotSettingsChanged(int category)
01448 {
01449     if (category==KApplication::SETTINGS_SHORTCUTS) {
01450         m_contextMenuKey = KGlobalSettings::contextMenuKey();
01451     }
01452 }
01453 
01454 void
01455 FormManager::emitWidgetSelected( KFormDesigner::Form* form, bool multiple )
01456 {
01457     enableFormActions();
01458     // Enable edit actions
01459     enableAction("edit_copy", true);
01460     enableAction("edit_cut", true);
01461     enableAction("edit_delete", true);
01462     enableAction("clear_contents", true);
01463 
01464     // 'Align Widgets' menu
01465     enableAction("align_menu", multiple);
01466     enableAction("align_to_left", multiple);
01467     enableAction("align_to_right", multiple);
01468     enableAction("align_to_top", multiple);
01469     enableAction("align_to_bottom", multiple);
01470 
01471     enableAction("adjust_size_menu", true);
01472     enableAction("adjust_width_small", multiple);
01473     enableAction("adjust_width_big", multiple);
01474     enableAction("adjust_height_small", multiple);
01475     enableAction("adjust_height_big", multiple);
01476 
01477     enableAction("format_raise", true);
01478     enableAction("format_lower", true);
01479 
01480     WidgetList *wlist = form->selectedWidgets();
01481     bool fontEnabled = false;
01482     for (WidgetListIterator it(*wlist); it.current(); ++it) {
01483         if (-1 != it.current()->metaObject()->findProperty("font", true)) {
01484             fontEnabled = true;
01485             break;
01486         }
01487     }
01488     enableAction("format_font", fontEnabled);
01489 
01490     // If the widgets selected is a container, we enable layout actions
01491     bool containerSelected = false;
01492     if(!multiple)
01493     {
01494         KFormDesigner::ObjectTreeItem *item = 0;
01495         if (form->selectedWidgets()->first())
01496             form->objectTree()->lookup( form->selectedWidgets()->first()->name() );
01497         if(item && item->container())
01498             containerSelected = true;
01499     }
01500     const bool twoSelected = form->selectedWidgets()->count()==2;
01501     // Layout actions
01502     enableAction("layout_menu", multiple || containerSelected);
01503     enableAction("layout_hbox", multiple || containerSelected);
01504     enableAction("layout_vbox", multiple || containerSelected);
01505     enableAction("layout_grid", multiple || containerSelected);
01506     enableAction("layout_hsplitter", twoSelected);
01507     enableAction("layout_vsplitter", twoSelected);
01508 
01509     KFormDesigner::Container *container = activeForm()->activeContainer();
01510     if (container)
01511         enableAction("break_layout", (container->layoutType() != KFormDesigner::Container::NoLayout));
01512 
01513     emit widgetSelected(form, true);
01514 }
01515 
01516 void
01517 FormManager::emitFormWidgetSelected( KFormDesigner::Form* form )
01518 {
01519 //  disableWidgetActions();
01520     enableAction("edit_copy", false);
01521     enableAction("edit_cut", false);
01522     enableAction("edit_delete", false);
01523     enableAction("clear_contents", false);
01524 
01525     // Disable format functions
01526     enableAction("align_menu", false);
01527     enableAction("align_to_left", false);
01528     enableAction("align_to_right", false);
01529     enableAction("align_to_top", false);
01530     enableAction("align_to_bottom", false);
01531     enableAction("adjust_size_menu", false);
01532     enableAction("format_raise", false);
01533     enableAction("format_lower", false);
01534 
01535     enableAction("format_font", false);
01536 
01537     enableFormActions();
01538 
01539     const bool twoSelected = form->selectedWidgets()->count()==2;
01540     const bool hasChildren = !form->objectTree()->children()->isEmpty();
01541 
01542     // Layout actions
01543     enableAction("layout_menu", hasChildren);
01544     enableAction("layout_hbox", hasChildren);
01545     enableAction("layout_vbox", hasChildren);
01546     enableAction("layout_grid", hasChildren);
01547     enableAction("layout_hsplitter", twoSelected);
01548     enableAction("layout_vsplitter", twoSelected);
01549     enableAction("break_layout", (form->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout));
01550 
01551     emit formWidgetSelected( form );
01552 }
01553 
01554 void
01555 FormManager::emitNoFormSelected()
01556 {
01557     disableWidgetActions();
01558 
01559     // Disable edit actions
01560 //  enableAction("edit_paste", false);
01561 //  enableAction("edit_undo", false);
01562 //  enableAction("edit_redo", false);
01563 
01564     // Disable 'Tools' actions
01565     enableAction("pixmap_collection", false);
01566     if (!(m_options & HideSignalSlotConnections))
01567         enableAction("form_connections", false);
01568     enableAction("taborder", false);
01569     enableAction("change_style", activeForm()!=0);
01570 
01571     // Disable items in 'File'
01572     if (!(m_options & SkipFileActions)) {
01573         enableAction("file_save", false);
01574         enableAction("file_save_as", false);
01575         enableAction("preview_form", false);
01576     }
01577 
01578     emit noFormSelected();
01579 }
01580 
01581 void
01582 FormManager::enableFormActions()
01583 {
01584     // Enable 'Tools' actions
01585     enableAction("pixmap_collection", true);
01586     if (!(m_options & HideSignalSlotConnections))
01587         enableAction("form_connections", true);
01588     enableAction("taborder", true);
01589     enableAction("change_style", true);
01590 
01591     // Enable items in 'File'
01592     if (!(m_options & SkipFileActions)) {
01593         enableAction("file_save", true);
01594         enableAction("file_save_as", true);
01595         enableAction("preview_form", true);
01596     }
01597 
01598     enableAction("edit_paste", isPasteEnabled());
01599     enableAction("edit_select_all", true);
01600 }
01601 
01602 void
01603 FormManager::disableWidgetActions()
01604 {
01605     // Disable edit actions
01606     enableAction("edit_copy", false);
01607     enableAction("edit_cut", false);
01608     enableAction("edit_delete", false);
01609     enableAction("clear_contents", false);
01610 
01611     // Disable format functions
01612     enableAction("align_menu", false);
01613     enableAction("align_to_left", false);
01614     enableAction("align_to_right", false);
01615     enableAction("align_to_top", false);
01616     enableAction("align_to_bottom", false);
01617     enableAction("adjust_size_menu", false);
01618     enableAction("format_raise", false);
01619     enableAction("format_lower", false);
01620 
01621     enableAction("layout_menu", false);
01622     enableAction("layout_hbox", false);
01623     enableAction("layout_vbox", false);
01624     enableAction("layout_grid", false);
01625     enableAction("layout_hsplitter", false);
01626     enableAction("layout_vsplitter", false);
01627     enableAction("break_layout", false);
01628 }
01629 
01630 void
01631 FormManager::emitUndoEnabled(bool enabled, const QString &text)
01632 {
01633     enableAction("edit_undo", enabled);
01634     emit undoEnabled(enabled, text);
01635 }
01636 
01637 void
01638 FormManager::emitRedoEnabled(bool enabled, const QString &text)
01639 {
01640     enableAction("edit_redo", enabled);
01641     emit redoEnabled(enabled, text);
01642 }
01643 
01644 void
01645 FormManager::changeFont()
01646 {
01647     if (!m_active)
01648         return;
01649     WidgetList *wlist = m_active->selectedWidgets();
01650     WidgetList widgetsWithFontProperty;
01651     QWidget *widget;
01652     QFont font;
01653     bool oneFontSelected = true;
01654     for (WidgetListIterator it(*wlist); (widget = it.current()); ++it) {
01655         if (m_active->library()->isPropertyVisible(widget->className(), widget, "font")) {
01656             widgetsWithFontProperty.append(widget);
01657             if (oneFontSelected) {
01658                 if (widgetsWithFontProperty.count()==1)
01659                     font = widget->font();
01660                 else if (font != widget->font())
01661                     oneFontSelected = false;
01662             }
01663         }
01664     }
01665     if (widgetsWithFontProperty.isEmpty())
01666         return;
01667     if (!oneFontSelected) //many different fonts selected: pick a font from toplevel conatiner
01668         font = m_active->widget()->font();
01669 
01670     if (1==widgetsWithFontProperty.count()) {
01671         //single widget's settings
01672         widget = widgetsWithFontProperty.first();
01673         KoProperty::Property &fontProp = m_propSet->property("font");
01674         if (QDialog::Accepted != KFontDialog::getFont(font, false, m_active->widget()))
01675             return;
01676         fontProp = font;
01677         return;
01678     }
01679     //multiple widgets
01680     int diffFlags=0;
01681     if (QDialog::Accepted != KFontDialog::getFontDiff(font, diffFlags, false, m_active->widget())
01682         || 0==diffFlags)
01683         return;
01684     //update font
01685     for (WidgetListIterator it(widgetsWithFontProperty); (widget = it.current()); ++it) {
01686         QFont prevFont( widget->font() );
01687         if (diffFlags & KFontChooser::FontDiffFamily)
01688             prevFont.setFamily( font.family() );
01689         if (diffFlags & KFontChooser::FontDiffStyle) {
01690             prevFont.setBold( font.bold() );
01691             prevFont.setItalic( font.italic() );
01692         }
01693         if (diffFlags & KFontChooser::FontDiffSize)
01694             prevFont.setPointSize( font.pointSize() );
01697         widget->setFont( prevFont );
01698         //temporary fix for dirty flag:
01699         emit dirty(m_active, true);
01700     }
01701 }
01702 
01703 #include "formmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys