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