From a4e31396884235366b8255e4a20be761a7bade4d Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Fri, 26 Mar 2010 17:42:17 +0100
Subject: [PATCH] Further love for Cpaster plugin

Introduce capabilities flags for Protocols, disable controls
in Pasteview accordingly. Work towards making PasteBin.com
work.
---
 src/plugins/cpaster/codepasterprotocol.cpp    |  4 +-
 src/plugins/cpaster/codepasterprotocol.h      |  2 +-
 src/plugins/cpaster/cpasterplugin.cpp         |  6 +-
 src/plugins/cpaster/pastebindotcaprotocol.h   |  2 +-
 .../cpaster/pastebindotcomprotocol.cpp        | 81 ++++++++++++-------
 src/plugins/cpaster/pastebindotcomprotocol.h  |  3 +
 src/plugins/cpaster/pasteselectdialog.cpp     |  4 +-
 src/plugins/cpaster/pasteview.cpp             | 33 ++++++--
 src/plugins/cpaster/pasteview.h               | 12 ++-
 src/plugins/cpaster/protocol.h                |  9 ++-
 10 files changed, 108 insertions(+), 48 deletions(-)

diff --git a/src/plugins/cpaster/codepasterprotocol.cpp b/src/plugins/cpaster/codepasterprotocol.cpp
index 93fa3b77c51..bb154020a3d 100644
--- a/src/plugins/cpaster/codepasterprotocol.cpp
+++ b/src/plugins/cpaster/codepasterprotocol.cpp
@@ -60,9 +60,9 @@ QString CodePasterProtocol::name() const
     return QLatin1String("CodePaster");
 }
 
-bool CodePasterProtocol::canList() const
+unsigned CodePasterProtocol::capabilities() const
 {
-    return true;
+    return ListCapability|PostCommentCapability|PostDescriptionCapability;
 }
 
 bool CodePasterProtocol::isValidHostName(const QString& hostName)
diff --git a/src/plugins/cpaster/codepasterprotocol.h b/src/plugins/cpaster/codepasterprotocol.h
index af8f3a3d152..977c0287825 100644
--- a/src/plugins/cpaster/codepasterprotocol.h
+++ b/src/plugins/cpaster/codepasterprotocol.h
@@ -52,7 +52,7 @@ public:
 
     QString name() const;
 
-    bool canList() const;
+    virtual unsigned capabilities() const;
     bool hasSettings() const;
     Core::IOptionsPage *settingsPage();
 
diff --git a/src/plugins/cpaster/cpasterplugin.cpp b/src/plugins/cpaster/cpasterplugin.cpp
index 47bd48e7f20..7ce13005308 100644
--- a/src/plugins/cpaster/cpasterplugin.cpp
+++ b/src/plugins/cpaster/cpasterplugin.cpp
@@ -181,10 +181,8 @@ void CodepasterPlugin::post()
     QString comment;
     QString protocolName;
 
-    PasteView view(0);
-    foreach (Protocol *p, m_protocols) {
-        view.addProtocol(p->name(), p->name() == m_settings->protocol);
-    }
+    PasteView view(m_protocols, 0);
+    view.setProtocol(m_settings->protocol);
 
     if (!view.show(username, description, comment, lst))
         return; // User canceled post
diff --git a/src/plugins/cpaster/pastebindotcaprotocol.h b/src/plugins/cpaster/pastebindotcaprotocol.h
index 7cea5d21253..3356e8e8c6d 100644
--- a/src/plugins/cpaster/pastebindotcaprotocol.h
+++ b/src/plugins/cpaster/pastebindotcaprotocol.h
@@ -44,7 +44,7 @@ public:
     QString name() const { return QLatin1String("Pastebin.Ca"); }
 
     bool hasSettings() const { return false; }
-    bool canList() const { return false; }
+    virtual unsigned capabilities() const { return 0; }
 
     void fetch(const QString &id);
     void paste(const QString &text,
diff --git a/src/plugins/cpaster/pastebindotcomprotocol.cpp b/src/plugins/cpaster/pastebindotcomprotocol.cpp
index 7a365529930..eb151c23239 100644
--- a/src/plugins/cpaster/pastebindotcomprotocol.cpp
+++ b/src/plugins/cpaster/pastebindotcomprotocol.cpp
@@ -29,13 +29,20 @@
 
 #include "pastebindotcomprotocol.h"
 #include "pastebindotcomsettings.h"
+#include "cgi.h"
+
 #include <coreplugin/icore.h>
 
 #include <QtCore/QDebug>
+#include <QtCore/QTextStream>
 #include <QtNetwork/QNetworkReply>
 
 using namespace Core;
 
+enum { debug = 0 };
+
+static const char phpScriptpC[] = "api_public.php";
+
 namespace CodePaster {
 PasteBinDotComProtocol::PasteBinDotComProtocol()
 {
@@ -46,13 +53,22 @@ PasteBinDotComProtocol::PasteBinDotComProtocol()
             this, SLOT(readPostResponseHeader(const QHttpResponseHeader&)));
 }
 
+QString PasteBinDotComProtocol::hostName() const
+{
+
+    QString rc = settings->hostPrefix();
+    if (!rc.isEmpty())
+        rc.append(QLatin1Char('.'));
+    rc.append(QLatin1String("pastebin.com"));
+    return rc;
+}
+
 void PasteBinDotComProtocol::fetch(const QString &id)
 {
-    QString link = QLatin1String("http://");
-    if (!settings->hostPrefix().isEmpty())
-        link.append(QString("%1.").arg(settings->hostPrefix()));
-    link.append("pastebin.com/pastebin.php?dl=");
-    link.append(id);
+    QString link;
+    QTextStream(&link) << "http://" << hostName() << '/' << phpScriptpC << "?dl=" << id;
+    if (debug)
+        qDebug() << "fetch: sending " << link;
     QUrl url(link);
     QNetworkRequest r(url);
 
@@ -63,35 +79,36 @@ void PasteBinDotComProtocol::fetch(const QString &id)
 
 void PasteBinDotComProtocol::paste(const QString &text,
                                    const QString &username,
-                                   const QString &comment,
-                                   const QString &description)
+                                   const QString & /* comment */,
+                                   const QString & /* description */)
 {
-    Q_UNUSED(comment);
-    Q_UNUSED(description);
-    QString data = "code2=";
-    data += text;
-    data += "&parent_pid=&format=text&expiry=d&poster=";
-    data += username;
-    data += "&paste=Send";
-    QHttpRequestHeader header("POST", "/pastebin.php");
-    header.setValue("host", "qt.pastebin.com" );
-    header.setContentType("application/x-www-form-urlencoded");
-    http.setHost("qt.pastebin.com", QHttp::ConnectionModeHttp);
-    header.setValue("User-Agent", "CreatorPastebin");
+    QString data;
+    QTextStream str(&data);
+    str << "paste_code=" << CGI::encodeURL(text) << "&paste_name="
+            << CGI::encodeURL(username);
+    QHttpRequestHeader header(QLatin1String("POST"), QLatin1String(phpScriptpC));
+
+    const QString host = hostName();
+    header.setValue(QLatin1String("host"), host);
+    header.setContentType(QLatin1String("application/x-www-form-urlencoded"));
+    http.setHost(host, QHttp::ConnectionModeHttp);
+    header.setValue(QLatin1String("User-Agent"), QLatin1String("CreatorPastebin"));
     postId = http.request(header, data.toAscii());
+    if (debug)
+        qDebug() << "paste" << data << postId << host;
 }
 
 void PasteBinDotComProtocol::readPostResponseHeader(const QHttpResponseHeader &header)
 {
-    switch (header.statusCode())
-    {
+    const int code = header.statusCode();
+    if (debug)
+        qDebug() << "readPostResponseHeader" << code << header.toString() << header.values();
+    switch (code) {
         // If we receive any of those, everything is bon.
-    case 200:
     case 301:
     case 303:
     case 307:
-        break;
-
+    case 200:
     case 302: {
         QString link = header.value("Location");
         emit pasteDone(link);
@@ -104,20 +121,28 @@ void PasteBinDotComProtocol::readPostResponseHeader(const QHttpResponseHeader &h
 
 void PasteBinDotComProtocol::postRequestFinished(int id, bool error)
 {
-    if (id == postId && error)
-        emit pasteDone(http.errorString());
+    if (id == postId && error) {
+        const QString errorMessage = http.errorString();
+        if (debug)
+            qDebug() << "postRequestFinished" << id << errorMessage;
+        emit pasteDone(errorMessage);
+    }
 }
 
 void PasteBinDotComProtocol::fetchFinished()
 {
     QString title;
     QString content;
-    bool error = reply->error();
+    const bool error = reply->error();
     if (error) {
         content = reply->errorString();
+        if (debug)
+            qDebug() << "fetchFinished: error" << fetchId << content;
     } else {
         title = QString::fromLatin1("Pastebin.com: %1").arg(fetchId);
-        content = reply->readAll();
+        content = QString::fromAscii(reply->readAll());
+        if (debug)
+            qDebug() << "fetchFinished: " << content.size();
     }
     reply->deleteLater();
     reply = 0;
diff --git a/src/plugins/cpaster/pastebindotcomprotocol.h b/src/plugins/cpaster/pastebindotcomprotocol.h
index edb2b319cfc..f7ddc25b714 100644
--- a/src/plugins/cpaster/pastebindotcomprotocol.h
+++ b/src/plugins/cpaster/pastebindotcomprotocol.h
@@ -46,6 +46,7 @@ public:
 
     QString name() const { return QLatin1String("Pastebin.Com"); }
 
+    virtual unsigned capabilities() const { return 0; }
     bool hasSettings() const { return true; }
     Core::IOptionsPage* settingsPage();
 
@@ -63,6 +64,8 @@ public slots:
     void readPostResponseHeader(const QHttpResponseHeader &);
 
 private:
+    QString hostName() const;
+
     PasteBinDotComSettings *settings;
     QNetworkAccessManager manager;
     QNetworkReply *reply;
diff --git a/src/plugins/cpaster/pasteselectdialog.cpp b/src/plugins/cpaster/pasteselectdialog.cpp
index 06358e0409b..8f19b776370 100644
--- a/src/plugins/cpaster/pasteselectdialog.cpp
+++ b/src/plugins/cpaster/pasteselectdialog.cpp
@@ -114,7 +114,7 @@ void PasteSelectDialog::list()
 {
     const int index = protocolIndex();
 
-    QTC_ASSERT(m_protocols.at(index)->canList(), return);
+    QTC_ASSERT((m_protocols.at(index)->capabilities() & Protocol::ListCapability), return);
 
     m_ui.listWidget->clear();
     m_ui.listWidget->addItem(new QListWidgetItem(tr("Waiting for items")));
@@ -123,7 +123,7 @@ void PasteSelectDialog::list()
 
 void PasteSelectDialog::protocolChanged(int i)
 {
-    const bool canList = m_protocols.at(i)->canList();
+    const bool canList = m_protocols.at(i)->capabilities() & Protocol::ListCapability;
     m_refreshButton->setEnabled(canList);
     if (canList) {
         list();
diff --git a/src/plugins/cpaster/pasteview.cpp b/src/plugins/cpaster/pasteview.cpp
index 78b9a4074ee..79cbec1476b 100644
--- a/src/plugins/cpaster/pasteview.cpp
+++ b/src/plugins/cpaster/pasteview.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "pasteview.h"
+#include "protocol.h"
 
 #include <QtGui/QFontMetrics>
 #include <QtGui/QPainter>
@@ -36,6 +37,7 @@
 #include <QtCore/QSettings>
 #include <QtCore/QByteArray>
 
+namespace CodePaster {
 class ColumnIndicatorTextEdit : public QTextEdit
 {
 public:
@@ -78,8 +80,9 @@ void ColumnIndicatorTextEdit::paintEvent(QPaintEvent *event)
 // -------------------------------------------------------------------------------------------------
 
 
-PasteView::PasteView(QWidget *parent)
-    : QDialog(parent)
+PasteView::PasteView(const QList<Protocol *> protocols,
+                     QWidget *parent)
+    : QDialog(parent), m_protocols(protocols)
 {
     m_ui.setupUi(this);
 
@@ -89,6 +92,11 @@ PasteView::PasteView(QWidget *parent)
     m_ui.vboxLayout1->addWidget(m_ui.uiPatchView);
     m_ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Paste"));
     connect(m_ui.uiPatchList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(contentChanged()));
+
+    foreach(const Protocol *p, protocols)
+        m_ui.protocolBox->addItem(p->name());
+    connect(m_ui.protocolBox, SIGNAL(currentIndexChanged(int)),
+            this, SLOT(protocolChanged(int)));
 }
 
 PasteView::~PasteView()
@@ -140,6 +148,13 @@ void PasteView::contentChanged()
     m_ui.uiPatchView->setPlainText(content());
 }
 
+void PasteView::protocolChanged(int p)
+{
+    const unsigned caps = m_protocols.at(p)->capabilities();
+    m_ui.uiDescription->setEnabled(caps & Protocol::PostDescriptionCapability);
+    m_ui.uiComment->setEnabled(caps & Protocol::PostCommentCapability);
+}
+
 int PasteView::show(const QString &user, const QString &description, const QString &comment,
                const FileDataList &parts)
 {
@@ -186,9 +201,15 @@ int PasteView::show(const QString &user, const QString &description, const QStri
     return ret;
 }
 
-void PasteView::addProtocol(const QString &protocol, bool defaultProtocol)
+void PasteView::setProtocol(const QString &protocol)
 {
-    m_ui.protocolBox->addItem(protocol);
-    if (defaultProtocol)
-        m_ui.protocolBox->setCurrentIndex(m_ui.protocolBox->findText(protocol));
+     const int index = m_ui.protocolBox->findText(protocol);
+     m_ui.protocolBox->setCurrentIndex(index);
+     if (index == m_ui.protocolBox->currentIndex()) {
+         protocolChanged(index); // Force enabling
+     } else {
+         m_ui.protocolBox->setCurrentIndex(index);
+     }
 }
+
+} //namespace CodePaster
diff --git a/src/plugins/cpaster/pasteview.h b/src/plugins/cpaster/pasteview.h
index 62ed44745e9..a69cc858872 100644
--- a/src/plugins/cpaster/pasteview.h
+++ b/src/plugins/cpaster/pasteview.h
@@ -35,17 +35,20 @@
 
 #include <QtGui/QDialog>
 
+namespace CodePaster {
+class Protocol;
 class PasteView : public QDialog
 {
     Q_OBJECT
 public:
-    explicit PasteView(QWidget *parent);
+    explicit PasteView(const QList<Protocol *> protocols,
+                       QWidget *parent);
     ~PasteView();
 
     int show(const QString &user, const QString &description, const QString &comment,
              const FileDataList &parts);
 
-    void addProtocol(const QString &protocol, bool defaultProtocol = false);
+    void setProtocol(const QString &protocol);
 
     QString user() const;
     QString description() const;
@@ -55,10 +58,13 @@ public:
 
 private slots:
     void contentChanged();
+    void protocolChanged(int);
 
 private:
+    const QList<Protocol *> m_protocols;
+
     Ui::ViewDialog m_ui;
     FileDataList m_parts;
 };
-
+} // namespace CodePaster
 #endif // VIEW_H
diff --git a/src/plugins/cpaster/protocol.h b/src/plugins/cpaster/protocol.h
index d8d9de3827f..da8a05153da 100644
--- a/src/plugins/cpaster/protocol.h
+++ b/src/plugins/cpaster/protocol.h
@@ -41,6 +41,11 @@ class Protocol : public QObject
 {
     Q_OBJECT
 public:
+    enum Capabilities  {
+        ListCapability = 0x1,
+        PostCommentCapability = 0x2,
+        PostDescriptionCapability = 0x4
+    };
     Protocol();
     virtual ~Protocol();
 
@@ -48,7 +53,9 @@ public:
 
     bool canFetch() const;
     bool canPost() const;
-    virtual bool canList() const = 0;
+
+
+    virtual unsigned capabilities() const = 0;
     virtual bool hasSettings() const;
     virtual Core::IOptionsPage* settingsPage();
 
-- 
GitLab