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.
497 lines
18 KiB
497 lines
18 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.
|
|
*/
|
|
|
|
#ifndef FORMMANAGER_H
|
|
#define FORMMANAGER_H
|
|
|
|
#include <qobject.h>
|
|
#include <qdom.h>
|
|
#include <qptrlist.h>
|
|
#include <qtimer.h>
|
|
#include <qguardedptr.h>
|
|
#include <qstringlist.h>
|
|
|
|
class QWidget;
|
|
class QWorkspace;
|
|
class KPopupMenu;
|
|
class KActionCollection;
|
|
class KAction;
|
|
class KToggleAction;
|
|
class KDialogBase;
|
|
class KTextEdit;
|
|
class KXMLGUIClient;
|
|
class KMainWindow;
|
|
|
|
namespace KoProperty {
|
|
class Editor;
|
|
class Set;
|
|
class Property;
|
|
class Widget;
|
|
}
|
|
|
|
namespace KFormDesigner {
|
|
|
|
class WidgetPropertySet;
|
|
class Form;
|
|
class Container;
|
|
class WidgetLibrary;
|
|
class ObjectTreeView;
|
|
class Connection;
|
|
class FormManager;
|
|
typedef QPtrList<KAction> ActionList;
|
|
|
|
//! @internal
|
|
//static FormManager* FormManager_static = 0;
|
|
|
|
//! A class to manage (create/load/save) Forms
|
|
/** This is Form Designer's main class, which is used by external APIs to access FormDesigner.
|
|
This is the class you have to use to integrate FormDesigner into another program.
|
|
It deals with creating, saving and loading Form, as well as widget insertion and copying.
|
|
It also ensures all the components (ObjectTreeView, Form and PropertyEditor) are synced,
|
|
and link them.
|
|
It holds the WidgetLibrary, the WidgetPropertySet, links to ObjectTreeView and PropertyEditor,
|
|
as well as the copied widget and the insert state.
|
|
**/
|
|
class KFORMEDITOR_EXPORT FormManager : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
/*! Constructs FormManager object.
|
|
Using \a options you can control manager's behaviour, see Options. */
|
|
FormManager(QObject *parent = 0, int options = 0, const char *name = 0);
|
|
|
|
virtual ~FormManager();
|
|
|
|
//! Creates widget library for supportedFactoryGroups
|
|
//! and initializes FormManager singleton. \a m should be always the same for every call.
|
|
static WidgetLibrary* createWidgetLibrary(FormManager* m,
|
|
const QStringList& supportedFactoryGroups);
|
|
|
|
//! Access to FormManager singleton
|
|
static FormManager* self();
|
|
|
|
/*! Options for creating FormManager objects.
|
|
* These are really bit-flags and may be or-ed together.
|
|
*/
|
|
enum Options { HideEventsInPopupMenu = 1, SkipFileActions = 2,
|
|
HideSignalSlotConnections = 4 }; //todo
|
|
|
|
/*! Creates all the KActions related to widget insertion, and plug them
|
|
into the \a collection. \a client XML GUI client is used to call
|
|
lib->addCustomWidgetActions(client).
|
|
These actions are automatically connected to \ref insertWidget() slot.
|
|
\return a QPtrList of the created actions.
|
|
*/
|
|
ActionList createActions(WidgetLibrary *lib, KActionCollection* collection, KXMLGUIClient *client);
|
|
|
|
/*! Enables or disables actions \a name.
|
|
KFD uses KPart's, action collection here.
|
|
Kexi implements this to get (shared) actions defined elsewhere. */
|
|
virtual void enableAction( const char* name, bool enable ) = 0;
|
|
|
|
/*! \return action for \a name. @see enableAction() */
|
|
virtual KAction* action(const char* name) = 0;
|
|
|
|
bool isPasteEnabled();
|
|
|
|
// //! \return A pointer to the WidgetLibrary owned by this Manager.
|
|
// WidgetLibrary* lib() const { return m_lib; }
|
|
|
|
//! \return A pointer to the WidgetPropertySet owned by this Manager.
|
|
WidgetPropertySet* propertySet() const { return m_propSet; }
|
|
|
|
/*! \return true if one of the insert buttons was pressed and the forms
|
|
are ready to create a widget. */
|
|
bool isInserting() const { return m_inserting; }
|
|
|
|
/*! \return The name of the class being inserted, corresponding
|
|
to the menu item or the toolbar button clicked. */
|
|
QCString selectedClass() const { return m_selectedClass; }
|
|
|
|
/*! Sets the point where the pasted widget should be moved to. */
|
|
void setInsertPoint(const QPoint &p);
|
|
|
|
//! \return If we are creating a Connection by drag-and-drop or not.
|
|
bool isCreatingConnection() { return m_drawingSlot; }
|
|
|
|
//! \return the Connection being created.
|
|
Connection* createdConnection() { return m_connection; }
|
|
|
|
/*! Resets the Connection being created. We stay in Connection creation mode,
|
|
but we start a new connection (when the user clicks
|
|
outside of signals/slots menu). */
|
|
void resetCreatedConnection();
|
|
|
|
//! Creates and display a menu with all the signals of widget \a w.
|
|
void createSignalMenu(QWidget *w);
|
|
|
|
//! Creates and display a menu with all the slots of widget \a w.
|
|
void createSlotMenu(QWidget *w);
|
|
|
|
//! Emits the signal \ref createFormSlot(). Used by WidgetPropertySet.
|
|
void emitCreateSlot(const QString &widget, const QString &value)
|
|
{ emit createFormSlot(m_active, widget, value); }
|
|
|
|
/*! \return The Form actually active and focused.
|
|
*/
|
|
Form* activeForm() const;
|
|
|
|
/*! \return the Form whose toplevel widget is \a w, or 0
|
|
if there is not or the Form is in preview mode. */
|
|
Form* formForWidget(QWidget *w);
|
|
|
|
/*! \return true if \a w is a toplevel widget,
|
|
ie. it is the main widget of a Form (so it should have a caption ,
|
|
an icon ...) */
|
|
bool isTopLevel(QWidget *w);
|
|
|
|
//! \return A pointer to the KoProperty::Editor we use.
|
|
//unused KoProperty::Editor* propertyEditor() const { return m_editor; }
|
|
|
|
/*! Shows a property set \a set in a Property Editor.
|
|
If \a buff is 0, Property Editor will be cleared.
|
|
If \a forceReload is true, the set will be reloaded even
|
|
if it's the same as previous one.
|
|
If \a propertyToSelect is not empty, an item for this name will be selected
|
|
(usable when previously there was no set visible). */
|
|
virtual void showPropertySet(WidgetPropertySet *set, bool forceReload = false,
|
|
const QCString& propertyToSelect = QCString());
|
|
|
|
void blockPropertyEditorUpdating(void *blockingObject);
|
|
|
|
void unblockPropertyEditorUpdating(void *blockingObject, WidgetPropertySet *set);
|
|
|
|
/*! Sets the external property editor pane used by FormDesigner (it may be docked).*/
|
|
void setEditor(KoProperty::Editor *editor);
|
|
|
|
/*! Sets the external object tree view used by FormDesigner (it may be docked).
|
|
This function also connects appropriate signals and slots to ensure
|
|
sync with the current Form. */
|
|
void setObjectTreeView(ObjectTreeView *treeview);
|
|
|
|
/*! Previews the Form \a form using the widget \a w as toplevel container for this Form. */
|
|
void previewForm(Form *form, QWidget *w, Form *toForm=0);
|
|
|
|
/*! Adds a existing form w and changes it to a container */
|
|
void importForm(Form *form=0, bool preview=false);
|
|
|
|
/*! Deletes the Form \a form and removes it from our list. */
|
|
void deleteForm(Form *form);
|
|
|
|
/*! This function creates and displays the context menu corresponding to the widget \a w.
|
|
The menu item are disabled if necessary, and
|
|
the widget specific part is added (menu from the factory and buddy selection). */
|
|
void createContextMenu(QWidget *w, Container *container, bool popupAtCursor = true);
|
|
|
|
//! \return If we align widgets to grid or not.
|
|
bool snapWidgetsToGrid();
|
|
|
|
//! @internal used by Container
|
|
int contextMenuKey() const { return m_contextMenuKey; }
|
|
|
|
//! @internal
|
|
void emitWidgetSelected( KFormDesigner::Form* form, bool multiple );
|
|
//! @internal
|
|
void emitFormWidgetSelected( KFormDesigner::Form* form );
|
|
//! @internal
|
|
void emitNoFormSelected();
|
|
|
|
/*! @internal
|
|
\return true is redo action is being executed.
|
|
Used in WidgetPropertySet::slotPropertyChanged() */
|
|
bool isRedoing() const { return m_isRedoing; }
|
|
|
|
public slots:
|
|
/*! Deletes the selected widget in active Form and all of its children. */
|
|
void deleteWidget();
|
|
|
|
/*! Copies the slected widget and all its children of the active Form using an XML representation. */
|
|
void copyWidget();
|
|
|
|
/*! Cuts (ie Copies and deletes) the selected widget and all its children of
|
|
the active Form using an XML representation. */
|
|
void cutWidget();
|
|
|
|
/*! Pastes the XML representation of the copied or cut widget. The widget is
|
|
pasted when the user clicks the Form to
|
|
indicate the new position of the widget, or at the position of the contextual menu if there is one. */
|
|
void pasteWidget();
|
|
|
|
/*! Selects all toplevel widgets in trhe current form. */
|
|
void selectAll();
|
|
|
|
/*! Clears the contents of the selected widget(s) (eg for a line edit or a listview). */
|
|
void clearWidgetContent();
|
|
|
|
void undo();
|
|
void redo();
|
|
|
|
/*! Displays a dialog where the user can modify the tab order of the active Form,
|
|
by drag-n-drop or using up/down buttons. */
|
|
void editTabOrder();
|
|
|
|
/*! Adjusts the size of the selected widget, ie resize it to its size hint. */
|
|
void adjustWidgetSize();
|
|
|
|
/*! Creates a dialog to edit the \ref activeForm() PixmapCollection. */
|
|
void editFormPixmapCollection();
|
|
|
|
/*! Creates a dialog to edit the Connection of \ref activeForm(). */
|
|
void editConnections();
|
|
|
|
//! Lay out selected widgets using HBox layout (calls \ref CreateLayoutCommand).
|
|
void layoutHBox();
|
|
//! Lay out selected widgets using VBox layout.
|
|
void layoutVBox();
|
|
//! Lay out selected widgets using Grid layout.
|
|
void layoutGrid();
|
|
//! Lay out selected widgets in an horizontal splitter
|
|
void layoutHSplitter();
|
|
//! Lay out selected widgets in a verticak splitter
|
|
void layoutVSplitter();
|
|
//! Lay out selected widgets using HFlow layout
|
|
void layoutHFlow();
|
|
//! Lay out selected widgets using VFlow layout.
|
|
void layoutVFlow();
|
|
|
|
//! Breaks selected layout(calls \ref BreakLayoutCommand).
|
|
void breakLayout();
|
|
|
|
void alignWidgetsToLeft();
|
|
void alignWidgetsToRight();
|
|
void alignWidgetsToTop();
|
|
void alignWidgetsToBottom();
|
|
void alignWidgetsToGrid();
|
|
|
|
void adjustSizeToGrid();
|
|
|
|
//! Resize all selected widgets to the width of the narrowest widget.
|
|
void adjustWidthToSmall();
|
|
|
|
//! Resize all selected widgets to the width of the widest widget.
|
|
void adjustWidthToBig();
|
|
|
|
//! Resize all selected widgets to the height of the shortest widget.
|
|
void adjustHeightToSmall();
|
|
|
|
//! Resize all selected widgets to the height of the tallest widget.
|
|
void adjustHeightToBig();
|
|
|
|
void bringWidgetToFront();
|
|
void sendWidgetToBack();
|
|
|
|
/*! This slot is called when the user presses a "Widget" toolbar button
|
|
or a "Widget" menu item. Prepares all Forms for
|
|
creation of a new widget (ie changes cursor ...).
|
|
*/
|
|
void insertWidget(const QCString &classname);
|
|
|
|
/*! Stops the current widget insertion (ie unset the cursor ...). */
|
|
void stopInsert();
|
|
|
|
//! Slot called when the user presses 'Pointer' icon. Switch to Default mode.
|
|
void slotPointerClicked();
|
|
|
|
//! Enter the Connection creation mode.
|
|
void startCreatingConnection();
|
|
|
|
//! Leave the Connection creation mode.
|
|
void stopCreatingConnection();
|
|
|
|
/*! Calls this slot when the window activated changes (eg connect
|
|
to QWorkspace::windowActivated(QWidget*)). You <b>need</b> to connect
|
|
to this slot, it will crash otherwise.
|
|
*/
|
|
void windowChanged(QWidget *w);
|
|
|
|
//! Used to delayed widgets' deletion (in Container::deleteItem())
|
|
void deleteWidgetLater( QWidget *w );
|
|
|
|
/*! For debugging purposes only:
|
|
shows a text window containing contents of .ui XML definition of the current form. */
|
|
void showFormUICode();
|
|
|
|
/*! Executes font dialog and changes it for currently selected widget(s). */
|
|
void changeFont();
|
|
|
|
signals:
|
|
/*! This signal is emitted as the property set switched.
|
|
If \a forceReload is true, the set needs to be reloaded even
|
|
if it's the same as previous one. */
|
|
void propertySetSwitched(KoProperty::Set *set, bool forceReload = false, const QCString& propertyToSelect = QCString());
|
|
|
|
/*! This signal is emitted when any change is made to the Form \a form,
|
|
so it will need to be saved. */
|
|
void dirty(KFormDesigner::Form *form, bool isDirty=true);
|
|
|
|
/*! Signal emitted when a normal widget is selected inside \a form
|
|
(ie not form widget). If \a multiple is true,
|
|
then more than one widget is selected. Use this to update actions state. */
|
|
void widgetSelected(KFormDesigner::Form *form, bool multiple);
|
|
|
|
/*! Signal emitted when the form widget is selected inside \a form.
|
|
Use this to update actions state. */
|
|
void formWidgetSelected(KFormDesigner::Form *form);
|
|
|
|
/*! Signal emitted when no form (or a preview form) is selected.
|
|
Use this to update actions state. */
|
|
void noFormSelected();
|
|
|
|
/*! Signal emitted when undo action activation changes.
|
|
\a text is the full text of the action (including command name). */
|
|
void undoEnabled(bool enabled, const QString &text = QString::null);
|
|
|
|
/*! Signal emitted when redo action activation changes.
|
|
\a text is the full text of the action (including command name). */
|
|
void redoEnabled(bool enabled, const QString &text = QString::null);
|
|
|
|
/*! Signal emitted when the user choose a signal in 'Events' menu
|
|
in context menu, or in 'Events' in property editor.
|
|
The code editor should then create the slot connected to this signal. */
|
|
void createFormSlot(KFormDesigner::Form *form, const QString &widget, const QString &signal);
|
|
|
|
/*! Signal emitted when the Connection creation by drag-and-drop ends.
|
|
\a connection is the created Connection. You should copy it,
|
|
because it is deleted just after the signal is emitted. */
|
|
void connectionCreated(KFormDesigner::Form *form, KFormDesigner::Connection &connection);
|
|
|
|
/*! Signal emitted when the Connection creation by drag-and-drop is aborted by user. */
|
|
void connectionAborted(KFormDesigner::Form *form);
|
|
|
|
/*! Signal emitted when "autoTabStops" is changed. */
|
|
void autoTabStopsSet(KFormDesigner::Form *form, bool set);
|
|
|
|
/*! Signal emitted before the form gets finally deleted. \a form is still a valid pointer,
|
|
but the widgets inside the form are in unknown state. */
|
|
void aboutToDeleteForm(KFormDesigner::Form *form);
|
|
|
|
/*! Signal emitted when new form gets created. */
|
|
void formCreated(KFormDesigner::Form *form);
|
|
|
|
protected slots:
|
|
void deleteWidgetLaterTimeout();
|
|
|
|
/*! Slot called when a buddy is chosen in the buddy list. Sets the label buddy. */
|
|
void buddyChosen(int id);
|
|
|
|
/*! Slot called when the user chooses an item in signal (or slot) menu.
|
|
The \ref createdConnection() is updated, and the connection created
|
|
(for the signal menu). */
|
|
void menuSignalChosen(int id);
|
|
|
|
/*! Slot called when the user changes current style using combbox in toolbar or menu. */
|
|
void slotStyle();
|
|
|
|
void slotConnectionCreated(KFormDesigner::Form*, KFormDesigner::Connection&);
|
|
|
|
void slotSettingsChanged(int category);
|
|
|
|
protected:
|
|
/*! Inits the Form, adds it to m_forms, and conects slots. */
|
|
void initForm(Form *form);
|
|
|
|
#if 0
|
|
/*! Default implementation just calls FormIO::loadFormFromDom().
|
|
Change this if you need to handle, eg. custom UI XML tags, as in Kexi's Form Designer. */
|
|
virtual bool loadFormFromDomInternal(Form *form, QWidget *container, QDomDocument &inBuf);
|
|
|
|
/*! Default implementation just calls FormIO::saveFormToString().
|
|
Change this if you need to handle, eg. custom UI XML tags, as in Kexi's Form Designer. */
|
|
virtual bool saveFormToStringInternal(Form *form, QString &dest, int indent = 0);
|
|
#endif
|
|
/*! Function called by the "Lay out in..." menu items. It creates a layout from the
|
|
currently selected widgets (that must have the same parent).
|
|
Calls \ref CreateLayoutCommand. */
|
|
void createLayout(int layoutType);
|
|
|
|
/*! Function called by all other AlignWidgets*() function. Calls \ref AlignWidgetsCommand. */
|
|
void alignWidgets(int type);
|
|
|
|
void enableFormActions();
|
|
void disableWidgetActions();
|
|
void emitUndoEnabled(bool enabled, const QString &text);
|
|
void emitRedoEnabled(bool enabled, const QString &text);
|
|
|
|
/*! True if emitSelectionSignals() updates property set so showPropertySet() will
|
|
not be needed in windowChanged(). False by default. Set to true in KexiFormManager. */
|
|
bool m_emitSelectionSignalsUpdatesPropertySet : 1;
|
|
|
|
private:
|
|
static FormManager* _self;
|
|
|
|
//! Enum for menu items indexes
|
|
enum { MenuTitle = 200, MenuCopy, MenuCut, MenuPaste, MenuDelete, MenuHBox = 301,
|
|
MenuVBox, MenuGrid, MenuHSplitter, MenuVSplitter, MenuNoBuddy = 501 };
|
|
|
|
WidgetPropertySet *m_propSet;
|
|
// WidgetLibrary *m_lib;
|
|
QGuardedPtr<KoProperty::Editor> m_editor;
|
|
QGuardedPtr<ObjectTreeView> m_treeview;
|
|
// Forms
|
|
QPtrList<Form> m_forms;
|
|
QPtrList<Form> m_preview;
|
|
QGuardedPtr<Form> m_active;
|
|
|
|
// Copy/Paste
|
|
QDomDocument m_domDoc;
|
|
KPopupMenu *m_popup;
|
|
QPoint m_insertPoint;
|
|
QGuardedPtr<QWidget> m_menuWidget;
|
|
|
|
// Insertion
|
|
bool m_inserting;
|
|
QCString m_selectedClass;
|
|
|
|
// Connection stuff
|
|
bool m_drawingSlot;
|
|
Connection *m_connection;
|
|
KPopupMenu *m_sigSlotMenu;
|
|
|
|
// Actions
|
|
KActionCollection *m_collection;
|
|
KToggleAction *m_pointer, *m_dragConnection, *m_snapToGrid;
|
|
|
|
//! Used to delayed widgets deletion
|
|
QTimer m_deleteWidgetLater_timer;
|
|
QPtrList<QWidget> m_deleteWidgetLater_list;
|
|
|
|
#ifdef KEXI_DEBUG_GUI
|
|
KDialogBase *m_uiCodeDialog;
|
|
KTextEdit *m_currentUICodeDialogEditor;
|
|
KTextEdit *m_originalUICodeDialogEditor;
|
|
#endif
|
|
|
|
int m_options; //!< @see Options enum
|
|
int m_contextMenuKey; //!< Id of context menu key (cached)
|
|
|
|
void *m_objectBlockingPropertyEditorUpdating;
|
|
bool m_isRedoing : 1;
|
|
|
|
friend class PropertyCommand;
|
|
friend class GeometryPropertyCommand;
|
|
friend class CutWidgetCommand;
|
|
friend class Form;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|