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.
koffice/kexi/formeditor/form.h

399 lines
14 KiB

/* This file is part of the KDE project
Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at>
Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
Copyright (C) 2004-2007 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 KFORMDESIGNERFORM_H
#define KFORMDESIGNERFORM_H
#include <tqobject.h>
#include <tqptrlist.h>
#include "resizehandle.h"
#include "utils.h"
#include "objecttree.h"
class TQWidget;
class TQDomElement;
class TDEActionCollection;
class KCommandHistory;
class KCommand;
class PixmapCollection;
namespace KFormDesigner {
class Container;
class WidgetPropertySet;
class WidgetLibrary;
class FormManager;
class ObjectTree;
class ObjectTreeItem;
class ConnectionBuffer;
//! Base (virtual) class for all form widgets
/*! You need to inherit this class, and implement the drawing functions. This is necessary
because you cannot inherit TQWidget twice, and we want form widgets to be any widget.
See FormWidgetBase in test/kfd_part.cpp and just copy functions there. */
class KFORMEDITOR_EXPORT FormWidget
{
public:
FormWidget();
virtual ~FormWidget();
/*! This function draws the rects in the \a list in the Form, above of all widgets,
using double-buffering. \a type can be 1 (selection rect)
or 2 (insert rect, dotted). */
virtual void drawRects(const TQValueList<TQRect> &list, int type) = 0;
virtual void drawRect(const TQRect &r, int type) = 0;
/*! This function inits the buffer used for double-buffering. Called before drawing rect. */
virtual void initBuffer() = 0;
/*! Clears the form, ie pastes the whole buffer to repaint the Form. */
virtual void clearForm() = 0;
/*! This function highlights two widgets (to is optional), which are
sender and receiver, and draws a link between them. */
virtual void highlightWidgets(TQWidget *from, TQWidget *to) = 0;
protected:
Form *m_form;
friend class Form;
};
//! @internal
class FormPrivate
{
public:
FormPrivate();
~FormPrivate();
// FormManager *manager;
TQGuardedPtr<Container> toplevel;
ObjectTree *topTree;
TQGuardedPtr<TQWidget> widget;
WidgetList selected;
ResizeHandleSet::Dict resizeHandles;
bool dirty;
bool interactive;
bool design;
TQString filename;
KCommandHistory *history;
TDEActionCollection *collection;
ObjectTreeList tabstops;
bool autoTabstops;
ConnectionBuffer *connBuffer;
PixmapCollection *pixcollection;
//! This map is used to store cursor shapes before inserting (so we can restore them later)
TQMap<TQObject*,TQCursor> cursors;
//!This string list is used to store the widgets which hasMouseTracking() == true (eg lineedits)
TQStringList *mouseTrackers;
FormWidget *formWidget;
//! A set of head properties to be stored in a .ui file.
//! This includes KFD format version.
TQMap<TQCString,TQString> headerProperties;
//! Format version, set by FormIO or on creating a new form.
uint formatVersion;
//! Format version, set by FormIO's loader or on creating a new form.
uint originalFormatVersion;
};
/*!
This class represents one form and holds the corresponding ObjectTree and Containers.
It takes care of widget selection and pasting widgets.
**/
//! A simple class representing a form
class KFORMEDITOR_EXPORT Form : public TQObject
{
TQ_OBJECT
public:
/*! Creates a simple Form, child of the FormManager \a manager.
*/
Form(WidgetLibrary* library, const char *name=0, bool designMode = true);
~Form();
//! \return A pointer to the WidgetLibrary supporting this form.
WidgetLibrary* library() const { return m_lib; }
/*!
Creates a toplevel widget out of another widget.
\a container will become the Form toplevel widget,
will be associated to an ObjectTree and so on.
\code TQWidget *toplevel = new TQWidget(this);
form->createToplevel(toplevel); \endcode
*/
void createToplevel(TQWidget *container, FormWidget *formWidget =0,
const TQCString &classname="TQWidget");
/*! \return the toplevel Container or 0 if this is a preview Form or createToplevel()
has not been called yet. */
Container* toplevelContainer() const { return d->toplevel; }
//! \return the FormWidget that holds this Form
FormWidget* formWidget() const { return d->formWidget; }
//! \return a pointer to this form's ObjectTree.
ObjectTree* objectTree() const { return d->topTree; }
//! \return the form's toplevel widget, or 0 if designMode() == false.
TQWidget* widget() const;
// //! \return the FormManager parent of this form.
// FormManager* manager() const { return d->manager; }
/*! \return A pointer to the currently active Container, ie the parent Container for a simple widget,
and the widget's Container if it is itself a container.
*/
Container* activeContainer();
/*! \return A pointer to the parent Container of the currently selected widget.
It is the same as activeContainer() for a simple widget, but unlike this function
it will also return the parent Container if the widget itself is a Container.
*/
Container* parentContainer(TQWidget *w=0);
/*! \return The \ref Container which is a parent of all widgets in \a wlist.
Used by \ref activeContainer(), and to find where
to paste widgets when multiple widgets are selected. */
ObjectTreeItem* commonParentContainer(WidgetList *wlist);
//! \return the list of currently selected widgets in this form
WidgetList* selectedWidgets() const {return &(d->selected);}
/*! \return currently selected widget in this form,
or 0 if there is no widget selected or more than one widget selected.
\see selectedWidgets() */
TQWidget* selectedWidget() const { return d->selected.count()==1 ? d->selected.first() : 0; }
/*! Emits the action signals, and optionaly the undo/redo related signals
if \a withUndoAction == true. See \a FormManager for signals description. */
void emitActionSignals(bool withUndoAction=true);
/*! Emits again all signal related to selection (ie Form::selectionChanged()).
Called eg when the user has the focus again. */
void emitSelectionSignals();
/*! Sets the Form interactivity mode. Form is not interactive when
pasting widgets, or loading a Form.
*/
void setInteractiveMode(bool interactive) { d->interactive = interactive; }
/*! \return true if the Form is being updated by the user, ie the created
widget were drawn on the Form.
\return false if the Form is being updated by the program, ie the widget
are created by FormIO, and so composed widgets
should not be populated automatically (such as TQTabWidget).
*/
bool interactiveMode() const { return d->interactive; }
/*! If \a design is true, the Form is in Design Mode (by default).
If \a design is false, then the Form is in Preview Mode, so
the ObjectTree and the Containers are removed. */
void setDesignMode(bool design);
//! \return The actual mode of the Form.
bool designMode() const { return d->design; }
bool isModified() { return d->dirty; }
//! \return the distance between two dots in the form background.
//! @todo make gridSize configurable at global level
int gridSize() { return 10; }
//! \return the default margin for all the layout inside this Form.
int defaultMargin() { return 11;}
//! \return the default spacing for all the layout inside this Form.
int defaultSpacing() { return 6;}
/*! This function is used by ObjectTree to emit childAdded() signal (as it is not a TQObject). */
void emitChildAdded(ObjectTreeItem *item);
/*! This function is used by ObjectTree to emit childRemoved() signal (as it is not a TQObject). */
void emitChildRemoved(ObjectTreeItem *item);
/*! \return The filename of the UI file this Form was saved to,
or TQString() if the Form hasn't be saved yet. */
TQString filename() const { return d->filename; }
//! Sets the filename of this Form to \a filename.
void setFilename(const TQString &file) { d->filename = file; }
KCommandHistory* commandHistory() const { return d->history; }
ConnectionBuffer* connectionBuffer() const { return d->connBuffer; }
PixmapCollection* pixmapCollection() const { return d->pixcollection; }
/*! Adds a widget in the form's command history. Please use it instead
of calling directly actionCollection()->addCommand(). */
void addCommand(KCommand *command, bool execute);
/*! Clears form's command history. */
void clearCommandHistory();
/*! \return A pointer to this Form tabstops list : it contains all the widget
that can have focus ( ie no labels, etc)
in the order of the tabs.*/
ObjectTreeList* tabStops() const { return &(d->tabstops); }
inline ObjectTreeListIterator tabStopsIterator() const { return ObjectTreeListIterator(d->tabstops); }
/*! Called (e.g. by KexiDBForm) when certain widgets can have updated focusPolicy properties
these having no TabFocus flags set are removed from tabStops() list. */
void updateTabStopsOrder();
/*! Adds the widget at the end of tabstops list. Called on widget creation. */
void addWidgetToTabStops(ObjectTreeItem *it);
/*! \return True if the Form automatically handles tab stops. */
bool autoTabStops() const { return d->autoTabstops; }
/*! If \a autoTab is true, then the Form will automatically handle tab stops,
and the "Edit Tab Order" dialog will be disabled.
The tab widget will be set from the top-left to the bottom-right corner.\n
If \ autoTab is false, then it's up to the user to change tab stops
(which are by default in order of creation).*/
void setAutoTabStops(bool autoTab) { d->autoTabstops = autoTab;}
/*! Tells the Form to reassign the tab stops because the widget layout has changed
(called for example before saving or displaying the tab order dialog).
Automatically sorts widget from the top-left to bottom-right corner.
Widget can be grouped with containers. In paticular, for tab widgets,
child widgets should ordered by parent tab's order. */
void autoAssignTabStops();
#ifdef KEXI_DEBUG_GUI
//! For debugging purposes
TQString m_recentlyLoadedUICode;
#endif
/*! Internal: called by ResizeHandle when mouse move event causes first
resize handle's dragging. As a result, current widget's editing (if any)
is finished - see WidgetFactory::resetEditor(). */
// void resizeHandleDraggingStarted(TQWidget *draggedWidget);
ResizeHandleSet* resizeHandlesForWidget(TQWidget* w);
/*! A set of value/key pairs provided to be stored as attributes in
<kfd:customHeader/> XML element (saved as a first child of \<UI> element). */
TQMap<TQCString,TQString>* headerProperties() const { return &d->headerProperties; }
//! \return format version number for this form.
//! For new forms it is equal to KFormDesigner::version().
uint formatVersion() const;
void setFormatVersion(uint ver);
//! \return original format version number for this form (as loaded from .ui XML string)
//! For new forms it is equal to KFormDesigner::version().
uint originalFormatVersion() const;
void setOriginalFormatVersion(uint ver);
public slots:
/*! This slot is called when the name of a widget was changed in Property Editor.
It renames the ObjectTreeItem associated to this widget.
*/
void changeName(const TQCString &oldname, const TQCString &newname);
/*! Sets \a selected to be the selected widget of this Form.
If \a add is true, the formerly selected widget is still selected,
and the new one is just added. If false, \a selected replace the actually selected widget.
The form widget is always selected alone.
\a moreWillBeSelected indicates whether more widgets will be selected soon
(so for multiselection we should not update the property pane before the last widget is selected) */
void setSelectedWidget(TQWidget *selected, bool add=false, bool dontRaise=false,
bool moreWillBeSelected = false);
/*! Unselects the widget \a w. Te widget is removed from the Cntainer 's list
and its resizeHandle is removed. */
void unSelectWidget(TQWidget *w);
/*! Sets the form widget (it will be uniquely selected widget). */
void selectFormWidget();
void clearSelection();
protected slots:
/*! This slot is called when the toplevel widget of this Form is deleted
(ie the window closed) so that the Form gets deleted at the same time.
*/
void formDeleted();
void emitUndoEnabled();
void emitRedoEnabled();
/*! This slot is called when a command is executed. The undo/redo signals
are emitted to update actions. */
void slotCommandExecuted();
/*! This slot is called when form is restored, ie when the user has undone
all actions. The form modified flag is updated, and
\ref FormManager::dirty() is called. */
void slotFormRestored();
signals:
/*! This signal is emitted by setSelectedWidget() when user selects a new widget,
to update both Property Editor and ObjectTreeView.
\a w is the newly selected widget.
*/
void selectionChanged(TQWidget *w, bool add, bool moreWillBeSelected = false);
/*! This signal is emitted when a new widget is created, to update ObjectTreeView.
\a it is the ObjectTreeItem representing this new widget.
*/
void childAdded(ObjectTreeItem *it);
/*! This signal is emitted when a widget is deleted, to update ObjectTreeView.
\a it is the ObjectTreeItem representing this deleted widget.
*/
void childRemoved(ObjectTreeItem *it);
//! This signal emitted when Form is about to be destroyed
void destroying();
protected:
void setConnectionBuffer(ConnectionBuffer *b) { d->connBuffer = b; }
void setFormWidget(FormWidget* w);
private:
WidgetLibrary *m_lib;
FormPrivate *d;
friend class FormManager;
friend class FormWidget;
friend class ConnectionDialog;
};
}
#endif