CPaster: Pimpl plugin

Change-Id: I595222c374be30bfc3f32897a6096a528188cfc5
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2020-01-24 18:34:57 +01:00
parent 37188ee3a1
commit 461d278a35
4 changed files with 128 additions and 138 deletions

View File

@@ -42,14 +42,16 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/mimetypes/mimedatabase.h> #include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/temporarydirectory.h> #include <utils/temporarydirectory.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
#include <QtPlugin>
#include <QDebug> #include <QDebug>
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
@@ -63,87 +65,112 @@ using namespace TextEditor;
namespace CodePaster { namespace CodePaster {
class CodePasterPluginPrivate : public QObject
{
Q_DECLARE_TR_FUNCTIONS(CodePaster::CodepasterPlugin)
public:
CodePasterPluginPrivate();
void post(CodePasterPlugin::PasteSources pasteSources);
void post(QString data, const QString &mimeType);
void pasteSnippet();
void fetch();
void finishPost(const QString &link);
void finishFetch(const QString &titleDescription,
const QString &content,
bool error);
void fetchUrl();
Settings m_settings;
QAction *m_postEditorAction = nullptr;
QAction *m_fetchAction = nullptr;
QAction *m_fetchUrlAction = nullptr;
PasteBinDotComProtocol pasteBinProto;
FileShareProtocol fileShareProto;
PasteCodeDotXyzProtocol pasteCodeProto;
const QList<Protocol *> m_protocols {
&pasteBinProto,
&fileShareProto,
&pasteCodeProto
};
SettingsPage m_settingsPage {
&m_settings,
Utils::transform(m_protocols, &Protocol::name)
};
QStringList m_fetchedSnippets;
UrlOpenProtocol m_urlOpen;
CodePasterServiceImpl m_service{this};
};
/*! /*!
\class CodePaster::Service \class CodePaster::Service
\brief The CodePaster::Service class is a service registered with PluginManager \brief The CodePaster::Service class is a service registered with PluginManager
that provides CodePaster \c post() functionality. that provides CodePaster \c post() functionality.
*/ */
CodePasterServiceImpl::CodePasterServiceImpl(QObject *parent) : CodePasterServiceImpl::CodePasterServiceImpl(CodePasterPluginPrivate *d)
QObject(parent) : d(d)
{ {}
}
void CodePasterServiceImpl::postText(const QString &text, const QString &mimeType) void CodePasterServiceImpl::postText(const QString &text, const QString &mimeType)
{ {
QTC_ASSERT(CodepasterPlugin::instance(), return); d->post(text, mimeType);
CodepasterPlugin::instance()->post(text, mimeType);
} }
void CodePasterServiceImpl::postCurrentEditor() void CodePasterServiceImpl::postCurrentEditor()
{ {
QTC_ASSERT(CodepasterPlugin::instance(), return); d->post(CodePasterPlugin::PasteEditor);
CodepasterPlugin::instance()->post(CodepasterPlugin::PasteEditor);
} }
void CodePasterServiceImpl::postClipboard() void CodePasterServiceImpl::postClipboard()
{ {
QTC_ASSERT(CodepasterPlugin::instance(), return); d->post(CodePasterPlugin::PasteClipboard);
CodepasterPlugin::instance()->post(CodepasterPlugin::PasteClipboard);
} }
// ---------- CodepasterPlugin // ---------- CodepasterPlugin
CodepasterPlugin *CodepasterPlugin::m_instance = nullptr;
CodepasterPlugin::CodepasterPlugin() : CodePasterPlugin::~CodePasterPlugin()
m_settings(new Settings)
{ {
CodepasterPlugin::m_instance = this; delete d;
} }
CodepasterPlugin::~CodepasterPlugin() bool CodePasterPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
delete m_urlOpen;
delete m_settings;
qDeleteAll(m_protocols);
CodepasterPlugin::m_instance = nullptr;
}
bool CodepasterPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{ {
Q_UNUSED(arguments) Q_UNUSED(arguments)
Q_UNUSED(errorMessage) Q_UNUSED(errorMessage)
d = new CodePasterPluginPrivate;
return true;
}
CodePasterPluginPrivate::CodePasterPluginPrivate()
{
// Create the settings Page // Create the settings Page
m_settings->fromSettings(ICore::settings()); m_settings.fromSettings(ICore::settings());
// Create the protocols and append them to the Settings // Connect protocols
QStringList protocolNames; for (Protocol *proto : m_protocols) {
connect(proto, &Protocol::pasteDone, this, &CodePasterPluginPrivate::finishPost);
Protocol *protos[] = {new PasteBinDotComProtocol, connect(proto, &Protocol::fetchDone, this, &CodePasterPluginPrivate::finishFetch);
new FileShareProtocol,
new PasteCodeDotXyzProtocol,
};
const int count = sizeof(protos) / sizeof(Protocol *);
for (int i = 0; i < count; ++i) {
connect(protos[i], &Protocol::pasteDone, this, &CodepasterPlugin::finishPost);
connect(protos[i], &Protocol::fetchDone, this, &CodepasterPlugin::finishFetch);
protocolNames.append(protos[i]->name());
m_protocols.append(protos[i]);
} }
(void) new SettingsPage(m_settings, protocolNames, this); connect(&m_urlOpen, &Protocol::fetchDone, this, &CodePasterPluginPrivate::finishFetch);
m_urlOpen = new UrlOpenProtocol;
connect(m_urlOpen, &Protocol::fetchDone, this, &CodepasterPlugin::finishFetch);
//register actions //register actions
ActionContainer *toolsContainer = ActionContainer *toolsContainer = ActionManager::actionContainer(Core::Constants::M_TOOLS);
ActionManager::actionContainer(Core::Constants::M_TOOLS);
ActionContainer *cpContainer = ActionContainer *cpContainer = ActionManager::createMenu("CodePaster");
ActionManager::createMenu("CodePaster");
cpContainer->menu()->setTitle(tr("&Code Pasting")); cpContainer->menu()->setTitle(tr("&Code Pasting"));
toolsContainer->addMenu(cpContainer); toolsContainer->addMenu(cpContainer);
@@ -152,33 +179,25 @@ bool CodepasterPlugin::initialize(const QStringList &arguments, QString *errorMe
m_postEditorAction = new QAction(tr("Paste Snippet..."), this); m_postEditorAction = new QAction(tr("Paste Snippet..."), this);
command = ActionManager::registerAction(m_postEditorAction, "CodePaster.Post"); command = ActionManager::registerAction(m_postEditorAction, "CodePaster.Post");
command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+C,Meta+P") : tr("Alt+C,Alt+P"))); command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+C,Meta+P") : tr("Alt+C,Alt+P")));
connect(m_postEditorAction, &QAction::triggered, this, &CodepasterPlugin::pasteSnippet); connect(m_postEditorAction, &QAction::triggered, this, &CodePasterPluginPrivate::pasteSnippet);
cpContainer->addAction(command); cpContainer->addAction(command);
m_fetchAction = new QAction(tr("Fetch Snippet..."), this); m_fetchAction = new QAction(tr("Fetch Snippet..."), this);
command = ActionManager::registerAction(m_fetchAction, "CodePaster.Fetch"); command = ActionManager::registerAction(m_fetchAction, "CodePaster.Fetch");
command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+C,Meta+F") : tr("Alt+C,Alt+F"))); command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? tr("Meta+C,Meta+F") : tr("Alt+C,Alt+F")));
connect(m_fetchAction, &QAction::triggered, this, &CodepasterPlugin::fetch); connect(m_fetchAction, &QAction::triggered, this, &CodePasterPluginPrivate::fetch);
cpContainer->addAction(command); cpContainer->addAction(command);
m_fetchUrlAction = new QAction(tr("Fetch from URL..."), this); m_fetchUrlAction = new QAction(tr("Fetch from URL..."), this);
command = ActionManager::registerAction(m_fetchUrlAction, "CodePaster.FetchUrl"); command = ActionManager::registerAction(m_fetchUrlAction, "CodePaster.FetchUrl");
connect(m_fetchUrlAction, &QAction::triggered, this, &CodepasterPlugin::fetchUrl); connect(m_fetchUrlAction, &QAction::triggered, this, &CodePasterPluginPrivate::fetchUrl);
cpContainer->addAction(command); cpContainer->addAction(command);
new CodePasterServiceImpl(this);
return true;
} }
void CodepasterPlugin::extensionsInitialized() ExtensionSystem::IPlugin::ShutdownFlag CodePasterPlugin::aboutToShutdown()
{
}
ExtensionSystem::IPlugin::ShutdownFlag CodepasterPlugin::aboutToShutdown()
{ {
// Delete temporary, fetched files // Delete temporary, fetched files
foreach (const QString &fetchedSnippet, m_fetchedSnippets) { for (const QString &fetchedSnippet : qAsConst(d->m_fetchedSnippets)) {
QFile file(fetchedSnippet); QFile file(fetchedSnippet);
if (file.exists()) if (file.exists())
file.remove(); file.remove();
@@ -232,41 +251,41 @@ static inline void fixSpecialCharacters(QString &data)
} }
} }
void CodepasterPlugin::post(PasteSources pasteSources) void CodePasterPluginPrivate::post(CodePasterPlugin::PasteSources pasteSources)
{ {
QString data; QString data;
QString mimeType; QString mimeType;
if (pasteSources & PasteEditor) if (pasteSources & CodePasterPlugin::PasteEditor)
textFromCurrentEditor(&data, &mimeType); textFromCurrentEditor(&data, &mimeType);
if (data.isEmpty() && (pasteSources & PasteClipboard)) { if (data.isEmpty() && (pasteSources & CodePasterPlugin::PasteClipboard)) {
QString subType = QStringLiteral("plain"); QString subType = "plain";
data = QGuiApplication::clipboard()->text(subType, QClipboard::Clipboard); data = QGuiApplication::clipboard()->text(subType, QClipboard::Clipboard);
} }
post(data, mimeType); post(data, mimeType);
} }
void CodepasterPlugin::post(QString data, const QString &mimeType) void CodePasterPluginPrivate::post(QString data, const QString &mimeType)
{ {
fixSpecialCharacters(data); fixSpecialCharacters(data);
const QString username = m_settings->username; const QString username = m_settings.username;
PasteView view(m_protocols, mimeType, ICore::dialogParent()); PasteView view(m_protocols, mimeType, ICore::dialogParent());
view.setProtocol(m_settings->protocol); view.setProtocol(m_settings.protocol);
const FileDataList diffChunks = splitDiffToFiles(data); const FileDataList diffChunks = splitDiffToFiles(data);
const int dialogResult = diffChunks.isEmpty() ? const int dialogResult = diffChunks.isEmpty() ?
view.show(username, QString(), QString(), m_settings->expiryDays, data) : view.show(username, QString(), QString(), m_settings.expiryDays, data) :
view.show(username, QString(), QString(), m_settings->expiryDays, diffChunks); view.show(username, QString(), QString(), m_settings.expiryDays, diffChunks);
// Save new protocol in case user changed it. // Save new protocol in case user changed it.
if (dialogResult == QDialog::Accepted if (dialogResult == QDialog::Accepted && m_settings.protocol != view.protocol()) {
&& m_settings->protocol != view.protocol()) { m_settings.protocol = view.protocol();
m_settings->protocol = view.protocol(); m_settings.toSettings(ICore::settings());
m_settings->toSettings(ICore::settings());
} }
} }
void CodepasterPlugin::fetchUrl() void CodePasterPluginPrivate::fetchUrl()
{ {
QUrl url; QUrl url;
do { do {
@@ -275,25 +294,25 @@ void CodepasterPlugin::fetchUrl()
if (!ok) if (!ok)
return; return;
} while (!url.isValid()); } while (!url.isValid());
m_urlOpen->fetch(url.toString()); m_urlOpen.fetch(url.toString());
} }
void CodepasterPlugin::pasteSnippet() void CodePasterPluginPrivate::pasteSnippet()
{ {
post(PasteEditor | PasteClipboard); post(CodePasterPlugin::PasteEditor | CodePasterPlugin::PasteClipboard);
} }
void CodepasterPlugin::fetch() void CodePasterPluginPrivate::fetch()
{ {
PasteSelectDialog dialog(m_protocols, ICore::dialogParent()); PasteSelectDialog dialog(m_protocols, ICore::dialogParent());
dialog.setProtocol(m_settings->protocol); dialog.setProtocol(m_settings.protocol);
if (dialog.exec() != QDialog::Accepted) if (dialog.exec() != QDialog::Accepted)
return; return;
// Save new protocol in case user changed it. // Save new protocol in case user changed it.
if (m_settings->protocol != dialog.protocol()) { if (m_settings.protocol != dialog.protocol()) {
m_settings->protocol = dialog.protocol(); m_settings.protocol = dialog.protocol();
m_settings->toSettings(ICore::settings()); m_settings.toSettings(ICore::settings());
} }
const QString pasteID = dialog.pasteId(); const QString pasteID = dialog.pasteId();
@@ -304,11 +323,11 @@ void CodepasterPlugin::fetch()
protocol->fetch(pasteID); protocol->fetch(pasteID);
} }
void CodepasterPlugin::finishPost(const QString &link) void CodePasterPluginPrivate::finishPost(const QString &link)
{ {
if (m_settings->copyToClipboard) if (m_settings.copyToClipboard)
QApplication::clipboard()->setText(link); QApplication::clipboard()->setText(link);
MessageManager::write(link, m_settings->displayOutput ? MessageManager::ModeSwitch : MessageManager::Silent); MessageManager::write(link, m_settings.displayOutput ? MessageManager::ModeSwitch : MessageManager::Silent);
} }
// Extract the characters that can be used for a file name from a title // Extract the characters that can be used for a file name from a title
@@ -345,7 +364,7 @@ static inline QString tempFilePattern(const QString &prefix, const QString &exte
return pattern; return pattern;
} }
void CodepasterPlugin::finishFetch(const QString &titleDescription, void CodePasterPluginPrivate::finishFetch(const QString &titleDescription,
const QString &content, const QString &content,
bool error) bool error)
{ {
@@ -386,9 +405,4 @@ void CodepasterPlugin::finishFetch(const QString &titleDescription,
editor->document()->setPreferredDisplayName(titleDescription); editor->document()->setPreferredDisplayName(titleDescription);
} }
CodepasterPlugin *CodepasterPlugin::instance()
{
return m_instance;
}
} // namespace CodePaster } // namespace CodePaster

View File

@@ -29,29 +29,27 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include <QStringList>
QT_BEGIN_NAMESPACE
class QAction;
QT_END_NAMESPACE
namespace CodePaster { namespace CodePaster {
class Settings;
class Protocol;
class CodePasterServiceImpl : public QObject, public CodePaster::Service class CodePasterPluginPrivate;
class CodePasterServiceImpl final : public QObject, public CodePaster::Service
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(CodePaster::Service) Q_INTERFACES(CodePaster::Service)
public:
explicit CodePasterServiceImpl(QObject *parent = nullptr);
void postText(const QString &text, const QString &mimeType) override; public:
void postCurrentEditor() override; explicit CodePasterServiceImpl(CodePasterPluginPrivate *d);
void postClipboard() override;
private:
void postText(const QString &text, const QString &mimeType) final;
void postCurrentEditor() final;
void postClipboard() final;
CodePasterPluginPrivate *d = nullptr;
}; };
class CodepasterPlugin : public ExtensionSystem::IPlugin class CodePasterPlugin final : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "CodePaster.json") Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "CodePaster.json")
@@ -63,38 +61,17 @@ public:
}; };
Q_DECLARE_FLAGS(PasteSources, PasteSource) Q_DECLARE_FLAGS(PasteSources, PasteSource)
CodepasterPlugin(); CodePasterPlugin() = default;
~CodepasterPlugin() override; ~CodePasterPlugin() final;
bool initialize(const QStringList &arguments, QString *errorMessage) override;
void extensionsInitialized() override;
ShutdownFlag aboutToShutdown() override;
static CodepasterPlugin *instance();
void post(PasteSources pasteSources);
void post(QString data, const QString &mimeType);
private: private:
void pasteSnippet(); bool initialize(const QStringList &arguments, QString *errorMessage) final;
void fetch(); void extensionsInitialized() final {}
void finishPost(const QString &link); ShutdownFlag aboutToShutdown() final;
void finishFetch(const QString &titleDescription,
const QString &content,
bool error);
void fetchUrl(); CodePasterPluginPrivate *d = nullptr;
static CodepasterPlugin *m_instance;
Settings *m_settings = nullptr;
QAction *m_postEditorAction = nullptr;
QAction *m_fetchAction = nullptr;
QAction *m_fetchUrlAction = nullptr;
QList<Protocol*> m_protocols;
QStringList m_fetchedSnippets;
Protocol *m_urlOpen = nullptr;
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(CodepasterPlugin::PasteSources) Q_DECLARE_OPERATORS_FOR_FLAGS(CodePasterPlugin::PasteSources)
} // namespace CodePaster } // namespace CodePaster

View File

@@ -75,8 +75,7 @@ void SettingsWidget::apply()
} }
} }
SettingsPage::SettingsPage(Settings *settings, const QStringList &protocolNames, QObject *parent) SettingsPage::SettingsPage(Settings *settings, const QStringList &protocolNames)
: Core::IOptionsPage(parent)
{ {
setId("A.CodePaster.General"); setId("A.CodePaster.General");
setDisplayName(tr("General")); setDisplayName(tr("General"));

View File

@@ -38,7 +38,7 @@ class Settings;
class SettingsPage final : public Core::IOptionsPage class SettingsPage final : public Core::IOptionsPage
{ {
public: public:
SettingsPage(Settings *settings, const QStringList &protocolNames, QObject *parent); SettingsPage(Settings *settings, const QStringList &protocolNames);
}; };
} // namespace CodePaster } // namespace CodePaster