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

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003-2004 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KEXIACTIONPROXY_H
0021 #define KEXIACTIONPROXY_H
0022 
0023 
0024 #include "kexiproject.h"
0025 #include "kexisharedactionhost.h"
0026 
0027 class QAction;
0028 class KexiActionProxy;
0029 
0030 //! Abstract helper class used to connect shared actions from outside of shared-action-aware object.
0031 /*! Methods like KexiActionProxy::plugSharedAction() are not public, but
0032  sometimes there's need for plugging an object that implements KexiActionProxy interface
0033  from outside.
0034 
0035  Reimplement KexiSharedActionConnector: do all needed connections in the constructor.
0036 
0037  For example, with KexiQueryDesignerSqlEditor class we're using KTextEdit
0038  (or KTextEditor::View) that's not shared-action-aware. So it's needed to connect
0039  e.g. "edit_undo" shared action to undo() slot, and so on. It is impelmented in more
0040  generic way by implementing KTextEdit_SharedActionConnector class,
0041  so the connection can be reused many times by just allocating KTextEdit_SharedActionConnector
0042  object for any KTextEditor when required (not only within KexiQueryDesignerSqlEditor).
0043 */
0044 //! @todo add method for setAvailable()
0045 class KEXICORE_EXPORT KexiSharedActionConnector
0046 {
0047 public:
0048     /* Connects shared actions offered by \a proxy to \a obj. */
0049     KexiSharedActionConnector(KexiActionProxy* proxy, QObject *obj);
0050     ~KexiSharedActionConnector();
0051 
0052 protected:
0053     void plugSharedAction(const QString& action_name, const char *slot);
0054 
0055     KexiActionProxy* m_proxy;
0056     QObject *m_object;
0057 };
0058 
0059 //! An interface that acts as proxy for shared actions within the application.
0060 /*!
0061  For example, edit->copy action can be reused to copy different types of items.
0062  Availability and meaning of given action depends on the context, while
0063  the context changes e.g. when another window is activated.
0064  This class is mostly used by subclassing in KexiWindow or KexiDockBase
0065  - you can subclass in a similar way.
0066 */
0067 class KEXICORE_EXPORT KexiActionProxy
0068 {
0069 public:
0070     /*! Constructs action proxy for object \a receiver, using \a host.
0071      If \a host is NULL, KexiSharedActionHost::defaultHost() is used.
0072      (you must be sure that it's true) -- it is casted to QObject and assigned as the receiver.*/
0073     explicit KexiActionProxy(QObject *receiver , KexiSharedActionHost *host = 0);
0074     virtual ~KexiActionProxy();
0075 
0076     /*! Activates  action named \a action_name for this proxy. If the action is executed
0077      (accepted), true is returned. */
0078     bool activateSharedAction(const QString& action_name, bool alsoCheckInChildren = true);
0079 
0080     /*! Sets host to \a host; rerely used. */
0081     void setSharedActionHost(KexiSharedActionHost& host) {
0082         m_host = &host;
0083     }
0084 
0085     /*! \return true, if action named \a action_name is enabled within the proxy.
0086      False is returned either if the action is not available or is not supported.
0087      \ sa isSupported() */
0088     bool isAvailable(const QString& action_name, bool alsoCheckInChildren = true) const;
0089 
0090     /*! \return true, if action named \a action_name is supported by the proxy. */
0091     bool isSupported(const QString& action_name) const;
0092 
0093 protected:
0094     /*! Plugs shared action named \a action_name to slot \a slot in \a receiver.
0095      \a Receiver is usually a child of _this_ widget. */
0096     void plugSharedAction(const QString& action_name, QObject* receiver, const char *slot);
0097 
0098     void unplugSharedAction(const QString& action_name);
0099 
0100     /*! Typical version of plugAction() method -- plugs action named \a action_name
0101      to slot \a slot in _this_ widget. */
0102     inline void plugSharedAction(const QString& action_name, const char *slot) {
0103         plugSharedAction(action_name, m_receiver, slot);
0104     }
0105 
0106     /*! Plugs action named \a action_name to a widget \a w, so the action is visible on this widget
0107      as an item. \a w will typically be a menu, popup menu or a toolbar.
0108      Does nothing if no action found, so generally this is safer than just caling e.g.
0109      <code> action("myaction")->plug(myPopup); </code>
0110      \sa action(), QWidget::addAction(QAction*) */
0111     void plugSharedAction(const QString& action_name, QWidget* w);
0112 
0113     /*! Unplugs action named \a action_name from a widget \a w.
0114      \sa plugSharedAction(const char *action_name, QWidget* w) */
0115     void unplugSharedAction(const QString& action_name, QWidget* w);
0116 
0117     /*! Like above, but creates alternative action as a copy of \a action_name,
0118      with \a alternativeText set. When this action is activated, just original action
0119      specified by \a action_name is activated. The aternative action has autmatically set name as:
0120      action_name + "_alt". The new action's owner is \a w. You can delete
0121      this action without informing action proxy about this.
0122      \return newly created action or 0 if \a action_name not found. */
0123     QAction * plugSharedAction(const QString& action_name, const QString& alternativeText, QWidget* w);
0124 
0125     /*! \return action named with \a name or NULL if there is no such action. */
0126     virtual QAction* sharedAction(const QString& action_name);
0127 
0128     inline QObject *receiver() const {
0129         return m_receiver;
0130     }
0131 
0132     virtual void setAvailable(const QString& action_name, bool set);
0133 
0134     /*! Adds \a child of this proxy. Children will receive activateSharedAction() event,
0135      If activateSharedAction() "event" is not consumed by the main proxy,
0136      we start to iterate over proxy children (in unspecified order) to and call
0137      activateSharedAction() on every child until one of them accept the "event".
0138 
0139      If proxy child is destroyed, it is automatically detached from its parent proxy.
0140      Parent proxy is 0 by default. This pointer is properly cleared when parent proxy is destroyed. */
0141     void addActionProxyChild(KexiActionProxy* child);
0142 
0143     void takeActionProxyChild(KexiActionProxy* child);
0144 
0145     KexiSharedActionHost *m_host;
0146     QPointer<QObject> m_receiver;
0147 
0148     QList<KexiActionProxy*> m_sharedActionChildren;
0149 
0150     QList<QAction *> m_alternativeActions;
0151 
0152     KexiActionProxy* m_actionProxyParent;
0153 
0154     QObject m_signal_parent; //!< it's just to have common parent for owned signals
0155 
0156 public:
0157     //! For internal use by addActionProxyChild(). \a parent can be 0.
0158     void setActionProxyParent_internal(KexiActionProxy* parent);
0159 
0160     //! @internal
0161     KexiActionProxy *m_focusedChild;
0162 
0163     friend class KexiSharedActionHost;
0164     friend class KexiSharedActionConnector;
0165 
0166 private:
0167     class Private;
0168     Private * const d;
0169 };
0170 
0171 #endif