QtPass Developer documentation
QtPass test coverage
Current view: top level - src/clipboardmanager.h Coverage Total Hit
Test: QtPass Lines: 100.0 % 1 1
Test Date: 2026-11-14 13:19:18 Functions: - 0 0

            Line data    Source code
       1              : // SPDX-FileCopyrightText: 2026 Anne Jan Brouwer
       2              : // SPDX-License-Identifier: GPL-3.0-or-later
       3              : /**
       4              :  * @file
       5              :  * @brief ClipboardManager, which puts secrets on the clipboard and removes
       6              :  * them again, and the MIME data that marks them as secrets.
       7              :  */
       8              : #ifndef SRC_CLIPBOARDMANAGER_H_
       9              : #define SRC_CLIPBOARDMANAGER_H_
      10              : 
      11              : #include <QMimeData>
      12              : #include <QObject>
      13              : #include <QString>
      14              : #include <QStringList>
      15              : #include <QTimer>
      16              : #include <optional>
      17              : 
      18              : /**
      19              :  * @brief Build clipboard MIME data with platform-specific security hints.
      20              :  * @param text - Plain text to copy
      21              :  * @return QMimeData* - Ownership transferred to caller. Caller must delete
      22              :  *         or transfer to QClipboard::setMimeData which takes ownership.
      23              :  */
      24              : auto buildClipboardMimeData(const QString &text) -> QMimeData *;
      25              : 
      26              : /**
      27              :  * @brief Convert quint32 to byte array for Windows clipboard formats.
      28              :  * @param value - DWORD value
      29              :  * @return QByteArray with raw bytes
      30              :  */
      31              : static inline auto dwordBytes(quint32 value) -> QByteArray {
      32              :   return {reinterpret_cast<const char *>(&value), sizeof(value)};
      33              : }
      34              : 
      35              : /**
      36              :  * @class ClipboardManager
      37              :  * @ingroup secrets
      38              :  * @brief Puts secrets on the system clipboard and takes them off again.
      39              :  *
      40              :  * Remembers what it copied so the autoclear timer (and the quit handler)
      41              :  * only remove that text, never something the user copied in the meantime.
      42              :  * Settings (selection vs. clipboard, autoclear on/off, delay) are read from
      43              :  * QtPassSettings; call setAutoclearTimer() after they change. Status text
      44              :  * for the main window's status bar is emitted, not shown, so this class has
      45              :  * no UI dependency and is unit-testable.
      46              :  */
      47              : class ClipboardManager : public QObject {
      48           50 :   Q_OBJECT
      49              : 
      50              : public:
      51              :   /**
      52              :    * @brief Construct a manager that also clears its text when the
      53              :    *        application quits.
      54              :    * @param parent Owner.
      55              :    */
      56              :   explicit ClipboardManager(QObject *parent = nullptr);
      57              : 
      58              :   /**
      59              :    * @brief Re-read the autoclear delay from the settings.
      60              :    */
      61              :   void setAutoclearTimer();
      62              : 
      63              :   /**
      64              :    * @brief Handle clipboard copying for a shown entry.
      65              :    *
      66              :    * In "always copy" mode (and only then) this copies @p text via copyText(),
      67              :    * which also arms the autoclear timer and records the clipboard contents.
      68              :    * In other modes it does nothing, leaving any pending autoclear tracking
      69              :    * intact.
      70              :    * @param text Password (or value) of the entry being shown.
      71              :    * @param p_output Full decrypted output; copying is skipped when it is empty.
      72              :    */
      73              :   void copyIfAlways(const QString &text, const QString &p_output = QString());
      74              : 
      75              :   /**
      76              :    * @brief The text this manager last put on the clipboard and still tracks.
      77              :    * @return Tracked text, empty once cleared.
      78              :    */
      79              :   [[nodiscard]] auto trackedText() const -> QString { return m_clippedText; }
      80              : 
      81              : public slots:
      82              :   /**
      83              :    * @brief Copy text into the system clipboard (or the X11 primary selection
      84              :    *        when configured) and arm the autoclear timer when enabled.
      85              :    * @param text Text to copy.
      86              :    */
      87              :   void copyText(const QString &text);
      88              : 
      89              :   /**
      90              :    * @brief Track text that got onto the clipboard some other way.
      91              :    *
      92              :    * For a copy QtPass did not make through copyText(): text selected and
      93              :    * copied from a widget showing a secret (Ctrl+C, the context menu, a drag,
      94              :    * or the X11 primary selection that a mouse selection fills). The text is
      95              :    * cleared with the rest when the autoclear timer runs; what copyText()
      96              :    * tracks stays tracked too.
      97              :    * @param text The copied text; nothing happens when it is empty.
      98              :    */
      99              :   void trackCopied(const QString &text);
     100              : 
     101              :   /**
     102              :    * @brief Remove the tracked text from the clipboard if it is still there.
     103              :    *        Silent no-op when nothing is tracked.
     104              :    */
     105              :   void clear();
     106              : 
     107              : signals:
     108              :   /**
     109              :    * @brief Something worth showing in the status bar happened.
     110              :    * @param message Translated text.
     111              :    */
     112              :   void statusMessage(const QString &message);
     113              : 
     114              : private:
     115              :   /**
     116              :    * @brief Single-shot autoclear timer; started by copyText() when the
     117              :    * autoclear setting is on, and calls clear() when it fires.
     118              :    */
     119              :   QTimer m_clearTimer;
     120              :   /**
     121              :    * @brief The secret copyText() last put on the clipboard; clear() removes
     122              :    * the clipboard content only while it still equals this.
     123              :    */
     124              :   QString m_clippedText;
     125              :   /// What was on the clipboard and in the selection before copyText() first
     126              :   /// put a secret there, for clear() to put back (restoreClipboard). Text
     127              :   /// only, as pass -c keeps it; absent when nothing was saved.
     128              :   std::optional<QString> m_previousClipboard;
     129              :   /** @brief As m_previousClipboard, for the X11 primary selection. */
     130              :   std::optional<QString> m_previousSelection;
     131              :   /**
     132              :    * @brief Empty a saved previous text equal to @p text, now copied as a
     133              :    * secret, so clear() does not put the secret back.
     134              :    * @param text The text that has just been copied as a secret.
     135              :    */
     136              :   void forgetIfSaved(const QString &text);
     137              :   QStringList m_otherCopies; ///< trackCopied() texts, cleared with the rest
     138              : };
     139              : 
     140              : #endif // SRC_CLIPBOARDMANAGER_H_
        

Generated by: LCOV version 2.0-1