File indexing completed on 2022-11-23 11:08:53

0001 /* This file is part of the KDE project
0002    Copyright (C) 2004-2015 Jarosław Staniek <staniek@kde.org>
0003 
0004    Contains parts of kmessagebox.h
0005    Copyright (C) 1999 Waldo Bastian (bastian@kde.org)
0006 
0007    This library is free software; you can redistribute it and/or
0008    modify it under the terms of the GNU Library General Public
0009    License as published by the Free Software Foundation; either
0010    version 2 of the License, or (at your option) any later version.
0011 
0012    This library is distributed in the hope that it will be useful,
0013    but WITHOUT ANY WARRANTY; without even the implied warranty of
0014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015    Library General Public License for more details.
0016 
0017    You should have received a copy of the GNU Library General Public License
0018    along with this library; see the file COPYING.LIB.  If not, write to
0019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #ifndef KDB_MSGHANDLER_H
0024 #define KDB_MSGHANDLER_H
0025 
0026 #include <QPointer>
0027 #include <QHash>
0028 #include <QVariant>
0029 #include <QWidget>
0030 
0031 #include "kdb_export.h"
0032 
0033 class KDbResult;
0034 class KDbResultable;
0035 class KDbMessageHandler;
0036 
0037 //! A guard class for transmitting messages based on KDbResult
0038 /*! It's intended use is for top-level public methods in applications that have to display
0039  messages. Create it's instance on stack; at the end of the block, on KDbMessageGuard's
0040  destruction result will be checked. If it's not empty, error is passed to the associated
0041  message handler.
0042  The example below emits error message if result is not empty before .
0043  @code
0044  class MyClass : ... public KDbResultable {
0045  [..]
0046      MyClass(KDbMessageHandler *handler) {
0047          setMessageHandler(handler); // need ...
0048      }
0049      bool connectToProject() {
0050          KDbMessageGuard mg(this); // MyClass is KDbResultable so this easy notation is possible
0051          if (... something failed ...) {
0052               m_result = KDbResult(tr("Operation failed."));
0053               return false; // ~KDbMessageGuard called here, m_result is passed to messageHandler()
0054          }
0055          // ...
0056          return true; // ~KDbMessageGuard called here is a no-op because there's no error in m_result
0057      }
0058  };
0059  @endcode
0060  There are two equivalent variants of usage:
0061  - using the KDbResultable object as in the example above (recommended)
0062  - using a reference to a KDbResult and a KDbMessageHandler
0063  @note instantiating KDbMessageGuard objects on the heap makes not much sense.
0064 */
0065 class KDB_EXPORT KDbMessageGuard
0066 {
0067 public:
0068     //! Builds a guard in the current code block using @a resultable
0069     //! Infromation from @a resultable will be used in ~KDbMessageGuard() to pass message
0070     //! to the resultable->messageHandler() handler if the handler is present
0071     //! and resultable->result().isError() == true.
0072     //! @note @a resultable is required
0073     explicit KDbMessageGuard(KDbResultable *resultable);
0074 
0075     //! Builds a guard in the current code block using a reference to @a result and @a handler
0076     //! These will be used in ~KDbMessageGuard() is result.isError() == true.
0077     //! @note @a handler is required
0078     KDbMessageGuard(const KDbResult &result, KDbMessageHandler *handler);
0079 
0080     ~KDbMessageGuard();
0081 
0082 protected:
0083     Q_DISABLE_COPY(KDbMessageGuard)
0084     class Private;
0085     Private * const d;
0086 };
0087 
0088 /*! Helper for setting temporary message title for an KDbResult object.
0089  Message title is a text prepended to error or warning messages.
0090  Use it as follows:
0091  @code
0092  KDbMessageTitleSetter ts(&m_result, tr("Terrible error occurred"));
0093  @endcode
0094  After leaving the current code block, myResultableObject's message title will be set back to the previous value.
0095 */
0096 class KDB_EXPORT KDbMessageTitleSetter
0097 {
0098 public:
0099     explicit KDbMessageTitleSetter(KDbResult* result, const QString& message = QString());
0100     explicit KDbMessageTitleSetter(KDbResultable* resultable, const QString& message = QString());
0101     ~KDbMessageTitleSetter();
0102 
0103 protected:
0104     KDbResult* m_result;
0105     QString m_prevMsgTitle;
0106 private:
0107     Q_DISABLE_COPY(KDbMessageTitleSetter)
0108 };
0109 
0110 //! An abstract class used to specify GUI information such as button texts tooltips and icons.
0111 class KDbGuiItem : private QHash<QByteArray, QVariant>
0112 {
0113 public:
0114     KDbGuiItem();
0115     ~KDbGuiItem();
0116     inline KDbGuiItem& setProperty(const QByteArray& name, const QVariant& value)
0117         { insert(name, value); return *this; }
0118     void removeProperty(const QByteArray& name) { remove(name); }
0119     inline bool isEmpty() const { return QHash<QByteArray, QVariant>::isEmpty(); }
0120     inline QVariant property(const QByteArray& name, const QVariant& defaultValue = QVariant()) const
0121         { return value(name, defaultValue); }
0122     inline bool hasProperty(const QByteArray& name) const { return contains(name); }
0123     inline QList<QByteArray> propertyNames() const { return keys(); }
0124     inline void clear() { QHash<QByteArray, QVariant>::clear(); }
0125 private:
0126     class Private;
0127     Private * const d;
0128     Q_DISABLE_COPY(KDbGuiItem)
0129 };
0130 
0131 /*! A prototype for Message Handler usable
0132  for reacting on messages sent by KDbObject object(s).
0133 */
0134 class KDB_EXPORT KDbMessageHandler
0135 {
0136 public:
0137     //! Message types
0138     enum MessageType
0139     {
0140         Information = 1,
0141         Error = 2,
0142         Warning = 3,
0143         Sorry = 4,
0144         Fatal = 5
0145     };
0146 
0147     //! Question types
0148     enum QuestionType
0149     {
0150         QuestionYesNo = 1,
0151         QuestionYesNoCancel = 2,
0152         WarningYesNo = 3,
0153         WarningContinueCancel = 4,
0154         WarningYesNoCancel = 5
0155     };
0156 
0157     //! Button codes
0158     enum ButtonCode
0159     {
0160         Ok = 1,
0161         Cancel = 2,
0162         Yes = Ok,
0163         No = 3,
0164         Continue = 4
0165     };
0166 
0167     //! Message options
0168     enum Option
0169     {
0170         Notify = 1,        ///< Emit a KNotify event
0171         AllowLink = 2,     ///< The message may contain links.
0172         Dangerous = 4      ///< The action to be confirmed by the dialog is a potentially destructive one
0173     };
0174     Q_DECLARE_FLAGS(Options, Option)
0175 
0176     /*! Constructs message handler, @a parent is a widget that will be a parent
0177      for displaying gui elements (e.g. message boxes). Can be 0 for non-gui usage. */
0178     explicit KDbMessageHandler(QWidget *parent = nullptr);
0179 
0180     virtual ~KDbMessageHandler();
0181 
0182     /*! @return true if the handler is enables so messages are not blocked.
0183      @see setEnabled(bool) */
0184     bool messagesEnabled() const;
0185 
0186     /*! Enables or disabled the handler to block/unblock its messages.
0187      Sometimes both lower- and higher-level messages are received,
0188      what is not optimal as only one of them should be displayed (e.g. a higher level
0189      with details). This can be solved by calling setEnabled(false) shortly before
0190      an action that can send the unwanted message. Afterwards messages can be enabled again
0191      by calling setEnabled(true).
0192      By default messages are enabled. */
0193     void setMessagesEnabled(bool enable);
0194 
0195     /*! Shows error message with @a title (it is not caption) and details. */
0196     virtual void showErrorMessage(
0197         KDbMessageHandler::MessageType messageType,
0198         const QString &message,
0199         const QString &details = QString(),
0200         const QString &caption = QString()
0201     ) = 0;
0202 
0203     /*! Shows error message with @a message text. Existing error message from @a obj object
0204      is also copied, if present. */
0205     virtual void showErrorMessage(
0206         const KDbResult& result,
0207         KDbMessageHandler::MessageType messageType = Error,
0208         const QString& message = QString(),
0209         const QString& caption = QString()
0210     ) = 0;
0211 
0212     /*! Interactively asks a question. For GUI version, message boxes are used.
0213      @a defaultResult is returned in case when no message handler is installed.
0214      @a message should contain translated string.
0215      Value of ButtonCode is returned.
0216      Reimplement this. This implementation does nothing, just returns @a defaultResult. */
0217     virtual KDbMessageHandler::ButtonCode askQuestion(
0218             KDbMessageHandler::QuestionType messageType,
0219             const QString& message,
0220             const QString &caption = QString(),
0221             KDbMessageHandler::ButtonCode defaultResult = KDbMessageHandler::Yes,
0222             const KDbGuiItem &buttonYes = KDbGuiItem(),
0223             const KDbGuiItem &buttonNo = KDbGuiItem(),
0224             const QString &dontShowAskAgainName = QString(),
0225             KDbMessageHandler::Options options = nullptr,
0226             KDbMessageHandler* msgHandler = nullptr);
0227 
0228     //! @return message redirection for this handler or 0 if there is no redirection.
0229     KDbMessageHandler* redirection();
0230 
0231     //! @overload KDbMessageHandler* redirection()
0232     const KDbMessageHandler* redirection() const;
0233 
0234     /*! Sets redirection of all messages for this handler to @a otherHandler.
0235      Passing 0 removes redirection. Setting new redirection replaces previous. */
0236     void setRedirection(KDbMessageHandler *otherHandler);
0237 
0238 protected:
0239     /*! @return a widget that will be parent for displaying gui elements (e.g. message boxes).
0240      Can be 0 for non-gui cases. */
0241     QWidget *parentWidget();
0242 
0243     class Private;
0244     Private * const d;
0245 private:
0246     Q_DISABLE_COPY(KDbMessageHandler)
0247 };
0248 
0249 #endif