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

0001 /* This file is part of the KDE project
0002    Copyright (C) 2004-2012 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KEXIVIEW_H
0021 #define KEXIVIEW_H
0022 
0023 #include <QWidget>
0024 #include <QEvent>
0025 #include <QCloseEvent>
0026 
0027 #include "kexiactionproxy.h"
0028 
0029 class KexiWindow;
0030 class KPropertySet;
0031 class KDbObject;
0032 
0033 //! Base class for single view embeddable in KexiWindow.
0034 /*! This class automatically works as a proxy for shared (application-wide) actions.
0035  KexiView has 'dirty' flag to indicate that view's data has changed.
0036  This flag's state is reused by KexiWindow object that contain the view.
0037  KexiView objects can be also nested, using addChildView(): any actions and 'dirty' flag
0038  are transmited to parent view in this case.
0039 
0040  KexiView objects are usually allocated within KexiWindow objects by implementing
0041  KexiPart::createView() method. See query or table part code for examples.
0042 
0043  KexiView object can be also allocated without attaching it KexiWindow,
0044  especially within dock window. see KexiMainWindow::initNavigator() to see example
0045  how KexiBrowser does this.
0046 
0047  @todo add some protected access methods
0048  */
0049 class KEXICORE_EXPORT KexiView : public QWidget, public KexiActionProxy
0050 {
0051     Q_OBJECT
0052 
0053 public:
0054     explicit KexiView(QWidget *parent);
0055     virtual ~KexiView();
0056 
0057     //! \return parent KexiWindow that containing this view,
0058     //! or 0 if no window contain this view
0059     KexiWindow* window() const;
0060 
0061     /*! Added for convenience.
0062      \return KexiPart object that was used to create this view (with a window)
0063      or 0 if this view is not created using KexiPart. \sa window() */
0064     KexiPart::Part* part() const;
0065 
0066     /*! \return preferred size hint, that can be used to resize the view.
0067      It is computed using maximum of (a) \a otherSize and (b) current dock area's size,
0068      so the view won't exceed this maximum size. The method is used e.g. in KexiWindow::sizeHint().
0069      If you reimplement this method, do not forget to return value of
0070      yoursize.boundedTo( KexiView::preferredSizeHint(otherSize) ). */
0071     virtual QSize preferredSizeHint(const QSize& otherSize);
0072 
0073     void addChildView(KexiView* childView);
0074 
0075     void removeView(Kexi::ViewMode mode);
0076 
0077     /*! True if contents (data) of the view is dirty and need to be saved
0078      This may or not be used, depending if changes in the window
0079      are saved immediately (e.g. like in datatableview) or saved by hand (by user)
0080      (e.g. like in alter-table window).
0081      "Dirty" flag is reused by KexiWindow::dirty().
0082      Default implementation just uses internal dirty flag, that is false by default.
0083      Reimplement this if you e.g. want reuse other "dirty"
0084      flag from internal structures that may be changed. */
0085     virtual bool isDirty() const;
0086 
0087     /*! @return true if data editing is in progress. This is useful to indicate
0088      * to the master window that the view should save the before switching to
0089      * other view. This information is used in KexiWindow::switchToViewMode().
0090      * Implement this in view that supports data editing, typically
0091      * of mode Kexi::DataViewMode. If you do this, also implement
0092      * saveDataChanges() and cancelDataChanges().
0093      * Default implementation just returns false. */
0094     virtual bool isDataEditingInProgress() const;
0095 
0096     /*! Saves changes that are currently made to the associated data.
0097      * Implement this in view that supports data editing, typically
0098      * of mode Kexi::DataViewMode. If you do this, also implement
0099      * isDataEditingInProgress() and cancelDataChanges().
0100      * This method is used by KexiWindow::switchToViewMode().
0101      * Default implementation just returns true.
0102      * @return true on success, false on failure and cancelled if the operation
0103      * has been cancelled. */
0104     virtual tristate saveDataChanges();
0105 
0106     /*! Cancel changes that are currently made to the associated data.
0107      * Implement this in view that supports data editing, typically
0108      * of mode Kexi::DataViewMode. If you do this, also implement
0109      * isDataEditingInProgress() and saveDataChanges().
0110      * This method is used by KexiWindow::switchToViewMode().
0111      * Default implementation just returns true.
0112      * @return true on success, false on failure and cancelled if the operation
0113      * has been cancelled. */
0114     virtual tristate cancelDataChanges();
0115 
0116     /*! \return the view mode for this view. */
0117     Kexi::ViewMode viewMode() const;
0118 
0119     /*! Reimplemented from KexiActionProxy.
0120      \return shared action with name \a action_name for this view.
0121      If there's no such action declared in Kexi Part (part()),
0122      global shared action is returned (if exists). */
0123     virtual QAction* sharedAction(const QString& action_name) override;
0124 
0125     /*! Enables or disables shared action declared in Kexi Part (part()).
0126      If there's no such action, global shared action is enabled or disabled (if exists). */
0127     virtual void setAvailable(const QString& action_name, bool set) override;
0128 
0129     enum StoreNewDataOption {
0130         OverwriteExistingData = 1 //!< Overwerite existing object in storeNewData()
0131     };
0132     Q_DECLARE_FLAGS(StoreNewDataOptions, StoreNewDataOption)
0133 
0134     QString defaultIconName() const;
0135 
0136     void setDefaultIconName(const QString& iconName);
0137 
0138     /*! For KexiQueryView */
0139     virtual QList<QVariant> currentParameters() const;
0140 
0141 public Q_SLOTS:
0142     virtual void setFocus();
0143 
0144     /*! Call this in your view's implementation whenever current property set
0145      (returned by propertySet()) is switched to other,
0146      so property editor contents need to be completely replaced. */
0147     virtual void propertySetSwitched();
0148 
0149     /*! Saves settings for the view. Default implementation does nothing and returns true.
0150       Implement this if there are settings to save. */
0151     virtual bool saveSettings();
0152 
0153     /*! Sets dirty flag on or off. It the flag changes,
0154      dirty(bool) signal is emitted by the parent window (KexiWindow),
0155      to inform the world about that. If this view has a parent view, setDirty()
0156      is called also on parent view.
0157      Always use this function to update 'dirty' flag information. */
0158     void setDirty(bool set);
0159 
0160     /*! Equal to setDirty(true). */
0161     void setDirty();
0162 
0163 Q_SIGNALS:
0164     //! emitted when the view is about to close
0165     void closing(bool *cancel);
0166 
0167     void focus(bool in);
0168 
0169 protected:
0170     virtual bool eventFilter(QObject *o, QEvent *e) override;
0171 
0172     /*! called by KexiWindow::switchToViewMode() right before window is switched to new mode
0173      By default does nothing. Reimplement this if you need to do something
0174      before switching to this view.
0175      \return true if you accept or false if a error occupied and view shouldn't change
0176      If there is no error but switching should be just cancelled
0177      (probably after showing some info messages), you need to return cancelled.
0178      Set \a dontStore to true (it's false by default) if you want to avoid data storing
0179      by storeData() or storeNewData(). */
0180     virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore);
0181 
0182     /*! called by KexiWindow::switchToViewMode() right after window is switched to new mode
0183      By default does nothing. Reimplement this if you need to do something
0184      after switching to this view.
0185      \return true if you accept or false if a error occupied and view shouldn't change
0186      If there is no error but switching should be just cancelled
0187      (probably after showing some info messages), you need to return cancelled. */
0188     virtual tristate afterSwitchFrom(Kexi::ViewMode mode);
0189 
0190     virtual void closeEvent(QCloseEvent * e) override;
0191 
0192     /*! \return a property set for this view. For reimplementation. By default returns NULL. */
0193     virtual KPropertySet *propertySet();
0194 
0195     /*! Call this in your view's implementation whenever current property set
0196      is changed that few properties are now visible and/or few other are invisible,
0197      so property editor operating on this property set should be completely reloaded.
0198      If \a preservePrevSelection is true and there was a property set
0199      assigned before call, previously selected item will be preselected
0200      in the editor (if found). */
0201     void propertySetReloaded(bool preservePrevSelection = false,
0202                              const QByteArray& propertyToSelect = QByteArray());
0203 
0204     /*! Tells this view to create and store data of the new object
0205      pointed by \a object on the backend.
0206      Called by KexiWindow::storeNewData() and KexiWindow::storeDataAs().
0207      Default implementation:
0208      - makes a deep copy of \a object
0209      - stores object data \a object in 'kexi__objects' internal table
0210        using KDbConnection::storeNewObjectData().
0211      Reimplement this for your needs.
0212      Requirements:
0213      - deep copy of \a object should be made
0214      - object data should be created at the backend
0215        (by calling KexiView::storeNewData(const KDbObject&, KexiView::StoreNewDataOptions,bool*))
0216        or using KDbConnection::storeNewObjectData() or more specialized method.
0217        For example KexiTableDesignerView uses KDbConnection::createTable(KDbTableSchema) for this
0218        (KDbTableSchema inherits KDbObject) to store more information than
0219        just the object data. You should use such subclasses if needed.
0220 
0221      Should return newly created object data object on success.
0222      In this case, do not store schema object yourself (make a deep copy if needed). */
0223     virtual KDbObject* storeNewData(const KDbObject& object,
0224                                     KexiView::StoreNewDataOptions options,
0225                                     bool *cancel);
0226 
0227     /*! Tells this view to fully copy existing object's data pointed by \a object on the backend.
0228      For example, for database tables it whould copy metadata, copy \a object, so the copy will
0229      have different name, caption and description, and physically copy the table (possibly on
0230      the server side).
0231      Called by KexiWindow::storeDataAs().
0232      Default implementation:
0233      - makes a deep copy of \a object
0234      - stores object data \a object in 'kexi__objects' internal table
0235        using KDbConnection::storeNewObjectData()
0236      - makes a full copy of data and user data.
0237      Reimplement this for your needs.
0238      Requirements:
0239      - deep copy of \a object should be made
0240      - object data should be created at the backend
0241        (by calling KexiView::copyData(const KDbObject&, KexiView::StoreNewDataOptions,bool*))
0242        or using KDbConnection::storeNewObjectData() or more specialized method.
0243        For example KexiTableDesignerView uses KDbConnection::createTable(KDbTableSchema) for this
0244        (KDbTableSchema inherits KDbObject) to store more information than
0245       just object data. Then it copies data table on the server side.
0246       You should use such subclasses if needed.
0247 
0248      Should return newly created object data object on success.
0249      In this case, do not store schema object yourself (make deep copy if needed). */
0250     virtual KDbObject* copyData(const KDbObject& object,
0251                                           KexiView::StoreNewDataOptions options,
0252                                           bool *cancel);
0253 
0254     /*! Loads large string data \a dataString block (e.g. xml form's representation),
0255      indexed with optional \a dataID, from the database backend.
0256      If \a canBeEmpty is true and there is no data block for dataID, true is returned
0257      and \a dataString is set to null string. The default is false.
0258      \return true on success
0259      \sa storeDataBlock(). */
0260     bool loadDataBlock(QString *dataString, const QString& dataID = QString(),
0261                        bool canBeEmpty = false);
0262 
0263     /*! Tells this view to store data changes on the backend.
0264      Called by KexiWindow::storeData().
0265      Default implementation:
0266      - stores object data \a object in 'kexi__objects' internal table
0267        using KDbConnection::storeObjectData().
0268      If \a dontAsk is true, no question dialog will
0269      be shown to the user. The default is false.
0270 
0271      Reimplement this for your needs. Should return true on success, false on failure
0272      and cancelled when the task should be cancelled.
0273      \sa storeNewData() */
0274     virtual tristate storeData(bool dontAsk = false);
0275 
0276     /*! Stores (potentially large) string data \a dataString, block (e.g. xml form's representation),
0277      at the database backend. Block will be stored in "kexi__objectdata" table pointed by
0278      this object's id and an optional \a dataID identifier.
0279 
0280      If window's id is not available (KexiWindow::id()),
0281      then ID that was just created in storeNewData() is used
0282      (see description of newlyAssignedID()).
0283      If there is already such record in the table, it's simply overwritten.
0284      \return true on success
0285     */
0286     bool storeDataBlock(const QString &dataString, const QString &dataID = QString());
0287 
0288     /*! Removes (potentially large) string data (e.g. xml form's representation),
0289      pointed by optional \a dataID, from the database backend.
0290      \return true on success. Does not fail if the block doe not exists.
0291      Note that if \a dataID is not specified, all data blocks for this view will be removed.
0292      \sa storeDataBlock(). */
0293     bool removeDataBlock(const QString& dataID = QString());
0294 
0295     void setViewWidget(QWidget* w, bool focusProxy = false);
0296 
0297     /*! Updates actions (e.g. availability). Reimplement it, if needed (you must
0298      call superclass impelmentation at the end!).
0299      This implementation does nothing for this view but calls updateActions()
0300      for every child-view of this view.
0301      called by KexiWindow on window's activation (\a activated is true)
0302      or deactivation. */
0303     virtual void updateActions(bool activated);
0304 
0305     virtual void setFocusInternal() {
0306         QWidget::setFocus();
0307     }
0308 
0309     /*! Allows to react on parent window's detaching.
0310      @todo it should be called by KexiWindow::youAreDetached().
0311      Default implementation does nothing.
0312      Implement it if you want to perform some appropriate actions. */
0313     virtual void windowDetached() {}
0314 
0315     /*! Allows to react on parent window's attaching.
0316      @todo it should be called by KexiWindow::youAreAttached().
0317      Default implementation does nothing.
0318      Implement it if you want to perform some appropriate actions. */
0319     virtual void windowAttached() {}
0320 
0321     /*! Assigns a list of view-level actions. Used by KexiView ctor. */
0322     void setViewActions(const QList<QAction*>& actions);
0323 
0324     /*! Assigns a list of main-menu-level actions. Used by KexiView ctor. */
0325     void setMainMenuActions(const QList<QAction*>& actions);
0326 
0327     /*! @return a list of view-level actions. */
0328     QList<QAction*> viewActions() const;
0329 
0330     /*! @return view-level action for name @a name or 0 if there is no such action. */
0331     QAction* viewAction(const char* name) const;
0332 
0333     void initViewActions();
0334     void initMainMenuActions();
0335 
0336     void toggleViewModeButtonBack();
0337 
0338     //! Sets properties in the Property Editor to be sorted if @a set is true.
0339     void setSortedProperties(bool set);
0340 
0341 private Q_SLOTS:
0342     void slotSwitchToViewModeInternal(Kexi::ViewMode mode);
0343     void slotSwitchToDataViewModeInternal(bool);
0344     void slotSwitchToDesignViewModeInternal(bool);
0345     void slotSwitchToTextViewModeInternal(bool);
0346 
0347 private:
0348     void createViewModeToggleButtons();
0349 
0350     class Private;
0351     Private * const d;
0352     friend class KexiWindow;
0353 };
0354 
0355 Q_DECLARE_OPERATORS_FOR_FLAGS(KexiView::StoreNewDataOptions)
0356 
0357 #endif