File indexing completed on 2024-05-12 16:39:45

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at>
0003    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
0004    Copyright (C) 2008-2011 Jarosław Staniek <staniek@kde.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #ifndef FORMEDITORCONTAINER_H
0023 #define FORMEDITORCONTAINER_H
0024 
0025 #include "kformdesigner_export.h"
0026 #include "utils.h"
0027 #include "form.h"
0028 
0029 #include <QPointer>
0030 #include <QWidget>
0031 #include <QMouseEvent>
0032 
0033 class QEvent;
0034 class QLayout;
0035 
0036 namespace KFormDesigner
0037 {
0038 
0039 class Container;
0040 class ObjectTreeItem;
0041 
0042 /**
0043  * This class is used to filter the events from any widget (and all its subwidgets)
0044  * and direct it to the Container.
0045  */
0046 //! A class for redirecting events
0047 class KFORMDESIGNER_EXPORT EventEater : public QObject
0048 {
0049     Q_OBJECT
0050 
0051 public:
0052     /*! Constructs eater object. All events for \a widget and it's subwidgets
0053     will be redirected to \a container. \a container will be also parent of eater object,
0054     so you don't need to care about deleting it. */
0055     EventEater(QWidget *widget, QObject *container);
0056 
0057     ~EventEater();
0058 
0059     //! Sets the object which will receive the events
0060     void setContainer(QObject *container);
0061 
0062 protected:
0063     bool eventFilter(QObject *o, QEvent *ev) override;
0064 
0065 private:
0066     QPointer<QWidget>  m_widget;
0067     QPointer<QObject>  m_container;
0068 };
0069 
0070 /**
0071  * This class makes a container out of any QWidget. You can then create child widgets, and
0072  the background is dotted.
0073  */
0074 //! A class to make a container from any widget
0075 class KFORMDESIGNER_EXPORT Container : public QObject
0076 {
0077     Q_OBJECT
0078 
0079 public:
0080     /**
0081      * Creates a Container from the widget \a container, which have
0082      \a toplevel as parent Container. */
0083     Container(Container *toplevel, QWidget *container, QObject *parent = 0);
0084 
0085     virtual ~Container();
0086 
0087     //! \return a pointer to the toplevel Container, or 0 if this Container is toplevel
0088     Container* toplevel();
0089 
0090     //! \return the same as toplevel()->widget()
0091     QWidget* topLevelWidget() const;
0092 
0093     //! \return The form this Container belongs to.
0094     Form* form() const;
0095 
0096     //! \return The watched widget.
0097     QWidget* widget() const;
0098 
0099     //! \return The ObjectTreeItem associated with this Container's widget.
0100     ObjectTreeItem* objectTree() const;
0101 
0102     //! Sets the Form which this Container belongs to.
0103     void setForm(Form *form);
0104 
0105     /*! Sets the ObjectTree of this Container.\n
0106      * NOTE: this is needed only if we are toplevel. */
0107     void setObjectTree(ObjectTreeItem *t);
0108 
0109     //! \return a pointer to the QLayout of this Container, or 0 if there is not.
0110     QLayout* layout() const;
0111 
0112     //! \return the type of the layout associated to this Container's widget (see Form::LayoutType enum).
0113     Form::LayoutType layoutType() const;
0114 
0115     //! \return the margin of this Container.
0116     int layoutMargin() const;
0117 
0118     //! \return the spacing of this Container.
0119     int layoutSpacing() const;
0120 
0121     /*! Sets this Container to use \a type of layout. The widget are inserted
0122      automatically in the layout following their positions.
0123       \sa createBoxLayout(), createGridLayout() */
0124     void setLayoutType(Form::LayoutType type);
0125 
0126     //! Sets the spacing of this Container.
0127     void setLayoutSpacing(int spacing);
0128 
0129     //! Sets the margin of this Container.
0130     void setLayoutMargin(int margin);
0131 
0132     //! \return the string representing the layoutType \a type.
0133     static QString layoutTypeToString(Form::LayoutType type);
0134 
0135     //! \return the LayoutType (an int) for a given layout name.
0136     static Form::LayoutType stringToLayoutType(const QString &name);
0137 
0138     /*! Stops the inline editing of the current widget (as when you click
0139      on another widget or press Esc). */
0140     void stopInlineEditing();
0141 
0142     /*! This is the main function of Container, which filters the event sent
0143        to the watched widget.\n It takes care of drawing the background and
0144        the insert rect, of creating the new child widgets, of moving the widgets
0145         and pop up a menu when right-clicking. */
0146     virtual bool eventFilter(QObject *o, QEvent *e) override;
0147 
0148 public Q_SLOTS:
0149     /*! Sets \a selected to be the selected widget of this container
0150       (and so of the Form). See Form::WidgetSelectionFlags description
0151       for exmplanation of possible combination of @a flags flags.
0152       \sa Form::selectWidget() */
0153       void selectWidget(QWidget *w, Form::WidgetSelectionFlags flags = Form::DefaultWidgetSelectionFlags);
0154 
0155     /*! Deselects the widget \a w. The widget is removed from the Form's list
0156      and its resizeHandles are removed. */
0157     void deselectWidget(QWidget *w);
0158 
0159     /*! Deletes the widget \a w. Removes it from ObjectTree, and sets selection
0160      to Container's widget. */
0161     void deleteWidget(QWidget *w);
0162 
0163     /*! Recreates the Container layout. Calls this when a widget has been moved
0164      or added to update the layout. */
0165     void reloadLayout();
0166 
0167     //! Used by handler-based resizing.
0168     void startChangingGeometryPropertyForSelectedWidget();
0169 
0170     //! Used by handler-based resizing.
0171     void setGeometryPropertyForSelectedWidget(const QRect &newGeometry);
0172 
0173 protected Q_SLOTS:
0174     /*! This slot is called when the watched widget is deleted. Deletes the Container too. */
0175     void widgetDeleted();
0176 
0177 protected:
0178     /*! Internal function to create a HBoxLayout or VBoxLayout for this container.
0179      \a list is a subclass of CustomSortableWidgetList that can sort widgets
0180      depending on their orientation (i.e. HorizontalWidgetList or VerticalWidgetList). */
0181     void createBoxLayout(CustomSortableWidgetList* list);
0182 
0183     /*! Internal function to create a GridLayout. if \a testOnly is true, the layout
0184       is simulated, and only the widget's grid info aris filled. */
0185     void createGridLayout(bool testOnly = false);
0186 
0187     void setLayout(QLayout *layout);
0188 
0189 #ifdef KFD_SIGSLOTS
0190     //! Drawing functions used by eventFilter
0191     void drawConnection(QMouseEvent *mev);
0192 #endif
0193 
0194     void moveSelectedWidgetsBy(int realdx, int realdy, QMouseEvent *mev = 0);
0195 
0196 private:
0197     bool handleMouseReleaseEvent(QObject *s, QMouseEvent *mev);
0198 
0199     QRect selectionOrInsertingRectangle() const;
0200 
0201     QPoint selectionOrInsertingBegin() const;
0202 
0203     void selectionWidgetsForRectangle(const QPoint& secondPoint);
0204 
0205     class Private;
0206     Private * const d;
0207     friend class InsertWidgetCommand;
0208     friend class PasteWidgetCommand;
0209     friend class DeleteWidgetCommand;
0210     friend class FormIO;
0211 };
0212 
0213 //! Interface for adding dynamically created (at design time) widget to event eater.
0214 /*! This is currently used by KexiDBFieldEdit from Kexi forms. */
0215 class KFORMDESIGNER_EXPORT DesignTimeDynamicChildWidgetHandler
0216 {
0217 public:
0218     DesignTimeDynamicChildWidgetHandler();
0219     ~DesignTimeDynamicChildWidgetHandler();
0220 
0221 protected:
0222     void childWidgetAdded(QWidget* w);
0223     void assignItem(ObjectTreeItem* item);
0224 
0225 private:
0226     class Private;
0227     Private * const d;
0228     friend class InsertWidgetCommand;
0229     friend class FormIO;
0230 };
0231 
0232 }
0233 
0234 #endif