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

0001 /*
0002     SPDX-FileCopyrightText: Andrew Stanley-Jones <asj@cban.com>
0003     SPDX-FileCopyrightText: 2004 Esben Mose Hansen <kde@mosehansen.dk>
0004     SPDX-FileCopyrightText: 2008 Dmitry Suzdalev <dimsuz@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 #pragma once
0009 
0010 #include "config-klipper.h"
0011 
0012 #include <QClipboard>
0013 #include <QElapsedTimer>
0014 #include <QPointer>
0015 #include <QTimer>
0016 
0017 #include <KTextEdit>
0018 
0019 #include "urlgrabber.h"
0020 
0021 class KToggleAction;
0022 class KActionCollection;
0023 class KlipperPopup;
0024 class URLGrabber;
0025 class QTime;
0026 class History;
0027 class QAction;
0028 class QMenu;
0029 class QMimeData;
0030 class HistoryItem;
0031 class KNotification;
0032 class KSystemClipboard;
0033 
0034 namespace KWayland
0035 {
0036 namespace Client
0037 {
0038 class PlasmaShell;
0039 }
0040 }
0041 
0042 enum class KlipperMode {
0043     Standalone,
0044     DataEngine,
0045 };
0046 
0047 class ClipboardContentTextEdit : public KTextEdit
0048 {
0049     Q_OBJECT
0050 public:
0051     ClipboardContentTextEdit(QWidget *parent);
0052     void keyPressEvent(QKeyEvent *event) override;
0053     Q_SIGNAL void done();
0054 };
0055 
0056 class Klipper : public QObject
0057 {
0058     Q_OBJECT
0059     Q_CLASSINFO("D-Bus Interface", "org.kde.klipper.klipper")
0060 
0061 public Q_SLOTS:
0062     Q_SCRIPTABLE QString getClipboardContents();
0063     Q_SCRIPTABLE void setClipboardContents(const QString &s);
0064     Q_SCRIPTABLE void clearClipboardContents();
0065     Q_SCRIPTABLE void clearClipboardHistory();
0066     Q_SCRIPTABLE void saveClipboardHistory();
0067     Q_SCRIPTABLE QStringList getClipboardHistoryMenu();
0068     Q_SCRIPTABLE QString getClipboardHistoryItem(int i);
0069     Q_SCRIPTABLE void showKlipperPopupMenu();
0070     Q_SCRIPTABLE void showKlipperManuallyInvokeActionMenu();
0071 
0072 public:
0073     Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mode = KlipperMode::Standalone);
0074     ~Klipper() override;
0075 
0076     bool eventFilter(QObject *object, QEvent *event) override;
0077 
0078     /**
0079      * Get clipboard history (the "document")
0080      */
0081     History *history()
0082     {
0083         return m_history;
0084     }
0085 
0086     URLGrabber *urlGrabber() const
0087     {
0088         return m_myURLGrabber;
0089     }
0090 
0091     void saveSettings() const;
0092 
0093     QMenu *actionsPopup() const
0094     {
0095         return m_actionsPopup;
0096     }
0097 
0098     KlipperPopup *popup()
0099     {
0100         return m_popup;
0101     }
0102 
0103     void editData(const QSharedPointer<const HistoryItem> &item);
0104     void showBarcode(const QSharedPointer<const HistoryItem> &item);
0105 
0106 public Q_SLOTS:
0107     void saveSession();
0108     void slotHistoryTopChanged();
0109     void slotConfigure();
0110     void slotCycleNext();
0111     void slotCyclePrev();
0112 
0113 protected:
0114     /**
0115      * The selection modes
0116      *
0117      * Don't use 1, as I use that as a guard against passing
0118      * a boolean true as a mode.
0119      */
0120     enum SelectionMode {
0121         Clipboard = 2,
0122         Selection = 4,
0123     };
0124     enum class ClipboardUpdateReason {
0125         UpdateClipboard,
0126         PreventEmptyClipboard,
0127     };
0128 
0129     /**
0130      * Loads history from disk.
0131      */
0132     bool loadHistory();
0133 
0134     /**
0135      * Save history to disk
0136      * @param empty save empty history instead of actual history
0137      */
0138     void saveHistory(bool empty = false);
0139 
0140     /**
0141      * Check data in clipboard, and if it passes these checks,
0142      * store the data in the clipboard history.
0143      */
0144     void checkClipData(bool selectionMode);
0145 
0146     /**
0147      * Enter clipboard data in the history.
0148      */
0149     QSharedPointer<HistoryItem> applyClipChanges(const QMimeData *data, bool selectionMode);
0150 
0151     void setClipboard(const HistoryItem &item, int mode, ClipboardUpdateReason updateReason = ClipboardUpdateReason::UpdateClipboard);
0152     bool ignoreClipboardChanges() const;
0153 
0154     KSharedConfigPtr config() const
0155     {
0156         return m_config;
0157     }
0158 
0159 Q_SIGNALS:
0160     void passivePopup(const QString &caption, const QString &text);
0161     void editFinished(QSharedPointer<const HistoryItem> item, int result);
0162 
0163 public Q_SLOTS:
0164     void slotPopupMenu();
0165     void slotAskClearHistory();
0166     void setURLGrabberEnabled(bool);
0167 
0168 protected Q_SLOTS:
0169     void showPopupMenu(QMenu *);
0170     void slotRepeatAction();
0171     void disableURLGrabber();
0172 
0173 private Q_SLOTS:
0174     void newClipData(QClipboard::Mode);
0175     void slotClearClipboard();
0176 
0177     void slotHistoryChanged();
0178 
0179     void slotQuit();
0180     void slotStartShowTimer();
0181 
0182     void slotClearOverflow();
0183     void slotCheckPending();
0184 
0185     void loadSettings();
0186 
0187 private:
0188     static void updateTimestamp();
0189 
0190     KSystemClipboard *m_clip;
0191 
0192     QElapsedTimer m_showTimer;
0193 
0194     History *m_history;
0195     KlipperPopup *m_popup;
0196     int m_overflowCounter;
0197 
0198     KToggleAction *m_toggleURLGrabAction;
0199     QAction *m_clearHistoryAction;
0200     QAction *m_repeatAction;
0201     QAction *m_editAction;
0202     QAction *m_showBarcodeAction;
0203     QAction *m_configureAction;
0204     QAction *m_quitAction;
0205     QAction *m_cycleNextAction;
0206     QAction *m_cyclePrevAction;
0207     QAction *m_showOnMousePos;
0208 
0209     bool m_bKeepContents : 1;
0210     bool m_bURLGrabber : 1;
0211     bool m_bReplayActionInHistory : 1;
0212     bool m_bUseGUIRegExpEditor : 1;
0213     bool m_bNoNullClipboard : 1;
0214     bool m_bIgnoreSelection : 1;
0215     bool m_bSynchronize : 1;
0216     bool m_bSelectionTextOnly : 1;
0217     bool m_bIgnoreImages : 1;
0218 
0219     /**
0220      * Avoid reacting to our own changes, using this
0221      * lock.
0222      * Don't manupulate this object directly... use the Ignore struct
0223      * instead
0224      */
0225     int m_selectionLocklevel;
0226     int m_clipboardLocklevel;
0227 
0228     URLGrabber *m_myURLGrabber;
0229     QString m_lastURLGrabberTextSelection;
0230     QString m_lastURLGrabberTextClipboard;
0231     KSharedConfigPtr m_config;
0232     QTimer m_overflowClearTimer;
0233     QTimer m_pendingCheckTimer;
0234     bool m_pendingContentsCheck;
0235 
0236     bool blockFetchingNewData();
0237     QString cycleText() const;
0238     KActionCollection *m_collection;
0239     QMenu *m_actionsPopup;
0240     KlipperMode m_mode;
0241     QTimer *m_saveFileTimer;
0242     QPointer<KNotification> m_notification;
0243     KWayland::Client::PlasmaShell *m_plasmashell;
0244 };