ollie/kde/gui/plumber.h

87 lines
2.9 KiB
C++

/*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Plumber — ollie-gui's bridge to the plan9port plumbing system.
*
* Full plumb client:
* - SEND: send() opens the "send" port on the plumber and writes a packed
* plumb message; the plumber's rules resolve it (file:line -> edit port,
* url -> web port, etc.). The source is "ollie" and the destination is
* left empty so the rules decide.
* - RECEIVE: a dedicated reader thread opens the "edit" port and blocks on
* reads. Each plumb message that arrives (file to open, with an optional
* addr) is emitted via edit() on the GUI thread via a queued signal.
*
* The namespace socket is $NAMESPACE/plumb, or /tmp/ns.$USER.$DISPLAY/plumb
* when $NAMESPACE is unset — the same resolution plan9's getns() performs.
*/
#ifndef PLUMBER_H
#define PLUMBER_H
#include <QObject>
#include <QString>
#include <QQmlEngine>
class PlumbReader; // reader living on its own thread
// Plumber wraps plan9port plumbing for context-aware actions.
// B3-click on text → plumber routes to appropriate handler (editor, browser, etc.)
class Plumber : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
explicit Plumber(QObject *parent = nullptr);
~Plumber() override;
/*! Resolve the plumb socket path ($NAMESPACE/plumb or display fallback). */
static QString socketPath();
/*!
* Build and send a plumb message carrying \a data (a token, path or URL)
* with working directory \a wdir. Returns true if the plumber accepted the
* write. On failure errorString() explains why.
*/
Q_INVOKABLE bool send(const QString &data, const QString &wdir = QString());
/*! Plumb text to a specific destination port. */
Q_INVOKABLE bool sendTo(const QString &data, const QString &dst, const QString &wdir = QString());
/*! Last send() error. */
Q_INVOKABLE QString errorString() const { return m_error; }
/*! Check if plumber namespace is available. */
Q_INVOKABLE bool available() const;
// Legacy compatibility aliases
Q_INVOKABLE void plumb(const QString &text) { send(text); }
Q_INVOKABLE void plumbTo(const QString &text, const QString &dst) { sendTo(text, dst); }
/*!
* Start the edit-port reader thread. Safe to call once; further calls are
* no-ops. Reader failures are reported via readerError().
*/
Q_INVOKABLE void startReader();
Q_SIGNALS:
/*!
* A plumb message arrived on the edit port: open \a file and, if \a addr is
* non-empty, jump to it. Emitted on the GUI (Plumber's) thread.
*/
void edit(const QString &file, const QString &addr, const QString &wdir);
/*! The reader stopped with an error (e.g. plumber not running). */
void readerError(const QString &message);
/*! Send failed. */
void plumbError(const QString &error);
private:
PlumbReader *m_reader = nullptr;
QString m_error;
};
#endif // PLUMBER_H