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