diff --git a/src/core/KexiGroupButton.h b/src/core/KexiGroupButton.h index a3faae6d7..19ef8c501 100644 --- a/src/core/KexiGroupButton.h +++ b/src/core/KexiGroupButton.h @@ -1,76 +1,76 @@ /* This file is part of the KDE libraries Copyright (C) 2007 Aurélien Gâteau Copyright (C) 2012 Jean-Nicolas Artaud Copyright (C) 2012-2016 Jarosław Staniek Based on Calligra libs' KoGroupButton This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 KEXIGROUPBUTTON_H #define KEXIGROUPBUTTON_H #include "kexicore_export.h" // Qt #include /** * A thin tool button which can be visually grouped with other buttons. * * The group can thus look like one solid bar: ( button1 | button2 | button3 ) * * For groupping layout can be used. For exclusive checkable behaviour assign QButtonGroup on the buttons. */ class KEXICORE_EXPORT KexiGroupButton : public QToolButton { Q_OBJECT Q_PROPERTY( GroupPosition groupPosition READ groupPosition WRITE setGroupPosition ) public: /** * Position of the button within the button group what affects the appearance. */ enum GroupPosition { NoGroup, //!< No particular position, gives the button unchanged appearance GroupLeft, //!< The button is at the left of the group, so it would have rounded the left part GroupRight, //!< The button is at the right of the group, so it would have rounded the right part GroupCenter //!< The button is on the center of the group, so it would have separators on both sides }; Q_ENUM(GroupPosition) explicit KexiGroupButton(GroupPosition position, QWidget* parent = 0); /** * Creates button with no NoGroup position. */ explicit KexiGroupButton(QWidget* parent = 0); virtual ~KexiGroupButton(); void setGroupPosition(KexiGroupButton::GroupPosition groupPosition); KexiGroupButton::GroupPosition groupPosition() const; protected: - virtual void paintEvent(QPaintEvent* event); + virtual void paintEvent(QPaintEvent* event) override; void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; private: class Private; Private *const d; }; #endif /* KEXIGROUPBUTTON_H */ diff --git a/src/core/KexiView.h b/src/core/KexiView.h index 2669ed830..c86d65911 100644 --- a/src/core/KexiView.h +++ b/src/core/KexiView.h @@ -1,357 +1,357 @@ /* This file is part of the KDE project Copyright (C) 2004-2012 Jarosław Staniek 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 KEXIVIEW_H #define KEXIVIEW_H #include #include #include #include "kexiactionproxy.h" class KexiWindow; class KPropertySet; class KDbObject; //! Base class for single view embeddable in KexiWindow. /*! This class automatically works as a proxy for shared (application-wide) actions. KexiView has 'dirty' flag to indicate that view's data has changed. This flag's state is reused by KexiWindow object that contain the view. KexiView objects can be also nested, using addChildView(): any actions and 'dirty' flag are transmited to parent view in this case. KexiView objects are usually allocated within KexiWindow objects by implementing KexiPart::createView() method. See query or table part code for examples. KexiView object can be also allocated without attaching it KexiWindow, especially within dock window. see KexiMainWindow::initNavigator() to see example how KexiBrowser does this. @todo add some protected access methods */ class KEXICORE_EXPORT KexiView : public QWidget, public KexiActionProxy { Q_OBJECT public: explicit KexiView(QWidget *parent); virtual ~KexiView(); //! \return parent KexiWindow that containing this view, //! or 0 if no window contain this view KexiWindow* window() const; /*! Added for convenience. \return KexiPart object that was used to create this view (with a window) or 0 if this view is not created using KexiPart. \sa window() */ KexiPart::Part* part() const; /*! \return preferred size hint, that can be used to resize the view. It is computed using maximum of (a) \a otherSize and (b) current dock area's size, so the view won't exceed this maximum size. The method is used e.g. in KexiWindow::sizeHint(). If you reimplement this method, do not forget to return value of yoursize.boundedTo( KexiView::preferredSizeHint(otherSize) ). */ virtual QSize preferredSizeHint(const QSize& otherSize); void addChildView(KexiView* childView); void removeView(Kexi::ViewMode mode); /*! True if contents (data) of the view is dirty and need to be saved This may or not be used, depending if changes in the window are saved immediately (e.g. like in datatableview) or saved by hand (by user) (e.g. like in alter-table window). "Dirty" flag is reused by KexiWindow::dirty(). Default implementation just uses internal dirty flag, that is false by default. Reimplement this if you e.g. want reuse other "dirty" flag from internal structures that may be changed. */ virtual bool isDirty() const; /*! @return true if data editing is in progress. This is useful to indicate * to the master window that the view should save the before switching to * other view. This information is used in KexiWindow::switchToViewMode(). * Implement this in view that supports data editing, typically * of mode Kexi::DataViewMode. If you do this, also implement * saveDataChanges() and cancelDataChanges(). * Default implementation just returns false. */ virtual bool isDataEditingInProgress() const; /*! Saves changes that are currently made to the associated data. * Implement this in view that supports data editing, typically * of mode Kexi::DataViewMode. If you do this, also implement * isDataEditingInProgress() and cancelDataChanges(). * This method is used by KexiWindow::switchToViewMode(). * Default implementation just returns true. * @return true on success, false on failure and cancelled if the operation * has been cancelled. */ virtual tristate saveDataChanges(); /*! Cancel changes that are currently made to the associated data. * Implement this in view that supports data editing, typically * of mode Kexi::DataViewMode. If you do this, also implement * isDataEditingInProgress() and saveDataChanges(). * This method is used by KexiWindow::switchToViewMode(). * Default implementation just returns true. * @return true on success, false on failure and cancelled if the operation * has been cancelled. */ virtual tristate cancelDataChanges(); /*! \return the view mode for this view. */ Kexi::ViewMode viewMode() const; /*! Reimplemented from KexiActionProxy. \return shared action with name \a action_name for this view. If there's no such action declared in Kexi Part (part()), global shared action is returned (if exists). */ - virtual QAction* sharedAction(const QString& action_name); + virtual QAction* sharedAction(const QString& action_name) override; /*! Enables or disables shared action declared in Kexi Part (part()). If there's no such action, global shared action is enabled or disabled (if exists). */ - virtual void setAvailable(const QString& action_name, bool set); + virtual void setAvailable(const QString& action_name, bool set) override; enum StoreNewDataOption { OverwriteExistingData = 1 //!< Overwerite existing object in storeNewData() }; Q_DECLARE_FLAGS(StoreNewDataOptions, StoreNewDataOption) QString defaultIconName() const; void setDefaultIconName(const QString& iconName); /*! For KexiQueryView */ virtual QList currentParameters() const; public Q_SLOTS: virtual void setFocus(); /*! Call this in your view's implementation whenever current property set (returned by propertySet()) is switched to other, so property editor contents need to be completely replaced. */ virtual void propertySetSwitched(); /*! Saves settings for the view. Default implementation does nothing and returns true. Implement this if there are settings to save. */ virtual bool saveSettings(); /*! Sets dirty flag on or off. It the flag changes, dirty(bool) signal is emitted by the parent window (KexiWindow), to inform the world about that. If this view has a parent view, setDirty() is called also on parent view. Always use this function to update 'dirty' flag information. */ void setDirty(bool set); /*! Equal to setDirty(true). */ void setDirty(); Q_SIGNALS: //! emitted when the view is about to close void closing(bool *cancel); void focus(bool in); protected: - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; /*! called by KexiWindow::switchToViewMode() right before window is switched to new mode By default does nothing. Reimplement this if you need to do something before switching to this view. \return true if you accept or false if a error occupied and view shouldn't change If there is no error but switching should be just cancelled (probably after showing some info messages), you need to return cancelled. Set \a dontStore to true (it's false by default) if you want to avoid data storing by storeData() or storeNewData(). */ virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); /*! called by KexiWindow::switchToViewMode() right after window is switched to new mode By default does nothing. Reimplement this if you need to do something after switching to this view. \return true if you accept or false if a error occupied and view shouldn't change If there is no error but switching should be just cancelled (probably after showing some info messages), you need to return cancelled. */ virtual tristate afterSwitchFrom(Kexi::ViewMode mode); - virtual void closeEvent(QCloseEvent * e); + virtual void closeEvent(QCloseEvent * e) override; /*! \return a property set for this view. For reimplementation. By default returns NULL. */ virtual KPropertySet *propertySet(); /*! Call this in your view's implementation whenever current property set is changed that few properties are now visible and/or few other are invisible, so property editor operating on this property set should be completely reloaded. If \a preservePrevSelection is true and there was a property set assigned before call, previously selected item will be preselected in the editor (if found). */ void propertySetReloaded(bool preservePrevSelection = false, const QByteArray& propertyToSelect = QByteArray()); /*! Tells this view to create and store data of the new object pointed by \a object on the backend. Called by KexiWindow::storeNewData() and KexiWindow::storeDataAs(). Default implementation: - makes a deep copy of \a object - stores object data \a object in 'kexi__objects' internal table using KDbConnection::storeNewObjectData(). Reimplement this for your needs. Requirements: - deep copy of \a object should be made - object data should be created at the backend (by calling KexiView::storeNewData(const KDbObject&, KexiView::StoreNewDataOptions,bool*)) or using KDbConnection::storeNewObjectData() or more specialized method. For example KexiTableDesignerView uses KDbConnection::createTable(KDbTableSchema) for this (KDbTableSchema inherits KDbObject) to store more information than just the object data. You should use such subclasses if needed. Should return newly created object data object on success. In this case, do not store schema object yourself (make a deep copy if needed). */ virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, bool *cancel); /*! Tells this view to fully copy existing object's data pointed by \a object on the backend. For example, for database tables it whould copy metadata, copy \a object, so the copy will have different name, caption and description, and physically copy the table (possibly on the server side). Called by KexiWindow::storeDataAs(). Default implementation: - makes a deep copy of \a object - stores object data \a object in 'kexi__objects' internal table using KDbConnection::storeNewObjectData() - makes a full copy of data and user data. Reimplement this for your needs. Requirements: - deep copy of \a object should be made - object data should be created at the backend (by calling KexiView::copyData(const KDbObject&, KexiView::StoreNewDataOptions,bool*)) or using KDbConnection::storeNewObjectData() or more specialized method. For example KexiTableDesignerView uses KDbConnection::createTable(KDbTableSchema) for this (KDbTableSchema inherits KDbObject) to store more information than just object data. Then it copies data table on the server side. You should use such subclasses if needed. Should return newly created object data object on success. In this case, do not store schema object yourself (make deep copy if needed). */ virtual KDbObject* copyData(const KDbObject& object, KexiView::StoreNewDataOptions options, bool *cancel); /*! Loads large string data \a dataString block (e.g. xml form's representation), indexed with optional \a dataID, from the database backend. If \a canBeEmpty is true and there is no data block for dataID, true is returned and \a dataString is set to null string. The default is false. \return true on success \sa storeDataBlock(). */ bool loadDataBlock(QString *dataString, const QString& dataID = QString(), bool canBeEmpty = false); /*! Tells this view to store data changes on the backend. Called by KexiWindow::storeData(). Default implementation: - stores object data \a object in 'kexi__objects' internal table using KDbConnection::storeObjectData(). If \a dontAsk is true, no question dialog will be shown to the user. The default is false. Reimplement this for your needs. Should return true on success, false on failure and cancelled when the task should be cancelled. \sa storeNewData() */ virtual tristate storeData(bool dontAsk = false); /*! Stores (potentially large) string data \a dataString, block (e.g. xml form's representation), at the database backend. Block will be stored in "kexi__objectdata" table pointed by this object's id and an optional \a dataID identifier. If window's id is not available (KexiWindow::id()), then ID that was just created in storeNewData() is used (see description of newlyAssignedID()). If there is already such record in the table, it's simply overwritten. \return true on success */ bool storeDataBlock(const QString &dataString, const QString &dataID = QString()); /*! Removes (potentially large) string data (e.g. xml form's representation), pointed by optional \a dataID, from the database backend. \return true on success. Does not fail if the block doe not exists. Note that if \a dataID is not specified, all data blocks for this view will be removed. \sa storeDataBlock(). */ bool removeDataBlock(const QString& dataID = QString()); void setViewWidget(QWidget* w, bool focusProxy = false); /*! Updates actions (e.g. availability). Reimplement it, if needed (you must call superclass impelmentation at the end!). This implementation does nothing for this view but calls updateActions() for every child-view of this view. called by KexiWindow on window's activation (\a activated is true) or deactivation. */ virtual void updateActions(bool activated); virtual void setFocusInternal() { QWidget::setFocus(); } /*! Allows to react on parent window's detaching. @todo it should be called by KexiWindow::youAreDetached(). Default implementation does nothing. Implement it if you want to perform some appropriate actions. */ virtual void windowDetached() {} /*! Allows to react on parent window's attaching. @todo it should be called by KexiWindow::youAreAttached(). Default implementation does nothing. Implement it if you want to perform some appropriate actions. */ virtual void windowAttached() {} /*! Assigns a list of view-level actions. Used by KexiView ctor. */ void setViewActions(const QList& actions); /*! Assigns a list of main-menu-level actions. Used by KexiView ctor. */ void setMainMenuActions(const QList& actions); /*! @return a list of view-level actions. */ QList viewActions() const; /*! @return view-level action for name @a name or 0 if there is no such action. */ QAction* viewAction(const char* name) const; void initViewActions(); void initMainMenuActions(); void toggleViewModeButtonBack(); //! Sets properties in the Property Editor to be sorted if @a set is true. void setSortedProperties(bool set); private Q_SLOTS: void slotSwitchToViewModeInternal(Kexi::ViewMode mode); void slotSwitchToDataViewModeInternal(bool); void slotSwitchToDesignViewModeInternal(bool); void slotSwitchToTextViewModeInternal(bool); private: void createViewModeToggleButtons(); class Private; Private * const d; friend class KexiWindow; }; Q_DECLARE_OPERATORS_FOR_FLAGS(KexiView::StoreNewDataOptions) #endif diff --git a/src/core/KexiWindow.h b/src/core/KexiWindow.h index 384bde96b..23e4625d2 100644 --- a/src/core/KexiWindow.h +++ b/src/core/KexiWindow.h @@ -1,321 +1,321 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2003-2015 Jarosław Staniek 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 KEXIWINDOWBASE_H #define KEXIWINDOWBASE_H #include "kexipartguiclient.h" #include "kexiactionproxy.h" #include "kexi.h" #include "kexipart.h" #include "KexiView.h" #include #include class KexiMainWindow; class KexiWindowData; class KexiView; class KPropertySet; namespace KexiPart { class Part; } //! Base class for child window of Kexi's main application window. /*! This class can contain a number of configurable views, switchable using toggle action. It also automatically works as a proxy for shared (application-wide) actions. */ class KEXICORE_EXPORT KexiWindow : public QWidget , public KexiActionProxy , public Kexi::ObjectStatus { Q_OBJECT public: virtual ~KexiWindow(); //! \return true if the window is registered. bool isRegistered() const; //! \return currently selected view or 0 if there is no current view KexiView *selectedView() const; /*! \return a view for a given \a mode or 0 if there's no such mode available (or opened). This does not open mode if it's not opened. */ KexiView *viewForMode(Kexi::ViewMode mode) const; //! Adds \a view for the dialog. It will be the _only_ view (of unspecified mode) for the dialog void addView(KexiView *view); /*! \return main (top level) widget inside this dialog. This widget is used for e.g. determining minimum size hint and size hint. */ // virtual QWidget* mainWidget() = 0; /*! reimplemented: minimum size hint is inherited from currently visible view. */ - virtual QSize minimumSizeHint() const; + virtual QSize minimumSizeHint() const override; /*! reimplemented: size hint is inherited from currently visible view. */ - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; //js todo: maybe remove this since it's often the same as partItem()->identifier()?: /*! This method sets internal identifier for the dialog, but if there is a part item associated with this dialog (see partItem()), partItem()->identifier() will be is used as identifier, so this method is noop. Thus, it's usable only for dialog types when no part item is assigned. */ void setId(int id); /*! If there is a part item associated with this dialog (see partItem()), partItem()->identifier() is returned, otherwise internal dialog's identifier (previously set by setID()) is returned. */ int id() const; //! \return Kexi part used to create this window KexiPart::Part* part() const; //! \return Kexi part item used to create this window KexiPart::Item* partItem() const; //! Kexi dialog's gui COMMON client. //! It's obtained by querying part object for this dialog. KexiPart::GUIClient* commonGUIClient() const; //! Kexi dialog's gui client for currently selected view. //! It's obtained by querying part object for this dialog. KexiPart::GUIClient* guiClient() const; /*! \return name of icon provided by part that created this dialog. The name is used by KexiMainWindow to set/reset icon for this dialog. */ virtual QString iconName(); /*! \return true if this dialog supports switching to \a mode. \a mode is one of Kexi::ViewMode enum elements. The flags are used e.g. for testing by KexiMainWindow, if actions of switching to given view mode is available. This member is intialised in KexiPart that creates this window object. */ bool supportsViewMode(Kexi::ViewMode mode) const; /*! \return information about supported view modes. */ Kexi::ViewModes supportedViewModes() const; /*! \return current view mode for this dialog. */ Kexi::ViewMode currentViewMode() const; void setContextHelp(const QString& caption, const QString& text, const QString& iconName); //! \return true if the window is attached within the main window bool isAttached() const { return true; } /*! True if contents (data) of the dialog is dirty and need to be saved This may or not be used, depending if changes in the dialog are saved immediately (e.g. like in datatableview) or saved by hand (by user) (e.g. like in alter-table dialog). \return true if at least one "dirty" flag is set for one of the dialog's view. */ bool isDirty() const; /*! \return a pointer to view that has recently set dirty flag. This value is cleared when dirty flag is set to false (i.e. upon saving changes). */ KexiView* viewThatRecentlySetDirtyFlag() const; /*! \return true, if this dialog's data were never saved. If it's true we're usually try to ask a user if the dialog's data should be saved somewhere. After dialog construction, "neverSaved" flag is set to appropriate value. KexiPart::Item::neverSaved() is reused. */ bool neverSaved() const; /*! \return property set provided by the current view, or NULL if there is no view set (or the view has no set assigned). */ KPropertySet *propertySet(); //! @return schema object associated with this window KDbObject* schemaObject() const; //! Sets 'owned' property for object data. //! If true, the window will delete the object data before destruction. //! By default object data is not owned. //! @see setSchemaObject(), KexiPart::loadSchemaObject(), KexiPart::loadAndSetSchemaObject() void setSchemaObjectOwned(bool set); /*! Used by KexiView subclasses. \return temporary data shared between views */ KexiWindowData *data() const; /*! Called primarily by KexiMainWindow to activate dialog. Selected view (if present) is also informed about activation. */ void activate(); /*! Called primarily by KexiMainWindow to deactivate dialog. Selected view (if present) is also informed about deactivation. */ void deactivate(); //! Helper, returns consistent window title for \a item. //! Used both for setting window's title and tab names in the main window. //! @todo Use Item::captionOrName() if this is defined in settings? static QString windowTitleForItem(const KexiPart::Item &item); public Q_SLOTS: virtual void setFocus(); void updateCaption(); /*! Internal. Called by KexiMainWindow::saveObject(). Tells this dialog to save changes of the existing object to the backend. If \a dontAsk is true, no question dialog will be shown to the user. The default is false. \sa storeNewData() \return true on success, false on failure and cancelled when storing has been cancelled. */ tristate storeData(bool dontAsk = false); /*! Internal. Called by KexiMainWindow::saveObject(). Tells this dialog to create and store data of the new object to the backend. Object's object data has been never stored, so it is created automatically, using information obtained form part item. On success, part item's ID is updated to new value, and object data is set. \sa schemaObject(). \return true on success, false on failure and cancelled when storing has been cancelled. */ tristate storeNewData(KexiView::StoreNewDataOptions options = 0); /*! Internal. Called by KexiMainWindow::saveObject(). Tells this dialog to create and store a copy of data of existing object to the backend. Object data has been never stored, so it is created automatically, using information obtained form the part item. On success, part item's ID is updated to new value, and object data is set. \sa schemaObject(). \return true on success, false on failure and cancelled when storing has been cancelled. */ tristate storeDataAs(KexiPart::Item *item, KexiView::StoreNewDataOptions options); /*! Reimplemented - we're informing the current view about performed detaching by calling KexiView::parentDialogDetached(), so the view can react on this event (by default KexiView::parentDialogDetached() does nothing, you can reimplement it). */ void sendDetachedStateToCurrentView(); /*! W're informing the current view about performed atttaching by calling KexiView::parentDialogAttached(), so the view can react on this event (by default KexiView::parentDialogAttached() does nothing, you can reimplement it). */ void sendAttachedStateToCurrentView(); /*! Saves settings for this window, for all views. @see KexiView::saveSettings() */ bool saveSettings(); Q_SIGNALS: void updateContextHelp(); //! emitted when the window is about to close void closing(); /*! Emitted to inform the world that 'dirty' flag changes. Activated by KexiView::setDirty(). */ void dirtyChanged(KexiWindow*); protected Q_SLOTS: /*! Sets 'dirty' flag on every dialog's view. */ void setDirty(bool dirty); /*! Switches this dialog to \a newViewMode. \a viewMode is one of Kexi::ViewMode enum elements. \return true for successful switching True is returned also if user has cancelled switching (rarely, but for any reason) - cancelled is returned. */ tristate switchToViewMode(Kexi::ViewMode newViewMode); protected: //! Used by KexiPart::Part KexiWindow(QWidget *parent, Kexi::ViewModes supportedViewModes, KexiPart::Part *part, KexiPart::Item *item); //! Used by KexiInternalPart KexiWindow(); /*! Used by Part::openInstance(), like switchToViewMode( Kexi::ViewMode newViewMode ), but passed \a staticObjectArgs. Only used for parts of class KexiPart::StaticPart. */ tristate switchToViewMode(Kexi::ViewMode newViewMode, QMap* staticObjectArgs, bool *proposeOpeningInTextViewModeBecauseOfProblems); void registerWindow(); - virtual void closeEvent(QCloseEvent * e); + virtual void closeEvent(QCloseEvent * e) override; //! \internal void addView(KexiView *view, Kexi::ViewMode mode); //! \internal void removeView(Kexi::ViewMode mode); //! \internal - virtual bool eventFilter(QObject *obj, QEvent *e); + virtual bool eventFilter(QObject *obj, QEvent *e) override; //! Used by \a view to inform the dialog about changing state of the "dirty" flag. void dirtyChanged(KexiView* view); bool isDesignModePreloadedForTextModeHackUsed(Kexi::ViewMode newViewMode) const; /*! Created view's mode - helper for switchToViewMode(), KexiView ctor uses that info. >0 values are useful. */ Kexi::ViewMode creatingViewsMode() const; /*! Sets temporary data shared between views. */ void setData(KexiWindowData* data); //! Used by KexiView QVariant internalPropertyValue(const QByteArray& name, const QVariant& defaultValue = QVariant()) const; //! Sets schema object associated with this window to @a schemaObject void setSchemaObject(KDbObject* schemaObject); private Q_SLOTS: /*! Helper, calls KexiMainWindowIface::switchToViewMode() which in turn calls KexiWindow::switchToViewMode() to get error handling and reporting as well on main window level. */ tristate switchToViewModeInternal(Kexi::ViewMode newViewMode); private: //! Closes the window and all views. If @a force is true, attempts to close every //! view even if one of them refuses to close. If @a force is false, false is returned //! as soon as first view refuses to close. //! @return true on sucessfull close; forced close always returns true bool close(bool force = false); void createSubwidgets(); void removeView(KexiView *view); class Private; Private *d; bool m_destroying; //!< true after entering to the dctor friend class KexiMainWindow; friend class KexiPart::Part; friend class KexiInternalPart; friend class KexiView; }; #endif diff --git a/src/core/kexi.cpp b/src/core/kexi.cpp index a8657734d..d3dfd024a 100644 --- a/src/core/kexi.cpp +++ b/src/core/kexi.cpp @@ -1,419 +1,419 @@ /* This file is part of the KDE project Copyright (C) 2003-2012 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexi.h" #include "KexiRecentProjects.h" #include "KexiMainWindowIface.h" #include "kexipartmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Kexi; //! used for speedup //! @internal class KexiInternal { public: static KexiInternal *_int; KexiInternal() : connset(0) { } ~KexiInternal() { delete connset; } static KexiInternal* self() { static bool created = false; if (!created) { _int = new KexiInternal; created = true; } return _int; } static void destroy() { delete _int; _int = 0; } KexiDBConnectionSet* connset; KexiRecentProjects recentProjects; KexiDBConnectionSet recentConnections; KDbDriverManager driverManager; KexiPart::Manager partManager; }; KexiInternal *KexiInternal::_int = 0; KexiDBConnectionSet& Kexi::connset() { //delayed if (!KexiInternal::self()->connset) { //load stored set data, OK? KexiInternal::self()->connset = new KexiDBConnectionSet(); KexiInternal::self()->connset->load(); } return *KexiInternal::self()->connset; } KexiRecentProjects* Kexi::recentProjects() { return &KexiInternal::self()->recentProjects; } KDbDriverManager& Kexi::driverManager() { return KexiInternal::self()->driverManager; } KexiPart::Manager& Kexi::partManager() { return KexiInternal::self()->partManager; } void Kexi::deleteGlobalObjects() { KexiInternal::self()->destroy(); } //temp bool _tempShowMacros = true; bool& Kexi::tempShowMacros() { #ifndef KEXI_MACROS_SUPPORT _tempShowMacros = false; #endif return _tempShowMacros; } bool _tempShowScripts = true; bool& Kexi::tempShowScripts() { #ifndef KEXI_SCRIPTS_SUPPORT _tempShowScripts = false; #endif return _tempShowScripts; } //-------------------------------------------------------------------------------- QString Kexi::nameForViewMode(ViewMode mode, bool withAmpersand) { if (!withAmpersand) return Kexi::nameForViewMode(mode, true).remove('&'); if (mode == NoViewMode) return xi18n("&No View"); else if (mode == DataViewMode) return xi18n("&Data View"); else if (mode == DesignViewMode) return xi18n("D&esign View"); else if (mode == TextViewMode) return xi18n("&Text View"); return xi18n("&Unknown"); } //-------------------------------------------------------------------------------- QString Kexi::iconNameForViewMode(ViewMode mode) { const char *const id = (mode == DataViewMode) ? KexiIconNameCStr("data-view") : (mode == DesignViewMode) ? KexiIconNameCStr("design-view") : (mode == TextViewMode) ? KexiIconNameCStr("sql-view"): 0; return QLatin1String(id); } //-------------------------------------------------------------------------------- ObjectStatus::ObjectStatus() : m_resultable(0), m_msgHandler(0) { } ObjectStatus::ObjectStatus(const QString& message, const QString& description) : m_resultable(0), m_msgHandler(0) { setStatus(message, description); } ObjectStatus::ObjectStatus(const KDbResultable* resultable, const QString& message, const QString& description) : m_resultable(0), m_msgHandler(0) { setStatus(resultable, message, description); } ObjectStatus::~ObjectStatus() { delete m_msgHandler; } const ObjectStatus& ObjectStatus::status() const { return *this; } bool ObjectStatus::error() const { return !message.isEmpty() || (m_resultable && m_resultable->result().isError()); } void ObjectStatus::setStatus(const QString& message, const QString& description) { m_resultable = 0; this->message = message; this->description = description; } void ObjectStatus::setStatus(const KDbResultable* resultable, const QString& message, const QString& description) { m_resultable = resultable; this->message = message; this->description = description; } void ObjectStatus::setStatus(KDbResultInfo* resultInfo, const QString& message, const QString& description) { if (resultInfo) { if (message.isEmpty()) { this->message = resultInfo->message; } else { this->message = message + " " + resultInfo->message; } if (description.isEmpty()) { this->description = resultInfo->description; } else { this->description = description + " " + resultInfo->description; } } else { setStatus(message, description); } } void ObjectStatus::setStatus(const KDbResultable* resultable, KDbResultInfo* resultInfo, const QString& message, const QString& description) { if (!resultable) setStatus(resultInfo, message, description); else if (!resultInfo) setStatus(resultable, message, description); else { setStatus(resultable, message, description); setStatus(resultInfo, this->message, this->description); } } void ObjectStatus::setStatus(const KDbResult &result, KDbResultInfo* resultInfo, const QString& message, const QString& description) { //! @todo KEXI3 test this if (!result.isError()) { if (resultInfo) { setStatus(resultInfo, message, description); } else { setStatus(message, description); } } else { if (resultInfo) { KDbResult r = result; r.prependMessage(message); r.prependMessage(description); setStatus(resultInfo, r.messageTitle(), r.message()); } else { setStatus(message, description); } } } void ObjectStatus::clearStatus() { message.clear(); description.clear(); } QString ObjectStatus::singleStatusString() const { if (message.isEmpty() || description.isEmpty()) return message; return message + " " + description; } void ObjectStatus::append(const ObjectStatus& otherStatus) { if (message.isEmpty()) { message = otherStatus.message; description = otherStatus.description; return; } const QString s(otherStatus.singleStatusString()); if (s.isEmpty()) return; if (description.isEmpty()) { description = s; return; } description = description + " " + s; } //! @internal class ObjectStatusMessageHandler : public KDbMessageHandler { public: explicit ObjectStatusMessageHandler(ObjectStatus *status) : KDbMessageHandler() , m_status(status) { } virtual ~ObjectStatusMessageHandler() { } virtual void showErrorMessage(KDbMessageHandler::MessageType messageType, const QString &msg, const QString &details = QString(), - const QString &caption = QString()) + const QString &caption = QString()) override { Q_UNUSED(messageType); Q_UNUSED(caption); m_status->setStatus(msg, details); } virtual void showErrorMessage(const KDbResult& result, KDbMessageHandler::MessageType messageType = KDbMessageHandler::Error, const QString& msg = QString(), - const QString& caption = QString()) + const QString& caption = QString()) override { Q_UNUSED(messageType); m_status->setStatus(result, 0, caption, msg); } ObjectStatus *m_status; }; ObjectStatus::operator KDbMessageHandler*() { if (!m_msgHandler) m_msgHandler = new ObjectStatusMessageHandler(this); return m_msgHandler; } void KEXI_UNFINISHED_INTERNAL(const QString& feature_name, const QString& extra_text, QString* line1, QString* line2) { if (feature_name.isEmpty()) *line1 = xi18n("This function is not available for version %1 of %2 application.", QString(KEXI_VERSION_STRING), QString(KEXI_APP_NAME)); else { QString feature_name_(feature_name); *line1 = xi18nc("@info", "%1 function is not available for version %2 of %3 application.", feature_name_.remove('&'), QString(KEXI_VERSION_STRING), QString(KEXI_APP_NAME)); } *line2 = extra_text; } void KEXI_UNFINISHED(const QString& feature_name, const QString& extra_text) { QString line1, line2; KEXI_UNFINISHED_INTERNAL(feature_name, extra_text, &line1, &line2); if (!line2.isEmpty()) line2.prepend("\n"); KMessageBox::sorry(0, line1 + line2); } QLabel *KEXI_UNFINISHED_LABEL(const QString& feature_name, const QString& extra_text) { QString line1, line2; KEXI_UNFINISHED_INTERNAL(feature_name, extra_text, &line1, &line2); QLabel *label = new QLabel(QLatin1String("") + line1 + QLatin1String("
") + line2); label->setAlignment(Qt::AlignCenter); label->setWordWrap(true); label->setAutoFillBackground(true); label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); return label; } //-------------------------------------------------------------------------------- QString Kexi::defaultFileBasedDriverIconName() { return KexiIconName("file-database"); } QIcon Kexi::defaultFileBasedDriverIcon() { return QIcon::fromTheme(defaultFileBasedDriverIconName()); } QString Kexi::serverIconName() { return KexiIconName("network-server-database"); } QIcon Kexi::serverIcon() { return QIcon::fromTheme(serverIconName()); } QString Kexi::appIncorrectlyInstalledMessage() { return xi18nc("@info", "%1 could have been incorrectly " "installed or started. The application will be closed.", QApplication::applicationDisplayName()); } QString Kexi::basePathForProject(const KDbConnectionData& connectionData) { KDbDriverManager manager; const KDbDriverMetaData* driverMetaData = manager.driverMetaData(connectionData.driverId()); if (driverMetaData && driverMetaData->isFileBased()) { const QFileInfo fileinfo(connectionData.databaseName()); return fileinfo.path(); } return QString(); } bool Kexi::isKexiInstance() { return KAboutData::applicationData().componentName() == QLatin1String("kexi"); } diff --git a/src/core/kexiguimsghandler.h b/src/core/kexiguimsghandler.h index d9bc2fbe8..c75b2eeb6 100644 --- a/src/core/kexiguimsghandler.h +++ b/src/core/kexiguimsghandler.h @@ -1,95 +1,95 @@ /* This file is part of the KDE project Copyright (C) 2004-2013 Jarosław Staniek 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 KEXIGUIMSGHANDLER_H #define KEXIGUIMSGHANDLER_H #include #include class KEXICORE_EXPORT KexiGUIMessageHandler : public KDbMessageHandler { public: explicit KexiGUIMessageHandler(QWidget *parent = 0); virtual ~KexiGUIMessageHandler(); using KDbMessageHandler::showErrorMessage; void showErrorMessage(const QString &message, const QString &details, const KDbResultable *resultable); void showErrorMessage(const QString &message, const KDbResultable *resultable); void showErrorMessage(Kexi::ObjectStatus *status); void showErrorMessage(const QString &message, Kexi::ObjectStatus *status); void showErrorMessage(const QString &title, const QString &details); /*! Displays a "Sorry" message with \a title text and optional \a details. */ void showSorryMessage(const QString &title, const QString &details = QString()); /*! Displays a message of a type \a type, with \a title text and optional \a details. \a dontShowAgainName can be specified to add "Do not show again" option if \a type is Warning. */ virtual void showMessage(MessageType type, const QString &title, const QString &details, const QString& dontShowAgainName = QString()); /*! Displays a Warning message with \a title text and optional \a details with "Continue" button instead "OK". \a dontShowAgainName can be specified to add "Do not show again" option. */ virtual void showWarningContinueMessage(const QString &title, const QString &details = QString(), const QString& dontShowAgainName = QString()); /*! Shows error message with @a title (it is not caption) and details. */ virtual void showErrorMessage( KDbMessageHandler::MessageType messageType, const QString &message, const QString &details = QString(), const QString &caption = QString() - ); + ) override; /*! Shows error message with @a message text. Existing error message from @a obj object is also copied, if present. */ virtual void showErrorMessage( const KDbResult& result, KDbMessageHandler::MessageType messageType = Error, const QString& message = QString(), const QString& caption = QString() - ); + ) override; /*! Interactively asks a question. For GUI version, message boxes are used. @a defaultResult is returned in case when no message handler is installed. @a message should contain translated string. Value of ButtonCode is returned. Reimplement this. This implementation does nothing, just returns @a defaultResult. */ virtual KDbMessageHandler::ButtonCode askQuestion( KDbMessageHandler::QuestionType messageType, const QString &message, const QString &caption = QString(), KDbMessageHandler::ButtonCode defaultResult = KDbMessageHandler::Yes, const KDbGuiItem &buttonYes = KDbGuiItem(), const KDbGuiItem &buttonNo = KDbGuiItem(), const QString &dontShowAskAgainName = QString(), KDbMessageHandler::Options options = 0, - KDbMessageHandler* msgHandler = 0); + KDbMessageHandler* msgHandler = 0) override; //! @return GUI message redirection for this handler or 0 if there is no GUI redirection. KexiGUIMessageHandler* guiRedirection(); protected: //using KDbMessageHandler::showErrorMessage; }; #endif diff --git a/src/core/kexitextmsghandler.h b/src/core/kexitextmsghandler.h index f672c285c..540acf60a 100644 --- a/src/core/kexitextmsghandler.h +++ b/src/core/kexitextmsghandler.h @@ -1,45 +1,45 @@ /* This file is part of the KDE project Copyright (C) 2004-2013 Jarosław Staniek 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 KEXITXTMSGHANDLER_H #define KEXITXTMSGHANDLER_H #include "kexiguimsghandler.h" //! @short A wrapper that redirects messages to a string variables instead of displaying them. //! See KexiTextMessageHandler constructor for details. class KEXICORE_EXPORT KexiTextMessageHandler : public KexiGUIMessageHandler { public: KexiTextMessageHandler(QString *messageTarget, QString *detailsTarget); virtual ~KexiTextMessageHandler(); using KexiGUIMessageHandler::showMessage; using KexiGUIMessageHandler::showErrorMessage; virtual void showErrorMessage(const QString &title, const QString &details = QString()); virtual void showMessage(MessageType type, const QString &title, const QString &details, - const QString& dontShowAgainName = QString()); + const QString& dontShowAgainName = QString()) override; protected: class Private; Private* const d; }; #endif diff --git a/src/formeditor/WidgetTreeWidget.h b/src/formeditor/WidgetTreeWidget.h index 00419b547..36522c1ad 100644 --- a/src/formeditor/WidgetTreeWidget.h +++ b/src/formeditor/WidgetTreeWidget.h @@ -1,179 +1,179 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2008-2010 Jarosław Staniek 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 KFD_WIDGETTREEWIDGET_H #define KFD_WIDGETTREEWIDGET_H #include #include "form.h" class QContextMenuEvent; namespace KFormDesigner { class ObjectTreeItem; //! @short An item in WidgetTreeWidget associated with an ObjectTreeItem. class KFORMDESIGNER_EXPORT WidgetTreeWidgetItem : public QTreeWidgetItem { public: /*! Flags for loadTree() */ enum LoadTreeFlag { NoLoadTreeFlags = 0, LoadTreeForAddedTabPage = 1 }; Q_DECLARE_FLAGS(LoadTreeFlags, LoadTreeFlag) //! Creates tree item. If @a forcedTabPageIndex >= 0, it is used as index for tab page. WidgetTreeWidgetItem(WidgetTreeWidgetItem *parent, ObjectTreeItem *data, LoadTreeFlags loadTreeFlags = NoLoadTreeFlags, int forcedTabPageIndex = -1, const QString& forcedTabPageName = QString()); //! For TabStopDialog explicit WidgetTreeWidgetItem(QTreeWidget *tree, ObjectTreeItem *data = 0, LoadTreeFlags loadTreeFlags = NoLoadTreeFlags, int forcedTabPageIndex = -1, const QString& forcedTabPageName = QString()); virtual ~WidgetTreeWidgetItem(); //! \return the item name, ie the ObjectTreeItem name QString name() const; //! \return the ObjectTreeItem information associated to this item. ObjectTreeItem* data() const; //! Added to unhide. - virtual QVariant data(int column, int role) const { return QTreeWidgetItem::data(column, role); } + virtual QVariant data(int column, int role) const override { return QTreeWidgetItem::data(column, role); } //! Reimplemented to alter sorting for certain widget types, e.g. tab pages. - virtual bool operator<( const QTreeWidgetItem & other ) const; + virtual bool operator<( const QTreeWidgetItem & other ) const override; //! Used to alter sorting for certain widget types, e.g. tab pages. QString customSortingKey() const; protected: //! Initializes text, icon, selectable flag, custom serting key void init(int forcedTabPageIndex, const QString& forcedTabPageName); void initTextAndIcon(int forcedTabPageIndex, const QString& forcedTabPageName); private: class Private; Private* const d; }; /*! @short A graphical view of Form's ObjectTree. This is a tree representin hierarchy of form widgets. The actually selected widgets are written bold and selected. Clicking on items selects the corresponding widgets on the form. */ class KFORMDESIGNER_EXPORT WidgetTreeWidget : public QTreeWidget { Q_OBJECT public: //! Options for the widget's behaviour or look enum Option { NoOptions = 0, DisableSelection = 1, //!< disables item selection DisableContextMenu = 2 //!< disables context menu }; Q_DECLARE_FLAGS(Options, Option) explicit WidgetTreeWidget(QWidget *parent = 0, Options options = NoOptions); virtual ~WidgetTreeWidget(); //! @return selected tree item or 0 if there is no selection or more than one item is selected. WidgetTreeWidgetItem* selectedItem() const; //! \return the pixmap name for a given class, to be shown next to the widget name. QString iconNameForClass(const QByteArray &classname) const; //! @see ObjectTreeItem* WidgetLibrary::selectableItem(ObjectTreeItem*) ObjectTreeItem* selectableItem(ObjectTreeItem* item); public Q_SLOTS: /*! Sets \a form as the current Form in the list. The list will automatically be filled with an item for each widget in the Form, and selection will be synced. Nothing happens if \a form is already the current Form. */ void setForm(KFormDesigner::Form *form); /*! Sets the widget \a w as selected item, so it will be written bold. It replaces previous selection if \a flags & Form::ReplacePreviousSelection is true. */ void selectWidget(QWidget *w, KFormDesigner::Form::WidgetSelectionFlags flags = KFormDesigner::Form::ReplacePreviousSelection); /*! Adds the ObjectTreeItem \a item in the list, with the appropriate parent. */ void addItem(KFormDesigner::ObjectTreeItem *item); /*! Removess the ObjectTreeItem \a item from the list. */ void removeItem(KFormDesigner::ObjectTreeItem *item); /*! Renames the list item from \a oldname to \a newname. */ void renameItem(const QByteArray &oldname, const QByteArray &newname); protected Q_SLOTS: /*! The selected list item has changed. */ void slotSelectionChanged(); /*! Called before Form object is destroyed. */ void slotBeforeFormDestroyed(); protected: //! Internal function to fill the list. void loadTree(ObjectTreeItem *item, WidgetTreeWidgetItem *parent, WidgetTreeWidgetItem::LoadTreeFlags flags = WidgetTreeWidgetItem::NoLoadTreeFlags); //! @return the item whose name is @a name. WidgetTreeWidgetItem* findItem(const QString &name); //! @return the item whose text in column 0 is @a text. WidgetTreeWidgetItem* findItemByFirstColumn(const QString& text); - virtual void contextMenuEvent(QContextMenuEvent* e); + virtual void contextMenuEvent(QContextMenuEvent* e) override; void handleContextMenuEvent(QContextMenuEvent* e); void selectWidgetForItem(QTreeWidgetItem *item); //! Try to alter selection of the item is nonselectable item clicked and parent item is available. QTreeWidgetItem* tryToAlterSelection(QTreeWidgetItem* current); //! If @a item is (grand)child of tab widget, activate proper tab page. //! Do it recursively because there may be nested tab widgets. void activateTabPageIfNeeded(QTreeWidgetItem* item); private: class Private; Private* const d; friend class TabStopDialog; }; Q_DECLARE_OPERATORS_FOR_FLAGS(WidgetTreeWidget::Options) Q_DECLARE_OPERATORS_FOR_FLAGS(WidgetTreeWidgetItem::LoadTreeFlags) } #endif diff --git a/src/formeditor/commands.h b/src/formeditor/commands.h index c16c74f69..a21ca70bd 100644 --- a/src/formeditor/commands.h +++ b/src/formeditor/commands.h @@ -1,559 +1,559 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2005-2010 Jarosław Staniek 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 KFORMEDITOR_COMMANDS_H #define KFORMEDITOR_COMMANDS_H #include "kformdesigner_export.h" #include "utils.h" #include "objecttree.h" #include "form.h" #include #include #include #include class QPoint; class QStringList; class QDomElement; namespace KFormDesigner { class ObjectTreeItem; class Container; class Form; //! Base class for KFormDesigner's commands class KFORMDESIGNER_EXPORT Command : public KUndo2Command { public: explicit Command(Command *parent = 0); explicit Command(const QString &text, Command *parent = 0); virtual ~Command(); //! Reimplemented to support effect of blockRedoOnce(). - virtual void redo(); + virtual void redo() override; //! Implement instead of redo(). virtual void execute() = 0; virtual void debug() const; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const Command &c); protected: //! Used to block execution of redo() once, on adding the command to the stack. void blockRedoOnce(); friend class Form; bool m_blockRedoOnce; //!< Used to block redo() once }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const Command &c); //! Command is used when changing a property for one or more widgets. class KFORMDESIGNER_EXPORT PropertyCommand : public Command { public: /*! @a oldValue is the old property value for selected widget. This enables reverting the change. @a value is the new property value. */ PropertyCommand(Form& form, const QByteArray &wname, const QVariant &oldValue, const QVariant &value, const QByteArray &propertyName, Command *parent = 0); /*! @a oldValues is a QHash of the old property values for every widget, to allow reverting the change. @a value is the new property value. You can use the simpler constructor for a single widget. */ PropertyCommand(Form& form, const QHash &oldValues, const QVariant &value, const QByteArray &propertyName, Command *parent = 0); virtual ~PropertyCommand(); Form* form() const; - virtual int id() const; + virtual int id() const override; void setUniqueId(int id); - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - bool mergeWith(const KUndo2Command * command); + bool mergeWith(const KUndo2Command * command) override; QByteArray propertyName() const; QVariant value() const; void setValue(const QVariant &value); const QHash& oldValues() const; //! @return old value if there is single value, otherwise null value. QVariant oldValue() const; //! @return widget name in case when there is only one widget //! with changed property in this command /*! Otherwise empty value is returned. */ QByteArray widgetName() const; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const PropertyCommand &c); protected: void init(); class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const PropertyCommand &c); //! Command used when moving multiples widgets at the same time, while holding Ctrl or Shift. /*! You need to supply a list of widget names, and the position of the cursor before moving. Use setPos() to tell the new cursor pos every time it changes.*/ class KFORMDESIGNER_EXPORT GeometryPropertyCommand : public Command { public: GeometryPropertyCommand(Form& form, const QStringList &names, const QPoint& oldPos, Command *parent = 0); virtual ~GeometryPropertyCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; void setPos(const QPoint& pos); QPoint pos() const; QPoint oldPos() const; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const GeometryPropertyCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const GeometryPropertyCommand &c); //! Command used when an "Align Widgets position" action is activated. /* You just need to give the list of widget names (the selected ones), and the type of alignment (see the enum for possible values). */ class KFORMDESIGNER_EXPORT AlignWidgetsCommand : public Command { public: AlignWidgetsCommand(Form &form, Form::WidgetAlignment alignment, const QWidgetList &list, Command *parent = 0); virtual ~AlignWidgetsCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const AlignWidgetsCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const AlignWidgetsCommand &c); //! Command used when an "Adjust Widgets Size" action is activated. /*! You just need to give the list of widget names (the selected ones), and the type of size modification (see the enum for possible values). */ class KFORMDESIGNER_EXPORT AdjustSizeCommand : public Command { public: enum Adjustment { SizeToGrid, SizeToFit, SizeToSmallWidth, SizeToBigWidth, SizeToSmallHeight, SizeToBigHeight }; AdjustSizeCommand(Form& form, Adjustment type, const QWidgetList &list, Command *parent = 0); virtual ~AdjustSizeCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const AdjustSizeCommand &c); protected: QSize getSizeFromChildren(ObjectTreeItem *item); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const AdjustSizeCommand &c); //! Command used when switching the layout of a container. /*! It remembers the old pos of every widget inside the container. */ class KFORMDESIGNER_EXPORT LayoutPropertyCommand : public PropertyCommand { public: LayoutPropertyCommand(Form& form, const QByteArray &wname, const QVariant &oldValue, const QVariant &value, Command *parent = 0); virtual ~LayoutPropertyCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const LayoutPropertyCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const LayoutPropertyCommand &c); //! Command used when inserting a widget using toolbar or menu. /*! You only have to give the parent Container and the widget pos. The other information is taken from the form. */ class KFORMDESIGNER_EXPORT InsertWidgetCommand : public Command { public: explicit InsertWidgetCommand(const Container& container, Command *parent = 0); /*! This ctor allows to set explicit class name and position. Used for dropping widgets on the form surface. If \a namePrefix is empty, widget's unique name is constructed using hint for \a className (WidgetLibrary::namePrefix()), otherwise, \a namePrefix is used to generate widget's name. This allows e.g. inserting a widgets having name constructed using */ InsertWidgetCommand(const Container& container, const QByteArray& className, const QPoint& pos, const QByteArray& namePrefix = QByteArray(), Command *parent = 0); virtual ~InsertWidgetCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; //! @return inserted widget's name QByteArray widgetName() const; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const InsertWidgetCommand &c); protected: void init(); class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const InsertWidgetCommand &c); //! @todo add CopyWidgetCommand //! Command used when pasting widgets. /*! You need to give the QDomDocument containing the widget(s) to paste, and optionally the point where to paste widgets. */ class KFORMDESIGNER_EXPORT PasteWidgetCommand : public Command { public: PasteWidgetCommand(const QDomDocument &domDoc, const Container& container, const QPoint& p = QPoint(), Command *parent = 0); virtual ~PasteWidgetCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const PasteWidgetCommand &c); protected: /*! Internal function used to change the coordinates of a widget to \a newPos before pasting it (to paste it at the position of the contextual menu). It modifies the "geometry" property of the QDomElement representing the widget. */ void changePos(QDomElement &el, const QPoint &newPos); /*! Internal function used to fix the coordinates of a widget before pasting it (to avoid having two widgets at the same position). It moves the widget by (10, 10) increment (several times if there are already pasted widgets at this position). */ void fixPos(QDomElement &el, Container *container); void moveWidgetBy(QDomElement &el, Container *container, const QPoint &p); /*! Internal function used to fix the names of the widgets before pasting them. It prevents from pasting a widget with the same name as an actual widget. The child widgets are also fixed recursively.\n If the name of the widget ends with a number (eg "QLineEdit1"), the new name is just incremented by one (eg becomes "QLineEdit2"). Otherwise, a "2" is just appended at the end of the name (eg "myWidget" becomes "myWidget2"). */ void fixNames(QDomElement &el); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const PasteWidgetCommand &c); //! Command used when deleting widgets using the "Delete" menu item. /*! You need to give a QWidgetList of the selected widgets. */ class KFORMDESIGNER_EXPORT DeleteWidgetCommand : public Command { public: DeleteWidgetCommand(Form& form, const QWidgetList &list, Command *parent = 0); virtual ~DeleteWidgetCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const DeleteWidgetCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const DeleteWidgetCommand &c); //! Command used when duplicating widgets. /*! You need to give a QWidgetList of the selected widgets. */ class KFORMDESIGNER_EXPORT DuplicateWidgetCommand : public Command { public: DuplicateWidgetCommand(const Container& container, const QWidgetList &list, const QPoint& copyToPoint, Command *parent = 0); virtual ~DuplicateWidgetCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const DuplicateWidgetCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const DuplicateWidgetCommand &c); //! Command used when cutting widgets. /*! It is basically a DeleteWidgetCommand which also updates the clipboard contents. */ class KFORMDESIGNER_EXPORT CutWidgetCommand : public DeleteWidgetCommand { public: CutWidgetCommand(Form &form, const QWidgetList &list, Command *parent = 0); virtual ~CutWidgetCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void undo(); + virtual void undo() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const CutWidgetCommand &c); protected: class Private; Private * const d2; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const CutWidgetCommand &c); //! Command that holds several PropertyCommand subcommands. /*! It appears as one to the user and in the command history. */ class KFORMDESIGNER_EXPORT PropertyCommandGroup : public Command { public: explicit PropertyCommandGroup(const QString &text, Command *parent = 0); virtual ~PropertyCommandGroup(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void debug() const; + virtual void debug() const override; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const PropertyCommandGroup &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const PropertyCommandGroup &c); //! Command is used when inline text is edited for a single widget. class KFORMDESIGNER_EXPORT InlineTextEditingCommand : public Command { public: /*! @a oldValue is the old property value for selected widget. This enables reverting the change. @a value is the new property value. */ InlineTextEditingCommand( Form& form, QWidget *widget, const QByteArray &editedWidgetClass, const QString &text, Command *parent = 0); virtual ~InlineTextEditingCommand(); - virtual int id() const; + virtual int id() const override; - virtual bool mergeWith(const KUndo2Command * command); + virtual bool mergeWith(const KUndo2Command * command) override; - virtual void execute(); + virtual void execute() override; - virtual void debug() const; + virtual void debug() const override; - virtual void undo(); + virtual void undo() override; Form* form() const; QString text() const; QString oldText() const; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const InlineTextEditingCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command group @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const InlineTextEditingCommand &c); class KFORMDESIGNER_EXPORT InsertPageCommand : public Command { public: InsertPageCommand(Container *container, QWidget *widget); virtual ~InsertPageCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; void execute(const QString& pageWidgetName, const QString& pageName, int pageIndex); - virtual void debug() const; + virtual void debug() const override; - virtual void undo(); + virtual void undo() override; void undo(const QString& name); friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const InsertPageCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const InsertPageCommand &c); class KFORMDESIGNER_EXPORT RemovePageCommand : public Command { public: RemovePageCommand(Container *container, QWidget *widget); virtual ~RemovePageCommand(); - virtual int id() const; + virtual int id() const override; - virtual void execute(); + virtual void execute() override; - virtual void debug() const; + virtual void debug() const override; - virtual void undo(); + virtual void undo() override; int pageIndex() const; QString pageName() const; friend KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const RemovePageCommand &c); protected: class Private; Private * const d; }; //! qDebug() stream operator. Writes command @a c to the debug output in a nicely formatted way. KFORMDESIGNER_EXPORT QDebug operator<<(QDebug dbg, const RemovePageCommand &c); } #endif diff --git a/src/formeditor/container.h b/src/formeditor/container.h index 89bcd12fe..3d8bb9635 100644 --- a/src/formeditor/container.h +++ b/src/formeditor/container.h @@ -1,234 +1,234 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2008-2011 Jarosław Staniek 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 FORMEDITORCONTAINER_H #define FORMEDITORCONTAINER_H #include "kformdesigner_export.h" #include "utils.h" #include "form.h" #include #include #include class QEvent; class QLayout; namespace KFormDesigner { class Container; class ObjectTreeItem; /** * This class is used to filter the events from any widget (and all its subwidgets) * and direct it to the Container. */ //! A class for redirecting events class KFORMDESIGNER_EXPORT EventEater : public QObject { Q_OBJECT public: /*! Constructs eater object. All events for \a widget and it's subwidgets will be redirected to \a container. \a container will be also parent of eater object, so you don't need to care about deleting it. */ EventEater(QWidget *widget, QObject *container); ~EventEater(); //! Sets the object which will receive the events void setContainer(QObject *container); protected: - bool eventFilter(QObject *o, QEvent *ev); + bool eventFilter(QObject *o, QEvent *ev) override; private: QPointer m_widget; QPointer m_container; }; /** * This class makes a container out of any QWidget. You can then create child widgets, and the background is dotted. */ //! A class to make a container from any widget class KFORMDESIGNER_EXPORT Container : public QObject { Q_OBJECT public: /** * Creates a Container from the widget \a container, which have \a toplevel as parent Container. */ Container(Container *toplevel, QWidget *container, QObject *parent = 0); virtual ~Container(); //! \return a pointer to the toplevel Container, or 0 if this Container is toplevel Container* toplevel(); //! \return the same as toplevel()->widget() QWidget* topLevelWidget() const; //! \return The form this Container belongs to. Form* form() const; //! \return The watched widget. QWidget* widget() const; //! \return The ObjectTreeItem associated with this Container's widget. ObjectTreeItem* objectTree() const; //! Sets the Form which this Container belongs to. void setForm(Form *form); /*! Sets the ObjectTree of this Container.\n * NOTE: this is needed only if we are toplevel. */ void setObjectTree(ObjectTreeItem *t); //! \return a pointer to the QLayout of this Container, or 0 if there is not. QLayout* layout() const; //! \return the type of the layout associated to this Container's widget (see Form::LayoutType enum). Form::LayoutType layoutType() const; //! \return the margin of this Container. int layoutMargin() const; //! \return the spacing of this Container. int layoutSpacing() const; /*! Sets this Container to use \a type of layout. The widget are inserted automatically in the layout following their positions. \sa createBoxLayout(), createGridLayout() */ void setLayoutType(Form::LayoutType type); //! Sets the spacing of this Container. void setLayoutSpacing(int spacing); //! Sets the margin of this Container. void setLayoutMargin(int margin); //! \return the string representing the layoutType \a type. static QString layoutTypeToString(Form::LayoutType type); //! \return the LayoutType (an int) for a given layout name. static Form::LayoutType stringToLayoutType(const QString &name); /*! Stops the inline editing of the current widget (as when you click on another widget or press Esc). */ void stopInlineEditing(); /*! This is the main function of Container, which filters the event sent to the watched widget.\n It takes care of drawing the background and the insert rect, of creating the new child widgets, of moving the widgets and pop up a menu when right-clicking. */ - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; public Q_SLOTS: /*! Sets \a selected to be the selected widget of this container (and so of the Form). See Form::WidgetSelectionFlags description for exmplanation of possible combination of @a flags flags. \sa Form::selectWidget() */ void selectWidget(QWidget *w, Form::WidgetSelectionFlags flags = Form::DefaultWidgetSelectionFlags); /*! Deselects the widget \a w. The widget is removed from the Form's list and its resizeHandles are removed. */ void deselectWidget(QWidget *w); /*! Deletes the widget \a w. Removes it from ObjectTree, and sets selection to Container's widget. */ void deleteWidget(QWidget *w); /*! Recreates the Container layout. Calls this when a widget has been moved or added to update the layout. */ void reloadLayout(); //! Used by handler-based resizing. void startChangingGeometryPropertyForSelectedWidget(); //! Used by handler-based resizing. void setGeometryPropertyForSelectedWidget(const QRect &newGeometry); protected Q_SLOTS: /*! This slot is called when the watched widget is deleted. Deletes the Container too. */ void widgetDeleted(); protected: /*! Internal function to create a HBoxLayout or VBoxLayout for this container. \a list is a subclass of CustomSortableWidgetList that can sort widgets depending on their orientation (i.e. HorizontalWidgetList or VerticalWidgetList). */ void createBoxLayout(CustomSortableWidgetList* list); /*! Internal function to create a GridLayout. if \a testOnly is true, the layout is simulated, and only the widget's grid info aris filled. */ void createGridLayout(bool testOnly = false); void setLayout(QLayout *layout); #ifdef KFD_SIGSLOTS //! Drawing functions used by eventFilter void drawConnection(QMouseEvent *mev); #endif void moveSelectedWidgetsBy(int realdx, int realdy, QMouseEvent *mev = 0); private: bool handleMouseReleaseEvent(QObject *s, QMouseEvent *mev); QRect selectionOrInsertingRectangle() const; QPoint selectionOrInsertingBegin() const; void selectionWidgetsForRectangle(const QPoint& secondPoint); class Private; Private * const d; friend class InsertWidgetCommand; friend class PasteWidgetCommand; friend class DeleteWidgetCommand; friend class FormIO; }; //! Interface for adding dynamically created (at design time) widget to event eater. /*! This is currently used by KexiDBFieldEdit from Kexi forms. */ class KFORMDESIGNER_EXPORT DesignTimeDynamicChildWidgetHandler { public: DesignTimeDynamicChildWidgetHandler(); ~DesignTimeDynamicChildWidgetHandler(); protected: void childWidgetAdded(QWidget* w); void assignItem(ObjectTreeItem* item); private: class Private; Private * const d; friend class InsertWidgetCommand; friend class FormIO; }; } #endif diff --git a/src/formeditor/form.h b/src/formeditor/form.h index 225444b57..54df40936 100644 --- a/src/formeditor/form.h +++ b/src/formeditor/form.h @@ -1,747 +1,747 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2017 Jarosław Staniek Copyright (C) 2014 Michał Poteralski 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 "kformdesigner_export.h" #include "widgetlibrary.h" #include #include #include class QWidget; class KActionCollection; class PixmapCollection; class KProperty; class KPropertySet; class KUndo2Command; namespace KFormDesigner { class Command; class PropertyCommandGroup; #ifdef KFD_SIGSLOTS class ConnectionBuffer; #endif class Container; class ObjectTree; class ObjectTreeItem; typedef QList ObjectTreeList; class FormPrivate; class FormWidget; class ResizeHandleSet; /*! 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 KFORMDESIGNER_EXPORT Form : public QObject { Q_OBJECT public: enum WidgetAlignment { AlignToGrid, AlignToLeft, AlignToRight, AlignToTop, AlignToBottom }; //! Form's mode: design or data. enum Mode { DataMode, DesignMode }; //! States like widget inserting. Used only in design mode. enum State { WidgetSelecting, //!< widget selecting WidgetInserting //!< widget inserting #ifdef KFD_SIGSLOTS , Connecting //!< signal/slot connecting #endif }; /*! Features used while creating Form objects. */ enum Feature { NoFeatures = 0, EnableEvents = 1, EnableFileActions = 2 #ifdef KFD_SIGSLOTS , EnableConnections = 4 #endif }; Q_DECLARE_FLAGS(Features, Feature) //! Types of layout enum LayoutType { NoLayout = 0, HBox, VBox, Grid, HFlow, VFlow, /* special types */ HSplitter, VSplitter }; /*! Creates Form object. */ Form(WidgetLibrary* library, Mode mode, KActionCollection &col, ActionGroup& group); /*! Creates Form object as a child of other form. */ explicit Form(Form *parent); ~Form(); //! \return A pointer to the WidgetLibrary supporting this form. WidgetLibrary* library() const; KPropertySet* propertySet(); void setFeatures(Features features); Features features() const; /*! 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 QWidget *toplevel = new QWidget(this); form->createToplevel(toplevel); \endcode */ void createToplevel(QWidget *container, FormWidget *formWidget = 0, const QByteArray &classname = "QWidget"); /*! \return the toplevel Container or 0 if the form is in data mode or createToplevel() has not been called yet. */ Container* toplevelContainer() const; //! \return the FormWidget that holds this Form FormWidget* formWidget() const; //! \return a pointer to this form's ObjectTree. ObjectTree* objectTree() const; //! \return the form's toplevel widget, or 0 if not in design mode. QWidget* widget() const; /*! \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(QWidget *w = 0) const; /*! \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(const QWidgetList &wlist); //! \return the list of currently selected widgets in this form QWidgetList* selectedWidgets() const; /*! \return currently selected widget in this form, or 0 if there is no widget selected or more than one widget selected. \see selectedWidgets() */ QWidget* selectedWidget() const; //! \return true if form widget itself is selected. /*! Used to check whether it is possible to execute copy/cut/delete actions. */ bool isFormWidgetSelected() const; /*! Emits the action signals. */ void emitActionSignals(); /*! Emits the action signals for the undo/redo related signals. */ void emitUndoActionSignals(); /*! 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); /*! \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 QTabWidget). */ bool interactiveMode() const; /*! Sets form's mode to @a mode. In data mode, information related to design mode (object tree and the containers..) is removed. */ void setMode(Mode mode); //! @return The actual mode of the Form. Mode mode() const; //! @return true if the form modification flag is set. bool isModified() const; //! Sets modification flag. Always emits modified() signal. void setModified(bool set); //! \return the default margin for all the layout inside this Form. int defaultMargin() const; //! \return the default spacing for all the layout inside this Form. int defaultSpacing() const; /*! This function is used by ObjectTree to emit childAdded() signal (as it is not a QObject). */ void emitChildAdded(ObjectTreeItem *item); /*! This function is used by ObjectTree to emit childRemoved() signal (as it is not a QObject). */ void emitChildRemoved(ObjectTreeItem *item); /*! \return The filename of the UI file this Form was saved to, or empty string if the Form hasn't be saved yet. */ //! @todo move this field out of this class QString fileName() const; //! Sets the filename of this Form to \a filename. //! @todo move this field out of this class void setFileName(const QString &file); /*! Clears form's undo/redo stack. */ void clearUndoStack(); /*! Sets undo/redo stack in a clean state, used when the document is saved. */ void setUndoStackClean(); #ifdef KFD_SIGSLOTS ConnectionBuffer* connectionBuffer() const; #endif PixmapCollection* pixmapCollection() const; void setPixmapsStoredInline(bool set); bool pixmapsStoredInline() const; //! Options for addCommand() method. enum AddCommandOption { DontExecuteCommand = 0, //!< command is not executed in addCommand() ExecuteCommand = 1 //!< command is executed in addCommand() }; /*! Adds a command @a command in the form's undo/redo stack and returns true. If @a command is merged with the existing command and deleted, false is returned. */ bool addCommand(Command *command, AddCommandOption option = ExecuteCommand); //! Creates a new PropertyCommand object and adds it to the undo/redo stack. /*! Takes care about the case when the same property of the same object is changed one-after-one. In this case only value of the present command on stack is changed. */ void addPropertyCommand(const QByteArray &wname, const QVariant &oldValue, const QVariant &value, const QByteArray &propertyName, AddCommandOption addOption, int idOfPropertyCommand = 0); void addPropertyCommand(const QHash &oldValues, const QVariant &value, const QByteArray &propertyName, AddCommandOption addOption, int idOfPropertyCommand = 0); //! Adds @a commandGroup to the undo/redo stack. /*! Assuming the @a commandGroup contains PropertyCommand objects, the method takes care about the case when the same properties of the same list of objects is changed one-after-one. In this case only values of the command in the present command group on the stack are changed and @a commandGroup is deleted.*/ void addPropertyCommandGroup(PropertyCommandGroup *commandGroup, AddCommandOption addOption, int idOfPropertyCommand = 0); /*! \return tabstops list. It contains all the widgets that can have focus (i.e. no labels, etc.) in the order of the tabs.*/ ObjectTreeList* 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; /*! If \a autoTab is true (the default), 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 \a autoTab is false, it's up to the user to change tab stops.*/ void setAutoTabStops(bool 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 particular, for tab widgets, child widgets should ordered by parent tab's order. */ void autoAssignTabStops(); //! Specifies target of context menu. Used in createContextMenu(). enum ContextMenuTarget { FormContextMenuTarget, //!< Context menu should be displayed on the form //!< with offset specified by menuPos argument. WidgetTreeContextMenuTarget //!< Context menu should be displayed on the widget tree //!< area with offset specified by menuPos argument. }; /*! This function creates and displays the context menu corresponding to the widget \a w. The menu item are disabled if necessary, and the widget specific part is added (menu from the factory and buddy selection). */ void createContextMenu(QWidget *w, Container *container, const QPoint& menuPos, ContextMenuTarget target); //! @return true if snapping to grid is enabled. The defalt value is false. bool isSnapToGridEnabled() const; //! Sets state of snapping to grid to @a enabled. void setSnapToGridEnabled(bool enabled); //! @return size of grid. Positive values make sense here. The defalt value is 0. //! @todo make gridSize configurable at global level int gridSize() const; //! Sets size of grid to @a gridSize. void setGridSize(int gridSize); #ifdef KEXI_DEBUG_GUI //! For debugging purposes QString m_recentlyLoadedUICode; #endif ResizeHandleSet* resizeHandlesForWidget(QWidget* w); /*! A set of value/key pairs provided to be stored as attributes in XML element (saved as a first child of \ element). */ QHash* headerProperties(); //! \return format version number for this form. //! For new forms it is equal to KFormDesigner::version(). QString formatVersion() const; void setFormatVersion(const QString &ver); //! \return original format version number for this form (as loaded from .ui XML string) //! For new forms it is equal to KFormDesigner::version(). QString originalFormatVersion() const; void setOriginalFormatVersion(const QString &ver); #ifdef KFD_SIGSLOTS /*! Related to signal/slots connections. Resets recently selected signal/slot connection (when the user clicks outside of signals/slots menu). We stay in "connection creation" mode, but user can only start a new connection. */ void resetSelectedConnection(); #endif //! @return state ofthe Form, i.e. the current operation like inserting a widget or selecting. State state() const; //! selection flags used in methods like selectWidget() enum WidgetSelectionFlag { AddToPreviousSelection = 0, //!< add to the previous selection, for clarity, //!< do not use with ReplacePreviousSelection ReplacePreviousSelection = 1, //!< replace the actually selected widget(s) MoreWillBeSelected = 0, //!< indicates that more selections will be added //!< do not use with LastSelection //!< so the property editor can be updated (used without ReplacePreviousSelection) LastSelection = 2, //!< indicates that this selection is the last one //!< so the property editor can be updated (used without ReplacePreviousSelection) Raise = 0, //!< raise the widget(s) on selection //!< do not use with DontRaise DontRaise = 4, //!< do not raise the widget(s) on selection DefaultWidgetSelectionFlags = ReplacePreviousSelection | LastSelection | Raise }; Q_DECLARE_FLAGS(WidgetSelectionFlags, WidgetSelectionFlag) /*! \return The name of the class being inserted, corresponding to the menu item or the toolbar button clicked. */ QByteArray selectedClass() const; /*! @return widgets list for names @a names. Form widget, if present is omitted. */ QList widgetsForNames(const QList& names) const; //! @return action from related action collection QAction* action(const QString& name); void createPropertyCommandsInDesignMode(QWidget* widget, const QHash &propValues, Command *parentCommand, bool addToActiveForm = true); //! @return class name of currently edited widget's QByteArray editedWidgetClass() const; //! @return true if we're within redo(). Useful to check if command is being executed //! in response of a redo or it is caused by some other event. bool isRedoing() const; public Q_SLOTS: /*! Called when the user presses a widget item of the toolbox. The form enters into "widget inserting" state. Prepares all form's widgets for creation of a new widget (i.e. temporarily changes their cursor). */ void enterWidgetInsertingState(const QByteArray &classname); //! Called when the user presses 'Pointer' icon. Switches to Default mode. void enterWidgetSelectingState(); /*! Aborts the current widget inserting operation (i.e. unsets the cursor ...). */ void abortWidgetInserting(); #ifdef KFD_SIGSLOTS //! Enters the Connection creation state. void enterConnectingState(); //! Leave the Connection creation mode. void abortCreatingConnection(); #endif /*! Called when the name of a widget was changed in the Property Editor. Renames the ObjectTreeItem associated to this widget. */ void changeName(const QByteArray &oldname, const QByteArray &newname); /*! Sets @a selected to be the selected widget of this Form. The form widget is always selected alone. */ void selectWidget(QWidget *selected, WidgetSelectionFlags flags = DefaultWidgetSelectionFlags); /*! Sets all widgets @a widgets to be the selected for this Form. Form widget, if present is omitted. */ void selectWidgets(const QList& widgets, WidgetSelectionFlags flags); /*! Sets all widgets with @a names to be the selected for this Form. Form widget, if present is omitted. */ void selectWidgets(const QList& names, WidgetSelectionFlags flags); /*! Removes selection for widget \a w. The widget is removed from the Container's list and its resize handle is removed as well. */ void deselectWidget(QWidget *w); /*! Sets the form widget selected. Deselects any previously selected widgets. */ void selectFormWidget(); /*! Clears the current selection. */ void clearSelection(); /*! Sets the point where the subsequently pasted widget should be moved to. */ void setInsertionPoint(const QPoint &p); void undo(); void redo(); /*! Changes undoing state of the list. Used by Undo command to prevent recursion. */ void setUndoing(bool isUndoing); bool isUndoing() const; /*! @return number of commands on the undo stack. */ int commandsCount() const; /*! @return command with index @a index on the undo stack. */ const KUndo2Command* command(int index) const; bool isTopLevelWidget(QWidget *w) const; /*! Deletes the selected widget in active Form and all of its children. */ void deleteWidget(); /*! Copies the slected widget and all its children of the active Form using an XML representation. */ void copyWidget(); /*! Cuts (ie Copies and deletes) the selected widget and all its children of the active Form using an XML representation. */ void cutWidget(); /*! Pastes the XML representation of the copied or cut widget. The widget is pasted when the user clicks the Form to indicate the new position of the widget, or at the position of the contextual menu if there is one. */ void pasteWidget(); /*! Selects all toplevel widgets in trhe current form. */ void selectAll(); /*! Clears the contents of the selected widget(s) (eg for a line edit or a listview). */ void clearWidgetContent(); /*! Displays a dialog where the user can modify the tab order of the active Form, by drag-n-drop or using up/down buttons. */ void editTabOrder(); /*! Adjusts the size of the selected widget, ie resize it to its size hint. */ void adjustWidgetSize(); /*! Creates a dialog to edit the \ref activeForm() PixmapCollection. */ void editFormPixmapCollection(); /*! Creates a dialog to edit the Connection of \ref activeForm(). */ void editConnections(); void alignWidgetsToLeft(); void alignWidgetsToRight(); void alignWidgetsToTop(); void alignWidgetsToBottom(); void alignWidgetsToGrid(); void adjustSizeToGrid(); //! Resize all selected widgets to the width of the narrowest widget. void adjustWidthToSmall(); //! Resize all selected widgets to the width of the widest widget. void adjustWidthToBig(); //! Resize all selected widgets to the height of the shortest widget. void adjustHeightToSmall(); //! Resize all selected widgets to the height of the tallest widget. void adjustHeightToBig(); void bringWidgetToFront(); void sendWidgetToBack(); /*! Executes font dialog and changes it for currently selected widget(s). */ void changeFont(); //! Sets slotPropertyChangedEnabled() enabled or disabled. void setSlotPropertyChangedEnabled(bool set); /*! @internal. This slot is called when the editor has lost focus or the user pressed Enter. It destroys the editor or installs again the event filter on the widget. */ void resetInlineEditor(); /*! This function provides a simple editing mode: it just disables event filtering for the widget, and it install it again when the widget loose focus or Enter is pressed. */ void disableFilter(QWidget *w, Container *container); protected Q_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 form is restored, ie when the user has undone all actions. The form modified flag is updated, and \ref modified() is called. */ void slotFormRestored(); /*! This function is called every time a property is modifed. It also takes care of saving set and enum properties. */ void slotPropertyChanged(KPropertySet& set, KProperty& property); /*! This slot is called when a property is reset using the "reload" button in PropertyEditor. */ void slotPropertyReset(KPropertySet& set, KProperty& property); /*! Default implementation changes "text" property. You have to reimplement this function for editing inside the Form to work if your widget's property you want to change isn't named "text". This slot is called when the line edit text changes, and you have to make it really change the good property of the widget using changeProperty() (text, or title, etc.). */ void changeInlineTextInternal(const QString& text); void slotInlineTextChanged(); /*! This slot is called when the editor is destroyed.*/ void inlineEditorDeleted(); void widgetDestroyed(); Q_SIGNALS: /*! This signal is emitted by selectWidget() when user selects a new widget, to update both the Property Editor and the Object Tree View. \a w is the newly selected widget. */ void selectionChanged(QWidget *w, KFormDesigner::Form::WidgetSelectionFlags flags); /*! This signal is emitted when a new widget is created, to update ObjectTreeView. \a it is the ObjectTreeItem representing this new widget. */ void childAdded(KFormDesigner::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(KFormDesigner::ObjectTreeItem *it); //! This signal emitted when Form is about to be destroyed void destroying(); /*! This signal is emitted when the property set has been switched. */ void propertySetSwitched(); /*! This signal is emitted when any change is made to the 'modified' flag of the form. */ void modified(bool m); /*! Signal emitted when a normal widget is selected inside of the form (not the form's widget). If \a multiple is true, then more than one widget is selected. Use this to update actions state. */ void widgetSelected(bool multiple); /*! Signal emitted when the form widget is selected inside of the form. Use this to update actions state. */ void formWidgetSelected(); /*! Signal emitted when no form (or a preview form) is selected. Use this to update actions state. */ void noFormSelected(); #ifdef KFD_SIGSLOTS /*! Signal emitted when the Connection creation by drag-and-drop ends. \a connection is the created Connection. You should copy it, because it is deleted just after the signal is emitted. */ void connectionCreated(KFormDesigner::Form *form, KFormDesigner::Connection &connection); /*! Signal emitted when the Connection creation by drag-and-drop is aborted by user. */ void connectionAborted(KFormDesigner::Form *form); #endif /*! Emitted when the name of the widget is modified. @a oldname is the name of the widget before the change, @a newname is the name after renaming. */ void widgetNameChanged(const QByteArray &oldname, const QByteArray &newname); protected: void emitSelectionChanged(QWidget *w, WidgetSelectionFlags flags); void updatePropertiesForSelection(QWidget *w, WidgetSelectionFlags flags); #ifdef KFD_SIGSLOTS //! Sets connection buffer to @a b, which will be owned by the form. //! The previous buffer will be deleted, if there is any. void setConnectionBuffer(ConnectionBuffer *b); #endif void setFormWidget(FormWidget* w); void emitFormWidgetSelected(); void emitWidgetSelected(bool multiple); //! @internal void emitNoFormSelected(); void enableFormActions(); void disableWidgetActions(); /*! Checks if the name entered by user is valid, ie that it is a valid identifier, and that there is no name conflict. */ bool isNameValid(const QString &name) const; void addWidget(QWidget *w); /*! Clears the current property set and fills it with properties related to the widget @a w. Also updates the newly created properties with previously set values. */ void createPropertiesForWidget(QWidget *w); /*! Changes \a property old value and changed state, using the value stored in \a tree. Optional \a meta can be specified if you need to handle enum values. */ void updatePropertyValue(ObjectTreeItem *tree, const char *property, const QMetaProperty &meta = QMetaProperty()); /*! Function called by all other alignWidgets*() function. */ void alignWidgets(WidgetAlignment alignment); /*! This function is used to filter the properties to be shown (ie not show "caption" if the widget isn't toplevel). \return true if the property should be shown. False otherwise.*/ bool isPropertyVisible(const QByteArray &property, bool isTopLevel, const QByteArray &classname = QByteArray()) const; // Following methods are used to create special types of properties, different // from Q_PROPERTY /*! Creates the properties related to alignment (ie hAlign, vAlign) for the QWidget \a widget. \a subwidget is the same as \a widget if the widget itself handles the property and it's a child widget if the child handles the property. For example, the second case is true for KexiDBAutoField. \a meta is the QMetaProperty for "alignment" property" of subwidget. */ void createAlignProperty(const QMetaProperty &meta, QWidget *widget, QWidget *subwidget); /*! Saves the properties related to alignment (ie hAlign, vAlign) and modifies the "alignment" property of the widget.*/ void saveAlignProperty(const QString &property); KActionCollection *actionCollection() const; //! @todo rm when the 2 libs are merged KFormDesigner::ActionGroup* widgetActionGroup() const; /*! Called when a property has been changed. @a w is the widget concerned, @a property is the name of the modified property, and @a value is the new value of this property. */ void handleWidgetPropertyChanged(QWidget *w, const QByteArray &name, const QVariant &value); /*! This function creates a QLineEdit to input some text and edit a widget's contents. */ void createInlineEditor(const KFormDesigner::WidgetFactory::InlineEditorCreationArguments& args); QString inlineEditorText() const; void setInlineEditorText(const QString& text); /*! This function destroys the editor when it loses focus or Enter is pressed. */ - virtual bool eventFilter(QObject *obj, QEvent *ev); + virtual bool eventFilter(QObject *obj, QEvent *ev) override; private: void init(Mode mode, KActionCollection &col, KFormDesigner::ActionGroup &group); void selectWidgetInternal(QWidget *w, WidgetSelectionFlags flags); FormPrivate * const d; friend class FormWidget; friend class WidgetLibrary; #ifdef KFD_SIGSLOTS friend class ConnectionDialog; #endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(Form::Features) Q_DECLARE_OPERATORS_FOR_FLAGS(Form::WidgetSelectionFlags) } #endif diff --git a/src/formeditor/formIO.h b/src/formeditor/formIO.h index 89f136e9d..bd481fb2b 100644 --- a/src/formeditor/formIO.h +++ b/src/formeditor/formIO.h @@ -1,224 +1,224 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2005-2007 Jarosław Staniek 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 FORMIO_H #define FORMIO_H #include "kformdesigner_export.h" #include #include #include #include #include class QString; class QDomElement; class QDomNode; class QDomDocument; class QVariant; class QLabel; //! A blank widget displayed when class is not supported class KFORMDESIGNER_EXPORT CustomWidget : public QWidget { Q_OBJECT public: CustomWidget(const QByteArray &className, QWidget *parent); virtual ~CustomWidget(); - virtual void paintEvent(QPaintEvent *ev); + virtual void paintEvent(QPaintEvent *ev) override; private: QByteArray m_className; }; namespace KFormDesigner { class Form; class ObjectTreeItem; class Container; //! KFormDesigner API major version number. Increased on every breaking of backward compatibility. //! Use KFormDesigner::version() to get real version number of the library. #define KFORMDESIGNER_VERSION_MAJOR KEXI_STABLE_VERSION_MAJOR //! KFormDesigner API minor version number. Increased on every compatible change. //! Use KFormDesigner::version() to get real version number of the library. #define KFORMDESIGNER_VERSION_MINOR KEXI_STABLE_VERSION_MINOR //! \return KFormDesigner API version number for this library: "major.minor" KFORMDESIGNER_EXPORT QString version(); /** This class act as a namespace for all .ui files related functions, ie saving/loading .ui files. You don't need to create a FormIO object, as all methods are static.\n This class is able to read and write Forms to .ui files, and to save each type of properties, including set and enum properties, and pixmaps(pixmap-related code was taken from Qt Designer). **/ //! A class to save/load forms from .ui files class KFORMDESIGNER_EXPORT FormIO : public QObject { Q_OBJECT public: FormIO(); ~FormIO(); /*! Save the Form in the \a domDoc QDomDocument. Called by saveForm(). \return true if saving succeeded. \sa saveForm() */ static bool saveFormToDom(Form *form, QDomDocument &domDoc); /*! Save the Form \a form to the file \a filename. If \a filename is null or not given, a Save File dialog will be shown to choose dest file. \return true if saving succeeded. \todo Add errors code and error dialog */ static bool saveFormToFile(Form *form, const QString &filename = QString()); /*! Saves the Form to the \a dest string. \a indent can be specified to apply indentation. \return true if saving succeeded. \sa saveForm() */ static bool saveFormToString(Form *form, QString &dest, int indent = 0); /*! Saves the \a form inside the \a dest QByteArray. \return true if saving succeeded. \sa saveFormToDom(), saveForm() */ static bool saveFormToByteArray(Form *form, QByteArray &dest); /*! Loads a form from the \a domDoc QDomDocument. Called by loadForm() and loadFormData(). \return true if loading succeeded. */ static bool loadFormFromDom(Form *form, QWidget *container, const QDomDocument &domDoc); /*! Loads a form from the \a src QByteArray. \sa loadFormFromDom(), loadForm(). \return true if loading succeeded. */ static bool loadFormFromByteArray(Form *form, QWidget *container, QByteArray &src, bool preview = false); static bool loadFormFromString(Form *form, QWidget *container, const QString &src, bool preview = false); /*! Loads the .ui file \a filename in the Form \a form. If \a filename is null or not given, a Open File dialog will be shown to select the file to open. createToplevelWidget() is used to load the Form's toplevel widget. \return true if loading succeeded. \todo Add errors code and error dialog */ static bool loadFormFromFile(Form *form, QWidget *container, const QString &filename = QString()); /*! Saves the widget associated to the ObjectTreeItem \a item into DOM document \a domDoc, with \a parent as parent node. It calls readPropertyValue() for each object property, readAttribute() for each attribute and itself to save child widgets. \return true if saving succeeded. This is used to copy/paste widgets. */ static void saveWidget(ObjectTreeItem *item, QDomElement &parent, QDomDocument &domDoc, bool insideGridLayout = false); /*! Cleans the "UI" QDomElement after saving widget. It deletes the "includes" element not needed when pasting, and make sure all the "widget" elements are at the beginning. Call this after copying a widget, before pasting.*/ static void cleanClipboard(QDomElement &uiElement); /*! Loads the widget associated to the QDomElement \a el into the Container \a container, with \a parent as parent widget. If parent = 0, the Container::widget() is used as parent widget. This is used to copy/paste widgets. */ static void loadWidget(Container *container, const QDomElement &el, QWidget *parent, QHash *buddies); /*! Save an element in the \a domDoc as child of \a parentNode. The element will be saved like this : \code <$(tagName) name = "$(property)">< value_as_XML ><$(tagName)/> \endcode */ static void savePropertyElement(QDomElement &parentNode, QDomDocument &domDoc, const QString &tagName, const QString &property, const QVariant &value); /*! Read an object property in the DOM doc. \param node the QDomNode of the property \param obj the widget whose property is being read \param name the name of the property being read */ static QVariant readPropertyValue(Form *form, QDomNode node, QObject *obj, const QString &name); /*! Write an object property in the DOM doc. \param item the widget item whose property is being saved \param parentNode the DOM document to write to \param name the name of the property being saved \param value the value of this property Properties of subwidget are saved with subwidget="true" arribute added to 'property' XML element. */ static void savePropertyValue(ObjectTreeItem *item, QDomElement &parentNode, QDomDocument &parent, const char *name, const QVariant &value); protected: /*! Saves the QVariant \a value as text to be included in an xml file, with \a parentNode.*/ static void writeVariant(QDomDocument &parent, QDomElement &parentNode, const QVariant& value); /*! Creates a toplevel widget from the QDomElement \a element in the Form \a form, with \a parent as parent widget. It calls readPropertyValue() and loadWidget() to load child widgets. */ static void createToplevelWidget(Form *form, QWidget *container, QDomElement &element); /*! \return the name of the pixmap saved, to use to access it This function save the QPixmap \a pixmap into the DOM document \a domDoc. The pixmap is converted to XPM and compressed for compatibility with Qt Designer. Encoding code is taken from Designer. */ static QString saveImage(QDomDocument &domDoc, const QPixmap &pixmap); /*! \return the loaded pixmap This function loads the pixmap named \a name in the DOM document \a domDoc. Decoding code is taken from QT Designer. */ //! @todo handle result of loading static QPixmap loadImage(QDomDocument domDoc, const QString& name); /*! Reads the child nodes of a "widget" element. */ static void readChildNodes(ObjectTreeItem *tree, Container *container, const QDomElement &el, QWidget *w, QHash *buddies); /*! Adds an include file name to be saved in the "includehints" part of .ui file, which is needed by uic. */ static void addIncludeFileName(const QString &include, QDomDocument &domDoc); private: //! This hash stores buddies associations until the Form is completely loaded. static QHash *m_buddies; }; } #endif diff --git a/src/formeditor/form_p.h b/src/formeditor/form_p.h index 9d3463c15..0ebc23eed 100644 --- a/src/formeditor/form_p.h +++ b/src/formeditor/form_p.h @@ -1,179 +1,179 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2014 Jarosław Staniek 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_P_H #define KFORMDESIGNERFORM_P_H #include #include #include #include "resizehandle.h" #include "commands.h" #include "form.h" //! @todo pixmapcollection #ifdef KEXI_PIXMAP_COLLECTIONS_SUPPORT #include "pixmapcollection.h" #endif #include #include #include class QStyleOption; namespace KFormDesigner { class ObjectTree; //! Used to alter the widget's style at design time class DesignModeStyle : public QProxyStyle { Q_OBJECT public: explicit DesignModeStyle(const QString &baseStyleName); //! Reimplemented to remove handling of the State_MouseOver state. virtual void drawControl(ControlElement element, const QStyleOption *option, - QPainter *p, const QWidget *w = 0) const; + QPainter *p, const QWidget *w = 0) const override; private: QStyleOption* alterOption(ControlElement element, const QStyleOption *option) const; }; //-------------- //! @internal class FormPrivate { public: FormPrivate(Form *form, WidgetLibrary* _library); ~FormPrivate(); void enableAction(const char* name, bool enable); void initPropertiesDescription(); QString propertyCaption(const QByteArray &name); QString valueCaption(const QByteArray &name); void addPropertyCaption(const QByteArray &property, const QString &caption); void addValueCaption(const QByteArray &value, const QString &caption); KPropertyListData* createValueList(WidgetInfo *winfo, const QStringList &list); //! Sets color of selected widget(s) to value of @a p. //! @a roleMethod can be backgroundColor or foregroundColor. //! Makes background inherited if @a roleMethod if background and value is null. void setColorProperty(KProperty& p, QPalette::ColorRole (QWidget::*roleMethod)() const, const QVariant& value); Form::Mode mode; Form::State state; Form::Features features; QPoint insertionPoint; QPointer toplevel; ObjectTree *topTree; QPointer widget; KPropertySet propertySet; QWidgetList selected; ResizeHandleSet::Hash resizeHandles; QByteArray selectedClass; bool modified; bool interactive; bool isUndoing; bool isRedoing; bool snapToGrid; int gridSize; QString filename; KUndo2Stack undoStack; KActionCollection internalCollection; KActionCollection *collection; KFormDesigner::ActionGroup* widgetActionGroup; ObjectTreeList tabstops; bool autoTabstops; #ifdef KFD_SIGSLOTS ConnectionBuffer *connBuffer; #endif #ifdef KEXI_PIXMAP_COLLECTIONS_SUPPORT PixmapCollection *pixcollection; #endif //! This map is used to store cursor shapes before inserting (so we can restore them later) QHash cursors; //! This string list is used to store the widgets which hasMouseTracking() == true (eg lineedits) QStringList *mouseTrackers; FormWidget *formWidget; //! A set of head properties to be stored in a .ui file. //! This includes KFD format version. QHash headerProperties; //! Format version, set by FormIO or on creating a new form. QString formatVersion; //! Format version, set by FormIO's loader or on creating a new form. QString originalFormatVersion; #ifdef KFD_SIGSLOTS //! true if slot connection is curently being painted Connection *connection; #endif //! used to update command's value when undoing PropertyCommand *lastCommand; PropertyCommandGroup *lastCommandGroup; int idOfPropertyCommand; bool slotPropertyChangedEnabled; bool slotPropertyChanged_addCommandEnabled; bool insideAddPropertyCommand; bool selectWidgetEnabled; // i18n stuff QMap propCaption; QMap propValCaption; QStyle *designModeStyle; QPointer inlineEditor; QPointer inlineEditorContainer; QByteArray editedWidgetClass; QString originalInlineText; bool pixmapsStoredInline; WidgetLibrary * const library; private: Form *q; }; } #endif diff --git a/src/formeditor/kexiactionselectiondialog.cpp b/src/formeditor/kexiactionselectiondialog.cpp index 972969062..ee9b210f1 100644 --- a/src/formeditor/kexiactionselectiondialog.cpp +++ b/src/formeditor/kexiactionselectiondialog.cpp @@ -1,771 +1,771 @@ /* This file is part of the KDE project Copyright (C) 2005-2006 Jarosław Staniek Copyright (C) 2012 Adam Pigg 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. */ #include "kexiactionselectiondialog.h" #include "kexiactionselectiondialog_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class ActionSelectorDialogTreeItem : public QTreeWidgetItem { public: enum ActionRole{ ActionCategoryRole = Qt::UserRole + 1, ActionDataRole, ActionPluginIdRole }; ActionSelectorDialogTreeItem(const QString &label, QTreeWidget *parent) : QTreeWidgetItem(parent) { setText(0, label); } ActionSelectorDialogTreeItem(const QString &label, QTreeWidgetItem *parent) : QTreeWidgetItem(parent) { setText(0, label); } using QTreeWidgetItem::data; QVariant data(ActionRole role) const { return QTreeWidgetItem::data(0, role); }; using QTreeWidgetItem::setData; void setData(ActionRole role, const QVariant &value) { QTreeWidgetItem::setData(0, role, value); } QIcon icon() const { return QTreeWidgetItem::icon(0); } void setIcon(const QIcon& icon) { QTreeWidgetItem::setIcon(0, icon); } }; //--------------------------------------- ActionsListViewBase::ActionsListViewBase(QWidget* parent) : QTreeWidget(parent) { setColumnCount(1); setHeaderHidden(true); setRootIsDecorated(false); } ActionsListViewBase::~ActionsListViewBase() { } QTreeWidgetItem *ActionsListViewBase::itemForAction(const QString& actionName, QTreeWidgetItem* parent) { Q_UNUSED(parent); QTreeWidgetItemIterator it(this); while (*it) { ActionSelectorDialogTreeItem* itm = dynamic_cast(*it); if (itm && itm->data(ActionSelectorDialogTreeItem::ActionDataRole).toString() == actionName) return itm; ++it; } return 0; } void ActionsListViewBase::selectAction(const QString& actionName) { //qDebug() << "Selecting action:" << actionName; QTreeWidgetItem *itm = itemForAction(actionName); if (itm) { setCurrentItem(itm); itm->setSelected(true); } } //--------------------------------------- KActionsListViewBase::KActionsListViewBase(QWidget* parent) : ActionsListViewBase(parent) { } KActionsListViewBase::~KActionsListViewBase() {} void KActionsListViewBase::init() { const QPixmap noIcon(KexiUtils::emptyIcon(KIconLoader::Small)); QList sharedActions(KexiMainWindowIface::global()->allActions()); const Kexi::ActionCategories *acat = Kexi::actionCategories(); foreach(QAction *action, sharedActions) { // qDebug() << (*it)->name() << " " << (*it)->text(); //! @todo group actions //! @todo: store QAction * here? const int actionCategories = acat->actionCategories(action->objectName().toLatin1()); if (actionCategories == -1) { qWarning() << "no category declared for action \"" << action->objectName() << "\"! Fix this!"; continue; } if (!isActionVisible(action->objectName().toLatin1(), actionCategories)) continue; QString actionName; if (!action->toolTip().isEmpty()) { actionName = action->toolTip().remove("").remove(""); } else { actionName = action->text().remove('&'); } ActionSelectorDialogTreeItem *pitem = new ActionSelectorDialogTreeItem( actionName, this); pitem->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "kaction"); pitem->setData(ActionSelectorDialogTreeItem::ActionDataRole, action->objectName()); pitem->setIcon(action->icon()); if (pitem->icon().isNull()) pitem->setIcon(noIcon); } setSortingEnabled(true); } //--------------------------------------- //! @internal Used to display KActions (in column 2) class KActionsListView : public KActionsListViewBase { Q_OBJECT public: explicit KActionsListView(QWidget* parent) : KActionsListViewBase(parent) { } virtual ~KActionsListView() {} - virtual bool isActionVisible(const char* actionName, int actionCategories) const { + virtual bool isActionVisible(const char* actionName, int actionCategories) const override { Q_UNUSED(actionName); return actionCategories & Kexi::GlobalActionCategory; } }; //! @internal Used to display KActions (in column 2) class CurrentFormActionsListView : public KActionsListViewBase { Q_OBJECT public: explicit CurrentFormActionsListView(QWidget* parent) : KActionsListViewBase(parent) { } virtual ~CurrentFormActionsListView() {} - virtual bool isActionVisible(const char* actionName, int actionCategories) const { + virtual bool isActionVisible(const char* actionName, int actionCategories) const override { return actionCategories & Kexi::WindowActionCategory && Kexi::actionCategories()->actionSupportsObjectType(actionName, KexiPart::FormObjectType); } }; //! @internal a list view displaying action categories user can select from (column 1) class ActionCategoriesListView : public ActionsListViewBase { Q_OBJECT public: explicit ActionCategoriesListView(QWidget* parent) : ActionsListViewBase(parent) { ActionSelectorDialogTreeItem *itm = new ActionSelectorDialogTreeItem(xi18n("No action"), this ); itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "noaction"); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, "noaction"); const QPixmap noIcon(KexiUtils::emptyIcon(KIconLoader::Small)); itm->setIcon(noIcon); itm = new ActionSelectorDialogTreeItem(xi18n("Application actions"), this ); itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "kaction"); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, "kaction"); itm->setIcon(koIcon("kexi")); KexiPart::PartInfoList *pl = Kexi::partManager().infoList(); if (pl) { foreach(KexiPart::Info *info, *pl) { KexiPart::Part *part = Kexi::partManager().part(info); if (!info->isVisibleInNavigator() || !part) continue; itm = new ActionSelectorDialogTreeItem(part->info()->name(), this ); itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "navObject"); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, info->typeName()); itm->setData(ActionSelectorDialogTreeItem::ActionPluginIdRole, info->pluginId()); itm->setIcon(QIcon::fromTheme(part->info()->iconName())); } } QTreeWidgetItem *fitm = itemForAction("form"); if (fitm) { itm = new ActionSelectorDialogTreeItem(xi18nc("Current form's actions", "Current"), fitm); } else { itm = new ActionSelectorDialogTreeItem(xi18nc("Current form's actions", "Current"), this); } itm->setData(ActionSelectorDialogTreeItem::ActionCategoryRole, "currentForm"); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole, "currentForm"); itm->setIcon(KexiIcon("form")); expandAll(); setSortingEnabled(false); } ~ActionCategoriesListView() { } }; //! @internal Used to display list of actions available to executing (column 3) class ActionToExecuteListView : public ActionsListViewBase { Q_OBJECT public: explicit ActionToExecuteListView(QWidget* parent) : ActionsListViewBase(parent) { } ~ActionToExecuteListView() { } //! Updates actions void showActionsForPluginId(const QString& pluginId) { if (m_currentPluginId == pluginId) return; m_currentPluginId = pluginId; clear(); KexiPart::Part *part = Kexi::partManager().partForPluginId(m_currentPluginId); if (!part) return; Kexi::ViewModes supportedViewModes = part->info()->supportedViewModes(); ActionSelectorDialogTreeItem *itm; const QPixmap noIcon(KexiUtils::emptyIcon(KIconLoader::Small)); if (supportedViewModes & Kexi::DataViewMode) { itm = new ActionSelectorDialogTreeItem(xi18n("Open in Data View"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "open"); itm->setIcon(koIcon("document-open")); } if (part->info()->isExecuteSupported()) { itm = new ActionSelectorDialogTreeItem(xi18n("Execute"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "execute"); itm->setIcon(koIcon("media-playback-start")); } #ifdef KEXI_QUICK_PRINTING_SUPPORT if (part->info()->isPrintingSupported()) { itm = new ActionSelectorDialogTreeItem(futureI18n("Print"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "print"); itm->setIcon(koIcon("document-print")); QAction *a = KStandardAction::printPreview(0, 0, 0); itm = new ActionSelectorDialogTreeItem(a->text().remove('&').remove("..."), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "printPreview"); itm->setIcon(a->icon()); delete a; itm = new ActionSelectorDialogTreeItem(futureI18n("Show Page Setup"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "pageSetup"); itm->setIcon(noIcon); setItemExpanded(itm, true); } #endif if (part->info()->isDataExportSupported()) { itm = new ActionSelectorDialogTreeItem( xi18nc("Note: use multiple rows if needed", "Export to File\nAs Data Table"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "exportToCSV"); itm->setIcon(KexiIcon("table")); QTreeWidgetItem *eitem = itm; itm = new ActionSelectorDialogTreeItem(xi18nc("Note: use multiple rows if needed", "Copy to Clipboard\nAs Data Table"), eitem); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "copyToClipboardAsCSV"); itm->setIcon(KexiIcon("table")); } itm = new ActionSelectorDialogTreeItem(xi18n("Create New Object (%1)", part->info()->name().toLower()), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "new"); itm->setIcon(koIcon("document-new")); if (supportedViewModes & Kexi::DesignViewMode) { itm = new ActionSelectorDialogTreeItem(xi18n("Open in Design View"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "design"); itm->setIcon(koIcon("document-properties")); } if (supportedViewModes & Kexi::TextViewMode) { itm = new ActionSelectorDialogTreeItem(xi18n("Open in Text View"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "editText"); itm->setIcon(noIcon); } itm = new ActionSelectorDialogTreeItem( xi18n("Close View"), this); itm->setData(ActionSelectorDialogTreeItem::ActionDataRole , "close"); itm->setIcon(koIcon("window-close")); expandAll(); setSortingEnabled(true); } QString m_currentPluginId; }; //------------------------------------- //! @internal class Q_DECL_HIDDEN KexiActionSelectionDialog::Private { public: Private() : kactionPageWidget(0), kactionListView(0), objectsListView(0) , currentFormActionsPageWidget(0) , currentFormActionsListView(0) , secondAnd3rdColumnMainWidget(0) , hideActionToExecuteListView(false) { } void raiseWidget(QWidget *w) { secondAnd3rdColumnStack->setCurrentWidget(w); } QString selectActionToBeExecutedMessage(const QString& actionType) const { if (actionType == "noaction") return QString(); if (actionType == "kaction" || actionType == "currentForm") return xi18n("&Select action to be executed after clicking %1 button:", actionWidgetName); // hardcoded, but it's not that bad if (actionType == "org.kexi-project.macro") return xi18n("&Select macro to be executed after clicking %1 button:", actionWidgetName); if (actionType == "org.kexi-project.script") return xi18n("&Select script to be executed after clicking %1 button:", actionWidgetName); //default: org.kexi-project.table/query/form/report... return xi18n("&Select object to be opened after clicking %1 button:", actionWidgetName); } // changes 3rd column visibility void setActionToExecuteSectionVisible(bool visible) { actionToExecuteListView->setVisible(visible); actionToExecuteLbl->setVisible(visible); } QString actionWidgetName; ActionCategoriesListView* actionCategoriesListView; //!< for column #1 QWidget *kactionPageWidget; KActionsListView* kactionListView; //!< for column #2 KexiProjectNavigator* objectsListView; //!< for column #2 QWidget *currentFormActionsPageWidget; //!< for column #2 CurrentFormActionsListView* currentFormActionsListView; //!< for column #2 QWidget *emptyWidget; QLabel *selectActionToBeExecutedLabel; QLabel *kactionPageLabel; QLabel *currentFormActionsPageLabel; ActionToExecuteListView* actionToExecuteListView; QLabel *actionToExecuteLbl; QWidget *secondAnd3rdColumnMainWidget; QGridLayout *glyr; QGridLayout *secondAnd3rdColumnGrLyr; QStackedWidget *secondAnd3rdColumnStack; //, *secondColumnStack; bool hideActionToExecuteListView; QDialogButtonBox *buttonBox; }; //------------------------------------- static QLabel *createSelectActionLabel(QWidget *parent, QWidget *buddy) { QLabel *lbl = new QLabel(parent); lbl->setBuddy(buddy); lbl->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); lbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); lbl->setWordWrap(true); lbl->setMinimumHeight(lbl->fontMetrics().height()*2); return lbl; } //------------------------------------- KexiActionSelectionDialog::KexiActionSelectionDialog( QWidget *parent, const KexiFormEventAction::ActionData& action, const QString& actionWidgetName) : QDialog(parent) , d(new Private()) { setModal(true); setObjectName("actionSelectorDialog"); setWindowTitle(xi18nc("@title:window", "Assigning Action to Button")); // layout QVBoxLayout *mainLayout = new QVBoxLayout; setLayout(mainLayout); QWidget *mainWidget = new QWidget(this); mainWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); mainLayout->addWidget(mainWidget); /* lbl 1 +------------+ +-------------------------------+ | | | [a] | | 1st column | | +----------- + +------------+ | | | | | 2nd column | | 3rd column | | | | | + + + + | | | | +------------+ +------------+ | +------------+ +-------------------------------+ \______________________________________________/ glyr [a]- QStackedWidget *secondAnd3rdColumnStack, - for displaying KActions, the stack contains d->kactionPageWidget QWidget - for displaying objects, the stack contains secondAnd3rdColumnMainWidget QWidget and QGridLayout *secondAnd3rdColumnGrLyr - kactionPageWidget contains only a QVBoxLayout and label+kactionListView */ d->glyr = new QGridLayout(mainWidget); // 2x2 KexiUtils::setStandardMarginsAndSpacing(d->glyr); d->glyr->setRowStretch(1, 1); // 1st column: action types d->actionCategoriesListView = new ActionCategoriesListView(mainWidget); d->actionCategoriesListView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); d->glyr->addWidget(d->actionCategoriesListView, 1, 0); connect(d->actionCategoriesListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(slotActionCategorySelected(QTreeWidgetItem*))); QLabel *lbl = new QLabel(xi18n("Action category:"), mainWidget); lbl->setBuddy(d->actionCategoriesListView); lbl->setMinimumHeight(lbl->fontMetrics().height()*2); lbl->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); lbl->setAlignment(Qt::AlignTop | Qt::AlignLeft); lbl->setWordWrap(true); d->glyr->addWidget(lbl, 0, 0, Qt::AlignTop | Qt::AlignLeft); // widget stack for 2nd and 3rd column d->secondAnd3rdColumnStack = new QStackedWidget(mainWidget); d->secondAnd3rdColumnStack->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); d->glyr->addWidget(d->secondAnd3rdColumnStack, 0, 1, 2, 1); d->secondAnd3rdColumnMainWidget = new QWidget(d->secondAnd3rdColumnStack); d->secondAnd3rdColumnMainWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); d->secondAnd3rdColumnGrLyr = new QGridLayout(d->secondAnd3rdColumnMainWidget); //! @todo KEXI3 QDialog::resizeLayout(d->secondAnd3rdColumnGrLyr, 0, KexiUtils::spacingHint()); d->secondAnd3rdColumnGrLyr->setRowStretch(1, 2); d->secondAnd3rdColumnStack->addWidget(d->secondAnd3rdColumnMainWidget); // 2nd column: list of actions/objects d->objectsListView = new KexiProjectNavigator(d->secondAnd3rdColumnMainWidget, KexiProjectNavigator::Borders); d->secondAnd3rdColumnGrLyr->addWidget(d->objectsListView, 1, 0); d->secondAnd3rdColumnGrLyr->setColumnStretch(0,1); d->secondAnd3rdColumnGrLyr->setColumnStretch(1,1); connect(d->objectsListView, SIGNAL(selectionChanged(KexiPart::Item*)), this, SLOT(slotItemForOpeningOrExecutingSelected(KexiPart::Item*))); d->selectActionToBeExecutedLabel = createSelectActionLabel(d->secondAnd3rdColumnMainWidget, 0); d->secondAnd3rdColumnGrLyr->addWidget( d->selectActionToBeExecutedLabel, 0, 0, Qt::AlignTop | Qt::AlignLeft); d->emptyWidget = new QWidget(d->secondAnd3rdColumnStack); d->secondAnd3rdColumnStack->addWidget(d->emptyWidget); // 3rd column: actions to execute d->actionToExecuteListView = new ActionToExecuteListView(d->secondAnd3rdColumnMainWidget); d->actionToExecuteListView->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); connect(d->actionToExecuteListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotActionToExecuteItemExecuted(QTreeWidgetItem*))); connect(d->actionToExecuteListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(slotActionToExecuteItemSelected(QTreeWidgetItem*))); d->secondAnd3rdColumnGrLyr->addWidget(d->actionToExecuteListView, 1, 1); d->actionToExecuteLbl = createSelectActionLabel(d->secondAnd3rdColumnMainWidget, d->actionToExecuteListView); d->actionToExecuteLbl->setText(xi18n("Action to execute:")); d->secondAnd3rdColumnGrLyr->addWidget(d->actionToExecuteLbl, 0, 1, Qt::AlignTop | Qt::AlignLeft); // buttons d->buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); QPushButton *okButton = d->buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); connect(d->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(d->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); d->actionWidgetName = actionWidgetName; d->buttonBox->button(QDialogButtonBox::Ok)->setText(xi18nc("Assign action", "&Assign")); //buttonBox->button(QDialogButtonBox::Ok)->setIcon(koIconName("dialog-ok")); d->buttonBox->button(QDialogButtonBox::Ok)->setToolTip(xi18n("Assign action")); mainLayout->addWidget(d->buttonBox); // temporary show all sections to avoid resizing the dialog in the future d->actionCategoriesListView->selectAction("table"); d->setActionToExecuteSectionVisible(true); adjustSize(); resize(qMax(700, width()), qMax(450, height())); bool ok; QString actionType, actionArg; KexiPart::Info* partInfo = action.decodeString(actionType, actionArg, &ok); if (ok) { d->actionCategoriesListView->selectAction(actionType); if (actionType == "kaction") { d->kactionListView->selectAction(actionArg); d->kactionListView->setFocus(); } else if (actionType == "currentForm") { d->currentFormActionsListView->selectAction(actionArg); d->currentFormActionsListView->setFocus(); } else if (partInfo && Kexi::partManager().part(partInfo)) // We use the Part Manager // to determine whether the Kexi-plugin is installed and whether we like to show // it in our list of actions. { KexiPart::Item *item = KexiMainWindowIface::global()->project()->item( partInfo, actionArg); if (d->objectsListView && item) { d->objectsListView->selectItem(*item); slotItemForOpeningOrExecutingSelected(item); QString actionOption(action.option); if (actionOption.isEmpty()) { actionOption = "open"; // for backward compatibility } d->actionToExecuteListView->selectAction(actionOption); d->objectsListView->setFocus(); } } } else {//invalid assignment or 'noaction' d->actionCategoriesListView->selectAction("noaction"); d->actionCategoriesListView->setFocus(); } } KexiActionSelectionDialog::~KexiActionSelectionDialog() { delete d; } void KexiActionSelectionDialog::slotKActionItemExecuted(QTreeWidgetItem*) { accept(); } void KexiActionSelectionDialog::slotKActionItemSelected(QTreeWidgetItem*) { d->setActionToExecuteSectionVisible(false); updateOKButtonStatus(); } void KexiActionSelectionDialog::slotCurrentFormActionItemExecuted(QTreeWidgetItem*) { accept(); } void KexiActionSelectionDialog::slotCurrentFormActionItemSelected(QTreeWidgetItem*) { d->setActionToExecuteSectionVisible(false); updateOKButtonStatus(); } void KexiActionSelectionDialog::slotItemForOpeningOrExecutingSelected(KexiPart::Item* item) { d->setActionToExecuteSectionVisible(item); } void KexiActionSelectionDialog::slotActionToExecuteItemExecuted(QTreeWidgetItem* item) { if (!item) return; ActionSelectorDialogTreeItem *listItem = dynamic_cast(item); if (listItem && listItem->data(ActionSelectorDialogTreeItem::ActionDataRole).isValid()) accept(); } void KexiActionSelectionDialog::slotActionToExecuteItemSelected(QTreeWidgetItem*) { updateOKButtonStatus(); } void KexiActionSelectionDialog::slotActionCategorySelected(QTreeWidgetItem* item) { ActionSelectorDialogTreeItem *categoryItm = dynamic_cast(item); // simple case: part-less item, e.g. kaction: if (categoryItm) { if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "kaction") { if (!d->kactionPageWidget) { //create lbl+list view with a vlayout d->kactionPageWidget = new QWidget(); d->kactionPageWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); QVBoxLayout *vlyr = new QVBoxLayout(d->kactionPageWidget); vlyr->setSpacing(KexiUtils::spacingHint()); d->kactionListView = new KActionsListView(d->kactionPageWidget); d->kactionListView->init(); d->kactionPageLabel = createSelectActionLabel(d->kactionPageWidget, d->kactionListView); vlyr->addWidget(d->kactionPageLabel); vlyr->addWidget(d->kactionListView); KexiUtils::setMargins(vlyr, 0); d->secondAnd3rdColumnStack->addWidget(d->kactionPageWidget); connect(d->kactionListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotKActionItemExecuted(QTreeWidgetItem*))); connect(d->kactionListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(slotKActionItemSelected(QTreeWidgetItem*))); } d->kactionPageLabel->setText( d->selectActionToBeExecutedMessage(categoryItm->data(ActionSelectorDialogTreeItem::ActionDataRole).toString())); d->setActionToExecuteSectionVisible(false); d->raiseWidget(d->kactionPageWidget); slotKActionItemSelected(d->kactionListView->currentItem()); //to refresh column #3 } else if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "currentForm") { if (!d->currentFormActionsPageWidget) { //create lbl+list view with a vlayout d->currentFormActionsPageWidget = new QWidget(); d->currentFormActionsPageWidget->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum); QVBoxLayout *vlyr = new QVBoxLayout(d->currentFormActionsPageWidget); vlyr->setSpacing(KexiUtils::spacingHint()); d->currentFormActionsListView = new CurrentFormActionsListView( d->currentFormActionsPageWidget); d->currentFormActionsListView->init(); d->currentFormActionsPageLabel = createSelectActionLabel( d->currentFormActionsPageWidget, d->currentFormActionsListView); vlyr->addWidget(d->currentFormActionsPageLabel); vlyr->addWidget(d->currentFormActionsListView); d->secondAnd3rdColumnStack->addWidget(d->currentFormActionsPageWidget); KexiUtils::setMargins(vlyr, 0); connect(d->currentFormActionsListView, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotCurrentFormActionItemExecuted(QTreeWidgetItem*))); connect(d->currentFormActionsListView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(slotCurrentFormActionItemSelected(QTreeWidgetItem*))); } d->currentFormActionsPageLabel->setText( d->selectActionToBeExecutedMessage(categoryItm->data(ActionSelectorDialogTreeItem::ActionDataRole).toString())); d->setActionToExecuteSectionVisible(false); d->raiseWidget(d->currentFormActionsPageWidget); slotCurrentFormActionItemSelected(d->currentFormActionsListView->currentItem()); //to refresh column #3 } else if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "noaction") { d->raiseWidget(d->emptyWidget); d->objectsListView->clearSelection(); //hide column #3 d->setActionToExecuteSectionVisible(false); } else if (categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "navObject") { QString pluginId = categoryItm->data(ActionSelectorDialogTreeItem::ActionPluginIdRole).toString(); d->selectActionToBeExecutedLabel->setText(d->selectActionToBeExecutedMessage(pluginId)); if (d->objectsListView->itemsPluginId() != pluginId) { QString errorString; d->objectsListView->setProject(KexiMainWindowIface::global()->project(), pluginId, &errorString, false); d->actionToExecuteListView->showActionsForPluginId(pluginId); d->setActionToExecuteSectionVisible(false); } if (d->secondAnd3rdColumnStack->currentWidget() != d->secondAnd3rdColumnMainWidget) { d->raiseWidget(d->secondAnd3rdColumnMainWidget); d->objectsListView->clearSelection(); d->setActionToExecuteSectionVisible(false); } else { d->raiseWidget(d->secondAnd3rdColumnMainWidget); } d->selectActionToBeExecutedLabel->setBuddy(d->secondAnd3rdColumnMainWidget); } d->actionCategoriesListView->update(); updateOKButtonStatus(); return; } d->actionCategoriesListView->update(); d->actionToExecuteListView->update(); updateOKButtonStatus(); } KexiFormEventAction::ActionData KexiActionSelectionDialog::currentAction() const { KexiFormEventAction::ActionData data; ActionSelectorDialogTreeItem *categoryItm = dynamic_cast(d->actionCategoriesListView->currentItem()); if (categoryItm) { const QString actionCategory = categoryItm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString(); if (actionCategory == "kaction") { const ActionSelectorDialogTreeItem* actionToExecute = dynamic_cast( d->kactionListView->currentItem()); if (actionToExecute) { data.string = QString("kaction:") + actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString(); return data; } } else if (actionCategory == "currentForm") { const ActionSelectorDialogTreeItem *actionToExecute = dynamic_cast( d->currentFormActionsListView->currentItem()); if (actionToExecute) { data.string = QString("currentForm:") + actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString(); return data; } } else if (actionCategory == "noaction") { return data; } else if (actionCategory == "navObject") { const ActionSelectorDialogTreeItem *actionToExecute = dynamic_cast( d->actionToExecuteListView->currentItem()); if (d->objectsListView && actionToExecute && !actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString().isEmpty()) { KexiPart::Item* partItem = d->objectsListView->selectedPartItem(); KexiPart::Info* partInfo = partItem ? Kexi::partManager().infoForPluginId(partItem->pluginId()) : 0; if (partInfo) { // opening or executing: table:name, query:name, form:name, macro:name, script:name, etc. data.string = QString("%1:%2").arg(partInfo->typeName()).arg(partItem->name()); data.option = actionToExecute->data(ActionSelectorDialogTreeItem::ActionDataRole).toString(); return data; } } } else { qWarning() << "No current category item"; } } return data; // No Action } void KexiActionSelectionDialog::updateOKButtonStatus() { ActionSelectorDialogTreeItem *itm = dynamic_cast(d->actionCategoriesListView->currentItem()); //qDebug() << "Current Action:" << currentAction().string << ":" << currentAction().option; QPushButton *btn = d->buttonBox->button(QDialogButtonBox::Ok); btn->setEnabled((itm && itm->data(ActionSelectorDialogTreeItem::ActionCategoryRole).toString() == "noaction") || !currentAction().isEmpty()); } #include "kexiactionselectiondialog.moc" diff --git a/src/formeditor/libactionwidget.h b/src/formeditor/libactionwidget.h index 0c833efb8..b666ae9be 100644 --- a/src/formeditor/libactionwidget.h +++ b/src/formeditor/libactionwidget.h @@ -1,65 +1,65 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004-2009 Jarosław Staniek 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 LIBACTIONWIDGET_H #define LIBACTIONWIDGET_H #include "kformdesigner_export.h" #include "utils.h" #include namespace KFormDesigner { class WidgetInfo; /** * KToggleAction subclass which remembers the matching class name. */ class KFORMDESIGNER_EXPORT LibActionWidget : public KToggleAction { Q_OBJECT public: /** LibActionWidget object is initialized to be mutually exclusive with all other LibActionWidget objects for group @a group. */ LibActionWidget(ActionGroup *group, WidgetInfo *w); virtual ~LibActionWidget(); Q_SIGNALS: /** * emits a signal containing the class name */ void toggled(const QByteArray &className); protected Q_SLOTS: /** reimplemented from KToggleAction */ - virtual void slotToggled(bool checked); + virtual void slotToggled(bool checked) override; private: class Private; Private* const d; }; } #endif diff --git a/src/formeditor/resizehandle.cpp b/src/formeditor/resizehandle.cpp index fe08d0bcc..e8add81fb 100644 --- a/src/formeditor/resizehandle.cpp +++ b/src/formeditor/resizehandle.cpp @@ -1,386 +1,386 @@ /* This file is part of the KDE libraries Copyright (C) 2002 Joseph Wenninger Copyright (C) 2004 Cedric Pasteur Copyright (C) 2009 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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. */ #include "resizehandle.h" #include "form.h" #include "container.h" #include "widgetfactory.h" #include "widgetlibrary.h" #include #include #include #include #define MINIMUM_WIDTH 10 #define MINIMUM_HEIGHT 10 using namespace KFormDesigner; namespace KFormDesigner { /** * A single widget which represents a small rectangle for resizing a form widget. */ class KFORMDESIGNER_EXPORT ResizeHandle : public QWidget { Q_OBJECT public: enum HandlePos { TopLeftCorner = 1, TopCenter = 2, TopRightCorner = 4, LeftCenter = 8, RightCenter = 16, BottomLeftCorner = 32, BottomCenter = 64, BottomRightCorner = 128 }; ResizeHandle(ResizeHandleSet *set, HandlePos pos); virtual ~ResizeHandle(); void setEditingMode(bool editing); protected: - virtual void mousePressEvent(QMouseEvent *ev); - virtual void mouseMoveEvent(QMouseEvent *ev); - virtual void mouseReleaseEvent(QMouseEvent *ev); - virtual void paintEvent(QPaintEvent *ev); + virtual void mousePressEvent(QMouseEvent *ev) override; + virtual void mouseMoveEvent(QMouseEvent *ev) override; + virtual void mouseReleaseEvent(QMouseEvent *ev) override; + virtual void paintEvent(QPaintEvent *ev) override; protected Q_SLOTS: - bool eventFilter(QObject *obj, QEvent *ev); + bool eventFilter(QObject *obj, QEvent *ev) override; void updatePos(); private: class Private; Private* const d; }; class Q_DECL_HIDDEN ResizeHandle::Private { public: Private(ResizeHandleSet* set_, HandlePos pos_) : set(set_), pos(pos_), dragging(false), x(0), y(0) {} ~Private() {} ResizeHandleSet *set; HandlePos pos; bool dragging; int x; int y; }; } ResizeHandle::ResizeHandle(ResizeHandleSet *set, HandlePos pos) : QWidget(set->widget()->parentWidget()), d(new Private(set, pos)) { setFixedSize(6, 6); d->set->widget()->installEventFilter(this); setAutoFillBackground(true); updatePos(); setEditingMode(false); show(); } ResizeHandle::~ResizeHandle() { delete d; } void ResizeHandle::setEditingMode(bool editing) { QPalette pal(palette()); pal.setBrush(backgroundRole(), editing ? QBrush(Qt::blue) : pal.text()); setPalette(pal); } void ResizeHandle::updatePos() { switch (d->pos) { case TopLeftCorner: move(d->set->widget()->x() - 3, d->set->widget()->y() - 3); setCursor(QCursor(Qt::SizeFDiagCursor)); break; case TopCenter: move(d->set->widget()->x() + d->set->widget()->width() / 2 - 3, d->set->widget()->y() - 3); setCursor(QCursor(Qt::SizeVerCursor)); break; case TopRightCorner: move(d->set->widget()->x() + d->set->widget()->width() - 3, d->set->widget()->y() - 3); setCursor(QCursor(Qt::SizeBDiagCursor)); break; case LeftCenter: move(d->set->widget()->x() - 3, d->set->widget()->y() + d->set->widget()->height() / 2 - 3); setCursor(QCursor(Qt::SizeHorCursor)); break; case RightCenter: move(d->set->widget()->x() + d->set->widget()->width() - 3, d->set->widget()->y() + d->set->widget()->height() / 2 - 3); setCursor(QCursor(Qt::SizeHorCursor)); break; case BottomLeftCorner: move(d->set->widget()->x() - 3, d->set->widget()->y() + d->set->widget()->height() - 3); setCursor(QCursor(Qt::SizeBDiagCursor)); break; case BottomCenter: move(d->set->widget()->x() + d->set->widget()->width() / 2 - 3, d->set->widget()->y() + d->set->widget()->height() - 3); setCursor(QCursor(Qt::SizeVerCursor)); break; case BottomRightCorner: move(d->set->widget()->x() + d->set->widget()->width() - 3, d->set->widget()->y() + d->set->widget()->height() - 3); setCursor(QCursor(Qt::SizeFDiagCursor)); break; } } bool ResizeHandle::eventFilter(QObject *o, QEvent *ev) { if (((ev->type() == QEvent::Move) || (ev->type() == QEvent::Resize)) && o == d->set->widget()) { updatePos(); } return false; } void ResizeHandle::mousePressEvent(QMouseEvent *ev) { if (ev->button() != Qt::LeftButton) return; const bool startDragging = !d->dragging; d->dragging = true; d->x = ev->x(); d->y = ev->y(); if (startDragging) { d->set->resizeStarted(); d->set->form()->resetInlineEditor(); emit d->set->geometryChangeStarted(); } } void ResizeHandle::mouseMoveEvent(QMouseEvent *ev) { int gridX = d->set->form()->gridSize(); int gridY = d->set->form()->gridSize(); if (!d->dragging) return; int tmpx = d->set->widget()->x(); int tmpy = d->set->widget()->y(); int tmpw = d->set->widget()->width(); int tmph = d->set->widget()->height(); int dummyx = ev->x() - d->x; int dummyy = ev->y() - d->y; if ( d->set->form()->isSnapToGridEnabled() && ev->buttons() == Qt::LeftButton && ev->modifiers() != (Qt::ControlModifier | Qt::AltModifier)) { dummyx = alignValueToGrid(dummyx, gridX); dummyy = alignValueToGrid(dummyy, gridY); } switch (d->pos) { case TopRightCorner: tmpw += dummyx; tmpy += dummyy; tmph -= dummyy; break; case RightCenter: tmpw += dummyx; break; case BottomRightCorner: tmpw += dummyx; tmph += dummyy; break; case TopCenter: tmpy += dummyy; tmph -= dummyy; break; case BottomCenter: tmph = tmph + dummyy; break; case TopLeftCorner: tmpx += dummyx; tmpw -= dummyx; tmpy += dummyy; tmph -= dummyy; break; case LeftCenter: tmpx += dummyx; tmpw -= dummyx; break; case BottomLeftCorner: tmpx += dummyx; tmpw -= dummyx; tmph += dummyy; break; } // Do not move the top-left corner further than the bottom-right corner if (tmpx >= d->set->widget()->x() + d->set->widget()->width()) { tmpx = d->set->widget()->x() + d->set->widget()->width() - MINIMUM_WIDTH; tmpw = MINIMUM_WIDTH; } if (tmpy >= d->set->widget()->y() + d->set->widget()->height()) { tmpy = d->set->widget()->y() + d->set->widget()->height() - MINIMUM_HEIGHT; tmph = MINIMUM_HEIGHT; } // Do not resize a widget outside of parent boundaries if (tmpx < 0) { tmpw += tmpx; tmpx = 0; } else if (tmpx + tmpw > d->set->widget()->parentWidget()->width()) { tmpw = d->set->widget()->parentWidget()->width() - tmpx; } if (tmpy < 0) { tmph += tmpy; tmpy = 0; } else if (tmpy + tmph > d->set->widget()->parentWidget()->height()) { tmph = d->set->widget()->parentWidget()->height() - tmpy; } const bool shouldBeMoved = (tmpx != d->set->widget()->x()) || (tmpy != d->set->widget()->y()); const bool shouldBeResized = (tmpw != d->set->widget()->width()) || (tmph != d->set->widget()->height()); if (shouldBeMoved && shouldBeResized) { d->set->widget()->hide(); } // Resize it if (shouldBeResized) { // Keep a QSize(10, 10) minimum size tmpw = (tmpw < MINIMUM_WIDTH) ? MINIMUM_WIDTH : tmpw; tmph = (tmph < MINIMUM_HEIGHT) ? MINIMUM_HEIGHT : tmph; } //qDebug() << "geometry: OLD" << d->set->widget()->geometry() << "NEW" << QRect(tmpx, tmpy, tmpw, tmph); emit d->set->geometryChanged(QRect(tmpx, tmpy, tmpw, tmph)); if (shouldBeMoved && shouldBeResized) { d->set->widget()->show(); } } void ResizeHandle::mouseReleaseEvent(QMouseEvent *) { d->dragging = false; d->set->resizeFinished(); } void ResizeHandle::paintEvent(QPaintEvent *) { } /////////////// ResizeHandleSet ////////////////// class Q_DECL_HIDDEN ResizeHandleSet::Private { public: Private(); ~Private() {} QRect origWidgetRect; QPointer handles[8]; QPointer widget; QPointer
form; }; ResizeHandleSet::Private::Private() : widget(0) { } ResizeHandleSet::ResizeHandleSet(QWidget *modify, Form *form) : QObject(modify->parentWidget()), d(new Private) { d->form = form; setWidget(modify); } ResizeHandleSet::~ResizeHandleSet() { for (int i = 0; i < 8; i++) delete d->handles[i]; delete d; } void ResizeHandleSet::setWidget(QWidget *modify) { if (modify == d->widget) return; if (d->widget) { for (int i = 0; i < 8; i++) delete d->handles[i]; } d->widget = modify; d->handles[0] = new ResizeHandle(this, ResizeHandle::TopLeftCorner); d->handles[1] = new ResizeHandle(this, ResizeHandle::TopCenter); d->handles[2] = new ResizeHandle(this, ResizeHandle::TopRightCorner); d->handles[3] = new ResizeHandle(this, ResizeHandle::LeftCenter); d->handles[4] = new ResizeHandle(this, ResizeHandle::RightCenter); d->handles[5] = new ResizeHandle(this, ResizeHandle::BottomLeftCorner); d->handles[6] = new ResizeHandle(this, ResizeHandle::BottomCenter); d->handles[7] = new ResizeHandle(this, ResizeHandle::BottomRightCorner); } void ResizeHandleSet::raise() { for (int i = 0; i < 8; i++) d->handles[i]->raise(); } void ResizeHandleSet::setEditingMode(bool editing) { for (int i = 0; i < 8; i++) d->handles[i]->setEditingMode(editing); } void ResizeHandleSet::resizeStarted() { d->origWidgetRect = d->widget->geometry(); } void ResizeHandleSet::resizeFinished() { if (d->widget) { //qDebug() << "old:" << d->origWidgetRect << "new:" << d->widget->geometry(); } } QWidget* ResizeHandleSet::widget() const { return d->widget; } Form* ResizeHandleSet::form() const { return d->form; } #include "resizehandle.moc" diff --git a/src/formeditor/utils.h b/src/formeditor/utils.h index de48e8a3c..adcc407bf 100644 --- a/src/formeditor/utils.h +++ b/src/formeditor/utils.h @@ -1,165 +1,165 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2007-2009 Jarosław Staniek 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 FORMEDITORUTILS_H #define FORMEDITORUTILS_H #include "kformdesigner_export.h" #include #include #include #include typedef QTabWidget TabWidgetBase; //! @todo uncomment //!//#define USE_KTabWidget class QMimeData; class QDomDocument; class QPainter; namespace KFormDesigner { class Form; /*! \return parent object of \a o that inherits \a className or NULL if no such parent If the parent is found, \a prevPrev is set to a child of child of the parent, what for TabWidget means the page widget. */ template type* findParent(QObject* o, const char* className, QObject* &prevPrev) { if (!o || !className || className[0] == '\0') return 0; QObject *prev = o; while (((o = o->parent())) && !o->inherits(className)) { prevPrev = prev; prev = o; } return static_cast(o); } //! A tab widget providing information about height of the tab bar. class KFORMDESIGNER_EXPORT TabWidget : public TabWidgetBase { Q_OBJECT public: explicit TabWidget(QWidget *parent) : TabWidgetBase(parent) {} virtual ~TabWidget() {} int tabBarHeight() const { return tabBar()->height(); } }; //! @short A common interface for HorizontalWidgetList and VerticalWidgetList class CustomSortableWidgetList : public QWidgetList { public: CustomSortableWidgetList() : QWidgetList() {} //! Copy constructor needed required by foreach() CustomSortableWidgetList(const CustomSortableWidgetList& list) : QWidgetList(list) {} virtual ~CustomSortableWidgetList() {} virtual void sort() {} }; //! @short A helper for sorting widgets horizontally class HorizontalWidgetList : public CustomSortableWidgetList { public: explicit HorizontalWidgetList(QWidget *topLevelWidget); //! Copy constructor needed required by foreach() HorizontalWidgetList(const HorizontalWidgetList& list); virtual ~HorizontalWidgetList(); - virtual void sort(); + virtual void sort() override; protected: class LessThan; LessThan *m_lessThan; }; //! @short A helper for sorting widgets vertically class VerticalWidgetList : public CustomSortableWidgetList { public: explicit VerticalWidgetList(QWidget *topLevelWidget); //! Copy constructor needed required by foreach() VerticalWidgetList(const VerticalWidgetList& list); virtual ~VerticalWidgetList(); - virtual void sort(); + virtual void sort() override; protected: class LessThan; LessThan *m_lessThan; }; /*! This function is used to remove all the child widgets from a list, and keep only the "toplevel" ones. */ KFORMDESIGNER_EXPORT void removeChildrenFromList(QWidgetList &list); KFORMDESIGNER_EXPORT void setRecursiveCursor(QWidget *w, Form *form); //! \return the size of \a w children /*! This can be used eg to get widget's sizeHint. */ KFORMDESIGNER_EXPORT QSize getSizeFromChildren(QWidget *widget, const char *inheritClass = "QWidget"); //! @return mimetype for the forms XML format inline QString mimeType() { return "application/x-kexi-form"; } //! @return deep copy of the mime data @a data (for all formats) KFORMDESIGNER_EXPORT QMimeData *deepCopyOfMimeData(const QMimeData *data); //! Copies @a xml data to the clipboard both in the plain text format and forms XML format KFORMDESIGNER_EXPORT void copyToClipboard(const QString& xml); //! Recursively saves widget list @a list and form @a form to @a doc XML document /*! @a containers hash is filled with containers found within the widget list, and @a parents is filled with the parent widgets found within the widget list. USed in DeleteWidgetCommand ctor. */ KFORMDESIGNER_EXPORT void widgetsToXML(QDomDocument& doc, QHash& containers, QHash& parents, const Form& form, const QWidgetList &list); //! QActionGroup extended by action() method. class KFORMDESIGNER_EXPORT ActionGroup : public QActionGroup { Q_OBJECT public: explicit ActionGroup( QObject * parent ); ~ActionGroup(); //! Reimplemented. void addAction(QAction* action); QAction *action(const QString& name) const; private: Q_DISABLE_COPY(ActionGroup) class Private; Private * const d; }; //! @return @a value aligned to the nearest multiple of gridSize KFORMDESIGNER_EXPORT int alignValueToGrid(int value, int gridSize); //! Paint semitransparent widget frame. //! For example it is useful for design mode to show geometry of label that has no visible frames. KFORMDESIGNER_EXPORT void paintWidgetFrame(QPainter& p, const QRect& geometry); } #endif diff --git a/src/formeditor/widgetfactory.h b/src/formeditor/widgetfactory.h index 94c4de680..780aece81 100644 --- a/src/formeditor/widgetfactory.h +++ b/src/formeditor/widgetfactory.h @@ -1,383 +1,383 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2009 Jarosław Staniek 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 KFORMDESIGNERWIDGETFACTORY_H #define KFORMDESIGNERWIDGETFACTORY_H #include #include #include #include #include "kformdesigner_export.h" class QWidget; class QListWidget; class QMenu; class QDomElement; class QDomDocument; class QVariant; class KActionCollection; class KPropertySet; namespace KFormDesigner { class Container; class ObjectTreeItem; class Form; class WidgetLibrary; class WidgetInfo; //! Used by WidgetFactory class KFORMDESIGNER_EXPORT InternalPropertyHandlerInterface { protected: InternalPropertyHandlerInterface(); virtual ~InternalPropertyHandlerInterface(); /*! Assigns \a value for internal property \a property for a class \a classname. Internal properties are not stored within objects, but can be provided to describe class' details. */ virtual void setInternalProperty(const QByteArray& classname, const QByteArray& property, const QVariant& value) = 0; friend class WidgetInfo; }; //! The base class for all widget Factories /*! This is the class you need to inherit to create a new Factory. There are few virtuals you need to implement, and some other functions to implement if you want more features.\n \n Widget Creation\n To be able to create widgets, you need to implement the create() function, an classes(), which should return all the widgets supported by this factory.\n \n GUI Integration\n The following functions allow you to customize even more the look-n-feel of your widgets inside KFormDesigner. You can use createMenuActions() to add custom items in widget's context menu. The previewWidget() is called when the Form gets in Preview mode, and you have a last opportunity to remove all editing-related stuff (see eg \ref Spring class).\n You can also choose which properties to show in the Property Editor. By default, most all properties are shown (see implementation for details), but you can hide some reimplementing isPropertyVisibleInternal() (don't forget to call superclass' method) To add new properties, just define new Q_PROPERTY in widget class definition.\n \n Inline editing\n KFormDesigner allow you to edit the widget's contents inside Form, without using a dialog. You can of course customize the behaviour of your widgets, using startInlineEditing(). There are some editing modes already implemented in WidgetFactroy, but you can create your own if you want: \li Editing using a line edit (createInlineEditor()): a line edit is created on top of widget, where the user inputs text. As the text changes, changeInlineText() is called (where you should set your widget's text and resize widget to fit the text if needed) and resizeEditor() to update editor's position when widget is moved/resized.\n \li Editing by disabling event filter: if you call disableFilter(), the event filter on the object is temporarily disabled, so the widget behaves as usual. This can be used for more complex widgets, such as spinbox, date/time edit, etc. \li Other modes: there are 3 other modes, to edit a string list: editList() (for combo box, listbox), to edit rich text: editRichText() (for labels, etc.)\n \n Widget saving/loading\n You can also control how your widget are saved/loaded. You can choose which properties to save (see autoSaveProperties()), and save/load custom properties, ie properties that are not Q_PROPERTY but you want to save in the UI file. This is used eg to save combo box or list widget contents (see saveSpecialProperty() and readSpecialProperty()). \n \n Special internal properties\n Use void WidgetInfo::setInternalProperty(const QByteArray& property, const QVariant& value) to set values of special internal properties. Currently these properties are used for customizing popup menu items used for orientation selection. Customization for class ClassName should look like: WidgetInfo *wi = ... wi->setInternalProperty("orientationSelectionPopup", true); wi->setInternalProperty("orientationSelectionPopup:horizontalIcon", "myicon"); Available internal properties: * "orientationSelectionPopup" - set it to true if you want a given class to offer orientation selection, so orientation selection popup will be displayed when needed. * "orientationSelectionPopup:horizontalIcon" - sets a name of icon for "Horizontal" item for objects of class 'ClassName'. Set this property only for classes supporting orientations. * "orientationSelectionPopup:verticalIcon" - the same for "Vertical" item. Set this property only for classes supporting orientations. * "orientationSelectionPopup:horizontalText" - sets a i18n'd text for "Horizontal" item for objects of class 'ClassName', e.g. xi18n("Insert Horizontal Line"). Set this property only for classes supporting orientations. * "orientationSelectionPopup:verticalText" - the same for "Vertical" item, e.g. xi18n("Insert Vertical Line"). Set this property only for classes supporting orientations. * "dontStartEditingOnInserting" - if true, WidgetFactory::startInlineEditing() will not be executed upon widget inseting by a user. * "forceShowAdvancedProperty:{propertyname}" - set it to true for "{propertyname}" advanced property if you want to force it to be visible even if WidgetLibrary::setAdvancedPropertiesVisible(false) has been called. For example, setting "forceShowAdvancedProperty:pixmap" to true unhides "pixmap" property for a given class. See KexiStandardFormWidgetsFactory::KexiStandardFormWidgetsFactory() for properties like "Line:orientationSelectionPopup:horizontalIcon". \n\n See the standard factories in formeditor/factories for an example of factories, and how to deal with complex widgets (eg tabwidget). */ class KFORMDESIGNER_EXPORT WidgetFactory : public QObject, public InternalPropertyHandlerInterface { Q_OBJECT public: //! Options used in createWidget() enum CreateWidgetOption { NoCreateWidgetOptions = 0, AnyOrientation = 1, //!< any orientation hint HorizontalOrientation = 2, //!< horizontal orientation hint VerticalOrientation = 4, //!< vertical orientation hint DesignViewMode = 8, //!< create widget in design view mode, otherwise preview mode DefaultOptions = AnyOrientation | DesignViewMode }; Q_DECLARE_FLAGS(CreateWidgetOptions, CreateWidgetOption) explicit WidgetFactory(QObject *parent); virtual ~WidgetFactory(); /*! Adds a new class described by \a w. */ void addClass(WidgetInfo *w); /*! This method allows to force a class \a classname to hidden. It is useful if you do not want a class to be available (e.g. because it is not implemented well yet for our purposes). All widget libraries are affected by this setting. */ void hideClass(const char *classname); /** * \return all classes which are provided by this factory */ QHash classes() const; /** * Creates a widget (and if needed a KFormDesigner::Container) * \return the created widget * \param classname the classname of the widget, which should get created * \param parent the parent for the created widget * \param name the name of the created widget * \param container the toplevel Container (if a container should get created) * \param options options for the created widget: orientation and view mode (see CreateWidgetOptions) */ virtual QWidget* createWidget(const QByteArray &classname, QWidget *parent, const char *name, KFormDesigner::Container *container, CreateWidgetOptions options = DefaultOptions) /*Q_REQUIRED_RESULT*/ = 0; /*! Creates custom actions. Reimplement this if you need to add some actions coming from the factory. */ virtual void createCustomActions(KActionCollection *col) { Q_UNUSED(col); } /*! This function can be used to add custom items in widget \a w context menu \a menu. */ virtual bool createMenuActions(const QByteArray &classname, QWidget *w, QMenu *menu, KFormDesigner::Container *container) = 0; //! Arguments used by Form::createInlineEditor() and startInlineEditing() /*! @a text is the text to display by default in the line edit. @a widget is the edited widget, @a geometry is the geometry the new line edit should have, and @a alignment is Qt::Alignment of the new line edit. If @a useFrame is false (the default), the line edit has no frame. if @a multiLine is false (the default), the line edit has single line. @a background describes line edit's background. If @a execute is true (the default), createInlineEditor() will be executed. */ class KFORMDESIGNER_EXPORT InlineEditorCreationArguments { public: InlineEditorCreationArguments( const QByteArray& _classname, QWidget *_widget, Container *_container); QByteArray classname; QString text; QWidget *widget; Container *container; QRect geometry; Qt::Alignment alignment; bool useFrame; bool multiLine; bool execute; //! true if the inline editor's bakground should be transparent (false by default) bool transparentBackground; }; /*! Sets up (if necessary) aguments for the inline editor used to edit the contents of the widget directly within the Form, e.g. creates a line edit to change the text of a label. @a args is used to pass the arguments back to the caller. */ virtual bool startInlineEditing(InlineEditorCreationArguments& args) = 0; /*! This function is called just before the Form is previewed. It allows widgets to make changes before switching (ie for a Spring, hiding the cross) */ virtual bool previewWidget(const QByteArray &classname, QWidget *widget, Container *container) = 0; virtual bool clearWidgetContent(const QByteArray &classname, QWidget *w); /*! This function is called when FormIO finds a property, at save time, that it cannot handle (ie not a normal property). This way you can save special properties, for example the contents of a listbox. \sa readSpecialProperty() */ virtual bool saveSpecialProperty(const QByteArray &classname, const QString &name, const QVariant &value, QWidget *w, QDomElement &parentNode, QDomDocument &parent); /*! This function is called when FormIO finds a property or an unknown element in a .ui file. You can this way load a special property, for example the contents of a listbox. \sa saveSpecialProperty() */ virtual bool readSpecialProperty(const QByteArray &classname, QDomElement &node, QWidget *w, ObjectTreeItem *item); /*! This function is used to know whether the \a property for the widget \a w should be shown or not in the PropertyEditor. If \a multiple is true, then multiple widgets of the same class are selected, and you should only show properties shared by widgets (eg font, color). By default, all properties are shown if multiple == true, and none if multiple == false. */ bool isPropertyVisible(const QByteArray &classname, QWidget *w, const QByteArray &property, bool multiple, bool isTopLevel); /*! \return The i18n'ed name of the property whose name is \a name, that will be displayed in PropertyEditor. */ QString propertyDescription(const char* name) const; /*! \return The i18n'ed name of the property's value whose name is \a name. */ QString valueDescription(const char* name) const; /*! This method is called after form's property set was filled with properties of a widget \a w, of class defined by \a info. Default implementation does nothing. Implement this if you need to set options for properties within the set \a set. */ virtual void setPropertyOptions(KPropertySet& set, const WidgetInfo& info, QWidget *w); /*! \return internal property \a property for a class \a classname. Internal properties are not stored within objects, but can be just provided to describe class' details. */ QVariant internalProperty(const QByteArray& classname, const QByteArray& property) const; /*! This function is called when the widget is resized, and the @a editor size needs to be updated. */ virtual void resizeEditor(QWidget *editor, QWidget *widget, const QByteArray &classname); /*! @return selectable item for @a item item. By default it is equal to @a item but e.g. for pages of QTabWidget, item for the widget itself is returned. Used when user clicks on the Widget Tree item or when parent of the current widget should to be selected. Defaults can be overridden by reimplementing this method. */ virtual ObjectTreeItem* selectableItem(ObjectTreeItem* item); /*! Sets the i18n'ed description of a property, which will be shown in PropertyEditor. */ void setPropertyDescription(const char *property, const QString &description); /*! Sets the i18n'ed description of a property value, which will be shown in PropertyEditor. */ void setValueDescription(const char *valueName, const QString &description); void setAdvancedPropertiesVisible(bool set); protected: /*! This function is called when we want to know whether the property should be visible. Implement it in the factory; don't forget to call implementation in the superclass. Default implementation hides "windowTitle", "windowIcon", "sizeIncrement" and "windowIconText" properties. */ virtual bool isPropertyVisibleInternal(const QByteArray &classname, QWidget *w, const QByteArray &property, bool isTopLevel); /*! Sometimes property sets should be reloaded when a given property value changed. Implement it in the factory. Default implementation always returns false. */ virtual bool propertySetShouldBeReloadedAfterPropertyChange(const QByteArray& classname, QWidget *w, const QByteArray& property); /*! This function provides a simple editing mode: it just disables event filtering for the widget, and it install it again when the widget loose focus or Enter is pressed. */ void disableFilter(QWidget *w, Container *container); /*! This function creates a little dialog (a KEditListBox) to modify the contents of a list (of strings). It can be used to modify the contents of a combo box for instance. The modified list is copied into \a list if the user presses "Ok" and true is returned. When user presses "Cancel" false is returned. */ bool editList(QWidget *w, QStringList &list) const; /*! This function creates a little editor to modify rich text. It supports alignment, subscript and superscript and all basic formatting properties. If the user presses "Ok", the edited text is put into @a text and true is returned. If the user presses "Cancel" false is returned. */ bool editRichText(QWidget *w, QString &text) const; #ifdef KEXI_LIST_FORM_WIDGET_SUPPORT /*! This function creates a dialog to modify the contents of a list widget. You can modify both columns and list items. The list widget is automatically updated if the user presses "Ok".*/ void editListWidget(QListWidget *listwidget) const; #endif /*! This function is used to modify a property of a widget (eg after editing it). Please use it instead of w->setProperty() to allow sync inside PropertyEditor. */ void changeProperty(Form *form, QWidget *widget, const char *name, const QVariant &value); /*! \return true if at least one class defined by this factory inherits a class from other factory. Used in WidgetLibrary::loadFactories() to load factories in proper order. */ bool inheritsFactories(); /*! Assigns \a value for internal property \a property for a class \a classname. Internal properties are not stored within objects, but can be provided to describe class' details. */ - void setInternalProperty(const QByteArray& classname, const QByteArray& property, const QVariant& value); + void setInternalProperty(const QByteArray& classname, const QByteArray& property, const QVariant& value) override; WidgetInfo* widgetInfoForClassName(const char* classname); const QSet* hiddenClasses() const; WidgetLibrary* library(); bool advancedPropertiesVisible() const; void setLibrary(WidgetLibrary* library); public Q_SLOTS: /*! @internal. This slot is called when the editor has lost focus or the user pressed Enter. It destroys the editor or installs again the event filter on the widget. */ //! Changes inline text for widget @a widget to @a text /*! Default implementation changes "text" property of the widget. You have to reimplement this function for inline editing inside the form @a form if your widget's property you want to change is not named "text". This slot is called when the line edit text changes, and you have to make it really change property of the widget using changeProperty() (text, title, etc.). */ virtual bool changeInlineText(Form *form, QWidget *widget, const QString& text, QString &oldText); private: class Private; Private* const d; friend class WidgetLibrary; }; Q_DECLARE_OPERATORS_FOR_FLAGS(WidgetFactory::CreateWidgetOptions) } #endif diff --git a/src/kexiutils/FlowLayout.h b/src/kexiutils/FlowLayout.h index 1a85f14ac..bcdddfaba 100644 --- a/src/kexiutils/FlowLayout.h +++ b/src/kexiutils/FlowLayout.h @@ -1,81 +1,81 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2007-2012 Jarosław Staniek 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 KEXIFLOWLAYOUT_H #define KEXIFLOWLAYOUT_H #include #include #include "kexiutils_export.h" //! @short a special "flow" layout //! @todo Vertical KexiFlowLayout ported to Qt4 but not tested. class KEXIUTILS_EXPORT KexiFlowLayout : public QLayout { Q_OBJECT public: explicit KexiFlowLayout(QWidget *parent, int margin = 0, int spacing = -1); explicit KexiFlowLayout(QLayout* parent, int margin = 0, int spacing = -1); explicit KexiFlowLayout(int margin = 0, int spacing = -1); virtual ~KexiFlowLayout(); /*! \return the widgets in the order of the layout, ie as it is stored in m_list. You must delete the list after using it. */ QList* widgetList() const; /*! Sets layout's orientation to \a orientation. Default orientation is Vertical. */ void setOrientation(Qt::Orientation orientation); /*! \return layout's orientation. */ Qt::Orientation orientation() const; void setJustified(bool justify); bool isJustified() const; - virtual void addItem(QLayoutItem *item); + virtual void addItem(QLayoutItem *item) override; virtual void addSpacing(int size); void insertWidget(int index, QWidget* widget, int stretch = 0, Qt::Alignment alignment = 0); - virtual void invalidate(); - - virtual bool hasHeightForWidth() const; - virtual int heightForWidth(int width) const; - virtual QSize sizeHint() const; - virtual QSize minimumSize() const; - virtual Qt::Orientations expandingDirections() const; - virtual int count() const; - virtual bool isEmpty() const; - virtual void setGeometry(const QRect&); - virtual QLayoutItem *itemAt(int index) const; - virtual QLayoutItem *takeAt(int index); + virtual void invalidate() override; + + virtual bool hasHeightForWidth() const override; + virtual int heightForWidth(int width) const override; + virtual QSize sizeHint() const override; + virtual QSize minimumSize() const override; + virtual Qt::Orientations expandingDirections() const override; + virtual int count() const override; + virtual bool isEmpty() const override; + virtual void setGeometry(const QRect&) override; + virtual QLayoutItem *itemAt(int index) const override; + virtual QLayoutItem *takeAt(int index) override; protected: int simulateLayout(const QRect &r); int doHorizontalLayout(const QRect&, bool testonly = false); int doVerticalLayout(const QRect&, bool testonly = false); private: class Private; Private* const d; }; #endif diff --git a/src/kexiutils/KexiAnimatedLayout_p.h b/src/kexiutils/KexiAnimatedLayout_p.h index 81a4f641e..241ffc6ad 100644 --- a/src/kexiutils/KexiAnimatedLayout_p.h +++ b/src/kexiutils/KexiAnimatedLayout_p.h @@ -1,47 +1,47 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIANIMATEDLAYOUT_P_H #define KEXIANIMATEDLAYOUT_P_H #include #include #include #include #include "KexiAnimatedLayout.h" class Q_DECL_HIDDEN KexiAnimatedLayout::Private : public QWidget { Q_OBJECT public: explicit Private(KexiAnimatedLayout* qq); void animateTo(QWidget* destination); protected: - void paintEvent(QPaintEvent* event); + void paintEvent(QPaintEvent* event) override; protected Q_SLOTS: void animationFinished(); private: QPointer q; QPixmap buffer; QPropertyAnimation animation; QPointer destinationWidget; }; #endif diff --git a/src/kexiutils/KexiCategorizedView.h b/src/kexiutils/KexiCategorizedView.h index d25cbda11..30a4b8e10 100644 --- a/src/kexiutils/KexiCategorizedView.h +++ b/src/kexiutils/KexiCategorizedView.h @@ -1,66 +1,66 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICATEGORIZEDVIEW_H #define KEXICATEGORIZEDVIEW_H #include "kexiutils_export.h" #include #include class QAbstractItemModel; typedef KCategoryDrawer KexiCategoryDrawerBase; //! Modification of category drawer for KCategorizedView: disallows clicking on the drawer class KEXIUTILS_EXPORT KexiCategoryDrawer : public KexiCategoryDrawerBase { Q_OBJECT public: explicit KexiCategoryDrawer(KCategorizedView *view); }; //! Single selection model for the drawer. class KEXIUTILS_EXPORT KexiCategorySingleSelectionModel : public QItemSelectionModel { Q_OBJECT public: explicit KexiCategorySingleSelectionModel(QAbstractItemModel* model); using QItemSelectionModel::select; //! Reimplemented to disable full category selections. //! Shouldn't be needed in KDElibs >= 4.5, //! where KexiTemplatesCategoryDrawer::mouseButtonPressed() works. void select(const QItemSelection& selection, - QItemSelectionModel::SelectionFlags command); + QItemSelectionModel::SelectionFlags command) override; }; //! Single selection categorized view. class KEXIUTILS_EXPORT KexiCategorizedView : public KCategorizedView { Q_OBJECT public: explicit KexiCategorizedView(QWidget *parent = 0); - virtual void setModel(QAbstractItemModel *model); + virtual void setModel(QAbstractItemModel *model) override; }; #endif diff --git a/src/kexiutils/KexiCloseButton.h b/src/kexiutils/KexiCloseButton.h index 6b2299c5d..8687719ba 100644 --- a/src/kexiutils/KexiCloseButton.h +++ b/src/kexiutils/KexiCloseButton.h @@ -1,50 +1,50 @@ /* This file is part of the KDE project Copyright (C) 2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICLOSEBUTTON_H #define KEXICLOSEBUTTON_H #include "kexiutils_export.h" #include //! A flat button with a "close" icon, looking exactly like a "close" button of //! a dock widget or a tab bar's tab. class KEXIUTILS_EXPORT KexiCloseButton : public QToolButton { Q_OBJECT public: explicit KexiCloseButton(QWidget* parent = 0); virtual ~KexiCloseButton(); //! Sets default margin (based on style), on by default. void setMarginEnabled(bool set); protected: - virtual void paintEvent(QPaintEvent *e); + virtual void paintEvent(QPaintEvent *e) override; private: void init(); class Private; Private * const d; }; #endif diff --git a/src/kexiutils/KexiCommandLinkButton.h b/src/kexiutils/KexiCommandLinkButton.h index 9de0672f7..ea3375675 100644 --- a/src/kexiutils/KexiCommandLinkButton.h +++ b/src/kexiutils/KexiCommandLinkButton.h @@ -1,62 +1,62 @@ /* This file is part of the KDE project Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). Copyright (C) 2011 Jarosław Staniek 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 KEXICOMMANDLINKBUTTON_H #define KEXICOMMANDLINKBUTTON_H #include #include class KexiCommandLinkButtonPrivate; class KEXIUTILS_EXPORT KexiCommandLinkButton : public KexiPushButton { Q_OBJECT Q_PROPERTY(QString description READ description WRITE setDescription) Q_PROPERTY(bool flat READ isFlat WRITE setFlat DESIGNABLE false) Q_PROPERTY(bool arrowVisible READ isArrowVisible WRITE setArrowVisible) public: explicit KexiCommandLinkButton(QWidget *parent=0); explicit KexiCommandLinkButton(const QString &text, QWidget *parent=0); KexiCommandLinkButton(const QString &text, const QString &description, QWidget *parent=0); virtual ~KexiCommandLinkButton(); QString description() const; void setDescription(const QString &description); bool isArrowVisible() const; void setArrowVisible(bool visible); protected: - QSize sizeHint() const; - int heightForWidth(int) const; - QSize minimumSizeHint() const; - bool event(QEvent *e); - void paintEvent(QPaintEvent *); + QSize sizeHint() const override; + int heightForWidth(int) const override; + QSize minimumSizeHint() const override; + bool event(QEvent *e) override; + void paintEvent(QPaintEvent *) override; private: Q_DISABLE_COPY(KexiCommandLinkButton) friend class KexiCommandLinkButtonPrivate; KexiCommandLinkButtonPrivate * const d; }; #endif // KEXICOMMANDLINKBUTTON diff --git a/src/kexiutils/KexiContextMessage.h b/src/kexiutils/KexiContextMessage.h index 3f7ed086d..866c3baa9 100644 --- a/src/kexiutils/KexiContextMessage.h +++ b/src/kexiutils/KexiContextMessage.h @@ -1,147 +1,147 @@ /* This file is part of the KDE project Copyright (C) 2011-2012 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICONTEXTMESSAGE_H #define KEXICONTEXTMESSAGE_H #include "kmessagewidget.h" //! Information about context message. class KEXIUTILS_EXPORT KexiContextMessage { public: explicit KexiContextMessage(const QString& text = QString()); explicit KexiContextMessage(QWidget *contentsWidget); explicit KexiContextMessage(const KexiContextMessage& other); ~KexiContextMessage(); QString text() const; void setText(const QString text); //! Alignment of button corresponding to action added in addAction() enum ButtonAlignment { AlignLeft, AlignRight }; //! Adds action. Does not take ownership. void addAction(QAction* action, ButtonAlignment alignment = AlignRight); QList actions() const; //! @return alignment of button for action @a action. ButtonAlignment buttonAlignment(QAction* action) const; //! Sets default action, i.e. button created with this action //! will be the default button of the message. //! Does not take ownership. void setDefaultAction(QAction* action); QAction* defaultAction() const; QWidget* contentsWidget() const; private: class Private; Private * const d; }; class QFormLayout; //! Context message widget constructed out of context message argument. class KEXIUTILS_EXPORT KexiContextMessageWidget : public KMessageWidget { Q_OBJECT public: //! Creates message widget constructed out of context message @a message. /*! Inserts itself into layout @a layout on top of the widget @a context. If @page is not 0 and @a message has any actions added, all children of @a page widget will be visually disabled to indicate modality of the message. The message widget will be automatically destroyed after triggering of any associated action. If @a layout is provided, direction of callout pointer is set by default to KMessageWidget::Down. This can be changed using setCalloutPointerDirection(). */ KexiContextMessageWidget(QWidget *page, QFormLayout* layout, QWidget *context, const KexiContextMessage& message); //! @overload KexiContextMessageWidget(QWidget*, QFormLayout*, QWidget*, const KexiContextMessage&); //! Does not enter into modal state and does not accept actions. KexiContextMessageWidget(QFormLayout* layout, QWidget *context, const KexiContextMessage& message); //! @overload KexiContextMessageWidget(QFormLayout*, QWidget*, const KexiContextMessage&); //! Does not enter into modal state and does not accept actions. KexiContextMessageWidget(QFormLayout* layout, QWidget *context, const QString& message); virtual ~KexiContextMessageWidget(); //! Sets widget @a widget to be foused after this message closes. //! By default context widget passed to constructor will be focused. //! Useful in modal mode. void setNextFocusWidget(QWidget *widget); //! Sets global position for callout pointer //! @overload KMessageWidget::setCalloutPointerPosition(const QPoint&) //! Also sets tracked widget @a trackedWidget. //! If the widget changes its local position, the pointer position //! is moved by the same delta. void setCalloutPointerPosition(const QPoint& globalPos, QWidget *trackedWidget = 0); //! Sets tracking policy for resize of the parent widget. //! When parent is resized in any way, size of the message box //! can be changed in one or two orientations. It is disabled by default //! and does not affect position of the callout pointer. //! Works only when tracked widget is set in setCalloutPointerPosition(). void setResizeTrackingPolicy(Qt::Orientations orientations); //! @return tracking policy for resize of the parent widget. Qt::Orientations resizeTrackingPolicy() const; //! Sets palette of the contents widget inheriting the message palette (background). //! Calling it is needed after delayed insering of the child contents widgets. void setPaletteInherited(); protected: - virtual bool eventFilter(QObject* watched, QEvent* event); + virtual bool eventFilter(QObject* watched, QEvent* event) override; private Q_SLOTS: void actionTriggered(); void slotAnimatedShowFinished(); void slotAnimatedHideFinished(); private: void init(QWidget *page, QFormLayout* layout, QWidget *context, const KexiContextMessage& message); //! Made private to disable addAction(). void addAction(QAction* action) { Q_UNUSED(action); } class Private; Private * const d; }; #endif diff --git a/src/kexiutils/KexiLinkButton.h b/src/kexiutils/KexiLinkButton.h index 25e770311..874c90db7 100644 --- a/src/kexiutils/KexiLinkButton.h +++ b/src/kexiutils/KexiLinkButton.h @@ -1,70 +1,70 @@ /* This file is part of the KDE project Copyright (C) 2012 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXILINKBUTTON_H #define KEXILINKBUTTON_H #include "kexiutils_export.h" #include class KGuiItem; //! A flat icon-based button without background that behaves like a link class KEXIUTILS_EXPORT KexiLinkButton : public QPushButton { Q_OBJECT public: explicit KexiLinkButton(QWidget* parent = 0); explicit KexiLinkButton(const QIcon &icon, QWidget* parent = 0); explicit KexiLinkButton(const KGuiItem &item, QWidget *parent = 0); explicit KexiLinkButton(const QPixmap &pixmap, QWidget* parent = 0); virtual ~KexiLinkButton(); /*! If true, foreground color of the current palette is always used for painting the button's icon. This is done by replacing color. The foreground color is QPalette::Text by default, and can be changed using setForegroundRole(). The icon is expected to be monochrome. Works well also after palette change. False by default. */ void setUsesForegroundColor(bool set); /*! @return true if foreground color of the current palette is always used for painting the button's icon. */ bool usesForegroundColor() const; void setIcon(const QIcon &icon); protected: - virtual void changeEvent(QEvent* event); + virtual void changeEvent(QEvent* event) override; private: void init(); void updateIcon(const QIcon &icon); class Private; Private * const d; }; #endif diff --git a/src/kexiutils/KexiLinkWidget.h b/src/kexiutils/KexiLinkWidget.h index 8d0f9f4c4..4fa12c633 100644 --- a/src/kexiutils/KexiLinkWidget.h +++ b/src/kexiutils/KexiLinkWidget.h @@ -1,79 +1,79 @@ /* This file is part of the KDE project Copyright (C) 2011-2018 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXILINKWIDGET_H #define KEXILINKWIDGET_H #include "kexiutils_export.h" #include class QKeySequence; //! Link widget class KEXIUTILS_EXPORT KexiLinkWidget : public QLabel { Q_OBJECT Q_PROPERTY(QString link READ link WRITE setLink) Q_PROPERTY(QString linkText READ linkText WRITE setLinkText) Q_PROPERTY(QString format READ format WRITE setFormat) public: explicit KexiLinkWidget(QWidget* parent = 0); KexiLinkWidget(const QString& link, const QString& linkText, QWidget* parent = 0); virtual ~KexiLinkWidget(); QString link() const; QString linkText() const; QString format() const; QKeySequence shortcut() const; public Q_SLOTS: void setLink(const QString& link); void setLinkText(const QString& linkText); //! Sets format for the button. /*! Format defines user-visible text written around the link. Use "%L" as a placeholder for the link, e.g. when format is "‹ %L" and link text is "Back", the widget will show "‹ Back" where "Back" is a link. By default format is empty, what means only the link is displayed. */ void setFormat(const QString& format); void click(); void setShortcut(const QKeySequence &key); protected: - virtual void changeEvent(QEvent* event); + virtual void changeEvent(QEvent* event) override; private: QString text() const { return QLabel::text(); } void setText(const QString& text) { QLabel::setText(text); } class Private; Private * const d; }; #endif diff --git a/src/kexiutils/KexiTitleLabel.h b/src/kexiutils/KexiTitleLabel.h index 21caff6db..e509d963c 100644 --- a/src/kexiutils/KexiTitleLabel.h +++ b/src/kexiutils/KexiTitleLabel.h @@ -1,44 +1,44 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITITLELABEL_H #define KEXITITLELABEL_H #include #include "kexiutils_export.h" class KEXIUTILS_EXPORT KexiTitleLabel : public QLabel { Q_OBJECT public: explicit KexiTitleLabel(QWidget * parent = 0, Qt::WindowFlags f = 0); explicit KexiTitleLabel(const QString & text, QWidget * parent = 0, Qt::WindowFlags f = 0); ~KexiTitleLabel(); protected: - void changeEvent(QEvent* event); + void changeEvent(QEvent* event) override; private: void updateFont(); void init(); class Private; Private * const d; }; #endif diff --git a/src/kexiutils/SmallToolButton.h b/src/kexiutils/SmallToolButton.h index bce6c0435..65e4bab30 100644 --- a/src/kexiutils/SmallToolButton.h +++ b/src/kexiutils/SmallToolButton.h @@ -1,92 +1,92 @@ /* This file is part of the KDE project Copyright (C) 2005-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXISMALLTOOLBUTTON_H #define KEXISMALLTOOLBUTTON_H #include #include "kexiutils_export.h" class QAction; class QIcon; //! @short A small tool button with icon and optional text class KEXIUTILS_EXPORT KexiSmallToolButton : public QToolButton { Q_OBJECT public: explicit KexiSmallToolButton(QWidget* parent = 0); explicit KexiSmallToolButton(const QString& text, QWidget* parent = 0); KexiSmallToolButton(const QIcon& icon, const QString& text, QWidget* parent = 0); explicit KexiSmallToolButton(const QIcon& icon, QWidget* parent = 0); explicit KexiSmallToolButton(QAction *action, QWidget* parent = 0); virtual ~KexiSmallToolButton(); void updateAction(); virtual void setIcon(const QIcon& icon); virtual void setIcon(const QString &iconName); virtual void setText(const QString& text); void setToolButtonStyle(Qt::ToolButtonStyle style); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; QAction* action() const; protected Q_SLOTS: void slotActionChanged(); void slotButtonToggled(bool checked); void slotActionToggled(bool checked); protected: void update(const QString& text, const QIcon& icon, bool tipToo = false); void init(); class Private; Private * const d; }; class QStyleOption; //! @short separator for custom toolbars class KEXIUTILS_EXPORT KexiToolBarSeparator : public QWidget { Q_OBJECT public: explicit KexiToolBarSeparator(QWidget *parent); virtual ~KexiToolBarSeparator(); - QSize sizeHint() const; + QSize sizeHint() const override; Qt::Orientation orientation() const; public Q_SLOTS: void setOrientation(Qt::Orientation o); protected: - virtual void paintEvent(QPaintEvent *e); + virtual void paintEvent(QPaintEvent *e) override; void initStyleOption(QStyleOption *o) const; private: class Private; Private* const d; }; #endif diff --git a/src/kexiutils/completer/KexiCompleter.cpp b/src/kexiutils/completer/KexiCompleter.cpp index 081cbce8f..d0971c073 100644 --- a/src/kexiutils/completer/KexiCompleter.cpp +++ b/src/kexiutils/completer/KexiCompleter.cpp @@ -1,1914 +1,1914 @@ /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \class KexiCompleter \brief The KexiCompleter class provides completions based on an item model. You can use KexiCompleter to provide auto completions in any Qt widget, such as QLineEdit and QComboBox. When the user starts typing a word, KexiCompleter suggests possible ways of completing the word, based on a word list. The word list is provided as a QAbstractItemModel. (For simple applications, where the word list is static, you can pass a QStringList to KexiCompleter's constructor.) \tableofcontents \section1 Basic Usage A KexiCompleter is used typically with a QLineEdit or QComboBox. For example, here's how to provide auto completions from a simple word list in a QLineEdit: \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 0 A QFileSystemModel can be used to provide auto completion of file names. For example: \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 1 To set the model on which KexiCompleter should operate, call setModel(). By default, KexiCompleter will attempt to match the \l {completionPrefix}{completion prefix} (i.e., the word that the user has started typing) against the Qt::EditRole data stored in column 0 in the model case sensitively. This can be changed using setCompletionRole(), setCompletionColumn(), and setCaseSensitivity(). If the model is sorted on the column and role that are used for completion, you can call setModelSorting() with either KexiCompleter::CaseSensitivelySortedModel or KexiCompleter::CaseInsensitivelySortedModel as the argument. On large models, this can lead to significant performance improvements, because KexiCompleter can then use binary search instead of linear search. The model can be a \l{QAbstractListModel}{list model}, a \l{QAbstractTableModel}{table model}, or a \l{QAbstractItemModel}{tree model}. Completion on tree models is slightly more involved and is covered in the \l{Handling Tree Models} section below. The completionMode() determines the mode used to provide completions to the user. \section1 Iterating Through Completions To retrieve a single candidate string, call setCompletionPrefix() with the text that needs to be completed and call currentCompletion(). You can iterate through the list of completions as below: \snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 2 completionCount() returns the total number of completions for the current prefix. completionCount() should be avoided when possible, since it requires a scan of the entire model. \section1 The Completion Model completionModel() return a list model that contains all possible completions for the current completion prefix, in the order in which they appear in the model. This model can be used to display the current completions in a custom view. Calling setCompletionPrefix() automatically refreshes the completion model. \section1 Handling Tree Models KexiCompleter can look for completions in tree models, assuming that any item (or sub-item or sub-sub-item) can be unambiguously represented as a string by specifying the path to the item. The completion is then performed one level at a time. Let's take the example of a user typing in a file system path. The model is a (hierarchical) QFileSystemModel. The completion occurs for every element in the path. For example, if the current text is \c C:\Wind, KexiCompleter might suggest \c Windows to complete the current path element. Similarly, if the current text is \c C:\Windows\Sy, KexiCompleter might suggest \c System. For this kind of completion to work, KexiCompleter needs to be able to split the path into a list of strings that are matched at each level. For \c C:\Windows\Sy, it needs to be split as "C:", "Windows" and "Sy". The default implementation of splitPath(), splits the completionPrefix using QDir::separator() if the model is a QFileSystemModel. To provide completions, KexiCompleter needs to know the path from an index. This is provided by pathFromIndex(). The default implementation of pathFromIndex(), returns the data for the \l{Qt::EditRole}{edit role} for list models and the absolute file path if the mode is a QFileSystemModel. \sa QAbstractItemModel, QLineEdit, QComboBox, {Completer Example} */ #include "KexiCompleter_p.h" #ifndef QT_NO_COMPLETER #include #include #include #include #include #include #include #include #include #include #include class KexiEmptyItemModel : public QAbstractItemModel { Q_OBJECT public: explicit KexiEmptyItemModel(QObject *parent = 0) : QAbstractItemModel(parent) {} - QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); } - QModelIndex parent(const QModelIndex &) const { return QModelIndex(); } - int rowCount(const QModelIndex &) const { return 0; } - int columnCount(const QModelIndex &) const { return 0; } - bool hasChildren(const QModelIndex &) const { return false; } - QVariant data(const QModelIndex &, int) const { return QVariant(); } + QModelIndex index(int, int, const QModelIndex &) const override { return QModelIndex(); } + QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); } + int rowCount(const QModelIndex &) const override { return 0; } + int columnCount(const QModelIndex &) const override { return 0; } + bool hasChildren(const QModelIndex &) const override { return false; } + QVariant data(const QModelIndex &, int) const override { return QVariant(); } }; Q_GLOBAL_STATIC(KexiEmptyItemModel, kexiEmptyModel) QAbstractItemModel *KexiAbstractItemModelPrivate::staticEmptyModel() { return kexiEmptyModel(); } namespace { struct DefaultRoleNames : public QHash { DefaultRoleNames() { (*this)[Qt::DisplayRole] = "display"; (*this)[Qt::DecorationRole] = "decoration"; (*this)[Qt::EditRole] = "edit"; (*this)[Qt::ToolTipRole] = "toolTip"; (*this)[Qt::StatusTipRole] = "statusTip"; (*this)[Qt::WhatsThisRole] = "whatsThis"; } }; } Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames) const QHash &KexiAbstractItemModelPrivate::defaultRoleNames() { return *qDefaultRoleNames(); } KexiCompletionModel::KexiCompletionModel(KexiCompleterPrivate *c, QObject *parent) : QAbstractProxyModel(parent), c(c), showAll(false), d(new KexiCompletionModelPrivate(this)) { QAbstractProxyModel::setSourceModel(KexiAbstractItemModelPrivate::staticEmptyModel()); createEngine(); } KexiCompletionModel::~KexiCompletionModel() { delete d; } int KexiCompletionModel::columnCount(const QModelIndex &) const { return sourceModel()->columnCount(); } void KexiCompletionModel::setSourceModel(QAbstractItemModel *source) { bool hadModel = (sourceModel() != 0); if (hadModel) QObject::disconnect(sourceModel(), 0, this, 0); QAbstractProxyModel::setSourceModel(source ? source : KexiAbstractItemModelPrivate::staticEmptyModel()); if (source) { // TODO: Optimize updates in the source model connect(source, SIGNAL(modelReset()), this, SLOT(invalidate())); connect(source, SIGNAL(destroyed()), this, SLOT(modelDestroyed())); connect(source, SIGNAL(layoutChanged()), this, SLOT(invalidate())); connect(source, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted())); connect(source, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(invalidate())); connect(source, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(invalidate())); connect(source, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(invalidate())); connect(source, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(invalidate())); } invalidate(); } void KexiCompletionModel::createEngine() { bool sortedEngine = false; switch (c->sorting) { case KexiCompleter::UnsortedModel: sortedEngine = false; break; case KexiCompleter::CaseSensitivelySortedModel: sortedEngine = c->cs == Qt::CaseSensitive; break; case KexiCompleter::CaseInsensitivelySortedModel: sortedEngine = c->cs == Qt::CaseInsensitive; break; } if (sortedEngine) engine.reset(new QSortedModelEngine(c)); else engine.reset(new QUnsortedModelEngine(c)); } QModelIndex KexiCompletionModel::mapToSource(const QModelIndex& index) const { if (!index.isValid()) return engine->curParent; int row; QModelIndex parent = engine->curParent; if (!showAll) { if (!engine->matchCount()) return QModelIndex(); Q_ASSERT(index.row() < engine->matchCount()); KexiIndexMapper& rootIndices = engine->historyMatch.indices; if (index.row() < rootIndices.count()) { row = rootIndices[index.row()]; parent = QModelIndex(); } else { row = engine->curMatch.indices[index.row() - rootIndices.count()]; } } else { row = index.row(); } return sourceModel()->index(row, index.column(), parent); } QModelIndex KexiCompletionModel::mapFromSource(const QModelIndex& idx) const { if (!idx.isValid()) return QModelIndex(); int row = -1; if (!showAll) { if (!engine->matchCount()) return QModelIndex(); KexiIndexMapper& rootIndices = engine->historyMatch.indices; if (idx.parent().isValid()) { if (idx.parent() != engine->curParent) return QModelIndex(); } else { row = rootIndices.indexOf(idx.row()); if (row == -1 && engine->curParent.isValid()) return QModelIndex(); // source parent and our parent don't match } if (row == -1) { KexiIndexMapper& indices = engine->curMatch.indices; engine->filterOnDemand(idx.row() - indices.last()); row = indices.indexOf(idx.row()) + rootIndices.count(); } if (row == -1) return QModelIndex(); } else { if (idx.parent() != engine->curParent) return QModelIndex(); row = idx.row(); } return createIndex(row, idx.column()); } bool KexiCompletionModel::setCurrentRow(int row) { if (row < 0 || !engine->matchCount()) return false; if (row >= engine->matchCount()) engine->filterOnDemand(row + 1 - engine->matchCount()); if (row >= engine->matchCount()) // invalid row return false; engine->curRow = row; return true; } QModelIndex KexiCompletionModel::currentIndex(bool sourceIndex) const { if (!engine->matchCount()) return QModelIndex(); int row = engine->curRow; if (showAll) row = engine->curMatch.indices[engine->curRow]; QModelIndex idx = createIndex(row, c->column); if (!sourceIndex) return idx; return mapToSource(idx); } QModelIndex KexiCompletionModel::index(int row, int column, const QModelIndex& parent) const { if (row < 0 || column < 0 || column >= columnCount(parent) || parent.isValid()) return QModelIndex(); if (!showAll) { if (!engine->matchCount()) return QModelIndex(); if (row >= engine->historyMatch.indices.count()) { int want = row + 1 - engine->matchCount(); if (want > 0) engine->filterOnDemand(want); if (row >= engine->matchCount()) return QModelIndex(); } } else { if (row >= sourceModel()->rowCount(engine->curParent)) return QModelIndex(); } return createIndex(row, column); } int KexiCompletionModel::completionCount() const { if (!engine->matchCount()) return 0; engine->filterOnDemand(INT_MAX); return engine->matchCount(); } int KexiCompletionModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; if (showAll) { // Show all items below current parent, even if we have no valid matches if (engine->curParts.count() != 1 && !engine->matchCount() && !engine->curParent.isValid()) return 0; return sourceModel()->rowCount(engine->curParent); } return completionCount(); } void KexiCompletionModel::setFiltered(bool filtered) { if (showAll == !filtered) return; showAll = !filtered; resetModel(); } bool KexiCompletionModel::hasChildren(const QModelIndex &parent) const { if (parent.isValid()) return false; if (showAll) return sourceModel()->hasChildren(mapToSource(parent)); if (!engine->matchCount()) return false; return true; } QVariant KexiCompletionModel::data(const QModelIndex& index, int role) const { return sourceModel()->data(mapToSource(index), role); } void KexiCompletionModel::modelDestroyed() { QAbstractProxyModel::setSourceModel(0); // switch to static empty model invalidate(); } void KexiCompletionModel::rowsInserted() { invalidate(); emit rowsAdded(); } void KexiCompletionModel::invalidate() { engine->cache.clear(); filter(engine->curParts); } void KexiCompletionModel::filter(const QStringList& parts) { engine->filter(parts); resetModel(); if (sourceModel()->canFetchMore(engine->curParent)) sourceModel()->fetchMore(engine->curParent); } void KexiCompletionModel::resetModel() { if (rowCount() == 0) { beginResetModel(); endResetModel(); return; } emit layoutAboutToBeChanged(); QModelIndexList piList = persistentIndexList(); QModelIndexList empty; for (int i = 0; i < piList.size(); i++) empty.append(QModelIndex()); changePersistentIndexList(piList, empty); emit layoutChanged(); } ////////////////////////////////////////////////////////////////////////////// void KexiCompletionEngine::filter(const QStringList& parts) { const QAbstractItemModel *model = c->proxy->sourceModel(); curParts = parts; if (curParts.isEmpty()) curParts.append(QString()); curRow = -1; curParent = QModelIndex(); curMatch = KexiMatchData(); historyMatch = filterHistory(); if (!model) return; QModelIndex parent; for (int i = 0; i < curParts.count() - 1; i++) { QString part = curParts[i]; int emi = filter(part, parent, -1).exactMatchIndex; if (emi == -1) return; parent = model->index(emi, c->column, parent); } // Note that we set the curParent to a valid parent, even if we have no matches // When filtering is disabled, we show all the items under this parent curParent = parent; if (curParts.last().isEmpty()) curMatch = KexiMatchData(KexiIndexMapper(0, model->rowCount(curParent) - 1), -1, false); else curMatch = filter(curParts.last(), curParent, 1); // build at least one curRow = curMatch.isValid() ? 0 : -1; } inline bool matchPrefix(const QString& s1, const QString& s2, Qt::CaseSensitivity cs) { return s1.startsWith(s2, cs); } inline bool matchSubstring(const QString& s1, const QString& s2, Qt::CaseSensitivity cs) { return s1.contains(s2, cs); } typedef bool (*MatchFunction)(const QString&, const QString&, Qt::CaseSensitivity); KexiMatchData KexiCompletionEngine::filterHistory() { QAbstractItemModel *source = c->proxy->sourceModel(); if (curParts.count() <= 1 || c->proxy->showAll || !source) return KexiMatchData(); #ifdef QT_NO_DIRMODEL bool isDirModel = false; #else bool isDirModel = qobject_cast(source) != 0; #endif #ifdef QT_NO_FILESYSTEMMODEL bool isFsModel = false; #else bool isFsModel = qobject_cast(source) != 0; #endif QVector v; KexiIndexMapper im(v); KexiMatchData m(im, -1, true); MatchFunction matchFunction = c->substringCompletion ? &matchSubstring : &matchPrefix; for (int i = 0; i < source->rowCount(); i++) { QString str = source->index(i, c->column).data().toString(); if (matchFunction(str, c->prefix, c->cs) #if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN) && ((!isFsModel && !isDirModel) || QDir::toNativeSeparators(str) != QDir::separator()) #endif ) m.indices.append(i); } return m; } // Returns a match hint from the cache by chopping the search string bool KexiCompletionEngine::matchHint(QString part, const QModelIndex& parent, KexiMatchData *hint) { if (c->cs == Qt::CaseInsensitive) part = part.toLower(); const CacheItem& map = cache[parent]; QString key = part; while (!key.isEmpty()) { key.chop(1); if (map.contains(key)) { *hint = map[key]; return true; } } return false; } bool KexiCompletionEngine::lookupCache(QString part, const QModelIndex& parent, KexiMatchData *m) { if (c->cs == Qt::CaseInsensitive) part = part.toLower(); const CacheItem& map = cache[parent]; if (!map.contains(part)) return false; *m = map[part]; return true; } // When the cache size exceeds 1MB, it clears out about 1/2 of the cache. void KexiCompletionEngine::saveInCache(QString part, const QModelIndex& parent, const KexiMatchData& m) { KexiMatchData old = cache[parent].take(part); cost = cost + m.indices.cost() - old.indices.cost(); if (cost * sizeof(int) > 1024 * 1024) { QMap::iterator it1 = cache.begin(); while (it1 != cache.end()) { CacheItem& ci = it1.value(); int sz = ci.count()/2; QMap::iterator it2 = ci.begin(); int i = 0; while (it2 != ci.end() && i < sz) { cost -= it2.value().indices.cost(); it2 = ci.erase(it2); i++; } if (ci.count() == 0) { it1 = cache.erase(it1); } else { ++it1; } } } if (c->cs == Qt::CaseInsensitive) part = part.toLower(); cache[parent][part] = m; } /////////////////////////////////////////////////////////////////////////////////// KexiIndexMapper QSortedModelEngine::indexHint(QString part, const QModelIndex& parent, Qt::SortOrder order) { const QAbstractItemModel *model = c->proxy->sourceModel(); if (c->cs == Qt::CaseInsensitive) part = part.toLower(); const CacheItem& map = cache[parent]; // Try to find a lower and upper bound for the search from previous results int to = model->rowCount(parent) - 1; int from = 0; const CacheItem::const_iterator it = map.lowerBound(part); // look backward for first valid hint for(CacheItem::const_iterator it1 = it; it1-- != map.constBegin();) { const KexiMatchData& value = it1.value(); if (value.isValid()) { if (order == Qt::AscendingOrder) { from = value.indices.last() + 1; } else { to = value.indices.first() - 1; } break; } } // look forward for first valid hint for(CacheItem::const_iterator it2 = it; it2 != map.constEnd(); ++it2) { const KexiMatchData& value = it2.value(); if (value.isValid() && !it2.key().startsWith(part)) { if (order == Qt::AscendingOrder) { to = value.indices.first() - 1; } else { from = value.indices.first() + 1; } break; } } return KexiIndexMapper(from, to); } Qt::SortOrder QSortedModelEngine::sortOrder(const QModelIndex &parent) const { const QAbstractItemModel *model = c->proxy->sourceModel(); int rowCount = model->rowCount(parent); if (rowCount < 2) return Qt::AscendingOrder; QString first = model->data(model->index(0, c->column, parent), c->role).toString(); QString last = model->data(model->index(rowCount - 1, c->column, parent), c->role).toString(); return QString::compare(first, last, c->cs) <= 0 ? Qt::AscendingOrder : Qt::DescendingOrder; } KexiMatchData QSortedModelEngine::filter(const QString& part, const QModelIndex& parent, int) { const QAbstractItemModel *model = c->proxy->sourceModel(); KexiMatchData hint; if (lookupCache(part, parent, &hint)) return hint; KexiIndexMapper indices; Qt::SortOrder order = sortOrder(parent); if (matchHint(part, parent, &hint)) { if (!hint.isValid()) return KexiMatchData(); indices = hint.indices; } else { indices = indexHint(part, parent, order); } // binary search the model within 'indices' for 'part' under 'parent' int high = indices.to() + 1; int low = indices.from() - 1; int probe; QModelIndex probeIndex; QString probeData; while (high - low > 1) { probe = (high + low) / 2; probeIndex = model->index(probe, c->column, parent); probeData = model->data(probeIndex, c->role).toString(); const int cmp = QString::compare(probeData, part, c->cs); if ((order == Qt::AscendingOrder && cmp >= 0) || (order == Qt::DescendingOrder && cmp < 0)) { high = probe; } else { low = probe; } } if ((order == Qt::AscendingOrder && low == indices.to()) || (order == Qt::DescendingOrder && high == indices.from())) { // not found saveInCache(part, parent, KexiMatchData()); return KexiMatchData(); } probeIndex = model->index(order == Qt::AscendingOrder ? low+1 : high-1, c->column, parent); probeData = model->data(probeIndex, c->role).toString(); if (!probeData.startsWith(part, c->cs)) { saveInCache(part, parent, KexiMatchData()); return KexiMatchData(); } const bool exactMatch = QString::compare(probeData, part, c->cs) == 0; int emi = exactMatch ? (order == Qt::AscendingOrder ? low+1 : high-1) : -1; int from = 0; int to = 0; if (order == Qt::AscendingOrder) { from = low + 1; high = indices.to() + 1; low = from; } else { to = high - 1; low = indices.from() - 1; high = to; } while (high - low > 1) { probe = (high + low) / 2; probeIndex = model->index(probe, c->column, parent); probeData = model->data(probeIndex, c->role).toString(); const bool startsWith = probeData.startsWith(part, c->cs); if ((order == Qt::AscendingOrder && startsWith) || (order == Qt::DescendingOrder && !startsWith)) { low = probe; } else { high = probe; } } KexiMatchData m(order == Qt::AscendingOrder ? KexiIndexMapper(from, high - 1) : KexiIndexMapper(low+1, to), emi, false); saveInCache(part, parent, m); return m; } //////////////////////////////////////////////////////////////////////////////////////// int QUnsortedModelEngine::buildIndices(const QString& str, const QModelIndex& parent, int n, const KexiIndexMapper& indices, KexiMatchData* m) { Q_ASSERT(m->partial); Q_ASSERT(n != -1 || m->exactMatchIndex == -1); const QAbstractItemModel *model = c->proxy->sourceModel(); int i, count = 0; MatchFunction matchFunction = c->substringCompletion ? &matchSubstring : &matchPrefix; for (i = 0; i < indices.count() && count != n; ++i) { QModelIndex idx = model->index(indices[i], c->column, parent); QString data = model->data(idx, c->role).toString(); if (!matchFunction(data, str, c->cs) || !(model->flags(idx) & Qt::ItemIsSelectable)) continue; m->indices.append(indices[i]); ++count; if (m->exactMatchIndex == -1 && QString::compare(data, str, c->cs) == 0) { m->exactMatchIndex = indices[i]; if (n == -1) return indices[i]; } } return indices[i-1]; } void QUnsortedModelEngine::filterOnDemand(int n) { Q_ASSERT(matchCount()); if (!curMatch.partial) return; Q_ASSERT(n >= -1); const QAbstractItemModel *model = c->proxy->sourceModel(); int lastRow = model->rowCount(curParent) - 1; KexiIndexMapper im(curMatch.indices.last() + 1, lastRow); int lastIndex = buildIndices(curParts.last(), curParent, n, im, &curMatch); curMatch.partial = (lastRow != lastIndex); saveInCache(curParts.last(), curParent, curMatch); } KexiMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& parent, int n) { KexiMatchData hint; QVector v; KexiIndexMapper im(v); KexiMatchData m(im, -1, true); const QAbstractItemModel *model = c->proxy->sourceModel(); bool foundInCache = lookupCache(part, parent, &m); if (!foundInCache) { if (matchHint(part, parent, &hint) && !hint.isValid()) return KexiMatchData(); } if (!foundInCache && !hint.isValid()) { const int lastRow = model->rowCount(parent) - 1; KexiIndexMapper all(0, lastRow); int lastIndex = buildIndices(part, parent, n, all, &m); m.partial = (lastIndex != lastRow); } else { if (!foundInCache) { // build from hint as much as we can buildIndices(part, parent, INT_MAX, hint.indices, &m); m.partial = hint.partial; } if (m.partial && ((n == -1 && m.exactMatchIndex == -1) || (m.indices.count() < n))) { // need more and have more const int lastRow = model->rowCount(parent) - 1; KexiIndexMapper rest(hint.indices.last() + 1, lastRow); int want = n == -1 ? -1 : n - m.indices.count(); int lastIndex = buildIndices(part, parent, want, rest, &m); m.partial = (lastRow != lastIndex); } } saveInCache(part, parent, m); return m; } /////////////////////////////////////////////////////////////////////////////// KexiCompleterPrivate::KexiCompleterPrivate(KexiCompleter *qq) : widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), substringCompletion(false), role(Qt::EditRole), column(0), maxVisibleItems(7), sorting(KexiCompleter::UnsortedModel), wrap(true), eatFocusOut(true), hiddenBecauseNoMatch(false), q(qq) { } void KexiCompleterPrivate::init(QAbstractItemModel *m) { proxy = new KexiCompletionModel(this, q); QObject::connect(proxy, SIGNAL(rowsAdded()), q, SLOT(_q_autoResizePopup())); q->setModel(m); #ifdef QT_NO_LISTVIEW q->setCompletionMode(KexiCompleter::InlineCompletion); #else q->setCompletionMode(KexiCompleter::PopupCompletion); #endif // QT_NO_LISTVIEW } void KexiCompleterPrivate::setCurrentIndex(QModelIndex index, bool select) { if (!q->popup()) return; if (!select) { popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } else { if (!index.isValid()) popup->selectionModel()->clear(); else popup->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); } index = popup->selectionModel()->currentIndex(); if (!index.isValid()) popup->scrollToTop(); else popup->scrollTo(index, QAbstractItemView::PositionAtTop); } void KexiCompleterPrivate::_q_completionSelected(const QItemSelection& selection) { QModelIndex index; if (!selection.indexes().isEmpty()) index = selection.indexes().first(); _q_complete(index, true); } void KexiCompleterPrivate::_q_complete(QModelIndex index, bool highlighted) { QString completion; if (!index.isValid() || (!proxy->showAll && (index.row() >= proxy->engine->matchCount()))) { completion = prefix; } else { if (!(index.flags() & Qt::ItemIsEnabled)) return; QModelIndex si = proxy->mapToSource(index); si = si.sibling(si.row(), column); // for clicked() completion = q->pathFromIndex(si); #ifndef QT_NO_DIRMODEL // add a trailing separator in inline if (mode == KexiCompleter::InlineCompletion) { if (qobject_cast(proxy->sourceModel()) && QFileInfo(completion).isDir()) completion += QDir::separator(); } #endif #ifndef QT_NO_FILESYSTEMMODEL // add a trailing separator in inline if (mode == KexiCompleter::InlineCompletion) { if (qobject_cast(proxy->sourceModel()) && QFileInfo(completion).isDir()) completion += QDir::separator(); } #endif } if (highlighted) { emit q->highlighted(index); emit q->highlighted(completion); } else { emit q->activated(index); emit q->activated(completion); } } void KexiCompleterPrivate::_q_autoResizePopup() { if (!popup || !popup->isVisible()) return; showPopup(popupRect); } static void adjustPopupGeometry(QWidget *popupWidget, QWidget *widget, int widthHint, int heightHint, const QRect ¤tRect) { const QRect screen = QApplication::desktop()->availableGeometry(widget); const Qt::LayoutDirection dir = widget->layoutDirection(); QPoint pos; int rh, w; int h = heightHint; if (currentRect.isValid()) { rh = currentRect.height(); w = currentRect.width(); pos = widget->mapToGlobal(dir == Qt::RightToLeft ? currentRect.bottomRight() : currentRect.bottomLeft()); } else { rh = widget->height(); pos = widget->mapToGlobal(QPoint(0, widget->height() - 2)); w = widget->width(); } if (widthHint > w) { w = widthHint; } if (w > screen.width()) w = screen.width(); if ((pos.x() + w) > (screen.x() + screen.width())) pos.setX(screen.x() + screen.width() - w); if (pos.x() < screen.x()) pos.setX(screen.x()); int top = pos.y() - rh - screen.top() + 2; int bottom = screen.bottom() - pos.y(); h = qMax(h, popupWidget->minimumHeight()); if (h > bottom) { h = qMin(qMax(top, bottom), h); if (top > bottom) pos.setY(pos.y() - h - rh + 2); } popupWidget->setGeometry(pos.x(), pos.y(), w, h); } void KexiCompleterPrivate::showPopup(const QRect& rect) { int widthHint = popup->sizeHintForColumn(0); QScrollBar *vsb = popup->verticalScrollBar(); if (vsb) { widthHint += vsb->sizeHint().width() + 3 + 3; } int heightHint = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3; QScrollBar *hsb = popup->horizontalScrollBar(); if (hsb && hsb->isVisible()) { heightHint += hsb->sizeHint().height(); } adjustPopupGeometry(popup, widget, widthHint, heightHint, rect); if (!popup->isVisible()) popup->show(); } void KexiCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path) { // Slot called when QFileSystemModel has finished loading. // If we hide the popup because there was no match because the model was not loaded yet, // we re-start the completion when we get the results if (hiddenBecauseNoMatch && prefix.startsWith(path) && prefix != (path + QLatin1Char('/')) && widget) { q->complete(); } } /*! Constructs a completer object with the given \a parent. */ KexiCompleter::KexiCompleter(QObject *parent) : QObject(parent), d(new KexiCompleterPrivate(this)) { d->init(); } /*! Constructs a completer object with the given \a parent that provides completions from the specified \a model. */ KexiCompleter::KexiCompleter(QAbstractItemModel *model, QObject *parent) : QObject(parent), d(new KexiCompleterPrivate(this)) { d->init(model); } #ifndef QT_NO_STRINGLISTMODEL /*! Constructs a KexiCompleter object with the given \a parent that uses the specified \a list as a source of possible completions. */ KexiCompleter::KexiCompleter(const QStringList& list, QObject *parent) : QObject(parent), d(new KexiCompleterPrivate(this)) { d->init(new QStringListModel(list, this)); } #endif // QT_NO_STRINGLISTMODEL /*! Destroys the completer object. */ KexiCompleter::~KexiCompleter() { delete d; } /*! Sets the widget for which completion are provided for to \a widget. This function is automatically called when a KexiCompleter is set on a QLineEdit using QLineEdit::setCompleter() or on a QComboBox using QComboBox::setCompleter(). The widget needs to be set explicitly when providing completions for custom widgets. \sa widget(), setModel(), setPopup() */ void KexiCompleter::setWidget(QWidget *widget) { if (widget && d->widget == widget) return; if (d->widget) d->widget->removeEventFilter(this); d->widget = widget; if (d->widget) d->widget->installEventFilter(this); if (d->popup) { d->popup->hide(); d->popup->setFocusProxy(d->widget); } } /*! Returns the widget for which the completer object is providing completions. \sa setWidget() */ QWidget *KexiCompleter::widget() const { return d->widget; } /*! Sets the model which provides completions to \a model. The \a model can be list model or a tree model. If a model has been already previously set and it has the KexiCompleter as its parent, it is deleted. For convenience, if \a model is a QFileSystemModel, KexiCompleter switches its caseSensitivity to Qt::CaseInsensitive on Windows and Qt::CaseSensitive on other platforms. \sa completionModel(), modelSorting, {Handling Tree Models} */ void KexiCompleter::setModel(QAbstractItemModel *model) { QAbstractItemModel *oldModel = d->proxy->sourceModel(); d->proxy->setSourceModel(model); if (d->popup) setPopup(d->popup); // set the model and make new connections if (oldModel && oldModel->QObject::parent() == this) delete oldModel; #ifndef QT_NO_DIRMODEL if (qobject_cast(model)) { #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) setCaseSensitivity(Qt::CaseInsensitive); #else setCaseSensitivity(Qt::CaseSensitive); #endif } #endif // QT_NO_DIRMODEL #ifndef QT_NO_FILESYSTEMMODEL QFileSystemModel *fsModel = qobject_cast(model); if (fsModel) { #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) setCaseSensitivity(Qt::CaseInsensitive); #else setCaseSensitivity(Qt::CaseSensitive); #endif setCompletionRole(QFileSystemModel::FileNameRole); connect(fsModel, SIGNAL(directoryLoaded(QString)), this, SLOT(_q_fileSystemModelDirectoryLoaded(QString))); } #endif // QT_NO_FILESYSTEMMODEL } /*! Returns the model that provides completion strings. \sa completionModel() */ QAbstractItemModel *KexiCompleter::model() const { return d->proxy->sourceModel(); } /*! \enum KexiCompleter::CompletionMode This enum specifies how completions are provided to the user. \value PopupCompletion Current completions are displayed in a popup window. \value InlineCompletion Completions appear inline (as selected text). \value UnfilteredPopupCompletion All possible completions are displayed in a popup window with the most likely suggestion indicated as current. \sa setCompletionMode() */ /*! \property KexiCompleter::completionMode \brief how the completions are provided to the user The default value is KexiCompleter::PopupCompletion. */ void KexiCompleter::setCompletionMode(KexiCompleter::CompletionMode mode) { d->mode = mode; d->proxy->setFiltered(mode != KexiCompleter::UnfilteredPopupCompletion); if (mode == KexiCompleter::InlineCompletion) { if (d->widget) d->widget->removeEventFilter(this); if (d->popup) { d->popup->deleteLater(); d->popup = 0; } } else { if (d->widget) d->widget->installEventFilter(this); } } KexiCompleter::CompletionMode KexiCompleter::completionMode() const { return d->mode; } /*! Sets the popup used to display completions to \a popup. KexiCompleter takes ownership of the view. A QListView is automatically created when the completionMode() is set to KexiCompleter::PopupCompletion or KexiCompleter::UnfilteredPopupCompletion. The default popup displays the completionColumn(). Ensure that this function is called before the view settings are modified. This is required since view's properties may require that a model has been set on the view (for example, hiding columns in the view requires a model to be set on the view). \sa popup() */ void KexiCompleter::setPopup(QAbstractItemView *popup) { Q_ASSERT(popup != 0); if (d->popup) { QObject::disconnect(d->popup->selectionModel(), 0, this, 0); QObject::disconnect(d->popup, 0, this, 0); } if (d->popup != popup) delete d->popup; if (popup->model() != d->proxy) popup->setModel(d->proxy); #if defined(Q_OS_MACOS) && !defined(QT_MAC_USE_COCOA) popup->show(); #else popup->hide(); #endif Qt::FocusPolicy origPolicy = Qt::NoFocus; if (d->widget) origPolicy = d->widget->focusPolicy(); popup->setParent(0, Qt::Popup); popup->setFocusPolicy(Qt::NoFocus); if (d->widget) d->widget->setFocusPolicy(origPolicy); popup->setFocusProxy(d->widget); popup->installEventFilter(this); popup->setItemDelegate(new KexiCompleterItemDelegate(popup)); #ifndef QT_NO_LISTVIEW if (QListView *listView = qobject_cast(popup)) { listView->setModelColumn(d->column); } #endif QObject::connect(popup, SIGNAL(clicked(QModelIndex)), this, SLOT(_q_complete(QModelIndex))); QObject::connect(this, SIGNAL(activated(QModelIndex)), popup, SLOT(hide())); QObject::connect(popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(_q_completionSelected(QItemSelection))); d->popup = popup; } /*! Returns the popup used to display completions. \sa setPopup() */ QAbstractItemView *KexiCompleter::popup() const { #ifndef QT_NO_LISTVIEW if (!d->popup && completionMode() != KexiCompleter::InlineCompletion) { QListView *listView = new QListView; listView->setEditTriggers(QAbstractItemView::NoEditTriggers); listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); listView->setSelectionBehavior(QAbstractItemView::SelectRows); listView->setSelectionMode(QAbstractItemView::SingleSelection); listView->setModelColumn(d->column); KexiCompleter *that = const_cast(this); that->setPopup(listView); } #endif // QT_NO_LISTVIEW return d->popup; } /*! \reimp */ bool KexiCompleter::event(QEvent *ev) { return QObject::event(ev); } /*! \reimp */ bool KexiCompleter::eventFilter(QObject *o, QEvent *e) { if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) { d->hiddenBecauseNoMatch = false; if (d->popup && d->popup->isVisible()) return true; } if (o != d->popup) return QObject::eventFilter(o, e); switch (e->type()) { case QEvent::KeyPress: { QKeyEvent *ke = static_cast(e); QModelIndex curIndex = d->popup->currentIndex(); QModelIndexList selList = d->popup->selectionModel()->selectedIndexes(); const int key = ke->key(); // In UnFilteredPopup mode, select the current item if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid() && d->mode == KexiCompleter::UnfilteredPopupCompletion) { d->setCurrentIndex(curIndex); return true; } // Handle popup navigation keys. These are hardcoded because up/down might make the // widget do something else (lineedit cursor moves to home/end on mac, for instance) switch (key) { case Qt::Key_End: case Qt::Key_Home: if (ke->modifiers() & Qt::ControlModifier) return false; break; case Qt::Key_Up: if (!curIndex.isValid()) { int rowCount = d->proxy->rowCount(); QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column); d->setCurrentIndex(lastIndex); return true; } else if (curIndex.row() == 0) { if (d->wrap) d->setCurrentIndex(QModelIndex()); return true; } return false; case Qt::Key_Down: if (!curIndex.isValid()) { QModelIndex firstIndex = d->proxy->index(0, d->column); d->setCurrentIndex(firstIndex); return true; } else if (curIndex.row() == d->proxy->rowCount() - 1) { if (d->wrap) d->setCurrentIndex(QModelIndex()); return true; } return false; case Qt::Key_PageUp: case Qt::Key_PageDown: return false; } // Send the event to the widget. If the widget accepted the event, do nothing // If the widget did not accept the event, provide a default implementation d->eatFocusOut = false; (static_cast(d->widget))->event(ke); d->eatFocusOut = true; if (!d->widget || e->isAccepted() || !d->popup->isVisible()) { // widget lost focus, hide the popup if (d->widget && (!d->widget->hasFocus() #ifdef QT_KEYPAD_NAVIGATION || (QApplication::keypadNavigationEnabled() && !d->widget->hasEditFocus()) #endif )) d->popup->hide(); if (e->isAccepted()) return true; } // default implementation for keys not handled by the widget when popup is open switch (key) { #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: if (!QApplication::keypadNavigationEnabled()) break; #endif case Qt::Key_Return: case Qt::Key_Enter: case Qt::Key_Tab: d->popup->hide(); if (curIndex.isValid()) d->_q_complete(curIndex); break; case Qt::Key_F4: if (ke->modifiers() & Qt::AltModifier) d->popup->hide(); break; case Qt::Key_Backtab: case Qt::Key_Escape: d->popup->hide(); break; default: break; } return true; } #ifdef QT_KEYPAD_NAVIGATION case QEvent::KeyRelease: { QKeyEvent *ke = static_cast(e); if (QApplication::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) { // Send the event to the 'widget'. This is what we did for KeyPress, so we need // to do the same for KeyRelease, in case the widget's KeyPress event set // up something (such as a timer) that is relying on also receiving the // key release. I see this as a bug in Qt, and should really set it up for all // the affected keys. However, it is difficult to tell how this will affect // existing code, and I can't test for every combination! d->eatFocusOut = false; static_cast(d->widget)->event(ke); d->eatFocusOut = true; } break; } #endif case QEvent::MouseButtonPress: { #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) { // if we've clicked in the widget (or its descendant), let it handle the click QWidget *source = qobject_cast(o); if (source) { QPoint pos = source->mapToGlobal((static_cast(e))->pos()); QWidget *target = QApplication::widgetAt(pos); if (target && (d->widget->isAncestorOf(target) || target == d->widget)) { d->eatFocusOut = false; static_cast(target)->event(e); d->eatFocusOut = true; return true; } } } #endif if (!d->popup->underMouse()) { d->popup->hide(); return true; } } return false; case QEvent::InputMethod: case QEvent::ShortcutOverride: QApplication::sendEvent(d->widget, e); break; default: return false; } return false; } /*! For KexiCompleter::PopupCompletion and KexiCompleter::UnfilteredPopupCompletion modes, calling this function displays the popup displaying the current completions. By default, if \a rect is not specified, the popup is displayed on the bottom of the widget(). If \a rect is specified the popup is displayed on the left edge of the rectangle. For KexiCompleter::InlineCompletion mode, the highlighted() signal is fired with the current completion. */ void KexiCompleter::complete(const QRect& rect) { QModelIndex idx = d->proxy->currentIndex(false); d->hiddenBecauseNoMatch = false; if (d->mode == KexiCompleter::InlineCompletion) { if (idx.isValid()) d->_q_complete(idx, true); return; } Q_ASSERT(d->widget != 0); if ((d->mode == KexiCompleter::PopupCompletion && !idx.isValid()) || (d->mode == KexiCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) { if (d->popup) d->popup->hide(); // no suggestion, hide d->hiddenBecauseNoMatch = true; return; } popup(); if (d->mode == KexiCompleter::UnfilteredPopupCompletion) d->setCurrentIndex(idx, false); d->showPopup(rect); d->popupRect = rect; } /*! Sets the current row to the \a row specified. Returns true if successful; otherwise returns false. This function may be used along with currentCompletion() to iterate through all the possible completions. \sa currentCompletion(), completionCount() */ bool KexiCompleter::setCurrentRow(int row) { return d->proxy->setCurrentRow(row); } /*! Returns the current row. \sa setCurrentRow() */ int KexiCompleter::currentRow() const { return d->proxy->currentRow(); } /*! Returns the number of completions for the current prefix. For an unsorted model with a large number of items this can be expensive. Use setCurrentRow() and currentCompletion() to iterate through all the completions. */ int KexiCompleter::completionCount() const { return d->proxy->completionCount(); } /*! \enum KexiCompleter::ModelSorting This enum specifies how the items in the model are sorted. \value UnsortedModel The model is unsorted. \value CaseSensitivelySortedModel The model is sorted case sensitively. \value CaseInsensitivelySortedModel The model is sorted case insensitively. \sa setModelSorting() */ /*! \property KexiCompleter::modelSorting \brief the way the model is sorted By default, no assumptions are made about the order of the items in the model that provides the completions. If the model's data for the completionColumn() and completionRole() is sorted in ascending order, you can set this property to \l CaseSensitivelySortedModel or \l CaseInsensitivelySortedModel. On large models, this can lead to significant performance improvements because the completer object can then use a binary search algorithm instead of linear search algorithm. The sort order (i.e ascending or descending order) of the model is determined dynamically by inspecting the contents of the model. \bold{Note:} The performance improvements described above cannot take place when the completer's \l caseSensitivity is different to the case sensitivity used by the model's when sorting. \sa setCaseSensitivity(), KexiCompleter::ModelSorting */ void KexiCompleter::setModelSorting(KexiCompleter::ModelSorting sorting) { if (d->sorting == sorting) return; d->sorting = sorting; d->proxy->createEngine(); d->proxy->invalidate(); } KexiCompleter::ModelSorting KexiCompleter::modelSorting() const { return d->sorting; } /*! \property KexiCompleter::completionColumn \brief the column in the model in which completions are searched for. If the popup() is a QListView, it is automatically setup to display this column. By default, the match column is 0. \sa completionRole, caseSensitivity */ void KexiCompleter::setCompletionColumn(int column) { if (d->column == column) return; #ifndef QT_NO_LISTVIEW if (QListView *listView = qobject_cast(d->popup)) listView->setModelColumn(column); #endif d->column = column; d->proxy->invalidate(); } int KexiCompleter::completionColumn() const { return d->column; } /*! \property KexiCompleter::completionRole \brief the item role to be used to query the contents of items for matching. The default role is Qt::EditRole. \sa completionColumn, caseSensitivity */ void KexiCompleter::setCompletionRole(int role) { if (d->role == role) return; d->role = role; d->proxy->invalidate(); } int KexiCompleter::completionRole() const { return d->role; } /*! \brief the completions wrap around when navigating through items The default is true. */ void KexiCompleter::setWrapAround(bool wrap) { if (d->wrap == wrap) return; d->wrap = wrap; } bool KexiCompleter::wrapAround() const { return d->wrap; } /*! \property KexiCompleter::maxVisibleItems \brief the maximum allowed size on screen of the completer, measured in items By default, this property has a value of 7. */ int KexiCompleter::maxVisibleItems() const { return d->maxVisibleItems; } void KexiCompleter::setMaxVisibleItems(int maxItems) { if (maxItems < 0) { qWarning("KexiCompleter::setMaxVisibleItems: " "Invalid max visible items (%d) must be >= 0", maxItems); return; } d->maxVisibleItems = maxItems; } /*! \property KexiCompleter::caseSensitivity \brief the case sensitivity of the matching The default is Qt::CaseSensitive. \sa substringCompletion, completionColumn, completionRole, modelSorting */ void KexiCompleter::setCaseSensitivity(Qt::CaseSensitivity cs) { if (d->cs == cs) return; d->cs = cs; d->proxy->createEngine(); d->proxy->invalidate(); } Qt::CaseSensitivity KexiCompleter::caseSensitivity() const { return d->cs; } /*! \property KexiCompleter::substringCompletion \brief the completion uses any substring matching If true the completion uses any substring matching. If false prefix matching is used. The default is false. \sa caseSensitivity */ void KexiCompleter::setSubstringCompletion(bool substringCompletion) { if (d->substringCompletion == substringCompletion) return; d->substringCompletion = substringCompletion; d->proxy->invalidate(); } bool KexiCompleter::substringCompletion() const { return d->substringCompletion; } /*! \property KexiCompleter::completionPrefix \brief the completion prefix used to provide completions. The completionModel() is updated to reflect the list of possible matches for \a prefix. */ void KexiCompleter::setCompletionPrefix(const QString &prefix) { d->prefix = prefix; d->proxy->filter(splitPath(prefix)); } QString KexiCompleter::completionPrefix() const { return d->prefix; } /*! Returns the model index of the current completion in the completionModel(). \sa setCurrentRow(), currentCompletion(), model() */ QModelIndex KexiCompleter::currentIndex() const { return d->proxy->currentIndex(false); } /*! Returns the current completion string. This includes the \l completionPrefix. When used alongside setCurrentRow(), it can be used to iterate through all the matches. \sa setCurrentRow(), currentIndex() */ QString KexiCompleter::currentCompletion() const { return pathFromIndex(d->proxy->currentIndex(true)); } /*! Returns the completion model. The completion model is a read-only list model that contains all the possible matches for the current completion prefix. The completion model is auto-updated to reflect the current completions. \note The return value of this function is defined to be an QAbstractItemModel purely for generality. This actual kind of model returned is an instance of an QAbstractProxyModel subclass. \sa completionPrefix, model() */ QAbstractItemModel *KexiCompleter::completionModel() const { return d->proxy; } /*! Returns the path for the given \a index. The completer object uses this to obtain the completion text from the underlying model. The default implementation returns the \l{Qt::EditRole}{edit role} of the item for list models. It returns the absolute file path if the model is a QFileSystemModel. \sa splitPath() */ QString KexiCompleter::pathFromIndex(const QModelIndex& index) const { if (!index.isValid()) return QString(); QAbstractItemModel *sourceModel = d->proxy->sourceModel(); if (!sourceModel) return QString(); bool isDirModel = false; bool isFsModel = false; #ifndef QT_NO_DIRMODEL isDirModel = qobject_cast(d->proxy->sourceModel()) != 0; #endif #ifndef QT_NO_FILESYSTEMMODEL isFsModel = qobject_cast(d->proxy->sourceModel()) != 0; #endif if (!isDirModel && !isFsModel) return sourceModel->data(index, d->role).toString(); QModelIndex idx = index; QStringList list; do { QString t; if (isDirModel) t = sourceModel->data(idx, Qt::EditRole).toString(); #ifndef QT_NO_FILESYSTEMMODEL else t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString(); #endif list.prepend(t); QModelIndex parent = idx.parent(); idx = parent.sibling(parent.row(), index.column()); } while (idx.isValid()); #if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN) if (list.count() == 1) // only the separator or some other text return list[0]; list[0].clear(); // the join below will provide the separator #endif return list.join(QDir::separator()); } /*! Splits the given \a path into strings that are used to match at each level in the model(). The default implementation of splitPath() splits a file system path based on QDir::separator() when the sourceModel() is a QFileSystemModel. When used with list models, the first item in the returned list is used for matching. \sa pathFromIndex(), {Handling Tree Models} */ QStringList KexiCompleter::splitPath(const QString& path) const { bool isDirModel = false; bool isFsModel = false; #ifndef QT_NO_DIRMODEL isDirModel = qobject_cast(d->proxy->sourceModel()) != 0; #endif #ifndef QT_NO_FILESYSTEMMODEL #ifdef QT_NO_DIRMODEL #endif isFsModel = qobject_cast(d->proxy->sourceModel()) != 0; #endif if ((!isDirModel && !isFsModel) || path.isEmpty()) return QStringList(completionPrefix()); QString pathCopy = QDir::toNativeSeparators(path); QString sep = QDir::separator(); #if defined(Q_OS_SYMBIAN) if (pathCopy == QLatin1String("\\")) return QStringList(pathCopy); #elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (pathCopy == QLatin1String("\\") || pathCopy == QLatin1String("\\\\")) return QStringList(pathCopy); QString doubleSlash(QLatin1String("\\\\")); if (pathCopy.startsWith(doubleSlash)) pathCopy.remove(0, 2); else doubleSlash.clear(); #endif QRegularExpression re(QLatin1Char('[') + QRegularExpression::escape(sep) + QLatin1Char(']')); QStringList parts = pathCopy.split(re); #if defined(Q_OS_SYMBIAN) // Do nothing #elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (!doubleSlash.isEmpty()) parts[0].prepend(doubleSlash); #else if (pathCopy[0] == sep[0]) // readd the "/" at the beginning as the split removed it parts[0] = QDir::fromNativeSeparators(QString(sep[0])); #endif return parts; } /*! \fn void KexiCompleter::activated(const QModelIndex& index) This signal is sent when an item in the popup() is activated by the user. (by clicking or pressing return). The item's \a index in the completionModel() is given. */ /*! \fn void KexiCompleter::activated(const QString &text) This signal is sent when an item in the popup() is activated by the user (by clicking or pressing return). The item's \a text is given. */ /*! \fn void KexiCompleter::highlighted(const QModelIndex& index) This signal is sent when an item in the popup() is highlighted by the user. It is also sent if complete() is called with the completionMode() set to KexiCompleter::InlineCompletion. The item's \a index in the completionModel() is given. */ /*! \fn void KexiCompleter::highlighted(const QString &text) This signal is sent when an item in the popup() is highlighted by the user. It is also sent if complete() is called with the completionMode() set to KexiCompleter::InlineCompletion. The item's \a text is given. */ void KexiCompleter::_q_complete(const QModelIndex& index) { d->_q_complete(index); } void KexiCompleter::_q_completionSelected(const QItemSelection& selection) { d->_q_completionSelected(selection); } void KexiCompleter::_q_autoResizePopup() { d->_q_autoResizePopup(); } void KexiCompleter::_q_fileSystemModelDirectoryLoaded(const QString& dir) { d->_q_fileSystemModelDirectoryLoaded(dir); } KexiCompletionModelPrivate::KexiCompletionModelPrivate(KexiCompletionModel *q) : q(q) { } void KexiCompletionModelPrivate::_q_sourceModelDestroyed() { q->setSourceModel(KexiAbstractItemModelPrivate::staticEmptyModel()); } #include "KexiCompleter.moc" #endif // QT_NO_COMPLETER diff --git a/src/kexiutils/completer/KexiCompleter.h b/src/kexiutils/completer/KexiCompleter.h index 84577f592..5064c2552 100644 --- a/src/kexiutils/completer/KexiCompleter.h +++ b/src/kexiutils/completer/KexiCompleter.h @@ -1,170 +1,170 @@ /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef KEXICOMPLETER_H #define KEXICOMPLETER_H #include #include #include #include #include #ifndef QT_NO_COMPLETER class QAbstractItemView; class QWidget; class QItemSelection; class KexiCompleterPrivate; class KEXIUTILS_EXPORT KexiCompleter : public QObject { Q_OBJECT Q_PROPERTY(QString completionPrefix READ completionPrefix WRITE setCompletionPrefix) Q_PROPERTY(ModelSorting modelSorting READ modelSorting WRITE setModelSorting) Q_PROPERTY(CompletionMode completionMode READ completionMode WRITE setCompletionMode) Q_PROPERTY(int completionColumn READ completionColumn WRITE setCompletionColumn) Q_PROPERTY(int completionRole READ completionRole WRITE setCompletionRole) Q_PROPERTY(int maxVisibleItems READ maxVisibleItems WRITE setMaxVisibleItems) Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity) Q_PROPERTY(bool substringCompletion READ substringCompletion WRITE setSubstringCompletion) Q_PROPERTY(bool wrapAround READ wrapAround WRITE setWrapAround) public: enum CompletionMode { PopupCompletion, UnfilteredPopupCompletion, InlineCompletion }; enum ModelSorting { UnsortedModel = 0, CaseSensitivelySortedModel, CaseInsensitivelySortedModel }; explicit KexiCompleter(QObject *parent = 0); explicit KexiCompleter(QAbstractItemModel *model, QObject *parent = 0); #ifndef QT_NO_STRINGLISTMODEL explicit KexiCompleter(const QStringList& completions, QObject *parent = 0); #endif ~KexiCompleter(); void setWidget(QWidget *widget); QWidget *widget() const; void setModel(QAbstractItemModel *c); QAbstractItemModel *model() const; void setCompletionMode(CompletionMode mode); CompletionMode completionMode() const; QAbstractItemView *popup() const; void setPopup(QAbstractItemView *popup); void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity); Qt::CaseSensitivity caseSensitivity() const; void setSubstringCompletion(bool substringCompletion); bool substringCompletion() const; void setModelSorting(ModelSorting sorting); ModelSorting modelSorting() const; void setCompletionColumn(int column); int completionColumn() const; void setCompletionRole(int role); int completionRole() const; bool wrapAround() const; int maxVisibleItems() const; void setMaxVisibleItems(int maxItems); int completionCount() const; bool setCurrentRow(int row); int currentRow() const; QModelIndex currentIndex() const; QString currentCompletion() const; QAbstractItemModel *completionModel() const; QString completionPrefix() const; public Q_SLOTS: void setCompletionPrefix(const QString &prefix); void complete(const QRect& rect = QRect()); void setWrapAround(bool wrap); public: virtual QString pathFromIndex(const QModelIndex &index) const; virtual QStringList splitPath(const QString &path) const; protected: - bool eventFilter(QObject *o, QEvent *e); - bool event(QEvent *); + bool eventFilter(QObject *o, QEvent *e) override; + bool event(QEvent *) override; Q_SIGNALS: void activated(const QString &text); void activated(const QModelIndex &index); void highlighted(const QString &text); void highlighted(const QModelIndex &index); private: Q_DISABLE_COPY(KexiCompleter) friend class KexiCompleterPrivate; KexiCompleterPrivate * const d; private Q_SLOTS: void _q_complete(const QModelIndex&); void _q_completionSelected(const QItemSelection&); void _q_autoResizePopup(); void _q_fileSystemModelDirectoryLoaded(const QString&); }; #endif // QT_NO_COMPLETER #endif // KEXICOMPLETER_H diff --git a/src/kexiutils/completer/KexiCompleter_p.h b/src/kexiutils/completer/KexiCompleter_p.h index 3c73b58ff..ed71af35c 100644 --- a/src/kexiutils/completer/KexiCompleter_p.h +++ b/src/kexiutils/completer/KexiCompleter_p.h @@ -1,267 +1,267 @@ /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this ** file. Please review the following information to ensure the GNU Lesser ** General Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU General ** Public License version 3.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of this ** file. Please review the following information to ensure the GNU General ** Public License version 3.0 requirements will be met: ** http://www.gnu.org/copyleft/gpl.html. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef KEXICOMPLETER_P_H #define KEXICOMPLETER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #ifndef QT_NO_COMPLETER #include #include #include #include #include #include "KexiCompleter.h" #include "private/KexiAbstractItemModel_p.h" class KexiCompletionModel; class KexiCompleterPrivate { public: explicit KexiCompleterPrivate(KexiCompleter *q); ~KexiCompleterPrivate() { delete popup; } void init(QAbstractItemModel *model = 0); QPointer widget; KexiCompletionModel *proxy; QAbstractItemView *popup; KexiCompleter::CompletionMode mode; QString prefix; Qt::CaseSensitivity cs; bool substringCompletion; int role; int column; int maxVisibleItems; KexiCompleter::ModelSorting sorting; bool wrap; bool eatFocusOut; QRect popupRect; bool hiddenBecauseNoMatch; void showPopup(const QRect&); void _q_complete(QModelIndex, bool = false); void _q_completionSelected(const QItemSelection&); void _q_autoResizePopup(); void _q_fileSystemModelDirectoryLoaded(const QString &path); void setCurrentIndex(QModelIndex, bool = true); KexiCompleter * const q; }; class KexiIndexMapper { public: KexiIndexMapper() : v(false), f(0), t(-1) { } KexiIndexMapper(int f, int t) : v(false), f(f), t(t) { } explicit KexiIndexMapper(QVector vec) : v(true), vector(vec), f(-1), t(-1) { } inline int count() const { return v ? vector.count() : t - f + 1; } inline int operator[] (int index) const { return v ? vector[index] : f + index; } inline int indexOf(int x) const { return v ? vector.indexOf(x) : ((t < f) ? -1 : x - f); } inline bool isValid() const { return !isEmpty(); } inline bool isEmpty() const { return v ? vector.isEmpty() : (t < f); } inline void append(int x) { Q_ASSERT(v); vector.append(x); } inline int first() const { return v ? vector.first() : f; } inline int last() const { return v ? vector.last() : t; } inline int from() const { Q_ASSERT(!v); return f; } inline int to() const { Q_ASSERT(!v); return t; } inline int cost() const { return vector.count()+2; } private: bool v; QVector vector; int f, t; }; struct KexiMatchData { KexiMatchData() : exactMatchIndex(-1), partial(false) { } KexiMatchData(const KexiIndexMapper& indices, int em, bool p) : indices(indices), exactMatchIndex(em), partial(p) { } KexiIndexMapper indices; inline bool isValid() const { return indices.isValid(); } int exactMatchIndex; bool partial; }; class KexiCompletionEngine { public: typedef QMap CacheItem; typedef QMap Cache; explicit KexiCompletionEngine(KexiCompleterPrivate *c) : c(c), curRow(-1), cost(0) { } virtual ~KexiCompletionEngine() { } void filter(const QStringList &parts); KexiMatchData filterHistory(); bool matchHint(QString, const QModelIndex&, KexiMatchData*); void saveInCache(QString, const QModelIndex&, const KexiMatchData&); bool lookupCache(QString part, const QModelIndex& parent, KexiMatchData *m); virtual void filterOnDemand(int) { } virtual KexiMatchData filter(const QString&, const QModelIndex&, int) = 0; int matchCount() const { return curMatch.indices.count() + historyMatch.indices.count(); } KexiMatchData curMatch, historyMatch; KexiCompleterPrivate *c; QStringList curParts; QModelIndex curParent; int curRow; Cache cache; int cost; }; class QSortedModelEngine : public KexiCompletionEngine { public: explicit QSortedModelEngine(KexiCompleterPrivate *c) : KexiCompletionEngine(c) { } - KexiMatchData filter(const QString&, const QModelIndex&, int); + KexiMatchData filter(const QString&, const QModelIndex&, int) override; KexiIndexMapper indexHint(QString, const QModelIndex&, Qt::SortOrder); Qt::SortOrder sortOrder(const QModelIndex&) const; }; class QUnsortedModelEngine : public KexiCompletionEngine { public: explicit QUnsortedModelEngine(KexiCompleterPrivate *c) : KexiCompletionEngine(c) { } - void filterOnDemand(int); - KexiMatchData filter(const QString&, const QModelIndex&, int); + void filterOnDemand(int) override; + KexiMatchData filter(const QString&, const QModelIndex&, int) override; private: int buildIndices(const QString& str, const QModelIndex& parent, int n, const KexiIndexMapper& iv, KexiMatchData* m); }; class KexiCompleterItemDelegate : public QItemDelegate { Q_OBJECT public: explicit KexiCompleterItemDelegate(QAbstractItemView *view) : QItemDelegate(view), view(view) { } - void paint(QPainter *p, const QStyleOptionViewItem& opt, const QModelIndex& idx) const { + void paint(QPainter *p, const QStyleOptionViewItem& opt, const QModelIndex& idx) const override { QStyleOptionViewItem optCopy = opt; optCopy.showDecorationSelected = true; if (view->currentIndex() == idx) optCopy.state |= QStyle::State_HasFocus; QItemDelegate::paint(p, optCopy, idx); } private: QAbstractItemView *view; }; class KexiCompletionModelPrivate; class KexiCompletionModel : public QAbstractProxyModel { Q_OBJECT public: KexiCompletionModel(KexiCompleterPrivate *c, QObject *parent); ~KexiCompletionModel(); void createEngine(); void setFiltered(bool); void filter(const QStringList& parts); int completionCount() const; int currentRow() const { return engine->curRow; } bool setCurrentRow(int row); QModelIndex currentIndex(bool) const; void resetModel(); - QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const; - int rowCount(const QModelIndex &index = QModelIndex()) const; - int columnCount(const QModelIndex &index = QModelIndex()) const; - bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex & = QModelIndex()) const { return QModelIndex(); } - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const override; + int rowCount(const QModelIndex &index = QModelIndex()) const override; + int columnCount(const QModelIndex &index = QModelIndex()) const override; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex & = QModelIndex()) const override { return QModelIndex(); } + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - void setSourceModel(QAbstractItemModel *sourceModel); - QModelIndex mapToSource(const QModelIndex& proxyIndex) const; - QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; + void setSourceModel(QAbstractItemModel *sourceModel) override; + QModelIndex mapToSource(const QModelIndex& proxyIndex) const override; + QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override; KexiCompleterPrivate *c; QScopedPointer engine; bool showAll; Q_SIGNALS: void rowsAdded(); public Q_SLOTS: void invalidate(); void rowsInserted(); void modelDestroyed(); private: KexiCompletionModelPrivate * const d; }; class KexiCompletionModelPrivate : public KexiAbstractItemModelPrivate { explicit KexiCompletionModelPrivate(KexiCompletionModel *q); virtual ~KexiCompletionModelPrivate() { } virtual void _q_sourceModelDestroyed(); KexiCompletionModel * const q; friend class KexiCompletionModel; }; #endif // QT_NO_COMPLETER #endif // KEXICOMPLETER_P_H diff --git a/src/kexiutils/kmessagewidget.h b/src/kexiutils/kmessagewidget.h index a6ea6bb65..2cf509ba6 100644 --- a/src/kexiutils/kmessagewidget.h +++ b/src/kexiutils/kmessagewidget.h @@ -1,218 +1,218 @@ /* This file is part of the KDE libraries * * Copyright (c) 2011 Aurélien Gâteau * Copyright (C) 2011-2012 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #ifndef KMESSAGEWIDGET_H #define KMESSAGEWIDGET_H #include "kexiutils_export.h" #include class KMessageWidgetPrivate; /** * @short A widget to provide feedback or propose opportunistic interactions. * * KMessageWidget can be used to provide inline positive or negative * feedback, or to implement opportunistic interactions. * * As a feedback widget, KMessageWidget provides a less intrusive alternative * to "OK Only" message boxes. If you do not need the modalness of KMessageBox, * consider using KMessageWidget instead. * * Negative feedback * * The KMessageWidget can be used as a secondary indicator of failure: the * first indicator is usually the fact the action the user expected to happen * did not happen. * * Example: User fills a form, clicks "Submit". * * @li Expected feedback: form closes * @li First indicator of failure: form stays there * @li Second indicator of failure: a KMessageWidget appears on top of the * form, explaining the error condition * * When used to provide negative feedback, KMessageWidget should be placed * close to its context. In the case of a form, it should appear on top of the * form entries. * * KMessageWidget should get inserted in the existing layout. Space should not * be reserved for it, otherwise it becomes "dead space", ignored by the user. * KMessageWidget should also not appear as an overlay to prevent blocking * access to elements the user needs to interact with to fix the failure. * * Positive feedback * * KMessageWidget can be used for positive feedback but it shouldn't be * overused. It is often enough to provide feedback by simply showing the * results of an action. * * Examples of acceptable uses: * * @li Confirm success of "critical" transactions * @li Indicate completion of background tasks * * Example of inadapted uses: * * @li Indicate successful saving of a file * @li Indicate a file has been successfully removed * * Opportunistic interaction * * Opportunistic interaction is the situation where the application suggests to * the user an action they could be interested in perform, either based on an * action the user just triggered or an event which the application noticed. * * Example of acceptable uses: * * @li A browser can propose remembering a recently entered password * @li A music collection can propose ripping a CD which just got inserted * @li A chat application may notify the user a "special friend" just connected */ class KEXIUTILS_EXPORT KMessageWidget : public QFrame { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) Q_PROPERTY(bool closeButtonVisible READ isCloseButtonVisible WRITE setCloseButtonVisible) Q_PROPERTY(MessageType messageType READ messageType WRITE setMessageType) public: enum MessageType { Positive, Information, Warning, Error }; Q_ENUM(MessageType) enum CalloutPointerDirection { NoPointer, Up, Down, Left, Right }; Q_ENUM(CalloutPointerDirection) /** * Constructs a KMessageWidget with the specified parent. */ explicit KMessageWidget(QWidget *parent = 0); explicit KMessageWidget(const QString &text, QWidget *parent = 0); KMessageWidget(QWidget *contentsWidget, QWidget *parent); ~KMessageWidget(); QString text() const; bool wordWrap() const; bool isCloseButtonVisible() const; bool clickClosesMessage() const; MessageType messageType() const; CalloutPointerDirection calloutPointerDirection() const; void addAction(QAction *action); void removeAction(QAction *action); void setDefaultAction(QAction *action); void setButtonLeftAlignedForAction(QAction *action); /** * @brief Sets autodeletion flag to be on or off. * If autodeletion is on, the widget is automatically * deleted after hide() or animatedHide() using QObject::deleteLater(). * Autodeletion is false by default. */ void setAutoDelete(bool set); - QSize sizeHint() const; + QSize sizeHint() const override; - QSize minimumSizeHint() const; + QSize minimumSizeHint() const override; QPoint calloutPointerPosition() const; public Q_SLOTS: void setText(const QString &text); void setWordWrap(bool wordWrap); void setCloseButtonVisible(bool visible); void setClickClosesMessage(bool set); void setMessageType(KMessageWidget::MessageType type); void setCalloutPointerDirection(KMessageWidget::CalloutPointerDirection direction); //! Sets global position for callout pointer void setCalloutPointerPosition(const QPoint& globalPos); QBrush backgroundBrush() const; QBrush borderBrush() const; /** * Show the widget using an animation, unless * KexiUtils::graphicsEffectLevel() does not allow simple effects. */ void animatedShow(); /** * Hide the widget using an animation, unless * KexiUtils::graphicsEffectLevel() does not allow simple effects. */ void animatedHide(); void resizeToContents(); Q_SIGNALS: void animatedShowFinished(); void animatedHideFinished(); protected: - virtual void paintEvent(QPaintEvent *event); + virtual void paintEvent(QPaintEvent *event) override; - virtual bool event(QEvent *event); + virtual bool event(QEvent *event) override; - virtual void resizeEvent(QResizeEvent *event); + virtual void resizeEvent(QResizeEvent *event) override; - virtual void showEvent(QShowEvent *event); + virtual void showEvent(QShowEvent *event) override; private Q_SLOTS: void slotTimeLineChanged(qreal value); void slotTimeLineFinished(); void tryClickCloseMessage(); private: KMessageWidgetPrivate *const d; friend class KMessageWidgetPrivate; }; #endif /* KMESSAGEWIDGET_H */ diff --git a/src/kexiutils/kmessagewidget_p.h b/src/kexiutils/kmessagewidget_p.h index be0044b77..34d0ffb60 100644 --- a/src/kexiutils/kmessagewidget_p.h +++ b/src/kexiutils/kmessagewidget_p.h @@ -1,76 +1,76 @@ /* This file is part of the KDE libraries * * Copyright (c) 2011 Aurélien Gâteau * Copyright (C) 2011 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #ifndef KMESSAGEWIDGET_P_H #define KMESSAGEWIDGET_P_H #include "kmessagewidget.h" #include class KMessageWidgetFrame : public QFrame { Q_OBJECT public: explicit KMessageWidgetFrame(QWidget* parent = 0); - virtual void paintEvent(QPaintEvent* event); + virtual void paintEvent(QPaintEvent* event) override; KMessageWidget::CalloutPointerDirection calloutPointerDirection() const; void setCalloutPointerDirection(KMessageWidget::CalloutPointerDirection direction); QPoint calloutPointerPosition() const; QPoint pointerPosition() const; void setCalloutPointerPosition(const QPoint& globalPos); void updateCalloutPointerPosition() const; const int radius; QBrush bgBrush; QBrush borderBrush; private: void paintCalloutPointer(); void updateCalloutPointerTransformation() const; KMessageWidget::CalloutPointerDirection m_calloutPointerDirection; mutable QTransform m_calloutPointerTransformation; mutable QSize m_sizeForRecentTransformation; QPoint m_calloutPointerGlobalPosition; QPolygonF m_polyline; QPolygonF m_polygon; }; class ClickableLabel : public QLabel { Q_OBJECT public: explicit ClickableLabel(QWidget *parent = 0); virtual ~ClickableLabel(); - virtual void mousePressEvent(QMouseEvent *ev); + virtual void mousePressEvent(QMouseEvent *ev) override; Q_SIGNALS: void clicked(); }; #endif /* KMESSAGEWIDGET_P_H */ diff --git a/src/kexiutils/utils.h b/src/kexiutils/utils.h index f8358deaf..de3d57166 100644 --- a/src/kexiutils/utils.h +++ b/src/kexiutils/utils.h @@ -1,724 +1,724 @@ /* This file is part of the KDE project Copyright (C) 2003-2017 Jarosław Staniek Contains code from kglobalsettings.h: Copyright (C) 2000, 2006 David Faure Copyright (C) 2008 Friedrich W. H. Kossebau Contains code from kdialog.h: Copyright (C) 1998 Thomas Tanghus (tanghus@earthling.net) Additions 1999-2000 by Espen Sand (espen@kde.org) and Holger Freyther 2005-2009 Olivier Goffart 2006 Tobias Koenig This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIUTILS_UTILS_H #define KEXIUTILS_UTILS_H #include "kexiutils_export.h" #include "kexi_global.h" #include #include #include #include #include #include #include #include #include #include class QColor; class QDomNode; class QMetaProperty; class QLayout; class QLineEdit; //! @short General Utils namespace KexiUtils { //! \return true if parent of \a o that is of type \a className or false otherwise inline bool parentIs(QObject* o, const char* className = 0) { if (!o) return false; while ((o = o->parent())) { if (o->inherits(className)) return true; } return false; } //! \return parent object of \a o that is of type \a type or 0 if no such parent template inline type findParentByType(QObject* o) { if (!o) return 0; while ((o = o->parent())) { if (dynamic_cast< type >(o)) return dynamic_cast< type >(o); } return 0; } /*! \return first found child of \a o, inheriting \a className. If objName is 0 (the default), all object names match. Returned pointer type is casted. */ KEXIUTILS_EXPORT QObject* findFirstQObjectChild(QObject *o, const char* className, const char* objName); /*! \return first found child of \a o, that inherit \a className. If \a objName is 0 (the default), all object names match. Returned pointer type is casted. */ template inline type findFirstChild(QObject *o, const char* className, const char* objName = 0) { return ::qobject_cast< type >(findFirstQObjectChild(o, className, objName)); } //! Finds property for name \a name and object \a object returns it index; //! otherwise returns a null QMetaProperty. KEXIUTILS_EXPORT QMetaProperty findPropertyWithSuperclasses(const QObject* object, const char* name); //! \return true if \a object object is of class name \a className inline bool objectIsA(QObject* object, const char* className) { return 0 == qstrcmp(object->metaObject()->className(), className); } //! \return true if \a object object is of the class names inside \a classNames KEXIUTILS_EXPORT bool objectIsA(QObject* object, const QList& classNames); //! \return a list of methods for \a metaObject meta object. //! The methods are of type declared in \a types and have access declared //! in \a access. KEXIUTILS_EXPORT QList methodsForMetaObject( const QMetaObject *metaObject, QFlags types = QFlags(QMetaMethod::Method | QMetaMethod::Signal | QMetaMethod::Slot), QFlags access = QFlags(QMetaMethod::Private | QMetaMethod::Protected | QMetaMethod::Public)); //! Like \ref KexiUtils::methodsForMetaObject() but includes methods from all //! parent meta objects of the \a metaObject. KEXIUTILS_EXPORT QList methodsForMetaObjectWithParents( const QMetaObject *metaObject, QFlags types = QFlags(QMetaMethod::Method | QMetaMethod::Signal | QMetaMethod::Slot), QFlags access = QFlags(QMetaMethod::Private | QMetaMethod::Protected | QMetaMethod::Public)); //! \return a list with all this class's properties. KEXIUTILS_EXPORT QList propertiesForMetaObject( const QMetaObject *metaObject); //! \return a list with all this class's properties including thise inherited. KEXIUTILS_EXPORT QList propertiesForMetaObjectWithInherited( const QMetaObject *metaObject); //! \return a list of enum keys for meta property \a metaProperty. //! If @a filter is not INT_MIN, the method only returns enum keys that overlap with filter //! and are not combination of other keys. KEXIUTILS_EXPORT QStringList enumKeysForProperty(const QMetaProperty &metaProperty, int filter = INT_MIN); //! Convert a list @a list of @a SourceType type to another list of @a DestinationType //! type using @a convertMethod function /*! Example: @code QList list = ....; QStringList result = KexiUtils::convertTypesUsingFunction(list); @endcode */ template QList convertTypesUsingFunction(const QList &list) { QList result; foreach(const SourceType &element, list) { result.append(ConvertFunction(element)); } return result; } //! Convert a list @a list of @a SourceType type to another list of @a DestinationType //! type using @a convertMethod /*! Example: @code QVariantList list = ....; QStringList result = KexiUtils::convertTypesUsingMethod(list); @endcode */ template QList convertTypesUsingMethod(const QList &list) { QList result; foreach(const SourceType &element, list) { result.append((element.*ConvertMethod)()); } return result; } /*! Sets "wait" cursor with 1 second delay (or 0 seconds if noDelay is true). Does nothing if the application has no GUI enabled. (see KApplication::guiEnabled()) */ KEXIUTILS_EXPORT void setWaitCursor(bool noDelay = false); /*! Remove "wait" cursor previously set with \a setWaitCursor(), even if it's not yet visible. Does nothing if the application has no GUI enabled. (see KApplication::guiEnabled()) */ KEXIUTILS_EXPORT void removeWaitCursor(); /*! Helper class. Allocate it in your code block as follows: KexiUtils::WaitCursor wait; .. and wait cursor will be visible (with one second delay) until you're in this block, without a need to call removeWaitCursor() before exiting the block. Does nothing if the application has no GUI enabled. (see KApplication::guiEnabled()) */ class KEXIUTILS_EXPORT WaitCursor { public: //! Wait cursor handler for application explicit WaitCursor(bool noDelay = false); //! @overload //! Wait cursor handler for widget @a widget explicit WaitCursor(QWidget *widget, bool noDelay = false); ~WaitCursor(); private: QObject *m_handler; }; /*! Helper class. Allocate it in your code block as follows: KexiUtils::WaitCursorRemover remover; .. and the wait cursor will be hidden unless you leave this block, without a need to call setWaitCursor() before exiting the block. After leaving the codee block, the cursor will be visible again, if it was visible before creating the WaitCursorRemover object. Does nothing if the application has no GUI enabled. (see KApplication::guiEnabled()) */ class KEXIUTILS_EXPORT WaitCursorRemover { public: WaitCursorRemover(); ~WaitCursorRemover(); private: bool m_reactivateCursor; }; /*! Creates a modal file dialog which returns the selected url of image filr to open or an empty string if none was chosen. Like KFileDialog::getImageOpenUrl(). */ //! @todo KEXI3 add equivalent of kfiledialog:/// KEXIUTILS_EXPORT QUrl getOpenImageUrl(QWidget *parent = 0, const QString &caption = QString(), const QUrl &directory = QUrl()); /*! Creates a modal file dialog with returns the selected url of image file to save or an empty string if none was chosen. Like KFileDialog::getSaveUrl(). */ //! @todo KEXI3 add equivalent of kfiledialog:/// KEXIUTILS_EXPORT QUrl getSaveImageUrl(QWidget *parent = 0, const QString &caption = QString(), const QUrl &directory = QUrl()); #ifndef KEXI_MOBILE /** * This method implements the logic to determine the user's default directory * to be listed. E.g. the documents directory, home directory or a recently * used directory. * * Use instead of KFileWidget::getStartUrl(const QUrl &startDir, QString &recentDirClass). * * @param startDir A URL specifying the initial directory, or using the * @c kfiledialog:/// syntax to specify a last used directory. * If the string includes a file name, it is ignored. * Refer to the KFileWidget::KFileWidget() documentation for the @c kfiledialog:/// * URL syntax. * @param recentDirClass If the @c kfiledialog:/// syntax is used, this * will return the string to be passed to KRecentDirs::dir() and * KRecentDirs::add(). Optional file name is supported. * @param fileName Optional file name that is added to the resulting URL. * @return The URL that should be listed by default (e.g. by KFileDialog or * KDirSelectDialog). * * @see KFileWidget::KFileWidget() * @since 3.1.0 * @todo Make it independent of KIOFileWidgets */ KEXIUTILS_EXPORT QUrl getStartUrl(const QUrl &startDirOrVariable, QString *recentDirClass, const QString &fileName = QString()); /** * Associates @p directory with @p fileClass * * Use instead of KRecentDirs::add() * * @since 3.1.0 * @todo Make it independent of KIOFileWidgets */ KEXIUTILS_EXPORT void addRecentDir(const QString &fileClass, const QString &directory); #endif // !KEXI_MOBILE /*! Displays a "The file %1 already exists. Do you want to overwrite it?" Yes/No message box. @a parent is used as a parent of the message box. @return @c true if @a filePath file does not exist or user has agreed to overwrite it; returns @c false if user does not agree to overwrite it. */ KEXIUTILS_EXPORT bool askForFileOverwriting(const QString& filePath, QWidget *parent = nullptr); /*! A global setting for minimal readable font. This can be used in dockers, rulers and other places where space is at a premium. @see QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont). @todo Add integration with KDE platform theme (how to detect it?); for now we don't assume it's installed */ KEXIUTILS_EXPORT QFont smallestReadableFont(); /*! \return a color being a result of blending \a c1 with \a c2 with \a factor1 and \a factor1 factors: (c1*factor1+c2*factor2)/(factor1+factor2). */ KEXIUTILS_EXPORT QColor blendedColors(const QColor& c1, const QColor& c2, int factor1 = 1, int factor2 = 1); /*! \return a contrast color for a color \a c: If \a c is light color, darker color created using c.dark(200) is returned; otherwise lighter color created using c.light(200) is returned. */ KEXIUTILS_EXPORT QColor contrastColor(const QColor& c); /*! \return a lighter color for a color \a c and a factor \a factor. For colors like Qt::red or Qt::green where hue and saturation are near to 255, hue is decreased so the result will be more bleached. For black color the result is dark gray rather than black. */ KEXIUTILS_EXPORT QColor bleachedColor(const QColor& c, int factor); /*! \return icon set computed as a result of colorizing \a icon pixmap with \a role color of \a palette palette. This function is useful for displaying monochromed icons on the list view or table view header, to avoid bloat, but still have the color compatible with accessibility settings. */ KEXIUTILS_EXPORT QIcon colorizeIconToTextColor(const QPixmap& icon, const QPalette& palette, QPalette::ColorRole role = QPalette::ButtonText); /*! Replaces colors in pixmap @a original using @a color color. Used for coloring bitmaps that have to reflect the foreground color. */ KEXIUTILS_EXPORT void replaceColors(QPixmap* original, const QColor& color); /*! Replaces colors in image @a original using @a color color. Used for coloring bitmaps that have to reflect the foreground color. */ KEXIUTILS_EXPORT void replaceColors(QImage* original, const QColor& color); /*! @return true if curent color scheme is light. Lightness of window background is checked to measure this. */ KEXIUTILS_EXPORT bool isLightColorScheme(); /*! @return alpha value for dimmed color (150). */ KEXIUTILS_EXPORT int dimmedAlpha(); /*! @return palette @a pal with dimmed color @a role. @see dimmedAlpha() */ KEXIUTILS_EXPORT QPalette paletteWithDimmedColor(const QPalette &pal, QPalette::ColorGroup group, QPalette::ColorRole role); /*! @overload paletteWithDimmedColor(const QPalette &, QPalette::ColorGroup, QPalette::ColorRole) */ KEXIUTILS_EXPORT QPalette paletteWithDimmedColor(const QPalette &pal, QPalette::ColorRole role); /*! @return palette altered for indicating "read only" flag. */ KEXIUTILS_EXPORT QPalette paletteForReadOnly(const QPalette &palette); /*! Convenience function that sets background color @a color for widget @a widget. "autoFillBackground" property is set to true for the widget. Background color role is obtained from QWidget::backgroundRole(). */ KEXIUTILS_EXPORT void setBackgroundColor(QWidget *widget, const QColor &color); /*! \return empty (fully transparent) pixmap that can be used as a place for icon of size \a iconGroup */ KEXIUTILS_EXPORT QPixmap emptyIcon(KIconLoader::Group iconGroup); #ifdef KEXI_DEBUG_GUI //! Creates debug window for convenient debugging output KEXIUTILS_EXPORT QWidget *createDebugWindow(QWidget *parent); //! Connects push button action to \a receiver and its \a slot. This allows to execute debug-related actions //! using buttons displayed in the debug window. KEXIUTILS_EXPORT void connectPushButtonActionForDebugWindow(const char* actionName, const QObject *receiver, const char* slot); #endif //! Sets focus for widget \a widget with reason \a reason. KEXIUTILS_EXPORT void setFocusWithReason(QWidget* widget, Qt::FocusReason reason); //! Unsets focus for widget \a widget with reason \a reason. KEXIUTILS_EXPORT void unsetFocusWithReason(QWidget* widget, Qt::FocusReason reason); //! If the application's layout direction, swaps left and right margins. //! @see QGuiApplication::isRightToLeft() void adjustIfRtl(QMargins *margins); //! Draws pixmap @a pixmap on painter @a p using predefined parameters. //! Used in KexiDBImageBox and KexiBlobTableEdit. KEXIUTILS_EXPORT void drawPixmap(QPainter* p, const QMargins& margins, const QRect& rect, const QPixmap& pixmap, Qt::Alignment alignment, bool scaledContents, bool keepAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation); //! Scales pixmap @a pixmap on painter @a p using predefined parameters. //! Used in KexiDBImageBox and KexiBlobTableEdit. KEXIUTILS_EXPORT QPixmap scaledPixmap(const QMargins& margins, const QRect& rect, const QPixmap& pixmap, QPoint* pos, Qt::Alignment alignment, bool scaledContents, bool keepAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation); //! This function should be used instead of QPixmap::loadFromData(). /** Loads a pixmap from @a data into @a pixmap. First tries to detect format, on failure * tries to load most common formats: png, jpg, bmp, tif. Then tries to load any of format * returned by QImageReader::supportedImageFormats(). * If @a format is provided, only this format is tried. * @return on success. * @note This function exists because QPixmap::loadFromData() not always works when there * are broken image format plugins installed (as it was the case with KRA plugin). * @todo Idea: Support while/black list of supported image formats. It would be useful * for security reasons because files can be loaded from remote locations. * @todo For the black/white list an enum describing local/remote data source is needed. */ KEXIUTILS_EXPORT bool loadPixmapFromData(QPixmap *pixmap, const QByteArray &data, const char *format = nullptr); //! A helper for automatic deleting of contents of containers. template class ContainerDeleter { public: explicit ContainerDeleter(Container& container) : m_container(container) {} ~ContainerDeleter() { clear(); } void clear() { qDeleteAll(m_container); m_container.clear(); } private: Container& m_container; }; /*! A modified QFrame which sets up sunken styled panel frame style depending on the current widget style. The widget also reacts on style changes. */ class KEXIUTILS_EXPORT KTextEditorFrame : public QFrame { Q_OBJECT public: explicit KTextEditorFrame(QWidget * parent = 0, Qt::WindowFlags f = 0); protected: - virtual void changeEvent(QEvent *event); + virtual void changeEvent(QEvent *event) override; }; /** * Returns the number of pixels that should be used between a * dialog edge and the outermost widget(s) according to the KDE standard. * * Copied from QDialog. * * @deprecated Use the style's pixelMetric() function to query individual margins. * Different platforms may use different values for the four margins. */ KEXIUTILS_EXPORT int marginHint(); /** * Returns the number of pixels that should be used between * widgets inside a dialog according to the KDE standard. * * Copied from QDialog. * * @deprecated Use the style's layoutSpacing() function to query individual spacings. * Different platforms may use different values depending on widget types and pairs. */ KEXIUTILS_EXPORT int spacingHint(); /*! Sets KexiUtils::marginHint() margins and KexiUtils::spacingHint() spacing for the layout @a layout. */ KEXIUTILS_EXPORT void setStandardMarginsAndSpacing(QLayout *layout); /*! Sets the same @a value for layout @a layout margins. */ KEXIUTILS_EXPORT void setMargins(QLayout *layout, int value); //! sometimes we leave a space in the form of empty QFrame and want to insert here //! a widget that must be instantiated by hand. //! This macro inserts a widget \a what into a frame \a where. #define GLUE_WIDGET(what, where) \ { QVBoxLayout *lyr = new QVBoxLayout(where); \ lyr->addWidget(what); } //! A tool for setting temporary value for boolean variable. /*! After destruction of the instance, the variable is set back to the original value. This class is useful in recursion guards. To use it, declare class atrribute of type bool and block it, e.g.: @code bool m_myNonRecursiveFunctionEnabled; // ... set m_myNonRecursiveFunctionEnabled initially to true void myNonRecursiveFunctionEnabled() { if (!m_myNonRecursiveFunctionEnabled) return; KexiUtils::BoolBlocker guard(&m_myNonRecursiveFunctionEnabled, false); // function's body guarded against recursion... } @endcode */ class KEXIUTILS_EXPORT BoolBlocker { public: inline BoolBlocker(bool *var, bool tempValue) : v(var), origValue(*var) { *var = tempValue; } inline ~BoolBlocker() { *v = origValue; } private: bool *v; bool origValue; }; /*! This helper function install an event filter on @a object and all of its children, directed to @a filter. */ KEXIUTILS_EXPORT void installRecursiveEventFilter(QObject *object, QObject *filter); /*! This helper function removes an event filter installed before on @a object and all of its children. */ KEXIUTILS_EXPORT void removeRecursiveEventFilter(QObject *object, QObject *filter); //! Blocks paint events on specified widget. /*! Works recursively. Useful when widget should be hidden without changing geometry it takes. */ class KEXIUTILS_EXPORT PaintBlocker : public QObject { Q_OBJECT public: explicit PaintBlocker(QWidget* parent); void setEnabled(bool set); bool enabled() const; protected: - virtual bool eventFilter(QObject* watched, QEvent* event); + virtual bool eventFilter(QObject* watched, QEvent* event) override; private: bool m_enabled; }; /*! * \short Options for opening of hyperlinks * \sa openHyperLink() */ class KEXIUTILS_EXPORT OpenHyperlinkOptions : public QObject { Q_OBJECT public: /*! * A tool used for opening hyperlinks */ enum HyperlinkTool{ DefaultHyperlinkTool, /*!< Default tool for a given type of the hyperlink */ BrowserHyperlinkTool, /*!< Opens hyperlink in a browser */ MailerHyperlinkTool /*!< Opens hyperlink in a default mailer */ }; Q_ENUM(HyperlinkTool) OpenHyperlinkOptions() : tool(DefaultHyperlinkTool) , allowExecutable(false) , allowRemote(false) {} HyperlinkTool tool; bool allowExecutable; bool allowRemote; }; /*! * Opens the given \a url using \a options * It can fail if opening a given link is not possible or allowed. * @return true on success, cancelled if user has cancelled the opening and false on failure */ KEXIUTILS_EXPORT tristate openHyperLink(const QUrl &url, QWidget *parent, const OpenHyperlinkOptions &options); //! \return size of combo box arrow according to \a style /*! Application's style is the default. \see QStyle::SC_ComboBoxArrow */ KEXIUTILS_EXPORT QSize comboBoxArrowSize(QStyle *style = 0); //! Adds a dirty ("document modified") flag to @a text according to current locale. //! It is usually "*" character appended. KEXIUTILS_EXPORT void addDirtyFlag(QString *text); //! @return The name of the user's preferred encoding //! Based on KLocale::encoding() KEXIUTILS_EXPORT QByteArray encoding(); //! The desired level of effects on the GUI enum GraphicEffect { NoEffects = 0x0000, ///< GUI with no effects at all. GradientEffects = 0x0001, ///< GUI with only gradients enabled. SimpleAnimationEffects = 0x0002, ///< GUI with simple animations enabled. ComplexAnimationEffects = 0x0006 ///< GUI with complex animations enabled. ///< Note that ComplexAnimationsEffects implies SimpleAnimationEffects. }; Q_DECLARE_FLAGS(GraphicEffects, GraphicEffect) //! @return the desired level of effects on the GUI. //! @note A copy of KGlobalSettings::graphicEffectsLevel() needed for porting from kdelibs4. KEXIUTILS_EXPORT GraphicEffects graphicEffectsLevel(); //! @return the inactive titlebar background color //! @note A copy of KGlobalSettings::inactiveTitleColor() needed for porting from kdelibs4. KEXIUTILS_EXPORT QColor inactiveTitleColor(); //! @return the inactive titlebar text (foreground) color //! @note A copy of KGlobalSettings::inactiveTextColor() needed for porting from kdelibs4. KEXIUTILS_EXPORT QColor inactiveTextColor(); //! @return the active titlebar background color //! @note A copy of KGlobalSettings::activeTitleColor() needed for porting from kdelibs4. KEXIUTILS_EXPORT QColor activeTitleColor(); //! @return the active titlebar text (foreground) color //! @note A copy of KGlobalSettings::activeTextColor() needed for porting from kdelibs4. KEXIUTILS_EXPORT QColor activeTextColor(); //! @return Paper White color, see https://techbase.kde.org/Projects/Usability/HIG/Color inline QColor paperWhite() { return QColor(0xfcfcfc); } //! @return Charcoal Grey color, see https://techbase.kde.org/Projects/Usability/HIG/Color inline QColor charcoalGrey() { return QColor(0x31363b); } //! @return Shade Black color, see https://techbase.kde.org/Projects/Usability/HIG/Color inline QColor shadeBlack() { return QColor(0x232629); } /*! @return @c true if whether the app runs in a single click mode (the default). @c false if returned if the app runs in double click mode. The flag is checked in two stages. Stage 1. Application config file's "SingleClickOpensItem" value in "MainWindow" group is checked. If it exists, the value is returned. On Windows if it does not exist, @c true is returned, on other systems Stage 2 checking is performed. Stage 2. For Qt < 5.5 this information is taken from @a widget widget's style. If there is no widget specified, QApplication::style() is used. For Qt >= 5.5 the result is equal to QApplication::styleHints()->singleClickActivation() and @a widget is ignored. @note This is a replacement for bool KGlobalSettings::singleClick(). */ KEXIUTILS_EXPORT bool activateItemsOnSingleClick(QWidget *widget = 0); /** * Detects name of desktop session based on environment variables. * * Possible value are like GNOME, XFCE, KDE. They are always uppercase. Following environment * variables are used: XDG_SESSION_DESKTOP. XDG_CURRENT_DESKTOP, DESKTOP_SESSION, KDE_FULL_SESSION, * GNOME_DESKTOP_SESSION_ID. * * @return empty string if no desktop session was detected or sessions are not supported for the * running OS (Windows, macOS, non-desktop OS). * * @note use QApplication::styleHints() if possible. */ KEXIUTILS_EXPORT QByteArray detectedDesktopSession(); /** * @return true is this is a KDE / Plasma desktop session * * Detection is based on detectedDesktopSession(). */ KEXIUTILS_EXPORT bool isKDEDesktopSession(); /** * @brief Returns @c true if native operating system's dialogs should be used * * Returns @c false if Qt's standard dialogs should be used instead of the operating system native * dialogs. Can be used with QColorDialog, QFileDialog and QFontDialog. * * Depends on the curent desktop in use: * - on Unix (other than macOS) returns @c true if isKDEDesktopSession() is @c true or if desktop * session can't be detected, @c false for other desktops * - @c true for all other operating systems, i.e. for MS Windows, macOS, etc. * * @todo Share this code with KReport and Kexi */ KEXIUTILS_EXPORT bool shouldUseNativeDialogs(); /** * @enum CaptionFlag * Used to specify how to construct a window caption * * @value AppNameCaption Indicates that the method shall include * the application name when making the caption string. * @value ModifiedCaption Causes a 'modified' sign will be included in the * returned string. This is useful when indicating that a file is * modified, i.e., it contains data that has not been saved. */ enum CaptionFlag { NoCaptionFlags = 0, AppNameCaption = 1, ModifiedCaption = 2 }; Q_DECLARE_FLAGS(CaptionFlags, CaptionFlag) /** * Builds a caption that contains the application name along with the * userCaption using a standard layout. * * To make a compliant caption for your window, simply do: * @p setWindowTitle(makeStandardCaption(yourCaption)); * * To ensure that the caption is appropriate to the desktop in which the * application is running, pass in a pointer to the window the caption will * be applied to. * * @param userCaption The caption string you want to display in the * window caption area. Do not include the application name! * @param flags * @return the created caption * Based on KDialog::makeStandardCaption() */ KEXIUTILS_EXPORT QString makeStandardCaption(const QString &userCaption, CaptionFlags flags = AppNameCaption); /** * Return rich text for @a string. Equivalent of KLocalizedString::toString(Kuit::RichText) * but and is removed so the result can be used as %* argument in other string. */ KEXIUTILS_EXPORT QString localizedStringToHtmlSubstring(const KLocalizedString& string); /** * Return rich text for concatenated sentences or paragraphs. * * Any of the parameters can be empty but at least first should be non-empty. */ KEXIUTILS_EXPORT QString localizedSentencesToHtml( const KLocalizedString &part1, const KLocalizedString &part2 = KLocalizedString(), const KLocalizedString &part3 = KLocalizedString(), const KLocalizedString &part4 = KLocalizedString(), const KLocalizedString &part5 = KLocalizedString(), const KLocalizedString &part6 = KLocalizedString()); /** * @return @c true if text cursor is at the end of the line edit @a lineEdit. * If the @a lineEdit edit has input mask, cursor is at the end if it's at position * lineEdit->displayText().length() - 1 or further. If the @a lineEdit has no input mask, cursor * is at the end if it's at position lineEdit->text().length() or further. */ KEXIUTILS_EXPORT bool cursorAtEnd(const QLineEdit *lineEdit); } //namespace KexiUtils /** * Writes the DOM tree to the stream and returns a reference to the stream. */ KEXIUTILS_EXPORT QDebug operator<<(QDebug dbg, const QDomNode &node); #endif //KEXIUTILS_UTILS_H diff --git a/src/main/KexiBugReportDialog.h b/src/main/KexiBugReportDialog.h index 3b6190d2b..d70d608d6 100644 --- a/src/main/KexiBugReportDialog.h +++ b/src/main/KexiBugReportDialog.h @@ -1,45 +1,45 @@ /* This file is part of the KDE project Copyright (C) 2014 Jarosław Staniek 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 KEXIBUGREPORTDIALOG_H #define KEXIBUGREPORTDIALOG_H #include //! A bug report dialog dedicated for Kexi. //! It reports proper app version, platform and OS, hides unnecessary information. class KexiBugReportDialog : public KBugReport { Q_OBJECT public: explicit KexiBugReportDialog(QWidget *parent = 0); public Q_SLOTS: - virtual void accept(); + virtual void accept() override; private: void collectData(); QString m_op_sys; QString m_rep_platform; Q_DISABLE_COPY(KexiBugReportDialog) }; #endif diff --git a/src/main/KexiMainWindow.cpp b/src/main/KexiMainWindow.cpp index ad351c415..09b8b614f 100644 --- a/src/main/KexiMainWindow.cpp +++ b/src/main/KexiMainWindow.cpp @@ -1,4433 +1,4433 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2003-2018 Jarosław Staniek 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. */ #include "KexiMainWindow.h" #include "KexiMainWindow_p.h" #include "kexiactionproxy.h" #include "kexipartmanager.h" #include "kexipart.h" #include "kexipartinfo.h" #include "kexipartguiclient.h" #include "kexiproject.h" #include "kexiprojectdata.h" #include "kexi.h" #include "kexiinternalpart.h" #include "kexiactioncategories.h" #include "kexifinddialog.h" #include "kexisearchandreplaceiface.h" #include "KexiBugReportDialog.h" #define KEXI_SKIP_REGISTERICONSRESOURCE #define KEXI_SKIP_SETUPPRIVATEICONSRESOURCE #include "KexiRegisterResource_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "startup/KexiStartup.h" #include "startup/KexiNewProjectAssistant.h" #include "startup/KexiOpenProjectAssistant.h" #include "startup/KexiWelcomeAssistant.h" #include "startup/KexiImportExportAssistant.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if !defined(KexiVDebug) # define KexiVDebug if (0) qDebug() #endif #ifdef HAVE_KCRASH #include //! @todo else, add Breakpad? https://phabricator.kde.org/T1642 #endif KexiDockWidgetStyle::KexiDockWidgetStyle(const QString &baseStyleName) : QProxyStyle(baseStyleName) { } KexiDockWidgetStyle::~KexiDockWidgetStyle() { } void KexiDockWidgetStyle::polish(QWidget* widget) { baseStyle()->polish(widget); widget->setContentsMargins(0, 0, 0, 0); } class Q_DECL_HIDDEN KexiDockWidget::Private { public: Private() {} QSize hint; }; KexiDockWidget::KexiDockWidget(const QString &_tabText, QWidget *parent) : QDockWidget(parent), tabText(_tabText), d(new Private) { // No floatable dockers, Dolphin had problems, we don't want the same... // https://bugs.kde.org/show_bug.cgi?id=288629 // https://bugs.kde.org/show_bug.cgi?id=322299 setFeatures(QDockWidget::NoDockWidgetFeatures);//DockWidgetClosable); setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea); setFocusPolicy(Qt::NoFocus); if (style()->objectName().compare("windowsvista", Qt::CaseInsensitive) == 0) { // windowsvista style has broken accelerator visualization support KAcceleratorManager::setNoAccel(this); } KexiDockWidgetStyle *customStyle = new KexiDockWidgetStyle(style()->objectName()); customStyle->setParent(this); setStyle(customStyle); setTitleBarWidget(new QWidget(this)); // hide the title layout()->setContentsMargins(0, 0, 0, 0); layout()->setSpacing(0); } KexiDockWidget::~KexiDockWidget() { delete d; } void KexiDockWidget::paintEvent(QPaintEvent *pe) { Q_UNUSED(pe); QStylePainter p(this); if (isFloating()) { QStyleOptionFrame framOpt; framOpt.initFrom(this); p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt); } // Title must be painted after the frame, since the areas overlap, and // the title may wish to extend out to all sides (eg. XP style) QStyleOptionDockWidget titleOpt; initStyleOption(&titleOpt); p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt); } void KexiDockWidget::setSizeHint(const QSize& hint) { d->hint = hint; } QSize KexiDockWidget::sizeHint() const { return d->hint.isValid() ? d->hint : QDockWidget::sizeHint(); } //------------------------------------------------- KexiMainWindowTabWidget::KexiMainWindowTabWidget(QWidget *parent, KexiMainWidget* mainWidget) : QTabWidget(parent) , m_mainWidget(mainWidget) , m_tabIndex(-1) { m_closeAction = new QAction(koIcon("tab-close"), xi18n("&Close Tab"), this); m_closeAction->setToolTip(xi18n("Close the current tab")); m_closeAction->setWhatsThis(xi18n("Closes the current tab.")); m_closeAllTabsAction = new QAction(xi18n("Cl&ose All Tabs"), this); m_closeAllTabsAction->setToolTip(xi18n("Close all tabs")); m_closeAllTabsAction->setWhatsThis(xi18n("Closes all tabs.")); connect(m_closeAction, SIGNAL(triggered()), this, SLOT(closeTab())); connect(m_closeAllTabsAction, SIGNAL(triggered()), this, SLOT(closeAllTabs())); //! @todo insert window list in the corner widget as in firefox #if 0 // close-tab button: QToolButton* rightWidget = new QToolButton(this); rightWidget->setDefaultAction(m_closeAction); rightWidget->setText(QString()); rightWidget->setAutoRaise(true); rightWidget->adjustSize(); setCornerWidget(rightWidget, Qt::TopRightCorner); #endif setMovable(true); setDocumentMode(true); tabBar()->setExpanding(false); } KexiMainWindowTabWidget::~KexiMainWindowTabWidget() { } void KexiMainWindowTabWidget::paintEvent(QPaintEvent * event) { if (count() > 0) QTabWidget::paintEvent(event); else QWidget::paintEvent(event); } void KexiMainWindowTabWidget::mousePressEvent(QMouseEvent *event) { //! @todo KEXI3 test KexiMainWindowTabWidget's contextMenu event port from KTabWidget if (event->button() == Qt::RightButton) { int tab = tabBar()->tabAt(event->pos()); const QPoint realPos(tabBar()->mapToGlobal(event->pos())); if (QRect(tabBar()->mapToGlobal(QPoint(0,0)), tabBar()->mapToGlobal(QPoint(tabBar()->width()-1, tabBar()->height()-1))).contains(realPos)) { showContextMenuForTab(tab, tabBar()->mapToGlobal(event->pos())); return; } } QTabWidget::mousePressEvent(event); } void KexiMainWindowTabWidget::closeTab() { KexiMainWindow *main = dynamic_cast(KexiMainWindowIface::global()); if (main) { main->closeWindowForTab(m_tabIndex); } } tristate KexiMainWindowTabWidget::closeAllTabs() { tristate alternateResult = true; QList windowList; KexiMainWindow *main = dynamic_cast(KexiMainWindowIface::global()); if (!main) { return alternateResult; } for (int i = 0; i < count(); i++) { KexiWindow *window = main->windowForTab(i); if (window) { windowList.append(window); } } foreach (KexiWindow *window, windowList) { tristate result = main->closeWindow(window); if (result != true && result != false) { return result; } if (result == false) { alternateResult = false; } } return alternateResult; } void KexiMainWindowTabWidget::showContextMenuForTab(int index, const QPoint& point) { QMenu menu; if (index >= 0) { menu.addAction(m_closeAction); } if (count() > 0) { menu.addAction(m_closeAllTabsAction); } //! @todo add "&Detach Tab" if (menu.actions().isEmpty()) { return; } setTabIndexFromContextMenu(index); menu.exec(point); } void KexiMainWindowTabWidget::setTabIndexFromContextMenu(int clickedIndex) { if (currentIndex() == -1) { m_tabIndex = -1; return; } m_tabIndex = clickedIndex; } //------------------------------------------------- static bool setupIconTheme(KLocalizedString *errorMessage, KLocalizedString *detailsErrorMessage) { // Register kexi resource first to have priority over the standard breeze theme. // For example "table" icon exists in both resources. if (!registerResource("icons/kexi_breeze.rcc", QStandardPaths::AppDataLocation, QString(), QString(), errorMessage, detailsErrorMessage) || !registerGlobalBreezeIconsResource(errorMessage, detailsErrorMessage)) { return false; } setupBreezeIconTheme(); // tell KIconLoader an co. about the theme KConfigGroup cg(KSharedConfig::openConfig(), "Icons"); cg.writeEntry("Theme", "breeze"); cg.sync(); return true; } //! @todo 3.1 replace with KexiStyle bool setupApplication() { #if defined Q_OS_WIN || defined Q_OS_MACOS // Only this style matches current Kexi theme and can be supported/tested const char *name = "breeze"; QScopedPointer style(QStyleFactory::create(name)); if (!style || style->objectName() != name) { qWarning() << qPrintable(QString("Could not find application style %1. " "Kexi will not start. Please check if Kexi is properly installed. ") .arg(name)); return false; } qApp->setStyle(style.take()); #endif return true; } //static int KexiMainWindow::create(const QStringList &arguments, const QString &componentName, const QList &extraOptions) { qApp->setQuitOnLastWindowClosed(false); KLocalizedString::setApplicationDomain("kexi"); //! @todo KEXI3 app->setAttribute(Qt::AA_UseHighDpiPixmaps, true); KexiAboutData aboutData; if (!componentName.isEmpty()) { aboutData.setComponentName(componentName); } KAboutData::setApplicationData(aboutData); if (!setupApplication()) { return 1; } #ifdef HAVE_KCRASH KCrash::initialize(); #endif KLocalizedString errorMessage; KLocalizedString detailsErrorMessage; if (!setupIconTheme(&errorMessage, &detailsErrorMessage)) { if (detailsErrorMessage.isEmpty()) { KMessageBox::error(nullptr, errorMessage.toString()); } else { KMessageBox::detailedError(nullptr, errorMessage.toString(), detailsErrorMessage.toString()); } qWarning() << qPrintable(errorMessage.toString(Kuit::PlainText)); return 1; } QApplication::setWindowIcon(koIcon("kexi")); const tristate res = KexiStartupHandler::global()->init(arguments, extraOptions); if (!res || ~res) { return (~res) ? 0 : 1; } //qDebug() << "startupActions OK"; /* Exit requested, e.g. after database removing. */ if (KexiStartupHandler::global()->action() == KexiStartupData::Exit) { return 0; } KexiMainWindow *win = new KexiMainWindow(); #ifdef KEXI_DEBUG_GUI QWidget* debugWindow = 0; KConfigGroup generalGroup = KSharedConfig::openConfig()->group("General"); if (generalGroup.readEntry("ShowInternalDebugger", false)) { debugWindow = KexiUtils::createDebugWindow(win); debugWindow->show(); } #endif if (true != win->startup()) { delete win; return 1; } win->restoreSettings(); win->show(); #ifdef KEXI_DEBUG_GUI win->raise(); static_cast(win)->activateWindow(); #endif /*foreach (QWidget *widget, QApplication::topLevelWidgets()) { qDebug() << widget; }*/ return 0; } //------------------------------------------------- KexiMainMenuActionShortcut::KexiMainMenuActionShortcut(const QKeySequence& key, QAction *action, QWidget *parent) : QShortcut(key, parent) , m_action(action) { connect(this, SIGNAL(activated()), this, SLOT(slotActivated())); } KexiMainMenuActionShortcut::~KexiMainMenuActionShortcut() { } void KexiMainMenuActionShortcut::slotActivated() { if (!m_action->isEnabled()) { return; } m_action->trigger(); } //------------------------------------------------- KexiMainWindow::KexiMainWindow(QWidget *parent) : KexiMainWindowSuper(parent) , KexiMainWindowIface() , KexiGUIMessageHandler(this) , d(new KexiMainWindow::Private(this)) { setObjectName("KexiMainWindow"); setAttribute(Qt::WA_DeleteOnClose); kexiTester() << KexiTestObject(this); if (d->userMode) qDebug() << "starting up in the User Mode"; setAsDefaultHost(); //this is default host now. //get informed connect(&Kexi::partManager(), SIGNAL(partLoaded(KexiPart::Part*)), this, SLOT(slotPartLoaded(KexiPart::Part*))); connect(&Kexi::partManager(), SIGNAL(newObjectRequested(KexiPart::Info*)), this, SLOT(newObject(KexiPart::Info*))); setAcceptDrops(true); setupActions(); setupMainWidget(); updateAppCaption(); if (!d->userMode) { setupContextHelp(); setupPropertyEditor(); } invalidateActions(); d->timer.singleShot(0, this, SLOT(slotLastActions())); if (KexiStartupHandler::global()->forcedFullScreen()) { toggleFullScreen(true); } // --- global config //! @todo move to specialized KexiConfig class KConfigGroup tablesGroup(d->config->group("Tables")); const int defaultMaxLengthForTextFields = tablesGroup.readEntry("DefaultMaxLengthForTextFields", int(-1)); if (defaultMaxLengthForTextFields >= 0) { KDbField::setDefaultMaxLength(defaultMaxLengthForTextFields); } // --- /global config } KexiMainWindow::~KexiMainWindow() { d->forceWindowClosing = true; closeProject(); delete d; Kexi::deleteGlobalObjects(); } KexiProject *KexiMainWindow::project() { return d->prj; } QList KexiMainWindow::allActions() const { return actionCollection()->actions(); } KActionCollection *KexiMainWindow::actionCollection() const { return d->actionCollection; } KexiWindow* KexiMainWindow::currentWindow() const { return windowForTab(d->mainWidget->tabWidget()->currentIndex()); } KexiWindow* KexiMainWindow::windowForTab(int tabIndex) const { if (!d->mainWidget->tabWidget()) return 0; KexiWindowContainer *windowContainer = dynamic_cast(d->mainWidget->tabWidget()->widget(tabIndex)); if (!windowContainer) return 0; return windowContainer->window; } void KexiMainWindow::setupMainMenuActionShortcut(QAction * action) { if (!action->shortcut().isEmpty()) { foreach(const QKeySequence &shortcut, action->shortcuts()) { (void)new KexiMainMenuActionShortcut(shortcut, action, this); } } } static void addThreeDotsToActionText(QAction* action) { action->setText(xi18nc("Action name with three dots...", "%1...", action->text())); } QAction * KexiMainWindow::addAction(const char *name, const QIcon &icon, const QString& text, const char *shortcut) { QAction *action = icon.isNull() ? new QAction(text, this) : new QAction(icon, text, this); actionCollection()->addAction(name, action); if (shortcut) { action->setShortcut(QKeySequence(shortcut)); QShortcut *s = new QShortcut(action->shortcut(), this); connect(s, SIGNAL(activated()), action, SLOT(trigger())); } return action; } QAction * KexiMainWindow::addAction(const char *name, const QString& text, const char *shortcut) { return addAction(name, QIcon(), text, shortcut); } void KexiMainWindow::setupActions() { KActionCollection *ac = actionCollection(); // PROJECT MENU QAction *action; ac->addAction("project_new", action = new KexiMenuWidgetAction(KStandardAction::New, this)); addThreeDotsToActionText(action); action->setShortcuts(KStandardShortcut::openNew()); action->setToolTip(xi18n("Create a new project")); action->setWhatsThis( xi18n("Creates a new project. Currently opened project is not affected.")); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectNew())); setupMainMenuActionShortcut(action); ac->addAction("project_open", action = new KexiMenuWidgetAction(KStandardAction::Open, this)); action->setToolTip(xi18n("Open an existing project")); action->setWhatsThis( xi18n("Opens an existing project. Currently opened project is not affected.")); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectOpen())); setupMainMenuActionShortcut(action); { ac->addAction("project_welcome", action = d->action_project_welcome = new KexiMenuWidgetAction( QIcon(), xi18n("Welcome"), this)); addThreeDotsToActionText(action); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectWelcome())); setupMainMenuActionShortcut(action); action->setToolTip(xi18n("Show Welcome page")); action->setWhatsThis( xi18n("Shows Welcome page with list of recently opened projects and other information. ")); } ac->addAction("project_save", d->action_save = KStandardAction::save(this, SLOT(slotProjectSave()), this)); d->action_save->setToolTip(xi18n("Save object changes")); d->action_save->setWhatsThis(xi18n("Saves object changes from currently selected window.")); setupMainMenuActionShortcut(d->action_save); d->action_save_as = addAction("project_saveas", koIcon("document-save-as"), xi18n("Save &As...")); d->action_save_as->setToolTip(xi18n("Save object as")); d->action_save_as->setWhatsThis( xi18n("Saves object from currently selected window under a new name (within the same project).")); connect(d->action_save_as, SIGNAL(triggered()), this, SLOT(slotProjectSaveAs())); #ifdef KEXI_SHOW_UNIMPLEMENTED ac->addAction("project_properties", action = d->action_project_properties = new KexiMenuWidgetAction( koIcon("document-properties"), futureI18n("Project Properties"), this)); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectProperties())); setupMainMenuActionShortcut(action); #else d->action_project_properties = d->dummy_action; #endif //! @todo replace document-import icon with something other ac->addAction("project_import_export_send", action = d->action_project_import_export_send = new KexiMenuWidgetAction( koIcon("document-import"), xi18n("&Import, Export or Send..."), this)); action->setToolTip(xi18n("Import, export or send project")); action->setWhatsThis( xi18n("Imports, exports or sends project.")); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectImportExportOrSend())); setupMainMenuActionShortcut(action); ac->addAction("project_close", action = d->action_close = new KexiMenuWidgetAction( koIcon("window-close"), xi18nc("Close Project", "&Close"), this)); action->setToolTip(xi18n("Close the current project")); action->setWhatsThis(xi18n("Closes the current project.")); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectClose())); setupMainMenuActionShortcut(action); ac->addAction("quit", action = new KexiMenuWidgetAction(KStandardAction::Quit, this)); connect(action, SIGNAL(triggered()), this, SLOT(slotProjectQuit())); action->setWhatsThis(xi18n("Quits Kexi application.")); setupMainMenuActionShortcut(action); #ifdef KEXI_SHOW_UNIMPLEMENTED d->action_project_relations = addAction("project_relations", KexiIcon("database-relations"), futureI18n("&Relationships..."), "Ctrl+R"); d->action_project_relations->setToolTip(futureI18n("Project relationships")); d->action_project_relations->setWhatsThis(futureI18n("Shows project relationships.")); connect(d->action_project_relations, SIGNAL(triggered()), this, SLOT(slotProjectRelations())); #else d->action_project_relations = d->dummy_action; #endif d->action_tools_import_project = addAction("tools_import_project", KexiIcon("database-import"), xi18n("&Import Database...")); d->action_tools_import_project->setToolTip(xi18n("Import entire database as a Kexi project")); d->action_tools_import_project->setWhatsThis( xi18n("Imports entire database as a Kexi project.")); connect(d->action_tools_import_project, SIGNAL(triggered()), this, SLOT(slotToolsImportProject())); d->action_tools_data_import = addAction("tools_import_tables", koIcon("document-import"), xi18n("Import Tables...")); d->action_tools_data_import->setToolTip(xi18n("Import data from an external source into this project")); d->action_tools_data_import->setWhatsThis(xi18n("Imports data from an external source into this project.")); connect(d->action_tools_data_import, SIGNAL(triggered()), this, SLOT(slotToolsImportTables())); d->action_tools_compact_database = addAction("tools_compact_database", //! @todo icon koIcon("application-x-compress"), xi18n("&Compact Database...")); d->action_tools_compact_database->setToolTip(xi18n("Compact the current database project")); d->action_tools_compact_database->setWhatsThis( xi18n("Compacts the current database project, so it will take less space and work faster.")); connect(d->action_tools_compact_database, SIGNAL(triggered()), this, SLOT(slotToolsCompactDatabase())); if (d->userMode) d->action_project_import_data_table = 0; else { d->action_project_import_data_table = addAction("project_import_data_table", KexiIcon("document-empty"), /*! @todo: change to "file_import" with a table or so */ xi18nc("Import->Table Data From File...", "Import Data From &File...")); d->action_project_import_data_table->setToolTip(xi18n("Import table data from a file")); d->action_project_import_data_table->setWhatsThis(xi18n("Imports table data from a file.")); connect(d->action_project_import_data_table, SIGNAL(triggered()), this, SLOT(slotProjectImportDataTable())); } d->action_project_export_data_table = addAction("project_export_data_table", KexiIcon("table"), /*! @todo: change to "file_export" with a table or so */ xi18nc("Export->Table or Query Data to File...", "Export Data to &File...")); d->action_project_export_data_table->setToolTip( xi18n("Export data from the active table or query to a file")); d->action_project_export_data_table->setWhatsThis( xi18n("Exports data from the active table or query to a file.")); connect(d->action_project_export_data_table, SIGNAL(triggered()), this, SLOT(slotProjectExportDataTable())); //! @todo new QAction(xi18n("From File..."), "document-open", 0, //! this, SLOT(slotImportFile()), actionCollection(), "project_import_file"); //! @todo new QAction(xi18n("From Server..."), "network-server-database", 0, //! this, SLOT(slotImportServer()), actionCollection(), "project_import_server"); #ifdef KEXI_QUICK_PRINTING_SUPPORT ac->addAction("project_print", d->action_project_print = KStandardAction::print(this, SLOT(slotProjectPrint()), this)); d->action_project_print->setToolTip(futureI18n("Print data from the active table or query")); d->action_project_print->setWhatsThis(futureI18n("Prints data from the active table or query.")); ac->addAction("project_print_preview", d->action_project_print_preview = KStandardAction::printPreview( this, SLOT(slotProjectPrintPreview()), this)); d->action_project_print_preview->setToolTip( futureI18n("Show print preview for the active table or query")); d->action_project_print_preview->setWhatsThis( futureI18n("Shows print preview for the active table or query.")); d->action_project_print_setup = addAction("project_print_setup", koIcon("configure"), futureI18n("Print Set&up...")); //!< @todo document-page-setup could be a better icon d->action_project_print_setup->setToolTip( futureI18n("Show print setup for the active table or query")); d->action_project_print_setup->setWhatsThis( futureI18n("Shows print setup for the active table or query.")); connect(d->action_project_print_setup, SIGNAL(triggered()), this, SLOT(slotProjectPageSetup())); #endif //EDIT MENU d->action_edit_cut = createSharedAction(KStandardAction::Cut); d->action_edit_copy = createSharedAction(KStandardAction::Copy); d->action_edit_paste = createSharedAction(KStandardAction::Paste); if (d->userMode) d->action_edit_paste_special_data_table = 0; else { d->action_edit_paste_special_data_table = addAction( "edit_paste_special_data_table", d->action_edit_paste->icon(), xi18nc("Paste Special->As Data &Table...", "Paste Special...")); d->action_edit_paste_special_data_table->setToolTip( xi18n("Paste clipboard data as a table")); d->action_edit_paste_special_data_table->setWhatsThis( xi18n("Pastes clipboard data as a table.")); connect(d->action_edit_paste_special_data_table, SIGNAL(triggered()), this, SLOT(slotEditPasteSpecialDataTable())); } d->action_edit_copy_special_data_table = addAction( "edit_copy_special_data_table", KexiIcon("table"), xi18nc("Copy Special->Table or Query Data...", "Copy Special...")); d->action_edit_copy_special_data_table->setToolTip( xi18n("Copy selected table or query data to clipboard")); d->action_edit_copy_special_data_table->setWhatsThis( xi18n("Copies selected table or query data to clipboard.")); connect(d->action_edit_copy_special_data_table, SIGNAL(triggered()), this, SLOT(slotEditCopySpecialDataTable())); d->action_edit_undo = createSharedAction(KStandardAction::Undo); d->action_edit_undo->setWhatsThis(xi18n("Reverts the most recent editing action.")); d->action_edit_redo = createSharedAction(KStandardAction::Redo); d->action_edit_redo->setWhatsThis(xi18n("Reverts the most recent undo action.")); ac->addAction("edit_find", d->action_edit_find = KStandardAction::find( this, SLOT(slotEditFind()), this)); d->action_edit_find->setToolTip(xi18n("Find text")); d->action_edit_find->setWhatsThis(xi18n("Looks up the first occurrence of a piece of text.")); ac->addAction("edit_findnext", d->action_edit_findnext = KStandardAction::findNext( this, SLOT(slotEditFindNext()), this)); ac->addAction("edit_findprevious", d->action_edit_findprev = KStandardAction::findPrev( this, SLOT(slotEditFindPrevious()), this)); d->action_edit_replace = 0; //! @todo d->action_edit_replace = KStandardAction::replace( //! this, SLOT(slotEditReplace()), actionCollection(), "project_print_preview" ); d->action_edit_replace_all = 0; //! @todo d->action_edit_replace_all = new QAction( xi18n("Replace All"), "", 0, //! this, SLOT(slotEditReplaceAll()), actionCollection(), "edit_replaceall"); d->action_edit_select_all = createSharedAction(KStandardAction::SelectAll); d->action_edit_delete = createSharedAction(xi18n("&Delete"), koIconName("edit-delete"), QKeySequence(), "edit_delete"); d->action_edit_delete->setToolTip(xi18n("Delete selected object")); d->action_edit_delete->setWhatsThis(xi18n("Deletes currently selected object.")); d->action_edit_delete_row = createSharedAction(xi18n("Delete Record"), KexiIconName("edit-table-delete-row"), QKeySequence(Qt::CTRL + Qt::Key_Delete), "edit_delete_row"); d->action_edit_delete_row->setToolTip(xi18n("Delete the current record")); d->action_edit_delete_row->setWhatsThis(xi18n("Deletes the current record.")); d->action_edit_clear_table = createSharedAction(xi18n("Clear Table Contents..."), KexiIconName("edit-table-clear"), QKeySequence(), "edit_clear_table"); d->action_edit_clear_table->setToolTip(xi18n("Clear table contents")); d->action_edit_clear_table->setWhatsThis(xi18n("Clears table contents.")); setActionVolatile(d->action_edit_clear_table, true); d->action_edit_edititem = createSharedAction(xi18n("Edit Item"), QString(), QKeySequence(), /* CONFLICT in TV: Qt::Key_F2, */ "edit_edititem"); d->action_edit_edititem->setToolTip(xi18n("Edit currently selected item")); d->action_edit_edititem->setWhatsThis(xi18n("Edits currently selected item.")); d->action_edit_insert_empty_row = createSharedAction(xi18n("&Insert Empty Row"), KexiIconName("edit-table-insert-row"), QKeySequence(Qt::SHIFT | Qt::CTRL | Qt::Key_Insert), "edit_insert_empty_row"); setActionVolatile(d->action_edit_insert_empty_row, true); d->action_edit_insert_empty_row->setToolTip(xi18n("Insert one empty row above")); d->action_edit_insert_empty_row->setWhatsThis( xi18n("Inserts one empty row above currently selected table row.")); //VIEW MENU /* UNUSED, see KexiToggleViewModeAction if (!d->userMode) { d->action_view_mode = new QActionGroup(this); ac->addAction( "view_data_mode", d->action_view_data_mode = new KToggleAction( KexiIcon("data-view"), xi18n("&Data View"), d->action_view_mode) ); // d->action_view_data_mode->setObjectName("view_data_mode"); d->action_view_data_mode->setShortcut(QKeySequence("F6")); //d->action_view_data_mode->setExclusiveGroup("view_mode"); d->action_view_data_mode->setToolTip(xi18n("Switch to data view")); d->action_view_data_mode->setWhatsThis(xi18n("Switches to data view.")); d->actions_for_view_modes.insert( Kexi::DataViewMode, d->action_view_data_mode ); connect(d->action_view_data_mode, SIGNAL(triggered()), this, SLOT(slotViewDataMode())); } else { d->action_view_mode = 0; d->action_view_data_mode = 0; } if (!d->userMode) { ac->addAction( "view_design_mode", d->action_view_design_mode = new KToggleAction( KexiIcon("design-view"), xi18n("D&esign View"), d->action_view_mode) ); // d->action_view_design_mode->setObjectName("view_design_mode"); d->action_view_design_mode->setShortcut(QKeySequence("F7")); //d->action_view_design_mode->setExclusiveGroup("view_mode"); d->action_view_design_mode->setToolTip(xi18n("Switch to design view")); d->action_view_design_mode->setWhatsThis(xi18n("Switches to design view.")); d->actions_for_view_modes.insert( Kexi::DesignViewMode, d->action_view_design_mode ); connect(d->action_view_design_mode, SIGNAL(triggered()), this, SLOT(slotViewDesignMode())); } else d->action_view_design_mode = 0; if (!d->userMode) { ac->addAction( "view_text_mode", d->action_view_text_mode = new KToggleAction( KexiIcon("sql-view"), xi18n("&Text View"), d->action_view_mode) ); d->action_view_text_mode->setObjectName("view_text_mode"); d->action_view_text_mode->setShortcut(QKeySequence("F8")); //d->action_view_text_mode->setExclusiveGroup("view_mode"); d->action_view_text_mode->setToolTip(xi18n("Switch to text view")); d->action_view_text_mode->setWhatsThis(xi18n("Switches to text view.")); d->actions_for_view_modes.insert( Kexi::TextViewMode, d->action_view_text_mode ); connect(d->action_view_text_mode, SIGNAL(triggered()), this, SLOT(slotViewTextMode())); } else d->action_view_text_mode = 0; */ if (d->isProjectNavigatorVisible) { d->action_show_nav = addAction("view_navigator", xi18n("Show Project Navigator"), "Alt+0"); d->action_show_nav->setToolTip(xi18n("Show the Project Navigator pane")); d->action_show_nav->setWhatsThis(xi18n("Shows the Project Navigator pane.")); connect(d->action_show_nav, SIGNAL(triggered()), this, SLOT(slotShowNavigator())); } else { d->action_show_nav = 0; } if (d->isProjectNavigatorVisible) { // Shortcut taken from "Activate Projects pane" http://doc.qt.io/qtcreator/creator-keyboard-shortcuts.html d->action_activate_nav = addAction("activate_navigator", xi18n("Activate Project Navigator"), "Alt+X"); d->action_activate_nav->setToolTip(xi18n("Activate the Project Navigator pane")); d->action_activate_nav->setWhatsThis(xi18n("Activates the Project Navigator pane. If it is hidden, shows it first.")); connect(d->action_activate_nav, SIGNAL(triggered()), this, SLOT(slotActivateNavigator())); } else { d->action_activate_nav = 0; } d->action_activate_mainarea = addAction("activate_mainarea", xi18n("Activate main area") // , "Alt+2"? //! @todo activate_mainarea: pressing Esc in project nav or propeditor should move back to the main area ); d->action_activate_mainarea->setToolTip(xi18n("Activate the main area")); d->action_activate_mainarea->setWhatsThis(xi18n("Activates the main area.")); connect(d->action_activate_mainarea, SIGNAL(triggered()), this, SLOT(slotActivateMainArea())); //! @todo windows with "_3" prefix have conflicting auto shortcut set to Alt+3 -> remove that! if (!d->userMode) { d->action_show_propeditor = addAction("view_propeditor", xi18n("Show Property Editor"), "Alt+3"); d->action_show_propeditor->setToolTip(xi18n("Show the Property Editor pane")); d->action_show_propeditor->setWhatsThis(xi18n("Shows the Property Editor pane.")); connect(d->action_show_propeditor, SIGNAL(triggered()), this, SLOT(slotShowPropertyEditor())); } else { d->action_show_propeditor = 0; } if (!d->userMode) { d->action_activate_propeditor = addAction("activate_propeditor", xi18n("Activate Property Editor"), "Alt+-"); d->action_activate_propeditor->setToolTip(xi18n("Activate the Property Editor pane")); d->action_activate_propeditor->setWhatsThis(xi18n("Activates the Property Editor pane. If it is hidden, shows it first.")); connect(d->action_activate_propeditor, SIGNAL(triggered()), this, SLOT(slotActivatePropertyEditor())); } else { d->action_activate_propeditor = 0; } d->action_view_global_search = addAction("view_global_search", xi18n("Switch to Global Search"), "Ctrl+K"); d->action_view_global_search->setToolTip(xi18n("Switch to Global Search box")); d->action_view_global_search->setWhatsThis(xi18n("Switches to Global Search box.")); // (connection is added elsewhere) //DATA MENU d->action_data_save_row = createSharedAction(xi18n("&Save Record"), koIconName("dialog-ok"), QKeySequence(Qt::SHIFT + Qt::Key_Return), "data_save_row"); d->action_data_save_row->setToolTip(xi18n("Save changes made to the current record")); d->action_data_save_row->setWhatsThis(xi18n("Saves changes made to the current record.")); //temp. disable because of problems with volatile actions setActionVolatile( d->action_data_save_row, true ); d->action_data_cancel_row_changes = createSharedAction(xi18n("&Cancel Record Changes"), koIconName("dialog-cancel"), QKeySequence(Qt::Key_Escape), "data_cancel_row_changes"); d->action_data_cancel_row_changes->setToolTip( xi18n("Cancel changes made to the current record")); d->action_data_cancel_row_changes->setWhatsThis( xi18n("Cancels changes made to the current record.")); //temp. disable because of problems with volatile actions setActionVolatile( d->action_data_cancel_row_changes, true ); d->action_data_execute = createSharedAction( xi18n("&Execute"), koIconName("media-playback-start"), QKeySequence(), "data_execute"); //! @todo d->action_data_execute->setToolTip(xi18n("")); //! @todo d->action_data_execute->setWhatsThis(xi18n("")); #ifdef KEXI_SHOW_UNIMPLEMENTED action = createSharedAction(futureI18n("&Filter"), koIconName("view-filter"), QKeySequence(), "data_filter"); setActionVolatile(action, true); #endif //! @todo action->setToolTip(xi18n("")); //! @todo action->setWhatsThis(xi18n("")); // - record-navigation related actions createSharedAction(KexiRecordNavigator::Actions::moveToFirstRecord(), QKeySequence(), "data_go_to_first_record"); createSharedAction(KexiRecordNavigator::Actions::moveToPreviousRecord(), QKeySequence(), "data_go_to_previous_record"); createSharedAction(KexiRecordNavigator::Actions::moveToNextRecord(), QKeySequence(), "data_go_to_next_record"); createSharedAction(KexiRecordNavigator::Actions::moveToLastRecord(), QKeySequence(), "data_go_to_last_record"); createSharedAction(KexiRecordNavigator::Actions::moveToNewRecord(), QKeySequence(), "data_go_to_new_record"); //FORMAT MENU d->action_format_font = createSharedAction(xi18n("&Font..."), koIconName("fonts-package"), QKeySequence(), "format_font"); d->action_format_font->setToolTip(xi18n("Change font for selected object")); d->action_format_font->setWhatsThis(xi18n("Changes font for selected object.")); //TOOLS MENU // WINDOW MENU // additional 'Window' menu items d->action_window_next = addAction("window_next", xi18n("&Next Window"), "Alt+Right"); d->action_window_next->setToolTip(xi18n("Next window")); d->action_window_next->setWhatsThis(xi18n("Switches to the next window.")); connect(d->action_window_next, SIGNAL(triggered()), this, SLOT(activateNextWindow())); d->action_window_previous = addAction("window_previous", xi18n("&Previous Window"), "Alt+Left"); d->action_window_previous->setToolTip(xi18n("Previous window")); d->action_window_previous->setWhatsThis(xi18n("Switches to the previous window.")); connect(d->action_window_previous, SIGNAL(triggered()), this, SLOT(activatePreviousWindow())); d->action_tab_next = addAction("tab_next", futureI18n("&Next Tab"), "Ctrl+Tab"); d->action_tab_next->setToolTip(futureI18n("Next tab")); d->action_tab_next->setWhatsThis(futureI18n("Switches to the next tab.")); connect(d->action_tab_next, &QAction::triggered, this, &KexiMainWindow::activateNextTab); d->action_tab_previous = addAction("tab_previous", futureI18n("&Previous Tab"), "Ctrl+Shift+Tab"); d->action_tab_previous->setToolTip(futureI18n("Previous tab")); d->action_tab_previous->setWhatsThis(futureI18n("Switches to the previous tab.")); connect(d->action_tab_previous, &QAction::triggered, this, &KexiMainWindow::activatePreviousTab); d->action_window_fullscreen = KStandardAction::fullScreen(this, SLOT(toggleFullScreen(bool)), this, ac); ac->addAction("full_screen", d->action_window_fullscreen); QList shortcuts; shortcuts << d->action_window_fullscreen->shortcut() << QKeySequence("F11"); d->action_window_fullscreen->setShortcuts(shortcuts); QShortcut *s = new QShortcut(d->action_window_fullscreen->shortcut(), this); connect(s, SIGNAL(activated()), d->action_window_fullscreen, SLOT(trigger())); if (d->action_window_fullscreen->shortcuts().count() > 1) { QShortcut *sa = new QShortcut(d->action_window_fullscreen->shortcuts().value(1), this); connect(sa, SIGNAL(activated()), d->action_window_fullscreen, SLOT(trigger())); } //SETTINGS MENU //! @todo put 'configure keys' into settings view #ifdef KEXI_SHOW_UNIMPLEMENTED //! @todo toolbars configuration will be handled in a special way #endif #ifdef KEXI_MACROS_SUPPORT Kexi::tempShowMacros() = true; #else Kexi::tempShowMacros() = false; #endif #ifdef KEXI_SCRIPTS_SUPPORT Kexi::tempShowScripts() = true; #else Kexi::tempShowScripts() = false; #endif #ifdef KEXI_SHOW_UNIMPLEMENTED //! @todo implement settings window in a specific way ac->addAction("settings", action = d->action_settings = new KexiMenuWidgetAction( KStandardAction::Preferences, this)); action->setObjectName("settings"); action->setText(futureI18n("Settings...")); action->setToolTip(futureI18n("Show Kexi settings")); action->setWhatsThis(futureI18n("Shows Kexi settings.")); connect(action, SIGNAL(triggered()), this, SLOT(slotSettings())); setupMainMenuActionShortcut(action); #else d->action_settings = d->dummy_action; #endif //! @todo reenable 'tip of the day' later #if 0 KStandardAction::tipOfDay(this, SLOT(slotTipOfTheDayAction()), actionCollection()) ->setWhatsThis(xi18n("This shows useful tips on the use of this application.")); #endif // GLOBAL d->action_show_help_menu = addAction("help_show_menu", xi18nc("Help Menu", "Help"), "Alt+H"); d->action_show_help_menu->setToolTip(xi18n("Show Help menu")); d->action_show_help_menu->setWhatsThis(xi18n("Shows Help menu.")); // (connection is added elsewhere) // ----- declare action categories, so form's "assign action to button" // (and macros in the future) will be able to recognize category // of actions and filter them ----------------------------------- //! @todo shouldn't we move this to core? Kexi::ActionCategories *acat = Kexi::actionCategories(); acat->addAction("data_execute", Kexi::PartItemActionCategory); //! @todo unused for now acat->addWindowAction("data_filter", KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addWindowAction("data_save_row", KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addWindowAction("data_cancel_row_changes", KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addWindowAction("delete_table_row", KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); //! @todo support this in KexiPart::FormObjectType as well acat->addWindowAction("data_sort_az", KexiPart::TableObjectType, KexiPart::QueryObjectType); //! @todo support this in KexiPart::FormObjectType as well acat->addWindowAction("data_sort_za", KexiPart::TableObjectType, KexiPart::QueryObjectType); //! @todo support this in KexiPart::FormObjectType as well acat->addWindowAction("edit_clear_table", KexiPart::TableObjectType, KexiPart::QueryObjectType); //! @todo support this in KexiPart::FormObjectType as well acat->addWindowAction("edit_copy_special_data_table", KexiPart::TableObjectType, KexiPart::QueryObjectType); //! @todo support this in FormObjectType as well acat->addWindowAction("project_export_data_table", KexiPart::TableObjectType, KexiPart::QueryObjectType); // GlobalActions, etc. acat->addAction("edit_copy", Kexi::GlobalActionCategory | Kexi::PartItemActionCategory); acat->addAction("edit_cut", Kexi::GlobalActionCategory | Kexi::PartItemActionCategory); acat->addAction("edit_paste", Kexi::GlobalActionCategory | Kexi::PartItemActionCategory); acat->addAction("edit_delete", Kexi::GlobalActionCategory | Kexi::PartItemActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("edit_delete_row", Kexi::GlobalActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("edit_edititem", Kexi::PartItemActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType); acat->addAction("edit_find", Kexi::GlobalActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("edit_findnext", Kexi::GlobalActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("edit_findprevious", Kexi::GlobalActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("edit_replace", Kexi::GlobalActionCategory | Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("edit_paste_special_data_table", Kexi::GlobalActionCategory); acat->addAction("help_about_app", Kexi::GlobalActionCategory); acat->addAction("help_about_kde", Kexi::GlobalActionCategory); acat->addAction("help_contents", Kexi::GlobalActionCategory); acat->addAction("help_report_bug", Kexi::GlobalActionCategory); acat->addAction("help_whats_this", Kexi::GlobalActionCategory); acat->addAction("help_donate", Kexi::GlobalActionCategory); // disabled for now acat->addAction("switch_application_language", Kexi::GlobalActionCategory); acat->addAction("options_configure_keybinding", Kexi::GlobalActionCategory); acat->addAction("project_close", Kexi::GlobalActionCategory); acat->addAction("project_import_data_table", Kexi::GlobalActionCategory); acat->addAction("project_new", Kexi::GlobalActionCategory); acat->addAction("project_open", Kexi::GlobalActionCategory); #ifdef KEXI_QUICK_PRINTING_SUPPORT //! @todo support this in FormObjectType, ReportObjectType as well as others acat->addAction("project_print", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType); //! @todo support this in FormObjectType, ReportObjectType as well as others acat->addAction("project_print_preview", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType); //! @todo support this in FormObjectType, ReportObjectType as well as others acat->addAction("project_print_setup", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType); #endif acat->addAction("quit", Kexi::GlobalActionCategory); acat->addAction("tools_compact_database", Kexi::GlobalActionCategory); acat->addAction("tools_import_project", Kexi::GlobalActionCategory); acat->addAction("tools_import_tables", Kexi::GlobalActionCategory); acat->addAction("view_data_mode", Kexi::GlobalActionCategory); acat->addAction("view_design_mode", Kexi::GlobalActionCategory); acat->addAction("view_text_mode", Kexi::GlobalActionCategory); acat->addAction("view_mainarea", Kexi::GlobalActionCategory); acat->addAction("view_navigator", Kexi::GlobalActionCategory); acat->addAction("activate_navigator", Kexi::GlobalActionCategory); acat->addAction("view_propeditor", Kexi::GlobalActionCategory); acat->addAction("activate_mainarea", Kexi::GlobalActionCategory); acat->addAction("activate_propeditor", Kexi::GlobalActionCategory); acat->addAction("window_close", Kexi::GlobalActionCategory | Kexi::WindowActionCategory); acat->setAllObjectTypesSupported("window_close", true); acat->addAction("window_next", Kexi::GlobalActionCategory); acat->addAction("window_previous", Kexi::GlobalActionCategory); acat->addAction("full_screen", Kexi::GlobalActionCategory); //skipped - design view only acat->addAction("format_font", Kexi::NoActionCategory); acat->addAction("project_save", Kexi::NoActionCategory); acat->addAction("edit_insert_empty_row", Kexi::NoActionCategory); //! @todo support this in KexiPart::TableObjectType, KexiPart::QueryObjectType later acat->addAction("edit_select_all", Kexi::NoActionCategory); //! @todo support this in KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType later acat->addAction("edit_redo", Kexi::NoActionCategory); //! @todo support this in KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType later acat->addAction("edit_undo", Kexi::NoActionCategory); //record-navigation related actions acat->addAction("data_go_to_first_record", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("data_go_to_previous_record", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("data_go_to_next_record", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("data_go_to_last_record", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); acat->addAction("data_go_to_new_record", Kexi::WindowActionCategory, KexiPart::TableObjectType, KexiPart::QueryObjectType, KexiPart::FormObjectType); //skipped - internal: acat->addAction("tablepart_create", Kexi::NoActionCategory); acat->addAction("querypart_create", Kexi::NoActionCategory); acat->addAction("formpart_create", Kexi::NoActionCategory); acat->addAction("reportpart_create", Kexi::NoActionCategory); acat->addAction("macropart_create", Kexi::NoActionCategory); acat->addAction("scriptpart_create", Kexi::NoActionCategory); } void KexiMainWindow::invalidateActions() { invalidateProjectWideActions(); invalidateSharedActions(); } void KexiMainWindow::invalidateSharedActions(QObject *o) { //! @todo enabling is more complex... /* d->action_edit_cut->setEnabled(true); d->action_edit_copy->setEnabled(true); d->action_edit_paste->setEnabled(true);*/ if (!o) o = focusWindow(); KexiSharedActionHost::invalidateSharedActions(o); } void KexiMainWindow::invalidateSharedActions() { invalidateSharedActions(0); } // unused, I think void KexiMainWindow::invalidateSharedActionsLater() { QTimer::singleShot(1, this, SLOT(invalidateSharedActions())); } void KexiMainWindow::invalidateProjectWideActions() { const bool has_window = currentWindow(); const bool window_dirty = currentWindow() && currentWindow()->isDirty(); const bool readOnly = d->prj && d->prj->dbConnection() && d->prj->dbConnection()->options()->isReadOnly(); //PROJECT MENU d->action_save->setEnabled(has_window && window_dirty && !readOnly); d->action_save_as->setEnabled(has_window && !readOnly); d->action_project_properties->setEnabled(d->prj); d->action_close->setEnabled(d->prj); d->action_project_relations->setEnabled(d->prj); //DATA MENU if (d->action_project_import_data_table) d->action_project_import_data_table->setEnabled(d->prj && !readOnly); if (d->action_tools_data_import) d->action_tools_data_import->setEnabled(d->prj && !readOnly); d->action_project_export_data_table->setEnabled( currentWindow() && currentWindow()->part()->info()->isDataExportSupported()); if (d->action_edit_paste_special_data_table) d->action_edit_paste_special_data_table->setEnabled(d->prj && !readOnly); #ifdef KEXI_QUICK_PRINTING_SUPPORT const bool printingActionsEnabled = currentWindow() && currentWindow()->part()->info()->isPrintingSupported() && !currentWindow()->neverSaved(); d->action_project_print->setEnabled(printingActionsEnabled); d->action_project_print_preview->setEnabled(printingActionsEnabled); d->action_project_print_setup->setEnabled(printingActionsEnabled); #endif //EDIT MENU //! @todo "copy special" is currently enabled only for data view mode; //! what about allowing it to enable in design view for "kexi/table" ? if (currentWindow() && currentWindow()->currentViewMode() == Kexi::DataViewMode) { KexiPart::Info *activePartInfo = currentWindow()->part()->info(); d->action_edit_copy_special_data_table->setEnabled( activePartInfo ? activePartInfo->isDataExportSupported() : false); } else { d->action_edit_copy_special_data_table->setEnabled(false); } d->action_edit_find->setEnabled(d->prj); //VIEW MENU if (d->action_show_nav) d->action_show_nav->setEnabled(d->prj); d->action_activate_mainarea->setEnabled(d->prj); if (d->action_show_propeditor) d->action_show_propeditor->setEnabled(d->prj); #ifdef KEXI_SHOW_CONTEXT_HELP d->action_show_helper->setEnabled(d->prj); #endif //CREATE MENU if (d->tabbedToolBar && d->tabbedToolBar->createWidgetToolBar()) d->tabbedToolBar->createWidgetToolBar()->setEnabled(d->prj); // DATA MENU //TOOLS MENU // "compact db" supported if there's no db or the current db supports compacting and is opened r/w: d->action_tools_compact_database->setEnabled( //! @todo Support compacting of non-opened projects /*!d->prj ||*/ (!readOnly && d->prj && d->prj->dbConnection() && (d->prj->dbConnection()->driver()->features() & KDbDriver::CompactingDatabaseSupported)) ); //DOCKS if (d->navigator) { d->navigator->setEnabled(d->prj); } if (d->propEditor) d->propEditorTabWidget->setEnabled(d->prj); } tristate KexiMainWindow::startup() { tristate result = true; switch (KexiStartupHandler::global()->action()) { case KexiStartupHandler::CreateBlankProject: d->updatePropEditorVisibility(Kexi::NoViewMode); break; #ifdef KEXI_PROJECT_TEMPLATES case KexiStartupHandler::CreateFromTemplate: result = createProjectFromTemplate(*KexiStartupHandler::global()->projectData()); break; #endif case KexiStartupHandler::OpenProject: result = openProject(*KexiStartupHandler::global()->projectData()); break; case KexiStartupHandler::ImportProject: result = showProjectMigrationWizard( KexiStartupHandler::global()->importActionData().mimeType, KexiStartupHandler::global()->importActionData().fileName ); break; case KexiStartupHandler::ShowWelcomeScreen: //! @todo show welcome screen as soon as is available QTimer::singleShot(100, this, SLOT(slotProjectWelcome())); break; default: d->updatePropEditorVisibility(Kexi::NoViewMode); } return result; } static QString internalReason(const KDbResult &result) { const QString msg = result.message(); if (msg.isEmpty()) { return QString(); } return xi18n("
(reason: %1)", msg); } tristate KexiMainWindow::openProject(const KexiProjectData& projectData) { //qDebug() << projectData; QScopedPointer prj(createKexiProjectObject(projectData)); if (~KexiDBPasswordDialog::getPasswordIfNeeded(prj->data()->connectionData(), this)) { return cancelled; } bool incompatibleWithKexi; tristate res = prj->open(&incompatibleWithKexi); if (prj->data()->connectionData()->isPasswordNeeded()) { // password was supplied in this session, and shouldn't be stored or reused afterwards, // so let's remove it prj->data()->connectionData()->setPassword(QString()); } if (~res) { return cancelled; } else if (!res) { if (incompatibleWithKexi) { if (KMessageBox::Yes == KMessageBox::questionYesNo(this, xi18nc("@info (don't add tags around %1, it's done already)", "Database project %1 does not appear to have been created using Kexi." "Do you want to import it as a new Kexi project?", projectData.infoString()), QString(), KGuiItem(xi18nc("@action:button Import Database", "&Import..."), KexiIconName("database-import")), KStandardGuiItem::cancel())) { const bool anotherProjectAlreadyOpened = prj; tristate res = showProjectMigrationWizard("application/x-kexi-connectiondata", projectData.databaseName(), *projectData.connectionData()); if (!anotherProjectAlreadyOpened) //the project could have been opened within this instance return res; //always return cancelled because even if migration succeeded, new Kexi instance //will be started if user wanted to open the imported db return cancelled; } return cancelled; } return false; } // success d->prj = prj.take(); setupProjectNavigator(); d->prj->data()->setLastOpened(QDateTime::currentDateTime()); Kexi::recentProjects()->addProjectData(*d->prj->data()); updateReadOnlyState(); invalidateActions(); setMessagesEnabled(false); QTimer::singleShot(1, this, SLOT(slotAutoOpenObjectsLater())); if (d->tabbedToolBar) { d->tabbedToolBar->showTab("create");// not needed since create toolbar already shows toolbar! move when kexi starts d->tabbedToolBar->showTab("data"); d->tabbedToolBar->showTab("external"); d->tabbedToolBar->showTab("tools"); d->tabbedToolBar->hideTab("form");//temporalily until createToolbar is split d->tabbedToolBar->hideTab("report");//temporalily until createToolbar is split // make sure any tab is activated d->tabbedToolBar->setCurrentTab(0); } return true; } tristate KexiMainWindow::openProject(const KexiProjectData& data, const QString& shortcutPath, bool *opened) { if (!shortcutPath.isEmpty() && d->prj) { const tristate result = openProjectInExternalKexiInstance( shortcutPath, QString(), QString()); if (result == true) { *opened = true; } return result; } return openProject(data); } tristate KexiMainWindow::createProjectFromTemplate(const KexiProjectData& projectData) { Q_UNUSED(projectData); #ifdef KEXI_PROJECT_TEMPLATES QStringList mimetypes; mimetypes.append(KDb::defaultFileBasedDriverMimeType()); QString fname; //! @todo KEXI3 add equivalent of kfiledialog:/// const QString startDir("kfiledialog:///OpenExistingOrCreateNewProject"/*as in KexiNewProjectWizard*/); const QString caption(xi18nc("@window:title", "Select New Project's Location")); while (true) { if (fname.isEmpty() && !projectData.connectionData()->databaseName().isEmpty()) { //propose filename from db template name fname = projectData.connectionData()->databaseName(); } const bool specialDir = fname.isEmpty(); qDebug() << fname << "............."; QFileDialog dlg(specialDir ? QUrl(startDir) : QUrl(), QString(), this); dlg.setModal(true); dlg.setMimeFilter(mimetypes); if (!specialDir) dlg.selectUrl(QUrl::fromLocalFile(fname); // may also be a filename dlg.setFileMode(QFileDialog::ExistingFile); dlg.setFileMode(QFileDialog::AcceptOpen); dlg.setWindowTitle(caption); if (QDialog::Accepted != dlg.exec()) { return cancelled; } if (dlg.selectedFiles().isEmpty() { return cancelled; } fname = dlg.selectedFiles().first(); if (fname.isEmpty()) { return cancelled; } if (KexiUtils::askForFileOverwriting(fname, this)) { break; } } QFile sourceFile(projectData.connectionData()->fileName()); if (!sourceFile.copy(fname)) { //! @todo show error from with QFile::FileError return false; } return openProject(fname, 0, QString(), projectData.autoopenObjects/*copy*/); #else return false; #endif } void KexiMainWindow::updateReadOnlyState() { const bool readOnly = d->prj && d->prj->dbConnection() && d->prj->dbConnection()->options()->isReadOnly(); //! @todo KEXI3 show read-only flag in the GUI because we have no statusbar if (d->navigator) { d->navigator->setReadOnly(readOnly); } // update "insert ....." actions for every part KexiPart::PartInfoList *plist = Kexi::partManager().infoList(); if (plist) { foreach(KexiPart::Info *info, *plist) { QAction *a = info->newObjectAction(); if (a) a->setEnabled(!readOnly); } } } void KexiMainWindow::slotAutoOpenObjectsLater() { QString not_found_msg; bool openingCancelled; //ok, now open "autoopen: objects if (d->prj) { for (const KexiProjectData::ObjectInfo &info : d->prj->data()->autoopenObjects) { KexiPart::Info *i = Kexi::partManager().infoForPluginId(info.value("type")); if (!i) { not_found_msg += "
  • "; if (!info.value("name").isEmpty()) { not_found_msg += (QString("\"") + info.value("name") + "\" - "); } if (info.value("action") == "new") { not_found_msg += xi18n("cannot create object - unknown object type \"%1\"", info.value("type")); } else { not_found_msg += xi18n("unknown object type \"%1\"", info.value("type")); } not_found_msg += internalReason(Kexi::partManager().result()) + "
  • "; continue; } // * NEW if (info.value("action") == "new") { if (!newObject(i, &openingCancelled) && !openingCancelled) { not_found_msg += "
  • "; not_found_msg += (xi18n("cannot create object of type \"%1\"", info.value("type")) + internalReason(d->prj->result()) + "
  • "); } else { d->wasAutoOpen = true; } continue; } KexiPart::Item *item = d->prj->item(i, info.value("name")); if (!item) { QString taskName; if (info.value("action") == "execute") { taskName = xi18nc("\"executing object\" action", "executing"); #ifdef KEXI_QUICK_PRINTING_SUPPORT } else if (info->value("action") == "print-preview") { taskName = futureI18n("making print preview for"); } else if (info->value("action") == "print") { taskName = futureI18n("printing"); #endif } else { taskName = xi18n("opening"); } not_found_msg += (QString("
  • ") + taskName + " \"" + info.value("name") + "\" - "); if ("table" == info.value("type").toLower()) { not_found_msg += xi18n("table not found"); } else if ("query" == info.value("type").toLower()) { not_found_msg += xi18n("query not found"); } else if ("macro" == info.value("type").toLower()) { not_found_msg += xi18n("macro not found"); } else if ("script" == info.value("type").toLower()) { not_found_msg += xi18n("script not found"); } else { not_found_msg += xi18n("object not found"); } not_found_msg += (internalReason(d->prj->result()) + "
  • "); continue; } // * EXECUTE, PRINT, PRINT PREVIEW if (info.value("action") == "execute") { tristate res = executeItem(item); if (false == res) { not_found_msg += (QString("
  • \"") + info.value("name") + "\" - " + xi18n("cannot execute object") + internalReason(d->prj->result()) + "
  • "); } continue; } #ifdef KEXI_QUICK_PRINTING_SUPPORT else if (info.value("action") == "print") { tristate res = printItem(item); if (false == res) { not_found_msg += (QString("
  • \"") + info.value("name") + "\" - " + futureI18n("cannot print object") + internalReason(d->prj->result()) + "
  • "); } continue; } else if (info.value("action") == "print-preview") { tristate res = printPreviewForItem(item); if (false == res) { not_found_msg += (QString("
  • \"") + info.value("name") + "\" - " + futureI18n("cannot make print preview of object") + internalReason(d->prj->result()) + "
  • "); } continue; } #endif Kexi::ViewMode viewMode; if (info.value("action") == "open") { viewMode = Kexi::DataViewMode; } else if (info.value("action") == "design") { viewMode = Kexi::DesignViewMode; } else if (info.value("action") == "edittext") { viewMode = Kexi::TextViewMode; } else { continue; //sanity } QString openObjectMessage; if (!openObject(item, viewMode, &openingCancelled, 0, &openObjectMessage) && (!openingCancelled || !openObjectMessage.isEmpty())) { not_found_msg += (QString("
  • \"") + info.value("name") + "\" - "); if (openObjectMessage.isEmpty()) { not_found_msg += xi18n("cannot open object"); } else { not_found_msg += openObjectMessage; } not_found_msg += internalReason(d->prj->result()) + "
  • "; continue; } else { d->wasAutoOpen = true; } } } setMessagesEnabled(true); if (!not_found_msg.isEmpty()) { showErrorMessage(xi18n("You have requested selected objects to be automatically opened " "or processed on startup. Several objects cannot be opened or processed."), QString("
      %1
    ").arg(not_found_msg)); } d->updatePropEditorVisibility(currentWindow() ? currentWindow()->currentViewMode() : Kexi::NoViewMode); #if defined(KDOCKWIDGET_P) if (d->propEditor) { KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget(); KDockSplitter *ds = (KDockSplitter *)dw->parentWidget(); if (ds) ds->setSeparatorPosInPercent(d->config->readEntry("RightDockPosition", 80/* % */)); } #endif updateAppCaption(); if (d->tabbedToolBar) { d->tabbedToolBar->hideMainMenu(); } qApp->processEvents(); emit projectOpened(); } tristate KexiMainWindow::closeProject() { if (d->tabbedToolBar) d->tabbedToolBar->hideMainMenu(); #ifndef KEXI_NO_PENDING_DIALOGS if (d->pendingWindowsExist()) { qDebug() << "pendingWindowsExist..."; d->actionToExecuteWhenPendingJobsAreFinished = Private::CloseProjectAction; return cancelled; } #endif //only save nav. visibility setting if there is project opened d->saveSettingsForShowProjectNavigator = d->prj && d->isProjectNavigatorVisible; if (!d->prj) return true; { // make sure the project can be closed bool cancel = false; emit acceptProjectClosingRequested(&cancel); if (cancel) return cancelled; } d->windowExistedBeforeCloseProject = currentWindow(); #if defined(KDOCKWIDGET_P) //remember docks position - will be used on storeSettings() if (d->propEditor) { KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget(); KDockSplitter *ds = (KDockSplitter *)dw->parentWidget(); if (ds) d->propEditorDockSeparatorPos = ds->separatorPosInPercent(); } if (d->nav) { if (d->propEditor) { //! @todo KEXI3 if (d->openedWindowsCount() == 0) //! @todo KEXI3 makeWidgetDockVisible(d->propEditorTabWidget); KDockWidget *dw = (KDockWidget *)d->propEditorTabWidget->parentWidget(); KDockSplitter *ds = (KDockSplitter *)dw->parentWidget(); if (ds) ds->setSeparatorPosInPercent(80); } KDockWidget *dw = (KDockWidget *)d->nav->parentWidget(); KDockSplitter *ds = (KDockSplitter *)dw->parentWidget(); int dwWidth = dw->width(); if (ds) { if (d->openedWindowsCount() != 0 && d->propEditorTabWidget && d->propEditorTabWidget->isVisible()) { d->navDockSeparatorPos = ds->separatorPosInPercent(); } else { d->navDockSeparatorPos = (100 * dwWidth) / width(); } } } #endif //close each window, optionally asking if user wants to close (if data changed) while (currentWindow()) { tristate res = closeWindow(currentWindow()); if (!res || ~res) return res; } // now we will close for sure emit beforeProjectClosing(); if (!d->prj->closeConnection()) return false; if (d->navigator) { d->navWasVisibleBeforeProjectClosing = d->navDockWidget->isVisible(); d->navDockWidget->hide(); d->navigator->setProject(0); slotProjectNavigatorVisibilityChanged(true); // hide side tab } if (d->propEditorDockWidget) d->propEditorDockWidget->hide(); d->clearWindows(); //sanity! delete d->prj; d->prj = 0; updateReadOnlyState(); invalidateActions(); updateAppCaption(); emit projectClosed(); return true; } void KexiMainWindow::setupContextHelp() { #ifdef KEXI_SHOW_CONTEXT_HELP d->ctxHelp = new KexiContextHelp(d->mainWidget, this); //! @todo /* d->ctxHelp->setContextHelp(xi18n("Welcome"),xi18n("The KEXI team wishes you a lot of productive work, " "with this product.


    If you have found a bug or have a feature request, please don't " "hesitate to report it at our issue " "tracking system .


    If you would like to join our effort, the development documentation " "at www.kexi-project.org is a good starting point."),0); */ addToolWindow(d->ctxHelp, KDockWidget::DockBottom | KDockWidget::DockLeft, getMainDockWidget(), 20); #endif } void KexiMainWindow::setupMainWidget() { QVBoxLayout *vlyr = new QVBoxLayout(this); vlyr->setContentsMargins(0, 0, 0, 0); vlyr->setSpacing(0); if (d->isMainMenuVisible) { QWidget *tabbedToolBarContainer = new QWidget(this); vlyr->addWidget(tabbedToolBarContainer); QVBoxLayout *tabbedToolBarContainerLyr = new QVBoxLayout(tabbedToolBarContainer); tabbedToolBarContainerLyr->setSpacing(0); tabbedToolBarContainerLyr->setContentsMargins( KexiUtils::marginHint() / 2, KexiUtils::marginHint() / 2, KexiUtils::marginHint() / 2, KexiUtils::marginHint() / 2); d->tabbedToolBar = new KexiTabbedToolBar(tabbedToolBarContainer); Q_ASSERT(d->action_view_global_search); connect(d->action_view_global_search, SIGNAL(triggered()), d->tabbedToolBar, SLOT(activateSearchLineEdit())); tabbedToolBarContainerLyr->addWidget(d->tabbedToolBar); d->tabbedToolBar->hideTab("form"); //temporarily until createToolbar is split d->tabbedToolBar->hideTab("report"); //temporarily until createToolbar is split } else { d->tabbedToolBar = 0; } QWidget *mainWidgetContainer = new QWidget(); vlyr->addWidget(mainWidgetContainer, 1); QHBoxLayout *mainWidgetContainerLyr = new QHBoxLayout(mainWidgetContainer); mainWidgetContainerLyr->setContentsMargins(0, 0, 0, 0); mainWidgetContainerLyr->setSpacing(0); KMultiTabBar *mtbar = new KMultiTabBar(KMultiTabBar::Left); mtbar->setStyle(KMultiTabBar::VSNET); mainWidgetContainerLyr->addWidget(mtbar); d->multiTabBars.insert(mtbar->position(), mtbar); d->mainWidget = new KexiMainWidget(); d->mainWidget->setParent(this); d->mainWidget->tabWidget()->setTabsClosable(true); connect(d->mainWidget->tabWidget(), SIGNAL(tabCloseRequested(int)), this, SLOT(closeWindowForTab(int))); mainWidgetContainerLyr->addWidget(d->mainWidget, 1); mtbar = new KMultiTabBar(KMultiTabBar::Right); mtbar->setStyle(KMultiTabBar::VSNET); mainWidgetContainerLyr->addWidget(mtbar); d->multiTabBars.insert(mtbar->position(), mtbar); } void KexiMainWindow::slotSetProjectNavigatorVisible(bool set) { if (d->navDockWidget) d->navDockWidget->setVisible(set); } void KexiMainWindow::slotSetPropertyEditorVisible(bool set) { if (d->propEditorDockWidget) d->propEditorDockWidget->setVisible(set); } void KexiMainWindow::slotProjectNavigatorVisibilityChanged(bool visible) { d->setTabBarVisible(KMultiTabBar::Left, PROJECT_NAVIGATOR_TABBAR_ID, d->navDockWidget, !visible); } void KexiMainWindow::slotPropertyEditorVisibilityChanged(bool visible) { if (!d->enable_slotPropertyEditorVisibilityChanged) return; d->setPropertyEditorTabBarVisible(!visible); if (!visible) d->propertyEditorCollapsed = true; } void KexiMainWindow::slotMultiTabBarTabClicked(int id) { if (id == PROJECT_NAVIGATOR_TABBAR_ID) { slotProjectNavigatorVisibilityChanged(true); d->navDockWidget->show(); } else if (id == PROPERTY_EDITOR_TABBAR_ID) { slotPropertyEditorVisibilityChanged(true); d->propEditorDockWidget->show(); d->propertyEditorCollapsed = false; } } static Qt::DockWidgetArea applyRightToLeftToDockArea(Qt::DockWidgetArea area) { if (QApplication::layoutDirection() == Qt::RightToLeft) { if (area == Qt::LeftDockWidgetArea) { return Qt::RightDockWidgetArea; } else if (area == Qt::RightDockWidgetArea) { return Qt::LeftDockWidgetArea; } } return area; } void KexiMainWindow::setupProjectNavigator() { if (!d->isProjectNavigatorVisible) return; if (d->navigator) { d->navDockWidget->show(); } else { KexiDockableWidget* navDockableWidget = new KexiDockableWidget; d->navigator = new KexiProjectNavigator(navDockableWidget); kexiTester() << KexiTestObject(d->navigator, "KexiProjectNavigator"); navDockableWidget->setWidget(d->navigator); d->navDockWidget = new KexiDockWidget(d->navigator->windowTitle(), d->mainWidget); d->navDockWidget->setObjectName("ProjectNavigatorDockWidget"); d->mainWidget->addDockWidget( applyRightToLeftToDockArea(Qt::LeftDockWidgetArea), d->navDockWidget, Qt::Vertical); navDockableWidget->setParent(d->navDockWidget); d->navDockWidget->setWidget(navDockableWidget); KConfigGroup mainWindowGroup(d->config->group("MainWindow")); const QSize projectNavigatorSize = mainWindowGroup.readEntry("ProjectNavigatorSize", QSize()); if (!projectNavigatorSize.isNull()) { navDockableWidget->setSizeHint(projectNavigatorSize); } connect(d->navDockWidget, SIGNAL(visibilityChanged(bool)), this, SLOT(slotProjectNavigatorVisibilityChanged(bool))); //Nav2 Signals connect(d->navigator, SIGNAL(openItem(KexiPart::Item*,Kexi::ViewMode)), this, SLOT(openObject(KexiPart::Item*,Kexi::ViewMode))); connect(d->navigator, SIGNAL(openOrActivateItem(KexiPart::Item*,Kexi::ViewMode)), this, SLOT(openObjectFromNavigator(KexiPart::Item*,Kexi::ViewMode))); connect(d->navigator, SIGNAL(newItem(KexiPart::Info*)), this, SLOT(newObject(KexiPart::Info*))); connect(d->navigator, SIGNAL(removeItem(KexiPart::Item*)), this, SLOT(removeObject(KexiPart::Item*))); connect(d->navigator->model(), SIGNAL(renameItem(KexiPart::Item*,QString,bool*)), this, SLOT(renameObject(KexiPart::Item*,QString,bool*))); connect(d->navigator->model(), SIGNAL(changeItemCaption(KexiPart::Item*,QString,bool*)), this, SLOT(setObjectCaption(KexiPart::Item*,QString,bool*))); connect(d->navigator, SIGNAL(executeItem(KexiPart::Item*)), this, SLOT(executeItem(KexiPart::Item*))); connect(d->navigator, SIGNAL(exportItemToClipboardAsDataTable(KexiPart::Item*)), this, SLOT(copyItemToClipboardAsDataTable(KexiPart::Item*))); connect(d->navigator, SIGNAL(exportItemToFileAsDataTable(KexiPart::Item*)), this, SLOT(exportItemAsDataTable(KexiPart::Item*))); #ifdef KEXI_QUICK_PRINTING_SUPPORT connect(d->navigator, SIGNAL(printItem(KexiPart::Item*)), this, SLOT(printItem(KexiPart::Item*))); connect(d->navigator, SIGNAL(pageSetupForItem(KexiPart::Item*)), this, SLOT(showPageSetupForItem(KexiPart::Item*))); #endif connect(d->navigator, SIGNAL(selectionChanged(KexiPart::Item*)), this, SLOT(slotPartItemSelectedInNavigator(KexiPart::Item*))); } if (d->prj->isConnected()) { QString partManagerErrorMessages; if (!partManagerErrorMessages.isEmpty()) { showWarningContinueMessage(partManagerErrorMessages, QString(), "ShowWarningsRelatedToPluginsLoading"); } d->navigator->setProject(d->prj, QString()/*all classes*/, &partManagerErrorMessages); } connect(d->prj, SIGNAL(newItemStored(KexiPart::Item*)), d->navigator->model(), SLOT(slotAddItem(KexiPart::Item*))); connect(d->prj, SIGNAL(itemRemoved(KexiPart::Item)), d->navigator->model(), SLOT(slotRemoveItem(KexiPart::Item))); d->navigator->setFocus(); if (d->forceShowProjectNavigatorOnCreation) { slotShowNavigator(); d->forceShowProjectNavigatorOnCreation = false; } else if (d->forceHideProjectNavigatorOnCreation) { d->forceHideProjectNavigatorOnCreation = false; } invalidateActions(); } void KexiMainWindow::slotLastActions() { } void KexiMainWindow::setupPropertyEditor() { if (!d->propEditor) { KConfigGroup mainWindowGroup(d->config->group("MainWindow")); //! @todo FIX LAYOUT PROBLEMS d->propEditorDockWidget = new KexiDockWidget(xi18n("Property Editor"), d->mainWidget); d->propEditorDockWidget->setObjectName("PropertyEditorDockWidget"); d->mainWidget->addDockWidget( applyRightToLeftToDockArea(Qt::RightDockWidgetArea), d->propEditorDockWidget, Qt::Vertical ); connect(d->propEditorDockWidget, SIGNAL(visibilityChanged(bool)), this, SLOT(slotPropertyEditorVisibilityChanged(bool))); d->propEditorDockableWidget = new KexiDockableWidget(d->propEditorDockWidget); d->propEditorDockWidget->setWidget(d->propEditorDockableWidget); const QSize propertyEditorSize = mainWindowGroup.readEntry("PropertyEditorSize", QSize()); if (!propertyEditorSize.isNull()) { d->propEditorDockableWidget->setSizeHint(propertyEditorSize); } QWidget *propEditorDockWidgetContents = new QWidget(d->propEditorDockableWidget); d->propEditorDockableWidget->setWidget(propEditorDockWidgetContents); QVBoxLayout *propEditorDockWidgetContentsLyr = new QVBoxLayout(propEditorDockWidgetContents); propEditorDockWidgetContentsLyr->setContentsMargins(0, 0, 0, 0); d->propEditorTabWidget = new QTabWidget(propEditorDockWidgetContents); d->propEditorTabWidget->setDocumentMode(true); propEditorDockWidgetContentsLyr->addWidget(d->propEditorTabWidget); d->propEditor = new KexiPropertyEditorView(d->propEditorTabWidget); d->propEditorTabWidget->setWindowTitle(d->propEditor->windowTitle()); d->propEditorTabWidget->addTab(d->propEditor, xi18n("Properties")); //! @todo REMOVE? d->propEditor->installEventFilter(this); KConfigGroup propertyEditorGroup(d->config->group("PropertyEditor")); QFont f(KexiUtils::smallestReadableFont()); const qreal pointSizeF = propertyEditorGroup.readEntry("FontPointSize", -1.0f); // points are more accurate if (pointSizeF > 0.0) { f.setPointSizeF(pointSizeF); } else { const int pixelSize = propertyEditorGroup.readEntry("FontSize", -1); // compatibility with Kexi 2.x if (pixelSize > 0) { f.setPixelSize(pixelSize); } } d->propEditorTabWidget->setFont(f); d->enable_slotPropertyEditorVisibilityChanged = false; d->propEditorDockWidget->setVisible(false); d->enable_slotPropertyEditorVisibilityChanged = true; } } void KexiMainWindow::slotPartLoaded(KexiPart::Part* p) { if (!p) return; p->createGUIClients(); } void KexiMainWindow::updateAppCaption() { //! @todo allow to set custom "static" app caption d->appCaptionPrefix.clear(); if (d->prj && d->prj->data()) {//add project name d->appCaptionPrefix = d->prj->data()->caption(); if (d->appCaptionPrefix.isEmpty()) { d->appCaptionPrefix = d->prj->data()->databaseName(); } if (d->prj->dbConnection()->options()->isReadOnly()) { d->appCaptionPrefix = xi18nc(" (read only)", "%1 (read only)", d->appCaptionPrefix); } } setWindowTitle(d->appCaptionPrefix); } bool KexiMainWindow::queryClose() { #ifndef KEXI_NO_PENDING_DIALOGS if (d->pendingWindowsExist()) { qDebug() << "pendingWindowsExist..."; d->actionToExecuteWhenPendingJobsAreFinished = Private::QuitAction; return false; } #endif const tristate res = closeProject(); if (~res) return false; if (res == true) storeSettings(); if (! ~res) { Kexi::deleteGlobalObjects(); qApp->quit(); } return ! ~res; } void KexiMainWindow::closeEvent(QCloseEvent *ev) { d->mainWidget->closeEvent(ev); } static const QSize KEXI_MIN_WINDOW_SIZE(1024, 768); void KexiMainWindow::restoreSettings() { KConfigGroup mainWindowGroup(d->config->group("MainWindow")); const bool maximize = mainWindowGroup.readEntry("Maximized", false); const QRect geometry(mainWindowGroup.readEntry("Geometry", QRect())); if (geometry.isValid()) setGeometry(geometry); else if (maximize) setWindowState(windowState() | Qt::WindowMaximized); else { QRect desk = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber(this)); if (desk.width() <= KEXI_MIN_WINDOW_SIZE.width() || desk.height() <= KEXI_MIN_WINDOW_SIZE.height()) { setWindowState(windowState() | Qt::WindowMaximized); } else { resize(KEXI_MIN_WINDOW_SIZE); } } // Saved settings } void KexiMainWindow::storeSettings() { //qDebug(); KConfigGroup mainWindowGroup(d->config->group("MainWindow")); if (isMaximized()) { mainWindowGroup.writeEntry("Maximized", true); mainWindowGroup.deleteEntry("Geometry"); } else { mainWindowGroup.deleteEntry("Maximized"); mainWindowGroup.writeEntry("Geometry", geometry()); } if (d->navigator) mainWindowGroup.writeEntry("ProjectNavigatorSize", d->navigator->parentWidget()->size()); if (d->propEditorDockableWidget) mainWindowGroup.writeEntry("PropertyEditorSize", d->propEditorDockableWidget->size()); d->config->sync(); } void KexiMainWindow::registerChild(KexiWindow *window) { //qDebug(); connect(window, SIGNAL(dirtyChanged(KexiWindow*)), this, SLOT(slotDirtyFlagChanged(KexiWindow*))); if (window->id() != -1) { d->insertWindow(window); } //qDebug() << "ID=" << window->id(); } void KexiMainWindow::updateCustomPropertyPanelTabs(KexiWindow *prevWindow, Kexi::ViewMode prevViewMode) { updateCustomPropertyPanelTabs( prevWindow ? prevWindow->part() : 0, prevWindow ? prevWindow->currentViewMode() : prevViewMode, currentWindow() ? currentWindow()->part() : 0, currentWindow() ? currentWindow()->currentViewMode() : Kexi::NoViewMode ); } void KexiMainWindow::updateCustomPropertyPanelTabs( KexiPart::Part *prevWindowPart, Kexi::ViewMode prevViewMode, KexiPart::Part *curWindowPart, Kexi::ViewMode curViewMode) { if (!d->propEditorTabWidget) return; if ( !curWindowPart || (/*prevWindowPart &&*/ curWindowPart && (prevWindowPart != curWindowPart || prevViewMode != curViewMode) ) ) { if (d->partForPreviouslySetupPropertyPanelTabs) { //remember current page number for this part if (( prevViewMode == Kexi::DesignViewMode && static_cast(d->partForPreviouslySetupPropertyPanelTabs) != curWindowPart) //part changed || curViewMode != Kexi::DesignViewMode) { //..or switching to other view mode d->recentlySelectedPropertyPanelPages.insert( d->partForPreviouslySetupPropertyPanelTabs, d->propEditorTabWidget->currentIndex()); } } //delete old custom tabs (other than 'property' tab) const int count = d->propEditorTabWidget->count(); for (int i = 1; i < count; i++) d->propEditorTabWidget->removeTab(1); } //don't change anything if part is not switched nor view mode changed if ((!prevWindowPart && !curWindowPart) || (prevWindowPart == curWindowPart && prevViewMode == curViewMode) || (curWindowPart && curViewMode != Kexi::DesignViewMode)) { //new part for 'previously setup tabs' d->partForPreviouslySetupPropertyPanelTabs = curWindowPart; return; } if (curWindowPart) { //recreate custom tabs curWindowPart->setupCustomPropertyPanelTabs(d->propEditorTabWidget); //restore current page number for this part if (d->recentlySelectedPropertyPanelPages.contains(curWindowPart)) { d->propEditorTabWidget->setCurrentIndex( d->recentlySelectedPropertyPanelPages[ curWindowPart ] ); } } //new part for 'previously setup tabs' d->partForPreviouslySetupPropertyPanelTabs = curWindowPart; } void KexiMainWindow::activeWindowChanged(KexiWindow *window, KexiWindow *prevWindow) { //qDebug() << "to=" << (window ? window->windowTitle() : ""); bool windowChanged = prevWindow != window; if (windowChanged) { if (prevWindow) { //inform previously activated dialog about deactivation prevWindow->deactivate(); } } updateCustomPropertyPanelTabs(prevWindow, prevWindow ? prevWindow->currentViewMode() : Kexi::NoViewMode); // inform the current view of the new dialog about property switching // (this will also call KexiMainWindow::propertySetSwitched() to update the current property editor's set if (windowChanged && currentWindow()) currentWindow()->selectedView()->propertySetSwitched(); if (windowChanged) { if (currentWindow() && currentWindow()->currentViewMode() != 0 && window) { //on opening new dialog it can be 0; we don't want this d->updatePropEditorVisibility(currentWindow()->currentViewMode()); restoreDesignTabIfNeeded(window->partItem()->pluginId(), window->currentViewMode(), prevWindow ? prevWindow->partItem()->identifier() : 0); activateDesignTabIfNeeded(window->partItem()->pluginId(), window->currentViewMode()); } } invalidateActions(); d->updateFindDialogContents(); if (window) window->setFocus(); } bool KexiMainWindow::activateWindow(int id) { #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; return activateWindow(*d->openedWindowFor(id, pendingType)); #else return activateWindow(*d->openedWindowFor(id)); #endif } bool KexiMainWindow::activateWindow(KexiWindow& window) { //qDebug(); d->focus_before_popup = &window; d->mainWidget->tabWidget()->setCurrentWidget(window.parentWidget()/*container*/); window.activate(); return true; } void KexiMainWindow::activateNextWindow() { // Case 1: go to next assistant page KexiAssistantPage *page = d->visibleMainMenuWidgetPage(); if (page) { page->next(); return; } // Case 2: go to next tab activateNextTab(); } void KexiMainWindow::activatePreviousWindow() { // Case 1: go to previous assistant page KexiAssistantPage *page = d->visibleMainMenuWidgetPage(); if (page) { page->tryBack(); return; } // Case 2: go to previous tab activatePreviousTab(); } void KexiMainWindow::activateNextTab() { //! @todo } void KexiMainWindow::activatePreviousTab() { //! @todo } void KexiMainWindow::slotSettings() { if (d->tabbedToolBar) { d->tabbedToolBar->showMainMenu("settings"); // dummy QLabel *dummy = KEXI_UNFINISHED_LABEL(actionCollection()->action("settings")->text()); d->tabbedToolBar->setMainMenuContent(dummy); } } void KexiMainWindow::slotConfigureKeys() { KShortcutsDialog::configure(actionCollection(), KShortcutsEditor::LetterShortcutsDisallowed, this); } void KexiMainWindow::slotConfigureToolbars() { KEditToolBar edit(actionCollection()); (void) edit.exec(); } void KexiMainWindow::slotProjectNew() { createNewProject(); } KexiProject* KexiMainWindow::createKexiProjectObject(const KexiProjectData &data) { KexiProject *prj = new KexiProject(data, this); connect(prj, SIGNAL(itemRenamed(KexiPart::Item,QString)), this, SLOT(slotObjectRenamed(KexiPart::Item,QString))); if (d->navigator){ connect(prj, SIGNAL(itemRemoved(KexiPart::Item)), d->navigator->model(), SLOT(slotRemoveItem(KexiPart::Item))); } return prj; } void KexiMainWindow::createNewProject() { if (!d->tabbedToolBar) return; d->tabbedToolBar->showMainMenu("project_new"); KexiNewProjectAssistant* assistant = new KexiNewProjectAssistant; connect(assistant, SIGNAL(createProject(KexiProjectData)), this, SLOT(createNewProject(KexiProjectData))); d->tabbedToolBar->setMainMenuContent(assistant); } tristate KexiMainWindow::createNewProject(const KexiProjectData &projectData) { QScopedPointer prj(createKexiProjectObject(projectData)); tristate res = prj->create(true /*overwrite*/); if (res != true) { return res; } //qDebug() << "new project created ---"; if (d->prj) { res = openProjectInExternalKexiInstance( prj->data()->connectionData()->databaseName(), prj->data()->connectionData(), prj->data()->databaseName()); Kexi::recentProjects()->addProjectData(*prj->data()); if (d->tabbedToolBar) { d->tabbedToolBar->hideMainMenu(); } return res; } if (d->tabbedToolBar) { d->tabbedToolBar->hideMainMenu(); } d->prj = prj.take(); setupProjectNavigator(); d->prj->data()->setLastOpened(QDateTime::currentDateTime()); Kexi::recentProjects()->addProjectData(*d->prj->data()); invalidateActions(); updateAppCaption(); return true; } void KexiMainWindow::slotProjectOpen() { if (!d->tabbedToolBar) return; d->tabbedToolBar->showMainMenu("project_open"); KexiOpenProjectAssistant* assistant = new KexiOpenProjectAssistant; connect(assistant, SIGNAL(openProject(KexiProjectData)), this, SLOT(openProject(KexiProjectData))); connect(assistant, SIGNAL(openProject(QString)), this, SLOT(openProject(QString))); d->tabbedToolBar->setMainMenuContent(assistant); } tristate KexiMainWindow::openProject(const QString& aFileName) { return openProject(aFileName, QString(), QString()); } tristate KexiMainWindow::openProject(const QString& aFileName, const QString& fileNameForConnectionData, const QString& dbName) { if (d->prj) return openProjectInExternalKexiInstance(aFileName, fileNameForConnectionData, dbName); KDbConnectionData *cdata = 0; if (!fileNameForConnectionData.isEmpty()) { cdata = Kexi::connset().connectionDataForFileName(fileNameForConnectionData); if (!cdata) { qWarning() << "cdata?"; return false; } } return openProject(aFileName, cdata, dbName); } tristate KexiMainWindow::openProject(const QString& aFileName, KDbConnectionData *cdata, const QString& dbName, const KexiProjectData::AutoOpenObjects& autoopenObjects) { if (d->prj) { return openProjectInExternalKexiInstance(aFileName, cdata, dbName); } KexiProjectData* projectData = 0; const KexiStartupHandler *h = KexiStartupHandler::global(); bool readOnly = h->isSet(h->options().readOnly); bool deleteAfterOpen = false; if (cdata) { //server-based project if (dbName.isEmpty()) {//no database name given, ask user bool cancel; projectData = KexiStartupHandler::global()->selectProject(cdata, &cancel, this); if (cancel) return cancelled; } else { //! @todo caption arg? projectData = new KexiProjectData(*cdata, dbName); deleteAfterOpen = true; } } else { if (aFileName.isEmpty()) { qWarning() << "aFileName.isEmpty()"; return false; } //file-based project qDebug() << "Project File: " << aFileName; KDbConnectionData fileConnData; fileConnData.setDatabaseName(aFileName); QString detectedDriverId; int detectOptions = 0; if (readOnly) { detectOptions |= KexiStartupHandler::OpenReadOnly; } KexiStartupData::Import importActionData; bool forceReadOnly; const tristate res = KexiStartupHandler::detectActionForFile( &importActionData, &detectedDriverId, fileConnData.driverId(), aFileName, this, detectOptions, &forceReadOnly); if (forceReadOnly) { readOnly = true; } if (true != res) return res; if (importActionData) { //importing requested return showProjectMigrationWizard(importActionData.mimeType, importActionData.fileName); } fileConnData.setDriverId(detectedDriverId); if (fileConnData.driverId().isEmpty()) return false; //opening requested projectData = new KexiProjectData(fileConnData); deleteAfterOpen = true; } if (!projectData) return false; projectData->setReadOnly(readOnly); projectData->autoopenObjects = autoopenObjects; const tristate res = openProject(*projectData); if (deleteAfterOpen) //projectData object has been copied delete projectData; return res; } tristate KexiMainWindow::openProjectInExternalKexiInstance(const QString& aFileName, KDbConnectionData *cdata, const QString& dbName) { QString fileNameForConnectionData; if (aFileName.isEmpty()) { //try .kexic file if (cdata) fileNameForConnectionData = Kexi::connset().fileNameForConnectionData(*cdata); } return openProjectInExternalKexiInstance(aFileName, fileNameForConnectionData, dbName); } tristate KexiMainWindow::openProjectInExternalKexiInstance(const QString& aFileName, const QString& fileNameForConnectionData, const QString& dbName) { QString fileName(aFileName); QStringList args; // open a file-based project or a server connection provided as a .kexic file // (we have no other simple way to provide the startup data to a new process) if (fileName.isEmpty()) { //try .kexic file if (!fileNameForConnectionData.isEmpty()) args << "--skip-conn-dialog"; //user does not expect conn. dialog to be shown here if (dbName.isEmpty()) { //use 'kexi --skip-conn-dialog file.kexic' fileName = fileNameForConnectionData; } else { //use 'kexi --skip-conn-dialog --connection file.kexic dbName' if (fileNameForConnectionData.isEmpty()) { qWarning() << "fileNameForConnectionData?"; return false; } args << "--connection" << fileNameForConnectionData; fileName = dbName; } } if (fileName.isEmpty()) { qWarning() << "fileName?"; return false; } //! @todo use KRun //! @todo untested //Can arguments be supplied to KRun like is used here? AP args << fileName; const bool ok = QProcess::startDetached( qApp->applicationFilePath(), args, QFileInfo(fileName).absoluteDir().absolutePath()); if (!ok) { d->showStartProcessMsg(args); } if (d->tabbedToolBar) { d->tabbedToolBar->hideMainMenu(); } return ok; } void KexiMainWindow::slotProjectWelcome() { if (!d->tabbedToolBar) return; d->tabbedToolBar->showMainMenu("project_welcome"); KexiWelcomeAssistant* assistant = new KexiWelcomeAssistant( Kexi::recentProjects(), this); connect(assistant, SIGNAL(openProject(KexiProjectData,QString,bool*)), this, SLOT(openProject(KexiProjectData,QString,bool*))); d->tabbedToolBar->setMainMenuContent(assistant); } void KexiMainWindow::slotProjectSave() { if (!currentWindow() || currentWindow()->currentViewMode() == Kexi::DataViewMode) { return; } saveObject(currentWindow()); updateAppCaption(); invalidateActions(); } void KexiMainWindow::slotProjectSaveAs() { if (!currentWindow() || currentWindow()->currentViewMode() == Kexi::DataViewMode) { return; } saveObject(currentWindow(), QString(), SaveObjectAs); updateAppCaption(); invalidateActions(); } void KexiMainWindow::slotProjectPrint() { #ifdef KEXI_QUICK_PRINTING_SUPPORT if (currentWindow() && currentWindow()->partItem()) printItem(currentWindow()->partItem()); #endif } void KexiMainWindow::slotProjectPrintPreview() { #ifdef KEXI_QUICK_PRINTING_SUPPORT if (currentWindow() && currentWindow()->partItem()) printPreviewForItem(currentWindow()->partItem()); #endif } void KexiMainWindow::slotProjectPageSetup() { #ifdef KEXI_QUICK_PRINTING_SUPPORT if (currentWindow() && currentWindow()->partItem()) showPageSetupForItem(currentWindow()->partItem()); #endif } void KexiMainWindow::slotProjectExportDataTable() { if (currentWindow() && currentWindow()->partItem()) exportItemAsDataTable(currentWindow()->partItem()); } void KexiMainWindow::slotProjectProperties() { if (!d->tabbedToolBar) return; d->tabbedToolBar->showMainMenu("project_properties"); // dummy QLabel *dummy = KEXI_UNFINISHED_LABEL(actionCollection()->action("project_properties")->text()); d->tabbedToolBar->setMainMenuContent(dummy); //! @todo load the implementation not the ui :) // ProjectSettingsUI u(this); // u.exec(); } void KexiMainWindow::slotProjectImportExportOrSend() { if (!d->tabbedToolBar) return; d->tabbedToolBar->showMainMenu("project_import_export_send"); KexiImportExportAssistant* assistant = new KexiImportExportAssistant( d->action_project_import_export_send, d->action_tools_import_project); connect(assistant, SIGNAL(importProject()), this, SLOT(slotToolsImportProject())); d->tabbedToolBar->setMainMenuContent(assistant); } void KexiMainWindow::slotProjectClose() { closeProject(); } void KexiMainWindow::slotProjectRelations() { if (!d->prj) return; KexiWindow *w = KexiInternalPart::createKexiWindowInstance("org.kexi-project.relations", this); activateWindow(*w); } void KexiMainWindow::slotImportFile() { KEXI_UNFINISHED("Import: " + xi18n("From File...")); } void KexiMainWindow::slotImportServer() { KEXI_UNFINISHED("Import: " + xi18n("From Server...")); } void KexiMainWindow::slotProjectQuit() { if (~ closeProject()) return; close(); } void KexiMainWindow::slotActivateNavigator() { if (!d->navigator) { return; } d->navigator->setFocus(); } void KexiMainWindow::slotActivateMainArea() { if (currentWindow()) currentWindow()->setFocus(); } void KexiMainWindow::slotActivatePropertyEditor() { if (!d->propEditor) { return; } if (d->propEditorTabWidget->currentWidget()) d->propEditorTabWidget->currentWidget()->setFocus(); } void KexiMainWindow::slotShowNavigator() { if (d->navDockWidget) d->navDockWidget->setVisible(!d->navDockWidget->isVisible()); } void KexiMainWindow::slotShowPropertyEditor() { if (d->propEditorDockWidget) d->propEditorDockWidget->setVisible(!d->propEditorDockWidget->isVisible()); } tristate KexiMainWindow::switchToViewMode(KexiWindow& window, Kexi::ViewMode viewMode) { const Kexi::ViewMode prevViewMode = currentWindow()->currentViewMode(); if (prevViewMode == viewMode) return true; if (!activateWindow(window)) return false; if (!currentWindow()) { return false; } if (&window != currentWindow()) return false; if (!currentWindow()->supportsViewMode(viewMode)) { showErrorMessage(xi18nc("@info", "Selected view is not supported for %1 object.", currentWindow()->partItem()->name()), xi18nc("@info", "Selected view (%1) is not supported by this object type (%2).", Kexi::nameForViewMode(viewMode), currentWindow()->part()->info()->name())); return false; } updateCustomPropertyPanelTabs(currentWindow()->part(), prevViewMode, currentWindow()->part(), viewMode); tristate res = currentWindow()->switchToViewMode(viewMode); if (!res) { updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert showErrorMessage(xi18n("Switching to other view failed (%1).", Kexi::nameForViewMode(viewMode)), currentWindow()); return false; } if (~res) { updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert return cancelled; } activateWindow(window); invalidateSharedActions(); invalidateProjectWideActions(); d->updateFindDialogContents(); d->updatePropEditorVisibility(viewMode); QString origTabToActivate; if (viewMode == Kexi::DesignViewMode) { // Save the orig tab: we want to back to design tab // when user moved to data view and then immediately to design view. origTabToActivate = d->tabsToActivateOnShow.value(currentWindow()->partItem()->identifier()); } restoreDesignTabIfNeeded(currentWindow()->partItem()->pluginId(), viewMode, currentWindow()->partItem()->identifier()); if (viewMode == Kexi::DesignViewMode) { activateDesignTab(currentWindow()->partItem()->pluginId()); // Restore the saved tab to the orig one. restoreDesignTabIfNeeded() saved tools tab probably. d->tabsToActivateOnShow.insert(currentWindow()->partItem()->identifier(), origTabToActivate); } return true; } void KexiMainWindow::slotViewDataMode() { if (currentWindow()) switchToViewMode(*currentWindow(), Kexi::DataViewMode); } void KexiMainWindow::slotViewDesignMode() { if (currentWindow()) switchToViewMode(*currentWindow(), Kexi::DesignViewMode); } void KexiMainWindow::slotViewTextMode() { if (currentWindow()) switchToViewMode(*currentWindow(), Kexi::TextViewMode); } //! Used to control if we're not Saving-As object under the original name class SaveAsObjectNameValidator : public KexiNameDialogValidator { public: SaveAsObjectNameValidator(const QString &originalObjectName) : m_originalObjectName(originalObjectName) { } - virtual bool validate(KexiNameDialog *dialog) const { + virtual bool validate(KexiNameDialog *dialog) const override { if (dialog->widget()->nameText() == m_originalObjectName) { KMessageBox::information(dialog, xi18nc("Could not save object under the original name.", "Could not save under the original name.")); return false; } return true; } private: QString m_originalObjectName; }; tristate KexiMainWindow::getNewObjectInfo( KexiPart::Item *partItem, const QString &originalName, KexiPart::Part *part, bool allowOverwriting, bool *overwriteNeeded, const QString& messageWhenAskingForName) { //data was never saved in the past -we need to create a new object at the backend KexiPart::Info *info = part->info(); if (!d->nameDialog) { d->nameDialog = new KexiNameDialog( messageWhenAskingForName, this); //check if that name is allowed d->nameDialog->widget()->addNameSubvalidator( new KDbObjectNameValidator(project()->dbConnection()->driver())); d->nameDialog->buttonBox()->button(QDialogButtonBox::Ok)->setText(xi18nc("@action:button Save object", "Save")); } else { d->nameDialog->widget()->setMessageText(messageWhenAskingForName); } d->nameDialog->widget()->setCaptionText(partItem->caption()); d->nameDialog->widget()->setNameText(partItem->name()); d->nameDialog->setWindowTitle(xi18nc("@title:window", "Save Object As")); d->nameDialog->setDialogIcon(info->iconName()); d->nameDialog->setAllowOverwriting(allowOverwriting); if (!originalName.isEmpty()) { d->nameDialog->setValidator(new SaveAsObjectNameValidator(originalName)); } if (d->nameDialog->execAndCheckIfObjectExists(*project(), *part, overwriteNeeded) != QDialog::Accepted) { return cancelled; } // close window of object that will be overwritten if (*overwriteNeeded) { KexiPart::Item* overwrittenItem = project()->item(info, d->nameDialog->widget()->nameText()); if (overwrittenItem) { KexiWindow * openedWindow = d->openedWindowFor(overwrittenItem->identifier()); if (openedWindow) { const tristate res = closeWindow(openedWindow); if (res != true) { return res; } } } } //update name and caption partItem->setName(d->nameDialog->widget()->nameText()); partItem->setCaption(d->nameDialog->widget()->captionText()); return true; } //! Used to delete part item on exit from block class PartItemDeleter : public QScopedPointer { public: explicit PartItemDeleter(KexiProject *prj) : m_prj(prj) {} ~PartItemDeleter() { if (!isNull()) { m_prj->deleteUnstoredItem(take()); } } private: KexiProject *m_prj; }; static void showSavingObjectFailedErrorMessage(KexiMainWindow *wnd, KexiPart::Item *item) { wnd->showErrorMessage( xi18nc("@info Saving object failed", "Saving %1 object failed.", item->name()), wnd->currentWindow()); } tristate KexiMainWindow::saveObject(KexiWindow *window, const QString& messageWhenAskingForName, SaveObjectOptions options) { tristate res; bool saveAs = options & SaveObjectAs; if (!saveAs && !window->neverSaved()) { //data was saved in the past -just save again res = window->storeData(options & DoNotAsk); if (!res) { showSavingObjectFailedErrorMessage(this, window->partItem()); } return res; } if (saveAs && window->neverSaved()) { //if never saved, saveAs == save saveAs = false; } const int oldItemID = window->partItem()->identifier(); KexiPart::Item *partItem; KexiView::StoreNewDataOptions storeNewDataOptions; PartItemDeleter itemDeleter(d->prj); if (saveAs) { partItem = d->prj->createPartItem(window->part()); if (!partItem) { //! @todo error return false; } itemDeleter.reset(partItem); } else { partItem = window->partItem(); } bool overwriteNeeded; res = getNewObjectInfo(partItem, saveAs ? window->partItem()->name() : QString(), window->part(), true /*allowOverwriting*/, &overwriteNeeded, messageWhenAskingForName); if (res != true) return res; if (overwriteNeeded) { storeNewDataOptions |= KexiView::OverwriteExistingData; } if (saveAs) { res = window->storeDataAs(partItem, storeNewDataOptions); } else { res = window->storeNewData(storeNewDataOptions); } if (~res) return cancelled; if (!res) { showSavingObjectFailedErrorMessage(this, partItem); return false; } d->updateWindowId(window, oldItemID); invalidateProjectWideActions(); itemDeleter.take(); return true; } tristate KexiMainWindow::closeWindow(KexiWindow *window) { return closeWindow(window ? window : currentWindow(), true); } tristate KexiMainWindow::closeCurrentWindow() { return closeWindow(0); } tristate KexiMainWindow::closeWindowForTab(int tabIndex) { KexiWindow* window = windowForTab(tabIndex); if (!window) return false; return closeWindow(window); } tristate KexiMainWindow::closeWindow(KexiWindow *window, bool layoutTaskBar, bool doNotSaveChanges) { //! @todo KEXI3 KexiMainWindow::closeWindow() ///@note Q_UNUSED layoutTaskBar Q_UNUSED(layoutTaskBar); if (!window) return true; if (d->insideCloseWindow) return true; const int previousItemId = window->partItem()->identifier(); #ifndef KEXI_NO_PENDING_DIALOGS d->addItemToPendingWindows(window->partItem(), Private::WindowClosingJob); #endif d->insideCloseWindow = true; if (window == currentWindow() && !window->isAttached()) { if (d->propEditor) { // ah, closing detached window - better switch off property buffer right now... d->propertySet = 0; d->propEditor->editor()->changeSet(0); } } bool remove_on_closing = window->partItem() ? window->partItem()->neverSaved() : false; if (window->isDirty() && !d->forceWindowClosing && !doNotSaveChanges) { //more accurate tool tips and what's this KGuiItem saveChanges(KStandardGuiItem::save()); saveChanges.setToolTip(xi18n("Save changes")); saveChanges.setWhatsThis( xi18nc("@info", "Saves all recent changes made in %1 object.", window->partItem()->name())); KGuiItem discardChanges(KStandardGuiItem::discard()); discardChanges.setWhatsThis( xi18nc("@info", "Discards all recent changes made in %1 object.", window->partItem()->name())); //dialog's data is dirty: //--adidional message, e.g. table designer will return // "Note: This table is already filled with data which will be removed." // if the window is in design view mode. const KLocalizedString additionalMessage( window->part()->i18nMessage(":additional message before saving design", window)); QString additionalMessageString; if (!additionalMessage.isEmpty()) additionalMessageString = additionalMessage.toString(); if (additionalMessageString.startsWith(':')) additionalMessageString.clear(); if (!additionalMessageString.isEmpty()) additionalMessageString = "

    " + additionalMessageString + "

    "; const KMessageBox::ButtonCode questionRes = KMessageBox::warningYesNoCancel(this, "

    " + window->part()->i18nMessage("Design of object %1 has been modified.", window) .subs(window->partItem()->name()).toString() + "

    " + xi18n("Do you want to save changes?") + "

    " + additionalMessageString /*may be empty*/, QString(), saveChanges, discardChanges); if (questionRes == KMessageBox::Cancel) { #ifndef KEXI_NO_PENDING_DIALOGS d->removePendingWindow(window->id()); #endif d->insideCloseWindow = false; d->windowsToClose.clear(); //give up with 'close all' return cancelled; } if (questionRes == KMessageBox::Yes) { //save it tristate res = saveObject(window, QString(), DoNotAsk); if (!res || ~res) { //! @todo show error info; (retry/ignore/cancel) #ifndef KEXI_NO_PENDING_DIALOGS d->removePendingWindow(window->id()); #endif d->insideCloseWindow = false; d->windowsToClose.clear(); //give up with 'close all' return res; } remove_on_closing = false; } } const int window_id = window->id(); //remember now, because removeObject() can destruct partitem object if (remove_on_closing) { //we won't save this object, and it was never saved -remove it if (!removeObject(window->partItem(), true)) { #ifndef KEXI_NO_PENDING_DIALOGS d->removePendingWindow(window->id()); #endif //msg? //! @todo ask if we'd continue and return true/false d->insideCloseWindow = false; d->windowsToClose.clear(); //give up with 'close all' return false; } } else { //not dirty now if (d->navigator) { d->navigator->updateItemName(*window->partItem(), false); } } hideDesignTab(previousItemId, QString()); d->removeWindow(window_id); d->setWindowContainerExistsFor(window->partItem()->identifier(), false); QWidget *windowContainer = window->parentWidget(); d->mainWidget->tabWidget()->removeTab( d->mainWidget->tabWidget()->indexOf(windowContainer)); #ifdef KEXI_QUICK_PRINTING_SUPPORT //also remove from 'print setup dialogs' cache, if needed int printedObjectID = 0; if (d->pageSetupWindowItemID2dataItemID_map.contains(window_id)) printedObjectID = d->pageSetupWindowItemID2dataItemID_map[ window_id ]; d->pageSetupWindows.remove(printedObjectID); #endif delete windowContainer; //focus navigator if nothing else available if (d->openedWindowsCount() == 0) { if (d->navigator) { d->navigator->setFocus(); } d->updatePropEditorVisibility(Kexi::NoViewMode); } invalidateActions(); d->insideCloseWindow = false; if (!d->windowsToClose.isEmpty()) {//continue 'close all' KexiWindow* w = d->windowsToClose.takeAt(0); closeWindow(w, true); } #ifndef KEXI_NO_PENDING_DIALOGS d->removePendingWindow(window_id); //perform pending global action that was suspended: if (!d->pendingWindowsExist()) { d->executeActionWhenPendingJobsAreFinished(); } #endif d->mainWidget->slotCurrentTabIndexChanged(d->mainWidget->tabWidget()->currentIndex()); showDesignTabIfNeeded(0); if (currentWindow()) { restoreDesignTabIfNeeded(currentWindow()->partItem()->pluginId(), currentWindow()->currentViewMode(), 0); } d->tabsToActivateOnShow.remove(previousItemId); return true; } QWidget* KexiMainWindow::findWindow(QWidget *w) { while (w && !acceptsSharedActions(w)) { if (w == d->propEditorDockWidget) return currentWindow(); w = w->parentWidget(); } return w; } KexiWindow* KexiMainWindow::openedWindowFor(int identifier) { return d->openedWindowFor(identifier); } KexiWindow* KexiMainWindow::openedWindowFor(const KexiPart::Item* item) { return item ? openedWindowFor(item->identifier()) : 0; } KDbQuerySchema* KexiMainWindow::unsavedQuery(int queryId) { KexiWindow * queryWindow = openedWindowFor(queryId); if (!queryWindow || !queryWindow->isDirty()) { return 0; } return queryWindow->part()->currentQuery(queryWindow->viewForMode(Kexi::DataViewMode)); } QList KexiMainWindow::currentParametersForQuery(int queryId) const { KexiWindow *queryWindow = d->openedWindowFor(queryId); if (!queryWindow) { return QList(); } KexiView *view = queryWindow->viewForMode(Kexi::DataViewMode); if (!view) { return QList(); } return view->currentParameters(); } bool KexiMainWindow::acceptsSharedActions(QObject *w) { return w->inherits("KexiWindow") || w->inherits("KexiView"); } bool KexiMainWindow::openingAllowed(KexiPart::Item* item, Kexi::ViewMode viewMode, QString* errorMessage) { //qDebug() << viewMode; //! @todo this can be more complex once we deliver ACLs... if (!d->userMode) return true; KexiPart::Part * part = Kexi::partManager().partForPluginId(item->pluginId()); if (!part) { if (errorMessage) { *errorMessage = Kexi::partManager().result().message(); } } //qDebug() << part << item->pluginId(); //if (part) // qDebug() << item->pluginId() << part->info()->supportedUserViewModes(); return part && (part->info()->supportedUserViewModes() & viewMode); } KexiWindow * KexiMainWindow::openObject(const QString& pluginId, const QString& name, Kexi::ViewMode viewMode, bool *openingCancelled, QMap* staticObjectArgs) { KexiPart::Item *item = d->prj->itemForPluginId(pluginId, name); if (!item) return 0; return openObject(item, viewMode, openingCancelled, staticObjectArgs); } KexiWindow * KexiMainWindow::openObject(KexiPart::Item* item, Kexi::ViewMode viewMode, bool *openingCancelled, QMap* staticObjectArgs, QString* errorMessage) { Q_ASSERT(openingCancelled); if (!d->prj || !item) { return 0; } if (!openingAllowed(item, viewMode, errorMessage)) { if (errorMessage) *errorMessage = xi18nc( "opening is not allowed in \"data view/design view/text view\" mode", "opening is not allowed in \"%1\" mode", Kexi::nameForViewMode(viewMode)); *openingCancelled = true; return 0; } //qDebug() << d->prj << item; KexiWindow *prevWindow = currentWindow(); KexiUtils::WaitCursor wait; #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; KexiWindow *window = d->openedWindowFor(item, pendingType); if (pendingType != Private::NoJob) { *openingCancelled = true; return 0; } #else KexiWindow *window = openedWindowFor(item); #endif int previousItemId = currentWindow() ? currentWindow()->partItem()->identifier() : 0; *openingCancelled = false; bool alreadyOpened = false; KexiWindowContainer *windowContainer = 0; if (window) { if (viewMode != window->currentViewMode()) { if (true != switchToViewMode(*window, viewMode)) return 0; } else activateWindow(*window); alreadyOpened = true; } else { if (d->windowContainerExistsFor(item->identifier())) { // window not yet present but window container exists: return 0 and wait return 0; } KexiPart::Part *part = Kexi::partManager().partForPluginId(item->pluginId()); d->updatePropEditorVisibility(viewMode, part ? part->info() : 0); //update tabs before opening updateCustomPropertyPanelTabs(currentWindow() ? currentWindow()->part() : 0, currentWindow() ? currentWindow()->currentViewMode() : Kexi::NoViewMode, part, viewMode); // open new tab earlier windowContainer = new KexiWindowContainer(d->mainWidget->tabWidget()); d->setWindowContainerExistsFor(item->identifier(), true); const int tabIndex = d->mainWidget->tabWidget()->addTab( windowContainer, QIcon::fromTheme(part ? part->info()->iconName() : QString()), KexiWindow::windowTitleForItem(*item)); d->mainWidget->tabWidget()->setTabToolTip(tabIndex, KexiPart::fullCaptionForItem(item, part)); QString whatsThisText; if (part) { whatsThisText = xi18nc("@info", "Tab for %1 (%2).", item->captionOrName(), part->info()->name()); } else { whatsThisText = xi18nc("@info", "Tab for %1.", item->captionOrName()); } d->mainWidget->tabWidget()->setTabWhatsThis(tabIndex, whatsThisText); d->mainWidget->tabWidget()->setCurrentWidget(windowContainer); #ifndef KEXI_NO_PENDING_DIALOGS d->addItemToPendingWindows(item, Private::WindowOpeningJob); #endif window = d->prj->openObject(windowContainer, item, viewMode, staticObjectArgs); if (window) { windowContainer->setWindow(window); // update text and icon d->mainWidget->tabWidget()->setTabText( d->mainWidget->tabWidget()->indexOf(windowContainer), window->windowTitle()); d->mainWidget->tabWidget()->setTabIcon( d->mainWidget->tabWidget()->indexOf(windowContainer), window->windowIcon()); } } if (!window || !activateWindow(*window)) { #ifndef KEXI_NO_PENDING_DIALOGS d->removePendingWindow(item->identifier()); #endif d->setWindowContainerExistsFor(item->identifier(), false); d->mainWidget->tabWidget()->removeTab( d->mainWidget->tabWidget()->indexOf(windowContainer)); delete windowContainer; updateCustomPropertyPanelTabs(0, Kexi::NoViewMode); //revert //! @todo add error msg... return 0; } if (viewMode != window->currentViewMode()) invalidateSharedActions(); #ifndef KEXI_NO_PENDING_DIALOGS d->removePendingWindow(window->id()); //perform pending global action that was suspended: if (!d->pendingWindowsExist()) { d->executeActionWhenPendingJobsAreFinished(); } #endif if (window && !alreadyOpened) { // Call switchToViewMode() and propertySetSwitched() again here because // this is the time when then new window is the current one - previous call did nothing. switchToViewMode(*window, window->currentViewMode()); currentWindow()->selectedView()->propertySetSwitched(); } invalidateProjectWideActions(); restoreDesignTabIfNeeded(item->pluginId(), viewMode, previousItemId); activateDesignTabIfNeeded(item->pluginId(), viewMode); QString origTabToActivate; if (prevWindow) { // Save the orig tab for prevWindow that was stored in the restoreDesignTabIfNeeded() call above origTabToActivate = d->tabsToActivateOnShow.value(prevWindow->partItem()->identifier()); } activeWindowChanged(window, prevWindow); if (prevWindow) { // Restore the orig tab d->tabsToActivateOnShow.insert(prevWindow->partItem()->identifier(), origTabToActivate); } return window; } KexiWindow * KexiMainWindow::openObjectFromNavigator(KexiPart::Item* item, Kexi::ViewMode viewMode) { bool openingCancelled; return openObjectFromNavigator(item, viewMode, &openingCancelled); } KexiWindow * KexiMainWindow::openObjectFromNavigator(KexiPart::Item* item, Kexi::ViewMode viewMode, bool *openingCancelled) { Q_ASSERT(openingCancelled); if (!openingAllowed(item, viewMode)) { *openingCancelled = true; return 0; } if (!d->prj || !item) return 0; #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; KexiWindow *window = d->openedWindowFor(item, pendingType); if (pendingType != Private::NoJob) { *openingCancelled = true; return 0; } #else KexiWindow *window = openedWindowFor(item); #endif *openingCancelled = false; if (window) { if (activateWindow(*window)) { return window; } } //if DataViewMode is not supported, try Design, then Text mode (currently useful for script part) KexiPart::Part *part = Kexi::partManager().partForPluginId(item->pluginId()); if (!part) return 0; if (viewMode == Kexi::DataViewMode && !(part->info()->supportedViewModes() & Kexi::DataViewMode)) { if (part->info()->supportedViewModes() & Kexi::DesignViewMode) return openObjectFromNavigator(item, Kexi::DesignViewMode, openingCancelled); else if (part->info()->supportedViewModes() & Kexi::TextViewMode) return openObjectFromNavigator(item, Kexi::TextViewMode, openingCancelled); } //do the same as in openObject() return openObject(item, viewMode, openingCancelled); } tristate KexiMainWindow::closeObject(KexiPart::Item* item) { #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; KexiWindow *window = d->openedWindowFor(item, pendingType); if (pendingType == Private::WindowClosingJob) return true; else if (pendingType == Private::WindowOpeningJob) return cancelled; #else KexiWindow *window = openedWindowFor(item); #endif if (!window) return cancelled; return closeWindow(window); } bool KexiMainWindow::newObject(KexiPart::Info *info, bool* openingCancelled) { Q_ASSERT(openingCancelled); if (d->userMode) { *openingCancelled = true; return false; } *openingCancelled = false; if (!d->prj || !info) return false; KexiPart::Part *part = Kexi::partManager().part(info); if (!part) return false; KexiPart::Item *it = d->prj->createPartItem(info); if (!it) { //! @todo error return false; } if (!it->neverSaved()) { //only add stored objects to the browser d->navigator->model()->slotAddItem(it); } return openObject(it, Kexi::DesignViewMode, openingCancelled); } tristate KexiMainWindow::removeObject(KexiPart::Item *item, bool dontAsk) { if (d->userMode) return cancelled; if (!d->prj || !item) return false; KexiPart::Part *part = Kexi::partManager().partForPluginId(item->pluginId()); if (!part) return false; if (!dontAsk) { if (KMessageBox::No == KMessageBox::questionYesNo(this, xi18nc("@info Delete ?", "Do you want to permanently delete the following object?" "%1 %2" "If you click Delete, " "you will not be able to undo the deletion.", part->info()->name(), item->name()), xi18nc("@title:window Delete Object %1.", "Delete %1?", item->name()), KStandardGuiItem::del(), KStandardGuiItem::no(), QString(), KMessageBox::Notify | KMessageBox::Dangerous)) { return cancelled; } } tristate res = true; #ifdef KEXI_QUICK_PRINTING_SUPPORT //also close 'print setup' dialog for this item, if any KexiWindow * pageSetupWindow = d->pageSetupWindows[ item->identifier()]; const bool oldInsideCloseWindow = d->insideCloseWindow; { d->insideCloseWindow = false; if (pageSetupWindow) res = closeWindow(pageSetupWindow); } d->insideCloseWindow = oldInsideCloseWindow; if (!res || ~res) { return res; } #endif #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; KexiWindow *window = d->openedWindowFor(item, pendingType); if (pendingType != Private::NoJob) { return cancelled; } #else KexiWindow *window = openedWindowFor(item); #endif if (window) {//close existing window const bool tmp = d->forceWindowClosing; d->forceWindowClosing = true; res = closeWindow(window); d->forceWindowClosing = tmp; //restore if (!res || ~res) { return res; } } #ifdef KEXI_QUICK_PRINTING_SUPPORT //in case the dialog is a 'print setup' dialog, also update d->pageSetupWindows int dataItemID = d->pageSetupWindowItemID2dataItemID_map[item->identifier()]; d->pageSetupWindowItemID2dataItemID_map.remove(item->identifier()); d->pageSetupWindows.remove(dataItemID); #endif if (!d->prj->removeObject(item)) { //! @todo better msg showSorryMessage(xi18n("Could not delete object.")); return false; } return true; } void KexiMainWindow::renameObject(KexiPart::Item *item, const QString& _newName, bool *success) { Q_ASSERT(success); if (d->userMode) { *success = false; return; } QString newName = _newName.trimmed(); if (newName.isEmpty()) { showSorryMessage(xi18n("Could not set empty name for this object.")); *success = false; return; } KexiWindow *window = openedWindowFor(item); if (window) { QString msg = xi18nc("@info", "Before renaming object %1 it should be closed." "Do you want to close it?", item->name()); KGuiItem closeAndRenameItem(KStandardGuiItem::closeWindow()); closeAndRenameItem.setText(xi18n("Close Window and Rename")); const int r = KMessageBox::questionYesNo(this, msg, QString(), closeAndRenameItem, KStandardGuiItem::cancel()); if (r != KMessageBox::Yes) { *success = false; return; } const tristate closeResult = closeWindow(window); if (closeResult != true) { *success = false; return; } } setMessagesEnabled(false); //to avoid double messages const bool res = d->prj->renameObject(item, newName); setMessagesEnabled(true); if (!res) { showErrorMessage(xi18nc("@info", "Renaming object %1 failed.", newName), d->prj); *success = false; return; } *success = true; } void KexiMainWindow::setObjectCaption(KexiPart::Item *item, const QString& _newCaption, bool *success) { Q_ASSERT(success); if (d->userMode) { *success = false; return; } QString newCaption = _newCaption.trimmed(); setMessagesEnabled(false); //to avoid double messages const bool res = d->prj->setObjectCaption(item, newCaption); setMessagesEnabled(true); if (!res) { showErrorMessage(xi18nc("@info", "Setting caption for object %1 failed.", newCaption), d->prj); *success = false; return; } *success = true; } void KexiMainWindow::slotObjectRenamed(const KexiPart::Item &item, const QString& oldName) { Q_UNUSED(oldName); #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; KexiWindow *window = d->openedWindowFor(&item, pendingType); if (pendingType != Private::NoJob) return; #else KexiWindow *window = openedWindowFor(&item); #endif if (!window) return; //change item window->updateCaption(); if (static_cast(currentWindow()) == window)//optionally, update app. caption updateAppCaption(); } void KexiMainWindow::acceptPropertySetEditing() { if (d->propEditor) d->propEditor->editor()->acceptInput(); } void KexiMainWindow::propertySetSwitched(KexiWindow *window, bool force, bool preservePrevSelection, bool sortedProperties, const QByteArray& propertyToSelect) { KexiWindow* _currentWindow = currentWindow(); //qDebug() << "currentWindow(): " // << (_currentWindow ? _currentWindow->windowTitle() : QString("NULL")) // << " window: " << (window ? window->windowTitle() : QString("NULL")); if (_currentWindow && _currentWindow != window) { d->propertySet = 0; //we'll need to move to another prop. set return; } if (d->propEditor) { KPropertySet *newSet = _currentWindow ? _currentWindow->propertySet() : 0; if (!newSet || (force || static_cast(d->propertySet) != newSet)) { d->propertySet = newSet; if (preservePrevSelection || force) { KPropertyEditorView::SetOptions options; if (preservePrevSelection) { options |= KPropertyEditorView::SetOption::PreservePreviousSelection; } if (sortedProperties) { options |= KPropertyEditorView::SetOption::AlphabeticalOrder; } if (propertyToSelect.isEmpty()) { d->propEditor->editor()->changeSet(d->propertySet, options); } else { d->propEditor->editor()->changeSet(d->propertySet, propertyToSelect, options); } } } } } void KexiMainWindow::slotDirtyFlagChanged(KexiWindow* window) { KexiPart::Item *item = window->partItem(); //update text in navigator and app. caption if (!d->userMode) { d->navigator->updateItemName(*item, window->isDirty()); } invalidateActions(); updateAppCaption(); d->mainWidget->tabWidget()->setTabText( d->mainWidget->tabWidget()->indexOf(window->parentWidget()), window->windowTitle()); } void KexiMainWindow::slotTipOfTheDay() { //! @todo } void KexiMainWindow::slotReportBug() { KexiBugReportDialog bugReport(this); bugReport.exec(); } bool KexiMainWindow::userMode() const { return d->userMode; } void KexiMainWindow::setupUserActions() { } void KexiMainWindow::slotToolsImportProject() { if (d->tabbedToolBar) d->tabbedToolBar->hideMainMenu(); showProjectMigrationWizard(QString(), QString()); } void KexiMainWindow::slotToolsImportTables() { if (project()) { QMap args; QDialog *dlg = KexiInternalPart::createModalDialogInstance("org.kexi-project.migration", "importtable", this, 0, &args); if (!dlg) return; //error msg has been shown by KexiInternalPart const int result = dlg->exec(); delete dlg; if (result != QDialog::Accepted) return; QString destinationTableName(args["destinationTableName"]); if (!destinationTableName.isEmpty()) { QString pluginId = "org.kexi-project.table"; bool openingCancelled; KexiMainWindow::openObject(pluginId, destinationTableName, Kexi::DataViewMode, &openingCancelled); } } } void KexiMainWindow::slotToolsCompactDatabase() { KexiProjectData *data = 0; KDbDriver *drv = 0; const bool projectWasOpened = d->prj; if (!d->prj) { //! @todo Support compacting of non-opened projects return; #if 0 KexiStartupDialog dlg( KexiStartupDialog::OpenExisting, 0, Kexi::connset(), this); if (dlg.exec() != QDialog::Accepted) return; if (dlg.selectedFile().isEmpty()) { //! @todo add support for server based if needed? return; } KDbConnectionData cdata; cdata.setDatabaseName(dlg.selectedFile()); //detect driver name for the selected file KexiStartupData::Import detectedImportAction; QString detectedDriverId; tristate res = KexiStartupHandler::detectActionForFile( &detectedImportAction, &detectedDriverId, QString() /*suggestedDriverId*/, cdata.databaseName(), 0, KexiStartupHandler::SkipMessages | KexiStartupHandler::ThisIsAProjectFile | KexiStartupHandler::DontConvert); if (true == res && !detectedImportAction) { cdata.setDriverId(detectedDriverId); drv = Kexi::driverManager().driver(cdata.driverId()); } if (!drv || !(drv->features() & KDbDriver::CompactingDatabaseSupported)) { KMessageBox::information(this, xi18n("Compacting database file %1 is not supported.", QDir::toNativeSeparators(cdata.databaseName()))); return; } data = new KexiProjectData(cdata); #endif } else { //sanity if (!(d->prj && d->prj->dbConnection() && (d->prj->dbConnection()->driver()->features() & KDbDriver::CompactingDatabaseSupported))) return; KGuiItem yesItem(KStandardGuiItem::cont()); yesItem.setText(xi18nc("@action:button Compact database", "Compact")); if (KMessageBox::Yes != KMessageBox::questionYesNo(this, xi18n("The current project has to be closed before compacting the database. " "It will be open again after compacting.\n\nDo you want to continue?"), QString(), yesItem, KStandardGuiItem::cancel())) { return; } data = new KexiProjectData(*d->prj->data()); // a copy drv = d->prj->dbConnection()->driver(); const tristate res = closeProject(); if (~res || !res) { delete data; return; } } if (!drv->adminTools().vacuum(*data->connectionData(), data->databaseName())) { showErrorMessage(QString(), &drv->adminTools()); } if (projectWasOpened) openProject(*data); delete data; } tristate KexiMainWindow::showProjectMigrationWizard(const QString& mimeType, const QString& databaseName) { return d->showProjectMigrationWizard(mimeType, databaseName, 0); } tristate KexiMainWindow::showProjectMigrationWizard( const QString& mimeType, const QString& databaseName, const KDbConnectionData &cdata) { return d->showProjectMigrationWizard(mimeType, databaseName, &cdata); } tristate KexiMainWindow::executeItem(KexiPart::Item* item) { KexiPart::Info *info = item ? Kexi::partManager().infoForPluginId(item->pluginId()) : 0; if ((! info) || (! info->isExecuteSupported())) return false; KexiPart::Part *part = Kexi::partManager().part(info); if (!part) return false; return part->execute(item); } void KexiMainWindow::slotProjectImportDataTable() { //! @todo allow data appending (it is not possible now) if (d->userMode) return; QMap args; args.insert("sourceType", "file"); QDialog *dlg = KexiInternalPart::createModalDialogInstance( "org.kexi-project.importexport.csv", "KexiCSVImportDialog", this, 0, &args); if (!dlg) return; //error msg has been shown by KexiInternalPart dlg->exec(); delete dlg; } tristate KexiMainWindow::executeCustomActionForObject(KexiPart::Item* item, const QString& actionName) { if (actionName == "exportToCSV") return exportItemAsDataTable(item); else if (actionName == "copyToClipboardAsCSV") return copyItemToClipboardAsDataTable(item); qWarning() << "no such action:" << actionName; return false; } tristate KexiMainWindow::exportItemAsDataTable(KexiPart::Item* item) { if (!item) return false; QMap args; if (!checkForDirtyFlagOnExport(item, &args)) { return false; } //! @todo: accept record changes... args.insert("destinationType", "file"); args.insert("itemId", QString::number(item->identifier())); QDialog *dlg = KexiInternalPart::createModalDialogInstance( "org.kexi-project.importexport.csv", "KexiCSVExportWizard", this, 0, &args); if (!dlg) return false; //error msg has been shown by KexiInternalPart int result = dlg->exec(); delete dlg; return result == QDialog::Rejected ? tristate(cancelled) : tristate(true); } bool KexiMainWindow::checkForDirtyFlagOnExport(KexiPart::Item *item, QMap *args) { //! @todo: handle tables if (item->pluginId() != "org.kexi-project.query") { return true; } KexiWindow * itemWindow = openedWindowFor(item); if (itemWindow && itemWindow->isDirty()) { tristate result; if (item->neverSaved()) { result = true; } else { int prevWindowId = 0; if (!itemWindow->isVisible()) { prevWindowId = currentWindow()->id(); activateWindow(itemWindow->id()); } result = askOnExportingChangedQuery(item); if (prevWindowId != 0) { activateWindow(prevWindowId); } } if (~result) { return false; } else if (true == result) { args->insert("useTempQuery","1"); } } return true; } tristate KexiMainWindow::askOnExportingChangedQuery(KexiPart::Item *item) const { const KMessageBox::ButtonCode result = KMessageBox::warningYesNoCancel(const_cast(this), xi18nc("@info", "Design of query %1 that you want to export data" " from is changed and has not yet been saved. Do you want to use data" " from the changed query for exporting or from its original (saved)" " version?", item->captionOrName()), QString(), KGuiItem(xi18nc("@action:button Export query data", "Use the Changed Query")), KGuiItem(xi18nc("@action:button Export query data", "Use the Original Query")), KStandardGuiItem::cancel(), QString(), KMessageBox::Notify | KMessageBox::Dangerous); if (result == KMessageBox::Yes) { return true; } else if (result == KMessageBox::No) { return false; } return cancelled; } bool KexiMainWindow::printItem(KexiPart::Item* item, const QString& titleText) { //! @todo printItem(item, KexiSimplePrintingSettings::load(), titleText); Q_UNUSED(item) Q_UNUSED(titleText) return false; } tristate KexiMainWindow::printItem(KexiPart::Item* item) { return printItem(item, QString()); } bool KexiMainWindow::printPreviewForItem(KexiPart::Item* item, const QString& titleText, bool reload) { //! @todo printPreviewForItem(item, KexiSimplePrintingSettings::load(), titleText, reload); Q_UNUSED(item) Q_UNUSED(titleText) Q_UNUSED(reload) return false; } tristate KexiMainWindow::printPreviewForItem(KexiPart::Item* item) { return printPreviewForItem(item, QString(), //! @todo store cached record data? true/*reload*/); } tristate KexiMainWindow::showPageSetupForItem(KexiPart::Item* item) { Q_UNUSED(item) //! @todo check if changes to this object's design are saved, if not: ask for saving //! @todo accept record changes... //! @todo printActionForItem(item, PageSetupForItem); return false; } //! @todo reenable printItem() when ported #if 0 bool KexiMainWindow::printItem(KexiPart::Item* item, const KexiSimplePrintingSettings& settings, const QString& titleText) { //! @todo: check if changes to this object's design are saved, if not: ask for saving //! @todo: accept record changes... KexiSimplePrintingCommand cmd(this, item->identifier()); //modal return cmd.print(settings, titleText); } bool KexiMainWindow::printPreviewForItem(KexiPart::Item* item, const KexiSimplePrintingSettings& settings, const QString& titleText, bool reload) { //! @todo: check if changes to this object's design are saved, if not: ask for saving //! @todo: accept record changes... KexiSimplePrintingCommand* cmd = d->openedCustomObjectsForItem( item, "KexiSimplePrintingCommand"); if (!cmd) { d->addOpenedCustomObjectForItem( item, cmd = new KexiSimplePrintingCommand(this, item->identifier()), "KexiSimplePrintingCommand" ); } return cmd->showPrintPreview(settings, titleText, reload); } tristate KexiMainWindow::printActionForItem(KexiPart::Item* item, PrintActionType action) { if (!item) return false; KexiPart::Info *info = Kexi::partManager().infoForPluginId(item->pluginId()); if (!info->isPrintingSupported()) return false; KexiWindow *printingWindow = d->pageSetupWindows[ item->identifier()]; if (printingWindow) { if (!activateWindow(*printingWindow)) return false; if (action == PreviewItem || action == PrintItem) { QTimer::singleShot(0, printingWindow->selectedView(), (action == PreviewItem) ? SLOT(printPreview()) : SLOT(print())); } return true; } #ifndef KEXI_NO_PENDING_DIALOGS Private::PendingJobType pendingType; KexiWindow *window = d->openedWindowFor(item, pendingType); if (pendingType != Private::NoJob) return cancelled; #else KexiWindow *window = openedWindowFor(item); #endif if (window) { // accept record changes QWidget *prevFocusWidget = focusWidget(); window->setFocus(); d->action_data_save_row->activate(QAction::Trigger); if (prevFocusWidget) prevFocusWidget->setFocus(); // opened: check if changes made to this dialog are saved, if not: ask for saving if (window->neverSaved()) //sanity check return false; if (window->isDirty()) { KGuiItem saveChanges(KStandardGuiItem::save()); saveChanges.setToolTip(futureI18n("Save changes")); saveChanges.setWhatsThis( futureI18n("Pressing this button will save all recent changes made in \"%1\" object.", item->name())); KGuiItem doNotSave(KStandardGuiItem::no()); doNotSave.setWhatsThis( futureI18n("Pressing this button will ignore all unsaved changes made in \"%1\" object.", window->partItem()->name())); QString question; if (action == PrintItem) question = futureI18n("Do you want to save changes before printing?"); else if (action == PreviewItem) question = futureI18n("Do you want to save changes before making print preview?"); else if (action == PageSetupForItem) question = futureI18n("Do you want to save changes before showing page setup?"); else return false; const KMessageBox::ButtonCode questionRes = KMessageBox::warningYesNoCancel(this, "

    " + window->part()->i18nMessage("Design of object %1 has been modified.", window) .subs(item->name()) + "

    " + question + "

    ", QString(), saveChanges, doNotSave); if (KMessageBox::Cancel == questionRes) return cancelled; if (KMessageBox::Yes == questionRes) { tristate savingRes = saveObject(window, QString(), DoNotAsk); if (true != savingRes) return savingRes; } } } KexiPart::Part * printingPart = Kexi::partManager().partForClass("org.kexi-project.simpleprinting"); if (!printingPart) printingPart = new KexiSimplePrintingPart(); //hardcoded as there're no .desktop file KexiPart::Item* printingPartItem = d->prj->createPartItem( printingPart, item->name() //<-- this will look like "table1 : printing" on the window list ); QMap staticObjectArgs; staticObjectArgs["identifier"] = QString::number(item->identifier()); if (action == PrintItem) staticObjectArgs["action"] = "print"; else if (action == PreviewItem) staticObjectArgs["action"] = "printPreview"; else if (action == PageSetupForItem) staticObjectArgs["action"] = "pageSetup"; else return false; bool openingCancelled; printingWindow = openObject(printingPartItem, Kexi::DesignViewMode, &openingCancelled, &staticObjectArgs); if (openingCancelled) return cancelled; if (!printingWindow) //sanity return false; d->pageSetupWindows.insert(item->identifier(), printingWindow); d->pageSetupWindowItemID2dataItemID_map.insert( printingWindow->partItem()->identifier(), item->identifier()); return true; } #endif void KexiMainWindow::slotEditCopySpecialDataTable() { KexiPart::Item* item = d->navigator->selectedPartItem(); if (item) copyItemToClipboardAsDataTable(item); } tristate KexiMainWindow::copyItemToClipboardAsDataTable(KexiPart::Item* item) { if (!item) return false; QMap args; if (!checkForDirtyFlagOnExport(item, &args)) { return false; } args.insert("destinationType", "clipboard"); args.insert("itemId", QString::number(item->identifier())); QDialog *dlg = KexiInternalPart::createModalDialogInstance( "org.kexi-project.importexport.csv", "KexiCSVExportWizard", this, 0, &args); if (!dlg) return false; //error msg has been shown by KexiInternalPart const int result = dlg->exec(); delete dlg; return result == QDialog::Rejected ? tristate(cancelled) : tristate(true); } void KexiMainWindow::slotEditPasteSpecialDataTable() { //! @todo allow data appending (it is not possible now) if (d->userMode) return; QMap args; args.insert("sourceType", "clipboard"); QDialog *dlg = KexiInternalPart::createModalDialogInstance( "org.kexi-project.importexport.csv", "KexiCSVImportDialog", this, 0, &args); if (!dlg) return; //error msg has been shown by KexiInternalPart dlg->exec(); delete dlg; } void KexiMainWindow::slotEditFind() { KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface(); if (!iface) return; d->updateFindDialogContents(true/*create if does not exist*/); d->findDialog()->setReplaceMode(false); d->findDialog()->show(); d->findDialog()->activateWindow(); d->findDialog()->raise(); } void KexiMainWindow::slotEditFind(bool next) { KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface(); if (!iface) return; tristate res = iface->find( d->findDialog()->valueToFind(), d->findDialog()->options(), next); if (~res) return; d->findDialog()->updateMessage(true == res); //! @todo result } void KexiMainWindow::slotEditFindNext() { slotEditFind(true); } void KexiMainWindow::slotEditFindPrevious() { slotEditFind(false); } void KexiMainWindow::slotEditReplace() { KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface(); if (!iface) return; d->updateFindDialogContents(true/*create if does not exist*/); d->findDialog()->setReplaceMode(true); //! @todo slotEditReplace() d->findDialog()->show(); d->findDialog()->activateWindow(); } void KexiMainWindow::slotEditReplaceNext() { slotEditReplace(false); } void KexiMainWindow::slotEditReplace(bool all) { KexiSearchAndReplaceViewInterface* iface = d->currentViewSupportingSearchAndReplaceInterface(); if (!iface) return; //! @todo add question: "Do you want to replace every occurrence of \"%1\" with \"%2\"? //! You won't be able to undo this." + "Do not ask again". tristate res = iface->findNextAndReplace( d->findDialog()->valueToFind(), d->findDialog()->valueToReplaceWith(), d->findDialog()->options(), all); d->findDialog()->updateMessage(true == res); //! @todo result } void KexiMainWindow::slotEditReplaceAll() { slotEditReplace(true); } void KexiMainWindow::highlightObject(const QString& pluginId, const QString& name) { if (!d->prj) return; KexiPart::Item *item = d->prj->itemForPluginId(pluginId, name); if (!item) return; if (d->navigator) { slotSetProjectNavigatorVisible(true); d->navigator->selectItem(*item); } } void KexiMainWindow::slotPartItemSelectedInNavigator(KexiPart::Item* item) { Q_UNUSED(item); } KToolBar *KexiMainWindow::toolBar(const QString& name) const { return d->tabbedToolBar ? d->tabbedToolBar->toolBar(name) : 0; } void KexiMainWindow::appendWidgetToToolbar(const QString& name, QWidget* widget) { if (d->tabbedToolBar) d->tabbedToolBar->appendWidgetToToolbar(name, widget); } void KexiMainWindow::setWidgetVisibleInToolbar(QWidget* widget, bool visible) { if (d->tabbedToolBar) d->tabbedToolBar->setWidgetVisibleInToolbar(widget, visible); } void KexiMainWindow::addToolBarAction(const QString& toolBarName, QAction *action) { if (d->tabbedToolBar) d->tabbedToolBar->addAction(toolBarName, action); } void KexiMainWindow::updatePropertyEditorInfoLabel(const QString& textToDisplayForNullSet) { d->propEditor->updateInfoLabelForPropertySet(d->propertySet, textToDisplayForNullSet); } void KexiMainWindow::addSearchableModel(KexiSearchableModel *model) { if (d->tabbedToolBar) { d->tabbedToolBar->addSearchableModel(model); } } void KexiMainWindow::removeSearchableModel(KexiSearchableModel *model) { if (d->tabbedToolBar) { d->tabbedToolBar->removeSearchableModel(model); } } void KexiMainWindow::setReasonableDialogSize(QDialog *dialog) { dialog->setMinimumSize(600, 400); dialog->resize(size() * 0.8); } void KexiMainWindow::restoreDesignTabAndActivateIfNeeded(const QString &tabName) { if (!d->tabbedToolBar) { return; } d->tabbedToolBar->showTab(tabName); if (currentWindow() && currentWindow()->partItem() && currentWindow()->partItem()->identifier() != 0) // for unstored items id can be < 0 { const QString tabToActivate = d->tabsToActivateOnShow.value( currentWindow()->partItem()->identifier()); //qDebug() << "tabToActivate:" << tabToActivate << "tabName:" << tabName; if (tabToActivate == tabName) { d->tabbedToolBar->setCurrentTab(tabToActivate); } } } void KexiMainWindow::restoreDesignTabIfNeeded(const QString &pluginId, Kexi::ViewMode viewMode, int previousItemId) { //qDebug() << pluginId << viewMode << previousItemId; if (viewMode == Kexi::DesignViewMode) { switch (d->prj->typeIdForPluginId(pluginId)) { case KexiPart::FormObjectType: { hideDesignTab(previousItemId, "org.kexi-project.report"); restoreDesignTabAndActivateIfNeeded("form"); break; } case KexiPart::ReportObjectType: { hideDesignTab(previousItemId, "org.kexi-project.form"); restoreDesignTabAndActivateIfNeeded("report"); break; } default: hideDesignTab(previousItemId); } } else { hideDesignTab(previousItemId); } } void KexiMainWindow::activateDesignTab(const QString &pluginId) { if (!d->tabbedToolBar) { return; } switch (d->prj->typeIdForPluginId(pluginId)) { case KexiPart::FormObjectType: d->tabbedToolBar->setCurrentTab("form"); break; case KexiPart::ReportObjectType: d->tabbedToolBar->setCurrentTab("report"); break; default:; } } void KexiMainWindow::activateDesignTabIfNeeded(const QString &pluginId, Kexi::ViewMode viewMode) { if (!d->tabbedToolBar) { return; } const QString tabToActivate = d->tabsToActivateOnShow.value(currentWindow()->partItem()->identifier()); //qDebug() << pluginId << viewMode << tabToActivate; if (viewMode == Kexi::DesignViewMode && tabToActivate.isEmpty()) { activateDesignTab(pluginId); } else { d->tabbedToolBar->setCurrentTab(tabToActivate); } } void KexiMainWindow::hideDesignTab(int itemId, const QString &pluginId) { if (!d->tabbedToolBar) { return; } //qDebug() << itemId << pluginId; if ( itemId > 0 && d->tabbedToolBar->currentWidget()) { const QString currentTab = d->tabbedToolBar->currentWidget()->objectName(); //qDebug() << "d->tabsToActivateOnShow.insert" << itemId << currentTab; d->tabsToActivateOnShow.insert(itemId, currentTab); } switch (d->prj->typeIdForPluginId(pluginId)) { case KexiPart::FormObjectType: d->tabbedToolBar->hideTab("form"); break; case KexiPart::ReportObjectType: d->tabbedToolBar->hideTab("report"); break; default: d->tabbedToolBar->hideTab("form"); d->tabbedToolBar->hideTab("report"); } } void KexiMainWindow::showDesignTabIfNeeded(int previousItemId) { if (d->insideCloseWindow && d->tabbedToolBar) return; if (currentWindow()) { restoreDesignTabIfNeeded(currentWindow()->partItem()->pluginId(), currentWindow()->currentViewMode(), previousItemId); } else { hideDesignTab(previousItemId); } } KexiUserFeedbackAgent* KexiMainWindow::userFeedbackAgent() const { return &d->userFeedback; } KexiMigrateManagerInterface* KexiMainWindow::migrateManager() { if (!d->migrateManager) { d->migrateManager = dynamic_cast( KexiInternalPart::createObjectInstance( "org.kexi-project.migration", "manager", this, this, nullptr)); } return d->migrateManager; } void KexiMainWindow::toggleFullScreen(bool isFullScreen) { static bool isTabbarRolledDown; if (d->tabbedToolBar) { if (isFullScreen) { isTabbarRolledDown = !d->tabbedToolBar->isRolledUp(); if (isTabbarRolledDown) { d->tabbedToolBar->toggleRollDown(); } } else { if (isTabbarRolledDown && d->tabbedToolBar->isRolledUp()) { d->tabbedToolBar->toggleRollDown(); } } } const Qt::WindowStates s = windowState() & Qt::WindowMaximized; if (isFullScreen) { setWindowState(windowState() | Qt::WindowFullScreen | s); } else { setWindowState((windowState() & ~Qt::WindowFullScreen)); showMaximized(); } } diff --git a/src/main/KexiMainWindow.h b/src/main/KexiMainWindow.h index b728a7d52..fae20629a 100644 --- a/src/main/KexiMainWindow.h +++ b/src/main/KexiMainWindow.h @@ -1,653 +1,653 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2003-2018 Jarosław Staniek 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 KEXIMAINWINDOW_H #define KEXIMAINWINDOW_H //#define KEXI_IMPL_WARNINGS #include "keximain_export.h" #include #include #include #include #include class QPaintEvent; class KDbObject; class KDbConnectionData; class KexiProjectData; class KexiMainWidget; namespace KexiPart { class Info; class Part; } #define KexiMainWindowSuper QWidget //KMainWindow /** * @short Kexi's main window implementation */ class KEXIMAIN_EXPORT KexiMainWindow : public QWidget /*KMainWindow*/, public KexiMainWindowIface, public KexiGUIMessageHandler { Q_OBJECT public: /*! Creates an empty mainwindow. */ explicit KexiMainWindow(QWidget *parent = 0); virtual ~KexiMainWindow(); - virtual KActionCollection* actionCollection() const; + virtual KActionCollection* actionCollection() const override; //! @todo virtual QWidget* focusWidget() const; - virtual QWidget* focusWidget() const { + virtual QWidget* focusWidget() const override { return KexiMainWindowSuper::focusWidget(); } /*! Used by the main Kexi's routine. Creates a new Kexi main window. For Kexi applications @a arguments are equal to CoreApplication::arguments() but test applications alter the list. If @a componentName is provided, it is assigned to application's KAboutData::componentName. It's not used by Kexi itself but is useful for test application that are based on KexiMainWindow. @a extraOptions can be supplied to extend the list of supported options. @note Extra options must not override Kexi's built-in options. @return 0 on success (the result can be used as a result of main()) and other value on error */ static int create(const QStringList &arguments, const QString &componentName = QString(), const QList &extraOptions = QList()); //! Project data of currently opened project or NULL if no project here yet. - virtual KexiProject *project(); + virtual KexiProject *project() override; /*! Registers window \a window for watching and adds it to the main window's stack. */ - virtual void registerChild(KexiWindow *window); + virtual void registerChild(KexiWindow *window) override; /*! Activates a window by it's document identifier. \return false if doc couldn't be raised or isn't opened. */ bool activateWindow(int id); /*! Like above, using \a window passed explicitly. Above method just calls this one. */ bool activateWindow(KexiWindow& window); /*! Performs startup actions. \return false if application should exit immediately with an error status. */ tristate startup(); /*! \return true if the application window is in the User Mode. */ - virtual bool userMode() const; + virtual bool userMode() const override; /*! \return true if opening of item \a item in \a viewMode mode is allowed. userMode() is taken into account as well as KexiPart::PartInfo::supportedUserViewModes() for \a item. */ bool openingAllowed(KexiPart::Item* item, Kexi::ViewMode viewMode, QString* errorMessage = 0); /*! Implemented for KexiMainWindow. */ - virtual QList allActions() const; + virtual QList allActions() const override; /*! \return currently active window or 0 if there is no active window. Implemented for KexiWindow. */ - virtual KexiWindow* currentWindow() const; + virtual KexiWindow* currentWindow() const override; /*! @return window for tab @a tabIndex or 0 if there is no such tab. */ KexiWindow* windowForTab(int tabIndex) const; //! @todo temporary solution before the tabbed toolbar framework emerges // see KexiMainWindowIface - virtual void appendWidgetToToolbar(const QString& name, QWidget* widget); + virtual void appendWidgetToToolbar(const QString& name, QWidget* widget) override; //! @todo temporary solution before the tabbed toolbar framework emerges // see KexiMainWindowIface - virtual void setWidgetVisibleInToolbar(QWidget* widget, bool visible); + virtual void setWidgetVisibleInToolbar(QWidget* widget, bool visible) override; //! @todo replace with the final Actions API // see KexiMainWindowIface - virtual void addToolBarAction(const QString& toolBarName, QAction *action); + virtual void addToolBarAction(const QString& toolBarName, QAction *action) override; // see KexiMainWindowIface - virtual KToolBar *toolBar(const QString& name) const; + virtual KToolBar *toolBar(const QString& name) const override; //! Shows design tab @a tabName again and activates it as current if it was hidden //! before for the same object. void restoreDesignTabAndActivateIfNeeded(const QString &tabName); //! Shows design tab again when switching between objects or views. void restoreDesignTabIfNeeded(const QString &pluginId, Kexi::ViewMode viewMode, int previousItemId); //! Sets currently visible design tab when switching to design view, according to object type opened. virtual void activateDesignTabIfNeeded(const QString &pluginId, Kexi::ViewMode viewMode); //! Hides design tabs when they are closed (depending on ID @a pluginId). //! If @a pluginId is empty, all tabs get hidden. virtual void hideDesignTab(int itemId, const QString &pluginId = QString()); /*! Implemented for KexiMainWindow */ - virtual KexiUserFeedbackAgent* userFeedbackAgent() const; + virtual KexiUserFeedbackAgent* userFeedbackAgent() const override; /*! Implemented for KexiMainWindow */ - virtual KexiMigrateManagerInterface* migrateManager(); + virtual KexiMigrateManagerInterface* migrateManager() override; public Q_SLOTS: /*! Implemented for KexiMainWindow */ - virtual tristate closeWindow(KexiWindow *window); + virtual tristate closeWindow(KexiWindow *window) override; /*! Closes the current window. */ tristate closeCurrentWindow(); /*! Closes window inside tab @a tabIndex. */ tristate closeWindowForTab(int tabIndex); /*! Internal implementation. If \a doNotSaveChanges is true, messages asking for saving the will be skipped and the changes will be dropped. This should not be usually used, maybe except for test suites (see kexi/tests/altertable/ directory). */ tristate closeWindow(KexiWindow *window, bool layoutTaskBar, bool doNotSaveChanges = false); /** * Activates next window * * If any assistant window is active and visible, moves to previous page of the assistant. * If assistant window is not active, this action triggers activateNextTab() if tabs are present. */ void activateNextWindow(); /** * Activates previous window * * If any assistant window is active and visible, moves to previous page of the assistant. * If assistant window is not active, this action triggers activatePreviousTab() if tabs are present. */ void activatePreviousWindow(); /*! Activates next tab if tabs are present. */ void activateNextTab(); /*! Activates next tab if tabs are present. */ void activatePreviousTab(); //! @todo move part of this to KexiProject, because currently KexiProject::openObject() allows multiple opens! /*! Opens object pointed by \a item in a view \a viewMode. \a staticObjectArgs can be passed for static object (only works when part for this item is of type KexiPart::StaticPart). \a openingCancelled is set to true if opening has been cancelled. \a errorMessage, if not 0, points to a string that can be set to error message if one encountered. @c nullptr can be returned if the KexiWindow object for @a item is not yet fully constructed but openObject() has been quickly called again for the same @a item. This can happen if user clicked multiple times on the same Project navigator's item. In this case @a openingCancelled is not set; the caller should not display error message but the opening should be silently abandoned. */ virtual KexiWindow* openObject(KexiPart::Item *item, Kexi::ViewMode viewMode, bool *openingCancelled, QMap* staticObjectArgs = 0, - QString* errorMessage = 0); + QString* errorMessage = 0) override; //! For convenience virtual KexiWindow* openObject(const QString& pluginId, const QString& name, Kexi::ViewMode viewMode, bool *openingCancelled, - QMap* staticObjectArgs = 0); + QMap* staticObjectArgs = 0) override; /*! Closes the object for \a item. \return true on success (closing can be dealyed though), false on failure and cancelled if the object has "opening" job assigned. */ - virtual tristate closeObject(KexiPart::Item* item); + virtual tristate closeObject(KexiPart::Item* item) override; /*! Implemented for KexiMainWindow */ virtual tristate saveObject(KexiWindow *window, const QString& messageWhenAskingForName = QString(), - SaveObjectOptions options = 0); + SaveObjectOptions options = 0) override; /*! Implemented for KexiMainWindowIface. */ - virtual KexiWindow *openedWindowFor(int identifier); - virtual KexiWindow *openedWindowFor(const KexiPart::Item *item); + virtual KexiWindow *openedWindowFor(int identifier) override; + virtual KexiWindow *openedWindowFor(const KexiPart::Item *item) override; /*! Implemented for KexiMainWindowIface */ - virtual QList currentParametersForQuery(int queryId) const; + virtual QList currentParametersForQuery(int queryId) const override; /*! Implemented for KexiMainWindowIface. */ - virtual KDbQuerySchema *unsavedQuery(int queryId); + virtual KDbQuerySchema *unsavedQuery(int queryId) override; /*! Implemented for KexiMainWindow */ virtual tristate getNewObjectInfo(KexiPart::Item *partItem, const QString &originalName, KexiPart::Part *part, bool allowOverwriting, bool *overwriteNeeded, - const QString& messageWhenAskingForName = QString()); + const QString& messageWhenAskingForName = QString()) override; /*! Implemented for KexiMainWindow */ - virtual void highlightObject(const QString& pluginId, const QString& name); + virtual void highlightObject(const QString& pluginId, const QString& name) override; /*! Opens project pointed by \a projectData. Application state (e.g. actions) is updated. \a projectData is copied into a project structures. \return true on success */ tristate openProject(const KexiProjectData& projectData); /*! Helper. Opens project pointed by \a aFileName. If \a aFileName is empty, a connection shortcut (.kexic file name) is obtained from global connection set using \a cdata (if present). In this case: * If connection shortcut has been found and \a dbName (a server database name) is provided 'kexi --skip-dialog --connection file.kexic dbName' is executed (or the project is opened directly if there's no project opened in the current Kexi main window. * If connection shortcut has been found and \a dbName is not provided, 'kexi --skip-dialog file.kexic' is executed (or the connection is opened directly if there's no porject opened in the current Kexi main window. */ tristate openProject(const QString& aFileName, KDbConnectionData *cdata, const QString& dbName = QString(), const KexiProjectData::AutoOpenObjects& autoopenObjects = KexiProjectData::AutoOpenObjects()); /*! Helper. Opens project pointed by \a aFileName. Like above but \a fileNameForConnectionData can be passed instead of a pointer to connection data itself. \return false if \a fileNameForConnectionData is not empty but there is no such connection in Kexi::connset() for this filename. \a fileNameForConnectionData can be empty. */ tristate openProject(const QString& aFileName, const QString& fileNameForConnectionData, const QString& dbName = QString()); /*! Helper. Opens project pointed by \a aFileName. */ tristate openProject(const QString& aFileName); /*! Opens project referenced by @a data. If @a shortcutPath is a empty .kexis filename and there is another project opened, a new instance of Kexi is started with the .kexis file as argument. Value pointed by @a opened is set to true if the database has been opened successfully. @return true on successful opening, cancelled if the operation was cancelled and false on failure.*/ tristate openProject(const KexiProjectData& data, const QString& shortcutPath, bool *opened); /*! Creates a new project using template pointed by \a projectData. Application state (e.g. actions) is updated. New project data is copied into a project structures. \return true on success */ tristate createProjectFromTemplate(const KexiProjectData& projectData); /*! Closes current project, \return true on success. Application state (e.g. actions) is updated. \return true on success. If closing was cancelled by user, cancelled is returned. */ tristate closeProject(); //! Shows "print" dialog for \a item. //! \return true on success. - virtual tristate printItem(KexiPart::Item* item); + virtual tristate printItem(KexiPart::Item* item) override; //! Shows "print preview" window. //! \return true on success. - virtual tristate printPreviewForItem(KexiPart::Item* item); + virtual tristate printPreviewForItem(KexiPart::Item* item) override; //! Shows "page setup" window for \a item. //! \return true on success and cancelled when the action was cancelled. - virtual tristate showPageSetupForItem(KexiPart::Item* item); + virtual tristate showPageSetupForItem(KexiPart::Item* item) override; /*! Executes custom action for the main window, usually provided by a plugin. Also used by KexiFormEventAction. */ - virtual tristate executeCustomActionForObject(KexiPart::Item* item, const QString& actionName); + virtual tristate executeCustomActionForObject(KexiPart::Item* item, const QString& actionName) override; /*! Add searchable model to the main window. This extends search to a new area. One example is Project Navigator. @see KexiMainWindowIface */ void addSearchableModel(KexiSearchableModel *model) override; /*! Removes searchable model from the main window. @a model is not deleted. @see KexiMainWindowIface */ void removeSearchableModel(KexiSearchableModel *model) override; //! Shows design tab when switching between objects or views. Depends on current window and view mode. void showDesignTabIfNeeded(int previousItemId); void toggleFullScreen(bool isFullScreen); /*! Implemented for KexiMainWindowIface. Sets reasonable dialog size based on main window size, that is 80% of its size. */ - virtual void setReasonableDialogSize(QDialog *dialog); + virtual void setReasonableDialogSize(QDialog *dialog) override; Q_SIGNALS: //! Emitted to make sure the project can be close. //! Connect a slot here and set \a cancel to true to cancel the closing. - void acceptProjectClosingRequested(bool *cancel); + void acceptProjectClosingRequested(bool *cancel) override; //! Emitted before closing the project (and destroying all it's data members). //! You can do you cleanup of your structures here. - void beforeProjectClosing(); + void beforeProjectClosing() override; //! Emitted after closing the project. - void projectClosed(); + void projectClosed() override; //! Emitted after opening a project, even after slotAutoOpenObjectsLater(). void projectOpened(); protected: /*! Setups main widget */ void setupMainWidget(); /*! Creates the Project Navigator (if it's not yet created), lookups items for current project and fills the nav. with not-opened items */ void setupProjectNavigator(); void setupContextHelp(); void setupPropertyEditor(); void setupMainMenuActionShortcut(QAction * action); /*! Creates standard actions like new, open, save ... */ void setupActions(); /*! Creates user project-wide actions */ void setupUserActions(); /*! Sets up the window from user settings. */ void restoreSettings(); /*! Writes user settings back. */ void storeSettings(); /*! Invalidates availability of all actions for current application state. */ void invalidateActions(); /*! Invalidates action availability for current application state. These actions are dependent on active window. */ - virtual void invalidateSharedActions(QObject *o); + virtual void invalidateSharedActions(QObject *o) override; /*! Invalidates action availability for current application state. These actions only depend on project availability, not on curently active window. */ void invalidateProjectWideActions(); /*! Shows dialog for creating new project, and creates one. The dialog is not shown if option for automatic creation is checked or KexiStartupHandler::global()->projectData() was provided from command line. \a cancelled is set to true if creation has been cancelled (e.g. user answered no when asked for database overwriting, etc. \return true if database was created, false on error or when cancel was pressed */ void createNewProject(); /*! Shows dialog for creating new blank project, and return a data describing it. If the dialog was cancelled, \a cancelled will be set to true (false otherwise). \a shortcutFileName, if not 0, will be set to a shortcut filename (in case when server database project was selected). */ KexiProjectData* createBlankProjectData(bool *cancelled, bool confirmOverwrites = true, QString *shortcutFileName = 0); /*! Reimplemented from KexiSharedActionHost: accepts only KexiDockBase and KexiWindow subclasses. */ virtual bool acceptsSharedActions(QObject *w); /*! Performs lookup like in KexiSharedActionHost::focusWindow() but starting from \a w instead of a widget returned by QWidget::focusWidget(). \return NULL if no widget matches acceptsSharedActions() or if \a w is NULL. */ - virtual QWidget* findWindow(QWidget *w); + virtual QWidget* findWindow(QWidget *w) override; /*! Updates application's caption - also shows project's name. */ void updateAppCaption(); - virtual void closeEvent(QCloseEvent *ev); + virtual void closeEvent(QCloseEvent *ev) override; //! Called by KexiMainWidget::queryClose() bool queryClose(); /*! Implemented for KexiMainWindowIface. Switches \a window to view \a mode. Activates the window if it is not the current window. */ - virtual tristate switchToViewMode(KexiWindow& window, Kexi::ViewMode viewMode); + virtual tristate switchToViewMode(KexiWindow& window, Kexi::ViewMode viewMode) override; /*! Helper. Updates setup of property panel's tabs. Used when switching from \a prevWindow window to a current window. */ void updateCustomPropertyPanelTabs(KexiWindow *prevWindow, Kexi::ViewMode prevViewMode); /*! @overload void updateCustomPropertyPanelTabs(KexiWindow *prevWindow, Kexi::ViewMode prevViewMode) */ void updateCustomPropertyPanelTabs(KexiPart::Part *prevWindowPart, Kexi::ViewMode prevViewMode, KexiPart::Part *curWindowPart, Kexi::ViewMode curViewMode); /*! Used in openProject when running another Kexi process is required. */ tristate openProjectInExternalKexiInstance(const QString& aFileName, KDbConnectionData *cdata, const QString& dbName); /*! Used in openProject when running another Kexi process is required. */ tristate openProjectInExternalKexiInstance(const QString& aFileName, const QString& fileNameForConnectionData, const QString& dbName); /*! Updates info label of the property editor by reusing properties provided by the current property set. Read documentation of KexiPropertyEditorView class for information about accepted properties. If the current property is 0 and @a textToDisplayForNullSet string is not empty, this string is displayed (without icon or any other additional part). If the current property is 0 and @a textToDisplayForNullSet string is empty, the info label widget becomes hidden. Implemented for KexiMainWindow. @see KexiPropertyPaneViewBase::updateInfoLabelForPropertySet() */ - virtual void updatePropertyEditorInfoLabel(const QString& textToDisplayForNullSet); + virtual void updatePropertyEditorInfoLabel(const QString& textToDisplayForNullSet) override; //! Activates design tab when switching to design view, according to \a pluginId. void activateDesignTab(const QString &pluginId); protected Q_SLOTS: tristate createNewProject(const KexiProjectData &projectData); /*! Called once after timeout (after ctors are executed). */ void slotAutoOpenObjectsLater(); /*! Called if a window (tab) changes from \a prevWindow to \a window. Both parameters can be 0. */ void activeWindowChanged(KexiWindow *window, KexiWindow *prevWindow); void slotPartLoaded(KexiPart::Part* p); //! Internal - creates and initializes Kexi project object based on @a data. KexiProject* createKexiProjectObject(const KexiProjectData &data); /*! Handles event when user double clicked (or single -depending on settings) or pressed Return key on the part item in the navigator. This differs from openObject() signal in that if the object is already opened in view mode other than \a viewMode, the mode is not changed. \sa KexiProjectNavigator::openOrActivateItem() */ KexiWindow* openObjectFromNavigator(KexiPart::Item* item, Kexi::ViewMode viewMode, bool *openingCancelled); //! For convenience KexiWindow* openObjectFromNavigator(KexiPart::Item* item, Kexi::ViewMode viewMode); /*! Creates new object of type defined by \a info part info. \a openingCancelled is set to true if opening has been cancelled. \return true on success. */ - virtual bool newObject(KexiPart::Info *info, bool *openingCancelled); + virtual bool newObject(KexiPart::Info *info, bool *openingCancelled) override; //! For convenience bool newObject(KexiPart::Info *info) { bool openingCancelled; return newObject(info, &openingCancelled); } //! For convenience KexiWindow* openObject(KexiPart::Item *item, Kexi::ViewMode viewMode, QMap* staticObjectArgs = 0) { bool openingCancelled; return openObject(item, viewMode, &openingCancelled, staticObjectArgs); } /*! Removes object pointed by \a item from current project. Asks for confirmation. \return true on success or cancelled if removing was cancelled (only possible if \a dontAsk is false). */ tristate removeObject(KexiPart::Item *item, bool dontAsk = false); /*! Renames object pointed by \a item to a new name \a _newName. Sets \a success to false on failure. Used as a slot connected to KexiProjectNavigator::renameItem() signal. */ void renameObject(KexiPart::Item *item, const QString& _newName, bool *succes); /*! Changes caption of object pointed by \a item to \a _newCaption. Sets \a success to false on failure. Used as a slot connected to KexiProjectNavigator::changeItemCaption() signal. */ void setObjectCaption(KexiPart::Item *item, const QString& _newCaption, bool *succes); /*! Reaction for object rename (signalled by KexiProject). If this item has opened window, it's caption is updated, and also optionally application's caption. */ - virtual void slotObjectRenamed(const KexiPart::Item &item, const QString& oldName); + virtual void slotObjectRenamed(const KexiPart::Item &item, const QString& oldName) override; //! @todo virtual void fillWindowMenu(); void invalidateSharedActions(); void invalidateSharedActionsLater(); //! Updates the statusbar, navigator and "Insert->....." actions, dependent on read-only state. //! Only called on project opening and closing. void updateReadOnlyState(); void slotProjectWelcome(); void slotProjectNew(); void slotProjectOpen(); void slotProjectSave(); void slotProjectSaveAs(); void slotProjectPrint(); void slotProjectPrintPreview(); void slotProjectPageSetup(); void slotProjectProperties(); void slotProjectImportExportOrSend(); void slotProjectClose(); void slotProjectRelations(); void slotProjectImportDataTable(); void slotProjectExportDataTable(); void slotProjectQuit(); void slotEditPasteSpecialDataTable(); void slotEditCopySpecialDataTable(); void slotEditFind(); void slotEditFind(bool next); //!< helper void slotEditFindNext(); void slotEditFindPrevious(); void slotEditReplace(bool all); //!< helper void slotEditReplace(); void slotEditReplaceNext(); void slotEditReplaceAll(); void slotActivateNavigator(); void slotActivateMainArea(); void slotActivatePropertyEditor(); void slotShowNavigator(); void slotShowPropertyEditor(); void slotViewDataMode(); void slotViewDesignMode(); void slotViewTextMode(); //!< sometimes called "SQL View" void slotSettings(); void slotConfigureKeys(); void slotConfigureToolbars(); void slotToolsImportProject(); void slotToolsImportTables(); void slotToolsCompactDatabase(); void slotReportBug(); void slotTipOfTheDay(); void slotImportFile(); void slotImportServer(); //! There are performed all actions that need to be done immediately after ctro (using timer) void slotLastActions(); - virtual void acceptPropertySetEditing(); + virtual void acceptPropertySetEditing() override; virtual void propertySetSwitched(KexiWindow *window, bool force = false, bool preservePrevSelection = true, bool sortedProperties = false, - const QByteArray& propertyToSelect = QByteArray()); + const QByteArray& propertyToSelect = QByteArray()) override; /*! Handles changes in 'dirty' flag for windows. */ void slotDirtyFlagChanged(KexiWindow* window); /*! Shows Project Migration Wizard. \return true on successful migration, cancelled on cancellation, and false on failure. If \a mimeType and \a databaseName are not empty, the wizard will only ask about parameters of destination project and skip pages related to source project. */ tristate showProjectMigrationWizard(const QString& mimeType, const QString& databaseName); /*! @overload tristate showProjectMigrationWizard(const QString& mimeType, const QString& databaseName) @a cdata is used preselect a server-based connection. */ tristate showProjectMigrationWizard(const QString& mimeType, const QString& databaseName, const KDbConnectionData &cdata); //! Receives "selectionChanged()" signal from navigator to update some actions. void slotPartItemSelectedInNavigator(KexiPart::Item* item); /*! Receives the "executeItem" signal from navigator to perform "execute" action on \a item. \return true on success */ tristate executeItem(KexiPart::Item* item); //! Shows "export as data table" dialog for \a item. tristate exportItemAsDataTable(KexiPart::Item* item); //! Shows "copy special as data table" dialog for \a item. tristate copyItemToClipboardAsDataTable(KexiPart::Item* item); bool checkForDirtyFlagOnExport(KexiPart::Item *item, QMap *args); /*! Shows a question message * "Design of query %1 that you want to export data from is changed and has not yet been saved. * Do you want to use data from the changed query for exporting or from its original (saved) version?" \return true if the user picked the first option, * false if the user picked the second option and cancelled value if user cancelled the export. */ tristate askOnExportingChangedQuery(KexiPart::Item* item) const; //! Shows "print" dialog for \a item. //! \return true on success. bool printItem(KexiPart::Item* item, const QString& titleText); //! Shows "print" dialog for \a item and \a settings. //! \return true on success. //! @todo reenable when ported bool printItem(KexiPart::Item* item, const KexiSimplePrintingSettings& settings, const QString& titleText = QString()); /*! Shows "print preview" window for \a item. The preview windoe is cached, so \a reload == true is sometimes needed if data or print settings have changed in the meantime. \return true on success. */ bool printPreviewForItem(KexiPart::Item* item, const QString& titleText, bool reload); //! Shows "print preview" window. //! \return true on success. //! @todo reenable when ported bool printPreviewForItem(KexiPart::Item* item, const KexiSimplePrintingSettings& settings, const QString& titleText = QString(), bool reload = false); /*! Implemented for KexiMainWindow. Helper for printItem() and printPreviewForItem(). Also used by KexiFormEventAction. \return true on success and cancelled when the action was cancelled. */ //! @todo reenable when ported tristate printActionForItem(KexiPart::Item* item, PrintActionType action); void slotSetProjectNavigatorVisible(bool set); void slotSetPropertyEditorVisible(bool set); void slotProjectNavigatorVisibilityChanged(bool visible); void slotPropertyEditorVisibilityChanged(bool visible); void slotMultiTabBarTabClicked(int id); private: //! Adds action @a name with text @a text and optional shortcut @a shortcut. //! This is helper method containing workaround for Kexi //! until QAction::setShortcut() works again. //! @return created action QAction * addAction(const char *name, const QString &text, const char *shortcut = 0); //! Like @ref addAction(const char *, const QString&, const char *) but also adds //! icon @a icon. //! @return created action QAction * addAction(const char *name, const QIcon &icon, const QString& text, const char *shortcut = 0); class MessageHandler; class Private; Private * const d; friend class KexiWindow; friend class KexiMainWidget; }; #endif diff --git a/src/main/KexiMainWindow_p.h b/src/main/KexiMainWindow_p.h index f0446df3d..b85296031 100644 --- a/src/main/KexiMainWindow_p.h +++ b/src/main/KexiMainWindow_p.h @@ -1,714 +1,714 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2003-2018 Jarosław Staniek 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 KEXIMAINWINDOW_P_H #define KEXIMAINWINDOW_P_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "KexiMainWindow.h" #include "KexiSearchLineEdit.h" #include "KexiUserFeedbackAgent.h" #include "KexiMenuWidget.h" #include "kexifinddialog.h" #include "KexiStartup.h" #include #include #include #include #include #include #include #define KEXI_NO_PROCESS_EVENTS #ifdef KEXI_NO_PROCESS_EVENTS # define KEXI_NO_PENDING_DIALOGS #endif #define PROJECT_NAVIGATOR_TABBAR_ID 0 #define PROPERTY_EDITOR_TABBAR_ID 1 #define KEXITABBEDTOOLBAR_SPACER_TAB_INDEX 1 class QPainter; class KexiAssistantPage; class KexiProjectNavigator; //! @short Main application's tabbed toolbar class KexiTabbedToolBar : public QTabWidget { Q_OBJECT public: explicit KexiTabbedToolBar(QWidget *parent); virtual ~KexiTabbedToolBar(); KToolBar *createWidgetToolBar() const; KToolBar *toolBar(const QString& name) const; void appendWidgetToToolbar(const QString& name, QWidget* widget); void setWidgetVisibleInToolbar(QWidget* widget, bool visible); //! @todo replace with the final Actions API void addAction(const QString& toolBarName, QAction *action); bool mainMenuVisible() const; QRect tabRect(int index) const; KHelpMenu *helpMenu() const; void addSearchableModel(KexiSearchableModel *model); void removeSearchableModel(KexiSearchableModel *model); KToolBar *createToolBar(const char *name, const QString& caption); void setCurrentTab(const QString& name); //! Sets current tab to @a index, counting from first visible (non-Kexi) tab. //! In non-user mode, the first visible tab is "create" tab. void setCurrentTab(int index); void hideTab(const QString& name); void showTab(const QString& name); bool isTabVisible(const QString& name) const; bool isRolledUp(); const QWidget* mainMenuContent(); public Q_SLOTS: void setMainMenuContent(QWidget *w); void selectMainMenuItem(const char *actionName); void showMainMenu(const char* actionName = 0); void hideMainMenu(); void toggleMainMenu(); void activateSearchLineEdit(); void toggleRollDown(); protected: - virtual void mouseMoveEvent(QMouseEvent* event); - virtual void leaveEvent(QEvent* event); - virtual bool eventFilter(QObject* watched, QEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event) override; + virtual void leaveEvent(QEvent* event) override; + virtual bool eventFilter(QObject* watched, QEvent* event) override; protected Q_SLOTS: void slotCurrentChanged(int index); void slotDelayedTabRaise(); void slotSettingsChanged(int category); //! Used for delayed loading of the "create" toolbar. Called only once. void setupCreateWidgetToolbar(); void slotTabDoubleClicked(int index); void tabBarAnimationFinished(); private: void addAction(KToolBar *tbar, const char* actionName); void addSeparatorAndAction(KToolBar *tbar, const char* actionName); class Private; Private * const d; }; //! @internal window container created to speedup opening new tabs class KexiWindowContainer : public QWidget { Q_OBJECT public: explicit KexiWindowContainer(QWidget* parent); virtual ~KexiWindowContainer(); void setWindow(KexiWindow* w); QPointer window; private: QVBoxLayout *lyr; }; class EmptyMenuContentWidget : public QWidget { Q_OBJECT public: explicit EmptyMenuContentWidget(QWidget* parent = 0); void alterBackground(); - virtual void changeEvent(QEvent *e); + virtual void changeEvent(QEvent *e) override; }; //! @todo KEXI3 is KexiMenuWidgetStyle needed? #if 0 //! A style proxy for KexiMenuWidget class KexiMenuWidgetStyle : public KexiUtils::StyleProxy { public: explicit KexiMenuWidgetStyle(QStyle *style, QObject *parent = 0); virtual ~KexiMenuWidgetStyle(); virtual void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const; }; #endif //! Main menu class KexiMainMenu : public QWidget { Q_OBJECT public: explicit KexiMainMenu(KexiTabbedToolBar *toolBar, QWidget* parent = 0); ~KexiMainMenu(); - virtual bool eventFilter(QObject * watched, QEvent* event); + virtual bool eventFilter(QObject * watched, QEvent* event) override; void setContent(QWidget *contentWidget); const QWidget *contentWidget() const; void setPersistentlySelectedAction(KexiMenuWidgetAction* action, bool set); /* void setActiveAction(QAction* action = 0);*/ void selectFirstItem(); tristate showProjectMigrationWizard( const QString& mimeType, const QString& databaseName, const KDbConnectionData *cdata); Q_SIGNALS: void contentAreaPressed(); void hideContentsRequested(); protected Q_SLOTS: //void contentWidgetDestroyed(); protected: - virtual void showEvent(QShowEvent * event); + virtual void showEvent(QShowEvent * event) override; private: QPointer m_menuWidget; KexiTabbedToolBar* m_toolBar; bool m_initialized; EmptyMenuContentWidget *m_content; QStackedLayout *m_contentLayout = nullptr; QPointer m_contentWidget; QVBoxLayout* m_mainContentLayout = nullptr; QPointer m_persistentlySelectedAction; bool m_selectFirstItem; }; class KexiTabbedToolBarTabBar; //! @internal class Q_DECL_HIDDEN KexiTabbedToolBar::Private : public QObject { Q_OBJECT public: explicit Private(KexiTabbedToolBar *t); KToolBar *createToolBar(const char *name, const QString& caption); int tabIndex; public Q_SLOTS: void showMainMenu(const char* actionName = 0); void hideMainMenu(); void hideContentsOrMainMenu(); void toggleMainMenu(); void updateMainMenuGeometry(); //! Initializes global search line edit. If it is enabled, it's created, if disabled, it's deleted. void initSearchLineEdit(); public: KexiTabbedToolBarTabBar *customTabBar; QPointer mainMenu; KexiTabbedToolBar *q; KActionCollection *ac; int createId; KToolBar *createWidgetToolBar; QHBoxLayout *helpLayer; #ifdef KEXI_AUTORISE_TABBED_TOOLBAR //! Used for delayed tab raising int tabToRaise; //! Used for delayed tab raising QTimer tabRaiseTimer; #endif //! Toolbars for name QHash toolbarsForName; QHash toolbarsIndexForName; QHash toolbarsCaptionForName; QVector toolbarsVisibleForIndex; QHash extraActions; bool rolledUp; QPropertyAnimation tabBarAnimation; QGraphicsOpacityEffect tabBarOpacityEffect; int rolledUpIndex; KHelpMenu *helpMenu; KexiSearchLineEdit *searchLineEdit = nullptr; void setCurrentTab(const QString& name); void hideTab(const QString& name); void showTab(const QString& name); bool isTabVisible(const QString& name) const; #ifndef NDEBUG void debugToolbars() const; #endif int lowestIndex; }; class KexiTabbedToolBarStyle; //! Tab bar reimplementation for KexiTabbedToolBar. /*! The main its purpose is to alter the width of "Kexi" tab. */ class KexiTabbedToolBarTabBar : public QTabBar { Q_OBJECT public: explicit KexiTabbedToolBarTabBar(QWidget *parent = 0); virtual QSize originalTabSizeHint(int index) const; - virtual QSize tabSizeHint(int index) const; + virtual QSize tabSizeHint(int index) const override; KexiTabbedToolBarStyle* customStyle; }; //! Style proxy for KexiTabbedToolBar, to get the "Kexi" tab style right. class KexiTabbedToolBarStyle : public QProxyStyle { Q_OBJECT public: explicit KexiTabbedToolBarStyle(const QString &baseStyleName); virtual ~KexiTabbedToolBarStyle(); virtual void drawControl(ControlElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget = 0) const; + QPainter *painter, const QWidget *widget = 0) const override; virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, - QPainter *painter, const QWidget *widget = 0) const; + QPainter *painter, const QWidget *widget = 0) const override; virtual int pixelMetric(PixelMetric metric, const QStyleOption* option = 0, - const QWidget* widget = 0) const; + const QWidget* widget = 0) const override; }; //! Style proxy for KexiTabbedToolBar, to fix the hardcoded margins (e.g. for Breeze). class KexiDockWidgetStyle : public QProxyStyle { Q_OBJECT public: explicit KexiDockWidgetStyle(const QString &baseStyleName); virtual ~KexiDockWidgetStyle(); using QProxyStyle::polish; void polish(QWidget* widget) Q_DECL_OVERRIDE; }; class KexiMainWidget; //! @internal tab widget acting as central widget for KexiMainWindow class KexiMainWindowTabWidget : public QTabWidget { Q_OBJECT public: KexiMainWindowTabWidget(QWidget *parent, KexiMainWidget *mainWidget); virtual ~KexiMainWindowTabWidget(); public Q_SLOTS: void closeTab(); tristate closeAllTabs(); protected: //! Shows context menu for tab at @a index at point @a point. //! If @a index is -1, context menu for empty area is requested. void showContextMenuForTab(int index, const QPoint& point); //! Reimplemented to hide frame when no tabs are displayed - virtual void paintEvent(QPaintEvent * event); + virtual void paintEvent(QPaintEvent * event) override; - virtual void mousePressEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event) override; KexiMainWidget *m_mainWidget; QAction *m_closeAction; QAction *m_closeAllTabsAction; private: int m_tabIndex; void setTabIndexFromContextMenu(int clickedIndex); }; //! @short A widget being main part of KexiMainWindow class KexiMainWidget : public KMainWindow { Q_OBJECT public: KexiMainWidget(); virtual ~KexiMainWidget(); void setParent(KexiMainWindow* mainWindow); KexiMainWindowTabWidget* tabWidget() const; protected: - virtual bool queryClose(); + virtual bool queryClose() override; protected Q_SLOTS: void slotCurrentTabIndexChanged(int index); Q_SIGNALS: void currentTabIndexChanged(int index); private: void setupCentralWidget(); KexiMainWindowTabWidget* m_tabWidget; KexiMainWindow *m_mainWindow; QPointer m_previouslyActiveWindow; friend class KexiMainWindow; friend class KexiMainWindowTabWidget; }; //------------------------------------------ //! @internal Dock widget with floating disabled but still collapsible class KexiDockWidget : public QDockWidget { Q_OBJECT public: KexiDockWidget(const QString &tabText, QWidget *parent); virtual ~KexiDockWidget(); virtual void setSizeHint(const QSize& hint); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; const QString tabText; //!< for tab bar tabs protected: - virtual void paintEvent(QPaintEvent *pe); + virtual void paintEvent(QPaintEvent *pe) override; private: class Private; Private * const d; }; //------------------------------------------ //! @internal safer dictionary typedef QMap< int, KexiWindow* > KexiWindowDict; //! @internal class Q_DECL_HIDDEN KexiMainWindow::Private { public: explicit Private(KexiMainWindow* w); ~Private(); #ifndef KEXI_NO_PENDING_DIALOGS //! Job type. Currently used for marking items as being opened or closed. enum PendingJobType { NoJob = 0, WindowOpeningJob, WindowClosingJob }; KexiWindow *openedWindowFor(const KexiPart::Item* item, PendingJobType &pendingType); KexiWindow *openedWindowFor(int identifier, PendingJobType &pendingType); void addItemToPendingWindows(const KexiPart::Item* item, PendingJobType jobType); bool pendingWindowsExist(); void removePendingWindow(int identifier); #else KexiWindow *openedWindowFor(int identifier); #endif void insertWindow(KexiWindow *window); bool windowContainerExistsFor(int identifier) const; void setWindowContainerExistsFor(int identifier, bool set); void updateWindowId(KexiWindow *window, int oldItemID); void removeWindow(int identifier); int openedWindowsCount(); //! Used in KexiMainWindowe::closeProject() void clearWindows(); void showStartProcessMsg(const QStringList& args); //! Updates Property Editor Pane's visibility for the current window and the @a viewMode view mode. /*! @a info can be provided to hadle cases when current window is not yet defined (in openObject()). */ void updatePropEditorVisibility(Kexi::ViewMode viewMode, KexiPart::Info *info = 0); void setTabBarVisible(KMultiTabBar::KMultiTabBarPosition position, int id, KexiDockWidget *dockWidget, bool visible); void setPropertyEditorTabBarVisible(bool visible); QObject *openedCustomObjectsForItem(KexiPart::Item* item, const char* name); void addOpenedCustomObjectForItem(KexiPart::Item* item, QObject* object, const char* name); KexiFindDialog *findDialog(); /*! Updates the find/replace dialog depending on the active view. Nothing is performed if the dialog is not instantiated yet or is invisible. */ void updateFindDialogContents(bool createIfDoesNotExist = false); //! \return the current view if it supports \a actionName, otherwise returns 0. KexiView *currentViewSupportingAction(const char* actionName) const; //! \return the current view if it supports KexiSearchAndReplaceViewInterface. KexiSearchAndReplaceViewInterface* currentViewSupportingSearchAndReplaceInterface() const; tristate showProjectMigrationWizard( const QString& mimeType, const QString& databaseName, const KDbConnectionData *cdata); /** * Returns current page of active visible main menu widget or @c nullptr if there is no visible * menu widget or menu widget contains no page. */ KexiAssistantPage *visibleMainMenuWidgetPage(); KexiMainWindow *wnd; KexiMainWidget *mainWidget; KActionCollection *actionCollection; KHelpMenu *helpMenu; KexiProject *prj; KSharedConfig::Ptr config; #ifdef KEXI_SHOW_CONTEXT_HELP KexiContextHelp *ctxHelp; #endif KexiProjectNavigator *navigator; KexiTabbedToolBar *tabbedToolBar; QMap tabsToActivateOnShow; KexiDockWidget *navDockWidget; QTabWidget *propEditorTabWidget; KexiDockWidget *propEditorDockWidget; QPointer propEditorDockableWidget; //! poits to kexi part which has been previously used to setup proppanel's tabs using //! KexiPart::setupCustomPropertyPanelTabs(), in updateCustomPropertyPanelTabs(). QPointer partForPreviouslySetupPropertyPanelTabs; QMap recentlySelectedPropertyPanelPages; QPointer propEditor; QPointer propertySet; KexiNameDialog *nameDialog; QTimer timer; //!< helper timer QString appCaptionPrefix; // focus_before_popup; //! Set to true only in destructor, used by closeWindow() to know if //! user can cancel window closing. If true user even doesn't see any messages //! before closing a window. This is for extremely sanity... and shouldn't be even needed. bool forceWindowClosing; //! Indicates that we're inside closeWindow() method - to avoid inf. recursion //! on window removing bool insideCloseWindow; #ifndef KEXI_NO_PENDING_DIALOGS //! Used in executeActionWhenPendingJobsAreFinished(). enum ActionToExecuteWhenPendingJobsAreFinished { NoAction, QuitAction, CloseProjectAction }; ActionToExecuteWhenPendingJobsAreFinished actionToExecuteWhenPendingJobsAreFinished; void executeActionWhenPendingJobsAreFinished(); #endif //! Used for delayed windows closing for 'close all' QList windowsToClose; #ifdef KEXI_QUICK_PRINTING_SUPPORT //! Opened page setup dialogs, used by printOrPrintPreviewForItem(). QHash pageSetupWindows; /*! A map from Kexi dialog to "print setup" part item's ID of the data item used by closeWindow() to find an ID of the data item, so the entry can be removed from pageSetupWindows dictionary. */ QMap pageSetupWindowItemID2dataItemID_map; #endif //! Indicates if project is started in User Mode bool userMode; //! Indicates if project navigator should be visible bool isProjectNavigatorVisible; //! Indicates if the main menu should be visible bool isMainMenuVisible; //! Set in restoreSettings() and used in initNavigator() //! to customize navigator visibility on startup bool forceShowProjectNavigatorOnCreation; bool forceHideProjectNavigatorOnCreation; bool navWasVisibleBeforeProjectClosing; bool saveSettingsForShowProjectNavigator; //! Used by openedCustomObjectsForItem() and addOpenedCustomObjectForItem() QHash m_openedCustomObjectsForItem; int propEditorDockSeparatorPos, navDockSeparatorPos; bool wasAutoOpen; bool windowExistedBeforeCloseProject; QMap multiTabBars; bool propertyEditorCollapsed; bool enable_slotPropertyEditorVisibilityChanged; KexiUserFeedbackAgent userFeedback; KexiMigrateManagerInterface* migrateManager; private: //! @todo move to KexiProject KexiWindowDict windows; //! A set of item identifiers for whose there are KexiWindowContainer instances already. //! This lets to verify that KexiWindow is about to be constructed and opened so multiple //! opening can be avoided. QSet windowContainers; #ifndef KEXI_NO_PROCESS_EVENTS QHash pendingWindows; //!< part item identifiers for windows whoose opening has been started //! @todo QMutex dialogsMutex; //!< used for locking windows and pendingWindows dicts #endif KexiFindDialog *m_findDialog; }; //------------------------------------------ //! Action shortcut used by KexiMainWindow::setupMainMenuActionShortcut(QAction *) //! Activates action only if enabled. class KexiMainMenuActionShortcut : public QShortcut { Q_OBJECT public: KexiMainMenuActionShortcut(const QKeySequence& key, QAction *action, QWidget *parent); virtual ~KexiMainMenuActionShortcut(); protected Q_SLOTS: //! Triggers associated action only when this action is enabled void slotActivated(); private: QPointer m_action; }; #endif diff --git a/src/main/KexiMenuWidget.h b/src/main/KexiMenuWidget.h index e43f9a14f..2d3f5f0fa 100644 --- a/src/main/KexiMenuWidget.h +++ b/src/main/KexiMenuWidget.h @@ -1,202 +1,202 @@ /* This file is part of the KDE project Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). Copyright (C) 2011-2014 Jarosław Staniek Based on qmenu.h from Qt 4.7 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 KEXIMENUWIDGET_H #define KEXIMENUWIDGET_H #include #include #include #include #include class KexiMenuWidgetPrivate; class KexiMenuWidgetActionPrivate; class QStyleOptionMenuItem; class QEventLoop; struct KexiMenuWidgetCaused; class KexiMenuWidgetAction : public QAction { Q_OBJECT public: explicit KexiMenuWidgetAction(QObject *parent); KexiMenuWidgetAction(const QString &text, QObject *parent); KexiMenuWidgetAction(const QIcon &icon, const QString &text, QObject *parent); KexiMenuWidgetAction(KStandardAction::StandardAction id, QObject *parent); ~KexiMenuWidgetAction(); void setPersistentlySelected(bool set); bool persistentlySelected() const; protected: const QScopedPointer d; }; class KexiMenuWidget : public QWidget { private: Q_OBJECT //Q_PROPERTY(bool tearOffEnabled READ isTearOffEnabled WRITE setTearOffEnabled) Q_PROPERTY(QString title READ title WRITE setTitle) Q_PROPERTY(QIcon icon READ icon WRITE setIcon) Q_PROPERTY(bool separatorsCollapsible READ separatorsCollapsible WRITE setSeparatorsCollapsible) Q_PROPERTY(bool frame READ hasFrame WRITE setFrame) public: explicit KexiMenuWidget(QWidget *parent = 0); explicit KexiMenuWidget(const QString &title, QWidget *parent = 0); ~KexiMenuWidget(); KexiMenuWidgetAction* persistentlySelectedAction() const; void setPersistentlySelectedAction(KexiMenuWidgetAction* action, bool set); #ifdef Q_NO_USING_KEYWORD inline void addAction(QAction *action) { QWidget::addAction(action); } #else using QWidget::addAction; #endif QAction *addAction(const QString &text); QAction *addAction(const QIcon &icon, const QString &text); QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); // QAction *addMenu(QMenu *menu); // QMenu *addMenu(const QString &title); // QMenu *addMenu(const QIcon &icon, const QString &title); QAction *addSeparator(); // QAction *insertMenu(QAction *before, QMenu *menu); QAction *insertSeparator(QAction *before); //! @return true if frame is visible. By default the frame is visible. //! It may be still visually no change, e.g. on Oxygen style. bool hasFrame() const; //! Sets frame visibility. void setFrame(bool set); //! @return true if persistent selections are enabled. False by default. //! @see setPersistentSelectionsEnabled() // bool persistentSelectionsEnabled() const; //! Sets flag of for persistent selections in action items. //! In KexiMenuWidget, persistent selection flag is used in place of submenus. // void setPersistentSelectionsEnabled(bool set); bool isEmpty() const; void clear(); void setTearOffEnabled(bool); bool isTearOffEnabled() const; bool isTearOffMenuVisible() const; void hideTearOffMenu(); void setDefaultAction(QAction *); QAction *defaultAction() const; void setActiveAction(QAction *act); QAction *activeAction() const; void popup(const QPoint &pos, QAction *at=0); // QAction *exec(); // QAction *exec(const QPoint &pos, QAction *at=0); // ### Qt 5: merge // static QAction *exec(QList actions, const QPoint &pos, QAction *at=0); // static QAction *exec(QList actions, const QPoint &pos, QAction *at, QWidget *parent); - QSize sizeHint() const; + QSize sizeHint() const override; QRect actionGeometry(QAction *) const; QAction *actionAt(const QPoint &) const; QAction *menuAction() const; QString title() const; void setTitle(const QString &title); QIcon icon() const; void setIcon(const QIcon &icon); void setNoReplayFor(QWidget *widget); bool separatorsCollapsible() const; void setSeparatorsCollapsible(bool collapse); Q_SIGNALS: void aboutToShow(); void aboutToHide(); void triggered(QAction *action); void hovered(QAction *action); protected: int columnCount() const; - void changeEvent(QEvent *); - void keyPressEvent(QKeyEvent *); - void mouseReleaseEvent(QMouseEvent *); - void mousePressEvent(QMouseEvent *); - void mouseMoveEvent(QMouseEvent *); + void changeEvent(QEvent *) override; + void keyPressEvent(QKeyEvent *) override; + void mouseReleaseEvent(QMouseEvent *) override; + void mousePressEvent(QMouseEvent *) override; + void mouseMoveEvent(QMouseEvent *) override; #ifndef QT_NO_WHEELEVENT - void wheelEvent(QWheelEvent *); + void wheelEvent(QWheelEvent *) override; #endif - void enterEvent(QEvent *); - void leaveEvent(QEvent *); - void showEvent(QShowEvent* event); - void hideEvent(QHideEvent *); - void paintEvent(QPaintEvent *); - void actionEvent(QActionEvent *); - void timerEvent(QTimerEvent *); - bool event(QEvent *); - bool focusNextPrevChild(bool next); + void enterEvent(QEvent *) override; + void leaveEvent(QEvent *) override; + void showEvent(QShowEvent* event) override; + void hideEvent(QHideEvent *) override; + void paintEvent(QPaintEvent *) override; + void actionEvent(QActionEvent *) override; + void timerEvent(QTimerEvent *) override; + bool event(QEvent *) override; + bool focusNextPrevChild(bool next) override; void initStyleOption(QStyleOptionMenuItem *option, const QAction *action) const; private Q_SLOTS: void internalSetSloppyAction(); //void internalDelayedPopup(); void actionTriggered(); void actionHovered(); void overrideMenuActionDestroyed(); protected: const KexiMenuWidgetCaused& causedPopup() const; enum SelectionReason { SelectedFromKeyboard, SelectedFromElsewhere }; void setCurrentAction(QAction *, int popup = -1, SelectionReason reason = SelectedFromElsewhere, bool activateFirst = false); QEventLoop *eventLoop() const; void setSyncAction(QAction *a); private: Q_DISABLE_COPY(KexiMenuWidget) KexiMenuWidgetPrivate * const d; friend class KexiMenuWidgetPrivate; }; #endif diff --git a/src/main/KexiMenuWidget_p.h b/src/main/KexiMenuWidget_p.h index 886b857c9..7814ab9f2 100644 --- a/src/main/KexiMenuWidget_p.h +++ b/src/main/KexiMenuWidget_p.h @@ -1,290 +1,290 @@ /* This file is part of the KDE project Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). Copyright (C) 2011-2013 Jarosław Staniek Based on qmenu_p.h from Qt 4.7 based on oxygenhelper.h Copyright 2009-2010 Hugo Pereira Da Costa Copyright 2008 Long Huynh Huu Copyright 2007 Matthew Woehlke Copyright 2007 C. Boemann Copyright 2007 Fredrik Höglund 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 KEXIMENUWIDGET_P_H #define KEXIMENUWIDGET_P_H #include "KexiMenuWidget.h" #include #include #include #include #include #include #include #include class QEventLoop; //! Used to define transparent clickable logo area class ClickableLogoArea : public QAbstractButton { Q_OBJECT public: explicit ClickableLogoArea(QWidget *parent = 0); protected Q_SLOTS: void slotClicked(); protected: - virtual void paintEvent(QPaintEvent*); + virtual void paintEvent(QPaintEvent*) override; }; //used to walk up the popup list struct KexiMenuWidgetCaused { QPointer widget; QPointer action; }; class OxygenHelper { public: OxygenHelper(); virtual ~OxygenHelper(); bool lowThreshold(const QColor &color); bool highThreshold(const QColor &color); virtual const QColor& backgroundTopColor(const QColor &color); virtual const QColor& backgroundBottomColor(const QColor &color); virtual const QColor& backgroundRadialColor(const QColor &color); virtual QPixmap verticalGradient(const QColor &color, int height, int offset = 0); virtual QPixmap radialGradient(const QColor &color, int width, int height = 64); void renderOxygenWindowBackground(QPainter *p, const QRect &clipRect, const QWidget *widget, const QWidget* window, const QColor& color, int y_shift=-23, int gradientHeight = 64); //!@name window background gradients //@{ /*! \par y_shift: shift the background gradient upwards, to fit with the windec \par gradientHeight: the height of the generated gradient. for different heights, the gradient is translated so that it is always at the same position from the bottom */ void renderWindowBackground(QPainter *p, const QRect &clipRect, const QWidget *widget, const QPalette & pal, int y_shift=-23, int gradientHeight = 64); void renderMenuBackground(QPainter* p, const QRect& clipRect, const QWidget* widget, const QPalette& pal); void renderMenuBackground(QPainter*, const QRect&, const QWidget*, const QColor&); //! draw frame that mimics some sort of shadows around a panel /*! it is used for menus, detached dock panels and toolbar, as well as window decoration when compositing is disabled */ // virtual void drawFloatFrame( // QPainter *p, const QRect r, const QColor &color, // bool drawUglyShadow=true, bool isActive=false, // const QColor &frameColor=QColor(), // TileSet::Tiles tiles = TileSet::Ring // ); typedef QCache PixmapCache; typedef QCache ColorCache; typedef QMap ColorMap; PixmapCache m_backgroundCache; ColorCache m_backgroundTopColorCache; ColorCache m_backgroundBottomColorCache; ColorCache m_backgroundRadialColorCache; ColorMap m_lowThreshold; ColorMap m_highThreshold; KSharedConfigPtr _config; qreal _contrast; qreal _bgcontrast; }; class KexiMenuWidgetPrivate // : public QWidgetPrivate { public: explicit KexiMenuWidgetPrivate(KexiMenuWidget *menu) : q(menu), itemsDirty(0), maxIconWidth(0), tabWidth(0), ncols(0), collapsibleSeparators(true), activationRecursionGuard(false), hasHadMouse(0), aboutToHide(0), motions(0), currentAction(0), scroll(0), eventLoop(0), /*tearoff(0),*/ /*tornoff(0),*/ /*tearoffHighlighted(0),*/ hasCheckableItems(0), sloppyAction(0), /* doChildEffects(false)*/ hasFrame(true), clickableLogoArea(0) { } virtual ~KexiMenuWidgetPrivate() { delete scroll; //! @todo KEXI3 port OxygenHelper #if 0 delete oxygenHelper; #endif } void init(); //static KexiMenuWidgetPrivate *get(KexiMenuWidgetPrivate *m) { return m->d_func(); } int scrollerHeight() const; KexiMenuWidget *q; //item calculations mutable int itemsDirty; mutable int maxIconWidth, tabWidth; QRect actionRect(QAction *) const; mutable QVector actionRects; mutable QHash widgetItems; void updateActionRects() const; QRect popupGeometry(const QWidget *widget) const; QRect popupGeometry(int screen = -1) const; mutable int ncols : 4; //4 bits is probably plenty bool collapsibleSeparators; bool activationRecursionGuard; //selection static KexiMenuWidget *mouseDown; QPoint mousePopupPos; int hasHadMouse; int aboutToHide; int motions; QAction *currentAction; QBasicTimer menuDelayTimer; QWidget *topCausedWidget() const; QAction *actionAt(QPoint p) const; void setFirstActionActive(); void setCurrentAction(QAction *, int popup = -1, KexiMenuWidget::SelectionReason reason = KexiMenuWidget::SelectedFromElsewhere, bool activateFirst = false); //void popupAction(QAction *, int, bool); void setSyncAction(); //scrolling support struct QMenuScroller { enum ScrollLocation { ScrollStay, ScrollBottom, ScrollTop, ScrollCenter }; enum ScrollDirection { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 }; uint scrollFlags : 2, scrollDirection : 2; int scrollOffset; QBasicTimer scrollTimer; QMenuScroller() : scrollFlags(ScrollNone), scrollDirection(ScrollNone), scrollOffset(0) { } ~QMenuScroller() { } } *scroll; void scrollMenu(QMenuScroller::ScrollLocation location, bool active=false); void scrollMenu(QMenuScroller::ScrollDirection direction, bool page=false, bool active=false); void scrollMenu(QAction *action, QMenuScroller::ScrollLocation location, bool active=false); //synchronous operation (ie exec()) QEventLoop *eventLoop; QPointer syncAction; //search buffer QString searchBuffer; QBasicTimer searchBufferTimer; //passing of mouse events up the parent hierarchy QPointer activeMenu; bool mouseEventTaken(QMouseEvent *); virtual QList > calcCausedStack() const; KexiMenuWidgetCaused causedPopup; void hideUpToMenuBar(); void hideMenu(KexiMenuWidget *menu, bool justRegister = false); //index mappings inline QAction *actionAt(int i) const { return q->actions().at(i); } inline int indexOf(QAction *act) const { return q->actions().indexOf(act); } //tear off support // uint tearoff : 1, tornoff : 1, tearoffHighlighted : 1; // QPointer tornPopup; mutable bool hasCheckableItems; //sloppy selection static int sloppyDelayTimer; mutable QAction *sloppyAction; QRegion sloppyRegion; //default action QPointer defaultAction; QAction *menuAction; QAction *defaultMenuAction; void setOverrideMenuAction(QAction *); void overrideMenuActionDestroyed(); //firing of events void activateAction(QAction *, QAction::ActionEvent, bool self=true); void activateCausedStack(const QList > &, QAction *, QAction::ActionEvent, bool); void actionTriggered(); void actionHovered(); bool hasMouseMoved(const QPoint &globalPos); void setLayoutDirection_helper(Qt::LayoutDirection direction); void updateLayoutDirection(); void setLayoutDirection_helper(QWidget* w, Qt::LayoutDirection direction); int frameWidth(const QStyleOption* opt = 0) const; bool actionPersistentlySelected(const QAction* action) const; void setActionPersistentlySelected(QAction* action, bool set); void toggleActionPersistentlySelected(QAction* action); //menu fading/scrolling effects //bool doChildEffects; QPointer actionAboutToTrigger; QPointer noReplayFor; //! Frame visibility bool hasFrame; QPointer previousPersistentlySelectedAction; //! True if persistent selections are enabled. False by default. //bool persistentSelectionsEnabled; //! @todo KEXI3 port OxygenHelper #if 0 OxygenHelper *oxygenHelper; #endif bool bespin; bool qtcurve; //! @return y coordinate of bottom margin of last menu item int bottomOfLastItem() const; int logoBottomMargin() const; void updateLogo(); void updateLogoPixmap(); QPixmap calligraLogoPixmap; ClickableLogoArea *clickableLogoArea; QWidget *socialWidget; QFont smallTextFont; }; #endif // KEXIMENUWIDGET_P_H diff --git a/src/main/KexiSearchLineEdit.cpp b/src/main/KexiSearchLineEdit.cpp index ce5c84e1c..0a2adc40d 100644 --- a/src/main/KexiSearchLineEdit.cpp +++ b/src/main/KexiSearchLineEdit.cpp @@ -1,883 +1,883 @@ /* This file is part of the KDE project Copyright (C) 2011-2016 Jarosław Staniek Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KexiSearchLineEdit.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class SearchableObject { public: KexiSearchableModel *model; int index; }; class KexiSearchLineEditCompleterPopupModel : public QAbstractListModel { Q_OBJECT public: explicit KexiSearchLineEditCompleterPopupModel(QObject *parent = 0); ~KexiSearchLineEditCompleterPopupModel(); - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; public Q_SLOTS: //! Adds a new model or updates information (model items) about existing one void addSearchableModel(KexiSearchableModel *model); //! Removes existing model void removeSearchableModel(KexiSearchableModel *model); private: class Private; Private * const d; }; class Q_DECL_HIDDEN KexiSearchLineEditCompleterPopupModel::Private { public: Private() : cachedCount(-1) { } ~Private() { qDeleteAll(searchableObjects); } void removeSearchableModel(KexiSearchableModel *model) { if (searchableModels.removeAll(model) == 0) { return; } QMutableMapIterator it(searchableObjects); while (it.hasNext()) { it.next(); if (it.value()->model == model) { it.remove(); } } } void updateCachedCount() { cachedCount = 0; foreach (KexiSearchableModel* searchableModel, searchableModels) { cachedCount += searchableModel->searchableObjectCount(); } } int cachedCount; QList searchableModels; QMap searchableObjects; }; KexiSearchLineEditCompleterPopupModel::KexiSearchLineEditCompleterPopupModel(QObject *parent) : QAbstractListModel(parent), d(new Private) { } KexiSearchLineEditCompleterPopupModel::~KexiSearchLineEditCompleterPopupModel() { delete d; } int KexiSearchLineEditCompleterPopupModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); if (d->cachedCount < 0) { d->updateCachedCount(); } return d->cachedCount; } QVariant KexiSearchLineEditCompleterPopupModel::data(const QModelIndex &index, int role) const { const int row = index.row(); if (d->cachedCount <= row) { return QVariant(); } SearchableObject *object = static_cast(index.internalPointer()); QModelIndex sourceIndex = object->model->sourceIndexForSearchableObject(object->index); return object->model->searchableData(sourceIndex, role); } QModelIndex KexiSearchLineEditCompleterPopupModel::index(int row, int column, const QModelIndex &parent) const { //qDebug() << row; if (!hasIndex(row, column, parent)) { qDebug() << "!hasIndex"; return QModelIndex(); } int r = row; SearchableObject *sobject = d->searchableObjects.value(row); if (!sobject) { foreach (KexiSearchableModel* searchableModel, d->searchableModels) { const int count = searchableModel->searchableObjectCount(); if (r < count) { sobject = new SearchableObject; sobject->model = searchableModel; sobject->index = r; d->searchableObjects.insert(row, sobject); break; } else { r -= count; } } } if (!sobject) { return QModelIndex(); } return createIndex(row, column, sobject); } void KexiSearchLineEditCompleterPopupModel::addSearchableModel(KexiSearchableModel *model) { if (!model) { return; } beginResetModel(); d->removeSearchableModel(model); d->searchableModels.append(model); connect(model->deleteNotifier(), &KexiSearchableModelDeleteNotifier::aboutToDelete, this, &KexiSearchLineEditCompleterPopupModel::removeSearchableModel, Qt::UniqueConnection); d->updateCachedCount(); endResetModel(); } void KexiSearchLineEditCompleterPopupModel::removeSearchableModel(KexiSearchableModel *model) { if (!model || !d->searchableModels.contains(model)) { return; } beginResetModel(); d->removeSearchableModel(model); d->updateCachedCount(); endResetModel(); } // ---- class KexiSearchLineEditCompleter : public KexiCompleter { Q_OBJECT public: explicit KexiSearchLineEditCompleter(QObject *parent = 0) : KexiCompleter(parent) { setCompletionRole(Qt::DisplayRole); } - virtual QString pathFromIndex(const QModelIndex &index) const { + virtual QString pathFromIndex(const QModelIndex &index) const override { if (!index.isValid()) return QString(); SearchableObject *object = static_cast(index.internalPointer()); QModelIndex sourceIndex = object->model->sourceIndexForSearchableObject(object->index); return object->model->pathFromIndex(sourceIndex); } }; // ---- class KexiSearchLineEditPopupItemDelegate; class Q_DECL_HIDDEN KexiSearchLineEdit::Private { public: explicit Private(KexiSearchLineEdit *_q) : q(_q), clearShortcut(QKeySequence(Qt::Key_Escape), _q), recentlyHighlightedModel(0) { // make Escape key clear the search box QObject::connect(&clearShortcut, SIGNAL(activated()), q, SLOT(slotClearShortcutActivated())); } void highlightSearchableObject(const QPair &source) { source.second->highlightSearchableObject(source.first); recentlyHighlightedModel = source.second; } void removeHighlightingForSearchableObject() { if (recentlyHighlightedModel) { recentlyHighlightedModel->highlightSearchableObject(QModelIndex()); recentlyHighlightedModel = 0; } } KexiSearchLineEditCompleter *completer; QTreeView *popupTreeView; KexiSearchLineEditCompleterPopupModel *model; KexiSearchLineEditPopupItemDelegate *delegate; QPointer previouslyFocusedWidget; private: KexiSearchLineEdit *q; QShortcut clearShortcut; KexiSearchableModel *recentlyHighlightedModel; }; // ---- static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) { qreal height = 0; qreal widthUsed = 0; textLayout.beginLayout(); while (true) { QTextLine line = textLayout.createLine(); if (!line.isValid()) break; line.setLineWidth(lineWidth); line.setPosition(QPointF(0, height)); height += line.height(); widthUsed = qMax(widthUsed, line.naturalTextWidth()); } textLayout.endLayout(); return QSizeF(widthUsed, height); } class KexiSearchLineEditPopupItemDelegate : public QStyledItemDelegate { Q_OBJECT public: KexiSearchLineEditPopupItemDelegate(QObject *parent, KexiCompleter *completer) : QStyledItemDelegate(parent), highlightMatchingSubstrings(true), m_completer(completer) { } //! Implemented to improve width hint - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override { QSize size(QStyledItemDelegate::sizeHint(option, index)); QStyleOptionViewItem v4 = option; QStyledItemDelegate::initStyleOption(&v4, index); const QSize s = v4.widget->style()->sizeFromContents(QStyle::CT_ItemViewItem, &v4, size, v4.widget); size.setWidth(s.width()); return size; } virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const + const QModelIndex &index) const override { QStyledItemDelegate::paint(painter, option, index); QStyleOptionViewItem v4 = option; QStyledItemDelegate::initStyleOption(&v4, index); // like in QCommonStyle::paint(): if (!v4.text.isEmpty()) { painter->save(); painter->setClipRect(v4.rect); QPalette::ColorGroup cg = v4.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(v4.state & QStyle::State_Active)) { cg = QPalette::Inactive; } if (v4.state & QStyle::State_Selected) { painter->setPen(v4.palette.color(cg, QPalette::HighlightedText)); } else { painter->setPen(v4.palette.color(cg, QPalette::Text)); } QRect textRect = v4.widget->style()->subElementRect(QStyle::SE_ItemViewItemText, &v4, v4.widget); viewItemDrawText(painter, &v4, textRect); painter->restore(); } } bool highlightMatchingSubstrings; protected: // bits from qcommonstyle.cpp void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const { const QWidget *widget = option->widget; const int textMargin = widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1; QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding const bool wrapText = option->features & QStyleOptionViewItem::WrapText; QTextOption textOption; textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap); textOption.setTextDirection(option->direction); textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment)); QTextLayout textLayout; textLayout.setTextOption(textOption); textLayout.setFont(option->font); QString text = option->text; textLayout.setText(text); if (highlightMatchingSubstrings) { QList formats; QString substring = m_completer->completionPrefix(); QColor underLineColor(p->pen().color()); underLineColor.setAlpha(128); QTextLayout::FormatRange formatRange; formatRange.format.setFontUnderline(true); formatRange.format.setUnderlineColor(underLineColor); for (int i = 0; i < text.length();) { i = text.indexOf(substring, i, Qt::CaseInsensitive); if (i == -1) break; formatRange.length = substring.length(); formatRange.start = i; formats.append(formatRange); i += formatRange.length; } textLayout.setAdditionalFormats(formats); } viewItemTextLayout(textLayout, textRect.width()); const int lineCount = textLayout.lineCount(); QPointF position = textRect.topLeft(); for (int i = 0; i < lineCount; ++i) { const QTextLine line = textLayout.lineAt(i); const QPointF adjustPos(0, qreal(textRect.height() - line.rect().height()) / 2.0); line.draw(p, position + adjustPos); position.setY(position.y() + line.y() + line.ascent()); } } - virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const + virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override { QStyledItemDelegate::initStyleOption(option, index); QStyleOptionViewItem *v4 = qstyleoption_cast(option); if (v4) { v4->text.clear(); } } KexiCompleter *m_completer; }; // ---- //! @internal Style-dependent fixes for the left margin, probably needed because of the limited //! width of the line edit - it's placed in tab bar's corner widget. static void fixLeftMargin(QLineEdit *lineEdit) { int add = 0; const QByteArray st(lineEdit->style()->objectName().toLatin1()); if (st == "breeze" || st == "gtk+") { add = 4; // like QLineEditIconButton::IconMargin } else if (st == "fusion") { add = 2; } if (add != 0) { QMargins margins(lineEdit->textMargins()); margins.setLeft(margins.left() + add); lineEdit->setTextMargins(margins); } } // ---- KexiSearchLineEdit::KexiSearchLineEdit(QWidget *parent) : QLineEdit(parent), d(new Private(this)) { d->completer = new KexiSearchLineEditCompleter(this); d->popupTreeView = new QTreeView; kexiTester() << KexiTestObject(d->popupTreeView, "globalSearch.treeView"); d->completer->setPopup(d->popupTreeView); d->completer->setModel(d->model = new KexiSearchLineEditCompleterPopupModel(d->completer)); d->completer->setCaseSensitivity(Qt::CaseInsensitive); d->completer->setSubstringCompletion(true); d->completer->setMaxVisibleItems(12); // Use unsorted model, sorting is handled in the source model itself. // Moreover, sorting KexiCompleter::CaseInsensitivelySortedModel breaks // filtering so only table names are displayed. d->completer->setModelSorting(KexiCompleter::UnsortedModel); d->popupTreeView->setHeaderHidden(true); d->popupTreeView->setRootIsDecorated(false); d->popupTreeView->setItemDelegate( d->delegate = new KexiSearchLineEditPopupItemDelegate(d->popupTreeView, d->completer)); // forked initialization like in QLineEdit::setCompleter: d->completer->setWidget(this); if (hasFocus()) { connectCompleter(); } setFocusPolicy(Qt::NoFocus); // We cannot focus set any policy here. // Qt::ClickFocus would make it impossible to find // previously focus widget in KexiSearchLineEdit::setFocus(). // We need this information to focus back when pressing Escape key. setClearButtonEnabled(true); setPlaceholderText(xi18n("Search")); fixLeftMargin(this); } KexiSearchLineEdit::~KexiSearchLineEdit() { delete d; } void KexiSearchLineEdit::connectCompleter() { connect(d->completer, SIGNAL(activated(QString)), this, SLOT(setText(QString))); connect(d->completer, SIGNAL(activated(QModelIndex)), this, SLOT(slotCompletionActivated(QModelIndex))); connect(d->completer, SIGNAL(highlighted(QString)), this, SLOT(slotCompletionHighlighted(QString))); connect(d->completer, SIGNAL(highlighted(QModelIndex)), this, SLOT(slotCompletionHighlighted(QModelIndex))); } void KexiSearchLineEdit::disconnectCompleter() { disconnect(d->completer, 0, this, 0); } void KexiSearchLineEdit::slotClearShortcutActivated() { //qDebug() << (QWidget*)d->previouslyFocusedWidget << text(); d->removeHighlightingForSearchableObject(); if (text().isEmpty() && d->previouslyFocusedWidget) { // after second Escape, go back to previously focused widget d->previouslyFocusedWidget->setFocus(); d->previouslyFocusedWidget = 0; } else { clear(); } } void KexiSearchLineEdit::addSearchableModel(KexiSearchableModel *model) { d->model->addSearchableModel(model); } void KexiSearchLineEdit::removeSearchableModel(KexiSearchableModel *model) { d->model->removeSearchableModel(model); } QPair KexiSearchLineEdit::mapCompletionIndexToSource(const QModelIndex &index) const { QModelIndex realIndex = qobject_cast(d->completer->completionModel())->mapToSource(index); if (!realIndex.isValid()) { return qMakePair(QModelIndex(), static_cast(0)); } SearchableObject *object = static_cast(realIndex.internalPointer()); if (!object) { return qMakePair(QModelIndex(), static_cast(0)); } return qMakePair(object->model->sourceIndexForSearchableObject(object->index), object->model); } void KexiSearchLineEdit::slotCompletionHighlighted(const QString &newText) { if (d->completer->completionMode() != KexiCompleter::InlineCompletion) { setText(newText); } else { int p = cursorPosition(); QString t = text(); setText(t.left(p) + newText.mid(p)); end(false); cursorBackward(text().length() - p, true); } } void KexiSearchLineEdit::slotCompletionHighlighted(const QModelIndex &index) { QPair source = mapCompletionIndexToSource(index); if (!source.first.isValid()) return; //qDebug() << source.second->searchableData(source.first, Qt::EditRole); d->highlightSearchableObject(source); } void KexiSearchLineEdit::slotCompletionActivated(const QModelIndex &index) { QPair source = mapCompletionIndexToSource(index); if (!source.first.isValid()) return; //qDebug() << source.second->searchableData(source.first, Qt::EditRole); d->highlightSearchableObject(source); d->removeHighlightingForSearchableObject(); if (source.second->activateSearchableObject(source.first)) { clear(); } } // forked bits from QLineEdit::inputMethodEvent() void KexiSearchLineEdit::inputMethodEvent(QInputMethodEvent *e) { QLineEdit::inputMethodEvent(e); if (isReadOnly() || !e->isAccepted()) return; if (!e->commitString().isEmpty()) { complete(Qt::Key_unknown); } } void KexiSearchLineEdit::setFocus() { //qDebug() << "d->previouslyFocusedWidget:" << (QWidget*)d->previouslyFocusedWidget // << "window()->focusWidget():" << window()->focusWidget(); if (!d->previouslyFocusedWidget && window()->focusWidget() != this) { d->previouslyFocusedWidget = window()->focusWidget(); } QLineEdit::setFocus(); } // forked bits from QLineEdit::focusInEvent() void KexiSearchLineEdit::focusInEvent(QFocusEvent *e) { //qDebug() << "d->previouslyFocusedWidget:" << (QWidget*)d->previouslyFocusedWidget // << "window()->focusWidget():" << window()->focusWidget(); if (!d->previouslyFocusedWidget && window()->focusWidget() != this) { d->previouslyFocusedWidget = window()->focusWidget(); } QLineEdit::focusInEvent(e); d->completer->setWidget(this); connectCompleter(); update(); } // forked bits from QLineEdit::focusOutEvent() void KexiSearchLineEdit::focusOutEvent(QFocusEvent *e) { QLineEdit::focusOutEvent(e); disconnectCompleter(); update(); if (e->reason() == Qt::TabFocusReason || e->reason() == Qt::BacktabFocusReason) { // go back to previously focused widget if (d->previouslyFocusedWidget) { d->previouslyFocusedWidget->setFocus(); } e->accept(); } d->previouslyFocusedWidget = 0; d->removeHighlightingForSearchableObject(); } // forked bits from QLineControl::processKeyEvent() void KexiSearchLineEdit::keyPressEvent(QKeyEvent *event) { bool inlineCompletionAccepted = false; //qDebug() << event->key() << (QWidget*)d->previouslyFocusedWidget; KexiCompleter::CompletionMode completionMode = d->completer->completionMode(); if ((completionMode == KexiCompleter::PopupCompletion || completionMode == KexiCompleter::UnfilteredPopupCompletion) && d->completer->popup() && d->completer->popup()->isVisible()) { // The following keys are forwarded by the completer to the widget // Ignoring the events lets the completer provide suitable default behavior switch (event->key()) { case Qt::Key_Escape: event->ignore(); return; #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: if (!QApplication::keypadNavigationEnabled()) break; d->completer->popup()->hide(); // just hide. will end up propagating to parent #endif default: break; // normal key processing } } else if (completionMode == KexiCompleter::InlineCompletion) { switch (event->key()) { case Qt::Key_Enter: case Qt::Key_Return: case Qt::Key_F4: #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: if (!QApplication::keypadNavigationEnabled()) break; #endif if (!d->completer->currentCompletion().isEmpty() && hasSelectedText() && textAfterSelection().isEmpty()) { setText(d->completer->currentCompletion()); inlineCompletionAccepted = true; } default: break; // normal key processing } } if (d->completer->popup() && !d->completer->popup()->isVisible() && (event->key() == Qt::Key_F4 || event->key() == Qt::Key_Down)) { // go back to completing when popup is closed and F4/Down pressed d->completer->complete(); } else if (d->completer->popup() && d->completer->popup()->isVisible() && event->key() == Qt::Key_F4) { // hide popup if F4 pressed d->completer->popup()->hide(); } if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { if (d->completer->popup() && !d->completer->popup()->isVisible()) { d->completer->setCompletionPrefix(text()); } if (d->completer->completionCount() == 1) { // single item on the completion list, select it automatically d->completer->setCurrentRow(0); slotCompletionActivated(d->completer->currentIndex()); event->accept(); if (d->completer->popup()) { d->completer->popup()->hide(); } return; } //qDebug() << "currentRow:" << d->completer->currentRow(); //qDebug() << "currentIndex:" << d->completer->currentIndex().isValid(); //qDebug() << "currentCompletion:" << d->completer->currentCompletion(); if (d->completer->popup() && d->completer->completionCount() > 1) { //qDebug() << "11111" << d->completer->completionPrefix() // << d->completer->completionCount(); // more than one item on completion list, find exact match, if found, accept for (int i = 0; i < d->completer->completionCount(); i++) { //qDebug() << d->completer->completionModel()->index(i, 0, QModelIndex()).data(Qt::EditRole).toString(); if (d->completer->completionPrefix() == d->completer->completionModel()->index(i, 0, QModelIndex()).data(Qt::EditRole).toString()) { d->completer->setCurrentRow(i); slotCompletionActivated(d->completer->currentIndex()); event->accept(); d->completer->popup()->hide(); return; } } // exactly matching item not found bool selectedItem = !d->completer->popup()->selectionModel()->selectedIndexes().isEmpty(); if (!selectedItem || !d->completer->popup()->isVisible()) { if (!d->completer->popup()->isVisible()) { // there is no matching text, go back to completing d->completer->complete(); } // do not hide event->accept(); return; } } // applying completion since there is item selected d->completer->popup()->hide(); connectCompleter(); QLineEdit::keyPressEvent(event); /* executes this: if (hasAcceptableInput() || fixup()) { emit returnPressed(); emit editingFinished(); } */ if (inlineCompletionAccepted) event->accept(); else event->ignore(); return; } if (event == QKeySequence::MoveToNextChar) { #if defined(Q_OS_WIN) if (hasSelectedText() && d->completer->completionMode() == KexiCompleter::InlineCompletion) { int selEnd = selectionEnd(); if (selEnd >= 0) { setCursorPosition(selEnd); } event->accept(); return; } #endif } else if (event == QKeySequence::MoveToPreviousChar) { #if defined(Q_OS_WIN) if (hasSelectedText() && d->completer->completionMode() == KexiCompleter::InlineCompletion) { int selStart = selectionStart(); if (selStart >= 0) { setCursorPosition(selStart); } event->accept(); return; } #endif } else { if (event->modifiers() & Qt::ControlModifier) { switch (event->key()) { case Qt::Key_Up: case Qt::Key_Down: complete(event->key()); return; default:; } } else { // ### check for *no* modifier switch (event->key()) { case Qt::Key_Backspace: if (!isReadOnly()) { backspace(); complete(Qt::Key_Backspace); return; } break; case Qt::Key_Delete: if (!isReadOnly()) { QLineEdit::keyPressEvent(event); complete(Qt::Key_Delete); return; } break; default:; } } } if (!isReadOnly()) { QString t = event->text(); if (!t.isEmpty() && t.at(0).isPrint()) { QLineEdit::keyPressEvent(event); complete(event->key()); return; } } QLineEdit::keyPressEvent(event); } void KexiSearchLineEdit::changeEvent(QEvent *event) { QLineEdit::changeEvent(event); if (event->type() == QEvent::StyleChange) { fixLeftMargin(this); } } // forked bits from QLineControl::advanceToEnabledItem() // iterating forward(dir=1)/backward(dir=-1) from the // current row based. dir=0 indicates a new completion prefix was set. bool KexiSearchLineEdit::advanceToEnabledItem(int dir) { int start = d->completer->currentRow(); if (start == -1) return false; int i = start + dir; if (dir == 0) dir = 1; do { if (!d->completer->setCurrentRow(i)) { if (!d->completer->wrapAround()) break; i = i > 0 ? 0 : d->completer->completionCount() - 1; } else { QModelIndex currentIndex = d->completer->currentIndex(); if (d->completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled) return true; i += dir; } } while (i != start); d->completer->setCurrentRow(start); // restore return false; } QString KexiSearchLineEdit::textBeforeSelection() const { return hasSelectedText() ? text().left(selectionStart()) : QString(); } QString KexiSearchLineEdit::textAfterSelection() const { return hasSelectedText() ? text().mid(selectionEnd()) : QString(); } int KexiSearchLineEdit::selectionEnd() const { return hasSelectedText() ? (selectionStart() + selectedText().length()) : -1; } // forked bits from QLineControl::complete() void KexiSearchLineEdit::complete(int key) { if (isReadOnly() || echoMode() != QLineEdit::Normal) return; QString text = this->text(); if (d->completer->completionMode() == KexiCompleter::InlineCompletion) { if (key == Qt::Key_Backspace) return; int n = 0; if (key == Qt::Key_Up || key == Qt::Key_Down) { if (textAfterSelection().length()) return; QString prefix = hasSelectedText() ? textBeforeSelection() : text; if (text.compare(d->completer->currentCompletion(), d->completer->caseSensitivity()) != 0 || prefix.compare(d->completer->completionPrefix(), d->completer->caseSensitivity()) != 0) { d->completer->setCompletionPrefix(prefix); } else { n = (key == Qt::Key_Up) ? -1 : +1; } } else { d->completer->setCompletionPrefix(text); } if (!advanceToEnabledItem(n)) return; } else { #ifndef QT_KEYPAD_NAVIGATION if (text.isEmpty()) { d->completer->popup()->hide(); return; } #endif d->completer->setCompletionPrefix(text); } d->popupTreeView->resizeColumnToContents(0); d->completer->complete(); } bool KexiSearchLineEdit::highlightMatchingSubstrings() const { return d->delegate->highlightMatchingSubstrings; } void KexiSearchLineEdit::setHighlightMatchingSubstrings(bool highlight) { d->delegate->highlightMatchingSubstrings = highlight; } #include "KexiSearchLineEdit.moc" diff --git a/src/main/KexiSearchLineEdit.h b/src/main/KexiSearchLineEdit.h index 574590972..0881ddc58 100644 --- a/src/main/KexiSearchLineEdit.h +++ b/src/main/KexiSearchLineEdit.h @@ -1,93 +1,93 @@ /* This file is part of the KDE project Copyright (C) 2011-2015 Jarosław Staniek Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXISEARCHLINEEDIT_H #define KEXISEARCHLINEEDIT_H #include #include #include #include class KexiSearchableModel; //! @short Search line edit with advanced autocompletion /*! It works like QLineEdit with QCompleter but uses fork of QCompleter for full-text-search. @note Qt Embedded features of QLineEdit+QCompleter (i.e. those marked with ifdef QT_KEYPAD_NAVIGATION) are not ported. */ class KexiSearchLineEdit : public QLineEdit { Q_OBJECT Q_PROPERTY(bool highlightMatchingSubstrings READ highlightMatchingSubstrings WRITE setHighlightMatchingSubstrings) public: explicit KexiSearchLineEdit(QWidget *parent = 0); virtual ~KexiSearchLineEdit(); /*! Add searchable model to the main window. This extends search to a new area. One example is Project Navigator. */ void addSearchableModel(KexiSearchableModel *model); /*! Removes searchable model from the main window. @a model is not deleted. */ void removeSearchableModel(KexiSearchableModel *model); /*! @return true if matching substrings are highlighted in completion list. @see setHighlightMatchingSubstrings() */ bool highlightMatchingSubstrings() const; /*! If @a highlight is true makes matching substrings are highlighted in completion list. By default highlighting is on. @see highlightMatchingSubstrings() */ void setHighlightMatchingSubstrings(bool highlight); public Q_SLOTS: void setFocus(); private Q_SLOTS: void slotCompletionHighlighted(const QString &newText); void slotCompletionHighlighted(const QModelIndex &index); void slotCompletionActivated(const QModelIndex &index); void slotClearShortcutActivated(); protected: - virtual void inputMethodEvent(QInputMethodEvent *e); - virtual void focusInEvent(QFocusEvent *e); - virtual void focusOutEvent(QFocusEvent *e); - virtual void keyPressEvent(QKeyEvent *e); - virtual void changeEvent(QEvent *event); + virtual void inputMethodEvent(QInputMethodEvent *e) override; + virtual void focusInEvent(QFocusEvent *e) override; + virtual void focusOutEvent(QFocusEvent *e) override; + virtual void keyPressEvent(QKeyEvent *e) override; + virtual void changeEvent(QEvent *event) override; private: void connectCompleter(); void disconnectCompleter(); bool advanceToEnabledItem(int dir); void complete(int key); QString textBeforeSelection() const; QString textAfterSelection() const; int selectionEnd() const; QPair mapCompletionIndexToSource(const QModelIndex &index) const; class Private; Private * const d; }; #endif diff --git a/src/main/startup/KexiAssistantMessageHandler.h b/src/main/startup/KexiAssistantMessageHandler.h index 30f5153c1..30c396447 100644 --- a/src/main/startup/KexiAssistantMessageHandler.h +++ b/src/main/startup/KexiAssistantMessageHandler.h @@ -1,67 +1,67 @@ /* This file is part of the KDE project Copyright (C) 2012-2013 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIASSISTANTMESSAGEHANDLER_H #define KEXIASSISTANTMESSAGEHANDLER_H #include #include class KDbObject; class KexiContextMessageWidget; class KexiAssistantMessageHandler : public KDbMessageHandler { public: KexiAssistantMessageHandler(); ~KexiAssistantMessageHandler(); protected: //! Shows error message with @a title (it is not caption) and details. //! Implementation for KDbMessageHandler. virtual void showErrorMessage( KDbMessageHandler::MessageType messageType, const QString &message, const QString &details = QString(), const QString &caption = QString() - ); + ) override; /*! Shows error message with @a msg text. Existing error message from @a obj object is also copied, if present. */ //! Implementation for KDbMessageHandler. virtual void showErrorMessage( const KDbResult& result, KDbMessageHandler::MessageType messageType = Error, const QString& message = QString(), const QString& caption = QString() - ); + ) override; virtual const QWidget* calloutWidget() const = 0; virtual QPoint calloutPointerPosition() const; virtual KMessageWidget::CalloutPointerDirection calloutPointerDirection() const; KexiContextMessageWidget* messageWidget(); private: class Private; Private * const d; }; #endif // KEXIASSISTANTMESSAGEHANDLER_H diff --git a/src/main/startup/KexiImportExportAssistant.h b/src/main/startup/KexiImportExportAssistant.h index e2c6e8c74..22b8e9f70 100644 --- a/src/main/startup/KexiImportExportAssistant.h +++ b/src/main/startup/KexiImportExportAssistant.h @@ -1,67 +1,67 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIIMPORTEXPORTASSISTANT_H #define KEXIIMPORTEXPORTASSISTANT_H #include #include #include "ui_KexiMainImportExportPage.h" class QAction; class KexiImportExportAssistant; class KexiMainImportExportPage : public KexiAssistantPage, public Ui::KexiMainImportExportPage { Q_OBJECT public: explicit KexiMainImportExportPage(KexiImportExportAssistant *assistant, QWidget* parent = 0); ~KexiMainImportExportPage(); }; class KexiImportExportAssistant : public KexiAssistantWidget { Q_OBJECT public: KexiImportExportAssistant( const QAction *action_project_import_export_send_, const QAction *action_import_project_, QWidget* parent = 0); virtual ~KexiImportExportAssistant(); const QAction *action_project_import_export_send; const QAction *action_import_project; public Q_SLOTS: - virtual void nextPageRequested(KexiAssistantPage* page); - virtual void cancelRequested(KexiAssistantPage* page); + virtual void nextPageRequested(KexiAssistantPage* page) override; + virtual void cancelRequested(KexiAssistantPage* page) override; Q_SIGNALS: void importProject(); private: class Private; Private* const d; }; #endif diff --git a/src/main/startup/KexiNewProjectAssistant.h b/src/main/startup/KexiNewProjectAssistant.h index 6d554f69c..08120c7c0 100644 --- a/src/main/startup/KexiNewProjectAssistant.h +++ b/src/main/startup/KexiNewProjectAssistant.h @@ -1,201 +1,201 @@ /* This file is part of the KDE project Copyright (C) 2003-2018 Jarosław Staniek Copyright (C) 2012 Dimitrios T. Tanis Copyright (C) 2014 Roman Shtemberko This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXINEWPROJECTASSISTANT_H #define KEXINEWPROJECTASSISTANT_H #include "KexiAssistantMessageHandler.h" #include "ui_KexiProjectStorageTypeSelectionPage.h" #include #include #include #include #include #include #include #include #include #include class KexiConnectionSelectorWidget; class KexiProjectSelectorWidget; class KexiTemplateSelectionPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiTemplateSelectionPage(QWidget* parent = 0); QString selectedTemplate; QString selectedCategory; protected Q_SLOTS: void slotItemClicked(const QModelIndex& index); private: KexiCategorizedView* m_templatesList; }; class KexiProjectStorageTypeSelectionPage : public KexiAssistantPage, public Ui::KexiProjectStorageTypeSelectionPage { Q_OBJECT public: explicit KexiProjectStorageTypeSelectionPage(QWidget* parent = 0); virtual ~KexiProjectStorageTypeSelectionPage(); enum class Type { None, //!< No type selected File, Server }; /** * Returns selected connection type * * Selection depends on button that is focused. */ Type selectedType() const; private Q_SLOTS: void buttonClicked(); }; class KexiDBCaptionPage; class KexiStartupFileHandler; class KexiProjectCaptionSelectionPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiProjectCaptionSelectionPage(QWidget* parent = nullptr); virtual ~KexiProjectCaptionSelectionPage(); bool isAcceptable(); KexiDBCaptionPage* contents; KexiStartupFileHandler *fileHandler; QPointer messageWidget; private Q_SLOTS: void captionTextChanged(const QString &text); void askForOverwriting(const KexiContextMessage& message); private: void updateUrl(); }; class QProgressBar; class KexiProjectCreationPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiProjectCreationPage(QWidget* parent = 0); virtual ~KexiProjectCreationPage(); QProgressBar* m_progressBar; }; class KexiProjectConnectionSelectionPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiProjectConnectionSelectionPage(QWidget* parent = 0); virtual ~KexiProjectConnectionSelectionPage(); KexiConnectionSelectorWidget* connSelector; private: QPointer m_errorMessagePopup; }; class KexiServerDBNamePage; class KexiGUIMessageHandler; class KexiProjectData; class KexiProjectSet; class KexiProjectSelectorWidget; class KexiNewProjectAssistant; class KexiProjectDatabaseNameSelectionPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiProjectDatabaseNameSelectionPage( KexiNewProjectAssistant* parent); virtual ~KexiProjectDatabaseNameSelectionPage(); bool setConnection(KDbConnectionData* data); KexiServerDBNamePage* contents; //! @todo KEXI3 use equivalent of QPointer KDbConnectionData* conndataToShow; QPointer messageWidget; bool isAcceptable(); private Q_SLOTS: void slotCaptionChanged(const QString &capt); void slotNameChanged(const QString &); void overwriteActionTriggered(); private: QString enteredDbName() const; KexiNewProjectAssistant* m_assistant; KexiProjectSet *m_projectSetToShow; KexiProjectSelectorWidget* m_projectSelector; bool m_dbNameAutofill; bool m_le_dbname_txtchanged_enabled; KexiProjectData* m_projectDataToOverwrite; QAction* m_messageWidgetActionYes; QAction* m_messageWidgetActionNo; }; class KexiProjectData; class KexiNewProjectAssistant : public KexiAssistantWidget, public KexiAssistantMessageHandler, public KDbResultable { Q_OBJECT public: explicit KexiNewProjectAssistant(QWidget* parent = 0); ~KexiNewProjectAssistant(); public Q_SLOTS: - virtual void nextPageRequested(KexiAssistantPage* page); - virtual void cancelRequested(KexiAssistantPage* page); + virtual void nextPageRequested(KexiAssistantPage* page) override; + virtual void cancelRequested(KexiAssistantPage* page) override; void tryAgainActionTriggered(); void cancelActionTriggered(); Q_SIGNALS: void createProject(const KexiProjectData &data); protected: - virtual const QWidget* calloutWidget() const; + virtual const QWidget* calloutWidget() const override; private: void createProject( const KDbConnectionData& cdata, const QString& databaseName, const QString& caption); class Private; Private* const d; }; #endif diff --git a/src/main/startup/KexiOpenProjectAssistant.h b/src/main/startup/KexiOpenProjectAssistant.h index 6704e1438..b309de3ba 100644 --- a/src/main/startup/KexiOpenProjectAssistant.h +++ b/src/main/startup/KexiOpenProjectAssistant.h @@ -1,107 +1,107 @@ /* This file is part of the KDE project Copyright (C) 2011-2013 Jarosław Staniek Copyright (C) 2012 Dimitrios T. Tanis This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIOPENPROJECTASSISTANT_H #define KEXIOPENPROJECTASSISTANT_H #include "KexiAssistantMessageHandler.h" #include #include #include #include #include #include #include class QTabWidget; class KexiProjectData; class KexiConnectionSelectorWidget; class KexiProjectSelectorWidget; class KexiOpenProjectAssistant; //! A page displaying file projects and connections for server projects class KexiMainOpenProjectPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiMainOpenProjectPage(QWidget* parent = 0); ~KexiMainOpenProjectPage(); QTabWidget* tabWidget; KexiConnectionSelectorWidget* fileSelector; KexiConnectionSelectorWidget* connSelector; private Q_SLOTS: void init(); void tabChanged(int index); private: QWidget* m_fileSelectorWidget; QWidget* m_connSelectorWidget; QPointer m_errorMessagePopup; }; //! A page for selecting existing server database project class KexiProjectDatabaseSelectionPage : public KexiAssistantPage { Q_OBJECT public: explicit KexiProjectDatabaseSelectionPage(KexiOpenProjectAssistant* parent); ~KexiProjectDatabaseSelectionPage(); bool setConnection(KDbConnectionData* data); KexiProjectSelectorWidget* projectSelector; //! @todo KEXI3 use equivalent of QPointer KDbConnectionData* conndataToShow; private: KexiOpenProjectAssistant* m_assistant; }; class KexiOpenProjectAssistant : public KexiAssistantWidget, public KexiAssistantMessageHandler { Q_OBJECT public: explicit KexiOpenProjectAssistant(QWidget* parent = 0); ~KexiOpenProjectAssistant(); public Q_SLOTS: - virtual void nextPageRequested(KexiAssistantPage* page); - virtual void cancelRequested(KexiAssistantPage* page); + virtual void nextPageRequested(KexiAssistantPage* page) override; + virtual void cancelRequested(KexiAssistantPage* page) override; void tryAgainActionTriggered(); void cancelActionTriggered(); Q_SIGNALS: void openProject(const KexiProjectData& data); void openProject(const QString& fileName); private Q_SLOTS: void slotOpenProject(KexiProjectData* data); protected: - virtual const QWidget* calloutWidget() const; + virtual const QWidget* calloutWidget() const override; private: class Private; Private* const d; }; #endif diff --git a/src/main/startup/KexiRecentProjectsModel.h b/src/main/startup/KexiRecentProjectsModel.h index 553c45ddd..c178cc2cf 100644 --- a/src/main/startup/KexiRecentProjectsModel.h +++ b/src/main/startup/KexiRecentProjectsModel.h @@ -1,60 +1,60 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIRECENTPROJECTSMODEL_H #define KEXIRECENTPROJECTSMODEL_H #include #include class KexiRecentProjects; class KexiRecentProjectsModel : public QAbstractListModel { Q_OBJECT public: enum AdditionalRoles { NameRole = Qt::UserRole, CategoryRole = Qt::UserRole + 1 }; explicit KexiRecentProjectsModel(const KexiRecentProjects& projects, QObject *parent = 0); QModelIndex index(int row, int column = 0, - const QModelIndex& parent = QModelIndex() ) const; - int rowCount(const QModelIndex& parent = QModelIndex()) const; - QVariant data(const QModelIndex& index, int role) const; - Qt::ItemFlags flags( const QModelIndex& index ) const; + const QModelIndex& parent = QModelIndex() ) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role) const override; + Qt::ItemFlags flags( const QModelIndex& index ) const override; private: const KexiRecentProjects* m_projects; }; class KexiRecentProjectsProxyModel : public KCategorizedSortFilterProxyModel { Q_OBJECT public: explicit KexiRecentProjectsProxyModel(QObject *parent = 0); protected: - virtual bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const; + virtual bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const override; }; #endif diff --git a/src/main/startup/KexiTemplatesModel.h b/src/main/startup/KexiTemplatesModel.h index 75a9c5b7d..944e8baef 100644 --- a/src/main/startup/KexiTemplatesModel.h +++ b/src/main/startup/KexiTemplatesModel.h @@ -1,60 +1,60 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITEMPLATESMODEL_H #define KEXITEMPLATESMODEL_H #include #include #include class KexiTemplatesModel : public QAbstractListModel { Q_OBJECT public: enum AdditionalRoles { NameRole = Qt::UserRole, CategoryRole = Qt::UserRole + 1 }; explicit KexiTemplatesModel(const KexiTemplateCategoryInfoList& templateCategories, QObject *parent = 0); ~KexiTemplatesModel(); QModelIndex index(int row, int column = 0, - const QModelIndex& parent = QModelIndex() ) const; - int rowCount(const QModelIndex& parent = QModelIndex()) const; - QVariant data(const QModelIndex& index, int role) const; - Qt::ItemFlags flags( const QModelIndex& index ) const; + const QModelIndex& parent = QModelIndex() ) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role) const override; + Qt::ItemFlags flags( const QModelIndex& index ) const override; private: class Private; Private* const d; }; class KexiTemplatesProxyModel : public KCategorizedSortFilterProxyModel { Q_OBJECT public: explicit KexiTemplatesProxyModel(QObject *parent = 0); }; #endif diff --git a/src/main/startup/KexiWelcomeAssistant.h b/src/main/startup/KexiWelcomeAssistant.h index 2dd02296a..34edbfe70 100644 --- a/src/main/startup/KexiWelcomeAssistant.h +++ b/src/main/startup/KexiWelcomeAssistant.h @@ -1,112 +1,112 @@ /* This file is part of the KDE project Copyright (C) 2011-2013 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIWELCOMEASSISTANT_H #define KEXIWELCOMEASSISTANT_H #include "KexiAssistantMessageHandler.h" #include #include #include #include #include class KexiProjectData; class KexiWelcomeAssistant; class KexiRecentProjectsProxyModel; class KexiWelcomeStatusBar; class KexiMainWindow; class KexiMainWelcomePage : public KexiAssistantPage { Q_OBJECT public: explicit KexiMainWelcomePage(KexiWelcomeAssistant* assistant, QWidget* parent = 0); QString selectedTemplate; QString selectedCategory; void updateRecentProjects(); inline KexiCategorizedView* recentProjectsView() const { return m_recentProjects; } inline QModelIndex clickedItem() const { return m_clickedIndex; } public Q_SLOTS: void slotItemClicked(const QModelIndex& index); Q_SIGNALS: void openProject(const KexiProjectData& data, const QString& shortcutPath, bool *opened); private Q_SLOTS: void loadProjects(); private: KexiCategorizedView* m_recentProjects; KexiRecentProjectsProxyModel* m_recentProjectsProxyModel; KexiWelcomeAssistant* m_assistant; KexiWelcomeStatusBar* m_statusBar; QModelIndex m_clickedIndex; }; class KexiProjectData; class KexiRecentProjects; class KexiWelcomeAssistant : public KexiAssistantWidget, public KexiAssistantMessageHandler { Q_OBJECT public: explicit KexiWelcomeAssistant(KexiRecentProjects* projects, KexiMainWindow* parent = 0); ~KexiWelcomeAssistant(); KexiRecentProjects* projects(); public Q_SLOTS: - virtual void nextPageRequested(KexiAssistantPage* page); - virtual void cancelRequested(KexiAssistantPage* page); + virtual void nextPageRequested(KexiAssistantPage* page) override; + virtual void cancelRequested(KexiAssistantPage* page) override; void tryAgainActionTriggered(); void cancelActionTriggered(); Q_SIGNALS: /*! Emitted if project @a data was selected to open. @a shortcutPath can be non empty to indicate .kexis filename useful for opening new instance of Kexi. Receiver should set value pointed by @a opened to true if the database has been opened successfully. */ void openProject(const KexiProjectData &data, const QString &shortcutPath, bool *opened); protected: void openProjectOrShowPasswordPage(KexiProjectData *data); void emitOpenProject(KexiProjectData *data); - virtual const QWidget* calloutWidget() const; - virtual QPoint calloutPointerPosition() const; - virtual KMessageWidget::CalloutPointerDirection calloutPointerDirection() const; + virtual const QWidget* calloutWidget() const override; + virtual QPoint calloutPointerPosition() const override; + virtual KMessageWidget::CalloutPointerDirection calloutPointerDirection() const override; private: void createProject( const KDbConnectionData& cdata, const QString& databaseName, const QString& caption); friend class KexiMainWelcomePage; class Private; Private* const d; }; #endif diff --git a/src/main/startup/KexiWelcomeStatusBar.cpp b/src/main/startup/KexiWelcomeStatusBar.cpp index ad34cee32..c8f5bd246 100644 --- a/src/main/startup/KexiWelcomeStatusBar.cpp +++ b/src/main/startup/KexiWelcomeStatusBar.cpp @@ -1,782 +1,782 @@ /* This file is part of the KDE project Copyright (C) 2011-2012 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KexiWelcomeStatusBar.h" #include "KexiWelcomeStatusBar_p.h" #include #include #include #include #include #include "KexiUserFeedbackAgent.h" #define KEXI_SKIP_SETUPPRIVATEICONSRESOURCE #define KEXI_SKIP_SETUPBREEZEICONTHEME #define KEXI_SKIP_REGISTERICONSRESOURCE #define KEXI_SKIP_REGISTERRESOURCE #include "KexiRegisterResource_p.h" #include #include #include #include #include #include #include #include #if defined(Q_OS_WIN) || defined(Q_OS_MACOS) # include # include # include # include #else # define USE_KIO_COPY # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QNetworkReply; class KJob; static const int GUI_UPDATE_INTERVAL = 60; // update interval for GUI, in minutes static const int DONATION_INTERVAL = 10; // donation interval, in days static const int UPDATE_FILES_LIST_SIZE_LIMIT = 1024 * 128; static const int UPDATE_FILES_COUNT_LIMIT = 128; //! @return x.y.0 static QString stableVersionStringDot0() { return QString::number(Kexi::stableVersionMajor()) + '.' + QString::number(Kexi::stableVersionMinor()) + ".0"; } static QString uiPath(const QString &fname) { KexiUserFeedbackAgent *f = KexiMainWindowIface::global()->userFeedbackAgent(); return f->serviceUrl() + QString("/ui/%1/").arg(stableVersionStringDot0()) + fname; } static QString basePath() { return QString(KEXI_BASE_PATH "/status"); } static QString findFileName(const QString &guiFileName) { QStringList triedLocations; QString result = locateFile(QString(), basePath() + '/' + guiFileName, QStandardPaths::GenericDataLocation, QString(), &triedLocations); if (result.isEmpty()) { // last chance: file from the source tree result = QFileInfo(QFile::decodeName(CMAKE_CURRENT_SOURCE_DIR "/status/") + guiFileName) .canonicalFilePath(); } //qDebug() << result; return result; } // --- class Q_DECL_HIDDEN KexiWelcomeStatusBarGuiUpdater::Private : public QObject { Q_OBJECT public: Private() : configGroup(KConfigGroup(KSharedConfig::openConfig()->group("User Feedback"))) { } KConfigGroup configGroup; public Q_SLOTS: void sendRequestListFilesFinished(KJob* job) { if (job->error()) { qWarning() << "Error while receiving .list file - no files will be updated"; //! @todo error... return; } KIO::StoredTransferJob* sendJob = qobject_cast(job); QString result = sendJob->data(); if (result.length() > UPDATE_FILES_LIST_SIZE_LIMIT) { // anti-DOS protection qWarning() << "Too large .list file (" << result.length() << "); the limit is" << UPDATE_FILES_LIST_SIZE_LIMIT << "- no files will be updated"; return; } //qDebug() << result; QStringList data = result.split('\n', QString::SkipEmptyParts); result.clear(); m_fileNamesToUpdate.clear(); if (data.count() > UPDATE_FILES_COUNT_LIMIT) { // anti-DOS protection qWarning() << "Too many files to update (" << data.count() << "); the limit is" << UPDATE_FILES_COUNT_LIMIT << "- no files will be updated"; return; } // OK, try to update (stage 1: check, stage 2: checking) for (int stage = 1; stage <= 2; stage++) { int i = 0; for (QStringList::ConstIterator it(data.constBegin()); it!=data.constEnd(); ++it, i++) { const QByteArray hash((*it).left(32).toLatin1()); const QString remoteFname((*it).mid(32 + 2)); if (stage == 1) { if (hash.length() != 32) { qWarning() << "Invalid hash" << hash << "in line" << i+1 << "- no files will be updated"; return; } if ((*it).mid(32, 2) != " ") { qWarning() << "Two spaces expected but found" << (*it).mid(32, 2) << "in line" << i+1 << "- no files will be updated"; return; } if (remoteFname.contains(QRegularExpression("\\s"))) { qWarning() << "Filename expected without whitespace but found" << remoteFname << "in line" << i+1 << "- no files will be updated"; return; } } else if (stage == 2) { checkFile(hash, remoteFname, &m_fileNamesToUpdate); } } } if (m_fileNamesToUpdate.isEmpty()) { //qDebug() << "No files to update."; return; } // update files QList sourceFiles; foreach (const QString &fname, m_fileNamesToUpdate) { sourceFiles.append(QUrl(uiPath(fname))); } m_tempDir.reset(new QTemporaryDir(QDir::tempPath() + "/kexi-status")); //qDebug() << m_tempDir->path(); #ifdef USE_KIO_COPY KIO::CopyJob *copyJob = KIO::copy(sourceFiles, QUrl::fromLocalFile(m_tempDir->path()), KIO::HideProgressInfo | KIO::Overwrite); connect(copyJob, &KIO::CopyJob::result, this, &Private::filesCopyFinished); #else if (!m_downloadManager) { m_downloadManager = new QNetworkAccessManager(this); connect(m_downloadManager.data(), &QNetworkAccessManager::finished, this, &Private::fileDownloadFinished); } m_sourceFilesToDownload = sourceFiles; downloadNextFile(); #endif //qDebug() << "copying from" << QUrl(uiPath(fname)) << "to" // << (dir + fname); } private Q_SLOTS: void filesCopyFinished(KJob* job) { #ifdef USE_KIO_COPY if (job->error()) { //! @todo error... qDebug() << "ERROR:" << job->errorString(); m_tempDir.reset(); return; } KIO::CopyJob* copyJob = qobject_cast(job); Q_UNUSED(copyJob) //qDebug() << "DONE" << copyJob->destUrl(); (void)copyFilesToDestinationDir(); #else Q_UNUSED(job) #endif } void fileDownloadFinished(QNetworkReply* reply) { #ifdef USE_KIO_COPY Q_UNUSED(reply) #else const bool ok = copyFile(reply); reply->deleteLater(); if (!ok) { qWarning() << "Error downloading file" << m_sourceFilesToDownload.first(); delete m_downloadManager; m_sourceFilesToDownload.clear(); m_tempDir.reset(); } m_sourceFilesToDownload.removeFirst(); downloadNextFile(); #endif } bool copyFile(QNetworkReply* reply) { #ifdef USE_KIO_COPY Q_UNUSED(reply) #else #define DOWNLOAD_BUFFER_SIZE 1024 * 50 if (reply->error() != QNetworkReply::NoError) { return false; } const QString filename(m_sourceFilesToDownload.first().fileName()); QString path(m_tempDir->path() + '/' + filename); QSaveFile f(path); if (!f.open(QIODevice::WriteOnly)) { return false; } QByteArray buf(DOWNLOAD_BUFFER_SIZE, Qt::Uninitialized); while (!reply->atEnd()) { const qint64 size = reply->read(buf.data(), buf.size()); if (size < 0) { return false; } if (f.write(buf.data(), size) != size) { return false; } } if (!f.commit()) { return false; } #endif return true; } private: #ifndef USE_KIO_COPY void downloadNextFile() { if (m_sourceFilesToDownload.isEmpty()) { // success (void)copyFilesToDestinationDir(); return; } m_downloadManager->get(QNetworkRequest(m_sourceFilesToDownload.first())); } #endif private: bool copyFilesToDestinationDir() { const QString dir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + basePath() + '/'); bool ok = true; if (!QDir(dir).exists()) { if (!QDir().mkpath(dir)) { ok = false; qWarning() << "Could not create" << dir; } } if (ok) { foreach (const QString &fname, m_fileNamesToUpdate) { const QByteArray oldName(QFile::encodeName(m_tempDir->path() + '/' + fname)), newName(QFile::encodeName(dir + fname)); if (0 != ::rename(oldName.constData(), newName.constData())) { qWarning() << "cannot move" << (m_tempDir->path() + '/' + fname) << "to" << (dir + fname); } } } QDir(m_tempDir->path()).removeRecursively(); m_tempDir.reset(); m_fileNamesToUpdate.clear(); return ok; } void checkFile(const QByteArray &hash, const QString &remoteFname, QStringList *fileNamesToUpdate) { QString localFname = findFileName(remoteFname); if (localFname.isEmpty()) { fileNamesToUpdate->append(remoteFname); qDebug() << "missing filename" << remoteFname << "- download it"; return; } QFile file(localFname); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "could not open file" << localFname << "- update it"; fileNamesToUpdate->append(remoteFname); return; } QCryptographicHash md5(QCryptographicHash::Md5); if (!md5.addData(&file)) { qWarning() << "could not check MD5 for file" << localFname << "- update it"; fileNamesToUpdate->append(remoteFname); return; } if (md5.result().toHex() != hash) { qDebug() << "not matching file" << localFname << "- update it"; fileNamesToUpdate->append(remoteFname); } } QStringList m_fileNamesToUpdate; QScopedPointer m_tempDir; #ifndef USE_KIO_COPY QList m_sourceFilesToDownload; QPointer m_downloadManager; #endif }; KexiWelcomeStatusBarGuiUpdater::KexiWelcomeStatusBarGuiUpdater() : QObject() , d(new Private) { } KexiWelcomeStatusBarGuiUpdater::~KexiWelcomeStatusBarGuiUpdater() { delete d; } void KexiWelcomeStatusBarGuiUpdater::update() { QDateTime lastStatusBarUpdate = d->configGroup.readEntry("LastStatusBarUpdate", QDateTime()); if (lastStatusBarUpdate.isValid()) { int minutes = lastStatusBarUpdate.secsTo(QDateTime::currentDateTime()) / 60; if (minutes < GUI_UPDATE_INTERVAL) { qDebug() << "gui updated" << minutes << "min. ago, next auto-update in" << (GUI_UPDATE_INTERVAL - minutes) << "min."; return; } } d->configGroup.writeEntry("LastStatusBarUpdate", QDateTime::currentDateTime()); KexiUserFeedbackAgent *f = KexiMainWindowIface::global()->userFeedbackAgent(); f->waitForRedirect(this, SLOT(slotRedirectLoaded())); } void KexiWelcomeStatusBarGuiUpdater::slotRedirectLoaded() { QByteArray postData = stableVersionStringDot0().toLatin1(); KIO::Job* sendJob = KIO::storedHttpPost(postData, QUrl(uiPath(".list")), KIO::HideProgressInfo); connect(sendJob, SIGNAL(result(KJob*)), d, SLOT(sendRequestListFilesFinished(KJob*))); sendJob->addMetaData("content-type", "Content-Type: application/x-www-form-urlencoded"); } // --- //! @internal class ScrollArea : public QScrollArea { Q_OBJECT public: explicit ScrollArea(QWidget *parent = 0) : QScrollArea(parent) { setFrameShape(QFrame::NoFrame); setBackgroundRole(QPalette::Base); setWidgetResizable(true); } void setEnabled(bool set) { if (set != isEnabled()) { QScrollArea::setEnabled(set); updateColors(); } } protected: - virtual void changeEvent(QEvent* event) + virtual void changeEvent(QEvent* event) override { switch (event->type()) { case QEvent::EnabledChange: case QEvent::PaletteChange: updateColors(); break; default:; } QScrollArea::changeEvent(event); } void updateColors() { if (!widget()) return; KColorScheme scheme(palette().currentColorGroup()); QColor linkColor = scheme.foreground(KColorScheme::LinkText).color(); //qDebug() << "_____________" << isEnabled(); foreach(QLabel* lbl, widget()->findChildren()) { QString t = lbl->text(); QRegularExpression re("", QRegularExpression::InvertedGreedinessOption); int pos = 0; int oldPos = 0; QString newText; QRegularExpressionMatch match = re.match(t); //qDebug() << "t:" << t; while ((pos = match.capturedStart(pos)) != -1) { //qDebug() << "pos:" << pos; //qDebug() << "newText += t.mid(oldPos, pos - oldPos)" // << t.mid(oldPos, pos - oldPos); newText += t.midRef(oldPos, pos - oldPos); //qDebug() << "newText1:" << newText; //qDebug() << lbl->objectName() << "~~~~" << t.mid(pos, re.matchedLength()); QString a = t.mid(pos, match.capturedLength()); //qDebug() << "a:" << a; int colPos = a.indexOf("color:"); if (colPos == -1) { // add color a.insert(a.length() - 1, " style=\"color:" + linkColor.name() + ";\""); } else { // replace color colPos += qstrlen("color:"); for (;colPos < a.length() && a[colPos] == ' '; colPos++) { } if (colPos < a.length() && a[colPos] == '#') { colPos++; int i = colPos; for (;i < a.length(); i++) { if (a[i] == ';' || a[i] == ' ' || a[i] == '"' || a[i] == '\'') break; } //qDebug() << "******" << a.mid(colPos, i - colPos); a.replace(colPos, i - colPos, linkColor.name().mid(1)); } } //qDebug() << "a2:" << a; newText += a; //qDebug() << "newText2:" << newText; pos += match.capturedLength(); oldPos = pos; //qDebug() << "pos2:" << pos; } //qDebug() << "oldPos:" << oldPos; newText += t.midRef(oldPos); //qDebug() << "newText3:" << newText; lbl->setText(newText); } #if 0 QString text; text = QString("%3") .arg(link).arg(linkColor.name()).arg(linkText); if (!format.isEmpty()) { text = QString(format).replace("%L", text); } q->setText(text); #endif } }; // --- class Q_DECL_HIDDEN KexiWelcomeStatusBar::Private { public: explicit Private(KexiWelcomeStatusBar* _q) : statusWidget(0), q(_q) { rccFname = findFileName("status.rcc"); if (!rccFname.isEmpty()) { QResource::registerResource(rccFname); } } ~Private() { delete msgWidget; if (!rccFname.isEmpty()) { QResource::unregisterResource(rccFname); } } template T widgetOfClass(T parent, const char *widgetName) const { T w = parent->template findChild(widgetName); if (!w) { qWarning() << "NO SUCH widget" << widgetName << "in" << parent; } return w; } QWidget* widget(QWidget *parent, const char *widgetName) const { return widgetOfClass(parent, widgetName); } QObject* object(QObject *parent, const char *objectName) const { QObject *o = parent->findChild(objectName); if (!o) { qWarning() << "NO SUCH object" << objectName << "in" << parent; } return o; } void setProperty(QWidget *parent, const char *widgetName, const char *propertyName, const QVariant &value) { QWidget *w = widget(parent, widgetName); if (w) { w->setProperty(propertyName, value); } } QVariant property(QWidget *parent, const char *widgetName, const char *propertyName) const { QWidget *w = widget(parent, widgetName); return w ? w->property(propertyName) : QVariant(); } void connect(QWidget *parent, const char *widgetName, const char *signalName, QObject *receiver, const char *slotName) { QWidget *w = widget(parent, widgetName); if (w) { QObject::connect(w, signalName, receiver, slotName); } } void animatedHide(QWidget *parent, const char *widgetName) { QWidget *w = widget(parent, widgetName); if (!w) return; KexiFadeWidgetEffect *animation = new KexiFadeWidgetEffect(w); QObject::connect(animation, SIGNAL(destroyed()), w, SLOT(hide())); animation->start(); } QWidget* loadGui(const QString &guiFileName, QWidget *parentWidget = 0) { QString fname = findFileName(guiFileName); if (fname.isEmpty()) { qWarning() << "filename" << fname << "not found"; return 0; } QFile file(fname); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "could not open file" << fname; return 0; } QUiLoader loader; QWidget* widget = loader.load(&file, parentWidget); if (!widget) { qWarning() << "could load ui from file" << fname; } file.close(); return widget; } void updateStatusWidget() { QWidget *widget = loadGui("status.ui", statusScrollArea); if (!widget) { return; } int smallFontSize = qFloor((QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pointSizeF() + q->font().pointSizeF()) / 2.0); smallFont = q->font(); smallFont.setPointSizeF(smallFontSize); widget->setFont(smallFont); //delete statusWidget; statusWidget = widget; statusScrollArea->setWidget(statusWidget); QString donationText = property(statusWidget, "link_donate", "text").toString(); donationText.remove(QStringLiteral("(+%1%)")); setProperty(statusWidget, "link_donate", "text", donationText); // do not alter background palette QPalette pal(widget->palette()); pal.setColor(QPalette::Disabled, QPalette::Base, pal.color(QPalette::Normal, QPalette::Base)); widget->setPalette(pal); setProperty(statusWidget, "donation_url", "visible", false); connect(statusWidget, "link_donate", SIGNAL(linkActivated(QString)), q, SLOT(showDonation())); } enum CalloutAlignment { AlignToBar, AlignToWidget }; //! Aligns callout pointer position of msgWidget to widget named @a alignToWidgetName void setMessageWidgetCalloutPointerPosition( const QString& alignToWidgetName, CalloutAlignment calloutAlignment = AlignToBar) { //qDebug() << q->pos() << q->mapToGlobal(QPoint(0, 100)); QPoint p(q->mapToGlobal(QPoint(0, 100))); QWidget *alignToWidget = this->widget(statusWidget, alignToWidgetName.toLatin1()); if (alignToWidget) { p.setY( alignToWidget->mapToGlobal( QPoint(-5, alignToWidget->height() / 2)).y()); if (calloutAlignment == AlignToWidget) { p.setX(alignToWidget->mapToGlobal(QPoint(-5, 0)).x()); //qDebug() << p; } } else { qWarning() << alignToWidgetName << "not found!"; } msgWidget->setCalloutPointerPosition(p, alignToWidget); } //! Shows message widget taking maximum space within the welcome page //! Returns created layout for further use into @a layout. //! Created widge is assigned to msgWidget. //! Calls slot @a slotToCallAfterShow after animated showing, if provided. //! Call msgWidget->animatedShow() afterwards. void showMaximizedMessageWidget(const QString &alignToWidgetName, QPointer *layout, const char* slotToCallAfterShow, CalloutAlignment calloutAlignment = AlignToBar) { QWidget *alignToWidget = this->widget(statusWidget, alignToWidgetName.toLatin1()); int msgWidth; if (alignToWidget && calloutAlignment == AlignToWidget) { msgWidth = q->parentWidget()->width() - alignToWidget->width() - 10; } else { msgWidth = q->parentWidget()->width() - q->width(); } QWidget *widget = new QWidget; *layout = new QGridLayout(widget); if (msgWidth > 100) { // nice text margin (*layout)->setColumnMinimumWidth(0, 50); } //qDebug() << (q->parentWidget()->width() - q->width()) << "***"; KexiContextMessage msg(widget); if (msgWidget) { delete static_cast(msgWidget); } msgWidget = new KexiContextMessageWidget(q->parentWidget()->parentWidget(), 0, 0, msg); msgWidget->setCalloutPointerDirection(KMessageWidget::Right); msgWidget->setMessageType(KMessageWidget::Information); msgWidget->setCloseButtonVisible(true); int offset_y = 0; if (alignToWidget) { offset_y = alignToWidget->mapToGlobal(QPoint(0, 0)).y() - q->parentWidget()->mapToGlobal(QPoint(0, 0)).y(); } else { qWarning() << alignToWidgetName << "not found!"; } msgWidget->resize(msgWidth, q->parentWidget()->height() - offset_y); setMessageWidgetCalloutPointerPosition(alignToWidgetName, calloutAlignment); msgWidget->setResizeTrackingPolicy(Qt::Horizontal | Qt::Vertical); statusScrollArea->setEnabled(false); // async show to for speed up if (slotToCallAfterShow) { QObject::connect(msgWidget, SIGNAL(animatedShowFinished()), q, slotToCallAfterShow); } QObject::connect(msgWidget, SIGNAL(animatedHideFinished()), q, SLOT(slotMessageWidgetClosed())); } ScrollArea *statusScrollArea; QWidget *statusWidget; QVBoxLayout *lyr; QPointer msgWidget; QFont smallFont; bool detailsDataVisible = false; KexiWelcomeStatusBarGuiUpdater guiUpdater; private: QString rccFname; KexiWelcomeStatusBar *q; QMap dict; }; KexiWelcomeStatusBar::KexiWelcomeStatusBar(QWidget* parent) : QWidget(parent), d(new Private(this)) { d->lyr = new QVBoxLayout(this); init(); } KexiWelcomeStatusBar::~KexiWelcomeStatusBar() { delete d; } void KexiWelcomeStatusBar::init() { d->statusScrollArea = new ScrollArea(this); d->lyr->addWidget(d->statusScrollArea); d->updateStatusWidget(); QTimer::singleShot(10, &d->guiUpdater, SLOT(update())); } void KexiWelcomeStatusBar::showDonation() { if (!sender()) { return; } if (KMessageBox::Yes != KMessageBox::questionYesNo(this, xi18nc("@info donate to the project", "Kexi may be totally free, but its development is costly." "Power, hardware, office space, internet access, traveling for meetings - everything costs." "Direct donation is the easiest and fastest way to efficiently support the Kexi Project. " "Everyone, regardless of any degree of involvement can do so." "What do you receive for your donation? Kexi will become more feature-full and stable as " "contributors will be able to devote more time to Kexi. Not only you can " "expect new features, but you can also have an influence on what features are added!" "Currently we are accepting donations through BountySource (a funding platform " "for open-source software) using secure PayPal, Bitcoin and Google Wallet transfers." "Contact us at https://community.kde.org/Kexi/Contact " "for more information." "Thanks for your support!"), xi18n("Donate to the Project"), KGuiItem(xi18nc("@action:button Go to Donation", "Proceed to the Donation Web Page"), QIcon(":/icons/heart.png")), KGuiItem(xi18nc("Do not donate now", "Not Now")), QString(), KMessageBox::Notify | KMessageBox::AllowLink)) { return; } QUrl donationUrl(d->property(this, "donation_url", "text").toString()); if (donationUrl.isValid()) { QDesktopServices::openUrl(donationUrl); KConfigGroup configGroup(KSharedConfig::openConfig()->group("User Feedback")); configGroup.writeEntry("LastDonation", QDateTime::currentDateTime()); } else { qWarning() << "Invalid donation URL" << donationUrl; } } #include "KexiWelcomeStatusBar.moc" diff --git a/src/migration/AlterSchemaTableModel.h b/src/migration/AlterSchemaTableModel.h index f166da150..a557a978b 100644 --- a/src/migration/AlterSchemaTableModel.h +++ b/src/migration/AlterSchemaTableModel.h @@ -1,58 +1,58 @@ /* This file is part of the KDE project Copyright (C) 2009 Adam Pigg Copyright (C) 2009-2016 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 ALTERSCHEMATABLEMODEL_H #define ALTERSCHEMATABLEMODEL_H #include #include #include class KDbTableSchema; class AlterSchemaTableModel : public QAbstractTableModel { Q_OBJECT public: explicit AlterSchemaTableModel(QObject* parent = nullptr); ~AlterSchemaTableModel(); - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; void setSchema(KDbTableSchema *schema); void setData(QList *data); void setRowCount(int i); private: //! Reimplemented just to avoid 'hidden' warnings bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) Q_DECL_OVERRIDE { return QAbstractTableModel::setData(index, value, role); } KDbTableSchema *m_schema; QList *m_data; //!< Small amount of data to display to user int m_recordCount; }; #endif // ALTERSCHEMATABLEMODEL_H diff --git a/src/migration/importoptionsdlg.h b/src/migration/importoptionsdlg.h index df592a815..6925a76b9 100644 --- a/src/migration/importoptionsdlg.h +++ b/src/migration/importoptionsdlg.h @@ -1,53 +1,53 @@ /* This file is part of the KDE project Copyright (C) 2005 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIMIGRATIONOPTIONSDIALOG_H #define KEXIMIGRATIONOPTIONSDIALOG_H #include class QCheckBox; class KexiCharacterEncodingComboBox; namespace KexiMigration { //! @short Import Options dialog. //! It is currently used for MDB driver only //! @todo Hardcoded. Move such code to KexiMigrate drivers. class OptionsDialog : public QDialog { Q_OBJECT public: OptionsDialog(const QString& databaseFile, const QString& selectedEncoding, QWidget* parent = 0); virtual ~OptionsDialog(); KexiCharacterEncodingComboBox* encodingComboBox() const; protected Q_SLOTS: - virtual void accept(); + virtual void accept() override; protected: KexiCharacterEncodingComboBox *m_encodingComboBox; QCheckBox *m_chkAlwaysUseThisEncoding; }; } #endif diff --git a/src/migration/importtablewizard.h b/src/migration/importtablewizard.h index bdf2b9566..157718f8a 100644 --- a/src/migration/importtablewizard.h +++ b/src/migration/importtablewizard.h @@ -1,130 +1,130 @@ /* This file is part of the KDE project Copyright (C) 2009 Adam Pigg Copyright (C) 2014-2016 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 IMPORTTABLEWIZARD_H #define IMPORTTABLEWIZARD_H #include "keximigrate_export.h" #include "migratemanager.h" #include #include class QDialogButtonBox; class QListWidget; class QLabel; class QProgressBar; class QCheckBox; class KDbConnection; class KexiConnectionSelectorWidget; class KexiProjectSelectorWidget; class KexiProjectSet; namespace Kexi { class ObjectStatus; } namespace KexiMigration { class MigrateManager; class KexiMigrate; class AlterSchemaWidget; class KEXIMIGRATE_EXPORT ImportTableWizard : public KAssistantDialog { Q_OBJECT public: explicit ImportTableWizard(KDbConnection* curDB, QWidget* parent = 0, QMap* args = 0, Qt::WindowFlags flags = 0); virtual ~ImportTableWizard( ); - virtual void back(); - virtual void next(); - virtual void accept(); - virtual void reject(); + virtual void back() override; + virtual void next() override; + virtual void accept() override; + virtual void reject() override; protected Q_SLOTS: void slot_currentPageChanged(KPageWidgetItem*,KPageWidgetItem*); private: KDbConnection* m_connection; KexiConnectionSelectorWidget *m_srcConnSel; KexiMigration::MigrateManager m_migrateManager; QPointer m_migrateDriver; QListWidget *m_tableListWidget; AlterSchemaWidget *m_alterSchemaWidget; KexiProjectSelectorWidget *m_srcDBName; KexiProjectSet* m_prjSet; QString m_importTableName; QMap* m_args; bool fileBasedSrcSelected() const; QString driverIdForSelectedSource(); KexiMigrate* prepareImport(Kexi::ObjectStatus* result); QLabel *m_lblImportingTxt, *m_lblImportingErrTxt, *m_progressLbl, *m_rowsImportedLbl, *m_finishLbl; QProgressBar *m_importingProgressBar; QCheckBox *m_finishCheckBox; QPushButton* m_importOptionsButton; bool m_importComplete; bool m_importWasCanceled; unsigned m_recordCount; //! Encoding for source db. Currently only used for MDB driver. //! @todo Hardcoded. Move to KexiMigrate driver's impl. QString m_sourceDbEncoding; bool doImport(); bool readFromTable(); //Page Items KPageWidgetItem *m_introPageItem, *m_srcConnPageItem, *m_srcDBPageItem, *m_tablesPageItem, *m_alterTablePageItem, *m_importingPageItem, *m_progressPageItem, *m_finishPageItem; //Page Widgets QWidget *m_introPageWidget, *m_srcConnPageWidget, *m_srcDBPageWidget, *m_tablesPageWidget, *m_alterTablePageWidget, *m_importingPageWidget, *m_progressPageWidget, *m_finishPageWidget; //Page Setup void setupIntroPage(); void setupSrcConn(); void setupSrcDB(); void setupTableSelectPage(); void setupAlterTablePage(); void setupImportingPage(); void setupProgressPage(); void setupFinishPage(); //Page Arrival void arriveSrcConnPage(); void arriveSrcDBPage(); void arriveTableSelectPage(KPageWidgetItem *prevPage); void arriveAlterTablePage(); void arriveImportingPage(); void arriveProgressPage(); void arriveFinishPage(); private Q_SLOTS: void slotConnPageItemSelected(bool isSelected); void slotTableListWidgetSelectionChanged(); void slotNameChanged(); void slotCancelClicked(); void slotOptionsButtonClicked(); }; } #endif // IMPORTTABLEWIZARD_H diff --git a/src/migration/importwizard.h b/src/migration/importwizard.h index a3aaa8101..1a2f309d6 100644 --- a/src/migration/importwizard.h +++ b/src/migration/importwizard.h @@ -1,118 +1,118 @@ /* This file is part of the KDE project Copyright (C) 2004 Adam Pigg Copyright (C) 2004-2016 Jarosław Staniek Copyright (C) 2005 Martin Ellis 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 KEXIMIGRATIONIMPORTWIZARD_H #define KEXIMIGRATIONIMPORTWIZARD_H #include "migratemanager.h" #include #include #include class QMimeType; class QLabel; class KPageWidgetItem; namespace Kexi { class ObjectStatus; } namespace KexiMigration { class KexiMigrate; //! GUI for importing external databases (file-based and server-based) class KEXIMIGRATE_EXPORT ImportWizard : public KAssistantDialog { Q_OBJECT public: /*! Creates wizard's instance. \a args contains arguments that can be parsed by parseArguments(). \a *arg will be also set to imported project's filename on success and to null value on failure or cancellation. */ explicit ImportWizard(QWidget *parent = 0, QMap* args = 0); virtual ~ImportWizard(); public Q_SLOTS: void progressUpdated(int percent); protected Q_SLOTS: - virtual void next(); - virtual void back(); + virtual void next() override; + virtual void back() override; void slot_currentPageChanged(KPageWidgetItem*,KPageWidgetItem*); - virtual void accept(); - virtual void reject(); + virtual void accept() override; + virtual void reject() override; void helpClicked(); void slotOptionsButtonClicked(); void destinationCaptionTextChanged(const QString &text); void sourceConnectionSelected(bool selected); private: void parseArguments(); void setupIntro(); void setupSrcConn(); void setupSrcDB(); void setupDstType(); void setupDstCaption(); void setupDst(); void setupFinish(); void setupImportType(); void setupImporting(); bool checkUserInput(); KexiMigrate* prepareImport(Kexi::ObjectStatus& result); /*! Performs import. \return true/false on success/faulure or cancelled when user cancelled importing (mainly because didn't allow overwriting an existing database by a new one). */ tristate import(); bool fileBasedSrcSelected() const; bool fileBasedDstSelected() const; QString driverIdForSelectedSource() const; QString driverIdForMimeType(const QMimeType &mime) const; QString findDriverIdForSelectedSource(); void arriveSrcConnPage(); void arriveSrcDBPage(); void arriveDstCaptionPage(); void arriveDstPage(); void arriveFinishPage(); void arriveImportingPage(); //! @return source filename selected by user or preselected one (if present) QString selectedSourceFileName() const; void updateDestinationDBFileName(); class Private; Private * const d; }; } #endif diff --git a/src/migration/mdb/src/keximdb/mdbmigrate.h b/src/migration/mdb/src/keximdb/mdbmigrate.h index c9171b6d6..99d0f2dda 100644 --- a/src/migration/mdb/src/keximdb/mdbmigrate.h +++ b/src/migration/mdb/src/keximdb/mdbmigrate.h @@ -1,95 +1,95 @@ /* This file is part of the KDE project Copyright (C) 2005,2006 Martin Ellis Copyright (C) 2005-2016 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MDBMIGRATE_H #define MDBMIGRATE_H #include #include #include #include namespace KexiMigration { class MDBMigrate : public KexiMigrate { Q_OBJECT public: explicit MDBMigrate(QObject *parent, const QVariantList& args = QVariantList()); virtual ~MDBMigrate(); //! Convert an MDB type to a KDb type, prompting user if necessary. KDbField::Type type(int type); //! Get the table definition for a given table name /*! Look up the table definition for the given table. This only returns a ptr to the MdbTableDef - it doesn't load e.g. the column data. Remember to mdb_free_tabledef the table definition when it's finished with. \return the table definition, or null if no matching table was found */ MdbTableDef* getTableDef(const QString& tableName); QVariant toQVariant(const char* data, unsigned int len, int type); bool getPrimaryKey(KDbTableSchema* table, MdbTableDef* tableDef); //! Reimplemented to add support for "sourceDatabaseHasNonUnicodeEncoding" property //! @todo this should be in KDbConnection class but Migration framework has no such yet! - virtual QVariant propertyValue(const QByteArray& propName); + virtual QVariant propertyValue(const QByteArray& propName) override; protected: //! Driver specific function to return table names - virtual bool drv_tableNames(QStringList *tablenames); + virtual bool drv_tableNames(QStringList *tablenames) override; //! Driver specific implementation to read a table schema virtual bool drv_readTableSchema( - const QString& originalName, KDbTableSchema *tableSchema); + const QString& originalName, KDbTableSchema *tableSchema) override; //! Creates connection object to the source database (driver-specific). KDbConnection* drv_createConnection() Q_DECL_OVERRIDE; //! Driver specific connection implementation - virtual bool drv_connect(); + virtual bool drv_connect() override; //! Disconnect from the db backend - virtual bool drv_disconnect(); + virtual bool drv_disconnect() override; //! Copy MDB table to a KDb table bool drv_copyTable(const QString& srcTable, KDbConnection *destConn, KDbTableSchema* dstTable, const RecordFilter *recordFilter = nullptr) Q_DECL_OVERRIDE; - virtual bool drv_progressSupported() { + virtual bool drv_progressSupported() override { return true; } - virtual bool drv_getTableSize(const QString& table, quint64 *size); + virtual bool drv_getTableSize(const QString& table, quint64 *size) override; private: MdbHandle *m_mdb = nullptr; }; } #endif diff --git a/src/migration/tsv/TsvMigrate.h b/src/migration/tsv/TsvMigrate.h index 716c64c11..c59f540e2 100644 --- a/src/migration/tsv/TsvMigrate.h +++ b/src/migration/tsv/TsvMigrate.h @@ -1,73 +1,73 @@ /* This file is part of the KDE project Copyright (C) 2004-2009 Adam Pigg Copyright (C) 2016 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITSVMIGRATE_H #define KEXITSVMIGRATE_H #include #include class QTextCodec; namespace KexiMigration { struct FileInfo; //! "Tab Separated Values" document import plugin class TsvMigrate : public KexiMigrate { Q_OBJECT public: explicit TsvMigrate(QObject *parent, const QVariantList &args = QVariantList()); virtual ~TsvMigrate(); protected: //! Connect to source KDbConnection* drv_createConnection() Q_DECL_OVERRIDE; bool drv_connect() Q_DECL_OVERRIDE; //! Disconnect from source - virtual bool drv_disconnect(); + virtual bool drv_disconnect() override; //! Get table names in source - virtual bool drv_tableNames(QStringList *tablenames); + virtual bool drv_tableNames(QStringList *tablenames) override; bool drv_copyTable(const QString& srcTable, KDbConnection *destConn, KDbTableSchema* dstTable, const RecordFilter *recordFilter = 0) Q_DECL_OVERRIDE; //! Read schema for a given table - virtual bool drv_readTableSchema(const QString& originalName, KDbTableSchema *tableSchema); + virtual bool drv_readTableSchema(const QString& originalName, KDbTableSchema *tableSchema) override; //! Starts reading data from the source dataset's table QSharedPointer drv_readFromTable(const QString & tableName) Q_DECL_OVERRIDE; private: bool openFile(FileInfo *info); }; } #endif diff --git a/src/plugins/forms/KexiFormScrollAreaWidget.h b/src/plugins/forms/KexiFormScrollAreaWidget.h index 0edd721ff..96def64c4 100644 --- a/src/plugins/forms/KexiFormScrollAreaWidget.h +++ b/src/plugins/forms/KexiFormScrollAreaWidget.h @@ -1,53 +1,53 @@ /* This file is part of the KDE project Copyright (C) 2014 Jarosław Staniek 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 KEXIFORMSCROLLAREAWIDGET_H #define KEXIFORMSCROLLAREAWIDGET_H #include #include class KexiFormScrollView; //! A widget displaying contents of KexiScrollArea class KexiFormScrollAreaWidget : public QWidget { Q_OBJECT public: explicit KexiFormScrollAreaWidget(KexiFormScrollView *area); virtual ~KexiFormScrollAreaWidget(); KexiFormScrollView *scrollArea; Q_SIGNALS: //! Emitted when the contents is being interactively resized. bool resized(); protected: - virtual void paintEvent(QPaintEvent *e); - virtual void mouseMoveEvent(QMouseEvent *e); - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseReleaseEvent(QMouseEvent *e); - virtual void leaveEvent(QEvent *e); + virtual void paintEvent(QPaintEvent *e) override; + virtual void mouseMoveEvent(QMouseEvent *e) override; + virtual void mousePressEvent(QMouseEvent *e) override; + virtual void mouseReleaseEvent(QMouseEvent *e) override; + virtual void leaveEvent(QEvent *e) override; private: bool m_resizing; }; #endif // KEXIFORMSCROLLAREAWIDGET_H diff --git a/src/plugins/forms/kexidbfactorybase.h b/src/plugins/forms/kexidbfactorybase.h index 46fde931d..46f51a631 100644 --- a/src/plugins/forms/kexidbfactorybase.h +++ b/src/plugins/forms/kexidbfactorybase.h @@ -1,51 +1,51 @@ /* This file is part of the KDE project Copyright (C) 2011 Jarosław Staniek 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 KEXIDBFACTORYBASE_H #define KEXIDBFACTORYBASE_H #include "kexiformutils_export.h" #include namespace KFormDesigner { class Form; } //! Kexi Base Factory /*! Provides a number of default features for Kexi widget factories. @todo after merging KexiDBFactory with KexiStandardFormWidgetsFactory merge KexiDBFactoryBase with KFormDesigner::WidgetFactory */ class KEXIFORMUTILS_EXPORT KexiDBFactoryBase : public KFormDesigner::WidgetFactory { Q_OBJECT public: explicit KexiDBFactoryBase(QObject *parent); virtual ~KexiDBFactoryBase(); protected: virtual bool isPropertyVisibleInternal(const QByteArray& classname, QWidget *w, - const QByteArray& property, bool isTopLevel); + const QByteArray& property, bool isTopLevel) override; }; #endif diff --git a/src/plugins/forms/kexiformpart.h b/src/plugins/forms/kexiformpart.h index d18c3053f..d025bb435 100644 --- a/src/plugins/forms/kexiformpart.h +++ b/src/plugins/forms/kexiformpart.h @@ -1,113 +1,113 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2005-2017 Jarosław Staniek 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 KEXIFORMPART_H #define KEXIFORMPART_H #include #include #include #include #include #include class QDomDocument; namespace KFormDesigner { class Form; class WidgetTreeWidget; } class KDbFieldList; class KexiDataSourcePage; class KexiFormPartTempData : public KexiWindowData, public KDbTableSchemaChangeListener { Q_OBJECT public: KexiFormPartTempData(KexiWindow* parent, KDbConnection *conn); ~KexiFormPartTempData(); //! Sets data source used for this data. //! If the previous data source is different and is not empty, listener for it will be unregistered. //! If the new data source is empty this temp-data object will be registered as a listener for it. void setDataSource(const QString &pluginId, const QString &dataSource); QPointer form; QPointer previewForm; QString tempForm; QPoint scrollViewContentsPos; //!< to preserve contents pos after switching //! Used in KexiFormView::setUnsavedLocalBLOBs() QHash unsavedLocalBLOBs; //! Used when loading a form from (temporary) XML in Data View //! to get unsaved blobs collected at design mode. QHash unsavedLocalBLOBsByName; protected: //! This temp-data acts as a listener for tracking changes in table schema //! used by the form. This method closes the form on request. tristate closeListener() override; private: Q_DISABLE_COPY(KexiFormPartTempData) class Private; Private * const d; }; //! Kexi Form Plugin /*! It just creates a \ref KexiFormView. See there for most of code. */ class KEXIFORMUTILS_EXPORT KexiFormPart : public KexiPart::Part { Q_OBJECT public: KexiFormPart(QObject *parent, const QVariantList &); virtual ~KexiFormPart(); KexiDataSourcePage* dataSourcePage() const; KFormDesigner::WidgetTreeWidget* widgetTreePage() const; #ifndef KEXI_NO_FORM_DATASOURCE_WIZARD void generateForm(KDbFieldList *list, QDomDocument &domDoc); #endif virtual KLocalizedString i18nMessage(const QString& englishMessage, - KexiWindow* window) const; + KexiWindow* window) const override; protected: KexiWindowData* createWindowData(KexiWindow* window) override Q_REQUIRED_RESULT; KexiView *createView(QWidget *parent, KexiWindow *window, KexiPart::Item *item, Kexi::ViewMode viewMode = Kexi::DataViewMode, QMap *staticObjectArgs = nullptr) override Q_REQUIRED_RESULT; - virtual void initPartActions(); - virtual void initInstanceActions(); - virtual void setupCustomPropertyPanelTabs(QTabWidget *tab); + virtual void initPartActions() override; + virtual void initInstanceActions() override; + virtual void setupCustomPropertyPanelTabs(QTabWidget *tab) override; private: class Private; Private* d; }; #endif diff --git a/src/plugins/forms/kexiformscrollview.h b/src/plugins/forms/kexiformscrollview.h index 208e4e08d..996ad801b 100644 --- a/src/plugins/forms/kexiformscrollview.h +++ b/src/plugins/forms/kexiformscrollview.h @@ -1,357 +1,357 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2016 Jarosław Staniek 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 KEXIFORMSCROLLVIEW_H #define KEXIFORMSCROLLVIEW_H #include "kexiformutils_export.h" #include #include #include #include #include #include #include #include class KexiRecordNavigator; class KexiDBForm; namespace KFormDesigner { class Form; } //! @short A widget for displaying a form view in a scrolled area. /** Users can resize the form's main widget, according to grid settings. * The content is resized so the widget can be further resized. * This class also implements: * - record navigation handling (KexiRecordNavigatorHandler) * - shared actions handling (KexiSharedActionClient) * - data-aware behaviour (KexiDataAwareObjectInterface) * - data provider bound to data-aware widgets (KexiFormDataProvider) * * @see KexiTableView */ class KEXIFORMUTILS_EXPORT KexiFormScrollView : public QScrollArea, public KexiRecordNavigatorHandler, public KexiSharedActionClient, public KexiDataAwareObjectInterface, public KexiFormDataProvider, public KexiFormEventHandler { Q_OBJECT KEXI_DATAAWAREOBJECTINTERFACE public: KexiFormScrollView(QWidget *parent, bool preview); virtual ~KexiFormScrollView(); void setForm(KFormDesigner::Form *form); KFormDesigner::Form* form() const; //! Needed to avoid conflict with QWidget::data(). inline KDbTableViewData* data() const { return KexiDataAwareObjectInterface::data(); } /*! Reimplemented from KexiDataAwareObjectInterface for checking 'readOnly' flag from a widget ('readOnly' flag from data member is still checked though). */ - virtual bool columnEditable(int col); + virtual bool columnEditable(int col) override; /*! \return number of visible columns in this view. There can be a number of duplicated columns defined, so columnCount() can return greater or smaller number than dataColumns(). */ - virtual int columnCount() const; + virtual int columnCount() const override; //! @return the number of records in the data set (if data set is present). - virtual int recordCount() const; + virtual int recordCount() const override; //! \return number of the currently selected record number or -1. - virtual int currentRecord() const; + virtual int currentRecord() const override; /*! \return column information for column number \a col. Reimplemented for KexiDataAwareObjectInterface: column data corresponding to widget number is used here (see fieldNumberForColumn()). */ - virtual KDbTableViewColumn* column(int col); + virtual KDbTableViewColumn* column(int col) override; /*! \return field number within data model connected to a data-aware widget at column \a col. */ - virtual int fieldNumberForColumn(int col); + virtual int fieldNumberForColumn(int col) override; /*! @internal Used by KexiFormView in view switching. */ void beforeSwitchView(); /*! \return last record visible on the screen (counting from 0). The returned value is guaranteed to be smaller or equal to currentRecord() or -1 if there are no records. Implemented for KexiDataAwareObjectInterface. */ //! @todo unimplemented for now, this will be used for continuous forms - virtual int lastVisibleRecord() const; + virtual int lastVisibleRecord() const override; /*! \return vertical scrollbar. Implemented for KexiDataAwareObjectInterface. */ - virtual QScrollBar* verticalScrollBar() const; + virtual QScrollBar* verticalScrollBar() const override; KexiDBForm* dbFormWidget() const; //! @return true if snapping to grid is enabled. The defalt value is false. bool isSnapToGridEnabled() const; bool isResizingEnabled() const; void setResizingEnabled(bool enabled); void setRecordNavigatorVisible(bool visible); bool isOuterAreaVisible() const; void setOuterAreaIndicatorVisible(bool visible); void refreshContentsSizeLater(); KexiRecordNavigator* recordNavigator() const; bool isPreviewing() const; QMargins viewportMargins() const; void setViewportMargins(const QMargins &margins); //! @return widget displaying contents of the main area. QWidget* mainAreaWidget() const; //! Sets widget for displaying contents of the main area. void setMainAreaWidget(QWidget* widget); //! temporary int leftMargin() const { return 0; } //! temporary int bottomMargin() const { return 0; } //! temporary void updateScrollBars() {} /*! @return geometry of the viewport, i.e. the scrollable area, minus any scrollbars, etc. Implementation for KexiDataAwareObjectInterface. */ - virtual QRect viewportGeometry() const; + virtual QRect viewportGeometry() const override; public Q_SLOTS: //! Implementation for KexiDataAwareObjectInterface //! \return arbitraty value of 10. - virtual int recordsPerPage() const; + virtual int recordsPerPage() const override; //! Implementation for KexiDataAwareObjectInterface - virtual void ensureCellVisible(int record, int col); + virtual void ensureCellVisible(int record, int col) override; //! Implementation for KexiDataAwareObjectInterface - virtual void ensureColumnVisible(int col); - - virtual void moveToRecordRequested(int r); - virtual void moveToLastRecordRequested(); - virtual void moveToPreviousRecordRequested(); - virtual void moveToNextRecordRequested(); - virtual void moveToFirstRecordRequested(); - virtual void addNewRecordRequested() { + virtual void ensureColumnVisible(int col) override; + + virtual void moveToRecordRequested(int r) override; + virtual void moveToLastRecordRequested() override; + virtual void moveToPreviousRecordRequested() override; + virtual void moveToNextRecordRequested() override; + virtual void moveToFirstRecordRequested() override; + virtual void addNewRecordRequested() override { KexiDataAwareObjectInterface::addNewRecordRequested(); } /*! Cancels changes made to the currently active editor. Reverts the editor's value to old one. \return true on success or false on failure (e.g. when editor does not exist) */ - virtual bool cancelEditor(); + virtual bool cancelEditor() override; public Q_SLOTS: /*! Clear command history right after final resize. */ void refreshContentsSize(); /*! Handles verticalScrollBar()'s valueChanged(int) signal. Called when vscrollbar's value has been changed. */ //! @todo unused for now, will be used for continuous forms - virtual void verticalScrollBarValueChanged(int v) { + virtual void verticalScrollBarValueChanged(int v) override { KexiDataAwareObjectInterface::verticalScrollBarValueChanged(v); } Q_SIGNALS: - void itemChanged(KDbRecordData* data, int record, int column); - void itemChanged(KDbRecordData* data, int record, int column, const QVariant &oldValue); - void itemDeleteRequest(KDbRecordData* data, int record, int column); - void currentItemDeleteRequest(); - void newItemAppendedForAfterDeletingInSpreadSheetMode(); //!< does nothing - void dataRefreshed(); - void dataSet(KDbTableViewData *data); - void itemSelected(KDbRecordData* data); - void cellSelected(int record, int column); - void sortedColumnChanged(int column); - void recordEditingStarted(int record); - void recordEditingTerminated(int record); - void updateSaveCancelActions(); - void reloadActions(); + void itemChanged(KDbRecordData* data, int record, int column) override; + void itemChanged(KDbRecordData* data, int record, int column, const QVariant &oldValue) override; + void itemDeleteRequest(KDbRecordData* data, int record, int column) override; + void currentItemDeleteRequest() override; + void newItemAppendedForAfterDeletingInSpreadSheetMode() override; //!< does nothing + void dataRefreshed() override; + void dataSet(KDbTableViewData *data) override; + void itemSelected(KDbRecordData* data) override; + void cellSelected(int record, int column) override; + void sortedColumnChanged(int column) override; + void recordEditingStarted(int record) override; + void recordEditingTerminated(int record) override; + void updateSaveCancelActions() override; + void reloadActions() override; //! Emitted when the main widget area is being interactively resized. bool resized(); protected Q_SLOTS: //! Handles KDbTableViewData::recordRepaintRequested() signal - virtual void slotRecordRepaintRequested(KDbRecordData* data); + virtual void slotRecordRepaintRequested(KDbRecordData* data) override; //! Handles KDbTableViewData::aboutToDeleteRecord() signal. Prepares info for slotRecordDeleted(). - virtual void slotAboutToDeleteRecord(KDbRecordData* data, KDbResultInfo* result, bool repaint) { + virtual void slotAboutToDeleteRecord(KDbRecordData* data, KDbResultInfo* result, bool repaint) override { KexiDataAwareObjectInterface::slotAboutToDeleteRecord(data, result, repaint); } //! Handles KDbTableViewData::recordDeleted() signal to repaint when needed. - virtual void slotRecordDeleted() { + virtual void slotRecordDeleted() override { KexiDataAwareObjectInterface::slotRecordDeleted(); } //! Handles KDbTableViewData::recordInserted() signal to repaint when needed. - virtual void slotRecordInserted(KDbRecordData* data, bool repaint); + virtual void slotRecordInserted(KDbRecordData* data, bool repaint) override; //! Like above, not db-aware version - virtual void slotRecordInserted(KDbRecordData* data, int record, bool repaint); + virtual void slotRecordInserted(KDbRecordData* data, int record, bool repaint) override; - virtual void slotRecordsDeleted(const QList&); + virtual void slotRecordsDeleted(const QList&) override; - virtual void slotDataDestroying() { + virtual void slotDataDestroying() override { KexiDataAwareObjectInterface::slotDataDestroying(); } /*! Reloads data for this widget. Handles KDbTableViewData::reloadRequested() signal. */ - virtual void reloadData() { + virtual void reloadData() override { KexiDataAwareObjectInterface::reloadData(); } //! Copy current selection to a clipboard (e.g. cell) - virtual void copySelection(); + virtual void copySelection() override; //! Cut current selection to a clipboard (e.g. cell) - virtual void cutSelection(); + virtual void cutSelection() override; //! Paste current clipboard contents (e.g. to a cell) - virtual void paste(); + virtual void paste() override; protected: //! Implementation for KexiDataAwareObjectInterface - virtual void clearColumnsInternal(bool repaint); + virtual void clearColumnsInternal(bool repaint) override; //! Implementation for KexiDataAwareObjectInterface - virtual KDbOrderByColumn::SortOrder currentLocalSortOrder() const; + virtual KDbOrderByColumn::SortOrder currentLocalSortOrder() const override; //! Implementation for KexiDataAwareObjectInterface - virtual int currentLocalSortColumn() const; + virtual int currentLocalSortColumn() const override; //! Implementation for KexiDataAwareObjectInterface. Visually does nothing //! but remembers index of the currently sorted column and order. - virtual void setLocalSortOrder(int column, KDbOrderByColumn::SortOrder order); + virtual void setLocalSortOrder(int column, KDbOrderByColumn::SortOrder order) override; //! Implementation for KexiDataAwareObjectInterface. //! Just calls KexiDataAwareObjectInterface's implementation. - void sortColumnInternal(int col, int order = 0); + void sortColumnInternal(int col, int order = 0) override; //! Implementation for KexiDataAwareObjectInterface. //! Nothing to do here. Record navigator is already updated. - virtual void updateGUIAfterSorting(int previousRecord); + virtual void updateGUIAfterSorting(int previousRecord) override; //! Implementation for KexiDataAwareObjectInterface virtual void createEditor(int record, int column, const QString& addText = QString(), - CreateEditorFlags flags = DefaultCreateEditorFlags); + CreateEditorFlags flags = DefaultCreateEditorFlags) override; //! Implementation for KexiDataAwareObjectInterface - virtual KexiDataItemInterface *editor(int col, bool ignoreMissingEditor = false); + virtual KexiDataItemInterface *editor(int col, bool ignoreMissingEditor = false) override; //! Implementation for KexiDataAwareObjectInterface - virtual void editorShowFocus(int record, int column); + virtual void editorShowFocus(int record, int column) override; /*! Implementation for KexiDataAwareObjectInterface Redraws specified cell. */ - virtual void updateCell(int record, int column); + virtual void updateCell(int record, int column) override; /*! Redraws the current cell. Implemented after KexiDataAwareObjectInterface. */ - virtual void updateCurrentCell(); + virtual void updateCurrentCell() override; /*! Implementation for KexiDataAwareObjectInterface Redraws all cells of specified record. */ - virtual void updateRecord(int record); + virtual void updateRecord(int record) override; /*! Implementation for KexiDataAwareObjectInterface Updates contents of the widget. Just call update() here on your widget. */ - virtual void updateWidgetContents(); + virtual void updateWidgetContents() override; /*! Implementation for KexiDataAwareObjectInterface Implementation for KexiDataAwareObjectInterface Updates widget's contents size e.g. using QScrollView::resizeContents(). */ - virtual void updateWidgetContentsSize(); + virtual void updateWidgetContentsSize() override; //! Reimplemented from KexiFormDataProvider. Reaction for change of \a item. - virtual void valueChanged(KexiDataItemInterface* item); + virtual void valueChanged(KexiDataItemInterface* item) override; /*! Reimplemented from KexiFormDataProvider. \return information whether we're currently at new record or not. This can be used e.g. by data-aware widgets to determine if "(auto)" label should be displayed. */ - virtual bool cursorAtNewRecord() const; + virtual bool cursorAtNewRecord() const override; /*! Implementation for KexiFormDataProvider. */ - virtual void lengthExceeded(KexiDataItemInterface *item, bool lengthExceeded); + virtual void lengthExceeded(KexiDataItemInterface *item, bool lengthExceeded) override; /*! Implementation for KexiFormDataProvider. */ - virtual void updateLengthExceededMessage(KexiDataItemInterface *item); + virtual void updateLengthExceededMessage(KexiDataItemInterface *item) override; //! Implementation for KexiDataAwareObjectInterface //! Called by KexiDataAwareObjectInterface::setCursorPosition() //! if cursor's position is really changed. - virtual void selectCellInternal(int previousRecord, int previousColumn); + virtual void selectCellInternal(int previousRecord, int previousColumn) override; /*! Reimplementation: used to refresh "editing indicator" visibility. */ - virtual void initDataContents(); + virtual void initDataContents() override; /*! @internal Updates record appearance after canceling record edit. Reimplemented from KexiDataAwareObjectInterface: just undoes changes for every data item. Used by cancelRecordEditing(). */ - virtual void updateAfterCancelRecordEditing(); + virtual void updateAfterCancelRecordEditing() override; /*! @internal Updates record appearance after accepting record edit. Reimplemented from KexiDataAwareObjectInterface: just clears 'edit' indicator. Used by cancelRecordEditing(). */ - virtual void updateAfterAcceptRecordEditing(); + virtual void updateAfterAcceptRecordEditing() override; /*! @internal Used to invoke copy/paste/cut etc. actions at the focused widget's level. */ void handleDataWidgetAction(const QString& actionName); /*! @internal */ bool shouldDisplayDefaultValueForItem(KexiFormDataItemInterface* itemIface) const; virtual void setHBarGeometry(QScrollBar & hbar, int x, int y, int w, int h); const QTimer *delayedResizeTimer() const; //! Update section of vertical header - virtual void updateVerticalHeaderSection(int section); + virtual void updateVerticalHeaderSection(int section) override; private: class Private; Private * const d; }; #endif diff --git a/src/plugins/forms/kexiformview.h b/src/plugins/forms/kexiformview.h index b94bd46ab..6a8db8981 100644 --- a/src/plugins/forms/kexiformview.h +++ b/src/plugins/forms/kexiformview.h @@ -1,175 +1,175 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2017 Jarosław Staniek 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 KEXIFORMVIEW_H #define KEXIFORMVIEW_H #include #include #include #include #include #include #include #include #include "kexiformutils_export.h" #define KEXI_NO_FORM_DATASOURCE_WIZARD class KexiFormPart; class KexiFormPartTempData; namespace KFormDesigner { class Container; } //! The KexiFormView lass provides a data-driven (record-based) form view . /*! The KexiFormView can display data provided "by hand" or from KDb-compatible database source. This class provides a single view used inside KexiWindow. It takes care of saving/loading form, of enabling actions when needed. One KexiFormView object is instantiated for data view mode and a second KexiFormView object is instantiated for design view mode. @see KexiDataTableView */ class KEXIFORMUTILS_EXPORT KexiFormView : public KexiDataAwareView { Q_OBJECT public: enum ResizeMode { ResizeAuto = 0, ResizeDefault = ResizeAuto, ResizeFixed = 1, NoResize = 2 /*! @todo */ }; explicit KexiFormView(QWidget *parent, bool dbAware = true); virtual ~KexiFormView(); - virtual QSize preferredSizeHint(const QSize& otherSize); + virtual QSize preferredSizeHint(const QSize& otherSize) override; int resizeMode() const; KFormDesigner::Form* form() const; /*! Assigns \a id local (static) BLOB's identifier for \a widget widget. Previously assigned BLOB will be usassigned. If \a id is 0, BLOB is unassigned and no new is assigned. This method is called when a widget supporting BLOB data (currently, images from KexiDBImageBox, within KexiDBFactory) has BLOB assigned by identifier \a id. BLOB identifiers are defined by KexiBLOBBuffer (KexiBLOBBuffer::self() instance). The data collected by this method is used on form's design saving (in design mode). Local BLOBs are retrieved KexiBLOBBuffer::self() and stored in "kexi__blobs" 'system' table. Note that db-aware BLOBs (non local) are not handled this way. */ void setUnsavedLocalBLOB(QWidget *widget, KexiBLOBBuffer::Id_t id); public Q_SLOTS: /*! Inserts autofields onto the form at \a pos position. \a sourcePartClass can be "org.kexi-project.table" or "org.kexi-project.query", \a sourceName is a name of a table or query, \a fields is a list of fields to insert (one or more) Fields are inserted using standard KFormDesigner::InsertWidgetCommand framework, so undo/redo is available for this operation. If multiple fields are provided, they will be aligned vertically. If \a pos is QPoint(-1,-1) (the default), position is computed automatically based on a position last inserted field using this method. If this method has not been called yet, position of QPoint(40, 40) will be set. Called by: - slotHandleDropEvent() when field(s) are dropped from the data source pane onto the form - KexiFormManager is a used clicked "Insert fields" button on the data source pane. */ void insertAutoFields(const QString& sourcePartClass, const QString& sourceName, const QStringList& fields, KFormDesigner::Container* targetContainerWidget, const QPoint& pos = QPoint(-1, -1)); protected Q_SLOTS: void slotPropertySetSwitched(); void setFormModified(); void slotFocus(bool in); void slotHandleDragMoveEvent(QDragMoveEvent* e); //! Handles field(s) dropping from the data source pane onto the form //! @see insertAutoFields() void slotHandleDropEvent(QDropEvent* e); void slotWidgetSelectionChanged(QWidget *w, KFormDesigner::Form::WidgetSelectionFlags flags); void slotWidgetNameChanged(const QByteArray& oldname, const QByteArray& newname); protected: - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); - virtual KPropertySet* propertySet(); + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; + virtual KPropertySet* propertySet() override; virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); - virtual tristate storeData(bool dontAsk = false); + bool *cancel) override; + virtual tristate storeData(bool dontAsk = false) override; KexiFormPartTempData* tempData() const; KexiFormPart* formPart() const; void setForm(KFormDesigner::Form *f); bool initForm(); bool loadForm(); //! Used in loadForm() void updateAutoFieldsDataSource(); //! Used in loadForm() void updateValuesForSubproperties(); - virtual void resizeEvent(QResizeEvent *); + virtual void resizeEvent(QResizeEvent *) override; //! Reimplemented for context key event of top-level form widget. //! Redirects to Container::eventFilter(). - virtual void contextMenuEvent(QContextMenuEvent *e); + virtual void contextMenuEvent(QContextMenuEvent *e) override; void initDataSource(); - virtual void setFocusInternal(); + virtual void setFocusInternal() override; /*! Called after loading the form contents (before showing it). */ void updateTabStopsOrder(); /*! @internal */ void deleteQuery(); /*! @internal */ void updateDataSourcePage(); /*! Reimplemented after KexiView. Updates actions (e.g. availability). */ - virtual void updateActions(bool activated); + virtual void updateActions(bool activated) override; //! Updates internal actions specific to forms. //! @todo merge with other "update" routines? void updateActionsInternal(); private: class Private; Private * const d; }; #endif diff --git a/src/plugins/forms/widgets/KexiDBPushButton.h b/src/plugins/forms/widgets/KexiDBPushButton.h index 789c2051d..c476fccd2 100644 --- a/src/plugins/forms/widgets/KexiDBPushButton.h +++ b/src/plugins/forms/widgets/KexiDBPushButton.h @@ -1,111 +1,111 @@ /* This file is part of the KDE project Copyright (C) 2013 Oleg Kukharchuk Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBPUSHBUTTON_H #define KEXIDBPUSHBUTTON_H #include "kexiformutils_export.h" #include #include #include #include class KexiDBPushButtonPrivate; //! @short Push Button widget for Kexi forms class KEXIFORMUTILS_EXPORT KexiDBPushButton : public KexiPushButton, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString onClickAction READ onClickAction WRITE setOnClickAction) Q_PROPERTY(QString onClickActionOption READ onClickActionOption WRITE setOnClickActionOption) Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) public: explicit KexiDBPushButton(const QString & text, QWidget * parent = 0); ~KexiDBPushButton(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); + virtual QVariant value() override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; //! always false - virtual bool cursorAtStart(); + virtual bool cursorAtStart() override; //! always false - virtual bool cursorAtEnd(); + virtual bool cursorAtEnd() override; - virtual void clear(); + virtual void clear() override; - virtual void setInvalidState(const QString& displayText); + virtual void setInvalidState(const QString& displayText) override; - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; public Q_SLOTS: //! action string for "on click" event //! @see KexiFormPart::slotAssignAction() //! @see KexiFormEventAction::ActionData QString onClickAction() const; void setOnClickAction(const QString& actionString); /*! action option allowing to select whether the object should be opened data view mode or printed, etc. @see KexiFormPart::slotAssignAction() @see KexiFormEventAction::ActionData */ QString onClickActionOption() const; void setOnClickActionOption(const QString& option); //! Sets the datasource to \a ds inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; protected: //! Sets value \a value for a widget. - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; friend class KexiDBPushButtonPrivate; KexiDBPushButtonPrivate * const d; }; #endif diff --git a/src/plugins/forms/widgets/kexidbautofield.h b/src/plugins/forms/widgets/kexidbautofield.h index fc378f51c..811afecb2 100644 --- a/src/plugins/forms/widgets/kexidbautofield.h +++ b/src/plugins/forms/widgets/kexidbautofield.h @@ -1,218 +1,218 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2005 Christian Nitschkowski Copyright (C) 2005-2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBAUTOFIELD_H #define KEXIDBAUTOFIELD_H #include "kexiformutils_export.h" #include #include #include #include #include #include #include class QLabel; //! Universal "Auto Field" widget for Kexi forms /*! It acts as a container for most data-aware widgets. */ class KEXIFORMUTILS_EXPORT KexiDBAutoField : public QWidget, public KexiFormDataItemInterface, public KFormDesigner::DesignTimeDynamicChildWidgetHandler, public KFormDesigner::WidgetWithSubpropertiesInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT //'caption' is uncovered now Q_PROPERTY(QString labelCaption READ caption WRITE setCaption) Q_PROPERTY(QString caption READ caption WRITE setCaption) Q_PROPERTY(QColor foregroundLabelColor READ foregroundLabelColor WRITE setForegroundLabelColor RESET unsetPalette) Q_PROPERTY(QColor backgroundLabelColor READ backgroundLabelColor WRITE setBackgroundLabelColor RESET unsetPalette) Q_PROPERTY(bool autoCaption READ hasAutoCaption WRITE setAutoCaption) Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(LabelPosition labelPosition READ labelPosition WRITE setLabelPosition) Q_PROPERTY(WidgetType widgetType READ widgetType WRITE setWidgetType) /*internal, for design time only*/ Q_PROPERTY(int fieldTypeInternal READ fieldTypeInternal WRITE setFieldTypeInternal STORED false) Q_PROPERTY(QString fieldCaptionInternal READ fieldCaptionInternal WRITE setFieldCaptionInternal STORED false) public: enum WidgetType { Auto = 100, Text, Integer, Double, Boolean, Date, Time, DateTime, MultiLineText, ComboBox, Image }; Q_ENUM(WidgetType) enum LabelPosition { Left = 300, Top, NoLabel }; Q_ENUM(LabelPosition) KexiDBAutoField(const QString &text, WidgetType type, LabelPosition pos, QWidget *parent = 0); explicit KexiDBAutoField(QWidget *parent = 0, LabelPosition pos = Left); virtual ~KexiDBAutoField(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } virtual void setDataSource(const QString &ds); virtual void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override; - virtual void setInvalidState(const QString& text); - virtual bool isReadOnly() const; - virtual void setReadOnly(bool readOnly); + virtual void setInvalidState(const QString& text) override; + virtual bool isReadOnly() const override; + virtual void setReadOnly(bool readOnly) override; - virtual QVariant value(); - virtual bool valueIsNull(); - virtual bool valueIsEmpty(); - virtual bool valueIsValid(); - virtual bool valueChanged(); - virtual void clear(); + virtual QVariant value() override; + virtual bool valueIsNull() override; + virtual bool valueIsEmpty() override; + virtual bool valueIsValid() override; + virtual bool valueChanged() override; + virtual void clear() override; //! Reimplemented to also install \a listenter for internal editor - virtual void installListener(KexiDataItemChangesListener* listener); + virtual void installListener(KexiDataItemChangesListener* listener) override; WidgetType widgetType() const; void setWidgetType(WidgetType type); LabelPosition labelPosition() const; virtual void setLabelPosition(LabelPosition position); QString caption() const; void setCaption(const QString &caption); bool hasAutoCaption() const; void setAutoCaption(bool autoCaption); /*! If \a displayDefaultValue is true, the value set by KexiDataItemInterface::setValue() is displayed in a special way. Used by KexiFormDataProvider::fillDataItems(). \a widget is equal to 'this'. Reimplemented after KexiFormDataItemInterface. */ - virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue); + virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue) override; QWidget* editor() const; QLabel* label() const; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; static WidgetType widgetTypeForFieldType(KDbField::Type type); /*! On design time it is not possible to pass a reference to KDbField object so we're just providing field type. Only used when widget type is Auto. @internal */ void setFieldTypeInternal(int kexiDBFieldType); /*! On design time it is not possible to pass a reference to KDbField object so we're just providing field caption. Only used when widget type is Auto. @internal */ void setFieldCaptionInternal(const QString& text); /*! @internal */ int fieldTypeInternal() const; /*! @internal */ QString fieldCaptionInternal() const; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; virtual void setFocusPolicy(Qt::FocusPolicy policy); //! Reimplemented to return internal editor's color. QColor paletteForegroundColor() const; //! Reimplemented to set internal editor's color. void setPaletteForegroundColor(const QColor & color); //! Reimplemented to return internal editor's color. QColor paletteBackgroundColor() const; //! Reimplemented to set internal editor's color. virtual void setPaletteBackgroundColor(const QColor & color); //! \return label's foreground color QColor foregroundLabelColor() const; //! Sets label's foreground color virtual void setForegroundLabelColor(const QColor & color); //! \return label's background color QColor backgroundLabelColor() const; //! Sets label's background color virtual void setBackgroundLabelColor(const QColor & color); //! Reimplemented to accept subproperties. @see KFormDesigner::WidgetWithSubpropertiesInterface virtual QVariant property(const char * name) const; //! Reimplemented to accept subproperties. @see KFormDesigner::WidgetWithSubpropertiesInterface virtual bool setProperty(const char * name, const QVariant & value); /*! Called by the top-level form on key press event to consume widget-specific shortcuts. */ - virtual bool keyPressed(QKeyEvent *ke); + virtual bool keyPressed(QKeyEvent *ke) override; public Q_SLOTS: virtual void unsetPalette(); protected Q_SLOTS: virtual void paletteChange(const QPalette& oldPal); //! Implemented for KexiDataItemInterface - virtual void moveCursorToEnd(); + virtual void moveCursorToEnd() override; //! Implemented for KexiDataItemInterface - virtual void moveCursorToStart(); + virtual void moveCursorToStart() override; //! Implemented for KexiDataItemInterface - virtual void selectAll(); + virtual void selectAll() override; protected: - virtual void setValueInternal(const QVariant&add, bool removeOld); + virtual void setValueInternal(const QVariant&add, bool removeOld) override; void init(const QString &text, WidgetType type, LabelPosition pos); virtual void createEditor(); void changeText(const QString &text, bool beautify = true); void updateInformationAboutUnboundField(); //! internal editor can be created too late, so certain properties should be copied void copyPropertiesToEditor(); - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; //! Used by @ref setLabelPositionInternal(LabelPosition) void setLabelPositionInternal(LabelPosition position, bool noLabel); //! Used by KexiDBAutoField::setColumnInfo() and KexiDBComboBox::setColumnInfo() void setColumnInfoInternal(KDbQueryColumnInfo *cinfo, KDbQueryColumnInfo *visibleColumnInfo); private: class Private; Private * const d; }; #endif diff --git a/src/plugins/forms/widgets/kexidbcheckbox.h b/src/plugins/forms/widgets/kexidbcheckbox.h index 7166e87c8..d146088fb 100644 --- a/src/plugins/forms/widgets/kexidbcheckbox.h +++ b/src/plugins/forms/widgets/kexidbcheckbox.h @@ -1,111 +1,111 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBCHECKBOX_H #define KEXIDBCHECKBOX_H #include "kexiformutils_export.h" #include #include #include //! @short A db-aware check box class KEXIFORMUTILS_EXPORT KexiDBCheckBox : public QCheckBox, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(Tristate tristate READ isTristate WRITE setTristate) public: explicit KexiDBCheckBox(const QString &text, QWidget *parent = 0); virtual ~KexiDBCheckBox(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); - virtual void setInvalidState(const QString& displayText); + virtual QVariant value() override; + virtual void setInvalidState(const QString& displayText) override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; /*! \return 'readOnly' flag for this widget. */ - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; /*! \return the view widget of this item, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; virtual void setEnabled(bool enabled); enum Tristate { TristateDefault, TristateOn, TristateOff }; Q_ENUM(Tristate) void setTristate(Tristate tristate); Tristate isTristate() const; /*! Reimplemented after KexiFormDataItemInterface. */ - virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue); + virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue) override; - virtual void paintEvent(QPaintEvent* e); + virtual void paintEvent(QPaintEvent* e) override; public Q_SLOTS: void setDataSource(const QString &ds); inline void setDataSourcePluginId(const QString &ds) { KexiFormDataItemInterface::setDataSourcePluginId(ds); } void slotStateChanged(int state); //! This implementation just disables read only widget - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; protected: - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; //! \return true in isTristate() == TristateDefault and the widget has bound data source //! or if isTristate() == TristateOn, else false is returned. bool isTristateInternal() const; //! Updates tristate in QCheckBox itself according to m_tristate. void updateTristate(); private: bool m_invalidState; bool m_tristateChanged; //!< used in setTristate() Tristate m_tristate; //!< used in isTristate() and setTristate() }; #endif diff --git a/src/plugins/forms/widgets/kexidbcombobox.h b/src/plugins/forms/widgets/kexidbcombobox.h index effe7424b..5a0a0b7fb 100644 --- a/src/plugins/forms/widgets/kexidbcombobox.h +++ b/src/plugins/forms/widgets/kexidbcombobox.h @@ -1,176 +1,176 @@ /* This file is part of the KDE project Copyright (C) 2006-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBCOMBOBOX_H #define KEXIDBCOMBOBOX_H #include "kexidbutils.h" #include "kexidbautofield.h" #include //! @short Combo box widget for Kexi forms /*! This widget is implemented on top of KexiDBAutoField, so as it uses KexiDBAutoField's ability of embedding subwidgets, it can display not only a line edit but also text edit or image box (more can be added in the future). A drop-down button is added to mimic native combo box widget's functionality. */ class KEXIFORMUTILS_EXPORT KexiDBComboBox : public KexiDBAutoField, public KexiComboBoxBase { Q_OBJECT Q_PROPERTY(bool editable READ isEditable WRITE setEditable) public: explicit KexiDBComboBox(QWidget *parent = 0); virtual ~KexiDBComboBox(); //! Implemented for KexiComboBoxBase: form has no 'related data' model (only the full database model) KDbTableViewColumn *column() override; //! Implemented for KexiComboBoxBase KDbField *field() override; //! Implemented for KexiComboBoxBase - virtual QVariant origValue() const; + virtual QVariant origValue() const override; void setEditable(bool set); bool isEditable() const; - virtual void setLabelPosition(LabelPosition position); + virtual void setLabelPosition(LabelPosition position) override; - virtual QVariant value(); + virtual QVariant value() override; - virtual QVariant visibleValue(); + virtual QVariant visibleValue() override; //! Reimplemented because to avoid taking value from the internal editor (index is taken from the popup instead) - virtual bool valueChanged(); + virtual bool valueChanged() override; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; //! Reimplemented after KexiDBAutoField: jsut sets \a cinfo without initializing a subwidget. //! Initialization is performed by \ref setVisibleColumnInfo(). void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override; /*! Used internally to set visible database column information. Reimplemented: performs initialization of the subwidget. */ - virtual void setVisibleColumnInfo(KDbQueryColumnInfo* cinfo); + virtual void setVisibleColumnInfo(KDbQueryColumnInfo* cinfo) override; /*! \return visible database column information for this item. Reimplemented. */ - virtual KDbQueryColumnInfo* visibleColumnInfo(); + virtual KDbQueryColumnInfo* visibleColumnInfo() override; virtual QColor paletteBackgroundColor() const; //! Reimplemented to also set 'this' widget's background color, not only subwidget's. - virtual void setPaletteBackgroundColor(const QColor & color); + virtual void setPaletteBackgroundColor(const QColor & color) override; /*! Undoes changes made to this item - just resets the widget to original value. Reimplemented after KexiFormDataItemInterface to also revert the visible value (i.e. text) to the original state. */ - virtual void undoChanges(); + virtual void undoChanges() override; public Q_SLOTS: - virtual void slotRecordAccepted(KDbRecordData *data, int record); - virtual void slotRecordSelected(KDbRecordData *data); + virtual void slotRecordAccepted(KDbRecordData *data, int record) override; + virtual void slotRecordSelected(KDbRecordData *data) override; protected Q_SLOTS: virtual void slotInternalEditorValueChanged(const QVariant& v); void slotPopupHidden(); protected: QRect buttonGeometry() const; - virtual void paintEvent(QPaintEvent *); + virtual void paintEvent(QPaintEvent *) override; - virtual void mousePressEvent(QMouseEvent *e); + virtual void mousePressEvent(QMouseEvent *e) override; - virtual void mouseDoubleClickEvent(QMouseEvent *e); + virtual void mouseDoubleClickEvent(QMouseEvent *e) override; - virtual void changeEvent(QEvent * event); + virtual void changeEvent(QEvent * event) override; - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; //! \return internal editor's geometry QRect editorGeometry() const; //! Creates editor. Reimplemented, because if the combo box is not editable, //! editor should not be created. - virtual void createEditor(); + virtual void createEditor() override; virtual bool subwidgetStretchRequired(KexiDBAutoField* autoField) const; //! Implemented for KexiComboBoxBase - virtual QWidget *internalEditor() const; + virtual QWidget *internalEditor() const override; //! Implemented for KexiComboBoxBase. Does nothing if the widget is not editable. - virtual void moveCursorToEndInInternalEditor(); + virtual void moveCursorToEndInInternalEditor() override; //! Implemented for KexiComboBoxBase. Does nothing if the widget is not editable. - virtual void selectAllInInternalEditor(); + virtual void selectAllInInternalEditor() override; //! Implemented for KexiComboBoxBase - virtual void setValueInInternalEditor(const QVariant& value); + virtual void setValueInInternalEditor(const QVariant& value) override; //! Implemented for KexiComboBoxBase - virtual QVariant valueFromInternalEditor(); + virtual QVariant valueFromInternalEditor() override; //! Implemented for KexiComboBoxBase - virtual void editRequested(); + virtual void editRequested() override; //! Implemented for KexiComboBoxBase - virtual void acceptRequested(); + virtual void acceptRequested() override; //! Implement this to return a position \a pos mapped from parent (e.g. viewport) //! to global coordinates. QPoint(-1, -1) should be returned if this cannot be computed. - virtual QPoint mapFromParentToGlobal(const QPoint& pos) const; + virtual QPoint mapFromParentToGlobal(const QPoint& pos) const override; //! Implement this to return a hint for popup width. - virtual int popupWidthHint() const; + virtual int popupWidthHint() const override; - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; //! Implemented to handle visible value instead of index - virtual void setVisibleValueInternal(const QVariant& value); + virtual void setVisibleValueInternal(const QVariant& value) override; bool handleMousePressEvent(QMouseEvent *e); bool handleKeyPressEvent(QKeyEvent *ke); //! Implemented for KexiDataItemInterface - virtual void beforeSignalValueChanged(); + virtual void beforeSignalValueChanged() override; - virtual KexiComboBoxPopup *popup() const; - virtual void setPopup(KexiComboBoxPopup *popup); + virtual KexiComboBoxPopup *popup() const override; + virtual void setPopup(KexiComboBoxPopup *popup) override; /*! Called by top-level form on key press event. Used for Key_Escape to if the popup is visible, so the key press won't be consumed to perform "cancel editing". Also used for grabbing page down/up keys. */ - virtual bool keyPressed(QKeyEvent *ke); + virtual bool keyPressed(QKeyEvent *ke) override; //! Implemented for KexiComboBoxBase KDbConnection *connection() override; class Private; Private * const d; }; #endif diff --git a/src/plugins/forms/widgets/kexidbcommandlinkbutton.h b/src/plugins/forms/widgets/kexidbcommandlinkbutton.h index d46da038f..41b903bfd 100644 --- a/src/plugins/forms/widgets/kexidbcommandlinkbutton.h +++ b/src/plugins/forms/widgets/kexidbcommandlinkbutton.h @@ -1,106 +1,106 @@ /* This file is part of the KDE project Copyright (C) 2012-2013 Oleg Kukharchuk Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBCOMMANDLINKBUTTON_H #define KEXIDBCOMMANDLINKBUTTON_H #include "kexiformutils_export.h" #include #include #include #include class KexiDBCommandLinkButtonPrivate; //! @short Push Button widget for Kexi forms class KEXIFORMUTILS_EXPORT KexiDBCommandLinkButton : public KexiCommandLinkButton, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString onClickAction READ onClickAction WRITE setOnClickAction) Q_PROPERTY(QString onClickActionOption READ onClickActionOption WRITE setOnClickActionOption) Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) public: KexiDBCommandLinkButton(const QString &text, const QString &description, QWidget * parent = 0); virtual ~KexiDBCommandLinkButton(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); + virtual QVariant value() override; - virtual bool valueIsNull(); + virtual bool valueIsNull() override; - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; //! always false - virtual bool cursorAtStart(); + virtual bool cursorAtStart() override; //! always false - virtual bool cursorAtEnd(); + virtual bool cursorAtEnd() override; - virtual void clear(); + virtual void clear() override; - virtual void setInvalidState(const QString& displayText); + virtual void setInvalidState(const QString& displayText) override; - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; public Q_SLOTS: //! action string for "on click" event //! @see KexiFormPart::slotAssignAction() //! @see KexiFormEventAction::ActionData QString onClickAction() const; void setOnClickAction(const QString& actionString); /*! action option allowing to select whether the object should be opened data view mode or printed, etc. @see KexiFormPart::slotAssignAction() @see KexiFormEventAction::ActionData */ QString onClickActionOption() const; void setOnClickActionOption(const QString& option); //! Sets the datasource to \a ds inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; protected: //! Sets value \a value for a widget. - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; friend class KexiDBCommanLinkButtonPrivate; KexiDBCommandLinkButtonPrivate * const d; }; #endif diff --git a/src/plugins/forms/widgets/kexidbdatepicker.h b/src/plugins/forms/widgets/kexidbdatepicker.h index a0f95779d..973a38f56 100644 --- a/src/plugins/forms/widgets/kexidbdatepicker.h +++ b/src/plugins/forms/widgets/kexidbdatepicker.h @@ -1,94 +1,94 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2016 Jarosław Staniek Copyright (C) 2012 Oleg Kukharchuk This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBDATEPICKER_H #define KEXIDBDATEPICKER_H #include "kexiformutils_export.h" #include #include #include //! @short A db-aware DatePicker class KEXIFORMUTILS_EXPORT KexiDBDatePicker : public KDatePicker, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) public: explicit KexiDBDatePicker(QWidget *parent = 0); virtual ~KexiDBDatePicker(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); - virtual void setInvalidState(const QString& displayText); + virtual QVariant value() override; + virtual void setInvalidState(const QString& displayText) override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; /*! \return 'readOnly' flag for this widget. */ - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; /*! \return the view widget of this item, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; virtual void setEnabled(bool enabled); public Q_SLOTS: inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } void slotValueChanged(); - virtual void setReadOnly(bool set); + virtual void setReadOnly(bool set) override; protected: - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; private: bool m_invalidState; bool m_readOnly; }; #endif diff --git a/src/plugins/forms/widgets/kexidbform.h b/src/plugins/forms/widgets/kexidbform.h index f83f98d2a..7e686496b 100644 --- a/src/plugins/forms/widgets/kexidbform.h +++ b/src/plugins/forms/widgets/kexidbform.h @@ -1,142 +1,142 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2005-2009 Jarosław Staniek 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 KEXIDBFORM_H #define KEXIDBFORM_H #include "kexiformutils_export.h" #include #include #include #include class QEvent; class QDropEvent; class QDragMoveEvent; class KexiDataAwareObjectInterface; class KexiFormScrollView; //! @short A DB-aware form widget, acting as form's toplevel widget class KEXIFORMUTILS_EXPORT KexiDBForm : public QWidget, public KFormDesigner::FormWidget, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(bool autoTabStops READ autoTabStops WRITE setAutoTabStops) //original "size" property is not designable, so here's a custom (not storable) replacement Q_PROPERTY(QSize sizeInternal READ sizeInternal WRITE resizeInternal STORED false) public: KexiDBForm(QWidget *parent, KexiDataAwareObjectInterface* dataAwareObject); virtual ~KexiDBForm(); KexiDataAwareObjectInterface* dataAwareObject() const; inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } //! no effect - virtual QVariant value() { + virtual QVariant value() override { return QVariant(); } - virtual void setInvalidState(const QString& displayText); + virtual void setInvalidState(const QString& displayText) override; bool autoTabStops() const; QList* orderedFocusWidgets() const; QList* orderedDataAwareWidgets() const; void updateTabStopsOrder(KFormDesigner::Form* form); void updateTabStopsOrder(); - virtual bool valueIsNull(); - virtual bool valueIsEmpty(); - virtual bool isReadOnly() const; - virtual QWidget* widget(); - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool valueIsNull() override; + virtual bool valueIsEmpty() override; + virtual bool isReadOnly() const override; + virtual QWidget* widget() override; + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; bool isPreviewing() const; public Q_SLOTS: void setAutoTabStops(bool set); inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } //! This implementation just disables read only widget - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; //! @internal for sizeInternal property QSize sizeInternal() const { return QWidget::size(); } //! @internal for sizeInternal property void resizeInternal(const QSize& s) { QWidget::resize(s); } Q_SIGNALS: void handleDragMoveEvent(QDragMoveEvent *e); void handleDropEvent(QDropEvent *e); protected: - virtual bool eventFilter(QObject * watched, QEvent * e); + virtual bool eventFilter(QObject * watched, QEvent * e) override; - virtual void paintEvent(QPaintEvent *e); + virtual void paintEvent(QPaintEvent *e) override; //! no effect - virtual void setValueInternal(const QVariant&, bool) {} + virtual void setValueInternal(const QVariant&, bool) override {} //! Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface - virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e) override; //! Used to emit handleDropEvent() signal needed to control dropping on the container's surface - virtual void dropEvent(QDropEvent *e); + virtual void dropEvent(QDropEvent *e) override; //! called from KexiFormScrollView::initDataContents() void updateReadOnlyFlags(); //! Points to a currently edited data item. //! It is cleared when the focus is moved to other KexiFormDataItemInterface *editedItem; class Private; Private * const d; friend class KexiFormScrollView; }; #endif diff --git a/src/plugins/forms/widgets/kexidbimagebox.h b/src/plugins/forms/widgets/kexidbimagebox.h index 0cf9bbaac..e1d868c83 100644 --- a/src/plugins/forms/widgets/kexidbimagebox.h +++ b/src/plugins/forms/widgets/kexidbimagebox.h @@ -1,263 +1,263 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBIMAGEBOX_H #define KEXIDBIMAGEBOX_H #include #include #include "kexiframe.h" #include "kexidbutils.h" #include #include #include #include #include class KexiDropDownButton; class KexiImageContextMenu; //! @short A data-aware, editable image box. /*! Can also act as a normal static image box. */ class KEXIFORMUTILS_EXPORT KexiDBImageBox : public KexiFrame, public KexiFormDataItemInterface, public KexiSubwidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(int pixmapId READ pixmapId WRITE setPixmapId STORED false) Q_PROPERTY(int storedPixmapId READ storedPixmapId WRITE setStoredPixmapId DESIGNABLE false STORED true) Q_PROPERTY(bool scaledContents READ hasScaledContents WRITE setScaledContents) Q_PROPERTY(bool smoothTransformation READ smoothTransformation WRITE setSmoothTransformation) Q_PROPERTY(bool keepAspectRatio READ keepAspectRatio WRITE setKeepAspectRatio) Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) Q_PROPERTY(bool dropDownButtonVisible READ dropDownButtonVisible WRITE setDropDownButtonVisible) Q_PROPERTY(Qt::FocusPolicy focusPolicy READ focusPolicyInternal WRITE setFocusPolicy) // overridden to update image geometry Q_ENUMS(Shape Shadow) Q_PROPERTY(Shape frameShape READ frameShape WRITE setFrameShape) Q_PROPERTY(Shadow frameShadow READ frameShadow WRITE setFrameShadow) Q_PROPERTY(int lineWidth READ lineWidth WRITE setLineWidth) Q_PROPERTY(int midLineWidth READ midLineWidth WRITE setMidLineWidth) public: explicit KexiDBImageBox(bool designMode, QWidget *parent = 0); virtual ~KexiDBImageBox(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); // { return m_value.data(); } + virtual QVariant value() override; // { return m_value.data(); } QPixmap pixmap() const; int pixmapId() const; int storedPixmapId() const; - virtual void setInvalidState(const QString& displayText); + virtual void setInvalidState(const QString& displayText) override; - virtual bool valueIsNull(); + virtual bool valueIsNull() override; - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; - virtual QWidget* widget(); + virtual QWidget* widget() override; //! always true - virtual bool cursorAtStart(); + virtual bool cursorAtStart() override; //! always true - virtual bool cursorAtEnd(); + virtual bool cursorAtEnd() override; - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; bool hasScaledContents() const; bool smoothTransformation() const; Qt::Alignment alignment() const; bool keepAspectRatio() const; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; KexiImageContextMenu *contextMenu() const; /*! \return original file name of image loaded from a file. This can be later reused for displaying the image within a collection (to be implemented) or on saving the image data back to file. */ //! @todo QString originalFileName() const { return m_value.originalFileName(); } //! Reimplemented to override behaviour of "paletteBackgroundColor" //! and "paletteForegroundColor" properties. - virtual void setPalette(const QPalette &pal); + virtual void setPalette(const QPalette &pal) override; //! Reimplemented to override behaviour of "paletteBackgroundColor" property. virtual void setPaletteBackgroundColor(const QColor & color); //! \return true id drop down button should be visible (the default). bool dropDownButtonVisible() const; //! For overridden property int lineWidth() const; /*! Overridden to change the policy behaviour a bit: NoFocus is returned regardless the real focus flag if the data source is empty (see dataSource()). */ //! @todo KEXI3 focusPolicy() is not virtual! Qt::FocusPolicy focusPolicy() const; //! \return the internal focus policy value, i.e. the one unrelated to data source presence. Qt::FocusPolicy focusPolicyInternal() const; /*! Sets the internal focus policy value. "Internal" means that if there is no data source set, real policy becomes NoFocus. */ virtual void setFocusPolicy(Qt::FocusPolicy policy); public Q_SLOTS: void setPixmapId(int id); void setStoredPixmapId(int id); //! Sets the datasource to \a ds virtual void setDataSource(const QString &ds); inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } - virtual void setReadOnly(bool set); + virtual void setReadOnly(bool set) override; //! Sets \a pixmapData data for this widget. If the widget has data source set, //! the pixmap will be also placed inside of the buffer and saved later. //! @todo void setPixmapData(const QByteArray& pixmapData) { m_value.setData(pixmapData); } /*! Sets original file name of image loaded from a file. @see originalFileName() */ //! @todo void setOriginalFileName(const QString& name) { m_value.setOriginalFileName(name); } void setScaledContents(bool set); void setSmoothTransformation(bool set); void setAlignment(Qt::Alignment alignment); void setKeepAspectRatio(bool set); //! \return sets dropDownButtonVisible property. @see dropDownButtonVisible() void setDropDownButtonVisible(bool set); //! Forces execution of "insert from file" action void insertFromFile(); void setFrameShape(QFrame::Shape s); void setFrameShadow(QFrame::Shadow s); void setLineWidth(int w); void setMidLineWidth(int w); Q_SIGNALS: void idChanged(long id); protected Q_SLOTS: void slotUpdateActionsAvailabilityRequested(bool* valueIsNull, bool* valueIsReadOnly); void handleInsertFromFileAction(const QUrl &url); void handleAboutToSaveAsAction(QString* origFilename, QString* mimeType, bool* dataIsEmpty); bool handleSaveAsAction(const QUrl &url); void handleCutAction(); void handleCopyAction(); void handlePasteAction(); - virtual void clear(); + virtual void clear() override; void handleShowPropertiesAction(); protected: //! \return data depending on the current mode (db-aware or static) QByteArray data() const; - virtual void contextMenuEvent(QContextMenuEvent * e); + virtual void contextMenuEvent(QContextMenuEvent * e) override; void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override; - virtual void paintEvent(QPaintEvent*); - virtual void resizeEvent(QResizeEvent* e); - virtual bool eventFilter(QObject * watched, QEvent * e); + virtual void paintEvent(QPaintEvent*) override; + virtual void resizeEvent(QResizeEvent* e) override; + virtual bool eventFilter(QObject * watched, QEvent * e) override; //! Sets value \a value for a widget. - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; //! @internal, added \a loadPixmap option used by paste(). void setValueInternal(const QVariant& add, bool removeOld, bool loadPixmap); //! Updates i18n'd action strings after datasource change void updateActionStrings(); void updatePixmap(); //! @internal void setData(const KexiBLOBBuffer::Handle& handle); bool popupMenuAvailable(); /*! Called by top-level form on key press event. Used for Key_Escape to if the popup is visible, so the key press won't be consumed to perform "cancel editing". */ - virtual bool keyPressed(QKeyEvent *ke); + virtual bool keyPressed(QKeyEvent *ke) override; //! \return real line width, i.e. for Boxed sunken or Boxed raised //! frames returns doubled width value. int realLineWidth() const; //! Implemented for KexiSubwidgetInterface - virtual bool subwidgetStretchRequired(KexiDBAutoField* autoField) const; + virtual bool subwidgetStretchRequired(KexiDBAutoField* autoField) const override; QPixmap m_pixmap; QByteArray m_value; //!< for db-aware mode QString m_valueMimeType; //!< for db-aware mode KexiBLOBBuffer::Handle m_data; KexiDropDownButton *m_chooser; QPointer m_contextMenu; Qt::Alignment m_alignment; Qt::FocusPolicy m_focusPolicyInternal; //!< Used for focusPolicyInternal() QPixmap m_currentScaledPixmap; //!< for caching QRect m_currentRect; //!< for caching QPoint m_currentPixmapPos; //!< for caching bool m_readOnly; bool m_scaledContents; bool m_smoothTransformation; bool m_keepAspectRatio; bool m_insideSetData; bool m_setFocusOnButtonAfterClosingPopup; bool m_paletteBackgroundColorChanged; bool m_paintEventEnabled; //!< used to disable paintEvent() bool m_dropDownButtonVisible; bool m_insideSetPalette; }; #endif diff --git a/src/plugins/forms/widgets/kexidblabel.h b/src/plugins/forms/widgets/kexidblabel.h index b30ee5030..43dc6afaa 100644 --- a/src/plugins/forms/widgets/kexidblabel.h +++ b/src/plugins/forms/widgets/kexidblabel.h @@ -1,130 +1,130 @@ /* This file is part of the KDE project Copyright (C) 2005 Christian Nitschkowski Copyright (C) 2005 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBLABEL_H #define KEXIDBLABEL_H #include #include #include #include #include #include #include "kexidbtextwidgetinterface.h" #include #include #include class QPainter; //! @short An extended, data-aware, read-only text label. class KEXIFORMUTILS_EXPORT KexiDBLabel : public QLabel, protected KexiDBTextWidgetInterface, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap DESIGNABLE false) Q_PROPERTY(bool scaledContents READ hasScaledContents WRITE setScaledContents DESIGNABLE false) Q_PROPERTY(QColor frameColor READ frameColor WRITE setFrameColor) public: explicit KexiDBLabel(QWidget *parent = 0, Qt::WindowFlags f = 0); explicit KexiDBLabel(const QString& text, QWidget *parent = 0, Qt::WindowFlags f = 0); virtual ~KexiDBLabel(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); + virtual QVariant value() override; - virtual void setInvalidState(const QString& displayText); + virtual void setInvalidState(const QString& displayText) override; - virtual bool valueIsNull(); + virtual bool valueIsNull() override; - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; //! always true - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; - virtual QWidget* widget(); + virtual QWidget* widget() override; //! always false - virtual bool cursorAtStart(); + virtual bool cursorAtStart() override; //! always false - virtual bool cursorAtEnd(); + virtual bool cursorAtEnd() override; - virtual void clear(); + virtual void clear() override; //! used to catch setIndent(), etc. virtual bool setProperty(const char * name, const QVariant & value); virtual QColor frameColor() const; const QPixmap *pixmap() const; public Q_SLOTS: //! Sets the datasource to \a ds inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } virtual void setText(const QString& text); virtual void setPalette(const QPalette &pal); virtual void setFrameColor(const QColor& color); protected Q_SLOTS: //! empty - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; protected: void init(); void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override; - virtual void paintEvent(QPaintEvent*); - virtual void resizeEvent(QResizeEvent* e); + virtual void paintEvent(QPaintEvent*) override; + virtual void resizeEvent(QResizeEvent* e) override; //! Sets value \a value for a widget. - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; //! Reimplemented to paint using real frame color instead of froeground. //! Also allows to paint more types of frame. virtual void drawFrame(QPainter *); void updatePixmapLater(); class Private; Private * const d; }; #endif diff --git a/src/plugins/forms/widgets/kexidblineedit.cpp b/src/plugins/forms/widgets/kexidblineedit.cpp index 7a67e0ee1..82a498370 100644 --- a/src/plugins/forms/widgets/kexidblineedit.cpp +++ b/src/plugins/forms/widgets/kexidblineedit.cpp @@ -1,464 +1,464 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexidblineedit.h" #include "kexidbautofield.h" #include #include #include #include #include #include #include #include #include #include #include #include //! @internal A validator used for read only flag to disable editing class KexiDBLineEdit_ReadOnlyValidator : public QValidator { Q_OBJECT public: KexiDBLineEdit_ReadOnlyValidator(QObject * parent) : QValidator(parent) { } ~KexiDBLineEdit_ReadOnlyValidator() {} - virtual State validate(QString &input, int &pos) const { + virtual State validate(QString &input, int &pos) const override { input = qobject_cast(parent())->originalText(); pos = qobject_cast(parent())->originalCursorPosition(); return Intermediate; } }; //----- //! A style proxy overriding KexiDBLineEdit style class KexiDBLineEditStyle : public QProxyStyle { Q_OBJECT public: explicit KexiDBLineEditStyle(const QString &baseStyleName) : QProxyStyle(baseStyleName), indent(0) { } virtual ~KexiDBLineEditStyle() { } void setIndent(int indent) { this->indent = indent; } - QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget = 0) const + QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget = 0) const override { const KFormDesigner::FormWidgetInterface *formWidget = dynamic_cast(widget); if (formWidget && formWidget->designMode()) { const KexiFormDataItemInterface *dataItemIface = dynamic_cast(widget); if (dataItemIface && !dataItemIface->dataSource().isEmpty() && !formWidget->editingMode()) { if (element == SE_LineEditContents) { QRect rect = QProxyStyle::subElementRect(SE_LineEditContents, option, widget); if (option->direction == Qt::LeftToRight) return rect.adjusted(indent, 0, 0, 0); else return rect.adjusted(0, 0, -indent, 0); } } } return QProxyStyle::subElementRect(element, option, widget); } int indent; }; //----- KexiDBLineEdit::KexiDBLineEdit(QWidget *parent) : QLineEdit(parent) , KexiDBTextWidgetInterface() , KexiFormDataItemInterface() , m_readWriteValidator(0) , m_menuExtender(this, this) , m_internalReadOnly(false) , m_slotTextChanged_enabled(true) , m_cursorPosition(0) , m_paletteChangeEvent_enabled(true) , m_inStyleChangeEvent(false) { QFont tmpFont; tmpFont.setPointSize(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pointSize()); setMinimumHeight(QFontMetrics(tmpFont).height() + 6); m_originalPalette = palette(); connect(this, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged(QString))); connect(this, SIGNAL(textEdited(QString)), this, SLOT(slotTextEdited(QString))); connect(this, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(slotCursorPositionChanged(int,int))); m_internalStyle = new KexiDBLineEditStyle(style()->objectName()); m_internalStyle->setParent(this); m_internalStyle->setIndent(KexiFormUtils::dataSourceTagIcon().width()); m_inStyleChangeEvent = true; // do not allow QLineEdit::event() to touch the style setStyle(m_internalStyle); m_inStyleChangeEvent = false; KexiDataItemInterface::setLengthExceededEmittedAtPreviousChange(false); } KexiDBLineEdit::~KexiDBLineEdit() { } void KexiDBLineEdit::setInvalidState(const QString& displayText) { QLineEdit::setReadOnly(true); //! @todo move this to KexiDataItemInterface::setInvalidStateInternal() ? if (focusPolicy() & Qt::TabFocus) setFocusPolicy(Qt::ClickFocus); setValueInternal(displayText, true); } void KexiDBLineEdit::setValueInternal(const QVariant& add, bool removeOld) { m_slotTextChanged_enabled = false; bool lengthExceeded; m_originalText = m_textFormatter.toString( removeOld ? QVariant() : KexiDataItemInterface::originalValue(), add.toString(), &lengthExceeded); setText(m_originalText); setCursorPosition(0); //ok? emitLengthExceededIfNeeded(lengthExceeded); m_slotTextChanged_enabled = true; } QVariant KexiDBLineEdit::value() { return m_textFormatter.fromString(text()); } void KexiDBLineEdit::slotTextChanged(const QString&) { if (!m_slotTextChanged_enabled) return; signalValueChanged(); } void KexiDBLineEdit::slotTextEdited(const QString& text) { bool lengthExceeded = m_textFormatter.lengthExceeded(text); emitLengthExceededIfNeeded(lengthExceeded); } bool KexiDBLineEdit::fixup() { const QString t(text()); bool lengthExceeded = m_textFormatter.lengthExceeded(t); if (lengthExceeded) { m_slotTextChanged_enabled = false; setText(t.left(field()->maxLength())); m_slotTextChanged_enabled = true; } return true; } void KexiDBLineEdit::slotCursorPositionChanged(int oldPos, int newPos) { Q_UNUSED(oldPos); if (m_originalText == text()) { // when cursor was moved without altering the text, remember its position, // otherwise the change will be reverted by the validator m_cursorPosition = newPos; } } int KexiDBLineEdit::originalCursorPosition() const { return m_cursorPosition; } bool KexiDBLineEdit::valueIsNull() { return valueIsEmpty(); //ok??? text().isNull(); } bool KexiDBLineEdit::valueIsEmpty() { return m_textFormatter.valueIsEmpty( text() ); } bool KexiDBLineEdit::valueIsValid() { return m_textFormatter.valueIsValid( text() ); } bool KexiDBLineEdit::isReadOnly() const { return m_internalReadOnly; } void KexiDBLineEdit::updatePalette() { m_paletteChangeEvent_enabled = false; setPalette(m_internalReadOnly ? KexiUtils::paletteForReadOnly(m_originalPalette) : m_originalPalette); m_paletteChangeEvent_enabled = true; } void KexiDBLineEdit::changeEvent(QEvent *e) { if (e->type() == QEvent::PaletteChange && m_paletteChangeEvent_enabled) { m_originalPalette = palette(); updatePalette(); } QLineEdit::changeEvent(e); } void KexiDBLineEdit::setReadOnly(bool readOnly) { m_internalReadOnly = readOnly; updatePalette(); if (!designMode()) { if (m_internalReadOnly) { if (m_readWriteValidator) disconnect(m_readWriteValidator, SIGNAL(destroyed(QObject*)), this, SLOT(slotReadWriteValidatorDestroyed(QObject*))); m_readWriteValidator = validator(); if (m_readWriteValidator) connect(m_readWriteValidator, SIGNAL(destroyed(QObject*)), this, SLOT(slotReadWriteValidatorDestroyed(QObject*))); if (!m_readOnlyValidator) m_readOnlyValidator = new KexiDBLineEdit_ReadOnlyValidator(this); setValidator(m_readOnlyValidator); } else { //revert to r/w validator setValidator(m_readWriteValidator); } } } void KexiDBLineEdit::slotReadWriteValidatorDestroyed(QObject*) { m_readWriteValidator = 0; } void KexiDBLineEdit::contextMenuEvent(QContextMenuEvent *e) { QMenu *menu = createStandardContextMenu(); m_menuExtender.exec(menu, e->globalPos()); delete menu; } QWidget* KexiDBLineEdit::widget() { return this; } bool KexiDBLineEdit::cursorAtStart() { return cursorPosition() == 0; } bool KexiDBLineEdit::cursorAtEnd() { return KexiUtils::cursorAtEnd(this);; } void KexiDBLineEdit::clear() { if (!m_internalReadOnly) QLineEdit::clear(); } void KexiDBLineEdit::setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) { KexiFormDataItemInterface::setColumnInfo(conn, cinfo); m_textFormatter.setField(cinfo ? cinfo->field() : nullptr); KexiTextFormatter::OverrideDecimalPlaces overrideDecimalPlaces; overrideDecimalPlaces.enabled = true; overrideDecimalPlaces.value = -1; // all possible digits m_textFormatter.setOverrideDecimalPlaces(overrideDecimalPlaces); m_textFormatter.setGroupSeparatorsEnabled(false); // needed, otherwise text box contains separators (confusing) if (!cinfo) return; //! @todo handle input mask (via QLineEdit::setInputMask()) using a special KDbFieldInputMask class delete m_readWriteValidator; KDbFieldValidator* fieldValidator = new KDbFieldValidator(*cinfo->field(), this); if (m_internalReadOnly) { m_readWriteValidator = fieldValidator; } else { setValidator(fieldValidator); } const QString inputMask(m_textFormatter.inputMask()); if (!inputMask.isEmpty()) setInputMask(inputMask); KexiDBTextWidgetInterface::setColumnInfo(cinfo, this); } void KexiDBLineEdit::paintEvent(QPaintEvent *pe) { QLineEdit::paintEvent(pe); KFormDesigner::FormWidgetInterface *formWidget = dynamic_cast(this); if (formWidget && formWidget->designMode()) { KexiFormDataItemInterface *dataItemIface = dynamic_cast(this); if (dataItemIface && !dataItemIface->dataSource().isEmpty() && !formWidget->editingMode()) { // draw "data source tag" icon QPainter p(this); QStyleOptionFrame option; initStyleOption(&option); int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); QRect r( style()->subElementRect(QStyle::SE_LineEditContents, &option, this) ); r.setX(r.x() + leftMargin); r.setY(r.y() + topMargin); r.setRight(r.right() - rightMargin); r.setBottom(r.bottom() - bottomMargin); QPixmap dataSourceTagIcon; int x; if (layoutDirection() == Qt::LeftToRight) { dataSourceTagIcon = KexiFormUtils::dataSourceTagIcon(); x = r.left() - dataSourceTagIcon.width() + 2; } else { dataSourceTagIcon = KexiFormUtils::dataSourceRTLTagIcon(); x = r.right() - 2; } p.drawPixmap( x, r.top() + (r.height() - dataSourceTagIcon.height()) / 2, dataSourceTagIcon ); } } } bool KexiDBLineEdit::event(QEvent * e) { if (e->type() == QEvent::StyleChange) { if (m_inStyleChangeEvent) { return true; } // let the QLineEdit set its KLineEditStyle if (!QLineEdit::event(e)) { return false; } // move the KLineEditStyle inside our internal style as parent m_internalStyle->setParent(style()); m_inStyleChangeEvent = true; // avoid recursion setStyle(m_internalStyle); m_inStyleChangeEvent = false; return true; } const bool ret = QLineEdit::event(e); KexiDBTextWidgetInterface::event(e, this, text().isEmpty()); if (e->type() == QEvent::FocusOut) { QFocusEvent *fe = static_cast(e); if (fe->reason() == Qt::TabFocusReason || fe->reason() == Qt::BacktabFocusReason) { //display aligned to left after loosing the focus (only if this is tab/backtab event) //! @todo add option to set cursor at the beginning setCursorPosition(0); //ok? } } return ret; } bool KexiDBLineEdit::appendStretchRequired(KexiDBAutoField* autoField) const { return KexiDBAutoField::Top == autoField->labelPosition(); } void KexiDBLineEdit::handleAction(const QString& actionName) { if (actionName == "edit_copy") { copy(); } else if (actionName == "edit_paste") { paste(); } else if (actionName == "edit_cut") { cut(); } //! @todo ? } void KexiDBLineEdit::setDisplayDefaultValue(QWidget *widget, bool displayDefaultValue) { KexiFormDataItemInterface::setDisplayDefaultValue(widget, displayDefaultValue); // initialize display parameters for default / entered value KexiDisplayUtils::DisplayParameters * const params = displayDefaultValue ? m_displayParametersForDefaultValue : m_displayParametersForEnteredValue; setFont(params->font); QPalette pal(palette()); pal.setColor(QPalette::Active, QPalette::Text, params->textColor); setPalette(pal); } void KexiDBLineEdit::undo() { cancelEditor(); } void KexiDBLineEdit::moveCursorToEnd() { QLineEdit::end(false/*!mark*/); } void KexiDBLineEdit::moveCursorToStart() { QLineEdit::home(false/*!mark*/); } void KexiDBLineEdit::selectAll() { QLineEdit::selectAll(); } bool KexiDBLineEdit::keyPressed(QKeyEvent *ke) { Q_UNUSED(ke); return false; } void KexiDBLineEdit::updateTextForDataSource() { if (!designMode()) return; setText(dataSource()); } void KexiDBLineEdit::setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); updateTextForDataSource(); } void KexiDBLineEdit::setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); updateTextForDataSource(); } #include "kexidblineedit.moc" diff --git a/src/plugins/forms/widgets/kexidblineedit.h b/src/plugins/forms/widgets/kexidblineedit.h index b10e7b29a..943641b41 100644 --- a/src/plugins/forms/widgets/kexidblineedit.h +++ b/src/plugins/forms/widgets/kexidblineedit.h @@ -1,194 +1,194 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBLINEEDIT_H #define KEXIDBLINEEDIT_H #include #include #include #include #include #include #include "kexidbtextwidgetinterface.h" #include "kexidbutils.h" #include #include #include class KexiDBWidgetContextMenuExtender; class KexiDBLineEditStyle; //! @short Line edit widget for Kexi forms /*! Handles many data types. User input is validated by using validators and/or input masks. */ class KEXIFORMUTILS_EXPORT KexiDBLineEdit : public QLineEdit, protected KexiDBTextWidgetInterface, public KexiFormDataItemInterface, public KexiSubwidgetInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(QString clickMessage READ placeholderText WRITE setPlaceholderText) // Internal, equivalent of placeholderText // For backward compatibility Kexi projects // created with Qt < 4.7. Q_PROPERTY(bool showClearButton READ isClearButtonEnabled WRITE setClearButtonEnabled) // Internal, equivalent of clearButtonEnabled // For backward compatibility Kexi projects // created with Qt 4. public: explicit KexiDBLineEdit(QWidget *parent); virtual ~KexiDBLineEdit(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); - virtual void setInvalidState(const QString& displayText); + virtual QVariant value() override; + virtual void setInvalidState(const QString& displayText) override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; /*! \return true if the value is valid */ - virtual bool valueIsValid(); + virtual bool valueIsValid() override; /*! \return 'readOnly' flag for this widget. */ - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; /*! If \a displayDefaultValue is true, the value set by KexiDataItemInterface::setValue() is displayed in a special way. Used by KexiFormDataProvider::fillDataItems(). \a widget is equal to 'this'. Reimplemented after KexiFormDataItemInterface. */ - virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue); + virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue) override; /*! \return the view widget of this item, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override; /*! Handles action having standard name \a actionName. Action could be: "edit_copy", "edit_paste", etc. Reimplemented after KexiDataItemInterface. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Called by top-level form on key press event to consume widget-specific shortcuts. */ - virtual bool keyPressed(QKeyEvent *ke); + virtual bool keyPressed(QKeyEvent *ke) override; //! Used when read only flag is true QString originalText() const { return m_originalText; } //! Used when read only flag is true int originalCursorPosition() const; public Q_SLOTS: void setDataSource(const QString &ds); void setDataSourcePluginId(const QString &pluginId); - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; //! Reimplemented, so "undo" means the same as "cancelEditor" action virtual void undo(); //! Implemented for KexiDataItemInterface - virtual void moveCursorToEnd(); + virtual void moveCursorToEnd() override; //! Implemented for KexiDataItemInterface - virtual void moveCursorToStart(); + virtual void moveCursorToStart() override; //! Implemented for KexiDataItemInterface - virtual void selectAll(); + virtual void selectAll() override; //! Implemented for KexiDataItemInterface - virtual bool fixup(); + virtual bool fixup() override; protected Q_SLOTS: void slotTextChanged(const QString&); void slotTextEdited(const QString& text); void slotCursorPositionChanged(int oldPos, int newPos); //! Used to protect m_readWriteValidator against after validator is destroyed void slotReadWriteValidatorDestroyed(QObject*); protected: - virtual void paintEvent(QPaintEvent *); - virtual void setValueInternal(const QVariant& add, bool removeOld); - virtual bool event(QEvent *); - virtual void contextMenuEvent(QContextMenuEvent *e); - virtual void changeEvent(QEvent *e); + virtual void paintEvent(QPaintEvent *) override; + virtual void setValueInternal(const QVariant& add, bool removeOld) override; + virtual bool event(QEvent *) override; + virtual void contextMenuEvent(QContextMenuEvent *e) override; + virtual void changeEvent(QEvent *e) override; //! Implemented for KexiSubwidgetInterface - virtual bool appendStretchRequired(KexiDBAutoField* autoField) const; + virtual bool appendStretchRequired(KexiDBAutoField* autoField) const override; void updateTextForDataSource(); void updatePalette(); //! Used to format text KexiTextFormatter m_textFormatter; //! Used for read only flag to disable editing QPointer m_readOnlyValidator; //! Used to remember the previous validator used for r/w mode, after setting //! the read only flag const QValidator* m_readWriteValidator; //! Used for extending context menu KexiDBWidgetContextMenuExtender m_menuExtender; //! Used in isReadOnly, as sometimes we want to have the flag set tot true when QLineEdit::isReadOnly //! is still false. bool m_internalReadOnly; //! Used in slotTextChanged() bool m_slotTextChanged_enabled; QString m_originalText; int m_cursorPosition; QPalette m_originalPalette; //!< Used for read-only case bool m_paletteChangeEvent_enabled; bool m_inStyleChangeEvent; QPointer m_internalStyle; }; #endif diff --git a/src/plugins/forms/widgets/kexidbprogressbar.h b/src/plugins/forms/widgets/kexidbprogressbar.h index af7f11428..de3ba078e 100644 --- a/src/plugins/forms/widgets/kexidbprogressbar.h +++ b/src/plugins/forms/widgets/kexidbprogressbar.h @@ -1,90 +1,90 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2005 Jarosław Staniek Copyright (C) 2012 Oleg Kukharchuk This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBPROGRESSBAR_H #define KEXIDBPROGRESSBAR_H #include "kexiformutils_export.h" #include #include #include //! @short A db-aware Progress bar class KEXIFORMUTILS_EXPORT KexiDBProgressBar : public QProgressBar, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) public: explicit KexiDBProgressBar(QWidget *parent = 0); virtual ~KexiDBProgressBar(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); - virtual void setInvalidState(const QString& displayText); + virtual QVariant value() override; + virtual void setInvalidState(const QString& displayText) override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; /*! \return 'readOnly' flag for this widget. */ - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; /*! \return the view widget of this item, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; virtual void setEnabled(bool enabled); public Q_SLOTS: inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } void slotValueChanged(); - virtual void setReadOnly(bool set); + virtual void setReadOnly(bool set) override; protected: - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; private: bool m_invalidState; }; #endif diff --git a/src/plugins/forms/widgets/kexidbslider.h b/src/plugins/forms/widgets/kexidbslider.h index 4aced5d8b..e5af1b4dd 100644 --- a/src/plugins/forms/widgets/kexidbslider.h +++ b/src/plugins/forms/widgets/kexidbslider.h @@ -1,92 +1,92 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2005 Jarosław Staniek Copyright (C) 2012 Oleg Kukharchuk This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBSLIDER_H #define KEXIDBSLIDER_H #include "kexiformutils_export.h" #include #include #include //! @short A db-aware slider class KEXIFORMUTILS_EXPORT KexiDBSlider : public KexiSlider, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) public: explicit KexiDBSlider(QWidget *parent = 0); virtual ~KexiDBSlider(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); - virtual void setInvalidState(const QString& displayText); + virtual QVariant value() override; + virtual void setInvalidState(const QString& displayText) override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; /*! \return 'readOnly' flag for this widget. */ - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; /*! \return the view widget of this item, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; virtual void setEnabled(bool enabled); public Q_SLOTS: inline void setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); } inline void setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); } void slotValueChanged(); - virtual void setReadOnly(bool set); + virtual void setReadOnly(bool set) override; protected: - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; private: bool m_invalidState; }; #endif diff --git a/src/plugins/forms/widgets/kexidbtextedit.cpp b/src/plugins/forms/widgets/kexidbtextedit.cpp index 4c15dd2c4..292a1f4e4 100644 --- a/src/plugins/forms/widgets/kexidbtextedit.cpp +++ b/src/plugins/forms/widgets/kexidbtextedit.cpp @@ -1,395 +1,395 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2012 Jarosław Staniek Copyright (C) 2014 Wojciech Kosowicz This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexidbtextedit.h" #include "kexidblineedit.h" #include #include #include #include #include #include #include #include #include class DataSourceLabel : public QLabel { Q_OBJECT public: explicit DataSourceLabel(QWidget *parent) : QLabel(parent) { } protected: - void paintEvent(QPaintEvent *pe) + void paintEvent(QPaintEvent *pe) override { QLabel::paintEvent(pe); QPainter p(this); int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); QRect r( rect() ); r.setX(r.x() + leftMargin); r.setY(r.y() + topMargin); r.setRight(r.right() - rightMargin); r.setBottom(r.bottom() - bottomMargin); QPixmap dataSourceTagIcon; int x; if (layoutDirection() == Qt::LeftToRight) { dataSourceTagIcon = KexiFormUtils::dataSourceTagIcon(); x = r.left() - 1; } else { dataSourceTagIcon = KexiFormUtils::dataSourceRTLTagIcon(); x = r.right() - dataSourceTagIcon.width() - 5; } p.drawPixmap( x, r.top() + (r.height() - dataSourceTagIcon.height()) / 2, dataSourceTagIcon ); } }; // -------------- KexiDBTextEdit::KexiDBTextEdit(QWidget *parent) : KTextEdit(parent) , KexiDBTextWidgetInterface() , KexiFormDataItemInterface() , m_menuExtender(this, this) , m_slotTextChanged_enabled(true) , m_dataSourceLabel(0) , m_length(0) , m_paletteChangeEvent_enabled(true) { QFont tmpFont; tmpFont.setPointSize(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont).pointSize()); setMinimumHeight(QFontMetrics(tmpFont).height() + 6); connect(this, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); //hmm disabled again because this makes the widget disappear entirely // setAutoFillBackground(true); // otherwise we get transparent background... // installEventFilter(this); setBackgroundRole(QPalette::Base); setAcceptRichText(false); } KexiDBTextEdit::~KexiDBTextEdit() { } void KexiDBTextEdit::setInvalidState(const QString& displayText) { setReadOnly(true); //! @todo move this to KexiDataItemInterface::setInvalidStateInternal() ? if (focusPolicy() & Qt::TabFocus) setFocusPolicy(Qt::ClickFocus); KTextEdit::setPlainText(displayText); } void KexiDBTextEdit::setValueInternal(const QVariant& add, bool removeOld) { //! @todo how about rich text? if (m_columnInfo && m_columnInfo->field()->type() == KDbField::Boolean) { //! @todo temporary solution for booleans! KTextEdit::setHtml(add.toBool() ? "1" : "0"); } else { QString t; if (removeOld) { t = add.toString(); } else { t = KexiDataItemInterface::originalValue().toString() + add.toString(); } if (acceptRichText()) { KTextEdit::setHtml(t); } else { KTextEdit::setPlainText(t); } } } QVariant KexiDBTextEdit::value() { return acceptRichText() ? toHtml() : toPlainText(); } void KexiDBTextEdit::slotTextChanged() { if (!m_slotTextChanged_enabled) return; if (m_length > 0) { QString t; if (acceptRichText()) { t = toHtml(); } else { t = toPlainText(); } if (t.length() > (int)m_length) { m_slotTextChanged_enabled = false; if (acceptRichText()) { //! @todo KEXI3 setHtml(t.left(m_length)); } else { setPlainText(t.left(m_length)); } m_slotTextChanged_enabled = true; moveCursorToEnd(); } } signalValueChanged(); } bool KexiDBTextEdit::valueIsNull() { return (acceptRichText() ? toHtml() : toPlainText()).isNull(); } bool KexiDBTextEdit::valueIsEmpty() { return (acceptRichText() ? toHtml() : toPlainText()).isEmpty(); } bool KexiDBTextEdit::isReadOnly() const { return KTextEdit::isReadOnly(); } void KexiDBTextEdit::setReadOnly(bool readOnly) { KTextEdit::setReadOnly(readOnly); //! @todo KEXI3 KexiDBTextEdit::setReadOnly() - bg color #if 0//TODO QPalette p = palette(); QColor c(readOnly ? KexiFormUtils::lighterGrayBackgroundColor(kapp->palette()) : p.color(QPalette::Active, QPalette::Base)); setPaper(c); p.setColor(QPalette::Base, c); p.setColor(QPalette::Background, c); setPalette(p); #endif } QWidget* KexiDBTextEdit::widget() { return this; } bool KexiDBTextEdit::cursorAtStart() { return textCursor().atStart(); } bool KexiDBTextEdit::cursorAtEnd() { return textCursor().atEnd(); } void KexiDBTextEdit::clear() { document()->clear(); } void KexiDBTextEdit::setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) { KexiFormDataItemInterface::setColumnInfo(conn, cinfo); if (!cinfo) { m_length = 0; return; } if (cinfo->field()->type() == KDbField::Text) { if (!designMode()) { if (cinfo->field()->maxLength() > 0) { m_length = cinfo->field()->maxLength(); } } } KexiDBTextWidgetInterface::setColumnInfo(m_columnInfo, this); } void KexiDBTextEdit::paintEvent(QPaintEvent *pe) { KTextEdit::paintEvent(pe); QPainter p(viewport()); //! @todo how about rich text? KexiDBTextWidgetInterface::paint(this, &p, toPlainText().isEmpty(), alignment(), hasFocus()); } void KexiDBTextEdit::contextMenuEvent(QContextMenuEvent *e) { QMenu *menu = createStandardContextMenu(); m_menuExtender.exec(menu, e->globalPos()); delete menu; } void KexiDBTextEdit::undo() { cancelEditor(); } void KexiDBTextEdit::setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue) { KexiFormDataItemInterface::setDisplayDefaultValue(widget, displayDefaultValue); // initialize display parameters for default / entered value KexiDisplayUtils::DisplayParameters * const params = displayDefaultValue ? m_displayParametersForDefaultValue : m_displayParametersForEnteredValue; QPalette pal(palette()); pal.setColor(QPalette::Active, QPalette::Text, params->textColor); setPalette(pal); setFont(params->font); //! @todo support rich text... /* m_slotTextChanged_enabled = false; //for rich text... const QString origText( text() ); KTextEdit::setText(QString()); setCurrentFont(params->font); setColor(params->textColor); KTextEdit::setText(origText); m_slotTextChanged_enabled = true;*/ } void KexiDBTextEdit::moveCursorToEnd() { moveCursor(QTextCursor::End); } void KexiDBTextEdit::moveCursorToStart() { moveCursor(QTextCursor::Start); } void KexiDBTextEdit::selectAll() { KTextEdit::selectAll(); } void KexiDBTextEdit::keyPressEvent(QKeyEvent *ke) { // for instance, Windows uses Ctrl+Tab for moving between tabs, so do not steal this shortcut if (KStandardShortcut::tabNext().contains(QKeySequence(ke->key() | ke->modifiers())) || KStandardShortcut::tabPrev().contains(QKeySequence(ke->key() | ke->modifiers()))) { ke->ignore(); return; } KTextEdit::keyPressEvent(ke); } bool KexiDBTextEdit::event(QEvent *e) { bool res = KTextEdit::event(e); if (e->type() == QEvent::LayoutDirectionChange) { if (m_dataSourceLabel) { m_dataSourceLabel->setLayoutDirection( layoutDirection() ); } updateTextForDataSource(); } else if (e->type() == QEvent::Resize) { if (m_dataSourceLabel) { m_dataSourceLabel->setFixedWidth(width()); } } return res; } void KexiDBTextEdit::updateTextForDataSource() { if (!designMode()) { if (m_dataSourceLabel) { m_dataSourceLabel->hide(); } return; } setPlainText(QString()); if (!m_dataSourceLabel && !dataSource().isEmpty()) { createDataSourceLabel(); } if (m_dataSourceLabel) { m_dataSourceLabel->setText(dataSource()); m_dataSourceLabel->setIndent( KexiFormUtils::dataSourceTagIcon().width() + (layoutDirection() == Qt::LeftToRight ? 0 : 7) ); m_dataSourceLabel->setVisible(!dataSource().isEmpty()); } } void KexiDBTextEdit::setDataSource(const QString &ds) { KexiFormDataItemInterface::setDataSource(ds); updateTextForDataSource(); } void KexiDBTextEdit::setDataSourcePluginId(const QString &pluginId) { KexiFormDataItemInterface::setDataSourcePluginId(pluginId); updateTextForDataSource(); } void KexiDBTextEdit::createDataSourceLabel() { if (m_dataSourceLabel) return; m_dataSourceLabel = new DataSourceLabel(viewport()); m_dataSourceLabel->hide(); m_dataSourceLabel->move(0, 0); int leftMargin, topMargin, rightMargin, bottomMargin; getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); m_dataSourceLabel->setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin); } void KexiDBTextEdit::selectAllOnFocusIfNeeded() { } void KexiDBTextEdit::focusOutEvent(QFocusEvent *e) { KTextEdit::focusOutEvent(e); if (textCursor().hasSelection()) { moveCursorToEnd(); } } void KexiDBTextEdit::updatePalette() { m_paletteChangeEvent_enabled = false; setPalette(isReadOnly() ? KexiUtils::paletteForReadOnly(m_originalPalette) : m_originalPalette); m_paletteChangeEvent_enabled = true; } void KexiDBTextEdit::changeEvent(QEvent *e) { if (e->type() == QEvent::PaletteChange && m_paletteChangeEvent_enabled) { m_originalPalette = palette(); updatePalette(); } KTextEdit::changeEvent(e); } #include "kexidbtextedit.moc" diff --git a/src/plugins/forms/widgets/kexidbtextedit.h b/src/plugins/forms/widgets/kexidbtextedit.h index ecdd1c860..fb8643062 100644 --- a/src/plugins/forms/widgets/kexidbtextedit.h +++ b/src/plugins/forms/widgets/kexidbtextedit.h @@ -1,144 +1,144 @@ /* This file is part of the KDE project Copyright (C) 2005 Cedric Pasteur Copyright (C) 2004-2012 Jarosław Staniek Copyright (C) 2014 Wojciech Kosowicz This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDBTEXTEDIT_H #define KEXIDBTEXTEDIT_H #include #include "kexidbtextwidgetinterface.h" #include "kexidbutils.h" #include #include #include class DataSourceLabel; //! @short Multiline edit widget for Kexi forms class KEXIFORMUTILS_EXPORT KexiDBTextEdit : public KTextEdit, protected KexiDBTextWidgetInterface, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) public: explicit KexiDBTextEdit(QWidget *parent); virtual ~KexiDBTextEdit(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } - virtual QVariant value(); - virtual void setInvalidState(const QString& displayText); + virtual QVariant value() override; + virtual void setInvalidState(const QString& displayText) override; //! \return true if editor's value is null (not empty) //! Used for checking if a given constraint within table of form is met. - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not necessary null). //! Only few data types can accept "EMPTY" property //! (use KDbField::hasEmptyProperty() to check this). //! Used for checking if a given constraint within table or form is met. - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; /*! \return 'readOnly' flag for this widget. */ - virtual bool isReadOnly() const; + virtual bool isReadOnly() const override; /*! \return the view widget of this item, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override; /*! If \a displayDefaultValue is true, the value set by KexiDataItemInterface::setValue() is displayed in a special way. Used by KexiFormDataProvider::fillDataItems(). \a widget is equal to 'this'. Reimplemented after KexiFormDataItemInterface. */ - virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue); + virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue) override; //! Windows uses Ctrl+Tab for moving between tabs, so do not steal this shortcut - virtual void keyPressEvent(QKeyEvent *ke); + virtual void keyPressEvent(QKeyEvent *ke) override; - virtual bool event(QEvent *e); + virtual bool event(QEvent *e) override; //! Selects contents of the widget if there is such behaviour set (it is by default). //! @todo add option for not selecting the field - virtual void selectAllOnFocusIfNeeded(); + virtual void selectAllOnFocusIfNeeded() override; public Q_SLOTS: void setDataSource(const QString &ds); void setDataSourcePluginId(const QString &pluginId); - virtual void setReadOnly(bool readOnly); + virtual void setReadOnly(bool readOnly) override; //! Reimplemented, so "undo" means the same as "cancelEditor" action //! @todo enable "real" undo internally so user can use ctrl+z while editing virtual void undo(); //! Implemented for KexiDataItemInterface - virtual void moveCursorToEnd(); + virtual void moveCursorToEnd() override; //! Implemented for KexiDataItemInterface - virtual void moveCursorToStart(); + virtual void moveCursorToStart() override; //! Implemented for KexiDataItemInterface - virtual void selectAll(); + virtual void selectAll() override; protected Q_SLOTS: void slotTextChanged(); protected: - virtual void paintEvent(QPaintEvent *); - virtual void contextMenuEvent(QContextMenuEvent *e); - virtual void changeEvent(QEvent *e); - virtual void setValueInternal(const QVariant& add, bool removeOld); - virtual void focusOutEvent(QFocusEvent *e); + virtual void paintEvent(QPaintEvent *) override; + virtual void contextMenuEvent(QContextMenuEvent *e) override; + virtual void changeEvent(QEvent *e) override; + virtual void setValueInternal(const QVariant& add, bool removeOld) override; + virtual void focusOutEvent(QFocusEvent *e) override; QMenu * createPopupMenu(const QPoint & pos); void updateTextForDataSource(); void createDataSourceLabel(); void updatePalette(); private: //! Used for extending context menu KexiDBWidgetContextMenuExtender m_menuExtender; //! Used to disable slotTextChanged() bool m_slotTextChanged_enabled; DataSourceLabel *m_dataSourceLabel; //! Text length allowed int m_length; QPalette m_originalPalette; //!< Used for read-only case bool m_paletteChangeEvent_enabled; }; #endif diff --git a/src/plugins/forms/widgets/kexiframe.h b/src/plugins/forms/widgets/kexiframe.h index 232ff261d..cfe2fdb12 100644 --- a/src/plugins/forms/widgets/kexiframe.h +++ b/src/plugins/forms/widgets/kexiframe.h @@ -1,92 +1,92 @@ /* This file is part of the KDE project Copyright (C) 2005-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIFRAME_H #define KEXIFRAME_H #include "kexiformutils_export.h" #include #include //! @short Frame widget for Kexi forms class KEXIFORMUTILS_EXPORT KexiFrame : public QFrame, public KFormDesigner::FormWidgetInterface { Q_OBJECT //! @todo Q_ENUMS( Shape Shadow ) Q_PROPERTY(QColor frameColor READ frameColor WRITE setFrameColor) //! @todo Q_PROPERTY( Shape frameShape READ frameShape WRITE setFrameShape ) //! @todo Q_PROPERTY( Shadow frameShadow READ frameShadow WRITE setFrameShadow ) public: explicit KexiFrame(QWidget * parent, Qt::WindowFlags f = 0); virtual ~KexiFrame(); virtual QColor frameColor() const; #if 0 //! @todo more options enum Shadow { NoShadow = QFrame::Plain, Raised = QFrame::Raised, Sunken = QFrame::Sunken }; //! @todo more options enum Shape { NoFrame = QFrame::NoFrame, //!< no frame Box = QFrame::Box, //!< rectangular box Panel = QFrame::Panel, //!< rectangular panel StyledPanel = QFrame::StyledPanel, //!< rectangular panel depending on the GUI style GroupBoxPanel = QFrame::GroupBoxPanel //!< rectangular group-box-like panel depending on the GUI style }; Shape frameShape() const; void setFrameShape(KexiFrame::Shape shape); Shadow frameShadow() const; void setFrameShadow(KexiFrame::Shadow shadow); #endif //! Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface - virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e) override; //! Used to emit handleDropEvent() signal needed to control dropping on the container's surface - virtual void dropEvent(QDropEvent *e); + virtual void dropEvent(QDropEvent *e) override; public Q_SLOTS: virtual void setPalette(const QPalette &pal); virtual void setFrameColor(const QColor& color); Q_SIGNALS: //! Needed to control dragging over the container's surface void handleDragMoveEvent(QDragMoveEvent *e); //! Needed to control dropping on the container's surface void handleDropEvent(QDropEvent *e); protected: virtual void drawFrame(QPainter *); //! Adds frame in design mode if there is no frame - void paintEvent(QPaintEvent *pe); + void paintEvent(QPaintEvent *pe) override; class Private; Private * const d; }; #endif diff --git a/src/plugins/forms/widgets/main/KexiMainFormWidgetsFactory.h b/src/plugins/forms/widgets/main/KexiMainFormWidgetsFactory.h index 9c86bacda..733b345fd 100644 --- a/src/plugins/forms/widgets/main/KexiMainFormWidgetsFactory.h +++ b/src/plugins/forms/widgets/main/KexiMainFormWidgetsFactory.h @@ -1,90 +1,90 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2016 Jarosław Staniek 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 KEXIMAINFORMWIDGETSFACTORY_H #define KEXIMAINFORMWIDGETSFACTORY_H #include "kexidbfactorybase.h" class QAction; //! Kexi Factory for data-aware widgets //! @todo merge with KexiStandardFormWidgetsFactory class KexiMainFormWidgetsFactory : public KexiDBFactoryBase { Q_OBJECT public: KexiMainFormWidgetsFactory(QObject *parent, const QVariantList &); virtual ~KexiMainFormWidgetsFactory(); QWidget *createWidget(const QByteArray &classname, QWidget *parent, const char *name, KFormDesigner::Container *container, CreateWidgetOptions options = DefaultOptions) override Q_REQUIRED_RESULT; - virtual void createCustomActions(KActionCollection* col); + virtual void createCustomActions(KActionCollection* col) override; virtual bool createMenuActions(const QByteArray &classname, QWidget *w, QMenu *menu, - KFormDesigner::Container *container); - virtual bool startInlineEditing(InlineEditorCreationArguments& args); - virtual bool previewWidget(const QByteArray &, QWidget *, KFormDesigner::Container *); - virtual bool clearWidgetContent(const QByteArray &classname, QWidget *w); + KFormDesigner::Container *container) override; + virtual bool startInlineEditing(InlineEditorCreationArguments& args) override; + virtual bool previewWidget(const QByteArray &, QWidget *, KFormDesigner::Container *) override; + virtual bool clearWidgetContent(const QByteArray &classname, QWidget *w) override; //! Moved into public for EditRichTextAction bool editRichText(QWidget *w, QString &text) const { return KexiDBFactoryBase::editRichText(w, text); } //! Moved into public for EditRichTextAction void changeProperty(KFormDesigner::Form *form, QWidget *widget, const char *name, const QVariant &value) { KexiDBFactoryBase::changeProperty(form, widget, name, value); } bool readSpecialProperty(const QByteArray &classname, QDomElement &node, QWidget *w, KFormDesigner::ObjectTreeItem *item) override; bool saveSpecialProperty(const QByteArray &classname, const QString &name, const QVariant &value, QWidget *w, QDomElement &parentNode, QDomDocument &parent) override; void setPropertyOptions(KPropertySet& set, const KFormDesigner::WidgetInfo& info, QWidget *w) override; protected Q_SLOTS: void slotImageBoxIdChanged(long id); /*KexiBLOBBuffer::Id_t*/ void reorderTabs(int oldpos, int newpos); protected: - KFormDesigner::ObjectTreeItem* selectableItem(KFormDesigner::ObjectTreeItem* item); + KFormDesigner::ObjectTreeItem* selectableItem(KFormDesigner::ObjectTreeItem* item) override; virtual bool changeInlineText(KFormDesigner::Form *form, QWidget *widget, - const QString &text, QString &oldText); - virtual void resizeEditor(QWidget *editor, QWidget *widget, const QByteArray &classname); + const QString &text, QString &oldText) override; + virtual void resizeEditor(QWidget *editor, QWidget *widget, const QByteArray &classname) override; virtual bool isPropertyVisibleInternal(const QByteArray& classname, QWidget *w, - const QByteArray& property, bool isTopLevel); + const QByteArray& property, bool isTopLevel) override; //! Sometimes property sets should be reloaded when a given property value changed. //! @todo this does not seem to work in Kexi 2.x virtual bool propertySetShouldBeReloadedAfterPropertyChange(const QByteArray& classname, QWidget *w, - const QByteArray& property); + const QByteArray& property) override; QAction * m_assignAction; }; #endif diff --git a/src/plugins/forms/widgets/main/KexiStandardContainerFormWidgets.h b/src/plugins/forms/widgets/main/KexiStandardContainerFormWidgets.h index 41271151e..260aa6ca0 100644 --- a/src/plugins/forms/widgets/main/KexiStandardContainerFormWidgets.h +++ b/src/plugins/forms/widgets/main/KexiStandardContainerFormWidgets.h @@ -1,265 +1,265 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004 Cedric Pasteur Copyright (C) 2006-2010 Jarosław Staniek 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 KEXISTANDARDCONTAINERWIDGETS_H #define KEXISTANDARDCONTAINERWIDGETS_H #include "FormWidgetInterface.h" #include "utils.h" #include #include class QPaintEvent; namespace KFormDesigner { class Container; } //! Helper widget (used when using 'Lay out horizontally') class HBox : public QFrame, public KFormDesigner::FormWidgetInterface { Q_OBJECT public: explicit HBox(QWidget *parent); virtual ~HBox(); - virtual void paintEvent(QPaintEvent *ev); + virtual void paintEvent(QPaintEvent *ev) override; }; //! Helper widget (used when using 'Lay out vertically') class VBox : public QFrame, public KFormDesigner::FormWidgetInterface { Q_OBJECT public: explicit VBox(QWidget *parent); virtual ~VBox(); - virtual void paintEvent(QPaintEvent *ev); + virtual void paintEvent(QPaintEvent *ev) override; }; //! Helper widget (used when using 'Lay out in a grid') class Grid : public QFrame, public KFormDesigner::FormWidgetInterface { Q_OBJECT public: explicit Grid(QWidget *parent); virtual ~Grid(); - virtual void paintEvent(QPaintEvent *ev); + virtual void paintEvent(QPaintEvent *ev) override; }; //! Helper widget (used when using 'Lay out with horizontal flow') class HFlow : public QFrame, public KFormDesigner::FormWidgetInterface { Q_OBJECT public: explicit HFlow(QWidget *parent); virtual ~HFlow(); - virtual void paintEvent(QPaintEvent *ev); + virtual void paintEvent(QPaintEvent *ev) override; }; //! Helper widget (used when using 'Lay out with horizontal flow') class VFlow : public QFrame, public KFormDesigner::FormWidgetInterface { Q_OBJECT public: explicit VFlow(QWidget *parent); virtual ~VFlow(); - virtual void paintEvent(QPaintEvent *ev); - virtual QSize sizeHint() const; + virtual void paintEvent(QPaintEvent *ev) override; + virtual QSize sizeHint() const override; }; //! A simple container widget class ContainerWidget : public QWidget { Q_OBJECT friend class KFDTabWidget; public: explicit ContainerWidget(QWidget *parent); virtual ~ContainerWidget(); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; //! Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface - virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e) override; //! Used to emit handleDropEvent() signal needed to control dropping on the container's surface - virtual void dropEvent(QDropEvent *e); + virtual void dropEvent(QDropEvent *e) override; Q_SIGNALS: //! Needed to control dragging over the container's surface void handleDragMoveEvent(QDragMoveEvent *e); //! Needed to control dropping on the container's surface void handleDropEvent(QDropEvent *e); }; //! Action of adding tab to a tab widget //! Keeps context expressed using container and receiver widget class AddTabAction : public QAction { Q_OBJECT public: AddTabAction(KFormDesigner::Container *container, TabWidgetBase *receiver, QObject *parent); public Q_SLOTS: void slotTriggered(); private: KFormDesigner::Container *m_container; TabWidgetBase *m_receiver; }; //! Action of removing tab from a tab widget //! Keeps context expressed using container and receiver widget class RemoveTabAction : public QAction { Q_OBJECT public: RemoveTabAction(KFormDesigner::Container *container, TabWidgetBase *receiver, QObject *parent); protected Q_SLOTS: void slotTriggered(); private: KFormDesigner::Container *m_container; TabWidgetBase *m_receiver; }; //! Action renaming tab widget's tab //! Keeps context expressed using container and receiver widget class RenameTabAction : public QAction { Q_OBJECT public: RenameTabAction(KFormDesigner::Container *container, TabWidgetBase *receiver, QObject *parent); protected Q_SLOTS: void slotTriggered(); private: KFormDesigner::Container *m_container; TabWidgetBase *m_receiver; }; //! Action of adding page to a stacked widget //! Keeps context expressed using container and receiver widget class AddStackPageAction : public QAction { Q_OBJECT public: AddStackPageAction(KFormDesigner::Container *container, QWidget *receiver, QObject *parent); protected Q_SLOTS: void slotTriggered(); private: KFormDesigner::Container *m_container; QWidget *m_receiver; }; //! Action of removing page from a stacked widget //! Keeps context expressed using container and receiver widget class RemoveStackPageAction : public QAction { Q_OBJECT public: RemoveStackPageAction(KFormDesigner::Container *container, QWidget *receiver, QObject *parent); protected Q_SLOTS: void slotTriggered(); private: KFormDesigner::Container *m_container; QWidget *m_receiver; }; //! Action of moving between pages of a stacked widget //! Keeps context expressed using container and receiver widget class GoToStackPageAction : public QAction { Q_OBJECT public: enum Direction { Previous, Next }; GoToStackPageAction(Direction direction, KFormDesigner::Container *container, QWidget *receiver, QObject *parent); protected Q_SLOTS: void slotTriggered(); private: int nextWidgetIndex() const; Direction m_direction; KFormDesigner::Container *m_container; QWidget *m_receiver; }; //! A tab widget class KFDTabWidget : public KFormDesigner::TabWidget { Q_OBJECT public: KFDTabWidget(KFormDesigner::Container *container, QWidget *parent); virtual ~KFDTabWidget(); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; //! Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface - virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e) override; //! Used to emit handleDropEvent() signal needed to control dropping on the container's surface - virtual void dropEvent(QDropEvent *e); + virtual void dropEvent(QDropEvent *e) override; KFormDesigner::Container *container() const { return m_container; } Q_SIGNALS: //! Needed to control dragging over the container's surface void handleDragMoveEvent(QDragMoveEvent *e); //! Needed to control dropping on the container's surface void handleDropEvent(QDropEvent *e); private: KFormDesigner::Container *m_container; }; //! A group box widget class GroupBox : public QGroupBox { Q_OBJECT public: GroupBox(const QString & title, QWidget *parent); virtual ~GroupBox(); //! Used to emit handleDragMoveEvent() signal needed to control dragging over the container's surface - virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e) override; //! Used to emit handleDropEvent() signal needed to control dropping on the container's surface - virtual void dropEvent(QDropEvent *e); + virtual void dropEvent(QDropEvent *e) override; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; Q_SIGNALS: //! Needed to control dragging over the container's surface void handleDragMoveEvent(QDragMoveEvent *e); //! Needed to control dropping on the container's surface void handleDropEvent(QDropEvent *e); }; #endif diff --git a/src/plugins/forms/widgets/webbrowser/WebBrowserFactory.h b/src/plugins/forms/widgets/webbrowser/WebBrowserFactory.h index 576bb9ef2..bd696a083 100644 --- a/src/plugins/forms/widgets/webbrowser/WebBrowserFactory.h +++ b/src/plugins/forms/widgets/webbrowser/WebBrowserFactory.h @@ -1,43 +1,43 @@ /* Copyright (C) 2011 Shreya Pandit This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef WEBBROWSERFACTORY_H #define WEBBROWSERFACTORY_H #include "kexidbfactorybase.h" //! Factory providing web browser widget class WebBrowserFactory: public KexiDBFactoryBase { Q_OBJECT public: WebBrowserFactory(QObject* parent, const QVariantList &args); virtual ~WebBrowserFactory(); QWidget *createWidget(const QByteArray &classname, QWidget *parent, const char *name, KFormDesigner::Container *container, CreateWidgetOptions options = DefaultOptions) override Q_REQUIRED_RESULT; virtual bool createMenuActions(const QByteArray &classname, QWidget *w, QMenu *menu, - KFormDesigner::Container *container); - virtual bool startInlineEditing(InlineEditorCreationArguments& args); + KFormDesigner::Container *container) override; + virtual bool startInlineEditing(InlineEditorCreationArguments& args) override; virtual bool previewWidget(const QByteArray &classname, QWidget *widget, - KFormDesigner::Container *container); + KFormDesigner::Container *container) override; }; #endif // WEBBROWSERFACTORY_H diff --git a/src/plugins/forms/widgets/webbrowser/WebBrowserWidget.h b/src/plugins/forms/widgets/webbrowser/WebBrowserWidget.h index cf860c460..e0136a30a 100644 --- a/src/plugins/forms/widgets/webbrowser/WebBrowserWidget.h +++ b/src/plugins/forms/widgets/webbrowser/WebBrowserWidget.h @@ -1,134 +1,134 @@ /* This file is part of the KDE project Copyright (C) 2011 Shreya Pandit 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 WEBBROWSERWIDGET_H #define WEBBROWSERWIDGET_H #include #include #include "widgetfactory.h" #include "container.h" #include #include #include #include #include #include class QPushButton; class QWebView; class QVBoxLayout; class QWebHistory; class QHBoxLayout; class QProgressBar; class QHBoxLayout; class QUrl; class WebBrowserWidget : public QWidget, public KexiFormDataItemInterface, public KFormDesigner::FormWidgetInterface { Q_OBJECT Q_PROPERTY(QString dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString dataSourcePartClass READ dataSourcePluginId WRITE setDataSourcePluginId) Q_PROPERTY(QString url READ url WRITE setUrl) Q_PROPERTY(qreal zoomFactor READ zoomFactor WRITE setZoomFactor) Q_PROPERTY(QString title READ title) Q_PROPERTY(QIcon icon READ icon) Q_PROPERTY(bool modified READ modified) Q_PROPERTY(qreal textScale READ textScale WRITE setTextScale) public: explicit WebBrowserWidget(QWidget *parent = 0); ~WebBrowserWidget(); inline QString dataSource() const { return KexiFormDataItemInterface::dataSource(); } inline QString dataSourcePluginId() const { return KexiFormDataItemInterface::dataSourcePluginId(); } inline QString url() const { return m_view->url().toString(); } inline bool modified() const { return m_view->isModified(); } inline QString title() const { return m_view->title(); } inline qreal zoomFactor() const { return m_view->zoomFactor(); } inline QIcon icon() const { return m_view->icon(); } inline qreal textScale () const { return m_view->textSizeMultiplier(); } - virtual QVariant value(); - virtual bool valueIsNull(); - virtual bool valueIsEmpty(); - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); - virtual void clear(); + virtual QVariant value() override; + virtual bool valueIsNull() override; + virtual bool valueIsEmpty() override; + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; + virtual void clear() override; void updateToolBar(); - bool isReadOnly() const; - virtual void setReadOnly(bool readOnly); - virtual void setInvalidState(const QString& displayText); + bool isReadOnly() const override; + virtual void setReadOnly(bool readOnly) override; + virtual void setInvalidState(const QString& displayText) override; public Q_SLOTS: void setDataSource(const QString &ds); void setDataSourcePluginId(const QString &ds); void setUrl(const QString& url); void setZoomFactor(qreal factor); void setTextScale(qreal scale); void hide_bar(); protected: - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; void setUrl(const QUrl& url); bool m_readOnly; private: QWebView* m_view; QVBoxLayout* v_layout; QProgressBar* m_pbar; bool m_urlChanged_enabled; QPushButton* m_back; QPushButton* m_forward; QPushButton* m_reload; QPushButton* m_stop; QHBoxLayout* h_layout; }; #endif diff --git a/src/plugins/importexport/csv/KexiCSVImportDialogModel.h b/src/plugins/importexport/csv/KexiCSVImportDialogModel.h index 1925ccc61..5a856fec6 100644 --- a/src/plugins/importexport/csv/KexiCSVImportDialogModel.h +++ b/src/plugins/importexport/csv/KexiCSVImportDialogModel.h @@ -1,60 +1,60 @@ /* This file is part of the KDE project Copyright (C) 2005-2015 Jarosław Staniek Copyright (C) 2012 Oleg Kukharchuk This work is based on kspread/dialogs/kspread_dlg_csv.cc. Copyright (C) 2002-2003 Norbert Andres Copyright (C) 2002-2003 Ariya Hidayat Copyright (C) 2002 Laurent Montel Copyright (C) 1999 David Faure 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 KEXICSVIMPORTDIALOGMODEL_H #define KEXICSVIMPORTDIALOGMODEL_H #include //! Model for displaying data of CSV import dialog. //! @see KexiCSVImportDialog class KexiCSVImportDialogModel : public QStandardItemModel { Q_OBJECT public: explicit KexiCSVImportDialogModel(QObject *parent); virtual ~KexiCSVImportDialogModel(); - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const override; void setColumnCount(int col); bool firstRowForFieldNames() const; void setFirstRowForFieldNames(bool flag); private: class Private; Private * const d; }; #endif diff --git a/src/plugins/importexport/csv/KexiCsvImportExportPlugin.h b/src/plugins/importexport/csv/KexiCsvImportExportPlugin.h index 8dae2fd13..30e0495e9 100644 --- a/src/plugins/importexport/csv/KexiCsvImportExportPlugin.h +++ b/src/plugins/importexport/csv/KexiCsvImportExportPlugin.h @@ -1,44 +1,44 @@ /* This file is part of the KDE project Copyright (C) 2005 Jarosław Staniek 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 KEXI_CSVIMPORTEXPORT_PART_H #define KEXI_CSVIMPORTEXPORT_PART_H #include #include "kexicsvexportwizard.h" //! Internal plugin for CSV import/export class KexiCsvImportExportPlugin : public KexiInternalPart { Q_OBJECT public: KexiCsvImportExportPlugin(QObject *parent, const QVariantList &args); virtual ~KexiCsvImportExportPlugin(); /*! Reimplemented to return wizard object. */ QWidget *createWidget(const char *widgetClass, QWidget *parent, const char *objName = nullptr, QMap *args = nullptr) override Q_REQUIRED_RESULT; /*! Reimplemented to execute a command \a commandName (nonvisual). The result are put into the \a args. */ - virtual bool executeCommand(const char* commandName, QMap* args = 0); + virtual bool executeCommand(const char* commandName, QMap* args = 0) override; protected: }; #endif diff --git a/src/plugins/importexport/csv/kexicsvexportwizard.h b/src/plugins/importexport/csv/kexicsvexportwizard.h index a1f278c76..1f66516e5 100644 --- a/src/plugins/importexport/csv/kexicsvexportwizard.h +++ b/src/plugins/importexport/csv/kexicsvexportwizard.h @@ -1,113 +1,113 @@ /* This file is part of the KDE project Copyright (C) 2012 Oleg Kukharchuk Copyright (C) 2005-2017 Jarosław Staniek 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 KEXI_CSVEXPORTWIZARD_H #define KEXI_CSVEXPORTWIZARD_H #include #include #include #include "kexicsvexport.h" class QCheckBox; class QGroupBox; class QPushButton; class KexiCSVDelimiterWidget; class KexiCSVTextQuoteComboBox; class KexiCSVInfoLabel; class KexiCharacterEncodingComboBox; class KexiFileWidgetInterface; class KPageWidgetItem; class KDbTableOrQuerySchema; /*! @short Kexi CSV export wizard Supports exporting to a file and to a clipboard. */ class KexiCSVExportWizard : public KAssistantDialog { Q_OBJECT public: explicit KexiCSVExportWizard(const KexiCSVExport::Options& options, QWidget * parent = 0); virtual ~KexiCSVExportWizard(); bool canceled() const; protected Q_SLOTS: - virtual void next(); - virtual void done(int result); + virtual void next() override; + virtual void done(int result) override; void slotShowOptionsButtonClicked(); void slotDefaultsButtonClicked(); void slotCurrentPageChanged(KPageWidgetItem*, KPageWidgetItem*); protected: //! \return default delimiter depending on mode. QString defaultDelimiter() const; //! \return default text quote depending on mode. QString defaultTextQuote() const; //! Helper, works like KSharedConfig::openConfig()->readBoolEntry(const char*, bool) but if mode is Clipboard, //! "Exporting" is replaced with "Copying" and "Export" is replaced with "Copy" //! and "CSVFiles" is replaced with "CSVToClipboard" //! in \a key, to keep the setting separate. bool readBoolEntry(const char *key, bool defaultValue); //! Helper like \ref readBoolEntry(const char *, bool), but for QString values. QString readEntry(const char *key, const QString& defaultValue = QString()); //! Helper, works like KSharedConfig::openConfig()->writeEntry(const char*,bool) but if mode is Clipboard, //! "Exporting" is replaced with "Copying" and "Export" is replaced with "Copy" //! and "CSVFiles" is replaced with "CSVToClipboard" //! in \a key, to keep the setting separate. void writeEntry(const char *key, bool value); //! Helper like \ref writeEntry(const char *, bool), but for QString values. void writeEntry(const char *key, const QString& value); //! Helper like \ref writeEntry(const char *, bool), but for deleting config entry. void deleteEntry(const char *key); QString selectedFile() const; KexiCSVExport::Options m_options; QWidget* m_exportOptionsWidget = nullptr; KPageWidgetItem *m_fileSavePage = nullptr; KPageWidgetItem *m_exportOptionsPage = nullptr; QPushButton *m_showOptionsButton = nullptr; QPushButton *m_defaultsBtn = nullptr; QGroupBox* m_exportOptionsSection = nullptr; KexiCSVInfoLabel *m_infoLblFrom = nullptr; KexiCSVInfoLabel *m_infoLblTo = nullptr; KexiCSVDelimiterWidget* m_delimiterWidget = nullptr; KexiCSVTextQuoteComboBox* m_textQuote = nullptr; KexiCharacterEncodingComboBox *m_characterEncodingCombo = nullptr; QCheckBox *m_addColumnNamesCheckBox = nullptr; QCheckBox *m_alwaysUseCheckBox = nullptr; KexiFileWidgetInterface *m_fileIface = nullptr; KDbTableOrQuerySchema* m_tableOrQuery; KConfigGroup m_importExportGroup; bool m_canceled = false; }; #endif diff --git a/src/plugins/importexport/csv/kexicsvimportdialog.cpp b/src/plugins/importexport/csv/kexicsvimportdialog.cpp index 61c0ee324..ebed8ed43 100644 --- a/src/plugins/importexport/csv/kexicsvimportdialog.cpp +++ b/src/plugins/importexport/csv/kexicsvimportdialog.cpp @@ -1,2177 +1,2177 @@ /* This file is part of the KDE project Copyright (C) 2005-2017 Jarosław Staniek Copyright (C) 2012 Oleg Kukharchuk This work is based on kspread/dialogs/kspread_dlg_csv.cc. Copyright (C) 2002-2003 Norbert Andres Copyright (C) 2002-2003 Ariya Hidayat Copyright (C) 2002 Laurent Montel Copyright (C) 1999 David Faure 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. */ #include "kexicsvimportdialog.h" #include "KexiCSVImportDialogModel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kexicsvwidgets.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _IMPORT_ICON koIconNeededWithSubs("change to file_import or so", "file_import","table") //! @internal An item delegate for KexiCSVImportDialog's table view class KexiCSVImportDialogItemDelegate : public QStyledItemDelegate { Q_OBJECT public: KexiCSVImportDialogItemDelegate(QObject *parent = 0); virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const override; }; KexiCSVImportDialogItemDelegate::KexiCSVImportDialogItemDelegate(QObject *parent) : QStyledItemDelegate(parent) { } QWidget* KexiCSVImportDialogItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem newOption(option); QWidget *editor = QStyledItemDelegate::createEditor(parent, newOption, index); if (editor && index.row() == 0) { QFont f(editor->font()); f.setBold(true); editor->setFont(f); } return editor; } // -- //! @internal class KexiCSVImportStatic { public: KexiCSVImportStatic() : types(QVector() << KDbField::Text << KDbField::Integer << KDbField::Double << KDbField::Boolean << KDbField::Date << KDbField::Time << KDbField::DateTime) { typeNames.insert(KDbField::Text, KDbField::typeGroupName(KDbField::TextGroup)); typeNames.insert(KDbField::Integer, KDbField::typeGroupName(KDbField::IntegerGroup)); typeNames.insert(KDbField::Double, KDbField::typeGroupName(KDbField::FloatGroup)); typeNames.insert(KDbField::Boolean, KDbField::typeName(KDbField::Boolean)); typeNames.insert(KDbField::Date, KDbField::typeName(KDbField::Date)); typeNames.insert(KDbField::Time, KDbField::typeName(KDbField::Time)); typeNames.insert(KDbField::DateTime, KDbField::typeName(KDbField::DateTime)); for (int i = 0; i < types.size(); ++i) { indicesForTypes.insert(types[i], i); } } const QVector types; QHash typeNames; QHash indicesForTypes; }; Q_GLOBAL_STATIC(KexiCSVImportStatic, kexiCSVImportStatic) #define MAX_ROWS_TO_PREVIEW 100 //max 100 rows is reasonable #define MAX_BYTES_TO_PREVIEW 10240 //max 10KB is reasonable #define MAX_CHARS_TO_SCAN_WHILE_DETECTING_DELIMITER 4096 #define MINIMUM_YEAR_FOR_100_YEAR_SLIDING_WINDOW 1930 #define PROGRESS_STEP_MS (1000/5) // 5 updates per second static bool shouldSaveRow(int row, bool firstRowForFieldNames) { return row > (firstRowForFieldNames ? 1 : 0); } // -- class Q_DECL_HIDDEN KexiCSVImportDialog::Private { public: Private() : imported(false) { } ~Private() { qDeleteAll(m_uniquenessTest); } void clearDetectedTypes() { m_detectedTypes.clear(); } void clearUniquenessTests() { qDeleteAll(m_uniquenessTest); m_uniquenessTest.clear(); } KDbField::Type detectedType(int col) const { return m_detectedTypes.value(col, KDbField::InvalidType); } void setDetectedType(int col, KDbField::Type type) { if (m_detectedTypes.count() <= col) { for (int i = m_detectedTypes.count(); i < col; ++i) { // append missing bits m_detectedTypes.append(KDbField::InvalidType); } m_detectedTypes.append(type); } else { m_detectedTypes[col] = type; } } QList* uniquenessTest(int col) const { return m_uniquenessTest.value(col); } void setUniquenessTest(int col, QList* test) { if (m_uniquenessTest.count() <= col) { for (int i = m_uniquenessTest.count(); i < col; ++i) { // append missing bits m_uniquenessTest.append(0); } m_uniquenessTest.append(test); } else { m_uniquenessTest[col] = test; } } bool imported; private: //! vector of detected types //! @todo more types QList m_detectedTypes; //! m_detectedUniqueColumns[i]==true means that i-th column has unique values //! (only for numeric type) QList< QList* > m_uniquenessTest; }; // -- KexiCSVImportDialog::KexiCSVImportDialog(Mode mode, QWidget * parent) : KAssistantDialog(parent), m_parseComments(false), m_canceled(false), m_adjustRows(true), m_startline(0), m_textquote(QString(KEXICSV_DEFAULT_FILE_TEXT_QUOTE)[0]), m_commentSymbol(QString(KEXICSV_DEFAULT_COMMENT_START)[0]), m_mode(mode), m_columnsAdjusted(false), m_firstFillTableCall(true), m_blockUserEvents(false), m_primaryKeyColumn(-1), m_dialogCanceled(false), m_conn(0), m_fieldsListModel(0), m_destinationTableSchema(0), m_implicitPrimaryKeyAdded(false), m_allRowsLoadedInPreview(false), m_stoppedAt_MAX_BYTES_TO_PREVIEW(false), m_stringNo("no"), m_stringI18nNo(xi18n("no")), m_stringFalse("false"), m_stringI18nFalse(xi18n("false")), m_partItemForSavedTable(0), m_importInProgress(false), m_importCanceled(false), d(new Private) { setWindowTitle( mode == File ? xi18nc("@title:window", "Import CSV Data From File") : xi18nc("@title:window", "Paste CSV Data From Clipboard") ); setWindowIcon(_IMPORT_ICON); //! @todo use "Paste CSV Data From Clipboard" caption for mode==Clipboard setObjectName("KexiCSVImportDialog"); setSizeGripEnabled(true); KexiMainWindowIface::global()->setReasonableDialogSize(this); KGuiItem::assign(configureButton(), KStandardGuiItem::configure()); KGuiItem::assign(finishButton(), KGuiItem(xi18nc("@action:button Import CSV", "&Import..."), _IMPORT_ICON)); finishButton()->setEnabled(false); backButton()->setEnabled(false); KConfigGroup importExportGroup(KSharedConfig::openConfig()->group("ImportExport")); m_maximumRowsForPreview = importExportGroup.readEntry( "MaximumRowsForPreviewInImportDialog", MAX_ROWS_TO_PREVIEW); m_maximumBytesForPreview = importExportGroup.readEntry( "MaximumBytesForPreviewInImportDialog", MAX_BYTES_TO_PREVIEW); m_minimumYearFor100YearSlidingWindow = importExportGroup.readEntry( "MinimumYearFor100YearSlidingWindow", MINIMUM_YEAR_FOR_100_YEAR_SLIDING_WINDOW); m_pkIcon = KexiSmallIcon("database-key"); if (m_mode == File) { createFileOpenPage(); } else if (m_mode == Clipboard) { QString subtype("plain"); m_clipboardData = QApplication::clipboard()->text(subtype, QClipboard::Clipboard); /* debug for (int i=0;QApplication::clipboard()->data(QClipboard::Clipboard)->format(i);i++) qDebug() << i << ": " << QApplication::clipboard()->data(QClipboard::Clipboard)->format(i); */ } else { return; } m_file = 0; m_inputStream = 0; createOptionsPage(); createImportMethodPage(); createTableNamePage(); createImportPage(); /** @todo reuse Clipboard too! */ /*if ( m_mode == Clipboard ) { setWindowTitle( xi18n( "Inserting From Clipboard" ) ); QMimeSource * mime = QApplication::clipboard()->data(); if ( !mime ) { KMessageBox::information( this, xi18n("There is no data in the clipboard.") ); m_canceled = true; return; } if ( !mime->provides( "text/plain" ) ) { KMessageBox::information( this, xi18n("There is no usable data in the clipboard.") ); m_canceled = true; return; } m_fileArray = QByteArray(mime->encodedData( "text/plain" ) ); } else if ( mode == File ) {*/ m_dateRegExp = QRegularExpression("^(\\d{1,4})([/\\-\\.])(\\d{1,2})([/\\-\\.])(\\d{1,4})$"); m_timeRegExp1 = QRegularExpression("^(\\d{1,2}):(\\d{1,2}):(\\d{1,2})$"); m_timeRegExp2 = QRegularExpression("^(\\d{1,2}):(\\d{1,2})$"); m_fpNumberRegExp1 = QRegularExpression("^[\\-]{0,1}\\d*[,\\.]\\d+$"); // E notation, e.g. 0.1e2, 0.1e+2, 0.1e-2, 0.1E2, 0.1E+2, 0.1E-2 m_fpNumberRegExp2 = QRegularExpression("^[\\-]{0,1}\\d*[,\\.]\\d+[Ee][+-]{0,1}\\d+$"); m_loadingProgressDlg = 0; if (m_mode == Clipboard) { m_infoLbl->setIcon(koIconName("edit-paste")); } m_tableView->setSelectionMode(QAbstractItemView::SingleSelection); connect(m_formatCombo, SIGNAL(activated(int)), this, SLOT(formatChanged(int))); connect(m_delimiterWidget, SIGNAL(delimiterChanged(QString)), this, SLOT(delimiterChanged(QString))); connect(m_commentWidget, SIGNAL(commentSymbolChanged(QString)), this, SLOT(commentSymbolChanged(QString))); connect(m_startAtLineSpinBox, SIGNAL(valueChanged(int)), this, SLOT(startlineSelected(int))); connect(m_comboQuote, SIGNAL(activated(int)), this, SLOT(textquoteSelected(int))); connect(m_tableView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(currentCellChanged(QModelIndex,QModelIndex))); connect(m_ignoreDuplicates, SIGNAL(stateChanged(int)), this, SLOT(ignoreDuplicatesChanged(int))); connect(m_1stRowForFieldNames, SIGNAL(stateChanged(int)), this, SLOT(slot1stRowForFieldNamesChanged(int))); connect(configureButton(), &QPushButton::clicked, this, &KexiCSVImportDialog::optionsButtonClicked); connect(this, SIGNAL(currentPageChanged(KPageWidgetItem*,KPageWidgetItem*)), this, SLOT(slotCurrentPageChanged(KPageWidgetItem*,KPageWidgetItem*))); KexiUtils::installRecursiveEventFilter(this, this); if ( m_mode == Clipboard ) initLater(); } KexiCSVImportDialog::~KexiCSVImportDialog() { delete m_file; delete m_inputStream; delete d; } void KexiCSVImportDialog::next() { KPageWidgetItem *curPage = currentPage(); if (curPage == m_openFilePage) { if (m_fileIface->checkSelectedFile()) { m_fname = m_fileIface->selectedFile(); } else { return; } if (!openData()) { return; } } else if (curPage == m_optionsPage) { const int numRows(m_table->rowCount()); if (numRows == 0) return; //impossible if (numRows == 1) { if (KMessageBox::No == KMessageBox::questionYesNo(this, xi18n("Data set contains no rows. Do you want to import empty table?"))) return; } } else if (curPage == m_saveMethodPage) { if (m_newTableOption->isChecked()) { m_tableNameWidget->setCurrentIndex(0); m_newTableWidget->setFocus(); } else { m_tableNameWidget->setCurrentIndex(1); m_tablesList->setFocus(); } } else if (curPage == m_tableNamePage) { KexiGUIMessageHandler msg; KexiProject *project = KexiMainWindowIface::global()->project(); if (!project) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No project available.")); return; } m_conn = project->dbConnection(); if (!m_conn) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No database connection available.")); return; } if (m_newTableOption->isChecked()) { m_partItemForSavedTable->setCaption(m_newTableWidget->captionText()); m_partItemForSavedTable->setName(m_newTableWidget->nameText()); KexiPart::Part *part = Kexi::partManager().partForPluginId("org.kexi-project.table"); KDbObject tmp; tristate res = (part && part->info()) ? m_conn->loadObjectData( project->typeIdForPluginId(part->info()->pluginId()), m_newTableWidget->nameText(), &tmp) : false; if (res == true) { KMessageBox::information(this, "

    " + part->i18nMessage("Object %1 already exists.", 0) .subs(m_newTableWidget->nameText()).toString() + "

    " + xi18n("Please choose other name.") + "

    " ); return; } else if (res == false) { qFatal("Plugin org.kexi-project.table not found"); return; } } else { m_partItemForSavedTable = m_tablesList->selectedPartItem(); } } KAssistantDialog::next(); } void KexiCSVImportDialog::slotShowSchema(KexiPart::Item *item) { if (!item) { return; } nextButton()->setEnabled(true); KDbConnection *conn = KexiMainWindowIface::global()->project()->dbConnection(); KDbTableOrQuerySchema *tableOrQuery = new KDbTableOrQuerySchema(conn, item->identifier()); m_tableCaptionLabel->setText(tableOrQuery->captionOrName()); m_tableNameLabel->setText(tableOrQuery->name()); m_recordCountLabel->setText(QString::number(conn->recordCount(tableOrQuery))); m_colCountLabel->setText(QString::number(tableOrQuery->fieldCount(conn))); delete m_fieldsListModel; m_fieldsListModel = new KexiFieldListModel(m_fieldsListView, ShowDataTypes); m_fieldsListModel->setSchema(conn, tableOrQuery); m_fieldsListView->setModel(m_fieldsListModel); m_fieldsListView->header()->resizeSections(QHeaderView::ResizeToContents); } void KexiCSVImportDialog::slotCurrentPageChanged(KPageWidgetItem *page, KPageWidgetItem *prev) { nextButton()->setEnabled(page == m_saveMethodPage ? false : true); finishButton()->setEnabled(page == m_importPage ? true : false); configureButton()->setEnabled(page == m_optionsPage); nextButton()->setEnabled(page == m_importPage ? false : true); backButton()->setEnabled(page == m_openFilePage ? false : true); if (page == m_saveMethodPage && prev == m_tableNamePage && m_partItemForSavedTable) { if (m_newTableOption->isChecked()) { KexiMainWindowIface::global()->project()->deleteUnstoredItem(m_partItemForSavedTable); } m_partItemForSavedTable = 0; } if(page == m_optionsPage){ if (m_mode == File) { m_loadingProgressDlg = new QProgressDialog(this); m_loadingProgressDlg->setObjectName("m_loadingProgressDlg"); m_loadingProgressDlg->setLabelText( xi18nc("@info", "Loading CSV Data from %1...", QDir::toNativeSeparators(m_fname))); m_loadingProgressDlg->setWindowTitle(xi18nc("@title:window", "Loading CSV Data")); m_loadingProgressDlg->setModal(true); m_loadingProgressDlg->setMaximum(m_maximumRowsForPreview); m_loadingProgressDlg->show(); } // delimiterChanged(detectedDelimiter); // this will cause fillTable() m_detectDelimiter = true; m_columnsAdjusted = false; fillTable(); delete m_loadingProgressDlg; m_loadingProgressDlg = 0; if (m_dialogCanceled) { // m_loadingProgressDlg->hide(); // m_loadingProgressDlg->close(); QTimer::singleShot(0, this, SLOT(reject())); return; } currentCellChanged(m_table->index(0,0), QModelIndex()); if (m_loadingProgressDlg) m_loadingProgressDlg->hide(); m_tableView->setFocus(); } else if (page == m_saveMethodPage) { m_newTableOption->setFocus(); } else if (page == m_tableNamePage) { if (m_newTableOption->isChecked() && !m_partItemForSavedTable) { KexiGUIMessageHandler msg; KexiProject *project = KexiMainWindowIface::global()->project(); //get suggested name based on the file name QString suggestedName; if (m_mode == File) { suggestedName = QUrl(m_fname).fileName(); //remove extension if (!suggestedName.isEmpty()) { const int idx = suggestedName.lastIndexOf('.'); if (idx != -1) { suggestedName = suggestedName.mid(0, idx).simplified(); } } } KexiPart::Part *part = Kexi::partManager().partForPluginId("org.kexi-project.table"); if (!part) { msg.showErrorMessage(Kexi::partManager().result()); return; } //-new part item m_partItemForSavedTable = project->createPartItem(part->info(), suggestedName); if (!m_partItemForSavedTable) { msg.showErrorMessage(project->result()); return; } m_newTableWidget->setCaptionText(m_partItemForSavedTable->caption()); m_newTableWidget->setNameText(m_partItemForSavedTable->name()); m_newTableWidget->captionLineEdit()->setFocus(); m_newTableWidget->captionLineEdit()->selectAll(); } else if (!m_newTableOption->isChecked()) { KexiPart::Item *i = m_tablesList->selectedPartItem(); if (!i) { nextButton()->setEnabled(false); } slotShowSchema(i); } } else if (page == m_importPage) { m_fromLabel->setFileName(m_fname); m_toLabel->setFileNameText(m_partItemForSavedTable->name()); m_importingProgressBar->hide(); m_importProgressLabel->hide(); } } void KexiCSVImportDialog::createFileOpenPage() { m_fileIface = KexiFileWidgetInterface::createWidget(QUrl("kfiledialog:///CSVImportExport"), KexiFileFilters::CustomOpening, this); m_fileIface->setAdditionalMimeTypes(csvMimeTypes()); m_fileIface->setDefaultExtension("csv"); m_fileIface->connectFileSelectedSignal(this, SLOT(next())); m_openFilePage = new KPageWidgetItem(m_fileIface->widget(), xi18n("Select Import Filename")); addPage(m_openFilePage); } void KexiCSVImportDialog::createOptionsPage() { QWidget *m_optionsWidget = new QWidget(this); QVBoxLayout *lyr = new QVBoxLayout(m_optionsWidget); m_infoLbl = new KexiCSVInfoLabel( m_mode == File ? xi18n("Preview of data from file:") : xi18n("Preview of data from clipboard"), m_optionsWidget, m_mode == File /*showFnameLine*/ ); lyr->addWidget(m_infoLbl); QWidget* page = new QFrame(m_optionsWidget); QGridLayout *glyr = new QGridLayout(page); lyr->addWidget(page); // Delimiter: comma, semicolon, tab, space, other m_delimiterWidget = new KexiCSVDelimiterWidget(true /*lineEditOnBottom*/, page); glyr->addWidget(m_delimiterWidget, 1, 0, 1, 1); QLabel *delimiterLabel = new QLabel(xi18n("Delimiter:"), page); delimiterLabel->setBuddy(m_delimiterWidget); delimiterLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); glyr->addWidget(delimiterLabel, 0, 0, 1, 1); m_commentWidget = new KexiCSVCommentWidget(true, page); glyr->addWidget(m_commentWidget, 1, 4); QLabel *commentLabel = new QLabel(xi18n("Comment symbol:"), page); commentLabel->setBuddy(m_commentWidget); commentLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); glyr->addWidget(commentLabel, 0, 4); // Format: number, text... //! @todo Object and Currency types m_formatCombo = new KComboBox(page); m_formatCombo->setObjectName("m_formatCombo"); for (int i = 0; i < kexiCSVImportStatic->types.size(); ++i) { m_formatCombo->addItem(kexiCSVImportStatic->typeNames.value(kexiCSVImportStatic->types[i])); } glyr->addWidget(m_formatCombo, 1, 1, 1, 1); m_formatLabel = new QLabel(page); m_formatLabel->setBuddy(m_formatCombo); m_formatLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); glyr->addWidget(m_formatLabel, 0, 1); m_primaryKeyField = new QCheckBox(xi18n("Primary key"), page); m_primaryKeyField->setObjectName("m_primaryKeyField"); glyr->addWidget(m_primaryKeyField, 2, 1); connect(m_primaryKeyField, SIGNAL(toggled(bool)), this, SLOT(slotPrimaryKeyFieldToggled(bool))); m_comboQuote = new KexiCSVTextQuoteComboBox(page); glyr->addWidget(m_comboQuote, 1, 2); TextLabel2 = new QLabel(xi18n("Text quote:"), page); TextLabel2->setBuddy(m_comboQuote); TextLabel2->setObjectName("TextLabel2"); TextLabel2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); TextLabel2->setAlignment(Qt::AlignLeft | Qt::AlignBottom); glyr->addWidget(TextLabel2, 0, 2); m_startAtLineSpinBox = new QSpinBox(page); m_startAtLineSpinBox->setObjectName("m_startAtLineSpinBox"); m_startAtLineSpinBox->setMinimum(1); m_startAtLineSpinBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_startAtLineSpinBox->setMinimumWidth( QFontMetrics(m_startAtLineSpinBox->font()).width("8888888")); glyr->addWidget(m_startAtLineSpinBox, 1, 3); m_startAtLineLabel = new QLabel(page); m_startAtLineLabel->setBuddy(m_startAtLineSpinBox); m_startAtLineLabel->setObjectName("m_startAtLineLabel"); m_startAtLineLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); m_startAtLineLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); glyr->addWidget(m_startAtLineLabel, 0, 3); m_ignoreDuplicates = new QCheckBox(page); m_ignoreDuplicates->setObjectName("m_ignoreDuplicates"); m_ignoreDuplicates->setText(xi18n("Ignore duplicated delimiters")); glyr->addWidget(m_ignoreDuplicates, 2, 2, 1, 2); m_1stRowForFieldNames = new QCheckBox(page); m_1stRowForFieldNames->setObjectName("m_1stRowForFieldNames"); m_1stRowForFieldNames->setText(xi18n("First row contains column names")); glyr->addWidget(m_1stRowForFieldNames, 3, 2, 1, 2); QSpacerItem* spacer_2 = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Preferred); glyr->addItem(spacer_2, 0, 5, 4, 1); glyr->setColumnStretch(5, 2); m_tableView = new QTableView(m_optionsWidget); m_table = new KexiCSVImportDialogModel(m_tableView); m_table->setObjectName("m_table"); m_tableView->setModel(m_table); m_tableItemDelegate = new KexiCSVImportDialogItemDelegate(m_tableView); m_tableView->setItemDelegate(m_tableItemDelegate); lyr->addWidget(m_tableView); QSizePolicy spolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); spolicy.setHorizontalStretch(1); spolicy.setVerticalStretch(1); m_tableView->setSizePolicy(spolicy); m_optionsPage = new KPageWidgetItem(m_optionsWidget, xi18n("Import Options")); addPage(m_optionsPage); } void KexiCSVImportDialog::createImportMethodPage() { m_saveMethodWidget = new QWidget(this); QGridLayout *l = new QGridLayout(m_saveMethodWidget); m_newTableOption = new QRadioButton( xi18nc("@option:check CSV import: data will be appended to a new table", "&New table")); m_newTableOption->setChecked(true); m_existingTableOption = new QRadioButton( xi18nc("@option:check CSV import: data will be appended to existing table", "&Existing table")); l->addWidget(m_newTableOption, 0, 0, 1, 1); l->addWidget(m_existingTableOption, 1, 0, 1, 1); QSpacerItem *hSpacer = new QSpacerItem(200, 20, QSizePolicy::Preferred, QSizePolicy::Minimum); QSpacerItem *vSpacer = new QSpacerItem(20, 200, QSizePolicy::Minimum, QSizePolicy::Expanding); l->addItem(hSpacer, 1, 1, 1, 1); l->addItem(vSpacer, 2, 0, 1, 1); m_saveMethodPage = new KPageWidgetItem(m_saveMethodWidget, xi18n("Choose Destination for Imported Data")); addPage(m_saveMethodPage); } void KexiCSVImportDialog::createTableNamePage() { m_tableNameWidget = new QStackedWidget(this); m_tableNameWidget->setObjectName("m_tableNameWidget"); QWidget *page1=new QWidget(m_tableNameWidget); m_newTableWidget = new KexiNameWidget(QString(), page1); m_newTableWidget->addNameSubvalidator(new KDbObjectNameValidator( KexiMainWindowIface::global()->project()->dbConnection()->driver())); QVBoxLayout *l=new QVBoxLayout(page1); l->addWidget(m_newTableWidget); l->addStretch(1); m_tableNameWidget->addWidget(page1); QSplitter *splitter = new QSplitter(m_tableNameWidget); QWidget *tablesListParentWidget = new QWidget; QVBoxLayout *tablesListParentWidgetLayout = new QVBoxLayout(tablesListParentWidget); tablesListParentWidgetLayout->setMargin(0); QLabel *tablesListLabel = new QLabel(xi18nc("@label", "Select existing table:")); tablesListParentWidgetLayout->addWidget(tablesListLabel); KexiProjectNavigator::Features tablesListFeatures = KexiProjectNavigator::DefaultFeatures; tablesListFeatures &= (~KexiProjectNavigator::AllowSingleClickForOpeningItems); tablesListFeatures &= (~KexiProjectNavigator::ClearSelectionAfterAction); tablesListFeatures |= KexiProjectNavigator::Borders; m_tablesList = new KexiProjectNavigator(tablesListParentWidget, tablesListFeatures); tablesListParentWidgetLayout->addWidget(m_tablesList, 1); tablesListLabel->setBuddy(m_tablesList); QString errorString; m_tablesList->setProject(KexiMainWindowIface::global()->project(), "org.kexi-project.table", &errorString, false); connect (m_tablesList, SIGNAL(openOrActivateItem(KexiPart::Item*,Kexi::ViewMode)), this, SLOT(next())); connect (m_tablesList, SIGNAL(selectionChanged(KexiPart::Item*)), this, SLOT(slotShowSchema(KexiPart::Item*))); splitter->addWidget(tablesListParentWidget); QWidget *tableDetailsWidget = new QWidget; QFormLayout *formLayout = new QFormLayout(tableDetailsWidget); formLayout->setContentsMargins(KexiUtils::marginHint(), 0, 0, 0); formLayout->addRow(new QLabel(xi18nc("@label Preview of selected table", "Table preview:"))); formLayout->addRow(xi18nc("@label", "Name:"), m_tableNameLabel = new QLabel(tableDetailsWidget)); formLayout->addRow(xi18nc("@label", "Caption:"), m_tableCaptionLabel = new QLabel(tableDetailsWidget)); formLayout->addRow(xi18nc("@label", "Row count:"), m_recordCountLabel = new QLabel(tableDetailsWidget)); formLayout->addRow(xi18nc("@label", "Column count:"), m_colCountLabel = new QLabel(tableDetailsWidget)); formLayout->addItem(new QSpacerItem(1, KexiUtils::spacingHint())); m_fieldsListView = new QTreeView(tableDetailsWidget); m_fieldsListView->setItemsExpandable(false); m_fieldsListView->setRootIsDecorated(false); QSizePolicy fieldsListViewPolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); fieldsListViewPolicy.setVerticalStretch(1); m_fieldsListView->setSizePolicy(fieldsListViewPolicy); formLayout->addRow(new QLabel(xi18nc("@label", "Fields:"))); formLayout->addRow(m_fieldsListView); splitter->addWidget(tableDetailsWidget); splitter->setStretchFactor(splitter->indexOf(tableDetailsWidget), 1); m_tableNameWidget->addWidget(splitter); m_tableNamePage = new KPageWidgetItem(m_tableNameWidget, xi18nc("@label", "Choose Name of Destination Table")); addPage(m_tableNamePage); } void KexiCSVImportDialog::createImportPage() { m_importWidget = new QWidget(this); m_fromLabel = new KexiCSVInfoLabel(m_mode == File ? xi18n("From CSV file:") : xi18n("From Clipboard"), m_importWidget, m_mode == File); m_fromLabel->separator()->hide(); if (m_mode != File) { m_fromLabel->setIcon(koIconName("edit-paste")); } m_toLabel = new KexiCSVInfoLabel(xi18nc("@label Importing CSV data to table:", "To table:"), m_importWidget, true); KexiPart::Info *partInfo = Kexi::partManager().infoForPluginId("org.kexi-project.table"); m_toLabel->setIcon(partInfo->iconName()); m_importProgressLabel = new QLabel(m_importWidget); m_importingProgressBar = new QProgressBar(m_importWidget); QVBoxLayout *l = new QVBoxLayout(m_importWidget); l->addWidget(m_fromLabel); l->addWidget(m_toLabel); l->addSpacing(m_importProgressLabel->fontMetrics().height()); l->addWidget(m_importProgressLabel); l->addWidget(m_importingProgressBar); l->addStretch(1); m_importingProgressBar->hide(); m_importProgressLabel->hide(); m_importPage = new KPageWidgetItem(m_importWidget, xi18n("Ready to Import")); addPage(m_importPage); } void KexiCSVImportDialog::initLater() { if (!openData()) return; m_columnsAdjusted = false; fillTable(); delete m_loadingProgressDlg; m_loadingProgressDlg = 0; if (m_dialogCanceled) { QTimer::singleShot(0, this, SLOT(reject())); return; } currentCellChanged(m_table->index(0,0), QModelIndex()); if (m_loadingProgressDlg) m_loadingProgressDlg->hide(); show(); m_tableView->setFocus(); } bool KexiCSVImportDialog::openData() { if (m_mode != File) //data already loaded, no encoding stuff needed return true; delete m_inputStream; m_inputStream = 0; if (m_file) { m_file->close(); delete m_file; } m_file = new QFile(m_fname); if (!m_file->open(QIODevice::ReadOnly)) { m_file->close(); delete m_file; m_file = 0; KMessageBox::sorry(this, xi18n("Cannot open input file %1.", QDir::toNativeSeparators(m_fname))); nextButton()->setEnabled(false); m_canceled = true; if (parentWidget()) parentWidget()->raise(); return false; } return true; } bool KexiCSVImportDialog::canceled() const { return m_canceled; } void KexiCSVImportDialog::fillTable() { KexiUtils::WaitCursor wc(true); repaint(); m_blockUserEvents = true; button(QDialogButtonBox::Cancel)->setEnabled(true); KexiUtils::WaitCursor wait; if (m_table->rowCount() > 0) //to accept editor m_tableView->setCurrentIndex(QModelIndex()); int row, column, maxColumn; QString field; m_table->clear(); d->clearDetectedTypes(); d->clearUniquenessTests(); m_primaryKeyColumn = -1; if (true != loadRows(field, row, column, maxColumn, true)) return; // file with only one line without EOL if (field.length() > 0) { setText(row - m_startline, column, field, true); ++row; field.clear(); } adjustRows(row - m_startline - (m_1stRowForFieldNames->isChecked() ? 1 : 0)); maxColumn = qMax(maxColumn, column); m_table->setColumnCount(maxColumn); for (column = 0; column < m_table->columnCount(); ++column) { updateColumn(column); if (!m_columnsAdjusted) m_tableView->resizeColumnToContents(column); } m_columnsAdjusted = true; if (m_primaryKeyColumn >= 0 && m_primaryKeyColumn < m_table->columnCount()) { if (KDbField::Integer != d->detectedType(m_primaryKeyColumn)) { setPrimaryKeyIcon(m_primaryKeyColumn, false); m_primaryKeyColumn = -1; } } m_tableView->setCurrentIndex(m_table->index(0, 0)); currentCellChanged(m_table->index(0, 0), QModelIndex()); setPrimaryKeyIcon(m_primaryKeyColumn, true); const int count = qMax(0, m_table->rowCount() - 1 + m_startline); m_allRowsLoadedInPreview = count < m_maximumRowsForPreview && !m_stoppedAt_MAX_BYTES_TO_PREVIEW; if (count > 1) { if (m_allRowsLoadedInPreview) { m_startAtLineSpinBox->setMaximum(count); m_startAtLineSpinBox->setValue(m_startline + 1); } m_startAtLineSpinBox->setEnabled(true); m_startAtLineLabel->setText( m_allRowsLoadedInPreview ? xi18n("Start at line (1-%1):", count) : xi18n("Start at line:") //we do not know what's real count ); m_startAtLineLabel->setEnabled(true); } else { // no data m_startAtLineSpinBox->setMaximum(1); m_startAtLineSpinBox->setValue(1); m_startAtLineSpinBox->setEnabled(false); m_startAtLineLabel->setText(xi18n("Start at line:")); m_startAtLineLabel->setEnabled(false); } updateRowCountInfo(); m_blockUserEvents = false; repaint(); } QString KexiCSVImportDialog::detectDelimiterByLookingAtFirstBytesOfFile(QTextStream *inputStream) { // try to detect delimiter // \t has priority, then ; then , const qint64 origOffset = inputStream->pos(); QChar c, prevChar = 0; int detectedDelimiter = 0; bool insideQuote = false; //characters by priority const int CH_TAB_AFTER_QUOTE = 500; const int CH_SEMICOLON_AFTER_QUOTE = 499; const int CH_COMMA_AFTER_QUOTE = 498; const int CH_TAB = 200; // \t const int CH_SEMICOLON = 199; // ; const int CH_COMMA = 198; // , QList tabsPerLine, semicolonsPerLine, commasPerLine; int tabs = 0, semicolons = 0, commas = 0; int line = 0; bool wasChar13 = false; // true if previous x was '\r' for (int i = 0; !inputStream->atEnd() && i < MAX_CHARS_TO_SCAN_WHILE_DETECTING_DELIMITER; i++) { (*m_inputStream) >> c; // read one char if (prevChar == '"') { if (c != '"') //real quote (not double "") insideQuote = !insideQuote; } if (insideQuote) { prevChar = c; continue; } if (c == ' ') continue; if (wasChar13 && c == '\n') { wasChar13 = false; continue; // previous x was '\r', eat '\n' } wasChar13 = c == '\r'; if (c == '\n' || c == '\r') {//end of line //remember # of tabs/semicolons/commas in this line tabsPerLine += tabs; tabs = 0; semicolonsPerLine += semicolons; semicolons = 0; commasPerLine += commas; commas = 0; line++; } else if (c == '\t') { tabs++; detectedDelimiter = qMax(prevChar == '"' ? CH_TAB_AFTER_QUOTE : CH_TAB, detectedDelimiter); } else if (c == ';') { semicolons++; detectedDelimiter = qMax(prevChar == '"' ? CH_SEMICOLON_AFTER_QUOTE : CH_SEMICOLON, detectedDelimiter); } else if (c == ',') { commas++; detectedDelimiter = qMax(prevChar == '"' ? CH_COMMA_AFTER_QUOTE : CH_COMMA, detectedDelimiter); } prevChar = c; } inputStream->seek(origOffset); //restore orig. offset //now, try to find a delimiter character that exists the same number of times in all the checked lines //this detection method has priority over others QList::ConstIterator it; if (tabsPerLine.count() > 1) { tabs = tabsPerLine.isEmpty() ? 0 : tabsPerLine.first(); for (it = tabsPerLine.constBegin(); it != tabsPerLine.constEnd(); ++it) { if (tabs != *it) break; } if (tabs > 0 && it == tabsPerLine.constEnd()) return "\t"; } if (semicolonsPerLine.count() > 1) { semicolons = semicolonsPerLine.isEmpty() ? 0 : semicolonsPerLine.first(); for (it = semicolonsPerLine.constBegin(); it != semicolonsPerLine.constEnd(); ++it) { if (semicolons != *it) break; } if (semicolons > 0 && it == semicolonsPerLine.constEnd()) return ";"; } if (commasPerLine.count() > 1) { commas = commasPerLine.first(); for (it = commasPerLine.constBegin(); it != commasPerLine.constEnd(); ++it) { if (commas != *it) break; } if (commas > 0 && it == commasPerLine.constEnd()) return ","; } //now return the winning character by looking at CH_* symbol if (detectedDelimiter == CH_TAB_AFTER_QUOTE || detectedDelimiter == CH_TAB) return "\t"; if (detectedDelimiter == CH_SEMICOLON_AFTER_QUOTE || detectedDelimiter == CH_SEMICOLON) return ";"; if (detectedDelimiter == CH_COMMA_AFTER_QUOTE || detectedDelimiter == CH_COMMA) return ","; return KEXICSV_DEFAULT_FILE_DELIMITER; //<-- default } tristate KexiCSVImportDialog::loadRows(QString &field, int &row, int &column, int &maxColumn, bool inGUI) { enum { S_START, S_QUOTED_FIELD, S_MAYBE_END_OF_QUOTED_FIELD, S_END_OF_QUOTED_FIELD, S_MAYBE_NORMAL_FIELD, S_NORMAL_FIELD, S_COMMENT } state = S_START; field.clear(); const bool ignoreDups = m_ignoreDuplicates->isChecked(); bool lastCharDelimiter = false; bool nextRow = false; row = column = 1; m_prevColumnForSetText = 0; maxColumn = 0; QChar x; const bool hadInputStream = m_inputStream != 0; delete m_inputStream; if (m_mode == Clipboard) { m_inputStream = new QTextStream(&m_clipboardData, QIODevice::ReadOnly); if (!hadInputStream) m_delimiterWidget->setDelimiter(KEXICSV_DEFAULT_CLIPBOARD_DELIMITER); } else { m_file->seek(0); //always seek at 0 because loadRows() is called many times m_inputStream = new QTextStream(m_file); QTextCodec *codec = KCharsets::charsets()->codecForName(m_options.encoding); if (codec) { m_inputStream->setCodec(codec); //QTextCodec::codecForName("CP1250")); } if (m_detectDelimiter) { const QString delimiter(detectDelimiterByLookingAtFirstBytesOfFile(m_inputStream)); if (m_delimiterWidget->delimiter() != delimiter) m_delimiterWidget->setDelimiter(delimiter); } } const QChar delimiter(m_delimiterWidget->delimiter()[0]); const QChar commentSymbol(m_commentWidget->commentSymbol()[0]); m_stoppedAt_MAX_BYTES_TO_PREVIEW = false; if (m_importingProgressBar) { m_elapsedTimer.start(); m_elapsedMs = m_elapsedTimer.elapsed(); } int offset = 0; bool wasChar13 = false; // true if previous x was '\r' for (;; ++offset) { if (m_importingProgressBar && (offset % 0x100) == 0 && (m_elapsedMs + PROGRESS_STEP_MS) < m_elapsedTimer.elapsed()) { //update progr. bar dlg on final exporting m_elapsedMs = m_elapsedTimer.elapsed(); m_importingProgressBar->setValue(offset); qApp->processEvents(); if (m_importCanceled) { return ::cancelled; } } if (m_inputStream->atEnd()) { if (x != '\n' && x != '\r') { x = '\n'; // simulate missing \n at end wasChar13 = false; } else { break; // finish! } } else { (*m_inputStream) >> x; // read one char } if (wasChar13 && x == '\n') { wasChar13 = false; continue; // previous x was '\r', eat '\n' } wasChar13 = x == '\r'; if (offset == 0 && x.unicode() == 0xfeff) { // Ignore BOM, the "Byte Order Mark" // (http://en.wikipedia.org/wiki/Byte_Order_Mark, // http://www.unicode.org/charts/PDF/UFFF0.pdf) // Probably fixed in Qt4. continue; } switch (state) { case S_START : if (x == m_textquote) { state = S_QUOTED_FIELD; } else if (x == delimiter) { field.clear(); if ((ignoreDups == false) || (lastCharDelimiter == false)) ++column; lastCharDelimiter = true; } else if (x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { if (!inGUI) { //fill remaining empty fields (database wants them explicitly) for (int additionalColumn = column; additionalColumn <= maxColumn; additionalColumn++) { setText(row - m_startline, additionalColumn, QString(), inGUI); } } nextRow = true; if (ignoreDups && lastCharDelimiter) { // we're ignoring repeated delimiters so remove any extra trailing delimiters --column; } maxColumn = qMax(maxColumn, column); column = 1; m_prevColumnForSetText = 0; if (x == commentSymbol && m_parseComments) { state = S_COMMENT; maxColumn -= 1; break; } } else { field += x; state = S_MAYBE_NORMAL_FIELD; } break; case S_QUOTED_FIELD : if (x == m_textquote) { state = S_MAYBE_END_OF_QUOTED_FIELD; } /*allow \n inside quoted fields else if (x == '\n') { setText(row - m_startline, column, field, inGUI); field = ""; if (x == '\n') { nextRow = true; maxColumn = qMax( maxColumn, column ); column = 1; } else { if ((ignoreDups == false) || (lastCharDelimiter == false)) ++column; lastCharDelimiter = true; } state = S_START; }*/ else { field += x; } break; case S_MAYBE_END_OF_QUOTED_FIELD : if (x == m_textquote) { field += x; //no, this was just escaped quote character state = S_QUOTED_FIELD; } else if (x == delimiter || x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { setText(row - m_startline, column, field, inGUI); field.clear(); if (x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { nextRow = true; maxColumn = qMax(maxColumn, column); column = 1; m_prevColumnForSetText = 0; if (x == commentSymbol && m_parseComments) { state = S_COMMENT; break; } } else { if ((ignoreDups == false) || (lastCharDelimiter == false)) ++column; lastCharDelimiter = true; } state = S_START; } else { state = S_END_OF_QUOTED_FIELD; } break; case S_END_OF_QUOTED_FIELD : if (x == delimiter || x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { setText(row - m_startline, column, field, inGUI); field.clear(); if (x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { nextRow = true; maxColumn = qMax(maxColumn, column); column = 1; m_prevColumnForSetText = 0; if (x == commentSymbol && m_parseComments) { state = S_COMMENT; break; } } else { if ((ignoreDups == false) || (lastCharDelimiter == false)) ++column; lastCharDelimiter = true; } state = S_START; } else { state = S_END_OF_QUOTED_FIELD; } break; case S_COMMENT : if (x == '\n' || x == '\r') { state = S_START; } if (lastCharDelimiter) { lastCharDelimiter = false; } break; case S_MAYBE_NORMAL_FIELD : case S_NORMAL_FIELD : if (state == S_MAYBE_NORMAL_FIELD && x == m_textquote) { field.clear(); state = S_QUOTED_FIELD; break; } if (x == delimiter || x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { setText(row - m_startline, column, field, inGUI); field.clear(); if (x == '\n' || x == '\r' || (x == commentSymbol && m_parseComments)) { nextRow = true; maxColumn = qMax(maxColumn, column); column = 1; m_prevColumnForSetText = 0; if (x == commentSymbol && m_parseComments) { state = S_COMMENT; break; } } else { if ((ignoreDups == false) || (lastCharDelimiter == false)) ++column; lastCharDelimiter = true; } state = S_START; } else { field += x; } break; } // switch if (x != delimiter) lastCharDelimiter = false; if (nextRow) { if (!inGUI && !shouldSaveRow(row - m_startline, m_1stRowForFieldNames->isChecked())) { // do not save to the database 1st row if it contains column names m_valuesToInsert.clear(); } else if (!saveRow(inGUI)) return false; ++row; } if (m_firstFillTableCall && row == 2 && !m_1stRowForFieldNames->isChecked() && m_table->firstRowForFieldNames()) { m_table->clear(); m_firstFillTableCall = false; //this trick is allowed only once, on startup m_1stRowForFieldNames->setChecked(true); //this will reload table m_blockUserEvents = false; repaint(); return false; } if (!m_importingProgressBar && row % 20 == 0) { qApp->processEvents(); //only for GUI mode: if (!m_firstFillTableCall && m_loadingProgressDlg && m_loadingProgressDlg->wasCanceled()) { delete m_loadingProgressDlg; m_loadingProgressDlg = 0; m_dialogCanceled = true; reject(); return false; } } if (!m_firstFillTableCall && m_loadingProgressDlg) { m_loadingProgressDlg->setValue(qMin(m_maximumRowsForPreview, row)); } if (inGUI && row > (m_maximumRowsForPreview + (m_table->firstRowForFieldNames() ? 1 : 0))) { qDebug() << "loading stopped at row #" << m_maximumRowsForPreview; break; } if (nextRow) { nextRow = false; //additional speedup: stop processing now if too many bytes were loaded for preview //qDebug() << offset; if (inGUI && offset >= m_maximumBytesForPreview && row >= 2) { m_stoppedAt_MAX_BYTES_TO_PREVIEW = true; return true; } } } return true; } void KexiCSVImportDialog::updateColumn(int col) { KDbField::Type detectedType = d->detectedType(col); if (detectedType == KDbField::InvalidType) { d->setDetectedType(col, KDbField::Text); //entirely empty column detectedType = KDbField::Text; } m_table->setHeaderData(col, Qt::Horizontal, QString(xi18n("Column %1", col + 1) + " \n(" + kexiCSVImportStatic->typeNames[detectedType].toLower() + ") ")); m_tableView->horizontalHeader()->adjustSize(); if (m_primaryKeyColumn == -1 && isPrimaryKeyAllowed(col)) { m_primaryKeyColumn = col; } } bool KexiCSVImportDialog::isPrimaryKeyAllowed(int col) { QList *list = d->uniquenessTest(col); if (m_primaryKeyColumn != -1 || !list || list->isEmpty()) { return false; } bool result = false; int expectedRowCount = m_table->rowCount(); if (m_table->firstRowForFieldNames()) { expectedRowCount--; } if (list->count() == expectedRowCount) { qSort(*list); QList::ConstIterator it = list->constBegin(); int prevValue = *it; ++it; for (; it != list->constEnd() && prevValue != (*it); ++it) { prevValue = (*it); } result = it == list->constEnd(); // no duplicates } list->clear(); // not needed now: conserve memory return result; } void KexiCSVImportDialog::detectTypeAndUniqueness(int row, int col, const QString& text) { int intValue; KDbField::Type type = d->detectedType(col); if (row == 1 || type != KDbField::Text) { bool found = false; if (text.isEmpty() && type == KDbField::InvalidType) found = true; //real type should be found later //detect type because it's 1st row or all prev. rows were not text //-FP number? (trying before "number" type is a must) if (!found && (row == 1 || type == KDbField::Integer || type == KDbField::Double || type == KDbField::InvalidType)) { bool ok = text.isEmpty() || m_fpNumberRegExp1.match(text).hasMatch() || m_fpNumberRegExp2.match(text).hasMatch(); if (ok && (row == 1 || type == KDbField::InvalidType)) { d->setDetectedType(col, KDbField::Double); found = true; //yes } } //-number? if (!found && (row == 1 || type == KDbField::Integer || type == KDbField::InvalidType)) { bool ok = text.isEmpty();//empty values allowed if (!ok) intValue = text.toInt(&ok); if (ok && (row == 1 || type == KDbField::InvalidType)) { d->setDetectedType(col, KDbField::Integer); found = true; //yes } } //-date? if (!found && (row == 1 || type == KDbField::Date || type == KDbField::InvalidType)) { if ((row == 1 || type == KDbField::InvalidType) && (text.isEmpty() || m_dateRegExp.match(text).hasMatch())) { d->setDetectedType(col, KDbField::Date); found = true; //yes } } //-time? if (!found && (row == 1 || type == KDbField::Time || type == KDbField::InvalidType)) { if ((row == 1 || type == KDbField::InvalidType) && (text.isEmpty() || m_timeRegExp1.match(text).hasMatch() || m_timeRegExp2.match(text).hasMatch())) { d->setDetectedType(col, KDbField::Time); found = true; //yes } } //-date/time? if (!found && (row == 1 || type == KDbField::Time || type == KDbField::InvalidType)) { if (row == 1 || type == KDbField::InvalidType) { bool detected = text.isEmpty(); if (!detected) { const QStringList dateTimeList(text.split(' ')); bool ok = dateTimeList.count() >= 2; //! @todo also support ISODateTime's "T" separator? //! @todo also support timezones? if (ok) { //try all combinations QString datePart(dateTimeList[0].trimmed()); QString timePart(dateTimeList[1].trimmed()); ok = m_dateRegExp.match(datePart).hasMatch() && (m_timeRegExp1.match(timePart).hasMatch() || m_timeRegExp2.match(timePart).hasMatch()); } detected = ok; } if (detected) { d->setDetectedType(col, KDbField::DateTime); found = true; //yes } } } if (!found && type == KDbField::InvalidType && !text.isEmpty()) { //eventually, a non-emptytext after a while d->setDetectedType(col, KDbField::Text); found = true; //yes } //default: text type (already set) } type = d->detectedType(col); //qDebug() << type; if (type == KDbField::Integer) { // check uniqueness for this value QList *list = d->uniquenessTest(col); if (text.isEmpty()) { if (list) { list->clear(); // empty value cannot be in PK } } else { if (!list) { list = new QList(); d->setUniquenessTest(col, list); } list->append(intValue); } } } QDate KexiCSVImportDialog::buildDate(int y, int m, int d) const { if (y < 100) { if ((1900 + y) >= m_minimumYearFor100YearSlidingWindow) return QDate(1900 + y, m, d); else return QDate(2000 + y, m, d); } return QDate(y, m, d); } bool KexiCSVImportDialog::parseDate(const QString& text, QDate& date) { QRegularExpressionMatch match = m_dateRegExp.match(text); if (!match.hasMatch()) return false; //dddd - dd - dddd //1 2 3 4 5 <- pos const int d1 = match.captured(1).toInt(), d3 = match.captured(3).toInt(), d5 = match.captured(5).toInt(); switch (m_options.dateFormat) { case KexiCSVImportOptions::DMY: date = buildDate(d5, d3, d1); break; case KexiCSVImportOptions::YMD: date = buildDate(d1, d3, d5); break; case KexiCSVImportOptions::MDY: date = buildDate(d5, d1, d3); break; case KexiCSVImportOptions::AutoDateFormat: if (match.captured(2) == "/") { //probably separator for american format mm/dd/yyyy date = buildDate(d5, d1, d3); } else { if (d5 > 31) //d5 == year date = buildDate(d5, d3, d1); else //d1 == year date = buildDate(d1, d3, d5); } break; default:; } return date.isValid(); } bool KexiCSVImportDialog::parseTime(const QString& text, QTime& time) { time = QTime::fromString(text, Qt::ISODate); //same as m_timeRegExp1 if (time.isValid()) return true; QRegularExpressionMatch match = m_timeRegExp2.match(text); if (match.hasMatch()) { //hh:mm:ss time = QTime(match.captured(1).toInt(), match.captured(3).toInt(), match.captured(5).toInt()); return true; } return false; } void KexiCSVImportDialog::setText(int row, int col, const QString& text, bool inGUI) { if (!inGUI) { if (!shouldSaveRow(row, m_1stRowForFieldNames->isChecked())) return; // do not care about this value if it contains column names (these were already used) //save text directly to database buffer if (m_prevColumnForSetText == 0) { //1st call m_valuesToInsert.clear(); if (m_implicitPrimaryKeyAdded) { m_valuesToInsert << QVariant(); //id will be autogenerated here } } if ((m_prevColumnForSetText + 1) < col) { //skipped one or more columns //before this: save NULLs first for (int i = m_prevColumnForSetText + 1; i < col; i++) { if (m_options.nullsImportedAsEmptyTextChecked && KDbField::isTextType(d->detectedType(i-1))) { m_valuesToInsert << QString(""); } else { m_valuesToInsert << QVariant(); } } } m_prevColumnForSetText = col; const KDbField::Type detectedType = d->detectedType(col-1); if (detectedType == KDbField::Integer) { m_valuesToInsert << (text.isEmpty() ? QVariant() : text.toInt()); //! @todo what about time and float/double types and different integer subtypes? } else if (detectedType == KDbField::Double) { //replace ',' with '.' QByteArray t(text.toLatin1()); const int textLen = t.length(); for (int i = 0; i < textLen; i++) { if (t[i] == ',') { t[i] = '.'; break; } } m_valuesToInsert << (t.isEmpty() ? QVariant() : t.toDouble()); } else if (detectedType == KDbField::Boolean) { const QString t(text.trimmed().toLower()); if (t.isEmpty()) m_valuesToInsert << QVariant(); else if (t == "0" || t == m_stringNo || t == m_stringI18nNo || t == m_stringFalse || t == m_stringI18nFalse) m_valuesToInsert << QVariant(false); else m_valuesToInsert << QVariant(true); //anything nonempty } else if (detectedType == KDbField::Date) { QDate date; if (parseDate(text, date)) m_valuesToInsert << date; else m_valuesToInsert << QVariant(); } else if (detectedType == KDbField::Time) { QTime time; if (parseTime(text, time)) m_valuesToInsert << time; else m_valuesToInsert << QVariant(); } else if (detectedType == KDbField::DateTime) { QStringList dateTimeList(text.split(' ')); if (dateTimeList.count() < 2) dateTimeList = text.split('T'); //also support ISODateTime's "T" separator //! @todo also support timezones? if (dateTimeList.count() >= 2) { //try all combinations QString datePart(dateTimeList[0].trimmed()); QDate date; if (parseDate(datePart, date)) { QString timePart(dateTimeList[1].trimmed()); QTime time; if (parseTime(timePart, time)) m_valuesToInsert << QDateTime(date, time); else m_valuesToInsert << QVariant(); } else m_valuesToInsert << QVariant(); } else m_valuesToInsert << QVariant(); } else { // Text type and the rest if (m_options.nullsImportedAsEmptyTextChecked && text.isNull()) { //default value is empty string not null - otherwise querying data without knowing SQL is very confusing m_valuesToInsert << QString(""); } else { m_valuesToInsert <columnCount() < col) { m_table->setColumnCount(col); } if (!m_1stRowForFieldNames->isChecked()) { if ((row + m_startline) == 1) {//this row is for column name if (m_table->firstRowForFieldNames() && !m_1stRowForFieldNames->isChecked()) { QString f(text.simplified()); if (f.isEmpty() || !f[0].isLetter()) { m_table->setFirstRowForFieldNames(false); } } } row++; //1st row was for column names } else { if ((row + m_startline) == 1) {//this is for column name m_table->setRowCount(1); QString colName(text.simplified()); if (!colName.isEmpty()) { if (colName.at(0) >= QLatin1Char('0') && colName.at(0) <= QLatin1Char('9')) { colName.prepend(xi18n("Column") + " "); } m_table->setData(m_table->index(0, col - 1), colName); } return; } } if (row < 2) // skipped by the user return; if (m_table->rowCount() < row) { m_table->setRowCount(row + 100); /* We add more rows at a time to limit recalculations */ m_adjustRows = true; } m_table->setData(m_table->index(row-1 ,col-1),m_options.trimmedInTextValuesChecked ? text.trimmed() : text); detectTypeAndUniqueness(row - 1, col - 1, text); } bool KexiCSVImportDialog::saveRow(bool inGUI) { if (inGUI) { //nothing to do return true; } bool res = m_importingStatement.execute(m_valuesToInsert); //! @todo move if (!res) { const QStringList msgList = KexiUtils::convertTypesUsingMethod(m_valuesToInsert); const KMessageBox::ButtonCode msgRes = KMessageBox::warningContinueCancelList(this, xi18nc("@info", "An error occurred during insert record."), QStringList(msgList.join(";")), QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), "SkipImportErrors" ); res = msgRes == KMessageBox::Continue; } m_valuesToInsert.clear(); return res; } void KexiCSVImportDialog::adjustRows(int iRows) { if (m_adjustRows) { m_table->setRowCount(iRows); m_adjustRows = false; for (int i = 0; i < iRows; i++) m_tableView->resizeRowToContents(i); } } void KexiCSVImportDialog::formatChanged(int index) { if (index < 0 || index >= kexiCSVImportStatic->types.size()) return; KDbField::Type type = kexiCSVImportStatic->types[index]; d->setDetectedType(m_tableView->currentIndex().column(), type); m_primaryKeyField->setEnabled(KDbField::Integer == type); m_primaryKeyField->setChecked(m_primaryKeyColumn == m_tableView->currentIndex().column() && m_primaryKeyField->isEnabled()); updateColumn(m_tableView->currentIndex().column()); } void KexiCSVImportDialog::delimiterChanged(const QString& delimiter) { Q_UNUSED(delimiter); m_columnsAdjusted = false; m_detectDelimiter = false; //selected by hand: do not detect in the future //delayed, otherwise combobox won't be repainted fillTableLater(); } void KexiCSVImportDialog::commentSymbolChanged(const QString& commentSymbol) { QString noneString = QString(xi18n("None")); if (commentSymbol.compare(noneString) == 0) { m_parseComments = false; } else { m_parseComments = true; } m_columnsAdjusted = false; m_detectDelimiter = false; //selected by hand: do not detect in the future //delayed, otherwise combobox won't be repainted fillTableLater(); } void KexiCSVImportDialog::textquoteSelected(int) { const QString tq(m_comboQuote->textQuote()); if (tq.isEmpty()) m_textquote = 0; else m_textquote = tq[0]; qDebug() << m_textquote; //delayed, otherwise combobox won't be repainted fillTableLater(); } void KexiCSVImportDialog::fillTableLater() { m_table->setColumnCount(0); QTimer::singleShot(10, this, SLOT(fillTable())); } void KexiCSVImportDialog::startlineSelected(int startline) { if (m_startline == (startline - 1)) return; m_startline = startline - 1; m_adjustRows = true; m_columnsAdjusted = false; fillTable(); m_tableView->setFocus(); } void KexiCSVImportDialog::currentCellChanged(const QModelIndex &cur, const QModelIndex &prev) { if (prev.column() == cur.column() || !cur.isValid()) return; const KDbField::Type type = d->detectedType(cur.column()); m_formatCombo->setCurrentIndex(kexiCSVImportStatic->indicesForTypes.value(type, -1)); m_formatLabel->setText(xi18n("Format for column %1:", cur.column() + 1)); m_primaryKeyField->setEnabled(KDbField::Integer == type); m_primaryKeyField->blockSignals(true); //block to disable executing slotPrimaryKeyFieldToggled() m_primaryKeyField->setChecked(m_primaryKeyColumn == cur.column()); m_primaryKeyField->blockSignals(false); } //! Used in emergency by accept() void KexiCSVImportDialog::dropDestinationTable(KexiProject* project, KexiPart::Item* &partItemForSavedTable) { m_importingProgressBar->hide(); project->deleteUnstoredItem(partItemForSavedTable); partItemForSavedTable = 0; m_conn->dropTable(m_destinationTableSchema); /*alsoRemoveSchema*/ m_destinationTableSchema = 0; m_conn = 0; } //! Used in emergency by accept() void KexiCSVImportDialog::raiseErrorInAccept(KexiProject* project, KexiPart::Item* &partItemForSavedTable) { finishButton()->setEnabled(true); project->deleteUnstoredItem(partItemForSavedTable); partItemForSavedTable = 0; delete m_destinationTableSchema; m_destinationTableSchema = 0; m_conn = 0; backButton()->setEnabled(true); m_importInProgress = false; m_importingProgressBar->hide(); } void KexiCSVImportDialog::accept() { if (d->imported) { parentWidget()->raise(); bool openingCanceled; KexiWindow *win = KexiMainWindowIface::global()->openedWindowFor(m_partItemForSavedTable); if (win) { KexiMainWindowIface::global()->closeObject(m_partItemForSavedTable); } KexiMainWindowIface::global()->openObject(m_partItemForSavedTable, Kexi::DataViewMode, &openingCanceled); KAssistantDialog::accept(); } else { import(); } } void KexiCSVImportDialog::import() { //! @todo MOVE MOST OF THIS TO CORE/ (KexiProject?) after KexiWindow code is moved to non-gui place KMessageBox::enableMessage("SkipImportErrors"); KexiGUIMessageHandler msg; //! @todo make it better integrated with main window KexiProject *project = KexiMainWindowIface::global()->project(); if (!project) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No project available.")); return; } m_conn = project->dbConnection(); if (!m_conn) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("No database connection available.")); return; } if (m_newTableOption->isChecked()) { m_destinationTableSchema = new KDbTableSchema(m_partItemForSavedTable->name()); m_destinationTableSchema->setCaption(m_partItemForSavedTable->caption()); m_destinationTableSchema->setDescription(m_partItemForSavedTable->description()); const int numCols(m_table->columnCount()); m_implicitPrimaryKeyAdded = false; //add PK if user wanted it int msgboxResult; if ( m_primaryKeyColumn == -1 && KMessageBox::No != (msgboxResult = KMessageBox::questionYesNoCancel(this, xi18nc("@info", "No primary key (autonumber) has been defined." "Should it be automatically defined on import (recommended)?" "An imported table without a primary key may not be " "editable (depending on database type)."), QString(), KGuiItem(xi18nc("@action:button Add Database Primary Key to a Table", "&Add Primary Key"), KexiIconName("database-key")), KGuiItem(xi18nc("@action:button Do Not Add Database Primary Key to a Table", "Do &Not Add"), KStandardGuiItem::no().icon())))) { if (msgboxResult == KMessageBox::Cancel) { raiseErrorInAccept(project, m_partItemForSavedTable); return; //cancel accepting } //add implicit PK field //! @todo make this field hidden (what about e.g. pgsql?) m_implicitPrimaryKeyAdded = true; QString fieldName("id"); QString fieldCaption("Id"); QSet colnames; for (int col = 0; col < numCols; col++) colnames.insert(m_table->data(m_table->index(0, col)).toString().toLower().simplified()); if (colnames.contains(fieldName)) { int num = 1; while (colnames.contains(fieldName + QString::number(num))) num++; fieldName += QString::number(num); fieldCaption += QString::number(num); } KDbField *field = new KDbField( fieldName, KDbField::Integer, KDbField::NoConstraints, KDbField::NoOptions, 0, 0, //int length=0, int precision=0, QVariant(), //QVariant defaultValue=QVariant(), fieldCaption ); //no description and width for now field->setPrimaryKey(true); field->setAutoIncrement(true); if (!m_destinationTableSchema->addField(field)) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("Cannot add column.")); delete field; delete m_destinationTableSchema; m_destinationTableSchema = 0; return; } } for (int col = 0; col < numCols; col++) { QString fieldCaption(m_table->data(m_table->index(0, col)).toString().simplified()); QString fieldName; if (fieldCaption.isEmpty()) { int i = 0; do { fieldCaption = xi18nc("@title:column Column 1, Column 2, etc.", "Column %1", i + 1); fieldName = KDb::stringToIdentifier(fieldCaption); if (!m_destinationTableSchema->field(fieldName)) { break; } i++; } while (true); } else { fieldName = KDb::stringToIdentifier(fieldCaption); if (m_destinationTableSchema->field(fieldName)) { QString fixedFieldName; int i = 2; //"apple 2, apple 3, etc. if there're many "apple" names do { fixedFieldName = fieldName + "_" + QString::number(i); if (!m_destinationTableSchema->field(fixedFieldName)) break; i++; } while (true); fieldName = fixedFieldName; fieldCaption += (" " + QString::number(i)); } } KDbField::Type detectedType = d->detectedType(col); //! @todo what about time and float/double types and different integer subtypes? //! @todo what about long text? if (detectedType == KDbField::InvalidType) { detectedType = KDbField::Text; } KDbField *field = new KDbField( fieldName, detectedType, KDbField::NoConstraints, KDbField::NoOptions, 0, 0, //int length=0, int precision=0, QVariant(), //QVariant defaultValue=QVariant(), fieldCaption ); //no description and width for now if ((int)col == m_primaryKeyColumn) { field->setPrimaryKey(true); field->setAutoIncrement(true); } if (!m_destinationTableSchema->addField(field)) { msg.showErrorMessage(KDbMessageHandler::Error, xi18n("Cannot add column.")); delete field; delete m_destinationTableSchema; m_destinationTableSchema = 0; return; } } } else { m_implicitPrimaryKeyAdded = false; m_destinationTableSchema = m_conn->tableSchema(m_partItemForSavedTable->name()); int firstColumn = 0; if (m_destinationTableSchema->field(0)->isPrimaryKey() && m_primaryKeyColumn == -1) { m_implicitPrimaryKeyAdded = true; firstColumn = 1; } if (m_destinationTableSchema->fields()->size() - firstColumn < m_table->columnCount()) { KMessageBox::error(this, xi18n("Field count does not match." "Please choose another table.")); return; } } m_importInProgress = true; backButton()->setEnabled(false); finishButton()->setEnabled(false); KexiPart::Part *part = Kexi::partManager().partForPluginId("org.kexi-project.table"); if (!part) { msg.showErrorMessage(Kexi::partManager().result()); return; } KDbTransaction transaction = m_conn->beginTransaction(); if (transaction.isNull()) { msg.showErrorMessage(m_conn->result()); raiseErrorInAccept(project, m_partItemForSavedTable); return; } KDbTransactionGuard tg(transaction); //-create physical table if (m_newTableOption->isChecked() && !m_conn->createTable(m_destinationTableSchema, KDbConnection::CreateTableOptions(KDbConnection::CreateTableOption::Default) & ~KDbConnection::CreateTableOptions(KDbConnection::CreateTableOption::DropDestination))) { msg.showErrorMessage(m_conn->result()); raiseErrorInAccept(project, m_partItemForSavedTable); return; } m_importingStatement = m_conn->prepareStatement( KDbPreparedStatement::InsertStatement, m_destinationTableSchema); if (!m_importingStatement.isValid()) { msg.showErrorMessage(m_conn->result()); raiseErrorInAccept(project, m_partItemForSavedTable); return; } if (m_file) { m_importProgressLabel->setText(xi18n("Importing data...")); m_importingProgressBar->setMaximum(QFileInfo(*m_file).size() - 1); m_importingProgressBar->show(); m_importProgressLabel->show(); } int row, column, maxColumn; QString field; // main job tristate res = loadRows(field, row, column, maxColumn, false /*!gui*/); if (true != res) { //importing canceled or failed if (!res) { //do not display err msg when res == cancelled m_importProgressLabel->setText(xi18n("Import has been canceled.")); } else if (~res) { m_importProgressLabel->setText(xi18n("Error occurred during import.")); } raiseErrorInAccept(project, m_partItemForSavedTable); return; } // file with only one line without '\n' if (field.length() > 0) { setText(row - m_startline, column, field, false /*!gui*/); //fill remaining empty fields (database wants them explicitly) for (int additionalColumn = column; additionalColumn <= maxColumn; additionalColumn++) { setText(row - m_startline, additionalColumn, QString(), false /*!gui*/); } if (!saveRow(false /*!gui*/)) { msg.showErrorMessage(m_conn->result()); raiseErrorInAccept(project, m_partItemForSavedTable); return; } ++row; field.clear(); } if (!tg.commit()) { msg.showErrorMessage(m_conn->result()); raiseErrorInAccept(project, m_partItemForSavedTable); return; } //-now we can store the item if (m_newTableOption->isChecked()) { m_partItemForSavedTable->setIdentifier(m_destinationTableSchema->id()); project->addStoredItem(part->info(), m_partItemForSavedTable); } m_importingProgressBar->hide(); m_importProgressLabel->setText(xi18nc("@info", "Data has been successfully imported to table %1.", m_destinationTableSchema->name())); m_importInProgress = false; //qDebug()<<"IMPORT DONE"; KGuiItem::assign(finishButton(), KStandardGuiItem::open()); finishButton()->setEnabled(true); KGuiItem::assign(button(QDialogButtonBox::Cancel), KStandardGuiItem::close()); nextButton()->setEnabled(false); backButton()->setEnabled(false); m_conn = 0; d->imported = true; } void KexiCSVImportDialog::reject() { //qDebug()<<"IMP_P"<horizontalHeaderItem(col)->text(); if (header == xi18nc("Text type for column", "Text")) return TEXT; else if (header == xi18nc("Numeric type for column", "Number")) return NUMBER; else if (header == xi18nc("Currency type for column", "Currency")) return CURRENCY; else return DATE; } QString KexiCSVImportDialog::getText(int row, int col) { return m_table->item(row, col)->text(); } void KexiCSVImportDialog::ignoreDuplicatesChanged(int) { fillTable(); } void KexiCSVImportDialog::slot1stRowForFieldNamesChanged(int state) { m_adjustRows = true; if (m_1stRowForFieldNames->isChecked() && m_startline > 0 && m_startline >= (m_startAtLineSpinBox->maximum() - 1)) { m_startline--; } m_columnsAdjusted = false; fillTable(); m_table->setFirstRowForFieldNames(state); } void KexiCSVImportDialog::optionsButtonClicked() { KexiCSVImportOptionsDialog dlg(m_options, this); if (QDialog::Accepted != dlg.exec()) return; KexiCSVImportOptions newOptions(dlg.options()); if (m_options != newOptions) { m_options = newOptions; if (!openData()) return; fillTable(); } } bool KexiCSVImportDialog::eventFilter(QObject * watched, QEvent * e) { QEvent::Type t = e->type(); // temporary disable keyboard and mouse events for time-consuming tasks if (m_blockUserEvents && (t == QEvent::KeyPress || t == QEvent::KeyRelease || t == QEvent::MouseButtonPress || t == QEvent::MouseButtonDblClick || t == QEvent::Paint)) return true; if (watched == m_startAtLineSpinBox && t == QEvent::KeyPress) { QKeyEvent *ke = static_cast(e); if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) { m_tableView->setFocus(); return true; } } return QDialog::eventFilter(watched, e); } void KexiCSVImportDialog::slotPrimaryKeyFieldToggled(bool on) { setPrimaryKeyIcon(m_primaryKeyColumn, false); m_primaryKeyColumn = on ? m_tableView->currentIndex().column() : -1; setPrimaryKeyIcon(m_primaryKeyColumn, true); } void KexiCSVImportDialog::setPrimaryKeyIcon(int column, bool set) { if (column >= 0 && column < m_table->columnCount()) { m_table->setData(m_table->index(0, column), set ? m_pkIcon : QPixmap(), Qt::DecorationRole); } } void KexiCSVImportDialog::updateRowCountInfo() { m_infoLbl->setFileName(m_fname); if (m_allRowsLoadedInPreview) { m_infoLbl->setCommentText( xi18nc("row count", "(rows: %1)", m_table->rowCount() - 1 + m_startline)); m_infoLbl->commentLabel()->setToolTip(QString()); } else { m_infoLbl->setCommentText( xi18nc("row count", "(rows: more than %1)", m_table->rowCount() - 1 + m_startline)); m_infoLbl->commentLabel()->setToolTip(xi18n("Not all rows are visible on this preview")); } } QPushButton* KexiCSVImportDialog::configureButton() const { // Help button is used as Configure return button(QDialogButtonBox::Help); } #include "kexicsvimportdialog.moc" diff --git a/src/plugins/importexport/csv/kexicsvimportdialog.h b/src/plugins/importexport/csv/kexicsvimportdialog.h index b24be0b79..75d41e882 100644 --- a/src/plugins/importexport/csv/kexicsvimportdialog.h +++ b/src/plugins/importexport/csv/kexicsvimportdialog.h @@ -1,315 +1,315 @@ /* This file is part of the KDE project Copyright (C) 2005-2017 Jarosław Staniek Copyright (C) 2012 Oleg Kukharchuk This work is based on kspread/dialogs/kspread_dlg_csv.cc. Copyright (C) 2002-2003 Norbert Andres Copyright (C) 2002-2003 Ariya Hidayat Copyright (C) 2002 Laurent Montel Copyright (C) 1999 David Faure 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 KEXI_CSVIMPORTDIALOG_H #define KEXI_CSVIMPORTDIALOG_H #include #include #include #include #include #include #include #include #include #include #include "kexicsvimportoptionsdlg.h" class QHBoxLayout; class QGridLayout; class QCheckBox; class QLabel; class QTableView; class QTreeView; class QFile; class QStackedWidget; class QProgressDialog; class QProgressBar; class QRadioButton; class QSpinBox; class KComboBox; class KPageWidgetItem; class KDbConnection; class KDbTableSchema; class KexiCSVCommentWidget; class KexiCSVDelimiterWidget; class KexiCSVTextQuoteComboBox; class KexiCSVInfoLabel; class KexiProject; class KexiCSVImportDialogModel; class KexiCSVImportDialogItemDelegate; class KexiFileWidgetInterface; class KexiNameWidget; class KexiProjectNavigator; class KexiFieldListModel; namespace KexiPart { class Item; } /** * @short Kexi CSV import dialog * * This is temporary solution for Kexi CSV import, * based on kspread/dialogs/kspread_dlg_csv.h, cc. * * Provides dialog for managing CSV (comma separated value) data. * * Currently KexiCSVImportDialog is used for converting text into columns, * inserting text file and pasting text from clipboard, where conversion * from CSV (comma separated value) data is is all required. * The different purposed mentioned above is determined * using mode, which can be Column, File, or Clipboard respectively. */ class KexiCSVImportDialog : public KAssistantDialog { Q_OBJECT public: enum Mode { Clipboard, File /*, Column*/ }; enum Header { TEXT, NUMBER, DATE, CURRENCY }; //! @todo what about making it kexidb-independent? explicit KexiCSVImportDialog(Mode mode, QWidget *parent = 0); virtual ~KexiCSVImportDialog(); bool canceled() const; protected: - virtual bool eventFilter(QObject *watched, QEvent *e); + virtual bool eventFilter(QObject *watched, QEvent *e) override; bool openData(); - virtual void accept(); - virtual void reject(); + virtual void accept() override; + virtual void reject() override; private: //! Used in emergency by accept() //! @note @a partItemForSavedTable is IN-OUT void dropDestinationTable(KexiProject* project, KexiPart::Item* &partItemForSavedTable); //! Used in emergency by accept() //! @note @a partItemForSavedTable is IN-OUT void raiseErrorInAccept(KexiProject* project, KexiPart::Item* &partItemForSavedTable); QGridLayout* MyDialogLayout; QHBoxLayout* Layout1; KexiCSVImportDialogModel *m_table; KexiCSVImportDialogItemDelegate *m_tableItemDelegate; QTableView *m_tableView; KexiCSVDelimiterWidget* m_delimiterWidget; KexiCSVCommentWidget* m_commentWidget; bool m_detectDelimiter; //!< true if delimiter should be detected //!< (true by default, set to false if user sets delimiter) QLabel* m_formatLabel; KComboBox* m_formatCombo; QSpinBox *m_startAtLineSpinBox; KexiCSVTextQuoteComboBox* m_comboQuote; QLabel* m_startAtLineLabel; QLabel* TextLabel2; QCheckBox* m_ignoreDuplicates; QCheckBox* m_1stRowForFieldNames; QCheckBox* m_primaryKeyField; KexiFileWidgetInterface *m_fileIface; QWidget *m_optionsWidget; QWidget *m_saveMethodWidget; KPageWidgetItem *m_openFilePage; KPageWidgetItem *m_optionsPage; KPageWidgetItem *m_saveMethodPage; KPageWidgetItem *m_chooseTablePage; QRadioButton *m_newTableOption; QRadioButton *m_existingTableOption; QStackedWidget *m_tableNameWidget; KPageWidgetItem *m_tableNamePage; KexiNameWidget *m_newTableWidget; KexiProjectNavigator *m_tablesList; QTreeView *m_fieldsListView; QLabel *m_tableCaptionLabel; QLabel *m_tableNameLabel; QLabel *m_recordCountLabel; QLabel *m_colCountLabel; QWidget *m_importWidget; KPageWidgetItem *m_importPage; KexiCSVInfoLabel *m_fromLabel; KexiCSVInfoLabel *m_toLabel; QLabel *m_importProgressLabel; void detectTypeAndUniqueness(int row, int col, const QString& text); void setText(int row, int col, const QString& text, bool inGUI); /*! Parses date from \a text and stores into \a date. m_dateRegExp is used for clever detection; if '/' separated is found, it's assumed the format is american mm/dd/yyyy. This function supports omitted zeros, so 1/2/2006 is parsed properly too. \return true on success. */ bool parseDate(const QString& text, QDate& date); /*! Parses time from \a text and stores into \a date. m_timeRegExp1 and m_timeRegExp2 are used for clever detection; both hh:mm:ss and hh:mm are supported. This function supports omitted zeros, so 1:2:3 is parsed properly too. \return true on success. */ bool parseTime(const QString& text, QTime& time); /*! Called after the first fillTable() when number of rows is unknown. */ void adjustRows(int iRows); int getHeader(int col); QString getText(int row, int col); void updateColumn(int col); bool isPrimaryKeyAllowed(int col); void setPrimaryKeyIcon(int column, bool set); void updateRowCountInfo(); tristate loadRows(QString &field, int &row, int &columnm, int &maxColumn, bool inGUI); /*! Detects delimiter by looking at first 4K bytes of the data. Used by loadRows(). The used algorithm: 1. Look byte by byte and locate special characters that can be delimiters. Special fact is taken into account: if there are '"' quotes used for text values, delimiters that follow directly the closing quote has higher priority than the one that follows other character. We do not assume that every text value is quoted. Summing up, there is following hierarchy (from highest to lowest): quote+tab, quote+semicolon, quote+comma, tab, semicolon, comma. Space characters are skipped. Text inside quotes is skipped, as well as double (escaped) quotes. 2. While scanning the data, for every row following number of tabs, semicolons and commas (only these outside of the quotes) are computed. On every line the values are appended to a separate list (QList). 3. After scanning, all the values are checked on the QList of tabs. If the list has more one element (so there was more than one row) and all the values (numbers of tabs) are equal, it's very probable the tab is a delimiter. So, this character is returned as a delimiter. 3a. The same algorithm as in 3. is performed for semicolon character. 3b. The same algorithm as in 3. is performed for comma character. 4. If the step 3. did not return a delimiter, a character found in step 1. with the highest priority is retured as delimiter. */ QString detectDelimiterByLookingAtFirstBytesOfFile(QTextStream *inputStream); /*! Callback, called whenever row is loaded in loadRows(). When inGUI is true, nothing is performed, else database buffer is written back to the database. */ bool saveRow(bool inGUI); //! @return date built out of @a y, @a m, @a d parts, //! taking m_minimumYearFor100YearSlidingWindow into account QDate buildDate(int y, int m, int d) const; //! Updates size of m_columnNames and m_changedColumnNames if needed void updateColumnVectorSize(); QPushButton* configureButton() const; bool m_parseComments; bool m_canceled; bool m_adjustRows; int m_startline; QChar m_textquote; QChar m_commentSymbol; QString m_clipboardData; QByteArray m_fileArray; Mode m_mode; QRegularExpression m_dateRegExp, m_timeRegExp1, m_timeRegExp2, m_fpNumberRegExp1, m_fpNumberRegExp2; bool m_columnsAdjusted; //!< to call adjustColumn() only once bool m_1stRowForFieldNamesDetected; //!< used to force rerun fillTable() after 1st row bool m_firstFillTableCall; //!< used to know whether it's 1st fillTable() call bool m_blockUserEvents; int m_primaryKeyColumn; //!< index of column with PK assigned (-1 if none) int m_maximumRowsForPreview; int m_maximumBytesForPreview; /*! The minimum year for the "100 year sliding date window": range of years that defines where any year expressed as two digits falls. Example: for date window from 1930 to 2029, two-digit years between 0 and 29 fall in the 2000s, and two-digit years between 30 and 99 fall in the 1900s. The default is 1930. */ int m_minimumYearFor100YearSlidingWindow; QPixmap m_pkIcon; QString m_fname; QFile* m_file; QTextStream *m_inputStream; //!< used in loadData() KexiCSVImportOptions m_options; QProgressDialog *m_loadingProgressDlg; QProgressBar *m_importingProgressBar; bool m_dialogCanceled; KexiCSVInfoLabel *m_infoLbl; KDbConnection *m_conn; //!< (temp) database connection used for importing KexiFieldListModel *m_fieldsListModel; KDbTableSchema *m_destinationTableSchema; //!< (temp) dest. table schema used for importing KDbPreparedStatement m_importingStatement; QList m_dbRowBuffer; //!< (temp) used for importing bool m_implicitPrimaryKeyAdded; //!< (temp) used for importing bool m_allRowsLoadedInPreview; //!< we need to know whether all rows were loaded or it's just a partial data preview bool m_stoppedAt_MAX_BYTES_TO_PREVIEW; //!< used to compute m_allRowsLoadedInPreview const QString m_stringNo, m_stringI18nNo, m_stringFalse, m_stringI18nFalse; //!< used for importing boolean values int m_prevColumnForSetText; //!< used for non-gui tracking of skipped clolumns, //!< so can be saved to the database, //!< e.g. first three columns are saved for ,,,"abc" line in the CSV data QElapsedTimer m_elapsedTimer; //!< Used to update progress qint64 m_elapsedMs; void createImportMethodPage(); void createOptionsPage(); void createFileOpenPage(); void createTableNamePage(); void createImportPage(); KDbPreparedStatementParameters m_valuesToInsert; KexiPart::Item* m_partItemForSavedTable; bool m_importInProgress; bool m_importCanceled; class Private; Private * const d; public Q_SLOTS: - virtual void next(); + virtual void next() override; private Q_SLOTS: void fillTable(); void fillTableLater(); void initLater(); void formatChanged(int id); void delimiterChanged(const QString& delimiter); void commentSymbolChanged(const QString& commentSymbol); void startlineSelected(int line); void textquoteSelected(int); void currentCellChanged(const QModelIndex &cur, const QModelIndex &prev); void ignoreDuplicatesChanged(int); void slot1stRowForFieldNamesChanged(int state); void optionsButtonClicked(); void slotPrimaryKeyFieldToggled(bool on); void slotCurrentPageChanged(KPageWidgetItem *page, KPageWidgetItem *prev); void slotShowSchema(KexiPart::Item *item); void import(); }; #endif diff --git a/src/plugins/importexport/csv/kexicsvimportoptionsdlg.h b/src/plugins/importexport/csv/kexicsvimportoptionsdlg.h index f0eaf2182..d5721cd4f 100644 --- a/src/plugins/importexport/csv/kexicsvimportoptionsdlg.h +++ b/src/plugins/importexport/csv/kexicsvimportoptionsdlg.h @@ -1,75 +1,75 @@ /* This file is part of the KDE project Copyright (C) 2005-2012 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICSVOPTIONSDIALOG_H #define KEXICSVOPTIONSDIALOG_H #include #include class KexiCharacterEncodingComboBox; class QComboBox; //! @short CSV Options class KexiCSVImportOptions { public: KexiCSVImportOptions(); ~KexiCSVImportOptions(); //! Date format values enum DateFormat { AutoDateFormat = 0, //!< auto DMY = 1, //!< day-month-year YMD = 2, //!< year-month-day MDY = 3 //!< month-day-year }; bool operator== (const KexiCSVImportOptions & opt) const; bool operator!= (const KexiCSVImportOptions & opt) const; QString encoding; DateFormat dateFormat; bool defaultEncodingExplicitySet; bool trimmedInTextValuesChecked; bool nullsImportedAsEmptyTextChecked; }; //! @short CSV Options dialog class KexiCSVImportOptionsDialog : public QDialog { Q_OBJECT public: explicit KexiCSVImportOptionsDialog(const KexiCSVImportOptions& options, QWidget* parent = 0); virtual ~KexiCSVImportOptionsDialog(); KexiCSVImportOptions options() const; protected Q_SLOTS: - virtual void accept(); + virtual void accept() override; protected: KexiCharacterEncodingComboBox *m_encodingComboBox; QCheckBox *m_chkAlwaysUseThisEncoding; QCheckBox *m_chkStripWhiteSpaceInTextValues; QCheckBox *m_chkImportNULLsAsEmptyText; QComboBox *m_comboDateFormat; }; #endif diff --git a/src/plugins/queries/kexiquerydesignerguieditor.h b/src/plugins/queries/kexiquerydesignerguieditor.h index eb95dfa84..4cf5d3162 100644 --- a/src/plugins/queries/kexiquerydesignerguieditor.h +++ b/src/plugins/queries/kexiquerydesignerguieditor.h @@ -1,173 +1,173 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch Copyright (C) 2004-2015 Jarosław Staniek 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 KEXIQUERYDESIGNERGUIEDITOR_H #define KEXIQUERYDESIGNERGUIEDITOR_H #include #include "kexiquerypart.h" #include class QDragMoveEvent; class QDropEvent; class KProperty; class KPropertySet; class KDbConnection; class KDbTableOrQuerySchema; class KDbResultInfo; class KDbRecordData; class KexiRelationsView; class KexiRelationsTableContainer; class KexiRelationsConnection; namespace KexiPart { class Item; } //! Design view of the Query Designer class KexiQueryDesignerGuiEditor : public KexiView { Q_OBJECT public: explicit KexiQueryDesignerGuiEditor(QWidget *parent); virtual ~KexiQueryDesignerGuiEditor(); KexiRelationsView *relationsView() const; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; public Q_SLOTS: - virtual void setFocus(); + virtual void setFocus() override; protected: void initTableColumns(); //!< Called just once. void initTableRows(); //!< Called to have all rows empty. - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); - virtual tristate storeData(bool dontAsk = false); + bool *cancel) override; + virtual tristate storeData(bool dontAsk = false) override; /*! Updates data in columns depending on tables that are currently inserted. Tabular Data in combo box popups is updated as well. */ void updateColumnsData(); /*! \return property buffer associated with currently selected row (i.e. field) or 0 if current row is empty. */ - virtual KPropertySet *propertySet(); + virtual KPropertySet *propertySet() override; KPropertySet* createPropertySet(int row, const QString& tableName, const QString& fieldName, bool newOne = false); /*! Builds query schema out of information provided by gui. The schema is stored in temp->query member. \a errMsg is optional error message returned. \return true on proper schema creation. */ bool buildSchema(QString *errMsg = 0); KexiQueryPartTempData * tempData() const; /*! Helper: allocates and initializes new table view's row. Doesn't insert it, just returns. \a tableName and \a fieldName should be provided. \a visible flag sets value for "Visible" column. */ KDbRecordData* createNewRow(const QString& tableName, const QString& fieldName, bool visible) const; KDbExpression parseExpressionString(const QString& fullString, KDbToken *token, bool allowRelationalOperator); /*! @internal generates smallest unique alias */ QByteArray generateUniqueAlias() const; void updatePropertiesVisibility(KPropertySet& buf); protected Q_SLOTS: void slotDragOverTableRecord(KDbRecordData *data, int record, QDragMoveEvent* e); void slotDroppedAtRecord(KDbRecordData *data, int record, QDropEvent *ev, KDbRecordData*& newRecord); //! Reaction on appending a new item after deleting one void slotNewItemAppendedForAfterDeletingInSpreadSheetMode(); void slotTableAdded(KDbTableSchema* t); void slotTableHidden(KDbTableSchema* t); //! Called before cell change in tableview. void slotBeforeCellChanged(KDbRecordData* data, int colnum, QVariant* newValue, KDbResultInfo* result); void slotRecordInserted(KDbRecordData* data, int record, bool repaint); void slotTablePositionChanged(KexiRelationsTableContainer*); void slotAboutConnectionRemove(KexiRelationsConnection*); void slotAppendFields(KDbTableOrQuerySchema& tableOrQuery, const QStringList& fieldNames); /*! Loads layout of relation GUI diagram. */ bool loadLayout(); /*! Stores layout of relation GUI diagram. */ bool storeLayout(); void showTablesForQuery(KDbQuerySchema *query); //! @internal void showFieldsOrRelationsForQueryInternal( KDbQuerySchema *query, bool showFields, bool showRelations, KDbResultInfo& result); //! convenience method equal to showFieldsOrRelationsForQueryInternal(query, true, true) void showFieldsAndRelationsForQuery(KDbQuerySchema *query, KDbResultInfo& result); //! convenience method equal to showFieldsOrRelationsForQueryInternal(query, true, false) void showFieldsForQuery(KDbQuerySchema *query, KDbResultInfo& result); //! convenience method equal to showFieldsOrRelationsForQueryInternal(query, false, true) void showRelationsForQuery(KDbQuerySchema *query, KDbResultInfo& result); void addConnection(KDbField *masterField, KDbField *detailsField); void slotPropertyChanged(KPropertySet& set, KProperty& property); void slotNewItemStored(KexiPart::Item* item); void slotItemRemoved(const KexiPart::Item& item); void slotItemRenamed(const KexiPart::Item& item, const QString& oldName); private: void slotBeforeColumnCellChanged(KDbRecordData *data, QVariant& newValue, KDbResultInfo* result); void slotBeforeTableCellChanged(KDbRecordData *data, QVariant& newValue, KDbResultInfo* result); void slotBeforeVisibleCellChanged(KDbRecordData *data, QVariant& newValue, KDbResultInfo* result); void slotBeforeTotalsCellChanged(KDbRecordData *data, QVariant& newValue, KDbResultInfo* result); void slotBeforeSortingCellChanged(KDbRecordData *data, QVariant& newValue, KDbResultInfo* result); void slotBeforeCriteriaCellChanged(KDbRecordData *data, QVariant& newValue, KDbResultInfo* result); class Private; Private * const d; friend class KexiQueryView; // for storeNewData() and storeData() only }; #endif diff --git a/src/plugins/queries/kexiquerydesignersql.h b/src/plugins/queries/kexiquerydesignersql.h index 7cbb57d71..3a3ac79b8 100644 --- a/src/plugins/queries/kexiquerydesignersql.h +++ b/src/plugins/queries/kexiquerydesignersql.h @@ -1,77 +1,77 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004-2016 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIQUERYDESIGNERSQL_H #define KEXIQUERYDESIGNERSQL_H #include "kexiquerypart.h" #include class KexiQueryDesignerSqlEditor; //! The KexiQueryDesignerSqlView class for editing Queries in text mode. /*! It is a view containing SQL text editor and SQL status widget split vertically. */ class KexiQueryDesignerSqlView : public KexiView { Q_OBJECT public: explicit KexiQueryDesignerSqlView(QWidget *parent); virtual ~KexiQueryDesignerSqlView(); QString sqlText() const; KexiQueryDesignerSqlEditor *editor() const; protected: KexiQueryPartTempData * tempData() const; - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); - virtual tristate storeData(bool dontAsk = false); + bool *cancel) override; + virtual tristate storeData(bool dontAsk = false) override; void setStatusOk(); void setStatusError(const QString& msg); void setStatusEmpty(); void setStatusText(const QString& text); - virtual void updateActions(bool activated); + virtual void updateActions(bool activated) override; protected Q_SLOTS: /*! Performs query checking (by text parsing). \return true and sets d->parsedQuery to the new query schema object on success. */ bool slotCheckQuery(); void slotTextChanged(); Q_SIGNALS: void queryShortcut(); private: class Private; Private * const d; friend class KexiQueryView; // for storeNewData() and storeData() only }; #endif diff --git a/src/plugins/queries/kexiquerypart.h b/src/plugins/queries/kexiquerypart.h index bd827cb3d..9d1b3f2cb 100644 --- a/src/plugins/queries/kexiquerypart.h +++ b/src/plugins/queries/kexiquerypart.h @@ -1,150 +1,150 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004-2017 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIQUERYPART_H #define KEXIQUERYPART_H #include #include #include #include #include //! @short Temporary data kept in memory while switching between Query Window's views class KexiQueryPartTempData : public KexiWindowData, public KDbTableSchemaChangeListener { Q_OBJECT public: KexiQueryPartTempData(KexiWindow* parent, KDbConnection *conn); virtual ~KexiQueryPartTempData(); - virtual tristate closeListener(); + virtual tristate closeListener() override; void clearQuery(); void unregisterForTablesSchemaChanges(); void registerTableSchemaChanges(KDbQuerySchema *q); /*! Assigns query \a query for this data. Existing query (available using query()) is deleted but only if it is not owned by parent window (i.e. != KexiWindow::schemaObject()). \a query can be 0. If \a query is equal to existing query, nothing is performed. */ void setQuery(KDbQuerySchema *query); //! \return query associated with this data KDbQuerySchema *query() const { return m_query; } //! Takes query associated with this data (without deleting) and returns it. //! After this call query() == 0 KDbQuerySchema *takeQuery(); //! Connection used for retrieving definition of the query KDbConnection *conn; /*! @return view mode if which the query member has changed. It's possibly one of previously visited views. Kexi::NoViewMode is the default, what means that query was not changed. Used on view switching. We're checking this flag to see if we should rebuild internal structure for DesignViewMode of regenerated sql text in TextViewMode after switch from other view. */ Kexi::ViewMode queryChangedInView() const; /*! Sets the queryChangedInView flag. If @a set is true, then the flag is changed to the current view mode. If @a set is false, the flag is changed to Kexi::NoViewMode. @see queryChangedInView() */ void setQueryChangedInView(bool set); private: KDbQuerySchema *m_query; Kexi::ViewMode m_queryChangedInView; }; //! @short Kexi Query Designer plugin class KexiQueryPart : public KexiPart::Part { Q_OBJECT public: KexiQueryPart(QObject *parent, const QVariantList &); virtual ~KexiQueryPart(); - virtual tristate remove(KexiPart::Item *item); + virtual tristate remove(KexiPart::Item *item) override; //! Implemented for KexiPart::Part. - virtual KDbQuerySchema* currentQuery(KexiView* view); + virtual KDbQuerySchema* currentQuery(KexiView* view) override; virtual KLocalizedString i18nMessage(const QString& englishMessage, - KexiWindow* window) const; + KexiWindow* window) const override; /*! Renames stored data pointed by \a item to \a newName. Reimplemented to mark the query obsolete by using KDbConnection::setQuerySchemaObsolete(). */ - virtual tristate rename(KexiPart::Item *item, const QString& newName); + virtual tristate rename(KexiPart::Item *item, const QString& newName) override; /** * Closes objects that listenen to changes of the query schema @a query, i.e. use it. * * These objects can be currently: * - lookup fields of tables * - queries using the query directly (as subqueries) or via lookup fields * - forms and reports that use the query directly as data source or via query. * * Scripts referencing the query programatically are not analyzed, so they can fail on next * execution. * * This method asks the user for approval if there is at least one object that listens for * changes of the schema (altering or removal). If there is no approval, returns * @c cancelled. On failure @c false is returned. If @a window is @c nullptr, @c true is * returned immediately because there is no window to care about. * * @note Unlike renaming tables, renaming queries just marks the previous query object one as * "obsolete" using KDbConnection::setQuerySchemaObsolete() and keeps the existing actual object * in memory so there is no risk of accessing deleted object by other objects. * * Special case: listener for the query @a query will be silently closed without asking for * confirmation. It is ignored when looking for objects that are "blocking" changes * of @a query. This exception is needed because the listener handles the data view's lifetime * and the data view should be reset silently without bothering the user. * * @see KexiQueryPartTempData::closeListener() * @see KexiTablePart::askForClosingObjectsUsingTableSchema() */ static tristate askForClosingObjectsUsingQuerySchema(KexiWindow *window, KDbConnection *conn, KDbQuerySchema *query, const KLocalizedString &msg); protected: KexiWindowData* createWindowData(KexiWindow* window) override Q_REQUIRED_RESULT; KexiView *createView(QWidget *parent, KexiWindow *window, KexiPart::Item *item, Kexi::ViewMode viewMode = Kexi::DataViewMode, QMap *staticObjectArgs = nullptr) override Q_REQUIRED_RESULT; - virtual void initPartActions(); - virtual void initInstanceActions(); + virtual void initPartActions() override; + virtual void initInstanceActions() override; virtual KDbObject* loadSchemaObject(KexiWindow *window, - const KDbObject& object, Kexi::ViewMode viewMode, bool *ownedByWindow); + const KDbObject& object, Kexi::ViewMode viewMode, bool *ownedByWindow) override; }; #endif diff --git a/src/plugins/queries/kexiqueryview.h b/src/plugins/queries/kexiqueryview.h index f6e8f2c7e..db7a10819 100644 --- a/src/plugins/queries/kexiqueryview.h +++ b/src/plugins/queries/kexiqueryview.h @@ -1,77 +1,77 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch Copyright (C) 2004, 2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIQUERYVIEW_H #define KEXIQUERYVIEW_H #include class KDbQuerySchema; class KexiQueryView : public KexiDataTableView { Q_OBJECT public: explicit KexiQueryView(QWidget *parent); virtual ~KexiQueryView(); /*! \return curent parameters for parametrized query */ - virtual QList currentParameters() const; + virtual QList currentParameters() const override; protected: - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); + bool *cancel) override; - virtual tristate storeData(bool dontAsk = false); + virtual tristate storeData(bool dontAsk = false) override; /** * Assigns query @a query to this view * * - executes it * - fills the table view with results * * @return @c true on success, @c false on failure and @c cancelled when user has cancelled * execution, for example when she pressed the Cancel button in the "Enter Query Parameter" * input dialog. * * In successful execution of the query of if @a query is @c nullptr previous query (if any) * is unassigned and data is removed. */ tristate setQuery(KDbQuerySchema *query); /** * @brief Query that was assigned to this view * * @note It is not owned. */ KDbQuerySchema *query(); friend class KexiQueryPartTempData; class Private; Private * const d; }; #endif diff --git a/src/plugins/reports/KexiDBReportDataSource.h b/src/plugins/reports/KexiDBReportDataSource.h index c8e8885dc..8ffc26e50 100644 --- a/src/plugins/reports/KexiDBReportDataSource.h +++ b/src/plugins/reports/KexiDBReportDataSource.h @@ -1,96 +1,96 @@ /* * Kexi Report Plugin * Copyright (C) 2007-2017 by Adam Pigg * Copyright (C) 2017-2018 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef __KEXIDBREPORTDATA_H__ #define __KEXIDBREPORTDATA_H__ #include #include #include class KexiReportPartTempData; //! @brief Implementation of database report data source class KexiDBReportDataSource : public KReportDataSource { public: /*! * @a pluginId specifies type of @a objectName, a table or query. * Types accepted: * -"org.kexi-project.table" * -"org.kexi-project.query" * -empty QString() - attempt to resolve @a objectName */ KexiDBReportDataSource(const QString &objectName, const QString &pluginId, KexiReportPartTempData *data); virtual ~KexiDBReportDataSource(); - virtual QStringList fieldNames() const; - virtual void setSorting(const QList& sorting); + virtual QStringList fieldNames() const override; + virtual void setSorting(const QList& sorting) override; //! Adds a condition to the data source. //! @note Only single-character relation operators such as "=" or ">" are supported now. //! @todo Use KDb parser to support all relation operators such as ">=". virtual void addCondition(const QString &field, const QVariant &value, - const QString &relation = QLatin1String("=")); + const QString &relation = QLatin1String("=")) override; - virtual QString sourceName() const; - virtual int fieldNumber(const QString &field) const; - virtual QVariant value(int) const; - virtual QVariant value(const QString &field) const; + virtual QString sourceName() const override; + virtual int fieldNumber(const QString &field) const override; + virtual QVariant value(int) const override; + virtual QVariant value(const QString &field) const override; - virtual bool open(); - virtual bool close(); - virtual bool moveNext(); - virtual bool movePrevious(); - virtual bool moveFirst(); - virtual bool moveLast(); + virtual bool open() override; + virtual bool close() override; + virtual bool moveNext() override; + virtual bool movePrevious() override; + virtual bool moveFirst() override; + virtual bool moveLast() override; - virtual qint64 at() const; - virtual qint64 recordCount() const; + virtual qint64 at() const override; + virtual qint64 recordCount() const override; /** * Runs aggregate function @a function on the data source * * @param function name such as max, min, avg * @param field name of field for which the aggregation should be executed * @param conditions optional conditions that limit the record set * @return value of the function, 0.0 on failure * * @warning SQL injection warning: validity of @a function name is not checked, this should not * be part of a public API. * @todo Move SQL aggregate functions to KDb. Current code depends on support for subqueries. */ double runAggregateFunction(const QString &function, const QString &field, const QMap &conditions); //Utility Functions - virtual QStringList dataSourceNames() const; - virtual KReportDataSource* create(const QString& source) const Q_REQUIRED_RESULT; + virtual QStringList dataSourceNames() const override; + virtual KReportDataSource* create(const QString& source) const override Q_REQUIRED_RESULT; private: class Private; Private * const d; bool getSchema(const QString& pluginId); }; #endif diff --git a/src/plugins/reports/kexireportdesignview.h b/src/plugins/reports/kexireportdesignview.h index 795b030cd..305643baf 100644 --- a/src/plugins/reports/kexireportdesignview.h +++ b/src/plugins/reports/kexireportdesignview.h @@ -1,84 +1,84 @@ /* * Kexi Report Plugin * Copyright (C) 2007-2009 by Adam Pigg * Copyright (C) 2011-2017 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KEXIREPORTDESIGNVIEW_H #define KEXIREPORTDESIGNVIEW_H #include #include #include #include #include class QScrollArea; class KexiSourceSelector; /** */ class KexiReportDesignView : public KexiView { Q_OBJECT public: KexiReportDesignView(QWidget *parent, KexiSourceSelector*); ~KexiReportDesignView(); - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; void triggerAction(const QString &); Q_SIGNALS: void itemInserted(const QString& entity); private: KexiReportPartTempData* tempData() const; QDomElement connectionData() const; void setConnectionData(const QDomElement &c); KReportDesigner *m_reportDesigner; QScrollArea * m_scrollArea; //Actions QAction *m_editCutAction; QAction *m_editCopyAction; QAction *m_editPasteAction; QAction *m_editDeleteAction; QAction *m_editSectionAction; QAction *m_itemRaiseAction; QAction *m_itemLowerAction; KexiSourceSelector *m_sourceSelector; protected: - virtual KPropertySet *propertySet(); - virtual tristate storeData(bool dontAsk = false); + virtual KPropertySet *propertySet() override; + virtual tristate storeData(bool dontAsk = false) override; virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); + bool *cancel) override; private Q_SLOTS: void slotDesignerPropertySetChanged(); public Q_SLOTS: void slotDataSourceChanged(); }; #endif diff --git a/src/plugins/reports/kexireportpart.h b/src/plugins/reports/kexireportpart.h index 1cac0ae4a..1f25bda1b 100644 --- a/src/plugins/reports/kexireportpart.h +++ b/src/plugins/reports/kexireportpart.h @@ -1,106 +1,106 @@ /* * Kexi Report Plugin * Copyright (C) 2007-2008 by Adam Pigg * Copyright (C) 2011-2017 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef _KEXIREPORTPART_H_ #define _KEXIREPORTPART_H_ #include #include #include #include #include #include class KexiReportPartTempData : public KexiWindowData, public KDbTableSchemaChangeListener { Q_OBJECT public: KexiReportPartTempData(KexiWindow* parent, KDbConnection *conn); ~KexiReportPartTempData(); QDomElement reportDefinition; QDomElement connectionDefinition; /*! true, if \a document member has changed in previous view. Used on view switching. Check this flag to see if we should refresh data for DataViewMode. */ bool reportSchemaChangedInPreviousView; KDbConnection *connection(); protected: //! This temp-data acts as a listener for tracking changes in table schema //! used by the report. This method closes the report on request. tristate closeListener() override; private: Q_DISABLE_COPY(KexiReportPartTempData) class Private; Private * const d; }; /** * @short Application Main Window */ class KexiReportPart : public KexiPart::Part, public KReportScriptSource { Q_OBJECT public: /** * Default Constructor */ KexiReportPart(QObject *parent, const QVariantList &l); /** * Default Destructor */ virtual ~KexiReportPart(); - virtual void setupCustomPropertyPanelTabs(QTabWidget *tab); + virtual void setupCustomPropertyPanelTabs(QTabWidget *tab) override; virtual KLocalizedString i18nMessage(const QString& englishMessage, - KexiWindow* window) const; + KexiWindow* window) const override; QStringList scriptList() const override; QString scriptCode(const QString& script) const override; protected: KexiView *createView(QWidget *parent, KexiWindow *win, KexiPart::Item *item, Kexi::ViewMode = Kexi::DataViewMode, QMap *staticObjectArgs = nullptr) override Q_REQUIRED_RESULT; KexiWindowData* createWindowData(KexiWindow* window) override Q_REQUIRED_RESULT; - virtual void initPartActions(); + virtual void initPartActions() override; virtual KDbObject* loadSchemaObject(KexiWindow *window, - const KDbObject& object, Kexi::ViewMode viewMode, bool *ownedByWindow); + const KDbObject& object, Kexi::ViewMode viewMode, bool *ownedByWindow) override; private Q_SLOTS: void slotToolboxActionTriggered(bool checked); //! Unchecks toolbox action for @a entity after it is used. void slotItemInserted(const QString& entity); private: class Private; Private* d; }; #endif // _KEXIREPORTPART_H_ diff --git a/src/plugins/reports/kexireportview.h b/src/plugins/reports/kexireportview.h index ee4e1b168..7da575562 100644 --- a/src/plugins/reports/kexireportview.h +++ b/src/plugins/reports/kexireportview.h @@ -1,91 +1,91 @@ /* * Kexi Report Plugin * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * Copyright (C) 2014-2018 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KEXIREPORTVIEW_H #define KEXIREPORTVIEW_H #include #include #include #include #include "kexireportpart.h" class KexiDBReportDataSource; class KReportPreRenderer; class ORODocument; class KReportView; //! @todo KEXI3 class KexiScriptAdaptor; class KRScriptFunctions; #ifndef KEXI_MOBILE class KexiRecordNavigator; #endif /** */ class KexiReportView : public KexiView, public KexiRecordNavigatorHandler { Q_OBJECT public: explicit KexiReportView(QWidget *parent); ~KexiReportView(); - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; - virtual void addNewRecordRequested(); - virtual void moveToFirstRecordRequested(); - virtual void moveToLastRecordRequested(); - virtual void moveToNextRecordRequested(); - virtual void moveToPreviousRecordRequested(); - virtual void moveToRecordRequested(int r); - virtual int currentRecord() const; - virtual int recordCount() const; + virtual void addNewRecordRequested() override; + virtual void moveToFirstRecordRequested() override; + virtual void moveToLastRecordRequested() override; + virtual void moveToNextRecordRequested() override; + virtual void moveToPreviousRecordRequested() override; + virtual void moveToRecordRequested(int r) override; + virtual int currentRecord() const override; + virtual int recordCount() const override; private: KReportPreRenderer *m_preRenderer; KReportView *m_reportView; #ifndef KEXI_MOBILE KexiRecordNavigator *m_pageSelector; #endif KexiReportPartTempData* tempData() const; KexiDBReportDataSource* createDataSource(const QDomElement &e); //! @todo KEXI3 KexiScriptAdaptor *m_kexi; KRScriptFunctions *m_functions; KReportRendererFactory m_factory; QUrl getExportUrl(const QString &mimetype, const QString &caption, const QString &lastExportPathOrVariable, const QString &extension); private Q_SLOTS: void slotPrintReport(); void slotExportAsPdf(); void slotExportAsWebPage(); #ifdef KEXI_SHOW_UNFINISHED void slotExportAsSpreadsheet(); void slotExportAsTextDocument(); #endif void openExportedDocument(const QUrl &destination); void finishedAllASyncItems(); }; #endif diff --git a/src/plugins/reports/krscriptfunctions.h b/src/plugins/reports/krscriptfunctions.h index f3af19b85..b7461d839 100644 --- a/src/plugins/reports/krscriptfunctions.h +++ b/src/plugins/reports/krscriptfunctions.h @@ -1,63 +1,63 @@ /* * Kexi Report Plugin * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) * Copyright (C) 2012-2018 Jarosław Staniek * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KRSCRIPTFUNCTIONS_H #define KRSCRIPTFUNCTIONS_H #include #include #include class KexiDBReportDataSource; class KDbConnection; class KDbCursor; /** */ class KRScriptFunctions : public KReportGroupTracker { Q_OBJECT public: KRScriptFunctions(KexiDBReportDataSource *dataSource); ~KRScriptFunctions(); private: KexiDBReportDataSource * const m_dataSource; QString m_source; //! @todo Move SQL aggregate functions to KDb qreal math(const QString &, const QString &); QMap m_groupData; public Q_SLOTS: - virtual void setGroupData(const QMap &groupData); + virtual void setGroupData(const QMap &groupData) override; qreal sum(const QString &); qreal avg(const QString &); qreal min(const QString &); qreal max(const QString &); qreal count(const QString &); QVariant value(const QString &); }; #endif diff --git a/src/plugins/tables/kexitabledesigner_dataview.h b/src/plugins/tables/kexitabledesigner_dataview.h index 4c8e29136..4783d312f 100644 --- a/src/plugins/tables/kexitabledesigner_dataview.h +++ b/src/plugins/tables/kexitabledesigner_dataview.h @@ -1,42 +1,42 @@ /* This file is part of the KDE project Copyright (C) 2004 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITABLEDESIGNERDATAVIEW_H #define KEXITABLEDESIGNERDATAVIEW_H #include #include "kexitablepart.h" class KexiTableDesigner_DataView : public KexiDataTableView { Q_OBJECT public: explicit KexiTableDesigner_DataView(QWidget *parent); virtual ~KexiTableDesigner_DataView(); KexiTablePartTempData* tempData() const; protected: - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; }; #endif diff --git a/src/plugins/tables/kexitabledesignercommands.h b/src/plugins/tables/kexitabledesignercommands.h index b14e91c8a..3f408c825 100644 --- a/src/plugins/tables/kexitabledesignercommands.h +++ b/src/plugins/tables/kexitabledesignercommands.h @@ -1,189 +1,189 @@ /* This file is part of the KDE project Copyright (C) 2006-2012 Jarosław Staniek 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 KEXITABLEDESIGNER_COMMANDS_H #define KEXITABLEDESIGNER_COMMANDS_H #include #include #include #include #include "kexitabledesignerview.h" class QPoint; class QByteArray; namespace KexiTableDesignerCommands { //! @short Base class for all Table Designer's commands class Command : public KUndo2Command { public: Command(const KUndo2MagicString &text, Command *parent, KexiTableDesignerView* view); Command(Command* parent, KexiTableDesignerView* view); virtual ~Command(); //! Used to collect actions data for AlterTableHandler //! Can return 0 if the action should not be passed to AlterTableHandler virtual KDbAlterTableHandler::ActionBase* createAction() const { return 0; } virtual QString debugString() const { return text().toString(); } - virtual void redo(); - virtual void undo(); + virtual void redo() override; + virtual void undo() override; //! Used to block execution of redo() once, on adding the command to the stack. void blockRedoOnce(); protected: virtual void redoInternal(); virtual void undoInternal(); QPointer m_view; bool m_blockRedoOnce; //!< Used to block redo() once friend class KexiTableDesignerView; }; //! @short Undo/redo command used for when changing a property for a table field class ChangeFieldPropertyCommand : public Command { public: /*! Creates the ChangeFieldPropertyCommand object. Note: we use internal "uid" property of a field (set["uid"]) to avoid problems with looking for field by name when more than one field exists with the same name (it's invalid but allowed in design time). \a oldlistData and \a newListData can be specified so Property::setListData() will be called on execute() and unexecute(). */ ChangeFieldPropertyCommand(Command* parent, KexiTableDesignerView* view, const KPropertySet& set, const QByteArray& propertyName, const QVariant& oldValue, const QVariant& newValue, KPropertyListData* const oldListData = 0, KPropertyListData* const newListData = 0); virtual ~ChangeFieldPropertyCommand(); - virtual void redoInternal(); - virtual void undoInternal(); - virtual KDbAlterTableHandler::ActionBase* createAction() const; - virtual QString debugString() const; + virtual void redoInternal() override; + virtual void undoInternal() override; + virtual KDbAlterTableHandler::ActionBase* createAction() const override; + virtual QString debugString() const override; protected: KDbAlterTableHandler::ChangeFieldPropertyAction m_alterTableAction; QVariant m_oldValue; KPropertyListData* m_oldListData, *m_listData; }; //! @short Undo/redo command used when a field is removed from a table class RemoveFieldCommand : public Command { public: /*! Constructs RemoveFieldCommand object. If \a set is 0, the action only means removing empty row (internal). */ RemoveFieldCommand(Command* parent, KexiTableDesignerView* view, int fieldIndex, const KPropertySet* set); virtual ~RemoveFieldCommand(); - virtual void redoInternal(); - virtual void undoInternal(); - virtual KDbAlterTableHandler::ActionBase* createAction() const; + virtual void redoInternal() override; + virtual void undoInternal() override; + virtual KDbAlterTableHandler::ActionBase* createAction() const override; - virtual QString debugString() const; + virtual QString debugString() const override; protected: KDbAlterTableHandler::RemoveFieldAction m_alterTableAction; KPropertySet* m_set; int m_fieldIndex; }; //! @short Undo/redo command used when a new field is inserted into a table class InsertFieldCommand : public Command { public: InsertFieldCommand(Command* parent, KexiTableDesignerView* view, int fieldIndex/*, const KDbField& field*/, const KPropertySet& set); virtual ~InsertFieldCommand(); - virtual void redoInternal(); - virtual void undoInternal(); - virtual KDbAlterTableHandler::ActionBase* createAction() const; + virtual void redoInternal() override; + virtual void undoInternal() override; + virtual KDbAlterTableHandler::ActionBase* createAction() const override; - virtual QString debugString() const; + virtual QString debugString() const override; protected: KDbAlterTableHandler::InsertFieldAction *m_alterTableAction; KPropertySet m_set; }; /* ---- Internal commands follow (not used for building performing ALTER TABLE ---- */ //! @short Undo/redo command used when property visibility is changed /*! Internal, only used in addition to property change. */ class ChangePropertyVisibilityCommand : public Command { public: /*! Creates the ChangePropertyVisibilityCommand object. Note: we use internal "uid" property of a field (set["uid"]) to avoid problems with looking for field by name when more than one field exists with the same name (it's invalid but allowed in design time). */ ChangePropertyVisibilityCommand(Command* parent, KexiTableDesignerView* view, const KPropertySet& set, const QByteArray& propertyName, bool visible); virtual ~ChangePropertyVisibilityCommand(); - virtual void redoInternal(); - virtual void undoInternal(); + virtual void redoInternal() override; + virtual void undoInternal() override; protected: KDbAlterTableHandler::ChangeFieldPropertyAction m_alterTableAction; bool m_oldVisibility; }; //! @short Undo/redo command used when property visibility is changed /*! Internal, only used in addition to property change. */ class InsertEmptyRecordCommand : public Command { public: /*! Creates the InsertEmptyRecordCommand object. */ InsertEmptyRecordCommand(Command* parent, KexiTableDesignerView* view, int row); virtual ~InsertEmptyRecordCommand(); - virtual void redoInternal(); - virtual void undoInternal(); + virtual void redoInternal() override; + virtual void undoInternal() override; protected: KDbAlterTableHandler::ChangeFieldPropertyAction m_alterTableAction; int m_row; }; } #endif diff --git a/src/plugins/tables/kexitabledesignerview.h b/src/plugins/tables/kexitabledesignerview.h index 68f522574..14f0b4798 100644 --- a/src/plugins/tables/kexitabledesignerview.h +++ b/src/plugins/tables/kexitabledesignerview.h @@ -1,252 +1,252 @@ /* This file is part of the KDE project Copyright (C) 2004-2017 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITABLEDESIGNERINTERVIEW_H #define KEXITABLEDESIGNERINTERVIEW_H #include #include #include #include #include "kexitablepart.h" class KDbRecordData; class KPropertySet; class KUndo2Command; class KexiTableDesignerViewPrivate; namespace KexiTableDesignerCommands { class Command; } //! Design view of the Table Designer /*! Contains a spreadsheet-like space for entering field definitions. Property editor is provided for altering field definitions. The view also supports Undo and Redo operations. These are connected to a factility creating a list of actions used by AlterTableHandler to perform required operation of altering the table. Altering itself is performed upon design saving (storeData()). Saving unstored designs just creates a new table. Saving changes made to empty (not filled with data) table is performed by physically deleting the previous table schema and recreating it TODO: this will be not quite when we have db relationships supported. Saving changes made to table containing data requires use of the AlterTableHandler functionality. */ class KexiTableDesignerView : public KexiDataTableView, public KexiTableDesignerInterface { Q_OBJECT public: /*! Creates a new alter table dialog. */ explicit KexiTableDesignerView(QWidget *parent); virtual ~KexiTableDesignerView(); KexiTablePartTempData* tempData() const; /*! Clears field information entered for record. This is performed by removing values from caption and data type columns. Used by InsertFieldCommand to undo inserting a new field. */ - virtual void clearRecord(int record, bool addCommand = false); + virtual void clearRecord(int record, bool addCommand = false) override; /*! Inserts a new field with \a caption for \a record. Property set is also created. */ - virtual void insertField(int record, const QString& caption, bool addCommand = false); + virtual void insertField(int record, const QString& caption, bool addCommand = false) override; /*! Inserts a new \a field for \a record. Property set is also created. \a set will be deeply-copied into the new set. Used by InsertFieldCommand to insert a new field. */ - virtual void insertField(int record, KPropertySet& set, bool addCommand = false); + virtual void insertField(int record, KPropertySet& set, bool addCommand = false) override; /*! Inserts a new empty record at position \a record. Used by RemoveFieldCommand as a part of undo inserting a new field; also used by InsertEmptyRecordCommand. */ - virtual void insertEmptyRecord(int record, bool addCommand = false); + virtual void insertEmptyRecord(int record, bool addCommand = false) override; /*! Deletes \a record from the table view. Property set is also deleted. All the subsequent fields are moved up. Used for undoing InsertEmptyRecordCommand and by RemoveFieldCommand to remove a field. */ - virtual void deleteRecord(int record, bool addCommand = false); + virtual void deleteRecord(int record, bool addCommand = false) override; /*! Changes property \a propertyName to \a newValue for a field at record \a record. If \a listData is not NULL and not empty, a deep copy of it is passed to Property::setListData(). If \a listData \a nlist if not NULL but empty, Property::setListData(0) is called. */ virtual void changeFieldPropertyForRecord(int record, const QByteArray& propertyName, const QVariant& newValue, - const KPropertyListData* listData, bool addCommand); + const KPropertyListData* listData, bool addCommand) override; /*! Changes property \a propertyName to \a newValue. Works exactly like changeFieldPropertyForRecord(); except the field is pointed by \a fieldUID. Used by ChangeFieldPropertyCommand to change field's property. */ void changeFieldProperty(int fieldUID, const QByteArray& propertyName, const QVariant& newValue, const KPropertyListData* listData = nullptr, bool addCommand = false); /*! Changes visibility of property \a propertyName to \a visible for a field pointed by \a fieldUID. Used by ChangePropertyVisibilityCommand. */ void changePropertyVisibility(int fieldUID, const QByteArray& propertyName, bool visible); /*! Builds table field's schema by looking at the \a set. */ KDbField * buildField(const KPropertySet &set) const; /*! Creates temporary table for the current design and returns debug string for it. */ - virtual QString debugStringForCurrentTableSchema(tristate& result); + virtual QString debugStringForCurrentTableSchema(tristate& result) override; /*! Simulates execution of alter table, and puts debug into \a debugTarget. A case when debugTarget is not 0 is true for the alter table test suite. */ - virtual tristate simulateAlterTableExecution(QString *debugTarget); + virtual tristate simulateAlterTableExecution(QString *debugTarget) override; public Q_SLOTS: /*! Real execution of the Alter Table. For debugging of the real alter table. \return true on success, false on failure and cancelled if user has cancelled execution. */ - virtual tristate executeRealAlterTable(); + virtual tristate executeRealAlterTable() override; protected Q_SLOTS: /*! Equivalent to updateActions(false). Called on record insert/delete in a KexiDataAwarePropertySet. */ void updateActions(); virtual void slotUpdateRecordActions(int record); void slotAboutToShowContextMenu(); //! Called before cell change in tableview. void slotBeforeCellChanged(KDbRecordData *data, int colnum, QVariant* newValue, KDbResultInfo* result); //! Called on record change in a tableview. void slotRecordUpdated(KDbRecordData *data); //! Called before record inserting in tableview. void slotRecordInserted(); //! Called before record deleting in tableview. void slotAboutToDeleteRecord(KDbRecordData* data, KDbResultInfo* result, bool repaint); /*! Called after any property has been changed in the current property set, to perform some actions (like updating other dependent properties) */ void slotPropertyChanged(KPropertySet& set, KProperty& property); /*! Toggles primary key for currently selected field. Does nothing for empty record. */ void slotTogglePrimaryKey(); /*! Undoes the recently performed action. */ void slotUndo(); /*! Redoes the recently undoed action. */ void slotRedo(); /*! Simulates real execution of the Alter Table. For debugging. */ void slotSimulateAlterTableExecution(); protected: - virtual void updateActions(bool activated); + virtual void updateActions(bool activated) override; //! called whenever data should be reloaded (on switching to this view mode) void initData(); /*! Creates a new property set for \a field. The property set will be asigned to \a record, and owned by this dialog. If \a newOne is true, the property set will be marked as newly created. \return newly created property set. */ KPropertySet* createPropertySet(int record, const KDbField& field, bool newOne = false); - virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore); + virtual tristate beforeSwitchTo(Kexi::ViewMode mode, bool *dontStore) override; - virtual tristate afterSwitchFrom(Kexi::ViewMode mode); + virtual tristate afterSwitchFrom(Kexi::ViewMode mode) override; /*! \return property set associated with currently selected record (i.e. field) or 0 if current record is empty. */ - virtual KPropertySet *propertySet(); + virtual KPropertySet *propertySet() override; /*! Reimplemented from KexiView, because tables creation is more complex. No table schema altering is required, so just buildSchema() is used to create a new schema. */ virtual KDbObject* storeNewData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); + bool *cancel) override; /*! Reimplemented from KexiView, because cloning of table objects is more complex. */ virtual KDbObject* copyData(const KDbObject& object, KexiView::StoreNewDataOptions options, - bool *cancel); + bool *cancel) override; /*! Reimplemented from KexiView, because table storage is more complex. Table schema altering may be required, so just buildSchema() is used to create a new schema. */ - virtual tristate storeData(bool dontAsk = false); + virtual tristate storeData(bool dontAsk = false) override; /*! Builds table schema by looking at the current design. Used in storeNewData() and storeData(). If \a beSilent is true, no message boxes are used to show questions or warnings. This is used in the altertable test suite (kexi/tests/altertable). \return true on successful schema creating, false on failure and cancelled when there was a problem with user's design (and user has been informed about it). */ tristate buildSchema(KDbTableSchema &schema, bool beSilent = false); /*! Builds action list usable for KDbAlterTableHandler by looking at undo buffer of commands' history. Used in storeData() */ tristate buildAlterTableActions(KDbAlterTableHandler::ActionList &actions); /*! Helper, used for slotTogglePrimaryKey() and slotPropertyChanged(). Assigns primary key icon and value for property set \a propertySet, and deselects it from previous pkey's record. \a aWasPKey is internal. If \a commandGroup is not 0, it is used as parent group for storing actions' history. */ void switchPrimaryKey(KPropertySet &propertySet, bool set, bool aWasPKey = false, KexiTableDesignerCommands::Command* commandGroup = 0); /*! Adds history command \a command to the undo/redo buffer. If \a execute is true, the command is executed afterwards. */ void addHistoryCommand(KexiTableDesignerCommands::Command* command, bool execute); //! Updates undo/redo shared actions availability by looking at command history's action void updateUndoRedoActions(); #ifdef KEXI_DEBUG_GUI void debugCommand(const KUndo2Command* command, int nestingLevel); #endif /*! Inserts a new \a field for \a record. Property set is also created. If \a set is not 0 (the default), it will be copied into the new set. Used by insertField(). */ void insertFieldInternal(int record, KPropertySet* set, const QString& caption, bool addCommand); //! Reimplemented to pass the information also to the "Lookup" tab - virtual void propertySetSwitched(); + virtual void propertySetSwitched() override; /*! \return true if physical altering is needed for the current list of actions. Used in KexiTableDesignerView::beforeSwitchTo() to avoid warning about removinf table data if table recreating is not needed. True is also returned if there is any trouble with getting the answer. */ bool isPhysicalAlteringNeeded(); private: KexiTableDesignerViewPrivate * const d; }; #endif diff --git a/src/plugins/tables/kexitablepart.h b/src/plugins/tables/kexitablepart.h index 267db835d..6096b45b7 100644 --- a/src/plugins/tables/kexitablepart.h +++ b/src/plugins/tables/kexitablepart.h @@ -1,147 +1,147 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2002, 2003 Joseph Wenninger Copyright (C) 2004-2017 Jarosław Staniek 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 KEXITABLEPART_H #define KEXITABLEPART_H #include #include #include #include #include #include class KexiLookupColumnPage; //! @short Temporary data kept in memory while switching between Table Window's views class KexiTablePartTempData : public KexiWindowData, public KDbTableSchemaChangeListener { Q_OBJECT public: KexiTablePartTempData(KexiWindow* parent, KDbConnection *conn); ~KexiTablePartTempData(); //! Table used for this data KDbTableSchema* table(); //! Sets table used for this data //! If the previous table differs from @a table and is not @c nullptr, listener for //! it will be unregistered. //! If @a table is not @c nullptr, this temp-data object will be registered as a listener //! for it. void setTable(KDbTableSchema *table); //! Connection used for retrieving definition of the query KDbConnection* connection(); /*! true, if \a table member has changed in previous view. Used on view switching. We're checking this flag to see if we should refresh data for DataViewMode. */ bool tableSchemaChangedInPreviousView; //! @c true indicates that closeListener() should close the table designer window. //! This is disabled in one case: upon saving of the design of this table. //! @see KexiTableDesignerView::storeData() bool closeWindowOnCloseListener = true; protected: //! Closes listener - this temp-data acts as a listener for tracking changes in table schema //! that is displayed in the window's data view. //! It just calls KexiDataTableView::setData(nullptr) is there's data set for the view //! (i.e. if KexiDataTableView::tableView()->data() is not @c nullptr). tristate closeListener() override; private: void closeDataInDataView(); Q_DISABLE_COPY(KexiTablePartTempData) class Private; Private * const d; }; //! @short Kexi Table Designer plugin class KexiTablePart : public KexiPart::Part { Q_OBJECT public: KexiTablePart(QObject *parent, const QVariantList &); virtual ~KexiTablePart(); - virtual tristate remove(KexiPart::Item *item); + virtual tristate remove(KexiPart::Item *item) override; - virtual tristate rename(KexiPart::Item *item, const QString& newName); + virtual tristate rename(KexiPart::Item *item, const QString& newName) override; /** * Closes objects that listenen to changes of the table schema @a table, i.e. use it. * * These objects can be currently: * - lookup fields of other tables * - queries using the table directly or via lookup fields * - forms and reports that use the table directly as data source or via query. * * Scripts referencing the table programatically are not analyzed, so they can fail on next * execution. * * This method asks the user for approval if there is at least one object that listens for * changes of the schema (altering, renaming or removal). If there is no approval, returns * @c cancelled. On failure @c false is returned. If @a window is @c nullptr, @c true is * returned immediately because there is no window to care about. * * Special case: listener for the table @a table will be silently closed without asking for * confirmation. It is ignored when looking for objects that are "blocking" changes * of @a table. This exception is needed because the listener handles the data view's lifetime * and the data view should be reset silently without bothering the user. * * @see KexiTablePartTempData::closeListener() * @see KexiQueryPart::askForClosingObjectsUsingQuerySchema() */ static tristate askForClosingObjectsUsingTableSchema(KexiWindow *window, KDbConnection *conn, KDbTableSchema *table, const KLocalizedString &msg); virtual KLocalizedString i18nMessage(const QString& englishMessage, - KexiWindow* window) const; + KexiWindow* window) const override; KexiLookupColumnPage* lookupColumnPage() const; protected: KexiWindowData* createWindowData(KexiWindow* window) override Q_REQUIRED_RESULT; KexiView *createView(QWidget *parent, KexiWindow *window, KexiPart::Item *item, Kexi::ViewMode viewMode = Kexi::DataViewMode, QMap *staticObjectArgs = nullptr) override Q_REQUIRED_RESULT; - virtual void initPartActions(); - virtual void initInstanceActions(); + virtual void initPartActions() override; + virtual void initInstanceActions() override; - virtual void setupCustomPropertyPanelTabs(QTabWidget *tab); + virtual void setupCustomPropertyPanelTabs(QTabWidget *tab) override; virtual KDbObject* loadSchemaObject(KexiWindow *window, const KDbObject& object, - Kexi::ViewMode viewMode, bool *ownedByWindow); + Kexi::ViewMode viewMode, bool *ownedByWindow) override; private: class Private; Private* const d; }; #endif diff --git a/src/widget/KexiConnectionSelectorWidget.h b/src/widget/KexiConnectionSelectorWidget.h index 0647894e8..a578747ae 100644 --- a/src/widget/KexiConnectionSelectorWidget.h +++ b/src/widget/KexiConnectionSelectorWidget.h @@ -1,176 +1,176 @@ /* This file is part of the KDE project Copyright (C) 2003-2017 Jarosław Staniek Copyright (C) 2012 Dimitrios T. Tanis This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICONNECTIONSELECTORWIDGET_H #define KEXICONNECTIONSELECTORWIDGET_H #include #include #include "kexiextwidgets_export.h" #include class QAbstractButton; class KDbDriverMetaData; //! An item for a single database connection class KEXIEXTWIDGETS_EXPORT ConnectionDataLVItem : public QTreeWidgetItem { public: ConnectionDataLVItem(KDbConnectionData *data, const KDbDriverMetaData &driverMetaData, QTreeWidget* list); ~ConnectionDataLVItem(); void update(const KDbDriverMetaData& driverMetaData); using QTreeWidgetItem::data; KDbConnectionData *data() const { return m_data; } protected: KDbConnectionData *m_data; }; //! @short Widget that allows to select a database connection (file- or server-based) /*! The widget allows to select database connection without choosing database itself. */ class KEXIEXTWIDGETS_EXPORT KexiConnectionSelectorWidget : public QWidget { Q_OBJECT public: //! Defines connection type enum ConnectionType { FileBased = 1, //!< the widget displays file-based connection ServerBased = 2 //!< the widget displays server-based connection }; //! Defines operation mode enum OperationMode { Opening = 1, Saving = 2 }; /*! Constructs a new widget which contains \a conn_set as connection set. \a conn_set can be altered, because Add/Edit/Remove buttons are available to users. \a startDirOrVariable can be provided to specify a start dir for file browser (it can also contain a configuration variable name with "kfiledialog:///" prefix as described in KRecentDirs documentation). */ //! @todo KEXI3 add equivalent of kfiledialog:/// for startDirOrVariable KexiConnectionSelectorWidget(KexiDBConnectionSet *conn_set, const QUrl& startDirOrVariable, OperationMode mode, QWidget* parent = 0); virtual ~KexiConnectionSelectorWidget(); /*! After accepting this dialog this method returns wherher user selected file- or server-based connection. */ ConnectionType selectedConnectionType() const; /*! \return data of selected connection, if server-based connection was selected. Returns NULL if no selection has been made or file-based connection has been selected. @see selectedConnectionType() */ KDbConnectionData* selectedConnectionData() const; /*! \return the name of database file, if file-based connection was selected. Returns empty string if no selection has been made or server-based connection has been selected. //! @note Call checkSelectedFile() first @see selectedConnectionType() */ QString selectedFile() const; QTreeWidget* connectionsList() const; bool confirmOverwrites() const; bool hasSelectedConnection() const; /*! @return true if the current file URL meets requied constraints (i.e. the file exists) Shows appropriate message box if needed. */ bool checkSelectedFile(); //! @return highlighted file QString highlightedFile() const; Q_SIGNALS: void connectionItemExecuted(ConnectionDataLVItem *item); void connectionItemHighlighted(ConnectionDataLVItem *item); void connectionSelected(bool hasSelected); void fileSelected(const QString &name); public Q_SLOTS: void showSimpleConnection(); void showAdvancedConnection(); virtual void setFocus(); /*! Hides helpers on the server based connection page (sometimes it's convenient not to have these): - "Select existing database server's connection..." (label at the top) - "Click "Back" button" (label at the bottom) - "Back" button itself */ void hideHelpers(); void hideConnectonIcon(); void hideDescription(); /*! Sets selected filename to @a name. Only works when selectedConnectionType()==FileBased. */ void setSelectedFile(const QString &name); /*! If true, user will be asked to accept overwriting existing project. This is true by default. */ void setConfirmOverwrites(bool set); void setFileMode(KexiFileFilters::Mode mode); void setAdditionalMimeTypes(const QStringList &mimeTypes); //! Sets excluded mime types void setExcludedMimeTypes(const QStringList& mimeTypes); void setFileWidgetFrameVisible(bool set); protected Q_SLOTS: void slotConnectionItemExecuted(QTreeWidgetItem *item); void slotConnectionItemExecuted(); void slotRemoteAddBtnClicked(); void slotRemoteEditBtnClicked(); void slotRemoteRemoveBtnClicked(); void slotConnectionSelectionChanged(); void slotPrjTypeSelected(QAbstractButton *btn); void slotFileConnectionSelected(const QString &name); void slotConnectionSelected(); protected: - virtual bool eventFilter(QObject* watched, QEvent* event); + virtual bool eventFilter(QObject* watched, QEvent* event) override; private: ConnectionDataLVItem* addConnectionData(KDbConnectionData* data); ConnectionDataLVItem* selectedConnectionDataItem() const; class Private; Private * const d; }; #endif // KEXICONNECTIONSELECTORWIDGET_H diff --git a/src/widget/KexiDataSourceComboBox.h b/src/widget/KexiDataSourceComboBox.h index 90de02c70..b4d8af3e4 100644 --- a/src/widget/KexiDataSourceComboBox.h +++ b/src/widget/KexiDataSourceComboBox.h @@ -1,91 +1,91 @@ /* This file is part of the KDE project Copyright (C) 2005-2016 Jarosław Staniek 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 KEXIDATASOURCECOMBOBOX_H #define KEXIDATASOURCECOMBOBOX_H #include "kexiextwidgets_export.h" #include class KexiProject; namespace KexiPart { class Item; } /** * A combo box listing availabe data sources (tables and queries) * with icons. "Define query..." item can be also prepended. */ class KEXIEXTWIDGETS_EXPORT KexiDataSourceComboBox : public KComboBox { Q_OBJECT public: explicit KexiDataSourceComboBox(QWidget *parent = 0); virtual ~KexiDataSourceComboBox(); //! \return global project that is used to retrieve schema informationm for this combo box. KexiProject* project() const; //! \return name plugin ID of selected item (usually a table or a query). Can return an empty string. //! You should use isSelectionValid() to check validity of the input. QString selectedPluginId() const; //! \return name of selected table or query. Can return an empty string or nonexisting name, //! so you should use isSelectionValid() to check validity of the input. QString selectedName() const; //! \return true if current selection is valid bool isSelectionValid() const; /*! \return index of item identified by a plugin ID \a pluginId and name \a name. Returs -1 of no such item exists. */ int findItem(const QString& pluginId, const QString& name); public Q_SLOTS: //! Sets global project that is used to retrieve schema informationm for this combo box. //! Tables visibility can be set using \a showTables queries visibility using \a showQueries. void setProject(KexiProject *prj, bool showTables = true, bool showQueries = true); /*! Sets item for data source described by \a pluginId and \a name. If \a pluginId is empty, either "org.kexi-project.table" and "org.kexi-project.query" are tried. */ void setDataSource(const QString& pluginId, const QString& name); Q_SIGNALS: //! Emitted whenever data source changes. //! Even setting invalid data source or clearing it will emit this signal. void dataSourceChanged(); protected Q_SLOTS: void slotNewItemStored(KexiPart::Item* item); void slotItemRemoved(const KexiPart::Item& item); void slotItemRenamed(const KexiPart::Item& item, const QString& oldName); void slotActivated(int index); void slotReturnPressed(const QString & text); void slotTextChanged(const QString &text); protected: - virtual void focusOutEvent(QFocusEvent *e); + virtual void focusOutEvent(QFocusEvent *e) override; class Private; Private * const d; }; #endif diff --git a/src/widget/KexiFileWidget.h b/src/widget/KexiFileWidget.h index 5eb1bb6af..84f41ea2a 100644 --- a/src/widget/KexiFileWidget.h +++ b/src/widget/KexiFileWidget.h @@ -1,117 +1,117 @@ /* This file is part of the KDE project Copyright (C) 2003-2018 Jarosław Staniek 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 KEXIFILEWIDGET_H #define KEXIFILEWIDGET_H #include #ifdef KEXI_USE_KFILEWIDGET #include "KexiFileWidgetInterface.h" #include //! @short Widget for opening/saving files supported by Kexi /*! For simplicity, initially the widget has hidden the preview pane. */ class KEXIEXTWIDGETS_EXPORT KexiFileWidget : public KFileWidget, public KexiFileWidgetInterface { Q_OBJECT public: //! @todo KEXI3 add equivalent of kfiledialog:/// for startDirOrVariable KexiFileWidget(const QUrl &startDirOrVariable, KexiFileFilters::Mode mode, const QString &fileName, QWidget *parent = nullptr); KexiFileWidget(const QUrl &startDirOrVariable, KexiFileFilters::Mode mode, QWidget *parent = nullptr); ~KexiFileWidget() override; using KFileWidget::setMode; /** * Returns the full path of the selected file in the local filesystem. * (Local files only) */ QString selectedFile() const override; /** * Returns the full path of the highlighted file in the local filesystem. * (Local files only) */ QString highlightedFile() const override; /** * @return the currently shown directory. */ QString currentDir() const override; public Q_SLOTS: void setMode(KexiFileFilters::Mode mode); //! Just sets locationWidget()->setCurrentText(text) //void setLocationText(const QString& text) override; /** * Sets the file name to preselect to @p name * * This takes absolute URLs and relative file names. */ void setSelectedFile(const QString &name) override; //! Typing a file that doesn't exist closes the file dialog, we have to //! handle this case better here. virtual void accept(); /** * Sets whether the line edit draws itself with a frame. */ void setWidgetFrame(bool set) override; Q_SIGNALS: void fileHighlighted(const QString &name); void fileSelected(const QString &name); void rejected(); protected Q_SLOTS: virtual void reject(); void slotFileHighlighted(const QUrl& url); void slotFileSelected(const QUrl& url); protected: - virtual void showEvent(QShowEvent *event); + virtual void showEvent(QShowEvent *event) override; - virtual void focusInEvent(QFocusEvent *event); + virtual void focusInEvent(QFocusEvent *event) override; /** * Updates filters in the widget based on current filter selection. */ void updateFilters() override; void applyEnteredFileName() override; QStringList currentFilters() const override; private: class Private; Private * const d; }; #endif // KEXI_USE_KFILEWIDGET #endif // KEXIFILEWIDGET_H diff --git a/src/widget/KexiNameDialog.h b/src/widget/KexiNameDialog.h index 59713be25..0eec6e5be 100644 --- a/src/widget/KexiNameDialog.h +++ b/src/widget/KexiNameDialog.h @@ -1,103 +1,103 @@ /* This file is part of the KDE project Copyright (C) 2004-2012 Jarosław Staniek 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 KEXINAMEDIALOG_H #define KEXINAMEDIALOG_H #include "kexiextwidgets_export.h" #include #include #include class QDialogButtonBox; class KexiNameWidget; class KexiNameDialog; //! Validator that can be used to check validity of data entered into KexiNameDialog class KEXIEXTWIDGETS_EXPORT KexiNameDialogValidator { public: KexiNameDialogValidator(); virtual ~KexiNameDialogValidator(); //! For implementation. Validates data entered into dialog @a dialog. //! @return true if the data if valid. virtual bool validate(KexiNameDialog *dialog) const = 0; }; //! A dialog displaying object's name and caption and allowing editing. //! @see KexiNameWidget class KEXIEXTWIDGETS_EXPORT KexiNameDialog : public QDialog { Q_OBJECT public: explicit KexiNameDialog(const QString& message, QWidget * parent = 0); KexiNameDialog(const QString& message, const QString& nameLabel, const QString& nameText, const QString& captionLabel, const QString& captionText, QWidget * parent = 0); virtual ~KexiNameDialog(); KexiNameWidget* widget() const; QDialogButtonBox* buttonBox(); void setDialogIcon(const QString &iconName); /*! Shows the dialog as a modal dialog, blocking until the user closes it, like QDialog::exec() but uses @a project and @a part to check if object of given type and name already exists. If so, warning or question is displayed. You can check @a overwriteNeeded after calling this method. If it's true, user agreed on overwriting, if it's false, user picked nonexisting name, so no overwrite will be needed. */ int execAndCheckIfObjectExists(const KexiProject &project, const KexiPart::Part &part, bool *overwriteNeeded); //! If set to true, the dialog will ask for overwriting the existing object if needed. //! If set to false, the dialog will inform about existing object and reject renaming. //! False by default. void setAllowOverwriting(bool set); //! Sets validator that will be used to check validity of data entered into this KexiNameDialog. //! Validation occurs before any other checks. //! Passes ownership of @a validator to this name dialog. //! Previous validator is removed. 0 an be passed. void setValidator(KexiNameDialogValidator *validator); protected Q_SLOTS: void slotTextChanged(); - virtual void accept(); + virtual void accept() override; void updateSize(); protected: void init(); - virtual void showEvent(QShowEvent * event); + virtual void showEvent(QShowEvent * event) override; //! Checks if specified name already exists. bool canOverwrite(); private: class Private; Private * const d; }; #endif diff --git a/src/widget/KexiProjectSelectorWidget.h b/src/widget/KexiProjectSelectorWidget.h index ea9065ca1..657b1a7bf 100644 --- a/src/widget/KexiProjectSelectorWidget.h +++ b/src/widget/KexiProjectSelectorWidget.h @@ -1,127 +1,127 @@ /* This file is part of the KDE project Copyright (C) 2003-2011 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIPROJECTSELECTORWIDGET_H #define KEXIPROJECTSELECTORWIDGET_H #include "kexiextwidgets_export.h" #include "ui_KexiProjectSelector.h" #include "kexiprojectset.h" #include #include /*! Widget that allows to select a kexi project (or database) */ class KEXIEXTWIDGETS_EXPORT KexiProjectSelectorWidget : public QWidget, private Ui_KexiProjectSelector { Q_OBJECT public: /*! Constructs a project selector widget. If \a showProjectNameColumn is true (the default) project names' column is visible. If \a showConnectionColumns is true (the default) information about database driver and connection columns are added. \a prj_set may be NULL - you can assign a set later with setProjectSet(). */ explicit KexiProjectSelectorWidget(QWidget* parent = 0, KexiProjectSet* prj_set = 0, bool showProjectNameColumn = true, bool showConnectionColumns = true); virtual ~KexiProjectSelectorWidget(); /*! \return data of selected project. Returns NULL if no selection has been made. */ KexiProjectData* selectedProjectData() const; /*! Assigns a new project set \a prj_set. Old project set is not destoyed - it is just left unassigned. If new project set is in error state (Object::error() == true), nothing is displayed. */ void setProjectSet(KexiProjectSet* prj_set); /*! \return currently assigned project set or NULL if no project set is assigned. */ KexiProjectSet *projectSet(); /*! Sets selectable state on or off. In this state one project item can be selected and executed by mouse double clicking or return key pressing. The property is true by default. */ void setSelectable(bool set); /*! \return if a witget has selectable state set. */ bool isSelectable() const; QLabel *label() const; QTreeWidget* list() const; Q_SIGNALS: void projectExecuted(KexiProjectData*); void selectionChanged(KexiProjectData*); protected Q_SLOTS: void slotItemExecuted(QTreeWidgetItem*); void slotItemExecuted(); void slotItemSelected(); protected: - virtual bool eventFilter(QObject* watched, QEvent* event); + virtual bool eventFilter(QObject* watched, QEvent* event) override; class Private; Private * const d; friend class ProjectDataLVItem; }; /*! Dialog container for KexiProjectSelectorWidget */ class KEXIEXTWIDGETS_EXPORT KexiProjectSelectorDialog : public KPageDialog { Q_OBJECT public: /*! Displays projects list for given connection Label "Select one of these existing projects on server" is displayed automatically You should test if project set was properly loaded using projectSet()->error(). */ KexiProjectSelectorDialog(QWidget *parent, const KDbConnectionData& cdata, bool showProjectNameColumn = true, bool showConnectionColumns = true); virtual ~KexiProjectSelectorDialog(); /*! \return data of selected project. Returns NULL if no selection has been made. */ KexiProjectData* selectedProjectData() const; /*! \return currently assigned project set or NULL if no project set is assigned. */ KexiProjectSet *projectSet() const; - virtual void showEvent(QShowEvent * event); + virtual void showEvent(QShowEvent * event) override; protected Q_SLOTS: void slotProjectExecuted(KexiProjectData*); void slotProjectSelectionChanged(KexiProjectData*); protected: void init(KexiProjectSet* prj_set, bool showProjectNameColumn, bool showConnectionColumns); class Private; Private * const d; }; #endif diff --git a/src/widget/dataviewcommon/kexidataawareobjectiface.h b/src/widget/dataviewcommon/kexidataawareobjectiface.h index e7a681965..9a058d311 100644 --- a/src/widget/dataviewcommon/kexidataawareobjectiface.h +++ b/src/widget/dataviewcommon/kexidataawareobjectiface.h @@ -1,1040 +1,1040 @@ /* This file is part of the KDE project Copyright (C) 2005-2015 Jarosław Staniek Based on KexiTableView code. Copyright (C) 2002 Till Busch Copyright (C) 2003 Lucijan Busch Copyright (C) 2003 Daniel Molkentin Copyright (C) 2003 Joseph Wenninger This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDATAAWAREOBJECTINTERFACE_H #define KEXIDATAAWAREOBJECTINTERFACE_H #include "kexidataviewcommon_export.h" #include #include #include #include #include #include #include #include class QHeaderView; class QScrollBar; class QMenu; class KDbRecordData; class KDbTableViewData; class KexiRecordNavigatorIface; //! default column width in pixels #define KEXI_DEFAULT_DATA_COLUMN_WIDTH 120 //! \brief The KexiDataAwareObjectInterface is an interface for record-based data object. /** This interface is implemented by KexiTableScrollArea and KexiFormView and used by KexiDataAwareView. If yu're implementing this interface, add KEXI_DATAAWAREOBJECTINTERFACE convenience macro just after Q_OBJECT. You should add following code to your destructor so data is deleted: \code if (m_owner) delete m_data; m_data = 0; \endcode This is not performed in KexiDataAwareObjectInterface because you may need to access m_data in your desctructor. */ class KEXIDATAVIEWCOMMON_EXPORT KexiDataAwareObjectInterface { public: KexiDataAwareObjectInterface(); virtual ~KexiDataAwareObjectInterface(); /*! Sets data for this object. if \a owner is true, the object will own \a data and therefore will be destroyed when needed, else: \a data is (possibly) shared and not owned by the widget. If widget already has _different_ data object assigned (and owns this data), old data is destroyed before new assignment. */ void setData(KDbTableViewData *data, bool owner = true); /*! \return data structure displayed for this object */ inline KDbTableViewData *data() const { return m_data; } /*! \return currently selected column number or -1. */ inline int currentColumn() const { return m_curColumn; } /*! \return number of the currently selected record number or -1. */ inline int currentRecord() const { return m_curRecord; } /*! \return last record visible on the screen (counting from 0). The returned value is guaranteed to be smaller or equal to currentRecord() or -1 if there are no records. */ virtual int lastVisibleRecord() const = 0; /*! \return currently selected record data or null. */ KDbRecordData *selectedRecord() const { return m_currentRecord; } /*! \return number of records in this view. */ int recordCount() const; /*! \return number of visible columns in this view. By default returns dataColumns(), what is proper table view. In case of form view, there can be a number of duplicated columns defined (data-aware widgets, see KexiFormScrollView::columnCount()), so columnCount() can return greater number than dataColumns(). */ virtual int columnCount() const; /*! Helper function. \return number of columns of data. */ int dataColumns() const; /*! \return true if data represented by this object is not editable (it can be editable with other ways although, outside of this object). */ virtual bool isReadOnly() const; /*! Sets readOnly flag for this object. Unless the flag is set, the widget inherits readOnly flag from it's data structure assigned with setData(). The default value if false. This method is useful when you need to switch on the flag indepentently from the data structure. Note: it is not allowed to force readOnly off when internal data is readOnly - in that case the method does nothing. You can check internal data flag calling data()->isReadOnly(). If \a set is true, insertingEnabled flag will be cleared automatically. \sa isInsertingEnabled() */ void setReadOnly(bool set); /*! \return true if sorting is enabled. */ inline bool isSortingEnabled() const { return m_isSortingEnabled; } /*! Sets sorting order on column @a column to @a order. This method do not work if sorting is disabled using setSortingEnabled(false). @a column may be -1, what means "no sorting". */ virtual void setSorting(int column, KDbOrderByColumn::SortOrder order = KDbOrderByColumn::SortOrder::Ascending); /*! Enables or disables sorting for this object This method is different that setSorting() because it prevents both user and programmer from sorting by clicking a column's header or calling setSorting(). By default sorting is enabled. */ virtual void setSortingEnabled(bool set); /*! \return sorted column number or -1 if no column is sorted within data or there is no data assigned at all. This does not mean that any sorting has been performed within GUI of this object, because the data could be changed in the meantime outside of this GUI object. */ int dataSortColumn() const; /*! \return sort order for data. This information does not mean that any sorting has been performed within GUI of this object, because the data could be changed in the meantime outside of this GUI object. dataSortColumn() should be checked first to see if sorting is enabled (and if there's data). */ KDbOrderByColumn::SortOrder dataSortOrder() const; /*! Sorts all records by column selected with setSorting(). If there is currently record edited, it is accepted. If acception failed, sort() will return false. \return true on success. */ virtual bool sort(); /*! Sorts currently selected column in ascending order. This slot is used typically for "data_sort_az" action. */ void sortAscending(); /*! Sorts currently selected column in descending order. This slot is used typically for "data_sort_za" action. */ void sortDescending(); /*! \return true if data inserting is enabled (the default). */ virtual bool isInsertingEnabled() const; /*! Sets insertingEnabled flag. If true, empty record is available at the end of this widget for new entering new data. Unless the flag is set, the widget inherits insertingEnabled flag from it's data structure assigned with setData(). The default value if false. Note: it is not allowed to force insertingEnabled on when internal data has insertingEnabled set off - in that case the method does nothing. You can check internal data flag calling data()->insertingEnabled(). Setting this flag to true will have no effect if read-only flag is true. \sa setReadOnly() */ void setInsertingEnabled(bool set); /*! \return true if record deleting is enabled. Equal to deletionPolicy() != NoDelete && !isReadOnly()). */ bool isDeleteEnabled() const; /*! \return true if inserting empty records is enabled (false by default). Mostly usable for not db-aware objects (e.g. used in Kexi Alter Table). Note, that if inserting is disabled, or the data set is read-only, this flag will be ignored. */ bool isEmptyRecordInsertingEnabled() const { return m_emptyRecordInsertingEnabled; } /*! Sets the emptyRecordInsertingEnabled flag. Note, that if inserting is disabled, this flag is ignored. */ void setEmptyRecordInsertingEnabled(bool set); /*! Enables or disables filtering. Filtering is enabled by default. */ virtual void setFilteringEnabled(bool set); /*! \return true if filtering is enabled. */ inline bool isFilteringEnabled() const { return m_isFilteringEnabled; } /*! Added for convenience: if @a set is true, this object will behave more like a spreadsheet (it's used for things like table designer view): - hides navigator - disables sorting, inserting and filtering - enables accepting record after cell accepting; see setAcceptsRecordEditAfterCellAccepting() - enables inserting empty record; see setEmptyRecordInsertingEnabled() */ virtual void setSpreadSheetMode(bool set); /*! \return true id "spreadSheetMode" is enabled. It's false by default. */ bool spreadSheetMode() const { return m_spreadSheetMode; } /*! \return number of currently edited record or -1. */ inline int recordEditing() const { return m_recordEditing; } enum DeletionPolicy { NoDelete = 0, AskDelete = 1, ImmediateDelete = 2, SignalDelete = 3 }; /*! \return deletion policy for this object. The default (after allocating) is AskDelete. */ DeletionPolicy deletionPolicy() const { return m_deletionPolicy; } virtual void setDeletionPolicy(DeletionPolicy policy); /*! Deletes currently selected record; does nothing if no record is currently selected. If record is in edit mode, editing is cancelled before deleting. */ virtual void deleteCurrentRecord(); /*! Inserts one empty record above \a pos. If \a pos is -1 (the default), new record is inserted above the current record (or above 1st record if there is no current). A new record becomes current if \a pos is -1 or if \a pos is equal currentRecord(). This method does nothing if: -inserting flag is disabled (see isInsertingEnabled()) -read-only flag is set (see isReadOnly()) \return inserted record's data */ virtual KDbRecordData *insertEmptyRecord(int pos = -1); /*! For reimplementation: called by deleteItem(). If returns false, deleting is aborted. Default implementation just returns true. */ virtual bool beforeDeleteItem(KDbRecordData *data); /*! Deletes \a record. Used by deleteCurrentRecord(). Calls beforeDeleteItem() before deleting, to double-check if deleting is allowed. \return true on success. */ bool deleteItem(KDbRecordData *data); /*! Inserts \a data at position \a pos. -1 means current record. Used by insertEmptyRecord(). */ void insertItem(KDbRecordData *data, int pos = -1); /*! Clears entire table data, its visible representation and deletes data at database backend (if this is db-aware object). Does not clear columns information. Does not destroy KDbTableViewData object (if present) but only clears its contents. Displays confirmation dialog if \a ask is true (the default is false). Repaints widget if \a repaint is true (the default). For empty tables, true is returned immediately. If isDeleteEnabled() is false, false is returned. For spreadsheet mode all current records are just replaced by empty records. \return true on success, false on failure, and cancelled if user cancelled deletion (only possible if \a ask is true). */ tristate deleteAllRecords(bool ask = false, bool repaint = true); /*! \return maximum number of records that can be displayed per one "page" for current view's size. */ virtual int recordsPerPage() const = 0; virtual void selectRecord(int record); virtual void selectNextRecord(); virtual void selectPreviousRecord(); virtual void selectNextPage(); //!< page down action virtual void selectPreviousPage(); //!< page up action virtual void selectFirstRecord(); virtual void selectLastRecord(); virtual void addNewRecordRequested(); /*! Clears the current selection. Current record and column will be now unspecified: currentRecord(), currentColumn() will return -1, and selectedRecord() will return null. */ virtual void clearSelection(); //! Flags for setCursorPosition() enum CursorPositionFlag { NoCursorPositionFlags = 0, //!< Default flag ForceSetCursorPosition = 1, //!< Update cursor position even if record and col doesn't //!< differ from actual position. DontEnsureCursorVisibleIfPositionUnchanged = 2 //!< Don't call ensureCellVisible() //!< when position is unchanged and //!< ForceSetCursorPosition is off. }; Q_DECLARE_FLAGS(CursorPositionFlags, CursorPositionFlag) /*! Moves cursor to \a record and \a col. If \a col is -1, current column number is used. If forceSet is true, cursor position is updated even if \a record and \a col doesn't differ from actual position. */ virtual void setCursorPosition(int record, int col = -1, CursorPositionFlags flags = NoCursorPositionFlags); /*! Ensures that cell at \a record and \a col is visible. If \a col is -1, current column number is used. \a record and \a col, if not -1, must be between 0 and recordCount()-1 (or columnCount()-1 accordingly). */ virtual void ensureCellVisible(int record, int col) = 0; /*! Ensures that column \a col is visible. If \a col is -1, current column number is used. \a col, if not -1, must be between 0 and columnCount()-1. */ virtual void ensureColumnVisible(int col) = 0; /*! Specifies, if this object automatically accepts record editing (using acceptRecordEdit()) on accepting any cell's edit (i.e. after acceptEditor()). \sa acceptsRecordEditAfterCellAccepting() */ virtual void setAcceptsRecordEditAfterCellAccepting(bool set); /*! \return true, if this object automatically accepts record editing (using acceptRecordEdit()) on accepting any cell's edit (i.e. after acceptEditor()). By default this flag is set to false. Not that if the query for this table has given constraints defined, like NOT NULL / NOT EMPTY for more than one field - editing a record would be impossible for the flag set to true, because of constraints violation. However, setting this flag to true can be useful especially for not-db-aware data set (it's used e.g. in Kexi Alter Table's field editor). */ bool acceptsRecordEditAfterCellAccepting() const { return m_acceptsRecordEditAfterCellAccepting; } /*! \return true, if this table accepts dropping data on the records. */ bool dropsAtRecordEnabled() const { return m_dropsAtRecordEnabled; } /*! Specifies, if this table accepts dropping data on the records. If enabled: - dragging over record is indicated by drawing a line at bottom side of this record - dragOverRecord() signal will be emitted on dragging, -droppedAtRecord() will be emitted on dropping By default this flag is set to false. */ virtual void setDropsAtRecordEnabled(bool set); /*! \return currently used data (field/cell) editor or 0 if there is no data editing. */ inline KexiDataItemInterface *editor() const { return m_editor; } /*! Cancels record editing. All changes made to the editing record during this current session will be undone. \return true on success or false on failure (e.g. when editor does not exist) */ virtual bool cancelRecordEditing(); /*! Accepts record editing. All changes made to the editing record during this current session will be accepted (saved). \return true if accepting was successful, false otherwise (e.g. when current record contains data that does not meet given constraints). */ virtual bool acceptRecordEditing(); virtual void removeEditor(); /*! Cancels changes made to the currently active editor. Reverts the editor's value to old one. \return true on success or false on failure (e.g. when editor does not exist) */ virtual bool cancelEditor(); //! Accepst changes made to the currently active editor. //! \return true on success or false on failure (e.g. when editor does not exist or there is data validation error) virtual bool acceptEditor(); //! Flags for use in createEditor() enum CreateEditorFlag { ReplaceOldValue = 1, //!< Remove old value replacing it with a new one EnsureCellVisible = 2, //!< Ensure the cell behind the editor is visible DefaultCreateEditorFlags = EnsureCellVisible //!< Default flags. }; Q_DECLARE_FLAGS(CreateEditorFlags, CreateEditorFlag) //! Creates editors and shows it, what usually means the beginning of a cell editing virtual void createEditor(int record, int col, const QString& addText = QString(), CreateEditorFlags flags = DefaultCreateEditorFlags) = 0; /*! Used when Return key is pressed on cell, the cell has been double clicked or "+" navigator's button is clicked. Also used when we want to continue editing a cell after "invalid value" message was displayed (in this case, \a setText is usually not empty, what means that text will be set in the cell replacing previous value). */ virtual void startEditCurrentCell(const QString& setText = QString(), CreateEditorFlags flags = DefaultCreateEditorFlags); /*! Deletes currently selected cell's contents, if allowed. In most cases delete is not accepted immediately but "record editing" mode is just started. */ virtual void deleteAndStartEditCurrentCell(); inline KDbRecordData *recordAt(int pos) const; /*! \return column information for column number \a col. Default implementation just returns column # col, but for Kexi Forms column data corresponding to widget number is used here (see KexiFormScrollView::fieldNumberForColumn()). */ virtual KDbTableViewColumn* column(int col); /*! \return field number within data model connected to a data-aware widget at column \a col. Can return -1 if there's no such column. */ virtual int fieldNumberForColumn(int col) { return col; } bool hasDefaultValueAt(const KDbTableViewColumn& tvcol); const QVariant* bufferedValueAt(int record, int col, bool useDefaultValueIfPossible = true); //! \return a type of column \a col - one of KDbField::Type int columnType(int col); //! \return default value for column \a col QVariant columnDefaultValue(int col) const; /*! \return true if column \a col is editable. Default implementation takes information about 'readOnly' flag from data member. Within forms, this is reimplemented for checking 'readOnly' flag from a widget ('readOnly' flag from data member is still checked though). */ virtual bool columnEditable(int col); /*! Redraws the current cell. To be implemented. */ virtual void updateCurrentCell() = 0; //! @return height of the horizontal header, 0 by default. virtual int horizontalHeaderHeight() const; //! signals virtual void itemChanged(KDbRecordData* data, int record, int column) = 0; virtual void itemChanged(KDbRecordData* data, int record, int column, const QVariant &oldValue) = 0; virtual void itemDeleteRequest(KDbRecordData* data, int record, int column) = 0; virtual void currentItemDeleteRequest() = 0; //! Emitted for spreadsheet mode when an item was deleted and a new item has been appended virtual void newItemAppendedForAfterDeletingInSpreadSheetMode() = 0; /*! Data has been refreshed on-screen - emitted from initDataContents(). */ virtual void dataRefreshed() = 0; virtual void dataSet(KDbTableViewData *data) = 0; /*! \return a pointer to context menu. This can be used to plug some actions there. */ QMenu* contextMenu() const { return m_contextMenu; } /*! \return true if the context menu is enabled (visible) for the view. True by default. */ bool contextMenuEnabled() const { return m_contextMenuEnabled; } /*! Enables or disables the context menu for the view. */ void setContextMenuEnabled(bool set) { m_contextMenuEnabled = set; } /*! Sets a title with icon for the context menu. Set empty icon and text to remove the title item. This method should be called before customizing the menu because it will be recreated by the method. */ void setContextMenuTitle(const QIcon &icon, const QString &text); /*! \return title text of the context menu. */ QString contextMenuTitleText() const { return m_contextMenuTitleText; } /*! \return title icon of the context menu. */ QIcon contextMenuTitleIcon() const { return m_contextMenuTitleIcon; } /*! \return true if vertical scrollbar's tooltips are enabled (true by default). */ bool scrollbarToolTipsEnabled() const; /*! Enables or disables vertical scrollbar's tooltip. */ void setScrollbarToolTipsEnabled(bool set); /*! Typically handles pressing Enter or F2 key: if current cell has boolean type, toggles it's value, otherwise starts editing (startEditCurrentCell()). */ void startEditOrToggleValue(); /*! \return true if the new record is edited; implies: recordEditing==true. */ inline bool newRecordEditing() const { return m_newRecordEditing; } /*! Reaction on toggling a boolean value of a cell: we're starting to edit the cell and inverting it's state. */ virtual void boolToggled(); virtual void connectCellSelectedSignal(const QObject* receiver, const char* intIntMember) = 0; virtual void connectRecordEditingStartedSignal(const QObject* receiver, const char* intMember) = 0; virtual void connectRecordEditingTerminatedSignal(const QObject* receiver, const char* voidMember) = 0; virtual void connectUpdateSaveCancelActionsSignal(const QObject* receiver, const char* voidMember) = 0; virtual void connectReloadActionsSignal(const QObject* receiver, const char* voidMember) = 0; virtual void connectDataSetSignal(const QObject* receiver, const char* kexiTableViewDataMember) = 0; virtual void connectToReloadDataSlot(const QObject* sender, const char* voidSignal) = 0; virtual void slotDataDestroying(); //! Copy current selection to a clipboard (e.g. cell) virtual void copySelection() = 0; //! Cut current selection to a clipboard (e.g. cell) virtual void cutSelection() = 0; //! Paste current clipboard contents (e.g. to a cell) virtual void paste() = 0; /*! Finds \a valueToFind within the data items \a options are used to control the process. Selection is moved to found value. If \a next is true, "find next" is performed, else "find previous" is performed. Searching behaviour also depends on status of the previous search: for every search, position of the cells containing the found value is stored internally by the data-aware interface (not in options). Moreover, position (start, end) of the found value is also stored. Thus, the subsequent search will reuse this information to be able to start searching exactly after the previously found value (or before for "find previous" option). The flags can be zeroed, what will lead to seaching from the first character of the current item (cell). \return true if value has been found, false if value has not been found, and cancelled if there is nothing to find or there is no data to search in. */ virtual tristate find(const QVariant& valueToFind, const KexiSearchAndReplaceViewInterface::Options& options, bool next); /*! Finds \a valueToFind within the data items and replaces with \a replacement \a options are used to control the process. \return true if value has been found and replaced, false if value has not been found and replaced, and cancelled if there is nothing to find or there is no data to search in or the data is read only. If \a replaceAll is true, all found values are replaced. */ virtual tristate findNextAndReplace(const QVariant& valueToFind, const QVariant& replacement, const KexiSearchAndReplaceViewInterface::Options& options, bool replaceAll); /*! \return vertical scrollbar */ virtual QScrollBar* verticalScrollBar() const = 0; /*! Used in KexiTableView::keyPressEvent() (and in continuous forms). \return true when the key press event \e was consumed. You should also check e->isAccepted(), if it's true, nothing should be done; if it is false, you should call setCursorPosition() for the altered \a curentColumn and \c currentRecord variables. If \a moveToFirstField is not 0, *moveToFirstField will be set to true when the cursor should be moved to the first field (in tab order) and to false otherwise. If \a moveToLastField is not 0, *moveToLastField will be set to true when the cursor should be moved to the last field (in tab order) and to false otherwise. Note for forms: if moveToFirstField and moveToLastField are not 0, \a currentColumn is altered after calling this method, so setCursorPosition() will set to the index of an appropriate column (field). This is needed because field widgets can be inserted and ordered in custom tab order, so the very first field in the data source can be other than the very first field in the form. Used by KexiTableView::keyPressEvent() and KexiTableView::keyPressEvent(). */ virtual bool handleKeyPress(QKeyEvent *e, int *currentRecord, int *currentColumn, bool fullRecordSelection, bool *moveToFirstField = 0, bool *moveToLastField = 0); protected: /*! Reimplementation for KexiDataAwareObjectInterface. Initializes data contents (resizes it, sets cursor at the first record). Sets record count for record navigator. Sets cursor positin (using setCursorPosition()) to first record or sets (-1, -1) position if no records are available. Called on setData(). Also called once on show event after refreshRequested() signal was received from TableViewData object. */ virtual void initDataContents(); /*! Clears columns information and thus all internal table data and its visible representation. Repaints widget if \a repaint is true. */ virtual void clearColumns(bool repaint = true); /*! Called by clearColumns() to clear internals of the object. */ virtual void clearColumnsInternal(bool repaint) = 0; /*! @internal for implementation \return sorting order (within GUI). currentLocalSortColumn() should be also checked, and if it returns -1, no particular sorting is set up. Even this does not mean that any sorting has been performed within GUI of this object, because the data could be changed in the meantime outside of this GUI object. @see dataSortOrder() currentLocalSortColumn() */ virtual KDbOrderByColumn::SortOrder currentLocalSortOrder() const = 0; /*! @internal for implementation \return sorted column number for this widget or -1 if no column is sorted witin GUI. This does not mean that the same sorting is performed within data member which is used by this widget, because the data could be changed in the meantime outside of this GUI widget. @see dataSortColumn() currentLocalSortOrder() */ virtual int currentLocalSortColumn() const = 0; /*! @internal for implementation Shows sorting indicator order in the GUI for column @a column. This should not perform any sorting in data assigned to this object. @a column may be -1, what means "no sorting". */ virtual void setLocalSortOrder(int column, KDbOrderByColumn::SortOrder order) = 0; /*! @internal Sets order for \a column: -1: descending, 1: ascending, 0: invert order */ virtual void sortColumnInternal(int col, int order = 0); /*! @internal for implementation Updates GUI after sorting. After sorting you need to ensure current record and column is visible to avoid user confusion. For exaple, in KexiTableView implementation, current cell is centered (if possible) and updateContents() is called. */ virtual void updateGUIAfterSorting(int previousRecord) = 0; /*! Emitted in initActions() to force reload actions You should remove existing actions and add them again. Define and emit reloadActions() signal here. */ virtual void reloadActions() = 0; /*! Reloads data for this object. */ virtual void reloadData(); /*! for implementation as a signal */ virtual void itemSelected(KDbRecordData *) = 0; /*! for implementation as a signal */ virtual void cellSelected(int record, int col) = 0; /*! for implementation as a signal */ virtual void sortedColumnChanged(int col) = 0; /*! for implementation as a signal */ virtual void recordEditingTerminated(int record) = 0; /*! for implementation as a signal */ virtual void updateSaveCancelActions() = 0; /*! Prototype for signal recordEditingStarted(int), implemented by KexiFormScrollView. */ virtual void recordEditingStarted(int record) = 0; /*! Clear temporary members like the pointer to current editor. If you reimplement this method, don't forget to call this one. */ virtual void clearVariables(); /*! @internal Creates editor structure without filling it with data. Used in createEditor() and few places to be able to display cell contents dependending on its type. If \a ignoreMissingEditor is false (the default), and editor cannot be instantiated, current record editing (if present) is cancelled. */ virtual KexiDataItemInterface *editor(int col, bool ignoreMissingEditor = false) = 0; /*! Updates editor's position, size and shows its focus (not the editor!) for \a record and \a column, using editor(). Does nothing if editor not found. */ virtual void editorShowFocus(int record, int column) = 0; /*! Redraws specified cell. */ virtual void updateCell(int record, int column) = 0; /*! Redraws all cells of specified record \a record. */ virtual void updateRecord(int record) = 0; /*! Updates contents of the widget. Just call update() here on your widget. */ virtual void updateWidgetContents() = 0; /*! Updates widget's contents size e.g. using QScrollView::resizeContents(). */ virtual void updateWidgetContentsSize() = 0; /*! @internal Updates record appearance after canceling record edit. Used by cancelRecordEdit(). By default just calls updateRecord(m_curRecord). Reimplemented by KexiFormScrollView. */ virtual void updateAfterCancelRecordEditing(); /*! @internal Updates record appearance after accepting record edit. Used by acceptRecordEditing(). By default just calls updateRecord(m_curRecord). Reimplemented by KexiFormScrollView. */ virtual void updateAfterAcceptRecordEditing(); //! Handles TableViewData::recordRepaintRequested() signal virtual void slotRecordRepaintRequested(KDbRecordData* data) { Q_UNUSED(data); } //! Handles TableViewData::aboutToDeleteRecord() signal. Prepares info for slotRecordDeleted(). virtual void slotAboutToDeleteRecord(KDbRecordData* data, KDbResultInfo* result, bool repaint); //! Handles TableViewData::recordDeleted() signal to repaint when needed. virtual void slotRecordDeleted(); //! Handles TableViewData::recordInserted() signal to repaint when needed. virtual void slotRecordInserted(KDbRecordData *data, bool repaint); virtual void beginInsertItem(KDbRecordData *data, int pos); virtual void endInsertItem(KDbRecordData *data, int pos); virtual void beginRemoveItem(KDbRecordData *data, int pos); virtual void endRemoveItem(int pos); //! Like above, not db-aware version virtual void slotRecordInserted(KDbRecordData *data, int record, bool repaint); virtual void slotRecordsDeleted(const QList &) {} //! for sanity checks (return true if m_data is present; else: outputs warning) inline bool hasData() const; /*! Used by setCursorPosition() if cursor's position changed. */ virtual void selectCellInternal(int previousRecord, int previousColumn); /*! Used in KexiDataAwareObjectInterface::slotRecordDeleted() to repaint tow \a record and all visible below. Implemented if there is more than one record displayed, i.e. currently for KexiTableView. */ virtual void updateAllVisibleRecordsBelow(int record) { Q_UNUSED(record); } /*! @return geometry of the viewport, i.e. the scrollable area, minus any scrollbars, etc. */ virtual QRect viewportGeometry() const = 0; //! Call this from the subclass. */ virtual void focusOutEvent(QFocusEvent* e); /*! Handles verticalScrollBar()'s valueChanged(int) signal. Called when vscrollbar's value has been changed. Call this method from the subclass. */ virtual void verticalScrollBarValueChanged(int v); /*! Changes 'record editing' >=0 there's currently edited record, else -1. * Can be reimplemented with calling superclass setRecordEditing() * Sends recordEditingStarted(int) signal. * @see recordEditing() recordEditingStarted(). */ void setRecordEditing(int record); /*! Shows error message box suitable for \a resultInfo. This can be "sorry" or "detailedSorry" message box or "queryYesNo" if resultInfo->allowToDiscardChanges is true. \return code of button clicked: KMessageBox::Ok in case of "sorry" or "detailedSorry" messages and KMessageBox::Yes or KMessageBox::No in case of "queryYesNo" message. */ int showErrorMessageForResult(const KDbResultInfo& resultInfo); /*! Shows context message @a message for editor @a item. */ void showEditorContextMessage( KexiDataItemInterface *item, const QString &message, KMessageWidget::MessageType type, KMessageWidget::CalloutPointerDirection direction); /*! Shows context message about exceeded length for editor @a item. If @a exceeded is true, a new message is created, else the message will be removed. */ void showLengthExceededMessage(KexiDataItemInterface *item, bool exceeded); /*! Updates message about exceeded length for editor @a item. Useful only where message created with showLengthExceededMessage() is displayed. */ void showUpdateForLengthExceededMessage(KexiDataItemInterface *item); /*! Prepares array of indices of visible values to search within. This is per-interface global cache. Needed for faster lookup because there could be lookup values. Called whenever columns definition changes, i.e. in setData() and clearColumns(). @see find() */ void updateIndicesForVisibleValues(); //! @return horizontal header, 0 by default. virtual QHeaderView* horizontalHeader() const; //! @return vertical header, 0 by default. virtual QHeaderView* verticalHeader() const; //! Update section of vertical header virtual void updateVerticalHeaderSection(int section) = 0; //! data structure displayed for this object KDbTableViewData *m_data; //! current record (cursor) int m_curRecord; //! current column (cursor) int m_curColumn; //! current record's data KDbRecordData *m_currentRecord; //! data iterator KDbTableViewDataIterator m_itemIterator; //! record's data for inserting KDbRecordData *m_insertRecord; //! true if m_data member is owned by this object bool m_owner; /*! true if a new record is edited; implies: m_recorfEditing == true. */ bool m_newRecordEditing; /*! 'sorting by column' availability flag for widget */ bool m_isSortingEnabled; /*! true if filtering is enabled for the view. */ bool m_isFilteringEnabled; /*! Public version of 'acceptsRecordEditingAfterCellAcceptin' flag (available for a user). It's OR'es together with above flag. */ bool m_acceptsRecordEditAfterCellAccepting; /*! Used in acceptEditor() to avoid infinite recursion, eg. when we're calling acceptRecordEditing() during cell accepting phase. */ bool m_inside_acceptEditor; // no bit field allowed /*! Used in acceptRecordEditing() to avoid infinite recursion, eg. when we're calling acceptRecordEdit() during cell accepting phase. */ bool m_inside_acceptRecordEdit; // no bit field allowed /*! @internal if true, this object automatically accepts record editing (using acceptRecordEditing()) on accepting any cell's edit (i.e. after acceptEditor()). */ bool m_internal_acceptsRecordEditingAfterCellAccepting; /*! true, if inserting empty records are enabled (false by default) */ bool m_emptyRecordInsertingEnabled; /*! Contains 1 if the object is readOnly, 0 if not; otherwise (-1 means "do not know") the 'readOnly' flag from object's internal data structure (KDbTableViewData *KexiTableView::m_data) is reused. */ int m_readOnly; //! @todo really keep this here and not in KexiTableView? /*! true if currently double click action was is performed (so accept/cancel editor shoudn't be executed) */ bool m_contentsMousePressEvent_dblClick; /*! like for readOnly: 1 if inserting is enabled */ int m_insertingEnabled; /*! true, if initDataContents() should be called on show event. */ bool m_initDataContentsOnShow; /*! Set to true in setCursorPosition() to indicate that cursor position was set before show() and it shouldn't be changed on show(). Only used if initDataContentsOnShow is true. */ bool m_cursorPositionSetExplicityBeforeShow; /*! true if spreadSheetMode is enabled. False by default. @see KexiTableView::setSpreadSheetMode() */ bool m_spreadSheetMode; /*! true, if this table accepts dropping data on the records (false by default). */ bool m_dropsAtRecordEnabled; /*! true, if this entire (visible) record should be updated when boving to other record. False by default. For table view with 'record highlighting' flag enabled, it is true. */ bool m_updateEntireRecordWhenMovingToOtherRecord; DeletionPolicy m_deletionPolicy; KexiDataItemInterface *m_editor; /*! Navigation panel, used if navigationPanelEnabled is true. */ KexiRecordNavigatorIface *m_navPanel; //!< main navigation widget bool m_navPanelEnabled; /*! Record number that over which user drags a mouse pointer. Used to indicate dropping possibility for that record. Equal -1 if no indication is needed. */ int m_dragIndicatorLine; /*! Context menu widget. */ QMenu *m_contextMenu; /*! Text of context menu title. */ QString m_contextMenuTitleText; /*! Icon of context menu title. */ QIcon m_contextMenuTitleIcon; /*! True if context menu is enabled. */ bool m_contextMenuEnabled; //! Used by updateAfterCancelRecordEditing() bool m_alsoUpdateNextRecord; /*! Record number (>=0 or -1 == no record) that will be deleted in deleteRecord(). It is set in slotAboutToDeleteRecord(KDbRecordData*,KDbResultInfo*,bool)) slot received from KDbTableViewData member. This value will be used in slotRecordDeleted() after recordDeleted() signal is received from KDbTableViewData member and then cleared (set to -1). */ int m_recordWillBeDeleted; /*! Displays passive error popup label used when invalid data has been entered. */ QPointer m_errorMessagePopup; /*! Used to enable/disable execution of verticalScrollBarValueChanged() when users navigate through records using keyboard, so scrollbar tooltips are not visible. */ bool m_verticalScrollBarValueChanged_enabled; /*! True, if vscrollbar tooltips are enabled (true by default). */ bool m_scrollbarToolTipsEnabled; //! Used to mark recently found value class PositionOfValue { public: PositionOfValue() : firstCharacter(0), lastCharacter(0), exists(false) {} int firstCharacter; int lastCharacter; bool exists; }; /*! Used to mark recently found value. Updated on successful execution of find(). If the current cursor's position changes, or data in the current cell changes, positionOfRecentlyFoundValue.exists is set to false. */ PositionOfValue m_positionOfRecentlyFoundValue; /*! Used to compare whether we're looking for new value. */ QVariant m_recentlySearchedValue; /*! Used to compare whether the search direction has changed. */ KexiSearchAndReplaceViewInterface::Options::SearchDirection m_recentSearchDirection; //! Setup by updateIndicesForVisibleValues() and used by find() QVector m_indicesForVisibleValues; private: /*! >= 0 if a record is edited */ int m_recordEditing; bool m_lengthExceededMessageVisible; //! true if acceptRecordEditing() should be called in setCursorPosition() (true by default) bool m_acceptRecordEditing_in_setCursorPosition_enabled; }; Q_DECLARE_OPERATORS_FOR_FLAGS(KexiDataAwareObjectInterface::CreateEditorFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(KexiDataAwareObjectInterface::CursorPositionFlags) inline bool KexiDataAwareObjectInterface::hasData() const { if (!m_data) qDebug() << "No data assigned!"; return m_data != 0; } inline KDbRecordData *KexiDataAwareObjectInterface::recordAt(int pos) const { KDbRecordData *data = m_data->at(pos); if (!data) qDebug() << "pos:" << pos << "- NO ITEM!!"; else { /* qDebug() << "record:" << record; int i=1; for (KexiTableItem::Iterator it = item->begin();it!=item->end();++it,i++) qDebug() << i<<": " << (*it).toString();*/ } return data; } //! Convenience macro used for KexiDataAwareObjectInterface implementations. #define KEXI_DATAAWAREOBJECTINTERFACE \ public: \ - void connectCellSelectedSignal(const QObject* receiver, const char* intIntMember) { \ + void connectCellSelectedSignal(const QObject* receiver, const char* intIntMember) override { \ connect(this, SIGNAL(cellSelected(int,int)), receiver, intIntMember); \ } \ - void connectRecordEditingStartedSignal(const QObject* receiver, const char* intMember) { \ + void connectRecordEditingStartedSignal(const QObject* receiver, const char* intMember) override { \ connect(this, SIGNAL(recordEditingStarted(int)), receiver, intMember); \ } \ - void connectRecordEditingTerminatedSignal(const QObject* receiver, const char* voidMember) { \ + void connectRecordEditingTerminatedSignal(const QObject* receiver, const char* voidMember) override { \ connect(this, SIGNAL(recordEditingTerminated(int)), receiver, voidMember); \ } \ void connectUpdateSaveCancelActionsSignal(const QObject* receiver, \ - const char* voidMember) { \ + const char* voidMember) override { \ connect(this, SIGNAL(updateSaveCancelActions()), receiver, voidMember); \ } \ - void connectReloadActionsSignal(const QObject* receiver, const char* voidMember) { \ + void connectReloadActionsSignal(const QObject* receiver, const char* voidMember) override { \ connect(this, SIGNAL(reloadActions()), receiver, voidMember); \ } \ void connectDataSetSignal(const QObject* receiver, \ - const char* kexiTableViewDataMember) { \ + const char* kexiTableViewDataMember) override { \ connect(this, SIGNAL(dataSet(KDbTableViewData*)), receiver, kexiTableViewDataMember); \ } \ - void connectToReloadDataSlot(const QObject* sender, const char* voidSignal) { \ + void connectToReloadDataSlot(const QObject* sender, const char* voidSignal) override { \ connect(sender, voidSignal, this, SLOT(reloadData())); \ } #endif diff --git a/src/widget/dataviewcommon/kexidataawareview.h b/src/widget/dataviewcommon/kexidataawareview.h index 481bc1077..8efd650c4 100644 --- a/src/widget/dataviewcommon/kexidataawareview.h +++ b/src/widget/dataviewcommon/kexidataawareview.h @@ -1,135 +1,135 @@ /* This file is part of the KDE project Copyright (C) 2005-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDATAAWAREVIEW_H #define KEXIDATAAWAREVIEW_H #include "kexidataviewcommon_export.h" #include #include class KexiDataAwareObjectInterface; class KexiSharedActionClient; /*! @short Provides a view displaying record-based data. The KexiDataAwareView is used to implement differently-looking views for displaying record-based data in a consistent way: - tabular data views - form data view Action implementations like data editing and deleting are shared for different view types to keep even better consistency. The view also implements KexiSearchAndReplaceViewInterface to support search/replace features used by shared KexiFindDialog. */ class KEXIDATAVIEWCOMMON_EXPORT KexiDataAwareView : public KexiView, public KexiSearchAndReplaceViewInterface { Q_OBJECT public: explicit KexiDataAwareView(QWidget *parent = 0); virtual ~KexiDataAwareView(); QWidget* mainWidget() const; - virtual QSize minimumSizeHint() const; + virtual QSize minimumSizeHint() const override; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; KexiDataAwareObjectInterface* dataAwareObject() const; /*! Sets up data for find/replace dialog, based on view's data model. Implemented for KexiSearchAndReplaceViewInterface. */ virtual bool setupFindAndReplace(QStringList& columnNames, QStringList& columnCaptions, - QString& currentColumnName); + QString& currentColumnName) override; /*! Finds \a valueToFind within the view. Implemented for KexiSearchAndReplaceViewInterface. */ virtual tristate find(const QVariant& valueToFind, - const KexiSearchAndReplaceViewInterface::Options& options, bool next); + const KexiSearchAndReplaceViewInterface::Options& options, bool next) override; /*! Finds \a valueToFind within the view and replaces with \a replacement. Implemented for KexiSearchAndReplaceViewInterface. */ virtual tristate findNextAndReplace(const QVariant& valueToFind, const QVariant& replacement, - const KexiSearchAndReplaceViewInterface::Options& options, bool replaceAll); + const KexiSearchAndReplaceViewInterface::Options& options, bool replaceAll) override; public Q_SLOTS: void deleteAllRecords(); void deleteCurrentRecord(); void deleteAndStartEditCurrentCell(); void startEditOrToggleValue(); bool acceptRecordEditing(); bool cancelRecordEditing(); void sortAscending(); void sortDescending(); void copySelection(); void cutSelection(); void paste(); void slotGoToFirstRecord(); void slotGoToPreviusRecord(); void slotGoToNextRecord(); void slotGoToLastRecord(); void slotGoToNewRecord(); /*! @return true if data editing is in progress. * Implemented for KexiView. */ - bool isDataEditingInProgress() const; + bool isDataEditingInProgress() const override; /*! Identical to acceptRecordEditing() * @todo replace acceptRecordEditing() with this method * Implemented for KexiView. */ - virtual tristate saveDataChanges(); + virtual tristate saveDataChanges() override; /*! Identical to cancelRecordEditing() * @todo replace cancelRecordEditing() with this method * Implemented for KexiView. */ - virtual tristate cancelDataChanges(); + virtual tristate cancelDataChanges() override; protected Q_SLOTS: void slotCellSelected(int record, int column); void reloadActions(); void slotUpdateRecordActions(int record); //! Updates 'save/cancel record changes' actions void slotUpdateSaveCancelActions(); void slotClosing(bool* cancel); protected: void init(QWidget* viewWidget, KexiSharedActionClient* actionClient, KexiDataAwareObjectInterface* dataAwareObject, // temporary, for KexiFormView in design mode bool noDataAware = false ); void initActions(); - virtual void updateActions(bool activated); + virtual void updateActions(bool activated) override; QWidget* internalView() const; - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; QAction* sharedActionRequested(QKeyEvent *ke, const char *actionName); private: class Private; Private * const d; }; #endif diff --git a/src/widget/dataviewcommon/kexidataprovider.h b/src/widget/dataviewcommon/kexidataprovider.h index ee65ec088..639da162d 100644 --- a/src/widget/dataviewcommon/kexidataprovider.h +++ b/src/widget/dataviewcommon/kexidataprovider.h @@ -1,94 +1,94 @@ /* This file is part of the KDE project Copyright (C) 2005 Jarosław Staniek 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 KEXIFORMDATAPROVIDER_H #define KEXIFORMDATAPROVIDER_H #include "kexidataviewcommon_export.h" #include "kexiformdataiteminterface.h" #include #include class KDbQuerySchema; class KDbRecordData; //! @short The KexiFormDataProvider class is a data provider for Kexi Forms /*! This provider collects data-aware widgets using setMainWidget(). Then, usedDataSources() unique list of required field names is available. On every call of fillDataItems() method, the provider will fill data items with appropriate data from a database cursor. Field names are collected effectively, so eg. having widgets using data sources: ("name", "surname", "surname", "name") - "name" and "surname" repeated - will only return ("name", "surname") list, so the cursor's query can be simplified and thus more effective. */ class KEXIDATAVIEWCOMMON_EXPORT KexiFormDataProvider : public KexiDataItemChangesListener { public: KexiFormDataProvider(); virtual ~KexiFormDataProvider(); /*! sets \a mainWidget to be a main widget for this data provider. Also find widgets whose will work as data items (all of them must implement KexiFormDataItemInterface), so these could be filled with data on demand. */ void setMainDataSourceWidget(QWidget* mainWidget); QStringList usedDataSources() const { return m_usedDataSources; } /*! Fills data items with appropriate data fetched from \a data. \a cursorAtNewRecord == true means that we are at new (not yet inserted) database row. */ void fillDataItems(KDbRecordData *data, bool cursorAtNewRecord); /*! Implementation for KexiDataItemChangesListener. Reaction for change of \a item. Does nothing here. */ - virtual void valueChanged(KexiDataItemInterface* item); + virtual void valueChanged(KexiDataItemInterface* item) override; /*! Implementation for KexiDataItemChangesListener. Implement this to return information whether we're currently at new record or not. This can be used e.g. by data-aware widgets to determine if "(autonumber)" label should be displayed. Returns false here. */ - virtual bool cursorAtNewRecord() const; + virtual bool cursorAtNewRecord() const override; /*! Invalidates data sources collected by this provided. \a invalidSources is the set of data sources that should be omitted for fillDataItems(). Used by KexiFormView::initDataSource(). */ void invalidateDataSources(const QSet& invalidSources, KDbConnection *conn, KDbQuerySchema* query); /*! Fills the same data provided by \a value to every data item (other than \a item) having the same data source as \a item. This method is called immediately when \a value is changed, so duplicated data items are quickly updated. */ void fillDuplicatedDataItems(KexiFormDataItemInterface* item, const QVariant& value); protected: QWidget *m_mainWidget; QSet *m_duplicatedItems; typedef QMap KexiFormDataItemInterfaceToIntMap; QList m_dataItems; QStringList m_usedDataSources; KexiFormDataItemInterfaceToIntMap m_fieldNumbersForDataItems; bool m_disableFillDuplicatedDataItems; }; #endif diff --git a/src/widget/dataviewcommon/kexiformdataiteminterface.h b/src/widget/dataviewcommon/kexiformdataiteminterface.h index a188c3a45..f5a8ac8b5 100644 --- a/src/widget/dataviewcommon/kexiformdataiteminterface.h +++ b/src/widget/dataviewcommon/kexiformdataiteminterface.h @@ -1,172 +1,172 @@ /* This file is part of the KDE project Copyright (C) 2005-2009 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIFORMDATAITEMINTERFACE_H #define KEXIFORMDATAITEMINTERFACE_H #include "kexidataviewcommon_export.h" #include #include #include class KDbConnection; class KDbField; //! An interface for declaring form widgets to be data-aware. class KEXIDATAVIEWCOMMON_EXPORT KexiFormDataItemInterface : public KexiDataItemInterface { public: KexiFormDataItemInterface(); virtual ~KexiFormDataItemInterface(); //! \return the name of the data source for this widget. //! Data source usually means here a table or query, a field name or an expression. inline QString dataSource() const { return m_dataSource; } //! Sets the name of the data source for this widget. //! Data source usually means here a table or query or field name name. inline void setDataSource(const QString &ds) { m_dataSource = ds; } /*! \return the plugin ID of the part for the widget's data source. It means IDs like "org.kexi-project.table" or "org.kexi-project.query" if the data source is set to object (as within form) or is empty if the data source is set to table field or query column. */ inline QString dataSourcePluginId() const { return m_dataSourcePartClass; } /*! Sets the plugin ID of the part for the data widget's data source. It usually means here a "org.kexi-project.table" or "org.kexi-project.query". @see dataSourcePluginId() */ inline void setDataSourcePluginId(const QString &pluginId) { m_dataSourcePartClass = pluginId; } /*! If \a displayDefaultValue is true, the value set by KexiDataItemInterface::setValue() is displayed in a special way. Used by KexiFormDataProvider::fillDataItems(). \a widget is equal to 'this'. You can reimplement this in the widget. Always call the superclass' implementation. setDisplayDefaultValue(.., false) is called in KexiFormScrollView::valueChanged() as a response on data change performed by user. */ virtual void setDisplayDefaultValue(QWidget* widget, bool displayDefaultValue); /*! \return true if default value is displayed for this item. */ virtual bool hasDisplayedDefaultValue() const { return m_displayDefaultValue; } /*! Convenience function: casts this item to a QWidget. Can return 0 if the item is not a QWidget-derived object. */ - virtual QWidget* widget() { + virtual QWidget* widget() override { return dynamic_cast(this); } /*! Sets 'invalid' state, e.g. a text editor widget should display text \a displayText and become read only to prevent entering data, because updating at the database backend is not available. \a displayText is usually set to something i18n'd like "#NAME?". Note: that even widgets that usually do not display texts (e.g. pixmaps) should display \a displayText too. */ virtual void setInvalidState(const QString& displayText) = 0; /*! Changes 'read only' flag, for this widget. Typically this flag can be passed to a widget itself, e.g. QLineEdit::setReadOnly(bool). */ virtual void setReadOnly(bool readOnly) = 0; //! \return database column information for this item KDbField* field() override; //! \return database column information for this item - KDbQueryColumnInfo* columnInfo() { + KDbQueryColumnInfo* columnInfo() override { return m_columnInfo; } /*! Used internally to set database column information. Reimplement if you need to do additional actions, e.g. set data validator based on field type. Don't forget about calling superclass implementation. */ - virtual void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) { + virtual void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo* cinfo) override { Q_UNUSED(conn) m_columnInfo = cinfo; } /*! Used internally to set visible database column information. Reimplemented in KexiDBComboBox: except for combo box, this does nothing. */ virtual void setVisibleColumnInfo(KDbQueryColumnInfo* cinfo) { Q_UNUSED(cinfo); } /*! \return visible database column information for this item. Except for combo box, this is exactly the same as columnInfo(). */ virtual KDbQueryColumnInfo* visibleColumnInfo() { return columnInfo(); } /*! Does nothing, because within forms, widgets are always visible. */ - virtual void hideWidget() { } + virtual void hideWidget() override { } /*! Does nothing, because within forms, widgets are always visible. */ - virtual void showWidget() { } + virtual void showWidget() override { } /*! Undoes changes made to this item - just resets the widget to original value. Note: This is internal method called by KexiFormScrollView::cancelEditor(). To cancel editing of the widget's data from the widget's code, use KexiFormDataItemInterface::cancelEditor(). Reimplemented in KexiDBComboBox to also revert the visible value (i.e. text) to the original state. */ virtual void undoChanges(); /* Cancels editing of the widget's data. This method just looks for the (grand)parent KexiFormScrollView object and calls KexiFormScrollView::cancelEditor(). */ void cancelEditor(); /*! @internal Called by top-level form on key press event. Default implementation does nothing. Implement this if you want to handle key presses from within the editor widget item. \return true if \a ke should be accepted by the widget item. This method is used e.g. in KexiDBImageBox for Key_Escape to if the popup is visible, so the key press won't be consumed to perform "cancel editing". */ virtual bool keyPressed(QKeyEvent *ke) { Q_UNUSED(ke); return false; } //! Selects contents of the widget if there is such behaviour set (it is by default). //! @todo add option for not selecting the field virtual void selectAllOnFocusIfNeeded(); protected: QString m_dataSource; QString m_dataSourcePartClass = QStringLiteral("org.kexi-project.table"); //!< default for cases when the part class is missing KDbQueryColumnInfo* m_columnInfo; KexiDisplayUtils::DisplayParameters *m_displayParametersForEnteredValue; //!< used in setDisplayDefaultValue() KexiDisplayUtils::DisplayParameters *m_displayParametersForDefaultValue; //!< used in setDisplayDefaultValue() bool m_displayDefaultValue; //!< used by setDisplayDefaultValue() friend class KexiDBAutoField; }; #endif diff --git a/src/widget/fields/KexiFieldComboBox.h b/src/widget/fields/KexiFieldComboBox.h index 6c9efebd6..4d8aab6a5 100644 --- a/src/widget/fields/KexiFieldComboBox.h +++ b/src/widget/fields/KexiFieldComboBox.h @@ -1,76 +1,76 @@ /* This file is part of the KDE project Copyright (C) 2005-2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIFIELDCOMBOBOX_H #define KEXIFIELDCOMBOBOX_H #include "kexiextwidgets_export.h" #include #include class KexiProject; /*! This widget provides a list of fields from a table or query within a combobox, so user can pick one of them. */ class KEXIEXTWIDGETS_EXPORT KexiFieldComboBox : public KComboBox { Q_OBJECT public: explicit KexiFieldComboBox(QWidget *parent = 0); virtual ~KexiFieldComboBox(); public Q_SLOTS: //! \return global project that is used to retrieve schema informationm for this combo box. KexiProject* project() const; //! Sets global project that is used to retrieve schema informationm for this combo box. void setProject(KexiProject *prj); void setTableOrQuery(const QString& name, KDbTableOrQuerySchema::Type type); QString tableOrQueryName() const; bool isTableAssigned() const; void setFieldOrExpression(const QString& string); void setFieldOrExpression(int index); QString fieldOrExpression() const; QString fieldOrExpressionCaption() const; /*! \return index of selected table or query field. -1 is returned if there is nothing selected or expression is selected of project is not assigned or table or query is not assigned. */ int indexOfField() const; Q_SIGNALS: void selected(); protected Q_SLOTS: void slotActivated(int); void slotReturnPressed(const QString & text); protected: - virtual void focusOutEvent(QFocusEvent *e); + virtual void focusOutEvent(QFocusEvent *e) override; class Private; Private * const d; }; #endif diff --git a/src/widget/fields/KexiFieldListModel.h b/src/widget/fields/KexiFieldListModel.h index 5e0a70da0..225b5d53a 100644 --- a/src/widget/fields/KexiFieldListModel.h +++ b/src/widget/fields/KexiFieldListModel.h @@ -1,68 +1,68 @@ /* This file is part of the KDE project Copyright (C) 2010 Adam Pigg This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KEXIFIELDLISTMODEL_H #define KEXIFIELDLISTMODEL_H #include "kexiextwidgets_export.h" #include class KDbConnection; class KDbTableOrQuerySchema; //! Flags used to alter models behaviour and appearance enum KexiFieldListOption { ShowDataTypes = 1, //!< if set, 'data type' column is added ShowAsterisk = 2, //!< if set, asterisk ('*') item is prepended to the list AllowMultiSelection = 4, //!< if set, multiple selection is allowed ShowEmptyItem = 8 //!< if set, an empty item is prepended to the list }; Q_DECLARE_FLAGS(KexiFieldListOptions, KexiFieldListOption) Q_DECLARE_OPERATORS_FOR_FLAGS(KexiFieldListOptions) Q_FLAGS(KexiFieldListOption) class KEXIEXTWIDGETS_EXPORT KexiFieldListModel : public QAbstractTableModel { Q_OBJECT public: explicit KexiFieldListModel(QObject* parent = 0, KexiFieldListOptions options = ShowDataTypes | AllowMultiSelection); virtual ~KexiFieldListModel(); /*! Sets table or query schema \a schema. The schema object will be owned by the KexiFieldListView object. */ void setSchema(KDbConnection *conn, KDbTableOrQuerySchema* schema); - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - virtual QStringList mimeTypes() const; - virtual QMimeData* mimeData(const QModelIndexList& indexes) const; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + virtual QStringList mimeTypes() const override; + virtual QMimeData* mimeData(const QModelIndexList& indexes) const override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; private: class Private; Private * const d; }; #endif // KEXIFIELDLISTMODEL_H diff --git a/src/widget/kexieditor.h b/src/widget/kexieditor.h index 70559ab10..49859a78b 100644 --- a/src/widget/kexieditor.h +++ b/src/widget/kexieditor.h @@ -1,123 +1,123 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2004-2005 Jarosław Staniek Copyright (C) 2005 Cedric Pasteur This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIEDITOR_H #define KEXIEDITOR_H #include "kexiextwidgets_export.h" #include namespace KTextEditor { class Document; } //! An text editor view that uses both KTextEditor and KTextEdit /*! It is used for SQL and script editor. */ class KEXIEXTWIDGETS_EXPORT KexiEditor : public KexiView { Q_OBJECT public: /** * Constructor. * * \param parent The parent \a QWidget this KexiEditor is child * of. You don't need to free the KexiEditor cause Qt * will handle that for us. * \param name The name this KexiEditor has. Used only for debugging. */ explicit KexiEditor(QWidget *parent = 0); /** * Destructor. */ virtual ~KexiEditor(); /** * \return true if internally the KTextEditor::EditorChooser got * used else, if a simple KTextEdit is used, false is returned. */ static bool isAdvancedEditor(); /** * \return the text displayed in the editor-widget. */ QString text(); /** * Set the highlight-mode to \p highlightmodename . If * \a isAdvancedEditor returns false (KTextEdit is used * rather then KTextEditor), then the method just does * nothing. The \p highlightmodename could be any kind * of string like e.g. "python", "kjs" or "sql" * KTextEditor supports. */ void setHighlightMode(const QString& highlightmodename); /** * Find row and column for this \p character and jump to the * position. */ void jump(int character); /** * Set the cursor position to \p line and \p col . */ void setCursorPosition(int line, int col); /** * Clear all remembered undo/redo-actions. Only * avaiable if \a isAdvancedEditor returns true. */ void clearUndoRedo(); /** * \return a default context menu implementation. */ virtual QMenu* defaultContextMenu(); public Q_SLOTS: /*! Sets editor's text to \a text. 'Dirty' flag remains unchanged. */ void setText(const QString &text); /*! Display the configuration-dialog. Only avaiable if isAdvancedEditor() returns true. */ void slotConfigureEditor(); protected Q_SLOTS: void slotTextChanged(KTextEditor::Document *); protected: /*! Update the actions. This call is redirected to \a KexiView::updateActions */ - virtual void updateActions(bool activated); + virtual void updateActions(bool activated) override; Q_SIGNALS: /*! Emitted if the text displayed in the editor changed. */ void textChanged(); private: /*! Private d-pointer class. */ class Private; Private * const d; }; #endif diff --git a/src/widget/kexisectionheader.h b/src/widget/kexisectionheader.h index 2a1688bfe..5bb292377 100644 --- a/src/widget/kexisectionheader.h +++ b/src/widget/kexisectionheader.h @@ -1,65 +1,65 @@ /* This file is part of the KDE project Copyright (C) 2004-2007 Jarosław Staniek 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 KEXISECTIONHEADER_H #define KEXISECTIONHEADER_H #include "kexiextwidgets_export.h" #include class QEvent; class QIcon; //! @short A section header widget acting as a splitter with caption and buttons /*! see KexiQueryDesignerGuiEditor for example use. */ class KEXIEXTWIDGETS_EXPORT KexiSectionHeader : public QWidget { Q_OBJECT public: KexiSectionHeader(const QString &caption, Qt::Orientation o, QWidget* parent = 0); virtual ~KexiSectionHeader(); //! Sets child widget wisible below (or on the right hand) of the section header. //! A widget previously set is removed from the layout. void setWidget(QWidget * widget); void addButton(const QIcon& icon, const QString& toolTip, const QObject * receiver, const char * member); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; void setCaption(const QString& caption); QString caption() const; public Q_SLOTS: void slotFocus(bool in); protected: - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; private: class Private; Private * const d; }; #endif diff --git a/src/widget/kexislider.cpp b/src/widget/kexislider.cpp index 681800bff..80e61b3d8 100644 --- a/src/widget/kexislider.cpp +++ b/src/widget/kexislider.cpp @@ -1,329 +1,329 @@ /* This file is part of the KDE project Copyright (C) 2012 Oleg Kukharchuk This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexislider.h" #include #include #include #include #include #include class Q_DECL_HIDDEN KexiSlider::Private { public: Private() {} Slider *slider; QSpinBox *spinBox; QBoxLayout *layout; }; class Slider : public QSlider { Q_OBJECT public: explicit Slider(QWidget *parent) : QSlider(parent) { } - QSize sizeHint() const + QSize sizeHint() const override { if (tickPosition() == QSlider::NoTicks) return QSlider::sizeHint(); // preserve space for labels QSize extra(0,0); QFontMetrics fm(font()); int h = fm.height() + 3; int w = fm.width(QString::number(maximum())) + 3; if (orientation() == Qt::Horizontal) { extra.setHeight(tickPosition() == QSlider::TicksBothSides ? h * 2 : h); } else { extra.setWidth(tickPosition() == QSlider::TicksBothSides ? w * 2 : w); } return QSlider::sizeHint() + extra; } protected: - virtual void paintEvent(QPaintEvent *ev) + virtual void paintEvent(QPaintEvent *ev) override { if (tickPosition() == QSlider::NoTicks) return QSlider::paintEvent(ev); QPainter p(this); QStyleOptionSlider option; initStyleOption(&option); const QSlider::TickPosition ticks( option.tickPosition ); const int available(style()->proxy()->pixelMetric(QStyle::PM_SliderSpaceAvailable, &option, this)); int interval = option.tickInterval; if( interval < 1 ) interval = option.pageStep; if( interval < 1 ) return; const QRect r(option.rect); const QPalette palette(option.palette); const int fudge(style()->proxy()->pixelMetric(QStyle::PM_SliderLength, &option, this) / 2); int current(option.minimum); int nextLabel = current; const QFontMetrics fm(fontMetrics()); int h = fm.height() + 3; int w = fm.width(QString::number(option.maximum)) + 3; if(availableproxy()->drawComplexControl(QStyle::CC_Slider, &option, &p, this); } }; KexiSlider::KexiSlider(QWidget *parent) : QWidget(parent) , d(new Private) { init(Qt::Horizontal); } KexiSlider::KexiSlider(Qt::Orientation orientation, QWidget *parent) : QWidget(parent) , d(new Private) { init(orientation); } void KexiSlider::init(Qt::Orientation orientation) { d->layout=new QBoxLayout(QBoxLayout::LeftToRight, this); d->layout->setSpacing(2); d->layout->setMargin(0); d->slider = new Slider(this); d->spinBox = new QSpinBox(this); d->spinBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); d->layout->addWidget(d->spinBox,0, Qt::AlignVCenter); d->layout->addWidget(d->slider,0, Qt::AlignVCenter); connect(d->slider, SIGNAL(valueChanged(int)), this, SIGNAL(valueChanged(int))); connect(d->slider, SIGNAL(sliderPressed()), this, SIGNAL(sliderPressed())); connect(d->slider, SIGNAL(sliderReleased()), this, SIGNAL(sliderReleased())); connect(d->slider, SIGNAL(valueChanged(int)), d->spinBox, SLOT(setValue(int))); connect(d->spinBox, SIGNAL(valueChanged(int)), d->slider, SLOT(setValue(int))); setMaximum(100); setOrientation(orientation); setTickPosition(QSlider::TicksAbove); } KexiSlider::~KexiSlider() { delete d; } void KexiSlider::setMinimum(int min) { d->spinBox->setMinimum(min); d->slider->setMinimum(min); } void KexiSlider::setMaximum(int max) { d->spinBox->setMaximum(max); d->slider->setMaximum(max); } void KexiSlider::setValue(int val) { d->slider->setValue(val); } int KexiSlider::minimum() const { return d->slider->minimum(); } int KexiSlider::maximum() const { return d->slider->maximum(); } int KexiSlider::value() const { return d->slider->value(); } void KexiSlider::setPageStep(int step) { d->slider->setPageStep(step); } int KexiSlider::pageStep() const { return d->slider->pageStep(); } void KexiSlider::setSingleStep(int step) { d->spinBox->setSingleStep(step); d->slider->setSingleStep(step); } int KexiSlider::singleStep() const { return d->slider->singleStep(); } void KexiSlider::setOrientation(Qt::Orientation o) { d->layout->removeWidget(d->spinBox); d->slider->setOrientation(o); if(o == Qt::Horizontal) d->layout->insertWidget(0, d->spinBox); else d->layout->addWidget(d->spinBox); updateLayout(); } Qt::Orientation KexiSlider::orientation() const { return d->slider->orientation(); } void KexiSlider::setTickInterval(int ti) { d->slider->setTickInterval(ti); } int KexiSlider::tickInterval() const { return d->slider->tickInterval(); } void KexiSlider::setTickPosition(QSlider::TickPosition pos) { d->slider->setTickPosition(pos); updateLayout(); } QSlider::TickPosition KexiSlider::tickPosition() const { return d->slider->tickPosition(); } void KexiSlider::setShowEditor(bool show) { d->spinBox->setVisible(show); } bool KexiSlider::showEditor() const { return d->spinBox->isVisible(); } void KexiSlider::updateLayout() { d->layout->setDirection(orientation() == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); if (tickPosition() == QSlider::TicksBothSides || tickPosition() == QSlider::NoTicks) { d->layout->setAlignment(d->slider, orientation() == Qt::Horizontal ? Qt::AlignVCenter :Qt::AlignHCenter); d->layout->setAlignment(d->spinBox, orientation() == Qt::Horizontal ? Qt::AlignVCenter :Qt::AlignHCenter); } else { if (orientation() == Qt::Horizontal) { d->layout->setAlignment(d->slider, tickPosition() == QSlider::TicksAbove ? Qt::AlignBottom : Qt::AlignTop); d->layout->setAlignment(d->spinBox, tickPosition() == QSlider::TicksAbove ? Qt::AlignBottom : Qt::AlignTop); } else { d->layout->setAlignment(d->slider, tickPosition() == QSlider::TicksLeft ? Qt::AlignRight : Qt::AlignLeft); d->layout->setAlignment(d->spinBox, tickPosition() == QSlider::TicksLeft ? Qt::AlignRight : Qt::AlignLeft); } } } #include "kexislider.moc" diff --git a/src/widget/navigator/KexiProjectItemDelegate.h b/src/widget/navigator/KexiProjectItemDelegate.h index e3aa7d48e..ab1a2c6c5 100644 --- a/src/widget/navigator/KexiProjectItemDelegate.h +++ b/src/widget/navigator/KexiProjectItemDelegate.h @@ -1,48 +1,48 @@ /* This file is part of the KDE project Copyright (C) 2011-2014 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 KEXIPROJECTITEMDELEGATE_H #define KEXIPROJECTITEMDELEGATE_H #include class KexiProject; //! @short Item delegate for the Kexi navigator tree view /*! It's currently needed to validate input when renaming items (KDbIdentifierValidator is used for this). @todo In the future custom painting and/or editing may be added through this delegate. */ class KexiProjectItemDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit KexiProjectItemDelegate(QObject *parent = 0); virtual ~KexiProjectItemDelegate(); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const override; virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const override; virtual QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const override; private: class Private; Private * const d; }; #endif // KEXIPROJECTITEMDELEGATE_H diff --git a/src/widget/navigator/KexiProjectModel.h b/src/widget/navigator/KexiProjectModel.h index bb17f6f4c..8320fd88a 100644 --- a/src/widget/navigator/KexiProjectModel.h +++ b/src/widget/navigator/KexiProjectModel.h @@ -1,116 +1,116 @@ /* This file is part of the KDE project Copyright (C) 2010-2011 Adam Pigg Copyright (C) 2010-2014 Jarosław Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 KEXIPROJECTMODEL_H #define KEXIPROJECTMODEL_H #include "kexiextwidgets_export.h" #include #include #include #include class KexiProjectModelItem; class KexiProject; class KEXIEXTWIDGETS_EXPORT KexiProjectModel : public QAbstractItemModel, public KexiSearchableModel { Q_OBJECT public: explicit KexiProjectModel(QObject* parent = 0); virtual ~KexiProjectModel(); enum ExtraRoles { SearchHighlight = Qt::UserRole + 0 //!< item is highlighted when corresponding global search //!< completion is highlighted }; KexiProject* project() const; void setProject(KexiProject* prj, const QString& itemsPartClass, QString* partManagerErrorMessages); QString itemsPartClass() const; //! @return number of objects int objectsCount() const; - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex& child) const; - virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; - virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const; - virtual Qt::ItemFlags flags(const QModelIndex& index) const; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + virtual QModelIndex parent(const QModelIndex& child) const override; + virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + virtual bool hasChildren(const QModelIndex& parent = QModelIndex()) const override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; void updateItemName(KexiPart::Item& item, bool dirty); QModelIndex indexFromItem(KexiProjectModelItem *item) const; KexiProjectModelItem *modelItemFromItem(const KexiPart::Item &item) const; KexiProjectModelItem *modelItemFromName(const QString &name) const; void clear(); //! @return index of first part item (looking from the top) or invalid item //! if there are no part items QModelIndex firstPartItem() const; //! Implemented for KexiSearchableModel - virtual int searchableObjectCount() const; + virtual int searchableObjectCount() const override; //! Implemented for KexiSearchableModel - virtual QModelIndex sourceIndexForSearchableObject(int objectIndex) const; + virtual QModelIndex sourceIndexForSearchableObject(int objectIndex) const override; //! Implemented for KexiSearchableModel - virtual QVariant searchableData(const QModelIndex &sourceIndex, int role) const; + virtual QVariant searchableData(const QModelIndex &sourceIndex, int role) const override; //! Implemented for KexiSearchableModel - virtual QString pathFromIndex(const QModelIndex &sourceIndex) const; + virtual QString pathFromIndex(const QModelIndex &sourceIndex) const override; //! Implemented for KexiSearchableModel - virtual bool highlightSearchableObject(const QModelIndex &index); + virtual bool highlightSearchableObject(const QModelIndex &index) override; //! Implemented for KexiSearchableModel - virtual bool activateSearchableObject(const QModelIndex &index); + virtual bool activateSearchableObject(const QModelIndex &index) override; QPersistentModelIndex itemWithSearchHighlight() const; bool renameItem(KexiPart::Item *item, const QString& newName); bool setItemCaption(KexiPart::Item *item, const QString& newCaption); public Q_SLOTS: void slotAddItem(KexiPart::Item *item); void slotRemoveItem(const KexiPart::Item &item); Q_SIGNALS: void renameItem(KexiPart::Item *item, const QString& newName, bool *succes); void changeItemCaption(KexiPart::Item *item, const QString& newCaption, bool *succes); void highlightSearchedItem(const QModelIndex &index); void activateSearchedItem(const QModelIndex &index); private: KexiProjectModelItem* addGroup(KexiPart::Info *info, KexiProjectModelItem *parent) const; KexiProjectModelItem* addItem(KexiPart::Info *info, KexiPart::Item *item, KexiProjectModelItem *parent) const; //! @return index of first part item within children of parentIndex (recursively) QModelIndex firstChildPartItem(const QModelIndex &parentIndex) const; class Private; Private * const d; }; #endif // KEXIPROJECTMODEL_H diff --git a/src/widget/navigator/KexiProjectNavigator.h b/src/widget/navigator/KexiProjectNavigator.h index fbf2f5df8..af2fe8f9e 100644 --- a/src/widget/navigator/KexiProjectNavigator.h +++ b/src/widget/navigator/KexiProjectNavigator.h @@ -1,211 +1,211 @@ /* This file is part of the KDE project Copyright (C) 2002, 2003 Lucijan Busch Copyright (C) 2003-2016 Jarosław Staniek Copyright (C) 2010 Adam Pigg 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 KEXIPROJECTNAVIGATOR_H #define KEXIPROJECTNAVIGATOR_H #include "kexiextwidgets_export.h" #include #include #include class QIcon; class QAction; class KActionCollection; class QModelIndex; class KexiProjectModel; namespace KexiPart { class Info; class Item; } class KexiProject; /*! @internal */ class KexiMenuBase : public QMenu { Q_OBJECT public: KexiMenuBase(QWidget *parent, KActionCollection *collection); ~KexiMenuBase(); QAction* addAction(const QString& actionName); protected: QPointer m_actionCollection; }; /*! @internal */ class KexiItemMenu : public KexiMenuBase { Q_OBJECT public: KexiItemMenu(QWidget *parent, KActionCollection *collection); ~KexiItemMenu(); //! Rebuilds the menu entirely using information obtained from \a partInfo //! and \a partItem. void update(const KexiPart::Info& partInfo, const KexiPart::Item& partItem); }; /*! @internal */ class KexiGroupMenu : public KexiMenuBase { Q_OBJECT public: KexiGroupMenu(QWidget *parent, KActionCollection *collection); ~KexiGroupMenu(); //! Rebuilds the menu entirely using information obtained from \a partInfo. void update(KexiPart::Info* partInfo); }; //! @short Project navigator widget //! It is also used to display list of objects for given database project in other places of Kexi. class KEXIEXTWIDGETS_EXPORT KexiProjectNavigator : public QWidget { Q_OBJECT public: enum Feature { NoFeatures = 0, Writable = 1, //!< Support actions that modify //!< the project (e.g. delete, rename). ContextMenus = 2, //!< Supports context menus Borders = 4, //!< Show borders like in a list view ClearSelectionAfterAction = 8, //!< Don't keep selection after item is open or executed AllowSingleClickForOpeningItems = 0x10, //!< Allow to use single click for opening //!< items (if this is the system setting). //!< Set it off to use single click only for //!< selecting items and double click for //!< opening items. DefaultFeatures = Writable | ContextMenus | ClearSelectionAfterAction | AllowSingleClickForOpeningItems //!< The default }; //! Specifies features of a navigator Q_DECLARE_FLAGS(Features, Feature) explicit KexiProjectNavigator(QWidget* parent, Features features = DefaultFeatures); virtual ~KexiProjectNavigator(); /*! Sets project \a prj for this browser. If \a partManagerErrorMessages is not NULL it will be set to error message if there's a problem with loading any KexiPart. If \a itemsPartClass is empty (the default), items of all part classes are displayed, items for only one part class are displayed. In the latter case, no group (parent) items are displayed. Previous items are removed. */ void setProject(KexiProject* prj, const QString& itemsPluginId = QString(), QString* partManagerErrorMessages = 0, bool addAsSearchableModel = true); /*! \return items' part class previously set by setProject. Returns empty string if setProject() was not executed yet or itemsPartClass argument of setProject() was empty (i.e. all part classes are displayed). */ QString itemsPluginId() const; //! @return selected part item or nullptr is no item is selected KexiPart::Item* selectedPartItem() const; //! @return part item which is highlighted because of global searching //! or nullptr is no item is highlighted KexiPart::Item* partItemWithSearchHighlight() const; bool actionEnabled(const QString& actionName) const; KexiProjectModel* model() const; public Q_SLOTS: virtual void setFocus(); void updateItemName(KexiPart::Item& item, bool dirty); void selectItem(KexiPart::Item& item); void clearSelection(); void clear(); //! Sets by main window to disable actions that may try to modify the project. //! Does not disable actions like opening objects. void setReadOnly(bool set); bool isReadOnly() const; Q_SIGNALS: void openItem(KexiPart::Item*, Kexi::ViewMode viewMode); /*! this signal is emitted when user double clicked (or single -depending on settings) or pressed return key on the part item. This signal differs from openItem() signal in that if the object is already opened in view mode other than \a viewMode, the mode is not changed. */ void openOrActivateItem(KexiPart::Item*, Kexi::ViewMode viewMode); void newItem(KexiPart::Info*); void removeItem(KexiPart::Item*); void selectionChanged(KexiPart::Item* item); void executeItem(KexiPart::Item*); void exportItemToClipboardAsDataTable(KexiPart::Item*); void exportItemToFileAsDataTable(KexiPart::Item*); void printItem(KexiPart::Item*); void pageSetupForItem(KexiPart::Item*); protected Q_SLOTS: void slotExecuteItem(const QModelIndex &item); void slotSelectionChanged(const QModelIndex& i); void slotNewObject(); void slotOpenObject(); void slotDesignObject(); void slotEditTextObject(); void slotRemove(); void slotCut(); void slotCopy(); void slotPaste(); void slotRename(); void slotExecuteObject(); void slotExportToClipboardAsDataTable(); void slotExportToFileAsDataTable(); void slotPrintObject(); void slotPageSetupForObject(); void slotUpdateEmptyStateLabel(); protected: void itemRenameDone(); QAction * addAction(const QString& name, const QIcon& icon, const QString& text, const QString& toolTip, const QString& whatsThis, const char* slot); - virtual void contextMenuEvent ( QContextMenuEvent *event ); + virtual void contextMenuEvent ( QContextMenuEvent *event ) override; private: class Private; Private * const d; }; Q_DECLARE_OPERATORS_FOR_FLAGS(KexiProjectNavigator::Features) #endif diff --git a/src/widget/navigator/KexiProjectTreeView.h b/src/widget/navigator/KexiProjectTreeView.h index 277465acd..2bbb27dba 100644 --- a/src/widget/navigator/KexiProjectTreeView.h +++ b/src/widget/navigator/KexiProjectTreeView.h @@ -1,54 +1,54 @@ /* This file is part of the KDE project Copyright (C) 2002, 2003 Lucijan Busch Copyright (C) 2003-2005 Jarosław Staniek 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 KEXIPROJECTTREEVIEW_H #define KEXIPROJECTTREEVIEW_H #include #include namespace KexiPart { class Item; class Part; } class KexiProjectModel; /*! @internal A tree view for project navigator widget */ class KexiProjectTreeView : public QTreeView { Q_OBJECT public: explicit KexiProjectTreeView(QWidget *parent = 0); virtual ~KexiProjectTreeView(); using QTreeView::setModel; void setModel(KexiProjectModel *model); protected: virtual void drawBranches(QPainter *painter, const QRect &rect, - const QModelIndex &index) const; + const QModelIndex &index) const override; protected Q_SLOTS: void slotHighlightSearchedItem(const QModelIndex &index); void slotActivateSearchedItem(const QModelIndex &index); }; #endif diff --git a/src/widget/properties/KexiCustomPropertyFactory.cpp b/src/widget/properties/KexiCustomPropertyFactory.cpp index c7f11992a..54bd7dd85 100644 --- a/src/widget/properties/KexiCustomPropertyFactory.cpp +++ b/src/widget/properties/KexiCustomPropertyFactory.cpp @@ -1,166 +1,166 @@ /* This file is part of the KDE project Copyright (C) 2005-2008 Jarosław Staniek 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. */ #include "KexiCustomPropertyFactory.h" #include "KexiCustomPropertyFactory_p.h" #include #include #include #include //! @todo KEXI3 #include #include #if 0 //! @internal class PixmapIdCustomProperty : public KCustomProperty { public: explicit PixmapIdCustomProperty(Property *parent) : KCustomProperty(parent) { } virtual ~PixmapIdCustomProperty() {} virtual void setValue(const QVariant &value, bool rememberOldValue) { Q_UNUSED(value); Q_UNUSED(rememberOldValue); } virtual QVariant value() const { return m_property->value(); } virtual bool handleValue() const { return false; } }; //! @internal class IdentifierCustomProperty : public KCustomProperty { public: explicit IdentifierCustomProperty(Property *parent) : KCustomProperty(parent) { } virtual ~IdentifierCustomProperty() {} virtual void setValue(const QVariant &value, bool rememberOldValue) { Q_UNUSED(rememberOldValue); if (!value.toString().isEmpty()) m_value = KDb::stringToIdentifier(value.toString()).toLower(); } virtual QVariant value() const { return m_value; } virtual bool handleValue() const { return true; } QString m_value; }; #endif //! @todo #if 0 //TODO class KexiImagePropertyEditorDelegate : public KPropertyEditorCreatorInterface, public KPropertyValuePainterInterface { public: KexiImagePropertyEditorDelegate() {} virtual QWidget * createEditor( int type, QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const; virtual void paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; }; #endif class KexiIdentifierPropertyEditorDelegate : public KPropertyStringDelegate { public: KexiIdentifierPropertyEditorDelegate() {} virtual QWidget * createEditor( int type, QWidget *parent, - const QStyleOptionViewItem & option, const QModelIndex & index ) const + const QStyleOptionViewItem & option, const QModelIndex & index ) const override { Q_UNUSED(type); Q_UNUSED(option); Q_UNUSED(index); return new KexiIdentifierPropertyEditor(parent); } }; class KexiImagePropertyEditorDelegate : public KPropertyPixmapDelegate { public: KexiImagePropertyEditorDelegate() { } virtual QWidget *createEditor(int type, QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const + const QModelIndex &index) const override { Q_UNUSED(type); Q_UNUSED(option); KProperty *property = KPropertyUtils::propertyForIndex(index); if (!property) { return nullptr; } return new KexiImagePropertyEditor(property, parent); } }; //--------------- KexiImagePropertyEditor::KexiImagePropertyEditor(KProperty *prop, QWidget *parent) : KPropertyPixmapEditor(prop, parent) { } KexiImagePropertyEditor::~KexiImagePropertyEditor() { } void KexiImagePropertyEditor::selectPixmap() { const QUrl url = KexiUtils::getOpenImageUrl(parentWidget()); if (!url.isLocalFile()) { //! @todo err msg return; } QPixmap pixmap; if (!pixmap.load(url.toLocalFile())) { //! @todo err msg return; } setValue(pixmap); } //--------------- KexiCustomPropertyFactory::KexiCustomPropertyFactory() : KPropertyWidgetsFactory() { addEditor(KexiCustomPropertyFactory::PixmapId, new KexiImagePropertyEditorDelegate); addEditor( KexiCustomPropertyFactory::Identifier, new KexiIdentifierPropertyEditorDelegate ); } void KexiCustomPropertyFactory::init() { if (KPropertyWidgetsPluginManager::self()->isEditorForTypeAvailable( KexiCustomPropertyFactory::Identifier)) { return; //already registered } KPropertyWidgetsPluginManager::self()->registerFactory( new KexiCustomPropertyFactory ); } diff --git a/src/widget/properties/KexiPropertyEditorView.h b/src/widget/properties/KexiPropertyEditorView.h index f3dc29831..07c7bfe3e 100644 --- a/src/widget/properties/KexiPropertyEditorView.h +++ b/src/widget/properties/KexiPropertyEditorView.h @@ -1,63 +1,63 @@ /* This file is part of the KDE project Copyright (C) 2004 Cedric Pasteur Copyright (C) 2004-2009 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIPROPERTYEDITORVIEW_H #define KEXIPROPERTYEDITORVIEW_H #include "kexiextwidgets_export.h" #include "KexiPropertyPaneViewBase.h" #include //! @short The container (acts as a dock window) for KexiPropertyEditor. /*! The widget displays KexiObjectInfoLabel on its top, to show user what object the properties belong to. Read KexiObjectInfoLabel documentation for the description what information is displayed. There are properties obtained from KexiMainWindow's current property set that help to customize displaying this information: - "this:classString property" of type string describes object's class name - "this:iconName" property of type string describes class name - "name" or "caption" property of type string describes object's name - "this:useCaptionAsObjectName" property of type boolean forces displaying "caption" property instead of "name" - this can be usable when we know that "caption" properties are available for a given type of objects (this is the case for Table Designer fields) */ class KEXIEXTWIDGETS_EXPORT KexiPropertyEditorView : public KexiPropertyPaneViewBase { Q_OBJECT public: explicit KexiPropertyEditorView(QWidget* parent); virtual ~KexiPropertyEditorView(); - virtual QSize sizeHint() const; - virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const override; + virtual QSize minimumSizeHint() const override; KPropertyEditorView *editor() const; protected Q_SLOTS: void slotPropertySetChanged(KPropertySet*); protected: class Private; Private * const d; }; #endif diff --git a/src/widget/relations/KexiRelationsScrollArea.cpp b/src/widget/relations/KexiRelationsScrollArea.cpp index f22581586..2bd70af14 100644 --- a/src/widget/relations/KexiRelationsScrollArea.cpp +++ b/src/widget/relations/KexiRelationsScrollArea.cpp @@ -1,621 +1,621 @@ /* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KexiRelationsScrollArea.h" #include "KexiRelationsView.h" #include "KexiRelationsConnection.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include //! @internal class Q_DECL_HIDDEN KexiRelationsScrollArea::Private { public: Private() : readOnly(false) , selectedConnection(0) , focusedTableContainer(0) { autoScrollTimer.setSingleShot(true); } KDbConnection *connection = nullptr; QWidget *areaWidget; TablesHash tables; bool readOnly; QSet relationsConnections; KexiRelationsConnection* selectedConnection; QPointer focusedTableContainer; QPointer movedTableContainer; QTimer autoScrollTimer; }; //------------- //! @internal scroll area widget that draws connections class KexiRelationsScrollAreaWidget : public QWidget { Q_OBJECT public: explicit KexiRelationsScrollAreaWidget(KexiRelationsScrollArea* parent); ~KexiRelationsScrollAreaWidget(); protected: - virtual void paintEvent(QPaintEvent *event); - virtual void mousePressEvent(QMouseEvent *ev); + virtual void paintEvent(QPaintEvent *event) override; + virtual void mousePressEvent(QMouseEvent *ev) override; private: KexiRelationsScrollArea *scrollArea() { return static_cast(parentWidget()->parentWidget()); } }; KexiRelationsScrollAreaWidget::KexiRelationsScrollAreaWidget( KexiRelationsScrollArea* parent) : QWidget(parent) { setAutoFillBackground(true); setBackgroundRole(QPalette::Mid); resize(10240, 7680); } KexiRelationsScrollAreaWidget::~KexiRelationsScrollAreaWidget() { } void KexiRelationsScrollAreaWidget::paintEvent(QPaintEvent *event) { scrollArea()->handlePaintEvent(event); } void KexiRelationsScrollAreaWidget::mousePressEvent(QMouseEvent *ev) { scrollArea()->handleMousePressEvent(ev); QWidget::mousePressEvent(ev); } //------------- KexiRelationsScrollArea::KexiRelationsScrollArea(QWidget *parent) : QScrollArea(parent) , d(new Private) { d->areaWidget = new KexiRelationsScrollAreaWidget(this); setWidget(d->areaWidget); setFocusPolicy(Qt::WheelFocus); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); #if 0 d->removeSelectedTableQueryAction = new QAction(xi18n("&Hide Selected Table/Query"), "edit-delete", "", this, SLOT(removeSelectedTableQuery()), parent->actionCollection(), "relationsview_removeSelectedTableQuery"); d->removeSelectedConnectionAction = new QAction(xi18n("&Delete Selected Relationship"), "dialog-cancel", "", this, SLOT(removeSelectedConnection()), parent->actionCollection(), "relationsview_removeSelectedConnection"); d->openSelectedTableQueryAction = new QAction(xi18n("&Open Selected Table/Query"), "", "", this, SLOT(openSelectedTableQuery()), 0/*parent->actionCollection()*/, "relationsview_openSelectedTableQuery"); #endif #if 0 d->popup = new QMenu(this, "popup"); d->openSelectedTableQueryAction->plug(d->popup); d->removeSelectedTableQueryAction->plug(d->popup); d->removeSelectedConnectionAction->plug(d->popup); invalidateActions(); #endif setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); //true); connect(&d->autoScrollTimer, SIGNAL(timeout()), this, SLOT(slotAutoScrollTimeout())); } KexiRelationsScrollArea::~KexiRelationsScrollArea() { clearSelection(); //sanity qDeleteAll(d->relationsConnections); d->relationsConnections.clear(); delete d; } KexiRelationsTableContainer * KexiRelationsScrollArea::tableContainer(KDbTableSchema *t) const { return t ? d->tables.value(t->name()) : 0; } KexiRelationsTableContainer* KexiRelationsScrollArea::addTableContainer(KDbTableSchema *t, const QRect &rect) { if (!t || !d->connection) return 0; qDebug() << t->name(); KexiRelationsTableContainer* c = tableContainer(t); if (c) { qWarning() << "table already added"; return c; } c = new KexiRelationsTableContainer(this, d->connection, /*! @todo what about query? */ new KDbTableOrQuerySchema(t), d->areaWidget); connect(c, SIGNAL(endDrag()), this, SLOT(slotTableViewEndDrag())); connect(c, SIGNAL(gotFocus()), this, SLOT(slotTableViewGotFocus())); connect(c, SIGNAL(contextMenuRequest(QPoint)), this, SIGNAL(tableContextMenuRequest(QPoint))); if (rect.isValid()) {//predefined size QSize finalSize = c->size().expandedTo(c->sizeHint()); QRect r = rect; r.setSize(finalSize + QSize(0, 10)); c->move(rect.left(), rect.top()); //we're doing this instead of setGeometry(rect) //because the geomenty might be saved on other system with bigger fonts :) c->resize(c->sizeHint()); } else { c->move(100, 100); } updateGeometry(); if (!rect.isValid()) { c->updateGeometry(); c->resize(c->sizeHint()); } int x, y; if (d->tables.count() > 0) { int place = -10; foreach(KexiRelationsTableContainer* container, d->tables) { int right = container->x() + container->width(); if (right > place) place = right; } x = place + 30; } else { x = 5; } y = 5; if (!rect.isValid()) { c->move(x, y); } d->tables.insert(t->name(), c); connect(c, SIGNAL(moved(KexiRelationsTableContainer*)), this, SLOT(containerMoved(KexiRelationsTableContainer*))); c->show(); if (hasFocus()) //ok? c->setFocus(); return c; } void KexiRelationsScrollArea::addConnection(const SourceConnection& _conn) { SourceConnection conn = _conn; KexiRelationsTableContainer *master = d->tables[conn.masterTable]; KexiRelationsTableContainer *details = d->tables[conn.detailsTable]; if (!master || !details) return; /*! @todo what about query? */ KDbTableSchema *masterTable = master->schema()->table(); /*! @todo what about query? */ KDbTableSchema *detailsTable = details->schema()->table(); if (!masterTable || !detailsTable) return; // ok, but we need to know where is the 'master' and where is the 'details' side: KDbField *masterFld = masterTable->field(conn.masterField); KDbField *detailsFld = detailsTable->field(conn.detailsField); if (!masterFld || !detailsFld) return; if (!masterFld->isUniqueKey()) { if (detailsFld->isUniqueKey()) { //SWAP: KDbField *tmpFld = masterFld; masterFld = detailsFld; detailsFld = tmpFld; KDbTableSchema *tmpTable = masterTable; masterTable = detailsTable; detailsTable = tmpTable; KexiRelationsTableContainer *tmp = master; master = details; details = tmp; QString tmp_masterTable = conn.masterTable; conn.masterTable = conn.detailsTable; conn.detailsTable = tmp_masterTable; QString tmp_masterField = conn.masterField; conn.masterField = conn.detailsField; conn.detailsField = tmp_masterField; } } // qDebug() << "finalSRC =" << d->tables[conn.srcTable]; KexiRelationsConnection *connView = new KexiRelationsConnection(master, details, conn, this); d->relationsConnections.insert(connView); qDebug() << "connView->connectionRect() " << connView->connectionRect(); d->areaWidget->update(); /*! @todo will be moved up to relation/query part as this is only visual class KDbTableSchema *mtable = d->conn->tableSchema(conn.srcTable); KDbTableSchema *ftable = d->conn->tableSchema(conn.rcvTable); KDbIndexSchema *forign = new KDbIndexSchema; ftable->addIndex(forign); forign->addField(mtable->field(conn.srcField)); new KDbReference(forign, mtable->primaryKey()); */ #if 0 if (!interactive) { qDebug() << "adding self"; RelationList l = d->relation->projectRelations(); l.append(conn); d->relation->updateRelationList(this, l); } #endif } void KexiRelationsScrollArea::containerMoved(KexiRelationsTableContainer *c) { d->movedTableContainer = c; QRect r; foreach(KexiRelationsConnection* cview, d->relationsConnections) { //! @todo optimize if (cview->masterTable() == c || cview->detailsTable() == c || cview->connectionRect().intersects(r)) { r |= cview->oldRect(); //qDebug() << r; r |= cview->connectionRect(); //qDebug() << r; } } //! @todo optimize! //scroll if needed: if (horizontalScrollBar()->maximum() > c->geometry().right()) { bool beyondBorder = c->geometry().left() > (horizontalScrollBar()->value() + width() - verticalScrollBar()->width()); if (!d->autoScrollTimer.isActive()) { if (beyondBorder) { d->autoScrollTimer.setInterval(200); d->autoScrollTimer.start(); // horizontalScrollBar()->setValue( horizontalScrollBar()->value() + 50 ); } } else { if (!beyondBorder) { d->autoScrollTimer.stop(); } } } else d->autoScrollTimer.stop(); d->areaWidget->update(); emit tablePositionChanged(c); } void KexiRelationsScrollArea::slotAutoScrollTimeout() { int delay = 100; if (d->movedTableContainer) { delay = qMin( 100, 100 - (d->movedTableContainer->geometry().left() - (horizontalScrollBar()->value() + width() - verticalScrollBar()->width())) ); if (delay < 0) delay = 0; delay = delay * delay / 100; qDebug() << delay; int add = 16; if (horizontalScrollBar()->maximum() > (d->movedTableContainer->geometry().right() + add)) { horizontalScrollBar()->setValue(horizontalScrollBar()->value() + add); d->movedTableContainer->move(d->movedTableContainer->x() + add, d->movedTableContainer->y()); } } d->areaWidget->update(); if (d->movedTableContainer) { d->autoScrollTimer.setInterval(delay); d->autoScrollTimer.start(); } } void KexiRelationsScrollArea::setReadOnly(bool b) { d->readOnly = b; //! @todo } void KexiRelationsScrollArea::slotListUpdate(QObject *) { #if 0 if (s != this) { d->connectionViews.clear(); RelationList rl = d->relation->projectRelations(); if (!rl.isEmpty()) { RelationList::ConstIterator it, end(rl.constEnd()); for (it = rl.begin(); it != end; ++it) { addConnection((*it), true); } } } updateContents(); #endif } void KexiRelationsScrollArea::handleMousePressEvent(QMouseEvent *ev) { foreach(KexiRelationsConnection* cview, d->relationsConnections) { if (!cview->matchesPoint(ev->pos(), 3)) continue; clearSelection(); setFocus(); cview->setSelected(true); d->areaWidget->update(cview->connectionRect()); d->selectedConnection = cview; emit connectionViewGotFocus(); if (ev->button() == Qt::RightButton) {//show popup qDebug() << "context"; emit connectionContextMenuRequest(ev->globalPos()); } return; } //connection not found clearSelection(); if (ev->button() == Qt::RightButton) {//show popup on view background area emit emptyAreaContextMenuRequest(ev->globalPos()); } else { emit emptyAreaGotFocus(); } setFocus(); } void KexiRelationsScrollArea::handlePaintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(d->areaWidget); p.setWindow( horizontalScrollBar() ? horizontalScrollBar()->value() : 0, verticalScrollBar() ? verticalScrollBar()->value() : 0, d->areaWidget->width(), d->areaWidget->height()); QRect clipping( horizontalScrollBar() ? horizontalScrollBar()->value() : 0, verticalScrollBar() ? verticalScrollBar()->value() : 0, width(), height()); foreach(KexiRelationsConnection *cview, d->relationsConnections) { cview->drawConnection(&p); } } void KexiRelationsScrollArea::clearSelection() { if (d->focusedTableContainer) { d->focusedTableContainer->unsetFocus(); d->focusedTableContainer = 0; } if (d->selectedConnection) { d->selectedConnection->setSelected(false); d->areaWidget->update(d->selectedConnection->connectionRect()); d->selectedConnection = 0; } } void KexiRelationsScrollArea::contextMenuEvent(QContextMenuEvent* event) { Q_UNUSED(event); if (d->selectedConnection) { emit connectionContextMenuRequest( mapToGlobal(d->selectedConnection->connectionRect().center())); } } void KexiRelationsScrollArea::keyPressEvent(QKeyEvent *ev) { if (ev->key() == Qt::Key_Delete) { removeSelectedObject(); } } void KexiRelationsScrollArea::slotTableViewEndDrag() { qDebug() << "END DRAG!"; d->autoScrollTimer.stop(); } void KexiRelationsScrollArea::removeSelectedObject() { if (d->selectedConnection) { KexiRelationsConnection* tmp = d->selectedConnection; d->selectedConnection = 0; removeConnection(tmp); #if 0 RelationList l = d->relation->projectRelations(); RelationList nl; for (RelationList::Iterator it = l.begin(); it != l.end(); ++it) { if ((*it).srcTable == d->selectedConnection->connection().srcTable && (*it).rcvTable == d->selectedConnection->connection().rcvTable && (*it).srcField == d->selectedConnection->connection().srcField && (*it).rcvField == d->selectedConnection->connection().rcvField) { qDebug() << "matching found!"; } else { nl.append(*it); } } d->relation->updateRelationList(this, nl); #endif } else if (d->focusedTableContainer) { KexiRelationsTableContainer *tmp = d->focusedTableContainer; d->focusedTableContainer = 0; hideTable(tmp); } } void KexiRelationsScrollArea::setConnection(KDbConnection *conn) { d->connection = conn; } void KexiRelationsScrollArea::hideTable(KexiRelationsTableContainer* container) { Q_ASSERT(container); /*! @todo what about query? */ TablesHashMutableIterator it(d->tables); if (!it.findNext(container)) return; hideTableInternal(&it); } void KexiRelationsScrollArea::hideTableInternal(TablesHashMutableIterator* it) { Q_ASSERT(it); KexiRelationsTableContainer* container = it->value(); KDbTableSchema *ts = container->schema()->table(); //for all connections: find and remove all connected with this table for (ConnectionSetMutableIterator itConn(d->relationsConnections);itConn.hasNext();) { KexiRelationsConnection* conn = itConn.next(); if (conn->masterTable() == container || conn->detailsTable() == container) { //remove this removeConnectionInternal(&itConn); } } it->remove(); container->deleteLater(); emit tableHidden(ts); } void KexiRelationsScrollArea::hideAllTablesExcept(QList* tables) { Q_ASSERT(tables); //! @todo what about queries? for (TablesHashMutableIterator it(d->tables); it.hasNext();) { it.next(); KDbTableSchema *table = it.value()->schema()->table(); if (!table || tables->contains(table)) continue; hideTableInternal(&it); } } void KexiRelationsScrollArea::removeConnection(KexiRelationsConnection *conn) { Q_ASSERT(conn); ConnectionSetMutableIterator it(d->relationsConnections); if (!it.findNext(conn)) return; removeConnectionInternal(&it); } void KexiRelationsScrollArea::removeConnectionInternal(ConnectionSetMutableIterator* it) { Q_ASSERT(it); KexiRelationsConnection *conn = it->value(); emit aboutConnectionRemove(conn); it->remove(); d->areaWidget->update(conn->connectionRect()); delete conn; } void KexiRelationsScrollArea::slotTableViewGotFocus() { if (d->focusedTableContainer == sender()) return; qDebug() << "GOT FOCUS!"; clearSelection(); d->focusedTableContainer = (KexiRelationsTableContainer*)sender(); emit tableViewGotFocus(); } QSize KexiRelationsScrollArea::sizeHint() const { return QSize(QScrollArea::sizeHint()); } void KexiRelationsScrollArea::clear() { removeAllConnections(); qDeleteAll(d->tables); d->tables.clear(); d->areaWidget->update(); } void KexiRelationsScrollArea::removeAllConnections() { clearSelection(); //sanity qDeleteAll(d->relationsConnections); d->relationsConnections.clear(); d->areaWidget->update(); } TablesHash* KexiRelationsScrollArea::tables() const { return &d->tables; } KexiRelationsConnection* KexiRelationsScrollArea::selectedConnection() const { return d->selectedConnection; } KexiRelationsTableContainer* KexiRelationsScrollArea::focusedTableContainer() const { return d->focusedTableContainer; } const QSet* KexiRelationsScrollArea::relationsConnections() const { return &d->relationsConnections; } #include "KexiRelationsScrollArea.moc" diff --git a/src/widget/relations/KexiRelationsScrollArea.h b/src/widget/relations/KexiRelationsScrollArea.h index e9d467e1f..7ebb4b45f 100644 --- a/src/widget/relations/KexiRelationsScrollArea.h +++ b/src/widget/relations/KexiRelationsScrollArea.h @@ -1,158 +1,158 @@ /* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIRELATIONSSCROLLAREA_H #define KEXIRELATIONSSCROLLAREA_H #include #include #include #include #include #include #include #include #include "KexiRelationsConnection.h" #include "KexiRelationsTableContainer.h" class KDbConnection; typedef QHash TablesHash; typedef QMutableHashIterator TablesHashMutableIterator; typedef QHash::ConstIterator TablesHashConstIterator; typedef QMutableSetIterator ConnectionSetMutableIterator; typedef QSet::ConstIterator ConnectionSetIterator; //! A data structure describing connection struct SourceConnection { QString masterTable; QString detailsTable; QString masterField; QString detailsField; }; /*! @short Provides a view for displaying relations between database tables. It is currently used for two purposes: - displaying global database relations - displaying relations defined for a database query The class is for displaying only - retrieving data and updating data on the backend side is implemented in KexiRelationWidget, and more specifically in: Kexi Relation Part and Kexi Query Part. */ class KEXIRELATIONSVIEW_EXPORT KexiRelationsScrollArea : public QScrollArea { Q_OBJECT public: explicit KexiRelationsScrollArea(QWidget *parent = 0); virtual ~KexiRelationsScrollArea(); //! \return a hash of added tables TablesHash* tables() const; /*! Adds a table \a t to the area. This changes only visual representation. If \a rect is valid, table widget geometry will be initialized. \return added table container or 0 on failure. */ KexiRelationsTableContainer* addTableContainer(KDbTableSchema *t, const QRect &rect = QRect()); /*! \return table container for table \a t. */ KexiRelationsTableContainer * tableContainer(KDbTableSchema *t) const; //! Adds a connection \a _conn to the area. This changes only visual representation. void addConnection(const SourceConnection& _conn); void setReadOnly(bool); KexiRelationsConnection* selectedConnection() const; KexiRelationsTableContainer* focusedTableContainer() const; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; const QSet* relationsConnections() const; //! @internal Handles mouse press event for area widget void handleMousePressEvent(QMouseEvent *ev); //! @internal Handles paint event for area widget void handlePaintEvent(QPaintEvent *event); Q_SIGNALS: void tableContextMenuRequest(const QPoint& pos); void connectionContextMenuRequest(const QPoint& pos); void emptyAreaContextMenuRequest(const QPoint& pos); void tableViewGotFocus(); void connectionViewGotFocus(); void emptyAreaGotFocus(); void tableHidden(KDbTableSchema* t); void tablePositionChanged(KexiRelationsTableContainer*); void aboutConnectionRemove(KexiRelationsConnection*); public Q_SLOTS: //! Clears current selection - table/query or connection void clearSelection(); /*! Removes all tables and connections from the view. Does not emit signals like tableHidden(). */ void clear(); /*! Removes all connections from the view. */ void removeAllConnections(); /*! Hides all tables except \a tables. */ void hideAllTablesExcept(QList* tables); //! removes selected table or connection void removeSelectedObject(); void setConnection(KDbConnection *conn); protected Q_SLOTS: void containerMoved(KexiRelationsTableContainer *c); void slotListUpdate(QObject *s); void slotTableViewEndDrag(); void slotTableViewGotFocus(); void slotAutoScrollTimeout(); protected: void contentsMousePressEvent(QMouseEvent *ev); - virtual void keyPressEvent(QKeyEvent *ev); - virtual void contextMenuEvent(QContextMenuEvent* event); + virtual void keyPressEvent(QKeyEvent *ev) override; + virtual void contextMenuEvent(QContextMenuEvent* event) override; void hideTable(KexiRelationsTableContainer* tableView); void removeConnection(KexiRelationsConnection *conn); //! Removes current value of iterator \a it, also deleted the container object. void hideTableInternal(TablesHashMutableIterator* it); //! Removes current value of iterator \a it, also deleted the connection object. void removeConnectionInternal(ConnectionSetMutableIterator* it); private: class Private; Private* const d; }; #endif diff --git a/src/widget/relations/KexiRelationsTableContainer.h b/src/widget/relations/KexiRelationsTableContainer.h index c18c06510..6afebc1cc 100644 --- a/src/widget/relations/KexiRelationsTableContainer.h +++ b/src/widget/relations/KexiRelationsTableContainer.h @@ -1,89 +1,89 @@ /* This file is part of the KDE project Copyright (C) 2002, 2003 Lucijan Busch Copyright (C) 2003-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIRELATIONSTABLECONTAINER_H #define KEXIRELATIONSTABLECONTAINER_H #include "kexirelationsview_export.h" #include #include #include class KDbTableOrQuerySchema; class KexiRelationsScrollArea; class KexiRelationViewTable; class KexiRelationViewTableContainerHeader; //! @short Provides a frame displaying single table or query in relation view. class KEXIRELATIONSVIEW_EXPORT KexiRelationsTableContainer : public QFrame { Q_OBJECT public: KexiRelationsTableContainer(KexiRelationsScrollArea *scrollArea, KDbConnection *conn, KDbTableOrQuerySchema *schema, QWidget *parent = nullptr); virtual ~KexiRelationsTableContainer(); int globalY(const QString &field); KDbTableOrQuerySchema* schema() const; int right() const { return x() + width() - 1; } int bottom() const { return y() + height() - 1; } /*! \return list of selected field names. */ QStringList selectedFieldNames() const; Q_SIGNALS: void moved(KexiRelationsTableContainer *); void endDrag(); void gotFocus(); void contextMenuRequest(const QPoint& pos); void fieldsDoubleClicked(KDbTableOrQuerySchema& tableOrQuery, const QStringList& fieldNames); public Q_SLOTS: void setFocus(); void unsetFocus(); protected Q_SLOTS: void moved(); void slotContextMenu(const QPoint& p); void slotFieldsDoubleClicked(const QModelIndex &idx); friend class KexiRelationViewTableContainerHeader; protected: - virtual void focusInEvent(QFocusEvent* event); - virtual void focusOutEvent(QFocusEvent* event); + virtual void focusInEvent(QFocusEvent* event) override; + virtual void focusOutEvent(QFocusEvent* event) override; private: class Private; Private* const d; }; #endif diff --git a/src/widget/relations/KexiRelationsTableContainer_p.h b/src/widget/relations/KexiRelationsTableContainer_p.h index f0c74829e..6bba473a4 100644 --- a/src/widget/relations/KexiRelationsTableContainer_p.h +++ b/src/widget/relations/KexiRelationsTableContainer_p.h @@ -1,96 +1,96 @@ /* This file is part of the KDE project Copyright (C) 2002, 2003 Lucijan Busch Copyright (C) 2003-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KexiRelationsTableContainer_P_H #define KexiRelationsTableContainer_P_H #include #include #include #include #include class KexiRelationsScrollArea; class KexiRelationViewTable; class KexiRelationViewTableContainerHeader; class KDbTableOrQuerySchema; //! @internal A field list widget used in table container to show fields class KexiRelationsTableFieldList : public KexiFieldListView { Q_OBJECT public: KexiRelationsTableFieldList(KDbConnection *conn, KDbTableOrQuerySchema* tableOrQuerySchema, KexiRelationsScrollArea *scrollArea, QWidget *parent = nullptr); virtual ~KexiRelationsTableFieldList(); int globalY(const QString &item); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; Q_SIGNALS: void tableScrolling(); protected Q_SLOTS: void slotContentsMoving(); protected: - virtual void dragEnterEvent(QDragEnterEvent* event); - virtual void dragMoveEvent(QDragMoveEvent* e); - virtual void dropEvent(QDropEvent *e); + virtual void dragEnterEvent(QDragEnterEvent* event) override; + virtual void dragMoveEvent(QDragMoveEvent* e) override; + virtual void dropEvent(QDropEvent *e) override; virtual void contentsMousePressEvent(QMouseEvent * e); - virtual bool eventFilter(QObject *o, QEvent *ev); + virtual bool eventFilter(QObject *o, QEvent *ev) override; private: KexiRelationsScrollArea *m_scrollArea; }; //! @internal A header widget used in table container class KexiRelationViewTableContainerHeader : public QLabel { Q_OBJECT public: explicit KexiRelationViewTableContainerHeader(const QString& text, QWidget *parent = 0); virtual ~KexiRelationViewTableContainerHeader(); virtual void setFocus(); virtual void unsetFocus(); Q_SIGNALS: void moved(); void endDrag(); protected: - bool eventFilter(QObject *obj, QEvent *ev); - void mousePressEvent(QMouseEvent *ev); - void mouseReleaseEvent(QMouseEvent *ev); + bool eventFilter(QObject *obj, QEvent *ev) override; + void mousePressEvent(QMouseEvent *ev) override; + void mouseReleaseEvent(QMouseEvent *ev) override; bool m_dragging; int m_grabX; int m_grabY; int m_offsetX; int m_offsetY; QColor m_activeBG, m_activeFG, m_inactiveBG, m_inactiveFG; }; #endif diff --git a/src/widget/relations/KexiRelationsView.h b/src/widget/relations/KexiRelationsView.h index e57e224c3..70ec8e3b5 100644 --- a/src/widget/relations/KexiRelationsView.h +++ b/src/widget/relations/KexiRelationsView.h @@ -1,123 +1,123 @@ /* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003-2007 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIRELATIONSVIEW_H #define KEXIRELATIONSVIEW_H #include "KexiRelationsScrollArea.h" #include class KDbConnection; class KDbTableSchema; class KDbTableOrQuerySchema; //! A Kexi view for displaying relationships. /*! It is used for within Query Designer Note: it will be also reused in Database Relationships view. */ class KEXIRELATIONSVIEW_EXPORT KexiRelationsView : public KexiView { Q_OBJECT public: explicit KexiRelationsView(QWidget *parent = 0); virtual ~KexiRelationsView(); //! Sets database connection @a conn for which tables and connections will be displayed. //! If @a conn is 0, contents is cleared. //! @return true on successfull retrieval of table and relation information. //! On failure result is available at conn->result() and KdbMessageGuard can be used. bool setConnection(KDbConnection *conn); //! \return a hash of added tables TablesHash* tables() const; KexiRelationsTableContainer* table(const QString& name) const; const QSet* relationsConnections() const; void addTable(const QString& t); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; /*! Used to add newly created object information to the combo box. */ void objectCreated(const QString &mime, const QString& name); void objectDeleted(const QString &mime, const QString& name); void objectRenamed(const QString &mime, const QString& name, const QString& newName); Q_SIGNALS: void tableAdded(KDbTableSchema* t); void tableHidden(KDbTableSchema* t); void tablePositionChanged(KexiRelationsTableContainer*); void aboutConnectionRemove(KexiRelationsConnection*); void appendFields(KDbTableOrQuerySchema& tableOrQuery, const QStringList& fieldNames); public Q_SLOTS: /*! Adds a table \a t to the area. This changes only visual representation. If \a rect is valid, table widget rgeometry will be initialized. */ void addTable(KDbTableSchema *t, const QRect &rect = QRect()); //! Adds a connection \a conn to the area. This changes only visual representation. void addConnection(const SourceConnection& conn); void removeSelectedObject(); /*! Removes all tables and connections from the widget and refreshes the connection assignment. @return true on success. */ bool clear(); /*! Removes all connections from the view. */ void removeAllConnections(); /*! Hides all tables except \a tables. */ void hideAllTablesExcept(QList* tables); protected Q_SLOTS: void slotAddTable(); void tableViewGotFocus(); void connectionViewGotFocus(); void emptyAreaGotFocus(); void tableContextMenuRequest(const QPoint& pos); void connectionContextMenuRequest(const QPoint& pos); void emptyAreaContextMenuRequest(const QPoint& pos); void appendSelectedFields(); void openSelectedTable(); void designSelectedTable(); void slotTableHidden(KDbTableSchema* table); void aboutToShowPopupMenu(); protected: /*! executes popup menu at \a pos, or, if \a pos not specified: at center of selected table view (if any selected), or at center point of the relations view. */ void executePopup(QPoint pos = QPoint(-1, -1)); //! Invalidates all actions availability. void invalidateActions(); private: class Private; Private* const d; }; #endif diff --git a/src/widget/tableview/KexiDataTableScrollArea.h b/src/widget/tableview/KexiDataTableScrollArea.h index 38b684696..ad34e96e3 100644 --- a/src/widget/tableview/KexiDataTableScrollArea.h +++ b/src/widget/tableview/KexiDataTableScrollArea.h @@ -1,84 +1,84 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2003 Joseph Wenninger Copyright (C) 2003-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDATATABLESCROLLAREA_H #define KEXIDATATABLESCROLLAREA_H #include "KexiTableScrollArea.h" class KDbCursor; /** * Database-aware table widget. */ class KEXIDATATABLE_EXPORT KexiDataTableScrollArea : public KexiTableScrollArea { Q_OBJECT public: /** * Creates a blank widget */ explicit KexiDataTableScrollArea(QWidget *parent); /*! Creates a table widget and fills it using data from \a cursor. Cursor will be opened (with open()) if it is not yet opened. Cursor must be defined on query schema, not raw statement (see KDbConnection::prepareQuery() and KDbConnection::executeQuery()), otherwise the table view remain not filled with data. Cursor \a cursor will not be owned by this object. */ KexiDataTableScrollArea(QWidget *parent, KDbCursor *cursor); ~KexiDataTableScrollArea(); using KexiTableScrollArea::setData; /*! Fills table view with data using \a cursor. \return true on success. Cursor \a cursor will not be owned by this object. */ bool setData(KDbCursor *cursor); /*! \return cursor used as data source for this table view, or NULL if no valid cursor is defined. */ KDbCursor *cursor() { return m_cursor; } /** * @returns the number of records in the data set, (if data set is present) * @note not all of the records have to be processed */ - virtual int recordCount() const { + virtual int recordCount() const override { return m_data ? m_data->count() : 0; } #ifdef KEXI_TABLE_PRINT_SUPPORT // virtual void print(KPrinter &printer); #endif protected: void init(); private: //db stuff KDbCursor *m_cursor; }; #endif diff --git a/src/widget/tableview/KexiDataTableView.h b/src/widget/tableview/KexiDataTableView.h index be32b65c8..89d4cd764 100644 --- a/src/widget/tableview/KexiDataTableView.h +++ b/src/widget/tableview/KexiDataTableView.h @@ -1,83 +1,83 @@ /* This file is part of the KDE project Copyright (C) 2003 Lucijan Busch Copyright (C) 2003 Joseph Wenninger Copyright (C) 2003-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDATATABLE_H #define KEXIDATATABLE_H #include "kexidatatable_export.h" #include class KDbCursor; class KDbTableViewData; class KexiTableScrollArea; /*! @short Provides a data-driven (record-based) tabular view. The KexiDataTableView can display data provided "by hand" or from KDb-compatible database source. @see KexiFormView */ class KEXIDATATABLE_EXPORT KexiDataTableView : public KexiDataAwareView { Q_OBJECT public: /*! CTOR1: Creates, empty table view that can be initialized later with setData(). If \a dbAware is true, table will be db-aware, and KexiDataTableView is used internally. Otherwise, table will be not-db-aware, and KexiTableView is used internally. In the latter case, data can be set by calling tableView()->setData(KDbTableViewData* data). */ explicit KexiDataTableView(QWidget *parent, bool dbAware = true); /*! CTOR2: Creates db-aware, table view initialized with \a cursor. KexiDataTableView is used internally. */ KexiDataTableView(QWidget *parent, KDbCursor *cursor); virtual ~KexiDataTableView(); KexiTableScrollArea* tableView() const; //! Loads settings for table into @a data model. //! Used after loading data model in KexiDataTableView::setData(KDbCursor*), before calling KexiTableView::setData(). //! @return true on success bool loadTableViewSettings(KDbTableViewData* data); public Q_SLOTS: /*! Sets data. Only works for db-aware table. */ void setData(KDbCursor *cursor); /*! Saves settings for the view. Implemented for KexiView. */ - virtual bool saveSettings(); + virtual bool saveSettings() override; protected Q_SLOTS: //! @todo void filter(); protected: void init(); class Private; Private * const d; }; #endif diff --git a/src/widget/tableview/KexiTableScrollArea.h b/src/widget/tableview/KexiTableScrollArea.h index d1c816800..c34bea9d2 100644 --- a/src/widget/tableview/KexiTableScrollArea.h +++ b/src/widget/tableview/KexiTableScrollArea.h @@ -1,709 +1,709 @@ /* This file is part of the KDE project Copyright (C) 2002 Till Busch Copyright (C) 2003 Lucijan Busch Copyright (C) 2003 Daniel Molkentin Copyright (C) 2003 Joseph Wenninger Copyright (C) 2003-2015 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. Original Author: Till Busch Original Project: buX (www.bux.at) */ #ifndef KEXITABLESCROLLAREA_H #define KEXITABLESCROLLAREA_H #include "kexidatatable_export.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class QPrinter; class QPrintDialog; class QAbstractItemModel; class KexiTableEdit; //! minimum column width in pixels #define KEXITV_MINIMUM_COLUMN_WIDTH 10 //! @short KexiTableScrollArea class provides a widget for displaying data in a tabular view. /*! @see KexiFormScrollView */ class KEXIDATATABLE_EXPORT KexiTableScrollArea : public QScrollArea, public KexiRecordNavigatorHandler, public KexiSharedActionClient, public KexiDataAwareObjectInterface, public KexiDataItemChangesListener { Q_OBJECT KEXI_DATAAWAREOBJECTINTERFACE public: /*! Defines table view's detailed appearance settings. */ class KEXIDATATABLE_EXPORT Appearance { public: explicit Appearance(QWidget *widget = 0); /*! Base color for cells, default is "Base" color for application's current palette */ QColor baseColor; /*! Text color for cells, default is "Text" color for application's current palette */ QColor textColor; /*! Grid color for cells, default is the same as default grid color of QTableView for application's current palette. */ QColor gridColor; /*! empty area color, default is "Base" color for application's current palette. */ QColor emptyAreaColor; /*! Alternate base color for cells, default is "AlternateBase" color for application's current palette. */ QColor alternateBaseColor; /*! True if background alternate color should be used, true by default. */ bool backgroundAltering; /*! True if full-record-selection mode is set, what means that all cells of the current record are always selected, instead of single cell. This mode is usable for read-only table views, when we're interested only in navigating by records. False by default, even for read-only table views. */ bool fullRecordSelection; /*! True if full grid is enabled. By default true if backgroundAltering is false or if baseColor == alternateBaseColor. It is set to false for comboboxpopup table, to mimic original combobox look and feel. */ bool horizontalGridEnabled; /*! True if full grid is enabled. True by default. It is set to false for comboboxpopup table, to mimic original combobox look and feel. */ bool verticalGridEnabled; /*! \if the navigation panel is enabled (visible) for the view. True by default. */ bool navigatorEnabled; /*! True if "record highlight" behaviour is enabled. False by default. */ bool recordHighlightingEnabled; /*! True if "record highlight over" behaviour is enabled. False by default. */ bool recordMouseOverHighlightingEnabled; /*! True if selection of a record should be kept when a user moved mouse pointer over other records. Makes only sense when recordMouseOverHighlightingEnabled is true. True by default. It is set to false for comboboxpopup table, to mimic original combobox look and feel. */ bool persistentSelections; /*! Color for record highlight, default is intermediate (33%/60%) between active highlight and base color. */ QColor recordHighlightingColor; /*! Color for text under record highlight, default is the same as textColor. Used when recordHighlightingEnabled is true. */ QColor recordHighlightingTextColor; /*! Color for record highlight for mouseover, default is intermediate (20%/80%) between active highlight and base color. Used when recordMouseOverHighlightingEnabled is true. */ QColor recordMouseOverHighlightingColor; /*! Color for text under record highlight for mouseover, default is the same as textColor. Used when recordMouseOverHighlightingEnabled is true. */ QColor recordMouseOverHighlightingTextColor; /*! Like recordMouseOverHighlightingColor but for areas painted with alternate color. This is computed using active highlight color and alternateBaseColor. */ QColor recordMouseOverAlternateHighlightingColor; }; explicit KexiTableScrollArea(KDbTableViewData* data = 0, QWidget* parent = 0); virtual ~KexiTableScrollArea(); //! redeclared to avoid conflict with private QWidget::data inline KDbTableViewData *data() const { return KexiDataAwareObjectInterface::data(); } /*! \return current appearance settings */ const Appearance& appearance() const; /*! Sets appearance settings. Table view is updated automatically. */ void setAppearance(const Appearance& a); /*! Convenience function. \return field object that define column \a column or NULL if there is no such column */ KDbField* field(int column) const; /*! \return maximum number of records that can be displayed per one "page" for current table view's size. */ - virtual int recordsPerPage() const; + virtual int recordsPerPage() const override; /*! \return number of records in this view. */ - virtual int recordCount() const; + virtual int recordCount() const override; /*! \return number of the currently selected record number or -1. */ - virtual int currentRecord() const; + virtual int currentRecord() const override; QRect cellGeometry(int record, int column) const; int columnWidth(int col) const; int recordHeight() const; int columnPos(int col) const; int recordPos(int record) const; int columnNumberAt(int pos) const; int recordNumberAt(int pos, bool ignoreEnd = false) const; /*! \return true if the last visible column takes up all the available space. @see setStretchLastColumn(bool). */ bool stretchLastColumn() const; /*! \return last record visible on the screen (counting from 0). The returned value is guaranteed to be smaller or equal to currentRecord() or -1 if there are no records. */ - virtual int lastVisibleRecord() const; + virtual int lastVisibleRecord() const override; /*! Redraws specified cell. */ - virtual void updateCell(int record, int column); + virtual void updateCell(int record, int column) override; /*! Redraws the current cell. Implemented after KexiDataAwareObjectInterface. */ - virtual void updateCurrentCell(); + virtual void updateCurrentCell() override; /*! Redraws all cells of specified record. */ - virtual void updateRecord(int record); + virtual void updateRecord(int record) override; bool editableOnDoubleClick() const; void setEditableOnDoubleClick(bool set); //! \return true if the vertical header is visible bool verticalHeaderVisible() const; //! Sets vertical header's visibility void setVerticalHeaderVisible(bool set); //! \return true if the horizontal header is visible bool horizontalHeaderVisible() const; //! Sets horizontal header's visibility void setHorizontalHeaderVisible(bool set); void updateViewportMargins(); #ifdef KEXI_TABLE_PRINT_SUPPORT // printing // void setupPrinter(KPrinter &printer, QPrintDialog &printDialog); void print(QPrinter &printer, QPrintDialog &printDialog); #endif // reimplemented for internal reasons virtual QSizePolicy sizePolicy() const; - virtual QSize sizeHint() const; - virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const override; + virtual QSize minimumSizeHint() const override; /*! @return geometry of the viewport, i.e. the scrollable area, minus any scrollbars, etc. Implementation for KexiDataAwareObjectInterface. */ - virtual QRect viewportGeometry() const; + virtual QRect viewportGeometry() const override; /*! Reimplemented to update cached fonts and record sizes for the painter. */ void setFont(const QFont &f); virtual QSize tableSize() const; void emitSelected(); //! single shot after 1ms for contents updating void triggerUpdate(); //! Initializes standard editor cell editor factories. This is called internally, once. static void initCellEditorFactories(); /*! \return highlighted record number or -1 if no record is highlighted. Makes sense if record highlighting is enabled. @see Appearance::recordHighlightingEnabled setHighlightedRecord() */ int highlightedRecordNumber() const; KDbRecordData *highlightedRecord() const; /*! \return vertical scrollbar. Implemented for KexiDataAwareObjectInterface. */ - virtual QScrollBar* verticalScrollBar() const; + virtual QScrollBar* verticalScrollBar() const override; - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; public Q_SLOTS: void setData(KDbTableViewData *data, bool owner = true); - virtual void clearColumnsInternal(bool repaint); + virtual void clearColumnsInternal(bool repaint) override; /*! Reimplementation for KexiDataAwareObjectInterface */ - virtual void setSpreadSheetMode(bool set); + virtual void setSpreadSheetMode(bool set) override; /*! Adjusts \a column column's width to its (current) contents. If \a column == -1, all columns' width is adjusted. */ void adjustColumnWidthToContents(int column = -1); //! Sets column width to \a width. void setColumnWidth(int column, int width); /*! If \a set is true, \a column column can be interactively resized by user. This is equivalent of QHeaderView::setResizeMode(column, QHeaderView::Interactive). If \a set is false, user cannot resize the column. This is equivalent of QHeaderView::setResizeMode(column, QHeaderView::Fixed). In both cases the column is initially resized to its default size and can be resized programatically afterwards using setColumnWidth(int, int). */ void setColumnResizeEnabled(int column, bool set); /*! If \a set is true, all columns in this table view can be interactively resized by user. This is equivalent of QHeaderView::setResizeMode(QHeaderView::Interactive). If \a set is false, user cannot resize the columns. This is equivalent of QHeaderView::setResizeMode(QHeaderView::Fixed). In both cases columns are initially resized to their default sizes and can be resized programatically afterwards using setColumnWidth(int, int). */ void setColumnsResizeEnabled(bool set); /*! Maximizes widths of columns selected by \a columnList, so the horizontal header has maximum overall width. Each selected column's width will be increased by the same value. Does nothing if \a columnList is empty or there is no free space to resize columns. If this table view is not visible, resizing will be performed on showing. */ void maximizeColumnsWidth(const QList &columnList); /*! If \a set is true the last visible column takes up all the available space ensuring that the available area is not wasted. Then it can't be resized by the user (setColumnResizeEnabled(columnCount()-1, !set) is used for that). The default value is false. @note Calling setColumnResizeEnabled(columnCount()-1, bool) can override this property. */ void setStretchLastColumn(bool set); /*! Sets highlighted record number or -1 if no record has to be highlighted. Makes sense if record highlighting is enabled. @see Appearance::recordHighlightingEnabled */ void setHighlightedRecordNumber(int record); /*! Ensures that cell at \a record and \a column is visible. If \a column is -1, current column number is used. If \a record is -1, current record number is used. \a record and \a column, if not -1, must be between 0 and recordCount()-1 (or columnCount()-1 accordingly). */ - virtual void ensureCellVisible(int record, int column); + virtual void ensureCellVisible(int record, int column) override; /*! Ensures that column \a col is visible. If \a col is -1, current column number is used. \a col, if not -1, must be between 0 and columnCount()-1. */ - virtual void ensureColumnVisible(int col); + virtual void ensureColumnVisible(int col) override; /*! Deletes currently selected record; does nothing if no record is currently selected. If record is in edit mode, editing is cancelled before deleting. */ - virtual void deleteCurrentRecord(); + virtual void deleteCurrentRecord() override; /*! Inserts one empty record above record \a record. If \a record is -1 (the default), new record is inserted above the current record (or above 1st record if there is no current). A new item becomes current if record is -1 or if record is equal currentRecord(). This method does nothing if: -inserting flag is disabled (see isInsertingEnabled()) -read-only flag is set (see isReadOnly()) \ return inserted record's data */ - virtual KDbRecordData *insertEmptyRecord(int pos = -1); + virtual KDbRecordData *insertEmptyRecord(int pos = -1) override; /*! Used when Return key is pressed on cell or "+" nav. button is clicked. Also used when we want to continue editing a cell after "invalid value" message was displayed (in this case, \a setText is usually not empty, what means that text will be set in the cell replacing previous value). */ virtual void startEditCurrentCell(const QString& setText = QString(), - CreateEditorFlags flags = DefaultCreateEditorFlags) { + CreateEditorFlags flags = DefaultCreateEditorFlags) override { KexiDataAwareObjectInterface::startEditCurrentCell(setText, flags); } /*! Deletes currently selected cell's contents, if allowed. In most cases delete is not accepted immediately but "record editing" mode is just started. */ - virtual void deleteAndStartEditCurrentCell() { + virtual void deleteAndStartEditCurrentCell() override { KexiDataAwareObjectInterface::deleteAndStartEditCurrentCell(); } /*! Cancels record editing All changes made to the editing record during this current session will be undone. \return true on success or false on failure (e.g. when editor does not exist) */ - virtual bool cancelRecordEditing() { + virtual bool cancelRecordEditing() override { return KexiDataAwareObjectInterface::cancelRecordEditing(); } /*! Accepts record editing. All changes made to the editing record during this current session will be accepted (saved). \return true if accepting was successful, false otherwise (e.g. when current record contain data that does not meet given constraints). */ - virtual bool acceptRecordEditing() { + virtual bool acceptRecordEditing() override { return KexiDataAwareObjectInterface::acceptRecordEditing(); } /*! Specifies, if this table view automatically accepts record editing (using acceptRecordEdit()) on accepting any cell's edit (i.e. after acceptEditor()). \sa acceptsRecordEditingAfterCellAccepting() */ - virtual void setAcceptsRecordEditAfterCellAccepting(bool set) { + virtual void setAcceptsRecordEditAfterCellAccepting(bool set) override { KexiDataAwareObjectInterface::setAcceptsRecordEditAfterCellAccepting(set); } /*! Specifies, if this table accepts dropping data on the records. If enabled: - dragging over record is indicated by drawing a line at bottom side of this record - dragOverRecord() signal will be emitted on dragging, -droppedAtRecord() will be emitted on dropping By default this flag is set to false. */ - virtual void setDropsAtRecordEnabled(bool set) { + virtual void setDropsAtRecordEnabled(bool set) override { KexiDataAwareObjectInterface::setDropsAtRecordEnabled(set); } - virtual bool cancelEditor() { + virtual bool cancelEditor() override { return KexiDataAwareObjectInterface::cancelEditor(); } - virtual bool acceptEditor() { + virtual bool acceptEditor() override { return KexiDataAwareObjectInterface::acceptEditor(); } /*! Reimplementation for KexiDataAwareObjectInterface, to react on changes of the sorting flag. */ - virtual void setSortingEnabled(bool set); + virtual void setSortingEnabled(bool set) override; Q_SIGNALS: - void dataSet(KDbTableViewData *data); + void dataSet(KDbTableViewData *data) override; - void itemSelected(KDbRecordData *data); - void cellSelected(int record, int column); + void itemSelected(KDbRecordData *data) override; + void cellSelected(int record, int column) override; void itemReturnPressed(KDbRecordData *data, int record, int column); void itemDblClicked(KDbRecordData *data, int record, int column); void itemMouseReleased(KDbRecordData *data, int record, int column); void dragOverRecord(KDbRecordData *data, int record, QDragMoveEvent* e); void droppedAtRecord(KDbRecordData *data, int record, QDropEvent *e, KDbRecordData*& newData); /*! Data has been refreshed on-screen - emitted from initDataContents(). */ - void dataRefreshed(); + void dataRefreshed() override; - void itemChanged(KDbRecordData *data, int record, int column); - void itemChanged(KDbRecordData *data, int record, int column, const QVariant &oldValue); - void itemDeleteRequest(KDbRecordData *data, int record, int column); - void currentItemDeleteRequest(); + void itemChanged(KDbRecordData *data, int record, int column) override; + void itemChanged(KDbRecordData *data, int record, int column, const QVariant &oldValue) override; + void itemDeleteRequest(KDbRecordData *data, int record, int column) override; + void currentItemDeleteRequest() override; //! Emitted for spreadsheet mode when an item was deleted and a new item has been appended - void newItemAppendedForAfterDeletingInSpreadSheetMode(); - void sortedColumnChanged(int col); + void newItemAppendedForAfterDeletingInSpreadSheetMode() override; + void sortedColumnChanged(int col) override; //! emitted when record editing is started (for updating or inserting) - void recordEditingStarted(int record); + void recordEditingStarted(int record) override; //! emitted when record editing is terminated (for updating or inserting) //! no matter if accepted or not - void recordEditingTerminated(int record); + void recordEditingTerminated(int record) override; //! emitted when state of 'save/cancel record changes' actions should be updated. - void updateSaveCancelActions(); + void updateSaveCancelActions() override; //! Emitted in initActions() to force reload actions //! You should remove existing actions and add them again. - void reloadActions(); + void reloadActions() override; protected Q_SLOTS: - virtual void slotDataDestroying() { + virtual void slotDataDestroying() override { KexiDataAwareObjectInterface::slotDataDestroying(); } - virtual void slotRecordsDeleted(const QList &records); + virtual void slotRecordsDeleted(const QList &records) override; //! updates display after deletion of many records void slotColumnWidthChanged(int column, int oldSize, int newSize); void slotSectionHandleDoubleClicked(int section); void slotUpdate(); //! implemented because we needed this as slot - virtual void sortColumnInternal(int col, int order = 0); + virtual void sortColumnInternal(int col, int order = 0) override; //! receives a signal from cell editors void slotEditRequested(); /*! Reloads data for this widget. Handles KDbTableViewData::reloadRequested() signal. */ - virtual void reloadData(); + virtual void reloadData() override; //! Handles KDbTableViewData::recordRepaintRequested() signal - virtual void slotRecordRepaintRequested(KDbRecordData* data); + virtual void slotRecordRepaintRequested(KDbRecordData* data) override; //! Handles KDbTableViewData::aboutToDeleteRecord() signal. Prepares info for slotRecordDeleted(). - virtual void slotAboutToDeleteRecord(KDbRecordData* data, KDbResultInfo* result, bool repaint) { + virtual void slotAboutToDeleteRecord(KDbRecordData* data, KDbResultInfo* result, bool repaint) override { KexiDataAwareObjectInterface::slotAboutToDeleteRecord(data, result, repaint); } //! Handles KDbTableViewData::recordDeleted() signal to repaint when needed. - virtual void slotRecordDeleted() { + virtual void slotRecordDeleted() override { KexiDataAwareObjectInterface::slotRecordDeleted(); } //! Handles KDbTableViewData::recordInserted() signal to repaint when needed. - virtual void slotRecordInserted(KDbRecordData *data, bool repaint) { + virtual void slotRecordInserted(KDbRecordData *data, bool repaint) override { KexiDataAwareObjectInterface::slotRecordInserted(data, repaint); } //! Like above, not db-aware version - virtual void slotRecordInserted(KDbRecordData *data, int record, bool repaint) { + virtual void slotRecordInserted(KDbRecordData *data, int record, bool repaint) override { KexiDataAwareObjectInterface::slotRecordInserted(data, record, repaint); } /*! Handles verticalScrollBar()'s valueChanged(int) signal. Called when vscrollbar's value has been changed. */ - virtual void verticalScrollBarValueChanged(int v); + virtual void verticalScrollBarValueChanged(int v) override; //! for navigator - virtual void moveToRecordRequested(int record); - virtual void moveToLastRecordRequested(); - virtual void moveToPreviousRecordRequested(); - virtual void moveToNextRecordRequested(); - virtual void moveToFirstRecordRequested(); - virtual void addNewRecordRequested() { + virtual void moveToRecordRequested(int record) override; + virtual void moveToLastRecordRequested() override; + virtual void moveToPreviousRecordRequested() override; + virtual void moveToNextRecordRequested() override; + virtual void moveToFirstRecordRequested() override; + virtual void addNewRecordRequested() override { KexiDataAwareObjectInterface::addNewRecordRequested(); } protected: /*! Reimplementation for KexiDataAwareObjectInterface Initializes data contents (resizes it, sets cursor at 1st row). Called on setData(). Also called once on show event after reloadRequested() signal was received from KDbTableViewData object. */ - virtual void initDataContents(); + virtual void initDataContents() override; /*! Implementation for KexiDataAwareObjectInterface. Updates widget's contents size using QScrollView::resizeContents() depending on tableSize(). */ - virtual void updateWidgetContentsSize(); + virtual void updateWidgetContentsSize() override; /*! Reimplementation for KexiDataAwareObjectInterface */ - virtual void clearVariables(); + virtual void clearVariables() override; /*! Implementation for KexiDataAwareObjectInterface */ - virtual KDbOrderByColumn::SortOrder currentLocalSortOrder() const; + virtual KDbOrderByColumn::SortOrder currentLocalSortOrder() const override; /*! Implementation for KexiDataAwareObjectInterface */ - virtual int currentLocalSortColumn() const; + virtual int currentLocalSortColumn() const override; /*! Implementation for KexiDataAwareObjectInterface */ - virtual void setLocalSortOrder(int column, KDbOrderByColumn::SortOrder order); + virtual void setLocalSortOrder(int column, KDbOrderByColumn::SortOrder order) override; /*! Implementation for KexiDataAwareObjectInterface */ - virtual void updateGUIAfterSorting(int previousRow); + virtual void updateGUIAfterSorting(int previousRow) override; int leftMargin() const; int topMargin() const; //! temporary int bottomMargin() const { return 0; } /*! @internal \return true if the row defined by \a data has default value at column \a col. If this is the case and \a value is not NULL, *value is set to the default value. */ bool isDefaultValueDisplayed(KDbRecordData *data, int col, QVariant* value = 0); //! painting and layout void drawContents(QPainter *p); void paintCell(QPainter* p, KDbRecordData *data, int record, int column, const QRect &cr, bool print = false); void paintEmptyArea(QPainter *p, int cx, int cy, int cw, int ch); void updateGeometries(); QPoint contentsToViewport2(const QPoint &p); void contentsToViewport2(int x, int y, int& vx, int& vy); QPoint viewportToContents2(const QPoint& vp); // event handling void contentsMousePressEvent(QMouseEvent* e); void contentsMouseReleaseEvent(QMouseEvent* e); //! @internal called by contentsMouseOrEvent() contentsMouseReleaseEvent() to move cursor bool handleContentsMousePressOrRelease(QMouseEvent* e, bool release); void contentsMouseMoveEvent(QMouseEvent* e); void contentsMouseDoubleClickEvent(QMouseEvent* e); void contentsContextMenuEvent(QContextMenuEvent* e); - virtual void keyPressEvent(QKeyEvent *e); - //virtual void focusInEvent(QFocusEvent* e); - virtual void focusOutEvent(QFocusEvent* e); - virtual void resizeEvent(QResizeEvent* e); + virtual void keyPressEvent(QKeyEvent *e) override; + //virtual void focusInEvent(QFocusEvent* e) override; + virtual void focusOutEvent(QFocusEvent* e) override; + virtual void resizeEvent(QResizeEvent* e) override; //virtual void viewportResizeEvent(QResizeEvent *e); - virtual void showEvent(QShowEvent *e); - virtual void dragMoveEvent(QDragMoveEvent *e); - virtual void dropEvent(QDropEvent *e); - virtual void dragLeaveEvent(QDragLeaveEvent *e); + virtual void showEvent(QShowEvent *e) override; + virtual void dragMoveEvent(QDragMoveEvent *e) override; + virtual void dropEvent(QDropEvent *e) override; + virtual void dragLeaveEvent(QDragLeaveEvent *e) override; //! For handling changes of palette - virtual void changeEvent(QEvent *e); + virtual void changeEvent(QEvent *e) override; /*! Implementation for KexiDataAwareObjectInterface */ - virtual KexiDataItemInterface *editor(int col, bool ignoreMissingEditor = false); + virtual KexiDataItemInterface *editor(int col, bool ignoreMissingEditor = false) override; KexiTableEdit *tableEditorWidget(int col, bool ignoreMissingEditor = false); /*! Implementation for KexiDataAwareObjectInterface */ - virtual void editorShowFocus(int row, int col); + virtual void editorShowFocus(int row, int col) override; //! Creates editors and shows it, what usually means the beginning of a cell editing virtual void createEditor(int row, int col, const QString& addText = QString(), - CreateEditorFlags flags = DefaultCreateEditorFlags); + CreateEditorFlags flags = DefaultCreateEditorFlags) override; - bool focusNextPrevChild(bool next); + bool focusNextPrevChild(bool next) override; /*! Used in key event: \return true if event \a e should execute action \a action_name. Action shortcuts defined by shortCutPressed() are reused, if present, and if \a e matches given action's shortcut - false is returned (beause action is already performed at main window's level). */ bool shortCutPressed(QKeyEvent *e, const QString &action_name); /*! Shows context menu at \a pos for selected cell if menu is configured, else: contextMenuRequested() signal is emitted. Method used in contentsMousePressEvent() (for right button) and keyPressEvent() for Qt::Key_Menu key. If \a pos is QPoint(-1,-1) (the default), menu is positioned below the current cell. */ void showContextMenu(const QPoint& pos = QPoint(-1, -1)); /*! internal */ inline void paintRow(KDbRecordData *data, QPainter *pb, int r, int rowp, int cx, int cy, int colfirst, int collast, int maxwc); virtual void setHBarGeometry(QScrollBar & hbar, int x, int y, int w, int h); //! Setups navigator widget void setupNavigator(); //! internal, to determine valid row number when navigator text changed int validRowNumber(const QString& text); /*! Reimplementation for KexiDataAwareObjectInterface (viewport()->setFocus() is just added) */ - virtual void removeEditor(); + virtual void removeEditor() override; /*! @internal Changes bottom margin settings, in pixels. At this time, it's used by KexiComboBoxPopup to decrease margin for popup's table. */ void setBottomMarginInternal(int pixels); - virtual void updateWidgetContents() { + virtual void updateWidgetContents() override { update(); } //! Copy current selection to a clipboard (e.g. cell) - virtual void copySelection(); + virtual void copySelection() override; //! Cut current selection to a clipboard (e.g. cell) - virtual void cutSelection(); + virtual void cutSelection() override; //! Paste current clipboard contents (e.g. to a cell) - virtual void paste(); + virtual void paste() override; /*! Used in KexiDataAwareObjectInterface::slotRecordDeleted() to repaint tow \a row and all visible below. */ - virtual void updateAllVisibleRecordsBelow(int row); + virtual void updateAllVisibleRecordsBelow(int row) override; - void updateAfterCancelRecordEditing(); - void updateAfterAcceptRecordEditing(); + void updateAfterCancelRecordEditing() override; + void updateAfterAcceptRecordEditing() override; /*! Sets \a cellValue if there is a lookup value for the cell \a data. Used in paintCell() and KexiTableCellToolTip::maybeTip() \return true if \a cellValue has been found. */ bool getVisibleLookupValue(QVariant& cellValue, KexiTableEdit *edit, KDbRecordData *data, KDbTableViewColumn *tvcol) const; /*! Implementation for KexiDataItemChangesListener. Reaction for change of \a item. */ - virtual void valueChanged(KexiDataItemInterface* item); + virtual void valueChanged(KexiDataItemInterface* item) override; /*! Implementation for KexiDataItemChangesListener. */ - virtual bool cursorAtNewRecord() const; + virtual bool cursorAtNewRecord() const override; /*! Implementation for KexiDataItemChangesListener. */ - virtual void lengthExceeded(KexiDataItemInterface *item, bool lengthExceeded); + virtual void lengthExceeded(KexiDataItemInterface *item, bool lengthExceeded) override; /*! Implementation for KexiDataItemChangesListener. */ - virtual void updateLengthExceededMessage(KexiDataItemInterface *item); + virtual void updateLengthExceededMessage(KexiDataItemInterface *item) override; - virtual int horizontalHeaderHeight() const; + virtual int horizontalHeaderHeight() const override; //! @return record navigator pane QWidget* navPanelWidget() const; //! @return true if record navigator pane exists and is has "visible" appearance set to ON bool navPanelWidgetVisible() const; - virtual bool event(QEvent *e); + virtual bool event(QEvent *e) override; //! @internal @return text information about a given column or other specific areas of the table view. QString whatsThisText(const QPoint &pos) const; /*! Called by KexiDataAwareObjectInterface::setCursorPosition() if cursor's position is really changed. */ - virtual void selectCellInternal(int previousRow, int previousColumn); + virtual void selectCellInternal(int previousRow, int previousColumn) override; //! @return horizontal header - virtual QHeaderView* horizontalHeader() const; + virtual QHeaderView* horizontalHeader() const override; //! @return vertical header - virtual QHeaderView* verticalHeader() const; + virtual QHeaderView* verticalHeader() const override; //! @return common model for header views of this area. @see KexiTableScrollAreaHeader QAbstractItemModel* headerModel() const; void updateScrollAreaWidgetSize(); //! Update section of vertical header - virtual void updateVerticalHeaderSection(int section); + virtual void updateVerticalHeaderSection(int section) override; - virtual void beginInsertItem(KDbRecordData *data, int pos); + virtual void beginInsertItem(KDbRecordData *data, int pos) override; - virtual void endInsertItem(KDbRecordData *data, int pos); + virtual void endInsertItem(KDbRecordData *data, int pos) override; - virtual void beginRemoveItem(KDbRecordData *data, int pos); + virtual void beginRemoveItem(KDbRecordData *data, int pos) override; - virtual void endRemoveItem(int pos); + virtual void endRemoveItem(int pos) override; class Private; Private * const d; friend class KexiTableScrollAreaWidget; friend class KexiTableCellToolTip; friend class KexiTableScrollAreaHeader; }; #endif diff --git a/src/widget/tableview/KexiTableScrollAreaHeader.cpp b/src/widget/tableview/KexiTableScrollAreaHeader.cpp index 491bfa20f..af734b3e8 100644 --- a/src/widget/tableview/KexiTableScrollAreaHeader.cpp +++ b/src/widget/tableview/KexiTableScrollAreaHeader.cpp @@ -1,344 +1,344 @@ /* This file is part of the KDE project Copyright (C) 2005-2015 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KexiTableScrollAreaHeader.h" #include "KexiTableScrollArea.h" #include "KexiTableScrollAreaHeaderModel.h" #include #include #include #include #include #include #include #include #include #include #include //! @internal A style that allows to temporary change background color while //! drawing header section primitive. Used in KexiTableScrollAreaHeader. class KexiTableScrollAreaHeaderStyle : public QProxyStyle { Q_OBJECT public: KexiTableScrollAreaHeaderStyle(const QString &baseStyleName) : QProxyStyle(baseStyleName) { } virtual ~KexiTableScrollAreaHeaderStyle() {} virtual void drawControl(ControlElement ce, const QStyleOption *option, QPainter *painter, - const QWidget *widget = 0) const + const QWidget *widget = 0) const override { const KexiTableScrollAreaHeader *headerWidget = qobject_cast(parent()); if (ce == CE_Header && option) { const QStyleOptionHeader *existingOption = qstyleoption_cast(option); QScopedPointer newOption( existingOption ? new QStyleOptionHeader(*existingOption) : new QStyleOptionHeader); const int currentSection = headerWidget->orientation() == Qt::Horizontal ? headerWidget->currentIndex().column() : headerWidget->currentIndex().row(); // qDebug() << headerWidget->orientation() << currentSection << // headerWidget->currentIndex().row() << headerWidget->currentIndex().column(); if (newOption->section >= 0) { int f1 = 0, f2 = 0; if (newOption->section == currentSection) { f1 = 34; f2 = 66; } else if (headerWidget->scrollArea()->appearance().recordMouseOverHighlightingEnabled && headerWidget->orientation() == Qt::Vertical && newOption->section == headerWidget->scrollArea()->highlightedRecordNumber()) { f1 = 10; f2 = 90; } if (f1 > 0) { newOption->palette.setColor(QPalette::Button, KexiUtils::blendedColors( headerWidget->selectionBackgroundColor(), headerWidget->palette().color(headerWidget->backgroundRole()), f1, f2)); //set background color as well (e.g. for thinkeramik) newOption->palette.setColor(QPalette::Window, newOption->palette.color(QPalette::Button)); } if (headerWidget->orientation() == Qt::Vertical) { // For mouse-over styles such as Breeze fill color and animate, // what's in conflict with what we do: disable this. newOption->state &= (0xffffffff ^ QStyle::State_MouseOver); //qDebug() << newOption->rect; } QProxyStyle::drawControl(ce, newOption.data(), painter, widget); return; } } QProxyStyle::drawControl(ce, option, painter, widget); } }; class Q_DECL_HIDDEN KexiTableScrollAreaHeader::Private { public: Private() : selectionBackgroundColor(qApp->palette().highlight().color()) , styleChangeEnabled(true) { } QColor selectionBackgroundColor; QPointer privateStyle; bool styleChangeEnabled; }; KexiTableScrollAreaHeader::KexiTableScrollAreaHeader(Qt::Orientation orientation, KexiTableScrollArea* parent) : QHeaderView(orientation, parent) , d(new Private) { setSectionsMovable(false); setSortingEnabled(parent->isSortingEnabled() && orientation == Qt::Horizontal); setSectionResizeMode(orientation == Qt::Horizontal ? QHeaderView::Interactive : QHeaderView::Fixed); setSelectionMode(QAbstractItemView::SingleSelection); setHighlightSections(true); setModel(parent->headerModel()); styleChanged(); } KexiTableScrollAreaHeader::~KexiTableScrollAreaHeader() { setModel(0); // avoid referencing deleted model setStyle(0); delete d->privateStyle; delete d; } void KexiTableScrollAreaHeader::changeEvent(QEvent *e) { if (e->type() == QEvent::StyleChange) { styleChanged(); } QHeaderView::changeEvent(e); } void KexiTableScrollAreaHeader::styleChanged() { if (!d->styleChangeEnabled) return; d->styleChangeEnabled = false; if (d->privateStyle) { setStyle(0); delete static_cast(d->privateStyle); } setStyle(d->privateStyle = new KexiTableScrollAreaHeaderStyle(style()->objectName())); d->privateStyle->setParent(this); d->styleChangeEnabled = true; } int KexiTableScrollAreaHeader::preferredSectionSize(int logicalIndex) const { const QString label = model()->headerData(logicalIndex, orientation(), Qt::DisplayRole).toString(); int preferredWidth = fontMetrics().width(label) + style()->pixelMetric(QStyle::PM_HeaderMargin) * 2; if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) { preferredWidth += (style()->pixelMetric(QStyle::PM_HeaderMarkSize) + 2 * style()->pixelMetric(QStyle::PM_HeaderMargin)); } QVariant decoration = model()->headerData(logicalIndex, orientation(), Qt::DecorationRole); const QIcon icon = decoration.value(); if (!icon.isNull()) { preferredWidth += IconSize(KIconLoader::Small) + style()->pixelMetric(QStyle::PM_HeaderMargin); } else { const QPixmap iconPixmap = decoration.value(); if (!iconPixmap.isNull()) { preferredWidth += iconPixmap.width() + style()->pixelMetric(QStyle::PM_HeaderMargin); } } return preferredWidth; } bool KexiTableScrollAreaHeader::viewportEvent(QEvent *e) { if ( orientation() == Qt::Horizontal && e->type() == QEvent::ToolTip) { QHelpEvent *he = static_cast(e); int section = logicalIndexAt(he->pos()); // take description by default QString tipText = model()->headerData(section, orientation(), Qt::ToolTipRole).toString(); if (tipText.isEmpty() && preferredSectionSize(section) > sectionSize(section)) { // try label only if it's not entirely visible tipText = model()->headerData(section, orientation(), Qt::DisplayRole).toString(); } QToolTip::showText(he->globalPos(), tipText, this, orientation() == Qt::Horizontal ? QRect(sectionPosition(section), 0, sectionSize(section), height()) : QRect(0, sectionPosition(section), width(), sectionSize(section))); return true; } return QHeaderView::viewportEvent(e); } void KexiTableScrollAreaHeader::mousePressEvent(QMouseEvent *e) { if (orientation() == Qt::Vertical && e->button() == Qt::LeftButton) { const int section = logicalIndexAt(e->y()); scrollArea()->setCursorPosition(section); } QHeaderView::mousePressEvent(e); } void KexiTableScrollAreaHeader::mouseMoveEvent(QMouseEvent *e) { if (orientation() == Qt::Vertical) { const int section = logicalIndexAt(e->y()); scrollArea()->setHighlightedRecordNumber(section); } QHeaderView::mouseMoveEvent(e); } void KexiTableScrollAreaHeader::leaveEvent(QEvent *e) { if (orientation() == Qt::Vertical) { scrollArea()->setHighlightedRecordNumber(-1); } QHeaderView::leaveEvent(e); } void KexiTableScrollAreaHeader::setSelectionBackgroundColor(const QColor &color) { d->selectionBackgroundColor = color; } QColor KexiTableScrollAreaHeader::selectionBackgroundColor() const { return d->selectionBackgroundColor; } int KexiTableScrollAreaHeader::headerWidth() const { int w = 0; for (int i = 0; i < count(); i++) { w += sectionSize(i); } return w; } KexiTableScrollArea* KexiTableScrollAreaHeader::scrollArea() const { return qobject_cast(parentWidget()); } void KexiTableScrollAreaHeader::updateSection(int logicalIndex) { QHeaderView::updateSection(logicalIndex); } QSize KexiTableScrollAreaHeader::sectionSizeFromContents(int logicalIndex) const { //QSize s = QHeaderView::sectionSizeFromContents(logicalIndex); // otherwise use the contents QStyleOptionHeader opt; initStyleOption(&opt); opt.section = logicalIndex; opt.orientation = orientation(); QVariant var = model()->headerData(logicalIndex, orientation(), Qt::FontRole); QFont fnt; if (var.isValid() && var.canConvert()) fnt = qvariant_cast(var); else fnt = font(); fnt.setBold(true); opt.fontMetrics = QFontMetrics(fnt); opt.text = model()->headerData(logicalIndex, orientation(), Qt::DisplayRole).toString(); //qDebug() << opt.text; //QVariant variant = model()->headerData(logicalIndex, orientation(), Qt::DecorationRole); //qDebug() << variant; // opt.icon = qvariant_cast(variant); // if (opt.icon.isNull()) // opt.icon = qvariant_cast(variant); QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); //qDebug() << size; if (isSortIndicatorShown()) { int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); if (orientation() == Qt::Horizontal) size.rwidth() += size.height() + margin; else size.rheight() += size.width() + margin; //qDebug() << "margin" << margin; } //qDebug() << size << "---"; //qDebug() << orientation() << logicalIndex << s; if (orientation() == Qt::Horizontal) { KDbTableViewData *data = scrollArea()->data(); KDbTableViewColumn *col = data ? data->visibleColumn(logicalIndex) : nullptr; if (col && col->width() > 0) { size.setWidth(col->width()); } } return size; } QSize KexiTableScrollAreaHeader::sizeHint() const { if (orientation() == Qt::Horizontal) { int width = 0; if (scrollArea()) { width = scrollArea()->viewport()->width() - 1; } int height = 0; for (int i = 0; i < count(); i++) { if (isSectionHidden(i)) continue; QSize hint = sectionSizeFromContents(i); height = qMax(height, hint.height()); //qDebug() << "height:" << height; } return QSize(width, height); } else { // vertical int height = 0; QStyleOptionHeader opt; initStyleOption(&opt); if (scrollArea()) { //qDebug() << "scrollArea()->width():" << scrollArea()->width(); height = scrollArea()->viewport()->height() - 1; } //qDebug() << scrollArea()->style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); return QSize(scrollArea()->recordHeight() + style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this), height); } } void KexiTableScrollAreaHeader::setSortingEnabled(bool set) { setSectionsClickable(set); setSortIndicatorShown(set); } #include "KexiTableScrollAreaHeader.moc" diff --git a/src/widget/tableview/KexiTableScrollAreaHeader.h b/src/widget/tableview/KexiTableScrollAreaHeader.h index 692dd843f..120e8fc7e 100644 --- a/src/widget/tableview/KexiTableScrollAreaHeader.h +++ b/src/widget/tableview/KexiTableScrollAreaHeader.h @@ -1,95 +1,95 @@ /* This file is part of the KDE project Copyright (C) 2005-2015 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITABLESCROLLAREAHEADER_H #define KEXITABLESCROLLAREAHEADER_H #include "kexidatatable_export.h" #include #include class KexiTableScrollArea; //! @short A header view with additional actions for use with table scroll area. /*! Displays field description (KDbField::description()) text as a tool tip, if available. Displays tool tips if a pointed section is not wide enough to fit its label text. \todo react on indexChange ( int section, int fromIndex, int toIndex ) signal */ class KEXIDATATABLE_EXPORT KexiTableScrollAreaHeader : public QHeaderView { Q_OBJECT public: explicit KexiTableScrollAreaHeader(Qt::Orientation orientation, KexiTableScrollArea* parent = 0); virtual ~KexiTableScrollAreaHeader(); //! @todo Support entire QBrush here? QColor selectionBackgroundColor() const; void setSelectionBackgroundColor(const QColor &color); //! @return the total width of all the header columns. int headerWidth() const; //! @return a suitable size hint for this header. - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; //! @return preferred size for section @a logicalIndex. //! Preferred size is a minimal one that has still visible text and sort indicator //! or icons (if they are present). his method does not alanyze size of contents. //! @todo Currently only works for horizontal orientation. int preferredSectionSize(int logicalIndex) const; //! @return scroll area (parent) of this header. KexiTableScrollArea* scrollArea() const; public Q_SLOTS: //! Updates the section specified by the given \a logicalIndex. //! Made public for use in the scroll view. void updateSection(int logicalIndex); //! Set sorting flags to @a set. Does not perform sorting, just changes visual feedback //! and whether clicking on section is enabled. void setSortingEnabled(bool set); protected: - virtual void changeEvent(QEvent *e); + virtual void changeEvent(QEvent *e) override; - virtual bool viewportEvent(QEvent *e); + virtual bool viewportEvent(QEvent *e) override; //! For vertical header. We do not use sectionClicked() because we want to handle clicking on any pixel. - virtual void mousePressEvent(QMouseEvent *e); + virtual void mousePressEvent(QMouseEvent *e) override; - virtual void mouseMoveEvent(QMouseEvent *e); + virtual void mouseMoveEvent(QMouseEvent *e) override; - virtual void leaveEvent(QEvent *e); + virtual void leaveEvent(QEvent *e) override; - virtual QSize sectionSizeFromContents(int logicalIndex) const; + virtual QSize sectionSizeFromContents(int logicalIndex) const override; private: void styleChanged(); class Private; Private * const d; }; #endif diff --git a/src/widget/tableview/KexiTableScrollAreaHeaderModel.h b/src/widget/tableview/KexiTableScrollAreaHeaderModel.h index e5c16cec4..3219755ba 100644 --- a/src/widget/tableview/KexiTableScrollAreaHeaderModel.h +++ b/src/widget/tableview/KexiTableScrollAreaHeaderModel.h @@ -1,62 +1,62 @@ /* This file is part of the KDE project Copyright (C) 2014-2015 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITABLESCROLLAREAHEADERMODEL_H #define KEXITABLESCROLLAREAHEADERMODEL_H #include "kexidatatable_export.h" #include #include class KexiTableScrollArea; //! @short A model for use in headers of table scroll area. /*! It's a QAbstractTableModel-compliant proxy to data that is provided by KexiTableScrollArea. */ class KEXIDATATABLE_EXPORT KexiTableScrollAreaHeaderModel : public QAbstractTableModel { Q_OBJECT public: explicit KexiTableScrollAreaHeaderModel(KexiTableScrollArea* parent = 0); virtual ~KexiTableScrollAreaHeaderModel(); - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; void beginInsertRows(const QModelIndex &parent, int first, int last); void endInsertRows(); void beginRemoveRows(const QModelIndex &parent, int first, int last); void endRemoveRows(); private: class Private; Private * const d; }; #endif diff --git a/src/widget/tableview/KexiTableScrollAreaWidget.h b/src/widget/tableview/KexiTableScrollAreaWidget.h index 538e3de22..d0ddb6b50 100644 --- a/src/widget/tableview/KexiTableScrollAreaWidget.h +++ b/src/widget/tableview/KexiTableScrollAreaWidget.h @@ -1,51 +1,51 @@ /* This file is part of the KDE project Copyright (C) 2014 Jarosław Staniek 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 KEXITABLESCROLLAREAWIDGET_H #define KEXITABLESCROLLAREAWIDGET_H #include class QMouseEvent; class KexiTableScrollArea; //! A widget displaying contents of KexiTableScrollArea class KexiTableScrollAreaWidget : public QWidget { Q_OBJECT public: explicit KexiTableScrollAreaWidget(KexiTableScrollArea *area); virtual ~KexiTableScrollAreaWidget(); KexiTableScrollArea *scrollArea; protected: // Events that are passed to KexiTableScrollArea - virtual void paintEvent(QPaintEvent *e); - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseReleaseEvent(QMouseEvent *e); - virtual void mouseMoveEvent(QMouseEvent *e); - virtual void mouseDoubleClickEvent(QMouseEvent *e); - virtual void contextMenuEvent(QContextMenuEvent *e); - virtual void leaveEvent(QEvent *e); + virtual void paintEvent(QPaintEvent *e) override; + virtual void mousePressEvent(QMouseEvent *e) override; + virtual void mouseReleaseEvent(QMouseEvent *e) override; + virtual void mouseMoveEvent(QMouseEvent *e) override; + virtual void mouseDoubleClickEvent(QMouseEvent *e) override; + virtual void contextMenuEvent(QContextMenuEvent *e) override; + virtual void leaveEvent(QEvent *e) override; friend class KexiTableScrollArea; }; #endif // KEXITABLESCROLLAREAWIDGET_H diff --git a/src/widget/tableview/kexiblobtableedit.h b/src/widget/tableview/kexiblobtableedit.h index 7ec7d0562..303b31817 100644 --- a/src/widget/tableview/kexiblobtableedit.h +++ b/src/widget/tableview/kexiblobtableedit.h @@ -1,169 +1,169 @@ /* This file is part of the KDE project Copyright (C) 2002 Peter Simonsson Copyright (C) 2004, 2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _KEXIBLOBTABLEEDIT_H_ #define _KEXIBLOBTABLEEDIT_H_ #include "kexitableedit.h" #include "kexicelleditorfactory.h" class QTemporaryFile; class QUrl; class KexiBlobTableEdit : public KexiTableEdit { Q_OBJECT public: explicit KexiBlobTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiBlobTableEdit(); - bool valueIsNull(); - bool valueIsEmpty(); + bool valueIsNull() override; + bool valueIsEmpty() override; - virtual QVariant value(); + virtual QVariant value() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; /*! Reimplemented: resizes a view(). */ - virtual void resize(int w, int h); + virtual void resize(int w, int h) override; - virtual void showFocus(const QRect& r, bool readOnly); + virtual void showFocus(const QRect& r, bool readOnly) override; - virtual void hideFocus(); + virtual void hideFocus() override; /*! \return total size of this editor, including popup button. */ - virtual QSize totalSize() const; + virtual QSize totalSize() const override; - virtual void paintFocusBorders(QPainter *p, QVariant &, int x, int y, int w, int h); + virtual void paintFocusBorders(QPainter *p, QVariant &, int x, int y, int w, int h) override; /*! Reimplemented to handle the key events. */ - virtual bool handleKeyPress(QKeyEvent* ke, bool editorActive); + virtual bool handleKeyPress(QKeyEvent* ke, bool editorActive) override; /*! Handles double click request coming from the table view. \return true if it has been consumed. Reimplemented in KexiBlobTableEdit (to execute "insert file" action. */ - virtual bool handleDoubleClick(); + virtual bool handleDoubleClick() override; /*! Handles action having standard name \a actionName. Action could be: "edit_cut", "edit_paste", etc. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Handles copy action for value. The \a value is copied to clipboard in format appropriate for the editor's impementation, e.g. for image cell it can be a pixmap. \a visibleValue is unused here. Reimplemented after KexiTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; protected Q_SLOTS: void slotUpdateActionsAvailabilityRequested(bool *valueIsNull, bool *valueIsReadOnly); void handleInsertFromFileAction(const QUrl &url); void handleAboutToSaveAsAction(QString *origFilename, QString *mimeType, bool *dataIsEmpty); void handleSaveAsAction(const QString& fileName); void handleCutAction(); void handleCopyAction(); void handlePasteAction(); - virtual void clear(); + virtual void clear() override; void handleShowPropertiesAction(); protected: //! initializes this editor with \a add value - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; //! @todo QString openWithDlg(const QString& file); //! @todo void execute(const QString& app, const QString& file); //! @todo QString openWithDlg(const QString& file); //! @todo void execute(const QString& app, const QString& file); //! @internal void updateFocus(const QRect& r); void signalEditRequested(); //! @internal void executeCopyAction(const QByteArray& data); - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; class Private; Private * const d; //! @todo QTemporaryFile* m_tempFile; //! @todo KProcess* m_proc; //! @todo QTextEdit *m_content; }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiBlobEditorFactoryItem) //======================= //This class is temporarily here: /*! @short Cell editor for displaying kde icon (using icon name provided as string). Read only. */ class KexiKIconTableEdit : public KexiTableEdit { Q_OBJECT public: explicit KexiKIconTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiKIconTableEdit(); //! \return true if editor's value is null (not empty) - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not null). //! Only few field types can accept "EMPTY" property //! (check this with KDbField::hasEmptyProperty()), - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; - virtual QVariant value(); + virtual QVariant value() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; - virtual void clear(); + virtual void clear() override; virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; /*! Handles copy action for value. Does nothing. \a visibleValue is unused here. Reimplemented after KexiTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; protected: //! initializes this editor with \a add value - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; void showHintButton(); void init(); class Private; Private * const d; }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiKIconTableEditorFactoryItem) #endif diff --git a/src/widget/tableview/kexibooltableedit.h b/src/widget/tableview/kexibooltableedit.h index aa795ea85..9048ab4d5 100644 --- a/src/widget/tableview/kexibooltableedit.h +++ b/src/widget/tableview/kexibooltableedit.h @@ -1,87 +1,87 @@ /* This file is part of the KDE project Copyright (C) 2004 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIBOOLTABLEEDIT_H #define KEXIBOOLTABLEEDIT_H #include #include "kexitableedit.h" #include "kexicelleditorfactory.h" /*! @short Cell editor for boolean type. */ class KexiBoolTableEdit : public KexiTableEdit { Q_OBJECT public: explicit KexiBoolTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiBoolTableEdit(); //! \return true if editor's value is null (not empty) - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not null). //! Only few field types can accept "EMPTY" property //! (check this with KDbField::hasEmptyProperty()), - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; - virtual QVariant value(); + virtual QVariant value() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; - virtual void clear(); + virtual void clear() override; virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; - virtual void clickedOnContents(); + virtual void clickedOnContents() override; /*! Handles action having standard name \a actionName. Action could be: "edit_cut", "edit_paste", etc. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Handles copy action for value. Copies empty string for null, "1" for true, "0" for false. \a visibleValue is unused here. Reimplemented after KexiTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; /*! \return width of \a value. Reimplemented after KexiTableEdit. */ - virtual int widthForValue(const QVariant &val, const QFontMetrics &fm); + virtual int widthForValue(const QVariant &val, const QFontMetrics &fm) override; protected Q_SLOTS: protected: //! initializes this editor with \a add value - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; void showHintButton(); //! We've no editor widget that would store current value, so we do this here QVariant m_currentValue; Q_SIGNALS: void hintClicked(); }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiBoolEditorFactoryItem) #endif diff --git a/src/widget/tableview/kexicomboboxpopup.h b/src/widget/tableview/kexicomboboxpopup.h index 827661c3b..aefdfe0cb 100644 --- a/src/widget/tableview/kexicomboboxpopup.h +++ b/src/widget/tableview/kexicomboboxpopup.h @@ -1,94 +1,94 @@ /* This file is part of the KDE project Copyright (C) 2004-2017 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICOMBOBOXPOPUP_H #define KEXICOMBOBOXPOPUP_H #include class KDbConnection; class KDbField; class KDbRecordData; class KDbTableViewColumn; class KDbTableViewData; class KexiComboBoxPopupPrivate; class KexiTableScrollArea; //! Internal class for displaying popup table view class KexiComboBoxPopup : public QFrame { Q_OBJECT public: //! @todo js: more ctors! /*! Constructor for creating a popup using definition from \a column. If the column is lookup column, its definition is used to display one or more column within the popup. Otherwise column.field() is used to display single-column data. @note @a conn is required only for db-aware data. */ KexiComboBoxPopup(KDbConnection *conn, KDbTableViewColumn *column, QWidget *parent = nullptr); /*! Alternative constructor supporting lookup fields and enum hints. @note @a conn is required only for db-aware data. */ KexiComboBoxPopup(KDbConnection *conn, KDbField *field, QWidget *parent = nullptr); virtual ~KexiComboBoxPopup(); KexiTableScrollArea* tableView(); /*! Sets maximum number of records for this popup. */ void setMaxRecordCount(int count); /*! \return maximum number of records for this popup. */ int maxRecordCount() const; /*! Default maximum number of records for KexiComboBoxPopup objects. */ static const int defaultMaxRecordCount; Q_SIGNALS: void recordAccepted(KDbRecordData *data, int record); void cancelled(); void hidden(); public Q_SLOTS: virtual void resize(int w, int h); void updateSize(int minWidth = 0); protected Q_SLOTS: void slotTVItemAccepted(KDbRecordData *data, int record, int column); void slotDataReloadRequested(); protected: void init(); - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; //! The main function for setting data; data can be set either by passing \a column or \a field. //! The second case is used for lookup. //! @note @a conn is required only for db-aware data. */ void setData(KDbConnection *conn, KDbTableViewColumn *column, KDbField *field); //! used by setData() void setDataInternal(KDbTableViewData *data, bool owner = true); //!< helper KexiComboBoxPopupPrivate * const d; friend class KexiComboBoxTableEdit; }; #endif diff --git a/src/widget/tableview/kexicomboboxtableedit.h b/src/widget/tableview/kexicomboboxtableedit.h index b5001cf04..5de00a2f0 100644 --- a/src/widget/tableview/kexicomboboxtableedit.h +++ b/src/widget/tableview/kexicomboboxtableedit.h @@ -1,186 +1,186 @@ /* This file is part of the KDE project Copyright (C) 2002 Peter Simonsson Copyright (C) 2003-2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _KEXICOMBOBOXTABLEEDIT_H_ #define _KEXICOMBOBOXTABLEEDIT_H_ #include "kexiinputtableedit.h" #include "kexicomboboxbase.h" #include #include #include #include #include class KDbTableViewColumn; class KexiComboBoxPopup; /*! @short Drop-down cell editor. */ class KexiComboBoxTableEdit : public KexiInputTableEdit, virtual public KexiComboBoxBase { Q_OBJECT public: explicit KexiComboBoxTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiComboBoxTableEdit(); //! Implemented for KexiComboBoxBase KDbTableViewColumn *column() override { return m_column; } //! Implemented for KexiComboBoxBase KDbField *field() override { return m_column->field(); } //! Implemented for KexiComboBoxBase - virtual QVariant origValue() const; + virtual QVariant origValue() const override; - virtual void setValueInternal(const QVariant& add, bool removeOld) { + virtual void setValueInternal(const QVariant& add, bool removeOld) override { KexiComboBoxBase::setValueInternal(add, removeOld); } - virtual QVariant value() { + virtual QVariant value() override { return KexiComboBoxBase::value(); } - virtual void clear(); + virtual void clear() override; - virtual bool valueChanged(); + virtual bool valueChanged() override; - virtual QVariant visibleValue(); + virtual QVariant visibleValue() override; /*! Reimplemented: resizes a view(). */ - virtual void resize(int w, int h); + virtual void resize(int w, int h) override; - virtual void showFocus(const QRect& r, bool readOnly); + virtual void showFocus(const QRect& r, bool readOnly) override; - virtual void hideFocus(); + virtual void hideFocus() override; - virtual void paintFocusBorders(QPainter *p, QVariant &cal, int x, int y, int w, int h); + virtual void paintFocusBorders(QPainter *p, QVariant &cal, int x, int y, int w, int h) override; /*! Setups contents of the cell. As a special case, if there is lookup field schema defined, \a val already contains the visible value (usually the text) set by \ref KexiTableView::paintcell(), so there is noo need to lookup the value in the combo box's popup. */ virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; /*! Used to handle key press events for the item. */ - virtual bool handleKeyPress(QKeyEvent *ke, bool editorActive); + virtual bool handleKeyPress(QKeyEvent *ke, bool editorActive) override; - virtual int widthForValue(const QVariant &val, const QFontMetrics &fm); + virtual int widthForValue(const QVariant &val, const QFontMetrics &fm) override; - virtual void hide(); + virtual void hide() override; virtual void show(); /*! \return total size of this editor, including popup button. */ - virtual QSize totalSize() const; + virtual QSize totalSize() const override; - virtual void createInternalEditor(KDbConnection *conn, const KDbQuerySchema& schema); + virtual void createInternalEditor(KDbConnection *conn, const KDbQuerySchema& schema) override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Reimplemented after KexiInputTableEdit. For a special case (combo box), \a visibleValue can be provided, so it can be copied to the clipboard instead of unreadable \a value. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; public Q_SLOTS: //! Implemented for KexiDataItemInterface - virtual void moveCursorToEnd(); + virtual void moveCursorToEnd() override; //! Implemented for KexiDataItemInterface - virtual void moveCursorToStart(); + virtual void moveCursorToStart() override; //! Implemented for KexiDataItemInterface - virtual void selectAll(); + virtual void selectAll() override; protected Q_SLOTS: void slotButtonClicked(); - void slotRecordAccepted(KDbRecordData *data, int record) { + void slotRecordAccepted(KDbRecordData *data, int record) override { KexiComboBoxBase::slotRecordAccepted(data, record); } - void slotRecordSelected(KDbRecordData* data) { + void slotRecordSelected(KDbRecordData* data) override { KexiComboBoxBase::slotRecordSelected(data); } void slotInternalEditorValueChanged(const QVariant& v) { KexiComboBoxBase::slotInternalEditorValueChanged(v); } void slotLineEditTextChanged(const QString& s); void slotPopupHidden(); protected: //! Implemented for KexiComboBoxBase KDbConnection *connection() override; //! internal void updateFocus(const QRect& r); - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; //! Implemented for KexiComboBoxBase - virtual QWidget *internalEditor() const; + virtual QWidget *internalEditor() const override; //! Implemented for KexiComboBoxBase - virtual void moveCursorToEndInInternalEditor(); + virtual void moveCursorToEndInInternalEditor() override; //! Implemented for KexiComboBoxBase - virtual void selectAllInInternalEditor(); + virtual void selectAllInInternalEditor() override; //! Implemented for KexiComboBoxBase - virtual void setValueInInternalEditor(const QVariant& value); + virtual void setValueInInternalEditor(const QVariant& value) override; //! Implemented for KexiComboBoxBase - virtual QVariant valueFromInternalEditor(); + virtual QVariant valueFromInternalEditor() override; //! Implemented for KexiComboBoxBase - virtual void editRequested() { + virtual void editRequested() override { KexiInputTableEdit::editRequested(); } //! Implemented for KexiComboBoxBase - virtual void acceptRequested() { + virtual void acceptRequested() override { KexiInputTableEdit::acceptRequested(); } //! Implemented for KexiComboBoxBase - virtual QPoint mapFromParentToGlobal(const QPoint& pos) const; + virtual QPoint mapFromParentToGlobal(const QPoint& pos) const override; //! Implemented for KexiComboBoxBase - virtual int popupWidthHint() const; + virtual int popupWidthHint() const override; //! Implemented this to update button state. - virtual void updateButton(); + virtual void updateButton() override; - virtual KexiComboBoxPopup *popup() const; - virtual void setPopup(KexiComboBoxPopup *popup); + virtual KexiComboBoxPopup *popup() const override; + virtual void setPopup(KexiComboBoxPopup *popup) override; class Private; Private * const d; }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiComboBoxEditorFactoryItem) #endif diff --git a/src/widget/tableview/kexidatetableedit.h b/src/widget/tableview/kexidatetableedit.h index 5d40de6b7..fd4a7e0f3 100644 --- a/src/widget/tableview/kexidatetableedit.h +++ b/src/widget/tableview/kexidatetableedit.h @@ -1,67 +1,67 @@ /* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003 Daniel Molkentin Copyright (C) 2003-2004,2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDATETABLEEDIT_H #define KEXIDATETABLEEDIT_H #include "kexiinputtableedit.h" #include /*! @short Editor class for Date type. It is a replacement QDateEdit due to usability problems: people are accustomed to use single-character cursor. Date format is retrieved from the KDE global settings. and input/output is performed using QLineEdit (from KexiInputTableEdit). */ class KexiDateTableEdit : public KexiInputTableEdit { Q_OBJECT public: explicit KexiDateTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiDateTableEdit(); virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); - virtual QVariant value(); - virtual bool valueIsNull(); - virtual bool valueIsEmpty(); - virtual bool valueIsValid(); - virtual bool valueChanged(); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; + virtual QVariant value() override; + virtual bool valueIsNull() override; + virtual bool valueIsEmpty() override; + virtual bool valueIsValid() override; + virtual bool valueChanged() override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; protected: //! helper void setValueInInternalEditor(const QVariant &value); - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; QDate dateValue() const; //! Used to format and convert date values KexiDateFormatter m_formatter; }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiDateEditorFactoryItem) #endif diff --git a/src/widget/tableview/kexidatetimetableedit.h b/src/widget/tableview/kexidatetimetableedit.h index efca761f9..f161ffc32 100644 --- a/src/widget/tableview/kexidatetimetableedit.h +++ b/src/widget/tableview/kexidatetimetableedit.h @@ -1,70 +1,70 @@ /* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003 Daniel Molkentin Copyright (C) 2003-2004,2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDATETIMETABLEEDIT_H #define KEXIDATETIMETABLEEDIT_H #include "kexidatetableedit.h" #include "kexitimetableedit.h" /*! @short Editor class for Date/Time type. It is a replacement QDateTimeEdit due to usability problems: people are accustomed to use single-character cursor. Date and Time format is retrieved from the KDE global settings and input/output is performed using QLineEdit (from KexiInputTableEdit). */ class KexiDateTimeTableEdit : public KexiInputTableEdit { Q_OBJECT public: explicit KexiDateTimeTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiDateTimeTableEdit(); virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); - virtual QVariant value(); - virtual bool valueIsNull(); - virtual bool valueIsEmpty(); - virtual bool valueIsValid(); - virtual bool valueChanged(); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; + virtual QVariant value() override; + virtual bool valueIsNull() override; + virtual bool valueIsEmpty() override; + virtual bool valueIsValid() override; + virtual bool valueChanged() override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; protected: //! helper void setValueInInternalEditor(const QVariant &value); - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; bool textIsEmpty() const; //! Used to format and convert date values KexiDateFormatter m_dateFormatter; //! Used to format and convert time values KexiTimeFormatter m_timeFormatter; }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiDateTimeEditorFactoryItem) #endif diff --git a/src/widget/tableview/kexiinputtableedit.h b/src/widget/tableview/kexiinputtableedit.h index 335b8da01..8cfb9ed9b 100644 --- a/src/widget/tableview/kexiinputtableedit.h +++ b/src/widget/tableview/kexiinputtableedit.h @@ -1,123 +1,123 @@ /* This file is part of the KDE project Copyright (C) 2002 Lucijan Busch Copyright (C) 2003-2016 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIINPUTTABLEEDIT_H #define KEXIINPUTTABLEEDIT_H #include #include #include "kexitableedit.h" #include "kexicelleditorfactory.h" #include "kexitextformatter.h" class QLineEdit; /*! @short General purpose cell editor using line edit widget. */ class KEXIDATATABLE_EXPORT KexiInputTableEdit : public KexiTableEdit { Q_OBJECT public: explicit KexiInputTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiInputTableEdit(); - virtual bool valueChanged(); + virtual bool valueChanged() override; //! \return true if editor's value is null (not empty) - virtual bool valueIsNull(); + virtual bool valueIsNull() override; //! \return true if editor's value is empty (not null). //! Only few field types can accept "EMPTY" property //! (check this with KDbField::hasEmptyProperty()), - virtual bool valueIsEmpty(); + virtual bool valueIsEmpty() override; //! \return true if the value is valid bool valueIsValid() override; - virtual QVariant value(); + virtual QVariant value() override; - virtual bool cursorAtStart(); - virtual bool cursorAtEnd(); + virtual bool cursorAtStart() override; + virtual bool cursorAtEnd() override; - virtual void clear(); + virtual void clear() override; /*! \return total size of this editor, including any buttons, etc. (if present). */ - virtual QSize totalSize() const; + virtual QSize totalSize() const override; /*! Handles action having standard name \a actionName. Action could be: "edit_cut", "edit_paste", etc. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Handles copy action for value. The \a value is copied to clipboard in format appropriate for the editor's impementation, e.g. for image cell it can be a pixmap. \a visibleValue is unused here. Reimplemented after KexiTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; /*! Shows a special tooltip for \a value if needed, i.e. if the value could not fit inside \a rect for a given font metrics \a fm. \return true a normal tooltip should be displayed (using QToolTip,) and false if no tooltip should be displayed or a custom tooltip was displayed internally (not yet supported). This implementation converts the value to text using KexiTextFormatter::toString() if \a value is not string to see whether it can fit inside the cell's \a rect. If the cell is currentl focused (selected), \a focused is true. */ virtual bool showToolTipIfNeeded(const QVariant& value, const QRect& rect, const QFontMetrics& fm, - bool focused); + bool focused) override; public Q_SLOTS: //! Implemented for KexiDataItemInterface - virtual void moveCursorToEnd(); + virtual void moveCursorToEnd() override; //! Implemented for KexiDataItemInterface - virtual void moveCursorToStart(); + virtual void moveCursorToStart() override; //! Implemented for KexiDataItemInterface - virtual void selectAll(); + virtual void selectAll() override; //! Implemented for KexiDataItemInterface - virtual bool fixup(); + virtual bool fixup() override; protected Q_SLOTS: void setRestrictedCompletion(); void completed(const QString &); void slotTextEdited(const QString&); protected: //! initializes this editor with \a add value - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; void showHintButton(); void init(); - virtual void paintEvent(QPaintEvent *e); + virtual void paintEvent(QPaintEvent *e) override; void updateLineEditStyleSheet(); KexiTextFormatter m_textFormatter; bool m_calculatedCell; QLineEdit *m_lineedit; Q_SIGNALS: void hintClicked(); }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiInputEditorFactoryItem) #endif diff --git a/src/widget/tableview/kexitableedit.h b/src/widget/tableview/kexitableedit.h index d5c4b7e84..a29d32ac3 100644 --- a/src/widget/tableview/kexitableedit.h +++ b/src/widget/tableview/kexitableedit.h @@ -1,232 +1,232 @@ /* This file is part of the KDE project Copyright (C) 2002 Peter Simonsson Copyright (C) 2003-2016 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef _KEXITABLEEDIT_H_ #define _KEXITABLEEDIT_H_ #include "kexidatatable_export.h" #include #include #include #include class KDbField; class KDbQueryColumnInfo; class KexiTextFormatter; /*! @short Abstract class for a cell editor. Handles cell painting and displaying the editor widget. */ class KEXIDATATABLE_EXPORT KexiTableEdit : public QWidget, public KexiDataItemInterface { Q_OBJECT public: explicit KexiTableEdit(KDbTableViewColumn *column, QWidget* parent = 0); virtual ~KexiTableEdit(); //! Implemented for KexiDataItemInterface. //! \return field information for this item KDbField *field() override; /*! A rich field information for db-aware data. For not-db-aware data it is always 0 (use field() instead. */ KDbQueryColumnInfo *columnInfo() override; //! Implemented for KexiDataItemInterface. //! Does nothing because instead KDbTableViewColumn is used to get field's schema. void setColumnInfo(KDbConnection *conn, KDbQueryColumnInfo *cinfo) override; //! \return column information for this item //! (extended information, comparing to field()). const KDbTableViewColumn *column() const; /*! \return displayed field. This is equal to field() in typical case but can return a different field definition if the column contains a lookup field. This distiction is especially used for displaying data dependent on the type and specifics of the field definition (e.g. text type versus integer type). Note that to compute the editor's value we still use field(). */ const KDbField *displayedField(); /*! Reimplemented: resizes a view(). */ virtual void resize(int w, int h); /*! \return the view widget of this editor, e.g. line edit widget. */ - virtual QWidget* widget(); + virtual QWidget* widget() override; /*! Hides item's widget, if available. */ - virtual void hideWidget(); + virtual void hideWidget() override; /*! Shows item's widget, if available. */ - virtual void showWidget(); + virtual void showWidget() override; /*! Paints a border for the cell described by \a x, \a y, \a w, \a h on \a p painter. The cell's value is \a val (may be useful if you want to reimplement this method). */ virtual void paintFocusBorders(QPainter *p, QVariant &cal, int x, int y, int w, int h); /*! For reimplementation. Sets up and paints cell's contents using context of \a val value. \a focused is true if the cell is focused. \a align is set using Qt::AlignmentFlags. Some additional things may be painted using \a p, but it is not needed to paint the text (this is done automatically outside of this method). Before calling, \a x, \a y_offset, \a w, \a h parameters are initialized, but you can tune these values depending on the context. You should set \a txt to a text representation of \a val, otherwise no text will be painted. \a p can be 0 - in this case no painting should be performed, becasue caller only expects that \a x, \a y_offset, \a w, \a h, \a txt parameters are tuned, if needed. \a p painter's pen is set to foreground color (usually black) that should be used to paint foreground information, if needed. For example boolean editor widget paints a rectangle using this color. */ virtual void setupContents(QPainter *p, bool focused, const QVariant& val, QString &txt, int &align, int &x, int &y_offset, int &w, int &h); /*! \return true if "selected text" color should be used to paint contents of the editor. True by default. It's false e.g. in boolean editor, where no selection is painted using paintSelectionBackground(). This flag is set in editor's constructor and checked in KexiTableView::paintCell(). Depending on it, appropriate ("text" or "selected text" color is set for painter) before setupContents() is called. */ bool usesSelectedTextColor() const; /*! For reimplementation. Paints selection's background using \a p. Most parameters are similar to these from setupContents(). */ virtual void paintSelectionBackground(QPainter *p, bool focused, const QString& txt, int align, int x, int y_offset, int w, int h, const QColor& fillColor, const QFontMetrics &fm, bool readOnly, bool fullRecordSelection); /*! Sometimes, editor can contain non-standard margin, for example combobox editor contains dropdown button at the right side. \return left margin's size; 0 by default. For reimplementation. */ int leftMargin() const; /*! Sometimes, editor can contain non-standard margin, for example combobox editor contains dropdown button at the right side. THe dropdown button's width is counted only if \a focused is true. \return right margin's size; 0 by default. For reimplementation. */ int rightMargin(bool focused) const; /*! Handles \a ke key event that came over the column that is bound to this editor. For implementation: true should be returned if \a ke should be accepted. If \a editorActive is true, this editor is currently active, i.e. the table view is in edit mode. By default false is returned. */ virtual bool handleKeyPress(QKeyEvent* ke, bool editorActive); /*! Handles double click request coming from the table view. \return true if it has been consumed. Reimplemented in KexiBlobTableEdit (to execute "insert file" action. */ virtual bool handleDoubleClick(); /*! Handles copy action for value. The \a value is copied to clipboard in format appropriate for the editor's impementation, e.g. for image cell it can be a pixmap. For a special case (combo box), \a visibleValue can be provided, so it can be copied to the clipboard instead of unreadable \a value. For reimplementation. */ virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) = 0; /*! \return width of \a value. For the default implementation \a val is converted to a string and width of this string is returned. */ virtual int widthForValue(const QVariant &val, const QFontMetrics &fm); /*! \return total size of this editor, including any buttons, etc. (if present). Reimplement this if you want to return more appropriate size. This impelmentation just returns QWidget::size(). */ virtual QSize totalSize() const; /*! Shows a special tooltip for \a value if needed, i.e. if the value could not fit inside \a rect for a given font metrics \a fm. \return true a normal tooltip should be displayed (using QToolTip,) and false if no tooltip should be displayed or a custom tooltip was displayed internally (not yet supported). Default implementation does nothing and returns false. If the cell is currentl focused (selected), \a focused is true. */ virtual bool showToolTipIfNeeded(const QVariant& value, const QRect& rect, const QFontMetrics& fm, bool focused); /*! Created internal editor for this editor is needed. This method is only implemented in KexiComboBoxTableEdit since it's visible value differs from internal value, so a different KexiTableEdit object is used to displaying the data. */ virtual void createInternalEditor(KDbConnection *conn, const KDbQuerySchema& schema); Q_SIGNALS: void editRequested(); void cancelRequested(); void acceptRequested(); protected: /*! Sets \a v as view widget for this editor. The view will be assigned as focus proxy for the editor, its events will be filtered, it will be resized when neede, and so on. */ void setViewWidget(QWidget *v); /*! Moves child widget within the viewport if the parent is scrollview (otherwise does nothing). Use this for child widgets that are outside of this editor widget, instead of calling QWidget::move(). */ void moveChild(QWidget * child, int x, int y); /*! Allows to force redrawing the related cell by the editor itself. Usable when the editor is not displayed by a QWidget but rather by table view cell itself, for example KexiBlobTableEdit. */ void repaintRelatedCell(); KDbTableViewColumn * const m_column; KexiTextFormatter* m_textFormatter; int m_leftMargin; int m_rightMargin, m_rightMarginWhenFocused; bool m_usesSelectedTextColor; //!< set in ctor, @see usesSelectedTextColor() private: //! @see widget() QWidget* m_view; }; //! Declaration of cell editor factory #define KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(factoryclassname) \ class factoryclassname : public KexiCellEditorFactoryItem \ { \ public: \ factoryclassname(); \ virtual ~factoryclassname(); \ \ protected: \ - virtual KexiTableEdit* createEditor(KDbTableViewColumn *column, QWidget* parent = 0); \ + virtual KexiTableEdit* createEditor(KDbTableViewColumn *column, QWidget* parent = 0) override; \ }; //! Implementation of cell editor factory #define KEXI_CELLEDITOR_FACTORY_ITEM_IMPL(factoryclassname, itemclassname) \ factoryclassname::factoryclassname() \ : KexiCellEditorFactoryItem() \ { \ m_className = "" #itemclassname ""; \ } \ \ factoryclassname::~factoryclassname() \ {} \ \ KexiTableEdit* factoryclassname::createEditor( \ KDbTableViewColumn *column, QWidget* parent) \ { \ return new itemclassname(column, parent); \ } #endif diff --git a/src/widget/tableview/kexitimetableedit.h b/src/widget/tableview/kexitimetableedit.h index 86a5b01b2..fc24ee610 100644 --- a/src/widget/tableview/kexitimetableedit.h +++ b/src/widget/tableview/kexitimetableedit.h @@ -1,65 +1,65 @@ /* This file is part of the KDE project Copyright (C) 2004,2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITIMETABLEEDIT_H #define KEXITIMETABLEEDIT_H #include "kexiinputtableedit.h" #include /*! @short Editor class for Time type. It is a replacement QTimeEdit due to usability problems: people are accustomed to use single-character cursor. Time format is retrieved from the KDE global settings and input/output is performed using QLineEdit (from KexiInputTableEdit). */ class KexiTimeTableEdit : public KexiInputTableEdit { Q_OBJECT public: explicit KexiTimeTableEdit(KDbTableViewColumn *column, QWidget *parent = 0); virtual ~KexiTimeTableEdit(); virtual void setupContents(QPainter *p, bool focused, const QVariant& val, - QString &txt, int &align, int &x, int &y_offset, int &w, int &h); - virtual QVariant value(); - virtual bool valueIsNull(); - virtual bool valueIsEmpty(); - virtual bool valueIsValid(); - virtual bool valueChanged(); + QString &txt, int &align, int &x, int &y_offset, int &w, int &h) override; + virtual QVariant value() override; + virtual bool valueIsNull() override; + virtual bool valueIsEmpty() override; + virtual bool valueIsValid() override; + virtual bool valueChanged() override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleAction(const QString& actionName); + virtual void handleAction(const QString& actionName) override; /*! Reimplemented after KexiInputTableEdit. */ - virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue); + virtual void handleCopyAction(const QVariant& value, const QVariant& visibleValue) override; protected: //! helper void setValueInInternalEditor(const QVariant &value); - virtual void setValueInternal(const QVariant& add, bool removeOld); + virtual void setValueInternal(const QVariant& add, bool removeOld) override; QTime timeValue(); //! Used to format and convert time values KexiTimeFormatter m_formatter; }; KEXI_DECLARE_CELLEDITOR_FACTORY_ITEM(KexiTimeEditorFactoryItem) #endif diff --git a/src/widget/undo/kundo2model.h b/src/widget/undo/kundo2model.h index 13237e619..2a0ffc72a 100644 --- a/src/widget/undo/kundo2model.h +++ b/src/widget/undo/kundo2model.h @@ -1,105 +1,105 @@ /* This file is part of the KDE project * Copyright (C) 2010 Matus Talcik * * 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. */ /**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef K_UNDO_2_MODEL #define K_UNDO_2_MODEL #include #include "kundo2stack.h" #include #include class KUndo2Model : public QAbstractItemModel { Q_OBJECT public: explicit KUndo2Model(QObject *parent = 0); KUndo2QStack *stack() const; virtual QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex parent(const QModelIndex &child) const; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + const QModelIndex &parent = QModelIndex()) const override; + virtual QModelIndex parent(const QModelIndex &child) const override; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QModelIndex selectedIndex() const; QItemSelectionModel *selectionModel() const; QString emptyLabel() const; void setEmptyLabel(const QString &label); void setCleanIcon(const QIcon &icon); QIcon cleanIcon() const; public Q_SLOTS: void setStack(KUndo2QStack *stack); private Q_SLOTS: void stackChanged(); void stackDestroyed(QObject *obj); void setStackCurrentIndex(const QModelIndex &index); private: KUndo2QStack *m_stack; QItemSelectionModel *m_sel_model; QString m_emty_label; QIcon m_clean_icon; }; #endif diff --git a/src/widget/utils/KexiDockableWidget.h b/src/widget/utils/KexiDockableWidget.h index b2e3d0a34..81f7ebf8a 100644 --- a/src/widget/utils/KexiDockableWidget.h +++ b/src/widget/utils/KexiDockableWidget.h @@ -1,58 +1,58 @@ /* This file is part of the KDE project Copyright (C) 2009 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDOCKABLEWIDGET_H #define KEXIDOCKABLEWIDGET_H #include "kexiguiutils_export.h" #include //! @short Ordinary QWidget that supports forcing size hint /*! The setSizeHint() method is needed be the main window to properly restore size on application startup. This widgets acts as a parent for a single child that can be set by setWidget(), so it is not necessary use inheritance. */ class KEXIGUIUTILS_EXPORT KexiDockableWidget : public QWidget { Q_OBJECT public: explicit KexiDockableWidget(QWidget* parent = 0); virtual ~KexiDockableWidget(); //! Sets child widget @a widget. //! The child is automatically added to internal layout (without margins) //! This method works only once. void setWidget(QWidget* widget); //! @return widget that has been set as a child. QWidget *widget() const; - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; void setSizeHint(const QSize& size); private: class Private; Private * const d; }; #endif diff --git a/src/widget/utils/kexicomboboxdropdownbutton.cpp b/src/widget/utils/kexicomboboxdropdownbutton.cpp index 2c57701af..6a0cbddc2 100644 --- a/src/widget/utils/kexicomboboxdropdownbutton.cpp +++ b/src/widget/utils/kexicomboboxdropdownbutton.cpp @@ -1,96 +1,96 @@ /* This file is part of the KDE project Copyright (C) 2006-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexicomboboxdropdownbutton.h" #include #include #include #include #include //! @internal A style that allows to alter some painting in KexiComboBoxDropDownButton. class KexiComboBoxDropDownButtonStyle : public QProxyStyle { Q_OBJECT public: explicit KexiComboBoxDropDownButtonStyle(const QString &baseStyleName) : QProxyStyle(baseStyleName) { } virtual ~KexiComboBoxDropDownButtonStyle() {} virtual void drawComplexControl(ComplexControl control, const QStyleOptionComplex * option, - QPainter * painter, const QWidget * widget = 0) const + QPainter * painter, const QWidget * widget = 0) const override { QStyleOptionToolButton opt(*qstyleoption_cast(option)); opt.state |= (State_MouseOver | State_DownArrow | State_Sunken); opt.state ^= (State_MouseOver | State_DownArrow | State_Sunken); QProxyStyle::drawComplexControl(control, &opt, painter, widget); } }; // ---- class Q_DECL_HIDDEN KexiComboBoxDropDownButton::Private { public: Private() : styleChangeEnabled(true) {} QPointer privateStyle; bool styleChangeEnabled; }; KexiComboBoxDropDownButton::KexiComboBoxDropDownButton(QWidget *parent) : QToolButton(parent) , d(new Private) { setAutoRaise(true); setArrowType(Qt::DownArrow); styleChanged(); } KexiComboBoxDropDownButton::~KexiComboBoxDropDownButton() { setStyle(0); delete d->privateStyle; d->privateStyle = 0; delete d; } void KexiComboBoxDropDownButton::styleChanged() { if (!d->styleChangeEnabled) return; d->styleChangeEnabled = false; if (d->privateStyle) { setStyle(0); delete static_cast(d->privateStyle); } setStyle(d->privateStyle = new KexiComboBoxDropDownButtonStyle(style()->objectName())); d->privateStyle->setParent(this); d->styleChangeEnabled = true; } bool KexiComboBoxDropDownButton::event(QEvent *event) { if (event->type() == QEvent::StyleChange) styleChanged(); return QToolButton::event(event); } #include "kexicomboboxdropdownbutton.moc" diff --git a/src/widget/utils/kexicomboboxdropdownbutton.h b/src/widget/utils/kexicomboboxdropdownbutton.h index baa3c0e6d..6d24d8443 100644 --- a/src/widget/utils/kexicomboboxdropdownbutton.h +++ b/src/widget/utils/kexicomboboxdropdownbutton.h @@ -1,47 +1,47 @@ /* This file is part of the KDE project Copyright (C) 2006-2014 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXICOMBOBOXDROPDOWNBUTTON_H #define KEXICOMBOBOXDROPDOWNBUTTON_H #include "kexiguiutils_export.h" #include //! @short A drop-down button for combo box widgets /*! Used in KexiComboBoxTableEdit. */ class KEXIGUIUTILS_EXPORT KexiComboBoxDropDownButton : public QToolButton { Q_OBJECT public: explicit KexiComboBoxDropDownButton(QWidget *parent = 0); virtual ~KexiComboBoxDropDownButton(); protected: - virtual bool event(QEvent *event); + virtual bool event(QEvent *event) override; private: void styleChanged(); class Private; Private * const d; }; #endif diff --git a/src/widget/utils/kexidropdownbutton.cpp b/src/widget/utils/kexidropdownbutton.cpp index 2c18c17c0..7dd5c45a6 100644 --- a/src/widget/utils/kexidropdownbutton.cpp +++ b/src/widget/utils/kexidropdownbutton.cpp @@ -1,131 +1,131 @@ /* This file is part of the KDE project Copyright (C) 2006-2008 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexidropdownbutton.h" #include #include #include #include #include #include #include //! @internal A style that removes menu indicator from KexiDropDownButton. class KexiDropDownButtonStyle : public QProxyStyle { Q_OBJECT public: explicit KexiDropDownButtonStyle(const QString &baseStyleName) : QProxyStyle(baseStyleName) { } virtual ~KexiDropDownButtonStyle() {} virtual void drawComplexControl( ComplexControl control, const QStyleOptionComplex * option, - QPainter * painter, const QWidget * widget = 0 ) const + QPainter * painter, const QWidget * widget = 0 ) const override { if (control == CC_ToolButton && qstyleoption_cast(option)) { QStyleOptionToolButton newOption(*qstyleoption_cast(option)); newOption.features &= ~QStyleOptionToolButton::HasMenu; QProxyStyle::drawComplexControl(control, &newOption, painter, widget); return; } QProxyStyle::drawComplexControl(control, option, painter, widget); } - virtual int styleHint( StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0 ) const + virtual int styleHint( StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0 ) const override { if (hint == QStyle::SH_ToolButton_PopupDelay) { return 0; } return QProxyStyle::styleHint(hint, option, widget, returnData); } }; KexiDropDownButton::KexiDropDownButton(QWidget *parent) : QToolButton(parent) { setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); KexiDropDownButtonStyle *s = new KexiDropDownButtonStyle(style()->objectName()); setStyle(s); s->setParent(this); //! @todo get this from a KStyle //! @todo use subControlRect /*TODO if (style()->objectName().toLower()=="thinkeramik") fixedWidth = 18; //typical width as in "windows" style else fixedWidth = style()->subControlRect( QStyle::CC_ComboBox, 0, QStyle::SC_ComboBoxArrow ).width(); setFixedWidth( fixedWidth ); */ } KexiDropDownButton::~KexiDropDownButton() { setStyle(0); } QSize KexiDropDownButton::sizeHint() const { return QSize(fontMetrics().maxWidth() + 2*2, fontMetrics().height()*2 + 2*2); } void KexiDropDownButton::paintEvent(QPaintEvent *e) { QToolButton::paintEvent(e); QPainter p(this); QStyleOptionToolButton option; option.initFrom(this); style()->drawPrimitive(QStyle::PE_IndicatorButtonDropDown, &option, &p); //! @todo use tableview's appearance parameters for color QRect r = rect(); QPen linePen(Qt::black); linePen.setWidth(1); p.setPen(linePen); p.drawLine(r.topLeft(), r.topRight()); } void KexiDropDownButton::keyPressEvent(QKeyEvent * e) { const int k = e->key(); const bool dropDown = (e->modifiers() == Qt::NoModifier && (k == Qt::Key_Space || k == Qt::Key_Enter || k == Qt::Key_Return || k == Qt::Key_F2 || k == Qt::Key_F4) ) || (e->modifiers() == Qt::AltModifier && k == Qt::Key_Down); if (dropDown) { e->accept(); animateClick(); QMouseEvent me(QEvent::MouseButtonPress, QPoint(2, 2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); QApplication::sendEvent(this, &me); return; } QToolButton::keyPressEvent(e); } #include "kexidropdownbutton.moc" diff --git a/src/widget/utils/kexidropdownbutton.h b/src/widget/utils/kexidropdownbutton.h index a9b160021..e37f95d9b 100644 --- a/src/widget/utils/kexidropdownbutton.h +++ b/src/widget/utils/kexidropdownbutton.h @@ -1,46 +1,46 @@ /* This file is part of the KDE project Copyright (C) 2006-2008 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIDROPDOWNBUTTON_H #define KEXIDROPDOWNBUTTON_H #include "kexiguiutils_export.h" #include //! @short A button for drop-down "Image" menu /*! Used in KexiDBImageBox and KexiBlobTableEdit. Additionally, the button reacts on pressing space, return, enter, F2, F4 and alt+down buttons. */ class KEXIGUIUTILS_EXPORT KexiDropDownButton : public QToolButton { Q_OBJECT public: explicit KexiDropDownButton(QWidget *parent = 0); virtual ~KexiDropDownButton(); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; protected: - virtual void paintEvent(QPaintEvent *e); - virtual void keyPressEvent(QKeyEvent * e); + virtual void paintEvent(QPaintEvent *e) override; + virtual void keyPressEvent(QKeyEvent * e) override; }; #endif diff --git a/src/widget/utils/kexirecordnavigator.h b/src/widget/utils/kexirecordnavigator.h index 39724b743..e6c0e9a74 100644 --- a/src/widget/utils/kexirecordnavigator.h +++ b/src/widget/utils/kexirecordnavigator.h @@ -1,192 +1,192 @@ /* This file is part of the KDE project Copyright (C) 2004 Lucijan Busch Copyright (C) 2003-2017 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXIRECORDNAVIGATOR_H #define KEXIRECORDNAVIGATOR_H #include "kexiguiutils_export.h" #include class QToolButton; class QAbstractScrollArea; class QScrollBar; class QEvent; class QPaintEvent; class KGuiItem; #include //! @short KexiRecordNavigator class provides a record navigator. /*! Record navigator is usually used for data tables (e.g. KexiTableView) or data-aware forms. You can plug KexiRecordNavigator object to your data-aware object in two ways: 1) By connectiong appropriate signals to slots (prevButtonClicked(), etc.) 2) A bit cleaner way: by inheriting from KexiRecordNavigatorHandler interface in your data-aware class and implementing all it's prototype methods like moveToRecordRequested(), and then calling setRecordHandler() on KexiRecordNavigator object. Note that using this method 2), you can create more than one navigator widget connected with your data-aware object (does not matter if this is useful). */ class KEXIGUIUTILS_EXPORT KexiRecordNavigator : public QWidget, public KexiRecordNavigatorIface { Q_OBJECT public: enum Button { ButtonFirst, ButtonPrevious, ButtonNext, ButtonLast, ButtonNew }; explicit KexiRecordNavigator(QAbstractScrollArea &parentView, QWidget *parent = 0); virtual ~KexiRecordNavigator(); /*! Sets record navigator handler. This allows to react on actions performed within navigator and vice versa. */ - void setRecordHandler(KexiRecordNavigatorHandler *handler); + void setRecordHandler(KexiRecordNavigatorHandler *handler) override; /*! \return true if data inserting is enabled (the default). */ bool isInsertingEnabled() const; /*! \return current record number displayed for this navigator. can return 0, if the 'text box's content is cleared. */ int currentRecordNumber() const; /*! \return record count displayed for this navigator. */ int recordCount() const; /*! Sets horizontal bar's \a hbar (at the bottom) geometry so this record navigator is properly positioned together with horizontal scroll bar. This method is used in QScrollView::setHBarGeometry() implementations: see KexiTableView::setHBarGeometry() and KexiFormScrollView::setHBarGeometry() for usage examples. */ - virtual void setHBarGeometry(QScrollBar & hbar, int x, int y, int w, int h); + virtual void setHBarGeometry(QScrollBar & hbar, int x, int y, int w, int h) override; /*! \return true if "editing" indicator is visible for this navigator. @see showEditingIndicator() */ bool editingIndicatorVisible() const; /*! \return true if "editing" indicator is enabled for this navigator. Only meaningful if setEditingIndicatorEnabled(true) is called. */ bool editingIndicatorEnabled() const; //! @short A set of GUI items usable for displaying related actions. /*! For instance, the items are used by Kexi main window to create shared actions. */ class KEXIGUIUTILS_EXPORT Actions { public: static const KGuiItem& moveToFirstRecord(); static const KGuiItem& moveToPreviousRecord(); static const KGuiItem& moveToNextRecord(); static const KGuiItem& moveToLastRecord(); static const KGuiItem& moveToNewRecord(); }; /*! @return pixmap with a "pen" icon appropriate to indicate "editing" state for a row. Can be reused elsewhere for consistency. Foreground color from @a palette palette is used to colorize the icon. */ static QPixmap penPixmap(const QPalette &palette); /*! @return pixmap with a "plus" icon appropriate to indicate "adding" state for a row Can be reused elsewhere for consistency. Foreground color from @a palette palette is used to colorize the icon. */ static QPixmap plusPixmap(const QPalette &palette); /*! @return pixmap with a "pointer" icon appropriate to indicate "current" state for a row Can be reused elsewhere for consistency. Foreground color from @a palette palette is used to colorize the icon. */ static QPixmap pointerPixmap(const QPalette &palette); public Q_SLOTS: /*! Sets insertingEnabled flag. If true, "+" button will be enabled. */ - void setInsertingEnabled(bool set); + void setInsertingEnabled(bool set) override; /*! Sets visibility of "inserting" button. */ - void setInsertingButtonVisible(bool set); + void setInsertingButtonVisible(bool set) override; /*! Sets visibility of the place where "editing" indicator will be displayed. "editing" indicator will display KexiRecordMarker::penImage() image when setEditingIndicatorVisible() is called. This method is currently used e.g. within standard kexi forms (see KexiFormScrollView class). */ void setEditingIndicatorEnabled(bool set); /*! Shows or hides "editing" indicator. */ - virtual void showEditingIndicator(bool show); + virtual void showEditingIndicator(bool show) override; virtual void setEnabled(bool set); /*! Sets current record number for this navigator, i.e. a value that will be displayed in the 'record number' text box. This can also affect button's enabling and disabling. @p r is counted from 1; if it is 0 'record number' text box's content is cleared. */ - virtual void setCurrentRecordNumber(int r); + virtual void setCurrentRecordNumber(int r) override; /*! Sets record count for this navigator. This can also affect button's enabling and disabling. By default count is 0. */ - virtual void setRecordCount(int count); + virtual void setRecordCount(int count) override; /*! Sets label text at the left of the for record navigator's button. By default this label contains translated "Record:" text. */ - virtual void setLabelText(const QString& text); + virtual void setLabelText(const QString& text) override; void setButtonToolTipText(KexiRecordNavigator::Button btn, const QString& tooltip); void setButtonWhatsThisText(KexiRecordNavigator::Button btn, const QString& whatsThis); void setNumberFieldToolTips(const QString& numberTooltip, const QString& countTooltip); Q_SIGNALS: void prevButtonClicked(); void nextButtonClicked(); void lastButtonClicked(); void firstButtonClicked(); void newButtonClicked(); void recordNumberEntered(int r); protected Q_SLOTS: void slotPrevButtonClicked(); void slotNextButtonClicked(); void slotLastButtonClicked(); void slotFirstButtonClicked(); void slotNewButtonClicked(); protected: //! @internal used for keyboard handling. - virtual bool eventFilter(QObject *o, QEvent *e); + virtual bool eventFilter(QObject *o, QEvent *e) override; - virtual void wheelEvent(QWheelEvent *e); + virtual void wheelEvent(QWheelEvent *e) override; - virtual void resizeEvent(QResizeEvent *e); + virtual void resizeEvent(QResizeEvent *e) override; QToolButton* createAction(const KGuiItem& item); - virtual void paintEvent(QPaintEvent* pe); + virtual void paintEvent(QPaintEvent* pe) override; void updateButtons(int recCnt); class Private; Private * const d; }; #endif diff --git a/src/widget/utils/kexitooltip.h b/src/widget/utils/kexitooltip.h index 170d48c15..4eb2ee1c7 100644 --- a/src/widget/utils/kexitooltip.h +++ b/src/widget/utils/kexitooltip.h @@ -1,52 +1,52 @@ /* This file is part of the KDE project Copyright (C) 2006 Jarosław Staniek This program 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 program 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 program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KEXITOOLTIP_H #define KEXITOOLTIP_H #include "kexiguiutils_export.h" #include #include #include //! \brief A tooltip that can display rich content class KEXIGUIUTILS_EXPORT KexiToolTip : public QWidget { Q_OBJECT public: explicit KexiToolTip(const QVariant& value, QWidget* parent = 0); virtual ~KexiToolTip(); - virtual QSize sizeHint() const; + virtual QSize sizeHint() const override; public Q_SLOTS: virtual void show(); protected: - virtual void paintEvent(QPaintEvent *pev); + virtual void paintEvent(QPaintEvent *pev) override; virtual void drawFrame(QPainter& p); virtual void drawContents(QPainter& p); private: class Private; Private * const d; }; #endif