diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/formeditor/formmanager.cpp | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/formeditor/formmanager.cpp')
-rw-r--r-- | kexi/formeditor/formmanager.cpp | 1716 |
1 files changed, 1716 insertions, 0 deletions
diff --git a/kexi/formeditor/formmanager.cpp b/kexi/formeditor/formmanager.cpp new file mode 100644 index 00000000..20b40cf9 --- /dev/null +++ b/kexi/formeditor/formmanager.cpp @@ -0,0 +1,1716 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Cedric Pasteur <[email protected]> + Copyright (C) 2005 Jaroslaw Staniek <[email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <kdebug.h> + +#include <qworkspace.h> +#include <qcursor.h> +#include <qstring.h> +#include <qlabel.h> +#include <qobjectlist.h> +#include <qstylefactory.h> +#include <qmetaobject.h> +#include <qregexp.h> +#include <qvaluevector.h> +#include <qvbox.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kpopupmenu.h> +#include <kstdaction.h> +#include <kaction.h> +#include <kxmlguiclient.h> +#include <kmainwindow.h> +#include <kmessagebox.h> +#include <kconfig.h> +#include <kstyle.h> +#include <kactionclasses.h> +#include <kapplication.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kdialogbase.h> +#include <ktextedit.h> +#include <ktabwidget.h> +#include <kfontdialog.h> + +#include <kdeversion.h> +#if KDE_VERSION >= KDE_MAKE_VERSION(3,1,9) && !defined(Q_WS_WIN) +# include <kactioncollection.h> +#endif + +#include "widgetpropertyset.h" +#include "objecttree.h" +#include "widgetlibrary.h" +#include "form.h" +#include "container.h" +#include "formIO.h" +#include "objecttreeview.h" +#include "commands.h" +#include "tabstopdialog.h" +#include "connectiondialog.h" +#include "pixmapcollection.h" +#include "events.h" +#include "utils.h" +#include "kfdpixmapedit.h" +#include <koproperty/editor.h> +#include <koproperty/property.h> +#include <koproperty/factory.h> + +#include "formmanager.h" + +#define KFD_NO_STYLES //disables; styles support needs improvements + +namespace KFormDesigner { + +//! @internal +class PropertyFactory : public KoProperty::CustomPropertyFactory +{ + public: + PropertyFactory(QObject *parent) + : KoProperty::CustomPropertyFactory(parent) +// m_manager(manager) + { + } + virtual ~PropertyFactory() {} + + KoProperty::CustomProperty* createCustomProperty(KoProperty::Property *) { return 0;} + + KoProperty::Widget* createCustomWidget(KoProperty::Property *prop) + { + return new KFDPixmapEdit(prop); + } +}; + +} + +using namespace KFormDesigner; + +static KStaticDeleter<FormManager> m_managerDeleter; +FormManager* FormManager::_self = 0L; + +FormManager::FormManager(QObject *parent, int options, const char *name) + : QObject(parent, name) +#ifdef KEXI_DEBUG_GUI + , m_uiCodeDialog(0) + , m_options(options) +#endif + , m_objectBlockingPropertyEditorUpdating(0) + , m_isRedoing(false) +{ + Q_UNUSED(options); +#ifdef KEXI_STANDALONE + KGlobal::locale()->insertCatalogue("standalone_kformdesigner"); +#else + KGlobal::locale()->insertCatalogue("kformdesigner"); +#endif + + connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) ); + slotSettingsChanged(KApplication::SETTINGS_SHORTCUTS); + +//moved to createWidgetLibrary() m_lib = new WidgetLibrary(this, supportedFactoryGroups); + m_propSet = new WidgetPropertySet(this); + + //unused m_editor = 0; + m_active = 0; + m_inserting = false; + m_drawingSlot = false; + m_collection = 0; + m_connection = 0; + m_popup = 0; + m_treeview = 0; + m_emitSelectionSignalsUpdatesPropertySet = false; + m_domDoc.appendChild(m_domDoc.createElement("UI")); + + m_deleteWidgetLater_list.setAutoDelete(true); + connect( &m_deleteWidgetLater_timer, SIGNAL(timeout()), this, SLOT(deleteWidgetLaterTimeout())); + connect( this, SIGNAL(connectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&)), + this, SLOT(slotConnectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&))); + + // register kfd custom editors + KoProperty::FactoryManager::self()->registerFactoryForEditor(KoProperty::Pixmap, + new PropertyFactory(KoProperty::FactoryManager::self())); +} + +FormManager::~FormManager() +{ + m_managerDeleter.setObject(_self, 0, false); //safe + delete m_popup; + delete m_connection; +#ifdef KEXI_DEBUG_GUI + delete m_uiCodeDialog; +#endif +// delete m_propFactory; +} + + +FormManager* FormManager::self() +{ + return _self; +} + +WidgetLibrary* +FormManager::createWidgetLibrary(FormManager* m, const QStringList& supportedFactoryGroups) +{ + if(!_self) + m_managerDeleter.setObject( _self, m ); + return new WidgetLibrary(_self, supportedFactoryGroups); +} + +void +FormManager::setEditor(KoProperty::Editor *editor) +{ + m_editor = editor; + + if(editor) + editor->changeSet(m_propSet->set()); +} + +void +FormManager::setObjectTreeView(ObjectTreeView *treeview) +{ + m_treeview = treeview; + if (m_treeview) + connect(m_propSet, SIGNAL(widgetNameChanged(const QCString&, const QCString&)), + m_treeview, SLOT(renameItem(const QCString&, const QCString&))); +} + +ActionList +FormManager::createActions(WidgetLibrary *lib, KActionCollection* collection, KXMLGUIClient* client) +{ + m_collection = collection; + + ActionList actions = lib->createWidgetActions(client, m_collection, this, SLOT(insertWidget(const QCString &))); + + if (m_options & HideSignalSlotConnections) + m_dragConnection = 0; + else { + m_dragConnection = new KToggleAction(i18n("Connect Signals/Slots"), + "signalslot", KShortcut(0), this, SLOT(startCreatingConnection()), m_collection, + "drag_connection"); + //to be exclusive with any 'widget' action + m_dragConnection->setExclusiveGroup("LibActionWidgets"); + m_dragConnection->setChecked(false); + actions.append(m_dragConnection); + } + + m_pointer = new KToggleAction(i18n("Pointer"), "mouse_pointer", KShortcut(0), + this, SLOT(slotPointerClicked()), m_collection, "pointer"); + m_pointer->setExclusiveGroup("LibActionWidgets"); //to be exclusive with any 'widget' action + m_pointer->setChecked(true); + actions.append(m_pointer); + + m_snapToGrid = new KToggleAction(i18n("Snap to Grid"), QString::null, KShortcut(0), + 0, 0, m_collection, "snap_to_grid"); + m_snapToGrid->setChecked(true); + actions.append(m_snapToGrid); + + // Create the Style selection action (with a combo box in toolbar and submenu items) + KSelectAction *m_style = new KSelectAction( i18n("Style"), KShortcut(0), + this, SLOT(slotStyle()), m_collection, "change_style"); + m_style->setEditable(false); + + KGlobal::config()->setGroup("General"); + QString currentStyle = QString::fromLatin1(kapp->style().name()).lower(); + const QStringList styles = QStyleFactory::keys(); + m_style->setItems(styles); + m_style->setCurrentItem(0); + + QStringList::ConstIterator endIt = styles.constEnd(); + int idx = 0; + for (QStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx) + { + if ((*it).lower() == currentStyle) { + m_style->setCurrentItem(idx); + break; + } + } + + m_style->setToolTip(i18n("Set the current view style.")); + m_style->setMenuAccelsEnabled(true); + actions.append(m_style); + + lib->addCustomWidgetActions(m_collection); + + return actions; +} + +bool +FormManager::isPasteEnabled() +{ + return m_domDoc.namedItem("UI").hasChildNodes(); +} + +void +FormManager::undo() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + activeForm()->commandHistory()->undo(); +} + +void +FormManager::redo() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + m_isRedoing = true; + activeForm()->commandHistory()->redo(); + m_isRedoing = false; +} + +void +FormManager::insertWidget(const QCString &classname) +{ + if(m_drawingSlot) + stopCreatingConnection(); + + m_inserting = true; + + Form *form; + for(form = m_forms.first(); form; form = m_forms.next()) + { +// form->d->cursors = new QMap<QString, QCursor>(); + if (form->toplevelContainer()) + form->widget()->setCursor(QCursor(CrossCursor)); + QObjectList *l = form->widget()->queryList( "QWidget" ); + for(QObject *o = l->first(); o; o = l->next()) + { + if( ((QWidget*)o)->ownCursor() ) + { +// form->d->cursors->insert(o->name(), ((QWidget*)o)->cursor()); + form->d->cursors.insert(o, static_cast<QWidget*>(o)->cursor()); + static_cast<QWidget*>(o)->setCursor(QCursor(Qt::CrossCursor)); + } + + } + delete l; + } + + m_selectedClass = classname; + m_pointer->setChecked(false); +} + +void +FormManager::stopInsert() +{ + if(m_drawingSlot) + stopCreatingConnection(); + if(!m_inserting) + return; + +//#ifndef KEXI_NO_CURSOR_PROPERTY + Form *form; + for(form = m_forms.first(); form; form = m_forms.next()) + { + form->widget()->unsetCursor(); + QObjectList *l = form->widget()->queryList( "QWidget" ); + for(QObject *o = l->first(); o; o = l->next()) + { + static_cast<QWidget*>(o)->unsetCursor(); +#if 0 + if( ((QWidget*)o)->ownCursor()) { + QMap<QObject*,QCursor>::ConstIterator curIt( form->d->cursors.find(o) ); + if (curIt!=form->d->cursors.constEnd()) + static_cast<QWidget*>(o)->setCursor( *curIt ); +// ((QWidget*)o)->setCursor( (*(form->d->cursors))[o->name()] ) ; + } +#endif + } + delete l; +// delete (form->d->cursors); +// form->d->cursors = 0; + } +//#endif + m_inserting = false; + m_pointer->setChecked(true); +} + +void +FormManager::slotPointerClicked() +{ + if(m_inserting) + stopInsert(); + else if(m_dragConnection) + stopCreatingConnection(); +} + +void +FormManager::startCreatingConnection() +{ + if (m_options & HideSignalSlotConnections) + return; + + if(m_inserting) + stopInsert(); + + // We set a Pointing hand cursor while drawing the connection + Form *form; + for(form = m_forms.first(); form; form = m_forms.next()) + { +// form->d->cursors = new QMap<QString, QCursor>(); + form->d->mouseTrackers = new QStringList(); + if (form->toplevelContainer()) + { + form->widget()->setCursor(QCursor(PointingHandCursor)); + form->widget()->setMouseTracking(true); + } + QObjectList *l = form->widget()->queryList( "QWidget" ); + for(QObject *o = l->first(); o; o = l->next()) + { + QWidget *w = static_cast<QWidget*>(o); + if( w->ownCursor() ) + { + form->d->cursors.insert(w, w->cursor()); +// form->d->cursors->insert(w->name(), w->cursor()); + w->setCursor(QCursor(PointingHandCursor )); + } + if(w->hasMouseTracking()) + form->d->mouseTrackers->append(w->name()); + w->setMouseTracking(true); + } + delete l; + } + delete m_connection; + m_connection = new Connection(); + m_drawingSlot = true; + if (m_dragConnection) + m_dragConnection->setChecked(true); +} + +void +FormManager::resetCreatedConnection() +{ + if (m_options & HideSignalSlotConnections) + return; + + delete m_connection; + m_connection = new Connection(); + + if(m_active && m_active->formWidget()) { + Form *ff = (Form*)m_active; + FormWidget *fw = 0; + if (ff) + fw = ff->formWidget(); + m_active->formWidget()->clearForm(); + } + if (m_active && m_active->widget()) + m_active->widget()->repaint(); +} + +void +FormManager::stopCreatingConnection() +{ + if (m_options & HideSignalSlotConnections) + return; + if(!m_drawingSlot) + return; + + if(m_active && m_active->formWidget()) + m_active->formWidget()->clearForm(); + + Form *form; + for(form = m_forms.first(); form; form = m_forms.next()) + { + form->widget()->unsetCursor(); + form->widget()->setMouseTracking(false); + QObjectList *l = form->widget()->queryList( "QWidget" ); + for(QObject *o = l->first(); o; o = l->next()) + { + QWidget *w = (QWidget*)o; + if( w->ownCursor()) { + QMap<QObject*,QCursor>::ConstIterator curIt( form->d->cursors.find(o) ); + if (curIt!=form->d->cursors.constEnd()) + static_cast<QWidget*>(o)->setCursor( *curIt ); + } +// w->setCursor( (*(form->d->cursors))[o->name()] ) ; + w->setMouseTracking( !form->d->mouseTrackers->grep(w->name()).isEmpty() ); + } + delete l; +// delete (form->d->cursors); +// form->d->cursors = 0; + delete (form->d->mouseTrackers); + form->d->mouseTrackers = 0; + } + + if(m_connection->slot().isNull()) + emit connectionAborted(activeForm()); + delete m_connection; + m_connection = 0; + m_drawingSlot = false; + m_pointer->setChecked(true); +} + +bool +FormManager::snapWidgetsToGrid() +{ + return m_snapToGrid->isChecked(); +} + +void +FormManager::windowChanged(QWidget *w) +{ + kdDebug() << "FormManager::windowChanged(" + << (w ? (QString(w->className())+" "+w->name()) : QString("0")) << ")" << endl; + + if(!w) + { + m_active = 0; + if(m_treeview) + m_treeview->setForm(0); + emit propertySetSwitched(0); + if(isCreatingConnection()) + stopCreatingConnection(); + + emitNoFormSelected(); + return; + } + + Form *previousActive = m_active; + Form *form; + for(form = m_forms.first(); form; form = m_forms.next()) + { + if(form->toplevelContainer() && form->widget() == w) + { + if(m_treeview) + m_treeview->setForm(form); + //if(m_propSet) + // m_propList->setCollection(form->pixmapCollection()); + + kdDebug() << "FormManager::windowChanged() active form is " << form->objectTree()->name() << endl; + + if(m_collection) + { +#ifndef KFD_NO_STYLES + // update the 'style' action + KSelectAction *m_style = (KSelectAction*)m_collection->action("change_style", "KSelectAction"); + const QString currentStyle = form->widget()->style().name(); + const QStringList styles = m_style->items(); + + int idx = 0; + QStringList::ConstIterator endIt = styles.constEnd(); + for (QStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx) + { + if ((*it).lower() == currentStyle) { + kdDebug() << "Updating the style to " << currentStyle << endl; + m_style->setCurrentItem(idx); + break; + } + } +#endif + } + + if((form != previousActive) && isCreatingConnection()) + resetCreatedConnection(); + + m_active = form; + + emit dirty(form, form->isModified()); + // update actions state + m_active->emitActionSignals(); + //update the buffer too + form->emitSelectionSignals(); + if (!m_emitSelectionSignalsUpdatesPropertySet) + showPropertySet( propertySet(), true ); + return; + } + } + + for(form = m_preview.first(); form; form = m_preview.next()) + { + kdDebug() << (form->widget() ? form->widget()->name() : "") << endl; + if(form->toplevelContainer() && form->widget() == w) { + kdDebug() << "FormManager::windowChanged() active preview form is " << form->widget()->name() << endl; + + if(m_collection) + { +#ifndef KFD_NO_STYLES + // update the 'style' action + KSelectAction *m_style = (KSelectAction*)m_collection->action("change_style", "KSelectAction"); + const QString currentStyle = form->widget()->style().name(); + const QStringList styles = m_style->items(); + + int idx = 0; + QStringList::ConstIterator endIt = styles.constEnd(); + for (QStringList::ConstIterator it = styles.constBegin(); it != endIt; ++it, ++idx) + { + if ((*it).lower() == currentStyle) { + kdDebug() << "Updating the style to " << currentStyle << endl; + m_style->setCurrentItem(idx); + break; + } + } +#endif + + resetCreatedConnection(); + m_active = form; + + emit dirty(form, false); + emitNoFormSelected(); + showPropertySet(0); + return; + } + } + } + //m_active = 0; +} + +Form* +FormManager::activeForm() const +{ + return m_active; +} + +Form* +FormManager::formForWidget(QWidget *w) +{ + for(Form *form = m_forms.first(); form; form = m_forms.next()) { + if(form->toplevelContainer() && form->widget() == w) + return form; + } + + return 0; // not one of toplevel widgets +} + +void +FormManager::deleteForm(Form *form) +{ + if (!form) + return; + if(m_forms.find(form) == -1) + m_preview.remove(form); + else + m_forms.remove(form); + + if(m_forms.count() == 0) { + m_active = 0; + emit propertySetSwitched(0); + } +} + +void +FormManager::importForm(Form *form, bool preview) +{ + if(!preview) + initForm(form); + else + { + m_preview.append(form); + form->setDesignMode(false); + } +} + +void +FormManager::initForm(Form *form) +{ + m_forms.append(form); + + if(m_treeview) + m_treeview->setForm(form); + + m_active = form; + + connect(form, SIGNAL(selectionChanged(QWidget*, bool, bool)), + m_propSet, SLOT(setSelectedWidgetWithoutReload(QWidget*, bool, bool))); + if(m_treeview) + { + connect(form, SIGNAL(selectionChanged(QWidget*, bool, bool)), + m_treeview, SLOT(setSelectedWidget(QWidget*, bool))); + connect(form, SIGNAL(childAdded(ObjectTreeItem* )), m_treeview, SLOT(addItem(ObjectTreeItem*))); + connect(form, SIGNAL(childRemoved(ObjectTreeItem* )), m_treeview, SLOT(removeItem(ObjectTreeItem*))); + } + connect(m_propSet, SIGNAL(widgetNameChanged(const QCString&, const QCString&)), + form, SLOT(changeName(const QCString&, const QCString&))); + + form->setSelectedWidget(form->widget()); + windowChanged(form->widget()); +} + +void +FormManager::previewForm(Form *form, QWidget *container, Form *toForm) +{ + if(!form || !container || !form->objectTree()) + return; + QDomDocument domDoc; + if (!FormIO::saveFormToDom(form, domDoc)) + return; + + Form *myform; + if(!toForm) + myform = new Form(form->library(), form->objectTree()->name().latin1(), + false/*!designMode, we need to set it early enough*/); + else + myform = toForm; + myform->createToplevel(container); + container->setStyle( &(form->widget()->style()) ); + + if (!FormIO::loadFormFromDom(myform, container, domDoc)) { + delete myform; + return; + } + + myform->setDesignMode(false); + m_preview.append(myform); + container->show(); +} + +/* +bool +FormManager::loadFormFromDomInternal(Form *form, QWidget *container, QDomDocument &inBuf) +{ + return FormIO::loadFormFromDom(myform, container, domDoc); +} + +bool +FormManager::saveFormToStringInternal(Form *form, QString &dest, int indent) +{ + return KFormDesigner::FormIO::saveFormToString(form, dest, indent); +}*/ + +bool +FormManager::isTopLevel(QWidget *w) +{ + if(!activeForm() || !activeForm()->objectTree()) + return false; + +// kdDebug() << "FormManager::isTopLevel(): for: " << w->name() << " = " +// << activeForm()->objectTree()->lookup(w->name())<< endl; + + ObjectTreeItem *item = activeForm()->objectTree()->lookup(w->name()); + if(!item) + return true; + + return (!item->parent()); +} + +void +FormManager::deleteWidget() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + QPtrList<QWidget> *list = activeForm()->selectedWidgets(); + if(list->isEmpty()) + return; + + if (activeForm()->widget() == list->first()) { + //toplevel form is selected, cannot delete it + return; + } + + KCommand *com = new DeleteWidgetCommand(*list, activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::copyWidget() +{ + if (!activeForm() || !activeForm()->objectTree()) + return; + + QPtrList<QWidget> *list = activeForm()->selectedWidgets(); + if(list->isEmpty()) + return; + + removeChildrenFromList(*list); + + // We clear the current clipboard + m_domDoc.setContent(QString(), true); + QDomElement parent = m_domDoc.createElement("UI"); + m_domDoc.appendChild(parent); + + QWidget *w; + for(w = list->first(); w; w = list->next()) + { + ObjectTreeItem *it = activeForm()->objectTree()->lookup(w->name()); + if (!it) + continue; + + FormIO::saveWidget(it, parent, m_domDoc); + } + + FormIO::cleanClipboard(parent); + + activeForm()->emitActionSignals(); // to update 'Paste' item state +} + +void +FormManager::cutWidget() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + QPtrList<QWidget> *list = activeForm()->selectedWidgets(); + if(list->isEmpty()) + return; + + KCommand *com = new CutWidgetCommand(*list, activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::pasteWidget() +{ + if(!m_domDoc.namedItem("UI").hasChildNodes()) + return; + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new PasteWidgetCommand(m_domDoc, activeForm()->activeContainer(), m_insertPoint); + activeForm()->addCommand(com, true); +} + +void +FormManager::setInsertPoint(const QPoint &p) +{ + m_insertPoint = p; +} + +void +FormManager::createSignalMenu(QWidget *w) +{ + m_sigSlotMenu = new KPopupMenu(); + m_sigSlotMenu->insertTitle(SmallIcon("connection"), i18n("Signals")); + + QStrList list = w->metaObject()->signalNames(true); + QStrListIterator it(list); + for(; it.current() != 0; ++it) + m_sigSlotMenu->insertItem(*it); + + int result = m_sigSlotMenu->exec(QCursor::pos()); + if(result == -1) + resetCreatedConnection(); + else + menuSignalChosen(result); + + delete m_sigSlotMenu; + m_sigSlotMenu = 0; +} + +void +FormManager::createSlotMenu(QWidget *w) +{ + m_sigSlotMenu = new KPopupMenu(); + m_sigSlotMenu->insertTitle(SmallIcon("connection"), i18n("Slots")); + + QString signalArg( m_connection->signal().remove( QRegExp(".*[(]|[)]") ) ); + + QStrList list = w->metaObject()->slotNames(true); + QStrListIterator it(list); + for(; it.current() != 0; ++it) + { + // we add the slot only if it is compatible with the signal + QString slotArg(*it); + slotArg = slotArg.remove( QRegExp(".*[(]|[)]") ); + if(!signalArg.startsWith(slotArg, true)) // args not compatible + continue; + + m_sigSlotMenu->insertItem(*it); + } + + int result = m_sigSlotMenu->exec(QCursor::pos()); + if(result == -1) + resetCreatedConnection(); + else + menuSignalChosen(result); + + delete m_sigSlotMenu; + m_sigSlotMenu = 0; +} + +void +FormManager::createContextMenu(QWidget *w, Container *container, bool popupAtCursor) +{ + if(!activeForm() || !activeForm()->widget()) + return; + const bool toplevelWidgetSelected = activeForm()->widget() == w; + const uint widgetsCount = container->form()->selectedWidgets()->count(); + const bool multiple = widgetsCount > 1; + //const bool enableRemove = w != m_active->widget(); + // We only enablelayout creation if more than one widget with the same parent are selected + const bool enableLayout = multiple || w == container->widget(); + + m_menuWidget = w; + QString n = container->form()->library()->displayName(w->className()); +// QValueVector<int> menuIds(); + + if (!m_popup) { + m_popup = new KPopupMenu(); + } + else { + m_popup->clear(); + } + + //set title + if(!multiple) + { + if(w == container->form()->widget()) + m_popup->insertTitle(SmallIcon("form"), i18n("%1 : Form").arg(w->name()) ); + else + m_popup->insertTitle( SmallIcon( + container->form()->library()->iconName(w->className())), QString(w->name()) + " : " + n ); + } + else + m_popup->insertTitle(SmallIcon("multiple_obj"), i18n("Multiple Widgets") + + QString(" (%1)").arg(widgetsCount)); + + KAction *a; +#define PLUG_ACTION(_name, forceVisible) \ + { a = action(_name); \ + if (a && (forceVisible || a->isEnabled())) { \ + if (separatorNeeded) \ + m_popup->insertSeparator(); \ + separatorNeeded = false; \ + a->plug(m_popup); \ + } \ + } + + bool separatorNeeded = false; + + PLUG_ACTION("edit_cut", !toplevelWidgetSelected); + PLUG_ACTION("edit_copy", !toplevelWidgetSelected); + PLUG_ACTION("edit_paste", true); + PLUG_ACTION("edit_delete", !toplevelWidgetSelected); + separatorNeeded = true; + PLUG_ACTION("layout_menu", enableLayout); + PLUG_ACTION("break_layout", enableLayout); + separatorNeeded = true; + PLUG_ACTION("align_menu", !toplevelWidgetSelected); + PLUG_ACTION("adjust_size_menu", !toplevelWidgetSelected); + separatorNeeded = true; + + // We create the buddy menu + if(!multiple && w->inherits("QLabel") && ((QLabel*)w)->text().contains("&") && (((QLabel*)w)->textFormat() != RichText)) + { + if (separatorNeeded) + m_popup->insertSeparator(); + + KPopupMenu *sub = new KPopupMenu(w); + QWidget *buddy = ((QLabel*)w)->buddy(); + + sub->insertItem(i18n("No Buddy"), MenuNoBuddy); + if(!buddy) + sub->setItemChecked(MenuNoBuddy, true); + sub->insertSeparator(); + + // add all the widgets that can have focus + for(ObjectTreeListIterator it( container->form()->tabStopsIterator() ); it.current(); ++it) + { + int index = sub->insertItem( + SmallIcon(container->form()->library()->iconName(it.current()->className().latin1())), + it.current()->name()); + if(it.current()->widget() == buddy) + sub->setItemChecked(index, true); + } + + /*int id =*/ m_popup->insertItem(i18n("Choose Buddy..."), sub); +// menuIds->append(id); + connect(sub, SIGNAL(activated(int)), this, SLOT(buddyChosen(int))); + + separatorNeeded = true; + } + + //int sigid=0; +#ifdef KEXI_DEBUG_GUI + if(!multiple && !(m_options & HideEventsInPopupMenu)) + { + if (separatorNeeded) + m_popup->insertSeparator(); + + // We create the signals menu + KPopupMenu *sigMenu = new KPopupMenu(); + QStrList list = w->metaObject()->signalNames(true); + QStrListIterator it(list); + for(; it.current() != 0; ++it) + sigMenu->insertItem(*it); + + int id = m_popup->insertItem(SmallIconSet(""), i18n("Events"), sigMenu); +// menuIds->append(id); + if(list.isEmpty()) + m_popup->setItemEnabled(id, false); + connect(sigMenu, SIGNAL(activated(int)), this, SLOT(menuSignalChosen(int))); + separatorNeeded = true; + } +#endif + + // Other items + if(!multiple) + { + int lastID = -1; + if (separatorNeeded) { + lastID = m_popup->insertSeparator(); + } + const uint oldIndex = m_popup->count()-1; + container->form()->library()->createMenuActions(w->className(), w, m_popup, container); + if (oldIndex == (m_popup->count()-1)) { +// for (uint i=oldIndex; i<m_popup->count(); i++) { +// int id = m_popup->idAt( i ); +// if (id!=-1) +// menuIds->append( id ); +// } + //nothing added + if (separatorNeeded) { + m_popup->removeItem( lastID ); +// menuIds->pop_back(); + } + } + } + + //show the popup at the selected widget + QPoint popupPos; + if (popupAtCursor) { + popupPos = QCursor::pos(); + } + else { + WidgetList *lst = container->form()->selectedWidgets(); + QWidget * sel_w = lst ? lst->first() : container->form()->selectedWidget(); + popupPos = sel_w ? sel_w->mapToGlobal(QPoint(sel_w->width()/2, sel_w->height()/2)) : QCursor::pos(); + } + m_insertPoint = container->widget()->mapFromGlobal(popupPos); + m_popup->exec(popupPos);//QCursor::pos()); + m_insertPoint = QPoint(); + +// QValueVector<int>::iterator it; +// for(it = menuIds->begin(); it != menuIds->end(); ++it) +// m_popup->removeItem(*it); +} + +void +FormManager::buddyChosen(int id) +{ + if(!m_menuWidget) + return; + QLabel *label = static_cast<QLabel*>((QWidget*)m_menuWidget); + + if(id == MenuNoBuddy) + { + label->setBuddy(0); + return; + } + + ObjectTreeItem *item = activeForm()->objectTree()->lookup(m_popup->text(id)); + if(!item || !item->widget()) + return; + label->setBuddy(item->widget()); +} + +void +FormManager::menuSignalChosen(int id) +{ + if (m_options & HideSignalSlotConnections) + return; + + //if(!m_menuWidget) + // return; + if(m_drawingSlot && m_sigSlotMenu) + { + if( m_connection->receiver().isNull() ) + m_connection->setSignal(m_sigSlotMenu->text(id)); + else + { + m_connection->setSlot(m_sigSlotMenu->text(id)); + kdDebug() << "Finished creating the connection: sender=" << m_connection->sender() << "; signal=" << m_connection->signal() << + "; receiver=" << m_connection->receiver() << "; slot=" << m_connection->slot() << endl; + emit connectionCreated(activeForm(), *m_connection); + stopCreatingConnection(); + } + } + else if(m_menuWidget) + emit createFormSlot(m_active, m_menuWidget->name(), m_popup->text(id)); +} + +void +FormManager::slotConnectionCreated(Form *form, Connection &connection) +{ + if (m_options & HideSignalSlotConnections) + return; + if(!form) + return; + + Connection *c = new Connection(connection); + form->connectionBuffer()->append(c); +} + +void +FormManager::layoutHBox() +{ + createLayout(Container::HBox); +} + +void +FormManager::layoutVBox() +{ + createLayout(Container::VBox); +} + +void +FormManager::layoutGrid() +{ + createLayout(Container::Grid); +} + +void +FormManager::layoutHSplitter() +{ + createLayout(Container::HSplitter); +} + +void +FormManager::layoutVSplitter() +{ + createLayout(Container::VSplitter); +} + +void +FormManager::layoutHFlow() +{ + createLayout(Container::HFlow); +} + +void +FormManager::layoutVFlow() +{ + createLayout(Container::VFlow); +} + +void +FormManager::createLayout(int layoutType) +{ + WidgetList *list = m_active->selectedWidgets(); + // if only one widget is selected (a container), we modify its layout + if (list->isEmpty()) {//sanity check + kdWarning() << "FormManager::createLayout(): list is empty!" << endl; + return; + } + if(list->count() == 1) + { + ObjectTreeItem *item = m_active->objectTree()->lookup(list->first()->name()); + if(!item || !item->container() || !m_propSet->contains("layout")) + return; + (*m_propSet)["layout"] = Container::layoutTypeToString(layoutType); + return; + } + + QWidget *parent = list->first()->parentWidget(); + for(QWidget *w = list->first(); w; w = list->next()) + { + kdDebug() << "comparing widget " << w->name() << " whose parent is " << w->parentWidget()->name() << " insteaed of " << parent->name() << endl; + if(w->parentWidget() != parent) + { + KMessageBox::sorry(m_active->widget()->topLevelWidget(), i18n("<b>Cannot create the layout.</b>\n" + "All selected widgets must have the same parent.")); + kdDebug() << "FormManager::createLayout() widgets don't have the same parent widget" << endl; + return; + } + } + + KCommand *com = new CreateLayoutCommand(layoutType, *list, m_active); + m_active->addCommand(com, true); +} + +void +FormManager::breakLayout() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + Container *container = activeForm()->activeContainer(); + QCString c( container->widget()->className() ); + + if((c == "Grid") || (c == "VBox") || (c == "HBox") || (c == "HFlow") || (c == "VFlow")) + { + KCommand *com = new BreakLayoutCommand(container); + m_active->addCommand(com, true); + } + else // normal container + { + if(activeForm()->selectedWidgets()->count() == 1) + (*m_propSet)["layout"] = "NoLayout"; + else + container->setLayout(Container::NoLayout); + } +} + +void +FormManager::showPropertySet(WidgetPropertySet *set, bool forceReload, const QCString& propertyToSelect) +{ + if (m_objectBlockingPropertyEditorUpdating) + return; + +/*unused if(m_editor) { + if (propertyToSelect.isEmpty() && forceReload) + m_editor->changeSet(set ? set->set() : 0, propertyToSelect); + else + m_editor->changeSet(set ? set->set() : 0); + }*/ + + emit propertySetSwitched(set ? set->set(): 0, /*preservePrevSelection*/forceReload, propertyToSelect); +} + +void +FormManager::blockPropertyEditorUpdating(void *blockingObject) +{ + if (!blockingObject || m_objectBlockingPropertyEditorUpdating) + return; + m_objectBlockingPropertyEditorUpdating = blockingObject; +} + +void +FormManager::unblockPropertyEditorUpdating(void *blockingObject, WidgetPropertySet *set) +{ + if (!blockingObject || m_objectBlockingPropertyEditorUpdating!=blockingObject) + return; + + m_objectBlockingPropertyEditorUpdating = 0; + showPropertySet(set, true/*forceReload*/); +} + +void +FormManager::editTabOrder() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + QWidget *topLevel = m_active->widget()->topLevelWidget(); + TabStopDialog dlg(topLevel); + //const bool oldAutoTabStops = m_active->autoTabStops(); + if (dlg.exec(m_active) == QDialog::Accepted) { + //inform about changing "autoTabStop" property + // -- this will be received eg. by Kexi, so custom "autoTabStop" property can be updated + emit autoTabStopsSet(m_active, dlg.autoTabStops()); + //force set dirty + emit dirty(m_active, true); + } +} + +void +FormManager::slotStyle() +{ + if(!activeForm()) + return; + + KSelectAction *m_style = (KSelectAction*)m_collection->action("change_style", "KSelectAction"); + QString style = m_style->currentText(); + activeForm()->widget()->setStyle( style); + + QObjectList *l = activeForm()->widget()->queryList( "QWidget" ); + for(QObject *o = l->first(); o; o = l->next()) + (static_cast<QWidget*>(o))->setStyle( style ); + delete l; +} + +void +FormManager::editFormPixmapCollection() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + PixmapCollectionEditor dialog(activeForm()->pixmapCollection(), activeForm()->widget()->topLevelWidget()); + dialog.exec(); +} + +void +FormManager::editConnections() +{ + if (m_options & HideSignalSlotConnections) + return; + if(!activeForm() || !activeForm()->objectTree()) + return; + + ConnectionDialog dialog(activeForm()->widget()->topLevelWidget()); + dialog.exec(activeForm()); +} + +void +FormManager::alignWidgets(int type) +{ + if(!activeForm() || !activeForm()->objectTree() || (activeForm()->selectedWidgets()->count() < 2)) + return; + + QWidget *parentWidget = activeForm()->selectedWidgets()->first()->parentWidget(); + + for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next()) + { + if(w->parentWidget() != parentWidget) + { + kdDebug() << "FormManager::alignWidgets() type ==" << type << " widgets don't have the same parent widget" << endl; + return; + } + } + + KCommand *com = new AlignWidgetsCommand(type, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::alignWidgetsToLeft() +{ + alignWidgets(AlignWidgetsCommand::AlignToLeft); +} + +void +FormManager::alignWidgetsToRight() +{ + alignWidgets(AlignWidgetsCommand::AlignToRight); +} + +void +FormManager::alignWidgetsToTop() +{ + alignWidgets(AlignWidgetsCommand::AlignToTop); +} + +void +FormManager::alignWidgetsToBottom() +{ + alignWidgets(AlignWidgetsCommand::AlignToBottom); +} + +void +FormManager::adjustWidgetSize() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToFit, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::alignWidgetsToGrid() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AlignWidgetsCommand(AlignWidgetsCommand::AlignToGrid, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::adjustSizeToGrid() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToGrid, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::adjustWidthToSmall() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToSmallWidth, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::adjustWidthToBig() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToBigWidth, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::adjustHeightToSmall() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToSmallHeight, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::adjustHeightToBig() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + KCommand *com = new AdjustSizeCommand(AdjustSizeCommand::SizeToBigHeight, *(activeForm()->selectedWidgets()), activeForm()); + activeForm()->addCommand(com, true); +} + +void +FormManager::bringWidgetToFront() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next()) + w->raise(); +} + +void +FormManager::sendWidgetToBack() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next()) + w->lower(); +} + +void +FormManager::selectAll() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + activeForm()->selectFormWidget(); + uint count = activeForm()->objectTree()->children()->count(); + for(ObjectTreeItem *it = activeForm()->objectTree()->children()->first(); it; + it = activeForm()->objectTree()->children()->next(), count--) + { + activeForm()->setSelectedWidget(it->widget(), /*add*/true, /*raise*/false, /*moreWillBeSelected*/count>1); + } +} + +void +FormManager::clearWidgetContent() +{ + if(!activeForm() || !activeForm()->objectTree()) + return; + + for(QWidget *w = activeForm()->selectedWidgets()->first(); w; w = activeForm()->selectedWidgets()->next()) + activeForm()->library()->clearWidgetContent(w->className(), w); +} + +void +FormManager::deleteWidgetLater( QWidget *w ) +{ + w->hide(); + w->reparent(0, WType_TopLevel, QPoint(0,0)); + m_deleteWidgetLater_list.append( w ); + m_deleteWidgetLater_timer.start( 100, true ); +} + +void +FormManager::deleteWidgetLaterTimeout() +{ + m_deleteWidgetLater_list.clear(); +} + +void +FormManager::showFormUICode() +{ +#ifdef KEXI_DEBUG_GUI + if(!activeForm()) + return; + + QString uiCode; + if (!FormIO::saveFormToString(activeForm(), uiCode, 3)) { + //! @todo show err? + return; + } + + if (!m_uiCodeDialog) { + m_uiCodeDialog = new KDialogBase(0, "uiwindow", true, i18n("Form's UI Code"), + KDialogBase::Close, KDialogBase::Close); + m_uiCodeDialog->resize(700, 600); + QVBox *box = m_uiCodeDialog->makeVBoxMainWidget(); + KTabWidget* tab = new KTabWidget(box); + + m_currentUICodeDialogEditor = new KTextEdit(QString::null, QString::null, tab); + tab->addTab( m_currentUICodeDialogEditor, i18n("Current")); + m_currentUICodeDialogEditor->setReadOnly(true); + QFont f( m_currentUICodeDialogEditor->font() ); + f.setFamily("courier"); + m_currentUICodeDialogEditor->setFont(f); + m_currentUICodeDialogEditor->setTextFormat(Qt::PlainText); + + m_originalUICodeDialogEditor = new KTextEdit(QString::null, QString::null, tab); + tab->addTab( m_originalUICodeDialogEditor, i18n("Original")); + m_originalUICodeDialogEditor->setReadOnly(true); + m_originalUICodeDialogEditor->setFont(f); + m_originalUICodeDialogEditor->setTextFormat(Qt::PlainText); + } + m_currentUICodeDialogEditor->setText( uiCode ); + //indent and set our original doc as well: + QDomDocument doc; + doc.setContent( activeForm()->m_recentlyLoadedUICode ); + m_originalUICodeDialogEditor->setText( doc.toString( 3 ) ); + m_uiCodeDialog->show(); +#endif +} + +void +FormManager::slotSettingsChanged(int category) +{ + if (category==KApplication::SETTINGS_SHORTCUTS) { + m_contextMenuKey = KGlobalSettings::contextMenuKey(); + } +} + +void +FormManager::emitWidgetSelected( KFormDesigner::Form* form, bool multiple ) +{ + enableFormActions(); + // Enable edit actions + enableAction("edit_copy", true); + enableAction("edit_cut", true); + enableAction("edit_delete", true); + enableAction("clear_contents", true); + + // 'Align Widgets' menu + enableAction("align_menu", multiple); + enableAction("align_to_left", multiple); + enableAction("align_to_right", multiple); + enableAction("align_to_top", multiple); + enableAction("align_to_bottom", multiple); + + enableAction("adjust_size_menu", true); + enableAction("adjust_width_small", multiple); + enableAction("adjust_width_big", multiple); + enableAction("adjust_height_small", multiple); + enableAction("adjust_height_big", multiple); + + enableAction("format_raise", true); + enableAction("format_lower", true); + + WidgetList *wlist = form->selectedWidgets(); + bool fontEnabled = false; + for (WidgetListIterator it(*wlist); it.current(); ++it) { + if (-1 != it.current()->metaObject()->findProperty("font", true)) { + fontEnabled = true; + break; + } + } + enableAction("format_font", fontEnabled); + + // If the widgets selected is a container, we enable layout actions + bool containerSelected = false; + if(!multiple) + { + KFormDesigner::ObjectTreeItem *item = 0; + if (form->selectedWidgets()->first()) + form->objectTree()->lookup( form->selectedWidgets()->first()->name() ); + if(item && item->container()) + containerSelected = true; + } + const bool twoSelected = form->selectedWidgets()->count()==2; + // Layout actions + enableAction("layout_menu", multiple || containerSelected); + enableAction("layout_hbox", multiple || containerSelected); + enableAction("layout_vbox", multiple || containerSelected); + enableAction("layout_grid", multiple || containerSelected); + enableAction("layout_hsplitter", twoSelected); + enableAction("layout_vsplitter", twoSelected); + + KFormDesigner::Container *container = activeForm() ? activeForm()->activeContainer() : 0; + if (container) + enableAction("break_layout", (container->layoutType() != KFormDesigner::Container::NoLayout)); + + emit widgetSelected(form, true); +} + +void +FormManager::emitFormWidgetSelected( KFormDesigner::Form* form ) +{ +// disableWidgetActions(); + enableAction("edit_copy", false); + enableAction("edit_cut", false); + enableAction("edit_delete", false); + enableAction("clear_contents", false); + + // Disable format functions + enableAction("align_menu", false); + enableAction("align_to_left", false); + enableAction("align_to_right", false); + enableAction("align_to_top", false); + enableAction("align_to_bottom", false); + enableAction("adjust_size_menu", false); + enableAction("format_raise", false); + enableAction("format_lower", false); + + enableAction("format_font", false); + + enableFormActions(); + + const bool twoSelected = form->selectedWidgets()->count()==2; + const bool hasChildren = !form->objectTree()->children()->isEmpty(); + + // Layout actions + enableAction("layout_menu", hasChildren); + enableAction("layout_hbox", hasChildren); + enableAction("layout_vbox", hasChildren); + enableAction("layout_grid", hasChildren); + enableAction("layout_hsplitter", twoSelected); + enableAction("layout_vsplitter", twoSelected); + enableAction("break_layout", (form->toplevelContainer()->layoutType() != KFormDesigner::Container::NoLayout)); + + emit formWidgetSelected( form ); +} + +void +FormManager::emitNoFormSelected() +{ + disableWidgetActions(); + + // Disable edit actions +// enableAction("edit_paste", false); +// enableAction("edit_undo", false); +// enableAction("edit_redo", false); + + // Disable 'Tools' actions + enableAction("pixmap_collection", false); + if (!(m_options & HideSignalSlotConnections)) + enableAction("form_connections", false); + enableAction("taborder", false); + enableAction("change_style", activeForm()!=0); + + // Disable items in 'File' + if (!(m_options & SkipFileActions)) { + enableAction("file_save", false); + enableAction("file_save_as", false); + enableAction("preview_form", false); + } + + emit noFormSelected(); +} + +void +FormManager::enableFormActions() +{ + // Enable 'Tools' actions + enableAction("pixmap_collection", true); + if (!(m_options & HideSignalSlotConnections)) + enableAction("form_connections", true); + enableAction("taborder", true); + enableAction("change_style", true); + + // Enable items in 'File' + if (!(m_options & SkipFileActions)) { + enableAction("file_save", true); + enableAction("file_save_as", true); + enableAction("preview_form", true); + } + + enableAction("edit_paste", isPasteEnabled()); + enableAction("edit_select_all", true); +} + +void +FormManager::disableWidgetActions() +{ + // Disable edit actions + enableAction("edit_copy", false); + enableAction("edit_cut", false); + enableAction("edit_delete", false); + enableAction("clear_contents", false); + + // Disable format functions + enableAction("align_menu", false); + enableAction("align_to_left", false); + enableAction("align_to_right", false); + enableAction("align_to_top", false); + enableAction("align_to_bottom", false); + enableAction("adjust_size_menu", false); + enableAction("format_raise", false); + enableAction("format_lower", false); + + enableAction("layout_menu", false); + enableAction("layout_hbox", false); + enableAction("layout_vbox", false); + enableAction("layout_grid", false); + enableAction("layout_hsplitter", false); + enableAction("layout_vsplitter", false); + enableAction("break_layout", false); +} + +void +FormManager::emitUndoEnabled(bool enabled, const QString &text) +{ + enableAction("edit_undo", enabled); + emit undoEnabled(enabled, text); +} + +void +FormManager::emitRedoEnabled(bool enabled, const QString &text) +{ + enableAction("edit_redo", enabled); + emit redoEnabled(enabled, text); +} + +void +FormManager::changeFont() +{ + if (!m_active) + return; + WidgetList *wlist = m_active->selectedWidgets(); + WidgetList widgetsWithFontProperty; + QWidget *widget; + QFont font; + bool oneFontSelected = true; + for (WidgetListIterator it(*wlist); (widget = it.current()); ++it) { + if (m_active->library()->isPropertyVisible(widget->className(), widget, "font")) { + widgetsWithFontProperty.append(widget); + if (oneFontSelected) { + if (widgetsWithFontProperty.count()==1) + font = widget->font(); + else if (font != widget->font()) + oneFontSelected = false; + } + } + } + if (widgetsWithFontProperty.isEmpty()) + return; + if (!oneFontSelected) //many different fonts selected: pick a font from toplevel conatiner + font = m_active->widget()->font(); + + if (1==widgetsWithFontProperty.count()) { + //single widget's settings + widget = widgetsWithFontProperty.first(); + KoProperty::Property &fontProp = m_propSet->property("font"); + if (QDialog::Accepted != KFontDialog::getFont(font, false, m_active->widget())) + return; + fontProp = font; + return; + } + //multiple widgets + int diffFlags=0; + if (QDialog::Accepted != KFontDialog::getFontDiff(font, diffFlags, false, m_active->widget()) + || 0==diffFlags) + return; + //update font + for (WidgetListIterator it(widgetsWithFontProperty); (widget = it.current()); ++it) { + QFont prevFont( widget->font() ); + if (diffFlags & KFontChooser::FontDiffFamily) + prevFont.setFamily( font.family() ); + if (diffFlags & KFontChooser::FontDiffStyle) { + prevFont.setBold( font.bold() ); + prevFont.setItalic( font.italic() ); + } + if (diffFlags & KFontChooser::FontDiffSize) + prevFont.setPointSize( font.pointSize() ); +/*! @todo this modification is not added to UNDO BUFFER: + do it when KoProperty::Set supports multiple selections */ + widget->setFont( prevFont ); + //temporary fix for dirty flag: + emit dirty(m_active, true); + } +} + +#include "formmanager.moc" |