You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1717 lines
44 KiB
1717 lines
44 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
|
|
Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
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"
|