File indexing completed on 2024-04-28 16:54:26

0001 /*
0002     SPDX-FileCopyrightText: 2000 Carsten Pfeiffer <pfeiffer@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #pragma once
0007 
0008 #include <QHash>
0009 #include <QSharedPointer>
0010 #include <QStringList>
0011 
0012 #include <KSharedConfig>
0013 
0014 class History;
0015 class HistoryItem;
0016 class QTimer;
0017 
0018 class KConfig;
0019 class QMenu;
0020 class QAction;
0021 
0022 class ClipAction;
0023 struct ClipCommand;
0024 typedef QList<ClipAction *> ActionList;
0025 
0026 class URLGrabber : public QObject
0027 {
0028     Q_OBJECT
0029 
0030 public:
0031     explicit URLGrabber(History *history);
0032     ~URLGrabber() override;
0033 
0034     /**
0035      * Checks a given string whether it matches any of the user-defined criteria.
0036      * If it does, the configured action will be executed.
0037      */
0038     void checkNewData(QSharedPointer<const HistoryItem> item);
0039     void invokeAction(QSharedPointer<const HistoryItem> item);
0040 
0041     ActionList actionList() const
0042     {
0043         return m_myActions;
0044     }
0045     void setActionList(const ActionList &);
0046 
0047     void loadSettings();
0048     void saveSettings() const;
0049 
0050     int popupTimeout() const
0051     {
0052         return m_myPopupKillTimeout;
0053     }
0054     void setPopupTimeout(int timeout)
0055     {
0056         m_myPopupKillTimeout = timeout;
0057     }
0058 
0059     QStringList excludedWMClasses() const
0060     {
0061         return m_myAvoidWindows;
0062     }
0063     void setExcludedWMClasses(const QStringList &list)
0064     {
0065         m_myAvoidWindows = list;
0066     }
0067 
0068     bool stripWhiteSpace() const
0069     {
0070         return m_stripWhiteSpace;
0071     }
0072     void setStripWhiteSpace(bool enable)
0073     {
0074         m_stripWhiteSpace = enable;
0075     }
0076 
0077 private:
0078     const ActionList &matchingActions(const QString &, bool automatically_invoked);
0079     void execute(const ClipAction *action, int commandIdx) const;
0080     bool isAvoidedWindow() const;
0081     void actionMenu(QSharedPointer<const HistoryItem> item, bool automatically_invoked);
0082     void matchingMimeActions(const QString &clipData);
0083 
0084     ActionList m_myActions;
0085     ActionList m_myMatches;
0086     QStringList m_myAvoidWindows;
0087     QSharedPointer<const HistoryItem> m_myClipItem;
0088     ClipAction *m_myCurrentAction;
0089 
0090     // holds mappings of menu action IDs to action commands (action+cmd index in it)
0091     QHash<QString, QPair<ClipAction *, int>> m_myCommandMapper;
0092     QMenu *m_myMenu;
0093     QTimer *m_myPopupKillTimer;
0094     int m_myPopupKillTimeout;
0095     bool m_stripWhiteSpace;
0096     History *m_history;
0097 
0098 private Q_SLOTS:
0099     void slotItemSelected(QAction *action);
0100     void slotKillPopupMenu();
0101 
0102 Q_SIGNALS:
0103     void sigPopup(QMenu *);
0104     void sigDisablePopup();
0105 };
0106 
0107 struct ClipCommand {
0108     /**
0109      * What to do with output of command
0110      */
0111     enum Output {
0112         IGNORE, // Discard output
0113         REPLACE, // Replace clipboard entry with output
0114         ADD, // Add output as new clipboard element
0115     };
0116 
0117     ClipCommand(const QString &_command,
0118                 const QString &_description,
0119                 bool enabled = true,
0120                 const QString &_icon = QString(),
0121                 Output _output = IGNORE,
0122                 const QString &serviceStorageId = QString());
0123 
0124     QString command;
0125     QString description;
0126     bool isEnabled;
0127     QString icon;
0128     Output output;
0129     // If this is set, it's an app to handle a mimetype, and will be launched normally using KRun.
0130     // StorageId is used instead of KService::Ptr, because the latter disallows operator=.
0131     QString serviceStorageId;
0132 };
0133 
0134 Q_DECLARE_METATYPE(ClipCommand::Output)
0135 
0136 /**
0137  * Represents one configured action. An action consists of one regular
0138  * expression, an (optional) description and a list of ClipCommands
0139  * (a command to be executed, a description and an enabled/disabled flag).
0140  */
0141 class ClipAction
0142 {
0143 public:
0144     explicit ClipAction(const QString &regExp = QString(), const QString &description = QString(), bool automagic = true);
0145 
0146     ClipAction(KSharedConfigPtr kc, const QString &);
0147     ~ClipAction();
0148 
0149     QString actionRegexPattern() const
0150     {
0151         return m_regexPattern;
0152     }
0153     void setActionRegexPattern(const QString &pattern)
0154     {
0155         m_regexPattern = pattern;
0156     }
0157 
0158     QStringList actionCapturedTexts() const
0159     {
0160         return m_regexCapturedTexts;
0161     }
0162     void setActionCapturedTexts(const QStringList &captured)
0163     {
0164         m_regexCapturedTexts = captured;
0165     }
0166 
0167     void setDescription(const QString &d)
0168     {
0169         m_myDescription = d;
0170     }
0171     QString description() const
0172     {
0173         return m_myDescription;
0174     }
0175 
0176     void setAutomatic(bool automatic)
0177     {
0178         m_automatic = automatic;
0179     }
0180     bool automatic() const
0181     {
0182         return m_automatic;
0183     }
0184 
0185     /**
0186      * Removes all ClipCommands associated with this ClipAction.
0187      */
0188     void clearCommands()
0189     {
0190         m_myCommands.clear();
0191     }
0192 
0193     void addCommand(const ClipCommand &cmd);
0194 
0195     /**
0196      * Replaces command at index @p idx with command @p newCmd
0197      */
0198     void replaceCommand(int idx, const ClipCommand &newCmd);
0199 
0200     /**
0201      * Returns command by its index in command list
0202      */
0203     ClipCommand command(int idx) const
0204     {
0205         return m_myCommands.at(idx);
0206     }
0207 
0208     QList<ClipCommand> commands() const
0209     {
0210         return m_myCommands;
0211     }
0212 
0213     /**
0214      * Saves this action to a a given KConfig object
0215      */
0216     void save(KSharedConfigPtr, const QString &) const;
0217 
0218 private:
0219     QString m_regexPattern;
0220     QStringList m_regexCapturedTexts;
0221     QString m_myDescription;
0222     QList<ClipCommand> m_myCommands;
0223     bool m_automatic;
0224 };