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

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003 Lucijan Busch <lucijan@kde.org>
0003    Copyright (C) 2003-2015 Jarosław Staniek <staniek@kde.org>
0004 
0005    This library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #ifndef KEXIWINDOWBASE_H
0022 #define KEXIWINDOWBASE_H
0023 
0024 #include "kexipartguiclient.h"
0025 #include "kexiactionproxy.h"
0026 #include "kexi.h"
0027 #include "kexipart.h"
0028 #include "KexiView.h"
0029 
0030 #include <QEvent>
0031 #include <QCloseEvent>
0032 
0033 class KexiMainWindow;
0034 class KexiWindowData;
0035 class KexiView;
0036 class KPropertySet;
0037 namespace KexiPart
0038 {
0039 class Part;
0040 }
0041 
0042 //! Base class for child window of Kexi's main application window.
0043 /*! This class can contain a number of configurable views, switchable using toggle action.
0044  It also automatically works as a proxy for shared (application-wide) actions. */
0045 class KEXICORE_EXPORT KexiWindow
0046             : public QWidget
0047             , public KexiActionProxy
0048             , public Kexi::ObjectStatus
0049 {
0050     Q_OBJECT
0051 
0052 public:
0053     virtual ~KexiWindow();
0054 
0055     //! \return true if the window is registered.
0056     bool isRegistered() const;
0057 
0058     //! \return currently selected view or 0 if there is no current view
0059     KexiView *selectedView() const;
0060 
0061     /*! \return a view for a given \a mode or 0 if there's no such mode available (or opened).
0062      This does not open mode if it's not opened. */
0063     KexiView *viewForMode(Kexi::ViewMode mode) const;
0064 
0065     //! Adds \a view for the dialog. It will be the _only_ view (of unspecified mode) for the dialog
0066     void addView(KexiView *view);
0067 
0068     /*! \return main (top level) widget inside this dialog.
0069      This widget is used for e.g. determining minimum size hint and size hint. */
0070 //  virtual QWidget* mainWidget() = 0;
0071 
0072     /*! reimplemented: minimum size hint is inherited from currently visible view. */
0073     virtual QSize minimumSizeHint() const override;
0074 
0075     /*! reimplemented: size hint is inherited from currently visible view. */
0076     virtual QSize sizeHint() const override;
0077 
0078     //js todo: maybe remove this since it's often the same as partItem()->identifier()?:
0079 
0080     /*! This method sets internal identifier for the dialog, but
0081      if there is a part item associated with this dialog (see partItem()),
0082      partItem()->identifier() will be is used as identifier, so this method is noop.
0083      Thus, it's usable only for dialog types when no part item is assigned. */
0084     void setId(int id);
0085 
0086     /*! If there is a part item associated with this dialog (see partItem()),
0087      partItem()->identifier() is returned, otherwise internal dialog's identifier
0088      (previously set by setID()) is returned. */
0089     int id() const;
0090 
0091     //! \return Kexi part used to create this window
0092     KexiPart::Part* part() const;
0093 
0094     //! \return Kexi part item used to create this window
0095     KexiPart::Item* partItem() const;
0096 
0097     //! Kexi dialog's gui COMMON client.
0098     //! It's obtained by querying part object for this dialog.
0099     KexiPart::GUIClient* commonGUIClient() const;
0100 
0101     //! Kexi dialog's gui client for currently selected view.
0102     //! It's obtained by querying part object for this dialog.
0103     KexiPart::GUIClient* guiClient() const;
0104 
0105     /*! \return name of icon provided by part that created this dialog.
0106      The name is used by KexiMainWindow to set/reset icon for this dialog. */
0107     virtual QString iconName();
0108 
0109     /*! \return true if this dialog supports switching to \a mode.
0110      \a mode is one of Kexi::ViewMode enum elements.
0111      The flags are used e.g. for testing by KexiMainWindow, if actions
0112      of switching to given view mode is available.
0113      This member is intialised in KexiPart that creates this window object. */
0114     bool supportsViewMode(Kexi::ViewMode mode) const;
0115 
0116     /*! \return information about supported view modes. */
0117     Kexi::ViewModes supportedViewModes() const;
0118 
0119     /*! \return current view mode for this dialog. */
0120     Kexi::ViewMode currentViewMode() const;
0121 
0122     void setContextHelp(const QString& caption, const QString& text, const QString& iconName);
0123 
0124     //! \return true if the window is attached within the main window
0125     bool isAttached() const {
0126         return true;
0127     }
0128 
0129     /*! True if contents (data) of the dialog is dirty and need to be saved
0130      This may or not be used, depending if changes in the dialog
0131      are saved immediately (e.g. like in datatableview) or saved by hand (by user)
0132      (e.g. like in alter-table dialog).
0133      \return true if at least one "dirty" flag is set for one of the dialog's view. */
0134     bool isDirty() const;
0135 
0136     /*! \return a pointer to view that has recently set dirty flag.
0137      This value is cleared when dirty flag is set to false (i.e. upon saving changes). */
0138     KexiView* viewThatRecentlySetDirtyFlag() const;
0139 
0140     /*! \return true, if this dialog's data were never saved.
0141      If it's true we're usually try to ask a user if the dialog's
0142      data should be saved somewhere. After dialog construction,
0143      "neverSaved" flag is set to appropriate value.
0144      KexiPart::Item::neverSaved() is reused.
0145     */
0146     bool neverSaved() const;
0147 
0148     /*! \return property set provided by the current view,
0149      or NULL if there is no view set (or the view has no set assigned). */
0150     KPropertySet *propertySet();
0151 
0152     //! @return schema object associated with this window
0153     KDbObject* schemaObject() const;
0154 
0155     //! Sets 'owned' property for object data.
0156     //! If true, the window will delete the object data before destruction.
0157     //! By default object data is not owned.
0158     //! @see setSchemaObject(), KexiPart::loadSchemaObject(), KexiPart::loadAndSetSchemaObject()
0159     void setSchemaObjectOwned(bool set);
0160 
0161     /*! Used by KexiView subclasses. \return temporary data shared between
0162      views */
0163     KexiWindowData *data() const;
0164 
0165     /*! Called primarily by KexiMainWindow to activate dialog.
0166      Selected view (if present) is also informed about activation. */
0167     void activate();
0168 
0169     /*! Called primarily by KexiMainWindow to deactivate dialog.
0170      Selected view (if present) is also informed about deactivation. */
0171     void deactivate();
0172 
0173     //! Helper, returns consistent window title for \a item.
0174     //! Used both for setting window's title and tab names in the main window.
0175     //! @todo Use Item::captionOrName() if this is defined in settings?
0176     static QString windowTitleForItem(const KexiPart::Item &item);
0177 
0178 public Q_SLOTS:
0179     virtual void setFocus();
0180 
0181     void updateCaption();
0182 
0183     /*! Internal. Called by KexiMainWindow::saveObject().
0184      Tells this dialog to save changes of the existing object
0185      to the backend. If \a dontAsk is true, no question dialog will
0186      be shown to the user. The default is false.
0187      \sa storeNewData()
0188      \return true on success, false on failure and cancelled when storing has been cancelled. */
0189     tristate storeData(bool dontAsk = false);
0190 
0191     /*! Internal. Called by KexiMainWindow::saveObject().
0192      Tells this dialog to create and store data of the new object
0193      to the backend.
0194      Object's object data has been never stored,
0195      so it is created automatically, using information obtained
0196      form part item. On success, part item's ID is updated to new value,
0197      and object data is set. \sa schemaObject().
0198      \return true on success, false on failure and cancelled when storing has been cancelled. */
0199     tristate storeNewData(KexiView::StoreNewDataOptions options = 0);
0200 
0201     /*! Internal. Called by KexiMainWindow::saveObject().
0202      Tells this dialog to create and store a copy of data of existing object to the backend.
0203      Object data has been never stored,
0204      so it is created automatically, using information obtained
0205      form the part item. On success, part item's ID is updated to new value,
0206      and object data is set. \sa schemaObject().
0207      \return true on success, false on failure and cancelled when storing has been cancelled. */
0208     tristate storeDataAs(KexiPart::Item *item, KexiView::StoreNewDataOptions options);
0209 
0210     /*! Reimplemented - we're informing the current view about performed
0211      detaching by calling KexiView::parentDialogDetached(), so the view
0212      can react on this event
0213      (by default KexiView::parentDialogDetached() does nothing, you can
0214      reimplement it). */
0215     void sendDetachedStateToCurrentView();
0216 
0217     /*! W're informing the current view about performed atttaching by calling
0218      KexiView::parentDialogAttached(), so the view can react on this event
0219      (by default KexiView::parentDialogAttached() does nothing, you can
0220      reimplement it). */
0221     void sendAttachedStateToCurrentView();
0222 
0223     /*! Saves settings for this window, for all views.
0224         @see KexiView::saveSettings() */
0225     bool saveSettings();
0226 
0227 Q_SIGNALS:
0228     void updateContextHelp();
0229 
0230     //! emitted when the window is about to close
0231     void closing();
0232 
0233     /*! Emitted to inform the world that 'dirty' flag changes.
0234      Activated by KexiView::setDirty(). */
0235     void dirtyChanged(KexiWindow*);
0236 
0237 protected Q_SLOTS:
0238     /*!  Sets 'dirty' flag on every dialog's view. */
0239     void setDirty(bool dirty);
0240 
0241     /*! Switches this dialog to \a newViewMode.
0242      \a viewMode is one of Kexi::ViewMode enum elements.
0243      \return true for successful switching
0244      True is returned also if user has cancelled switching
0245      (rarely, but for any reason) - cancelled is returned. */
0246     tristate switchToViewMode(Kexi::ViewMode newViewMode);
0247 
0248 protected:
0249     //! Used by KexiPart::Part
0250     KexiWindow(QWidget *parent, Kexi::ViewModes supportedViewModes, KexiPart::Part *part,
0251                KexiPart::Item *item);
0252 
0253     //! Used by KexiInternalPart
0254     KexiWindow();
0255 
0256     /*! Used by Part::openInstance(),
0257      like switchToViewMode( Kexi::ViewMode newViewMode ), but passed \a staticObjectArgs.
0258      Only used for parts of class KexiPart::StaticPart. */
0259     tristate switchToViewMode(Kexi::ViewMode newViewMode,
0260                               QMap<QString, QVariant>* staticObjectArgs,
0261                               bool *proposeOpeningInTextViewModeBecauseOfProblems);
0262 
0263     void registerWindow();
0264 
0265     virtual void closeEvent(QCloseEvent * e) override;
0266 
0267     //! \internal
0268     void addView(KexiView *view, Kexi::ViewMode mode);
0269 
0270     //! \internal
0271     void removeView(Kexi::ViewMode mode);
0272 
0273     //! \internal
0274     virtual bool eventFilter(QObject *obj, QEvent *e) override;
0275 
0276     //! Used by \a view to inform the dialog about changing state of the "dirty" flag.
0277     void dirtyChanged(KexiView* view);
0278 
0279     bool isDesignModePreloadedForTextModeHackUsed(Kexi::ViewMode newViewMode) const;
0280 
0281     /*! Created view's mode - helper for switchToViewMode(),
0282      KexiView ctor uses that info. >0 values are useful. */
0283     Kexi::ViewMode creatingViewsMode() const;
0284 
0285     /*! Sets temporary data shared between views. */
0286     void setData(KexiWindowData* data);
0287 
0288     //! Used by KexiView
0289     QVariant internalPropertyValue(const QByteArray& name,
0290                                    const QVariant& defaultValue = QVariant()) const;
0291 
0292     //! Sets schema object associated with this window to @a schemaObject
0293     void setSchemaObject(KDbObject* schemaObject);
0294 
0295 private Q_SLOTS:
0296     /*! Helper, calls KexiMainWindowIface::switchToViewMode() which in turn calls KexiWindow::switchToViewMode()
0297      to get error handling and reporting as well on main window level. */
0298     tristate switchToViewModeInternal(Kexi::ViewMode newViewMode);
0299 
0300 private:
0301     //! Closes the window and all views. If @a force is true, attempts to close every
0302     //! view even if one of them refuses to close. If @a force is false, false is returned
0303     //! as soon as first view refuses to close.
0304     //! @return true on successful close; forced close always returns true
0305     bool close(bool force = false);
0306 
0307     void createSubwidgets();
0308     void removeView(KexiView *view);
0309 
0310     class Private;
0311     Private *d;
0312 
0313     bool m_destroying; //!< true after entering to the dctor
0314 
0315     friend class KexiMainWindow;
0316     friend class KexiPart::Part;
0317     friend class KexiInternalPart;
0318     friend class KexiView;
0319 };
0320 
0321 #endif