diff --git a/src/plugins/cpaster/fileshareprotocol.cpp b/src/plugins/cpaster/fileshareprotocol.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef253ace694c18ee9511d2c0f8d1fdce744df1bb --- /dev/null +++ b/src/plugins/cpaster/fileshareprotocol.cpp @@ -0,0 +1,218 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "fileshareprotocol.h" +#include "fileshareprotocolsettingspage.h" + +#include <coreplugin/icore.h> +#include <coreplugin/messagemanager.h> +#include <coreplugin/messageoutputwindow.h> + +#include <utils/qtcassert.h> + +#include <QtCore/QXmlStreamReader> +#include <QtCore/QXmlStreamAttribute> +#include <QtCore/QTemporaryFile> +#include <QtCore/QDir> +#include <QtCore/QFileInfo> +#include <QtCore/QDebug> + +enum { debug = 0 }; + +static const char tempPatternC[] = "pasterXXXXXX.xml"; +static const char tempGlobPatternC[] = "paster*.xml"; +static const char pasterElementC[] = "paster"; +static const char userElementC[] = "user"; +static const char descriptionElementC[] = "description"; +static const char textElementC[] = "text"; + +namespace CodePaster { + +FileShareProtocol::FileShareProtocol() : + m_settings(new FileShareProtocolSettings), + m_settingsPage(new FileShareProtocolSettingsPage(m_settings)) +{ + m_settings->fromSettings(Core::ICore::instance()->settings()); +} + +FileShareProtocol::~FileShareProtocol() +{ +} + +QString FileShareProtocol::name() const +{ + return m_settingsPage->displayName(); +} + +unsigned FileShareProtocol::capabilities() const +{ + return ListCapability|PostDescriptionCapability; +} + +bool FileShareProtocol::hasSettings() const +{ + return true; +} + +Core::IOptionsPage *FileShareProtocol::settingsPage() const +{ + return m_settingsPage; +} + +static bool parse(const QString &fileName, + QString *errorMessage, + QString *user = 0, QString *description = 0, QString *text = 0) +{ + unsigned elementCount = 0; + + errorMessage->clear(); + if (user) + user->clear(); + if (description) + description->clear(); + if (text) + text->clear(); + + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) { + *errorMessage = FileShareProtocol::tr("Cannot open %1: %2").arg(fileName, file.errorString()); + return false; + } + QXmlStreamReader reader(&file); + while (!reader.atEnd()) { + if (reader.readNext() == QXmlStreamReader::StartElement) { + const QStringRef elementName = reader.name(); + // Check start element + if (elementCount == 0 && elementName != QLatin1String(pasterElementC)) { + *errorMessage = FileShareProtocol::tr("%1 does not appear to be a paster file.").arg(fileName); + return false; + } + // Parse elements + elementCount++; + if (user && elementName == QLatin1String(userElementC)) { + *user = reader.readElementText(); + } else if (description && elementName == QLatin1String(descriptionElementC)) { + *description = reader.readElementText(); + } else if (text && elementName == QLatin1String(textElementC)) { + *text = reader.readElementText(); + } + } + } + if (reader.hasError()) { + *errorMessage = FileShareProtocol::tr("Error in %1 at %2: %3") + .arg(fileName).arg(reader.lineNumber()).arg(reader.errorString()); + return false; + } + return true; +} + +bool FileShareProtocol::checkConfiguration(QString *errorMessage) const +{ + if (m_settings->path.isEmpty()) { + if (errorMessage) + *errorMessage = tr("Please configure a path."); + return false; + } + return true; +} + +void FileShareProtocol::fetch(const QString &id) +{ + // Absolute or relative path name. + QFileInfo fi(id); + if (fi.isRelative()) + fi = QFileInfo(m_settings->path + QLatin1Char('/') + id); + QString errorMessage; + QString text; + if (parse(fi.absoluteFilePath(), &errorMessage, 0, 0, &text)) { + emit fetchDone(id, text, false); + } else { + emit fetchDone(id, errorMessage, true); + } +} + +void FileShareProtocol::list() +{ + // Read out directory, display by date (latest first) + QDir dir(m_settings->path, QLatin1String(tempGlobPatternC), + QDir::Time, QDir::Files|QDir::NoDotAndDotDot|QDir::Readable); + QStringList entries; + QString user; + QString description; + QString errorMessage; + const QChar blank = QLatin1Char(' '); + const QFileInfoList entryInfoList = dir.entryInfoList(); + const int count = qMin(m_settings->displayCount, entryInfoList.size()); + for (int i = 0; i < count; i++) { + const QFileInfo& entryFi = entryInfoList.at(i); + if (parse(entryFi.absoluteFilePath(), &errorMessage, &user, &description)) { + QString entry = entryFi.fileName(); + entry += blank; + entry += user; + entry += blank; + entry += description; + entries.push_back(entry); + } + if (debug) + qDebug() << entryFi.absoluteFilePath() << errorMessage; + } + emit listDone(name(), entries); +} + +void FileShareProtocol::paste(const QString &text, + ContentType /* ct */, + const QString &username, + const QString & /* comment */, + const QString &description) +{ + // Write out temp XML file + QTemporaryFile tempFile(m_settings->path + QLatin1Char('/') + QLatin1String(tempPatternC)); + tempFile.setAutoRemove(false); + if (!tempFile.open()) { + const QString msg = tr("Unable to open a file for writing in %1: %2").arg(m_settings->path, tempFile.errorString()); + Core::ICore::instance()->messageManager()->printToOutputPanePopup(msg); + return; + } + // Flat text sections embedded into pasterElement + QXmlStreamWriter writer(&tempFile); + writer.writeStartDocument(); + writer.writeStartElement(QLatin1String(pasterElementC)); + + writer.writeTextElement(QLatin1String(userElementC), username); + writer.writeTextElement(QLatin1String(descriptionElementC), description); + writer.writeTextElement(QLatin1String(textElementC), text); + + writer.writeEndElement(); + writer.writeEndDocument(); + tempFile.close(); + + const QString msg = tr("Pasted: %1").arg(tempFile.fileName()); + Core::ICore::instance()->messageManager()->printToOutputPanePopup(msg); +} +} // namespace CodePaster diff --git a/src/plugins/cpaster/fileshareprotocol.h b/src/plugins/cpaster/fileshareprotocol.h new file mode 100644 index 0000000000000000000000000000000000000000..bcb892eca019131dd49f320b00e736b1c4db4a65 --- /dev/null +++ b/src/plugins/cpaster/fileshareprotocol.h @@ -0,0 +1,71 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef FILESHAREPROTOCOL_H +#define FILESHAREPROTOCOL_H + +#include "protocol.h" + +#include <QtCore/QSharedPointer> + +namespace CodePaster { + +class FileShareProtocolSettingsPage; +struct FileShareProtocolSettings; + +/* FileShareProtocol: Allows for pasting via a shared network + * drive by writing XML files. */ + +class FileShareProtocol : public Protocol +{ + Q_DISABLE_COPY(FileShareProtocol) +public: + FileShareProtocol(); + virtual ~FileShareProtocol(); + + virtual QString name() const; + virtual unsigned capabilities() const; + virtual bool hasSettings() const; + virtual Core::IOptionsPage *settingsPage() const; + + virtual bool checkConfiguration(QString *errorMessage = 0) const; + virtual void fetch(const QString &id); + virtual void list(); + virtual void paste(const QString &text, + ContentType ct = Text, + const QString &username = QString(), + const QString &comment = QString(), + const QString &description = QString()); +private: + const QSharedPointer<FileShareProtocolSettings> m_settings; + FileShareProtocolSettingsPage *m_settingsPage; +}; +} // namespace CodePaster + +#endif // FILESHAREPROTOCOL_H diff --git a/src/plugins/cpaster/fileshareprotocolsettingspage.cpp b/src/plugins/cpaster/fileshareprotocolsettingspage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f678e7a0153763fc325a19e7b072ac1f58bce21b --- /dev/null +++ b/src/plugins/cpaster/fileshareprotocolsettingspage.cpp @@ -0,0 +1,138 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "fileshareprotocolsettingspage.h" +#include "cpasterconstants.h" + +#include <coreplugin/icore.h> + +#include <QtCore/QDir> +#include <QtCore/QSettings> +#include <QtCore/QCoreApplication> + +static const char settingsGroupC[] = "FileSharePasterSettings"; +static const char pathKeyC[] = "Path"; +static const char displayCountKeyC[] = "DisplayCount"; + +namespace CodePaster { + +FileShareProtocolSettings::FileShareProtocolSettings() : + path(QDir::tempPath()), displayCount(10) +{ +} + +void FileShareProtocolSettings::toSettings(QSettings *s) const +{ + s->beginGroup(QLatin1String(settingsGroupC)); + s->setValue(QLatin1String(pathKeyC), path); + s->setValue(QLatin1String(displayCountKeyC), displayCount); + s->endGroup(); +} + +void FileShareProtocolSettings::fromSettings(const QSettings *s) +{ + FileShareProtocolSettings defaultValues; + const QString keyRoot = QLatin1String(settingsGroupC) + QLatin1Char('/'); + path = s->value(keyRoot + QLatin1String(pathKeyC), defaultValues.path).toString(); + displayCount = s->value(keyRoot + QLatin1String(displayCountKeyC), defaultValues.displayCount).toInt(); +} + +bool FileShareProtocolSettings::equals(const FileShareProtocolSettings &rhs) const +{ + return displayCount == rhs.displayCount && path == rhs.path; +} + +FileShareProtocolSettingsWidget::FileShareProtocolSettingsWidget(QWidget *parent) : + QWidget(parent) +{ + m_ui.setupUi(this); +} + +void FileShareProtocolSettingsWidget::setSettings(const FileShareProtocolSettings &s) +{ + m_ui.pathChooser->setPath(s.path); + m_ui.displayCountSpinBox->setValue(s.displayCount); +} + +FileShareProtocolSettings FileShareProtocolSettingsWidget::settings() const +{ + FileShareProtocolSettings rc; + rc.path = m_ui.pathChooser->path(); + rc.displayCount = m_ui.displayCountSpinBox->value(); + return rc; +} + +// ----------FileShareProtocolSettingsPage +FileShareProtocolSettingsPage::FileShareProtocolSettingsPage(const QSharedPointer<FileShareProtocolSettings> &s, + QObject *parent) : + Core::IOptionsPage(parent), m_settings(s) +{ +} + +QString FileShareProtocolSettingsPage::id() const +{ + return QLatin1String("X.FileSharePaster"); +} + +QString FileShareProtocolSettingsPage::displayName() const +{ + return tr("Fileshare"); +} + +QString FileShareProtocolSettingsPage::category() const +{ + return QLatin1String(Constants::CPASTER_SETTINGS_CATEGORY); +} + +QString FileShareProtocolSettingsPage::displayCategory() const +{ + return QCoreApplication::translate("CodePaster", Constants::CPASTER_SETTINGS_TR_CATEGORY); +} + +QIcon FileShareProtocolSettingsPage::categoryIcon() const +{ + return QIcon(); +} + +QWidget *FileShareProtocolSettingsPage::createPage(QWidget *parent) +{ + m_widget = new FileShareProtocolSettingsWidget(parent); + m_widget->setSettings(*m_settings); + return m_widget; +} + +void FileShareProtocolSettingsPage::apply() +{ + const FileShareProtocolSettings newSettings = m_widget->settings(); + if (newSettings != *m_settings) { + *m_settings = newSettings; + m_settings->toSettings(Core::ICore::instance()->settings()); + } +} +} // namespace CodePaster diff --git a/src/plugins/cpaster/fileshareprotocolsettingspage.h b/src/plugins/cpaster/fileshareprotocolsettingspage.h new file mode 100644 index 0000000000000000000000000000000000000000..9705e3c848e483c4d677949d451b1c86beeccd61 --- /dev/null +++ b/src/plugins/cpaster/fileshareprotocolsettingspage.h @@ -0,0 +1,95 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef FILESHAREPROTOCOLSETTINGSPAGE_H +#define FILESHAREPROTOCOLSETTINGSPAGE_H + +#include <coreplugin/dialogs/ioptionspage.h> +#include "ui_fileshareprotocolsettingswidget.h" + +#include <QtCore/QSharedPointer> +#include <QtCore/QPointer> +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QSettings; +QT_END_NAMESPACE + +namespace CodePaster { + +struct FileShareProtocolSettings { + FileShareProtocolSettings(); + void toSettings(QSettings *) const; + void fromSettings(const QSettings *); + bool equals(const FileShareProtocolSettings &rhs) const; + + QString path; + int displayCount; +}; + +inline bool operator==(const FileShareProtocolSettings &s1, const FileShareProtocolSettings &s2) +{ return s1.equals(s2); } +inline bool operator!=(const FileShareProtocolSettings &s1, const FileShareProtocolSettings &s2) +{ return !s1.equals(s2); } + +class FileShareProtocolSettingsWidget : public QWidget { + Q_OBJECT +public: + explicit FileShareProtocolSettingsWidget(QWidget *parent = 0); + + void setSettings(const FileShareProtocolSettings &); + FileShareProtocolSettings settings() const; + +private: + Ui::FileShareProtocolSettingsWidget m_ui; +}; +class FileShareProtocolSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT +public: + explicit FileShareProtocolSettingsPage(const QSharedPointer<FileShareProtocolSettings> &s, + QObject *parent = 0); + + QString id() const; + QString displayName() const; + QString category() const; + QString displayCategory() const; + QIcon categoryIcon() const; + + QWidget *createPage(QWidget *parent); + void apply(); + void finish() { } + +private: + const QSharedPointer<FileShareProtocolSettings> m_settings; + QPointer<FileShareProtocolSettingsWidget> m_widget; +}; +} // namespace CodePaster + +#endif // FILESHAREPROTOCOLSETTINGSPAGE_H diff --git a/src/plugins/cpaster/fileshareprotocolsettingswidget.ui b/src/plugins/cpaster/fileshareprotocolsettingswidget.ui new file mode 100644 index 0000000000000000000000000000000000000000..e36e79f9821eec117a8ca97a4a8302700b824c80 --- /dev/null +++ b/src/plugins/cpaster/fileshareprotocolsettingswidget.ui @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CodePaster::FileShareProtocolSettingsWidget</class> + <widget class="QWidget" name="CodePaster::FileShareProtocolSettingsWidget"> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="1" column="0"> + <widget class="QLabel" name="pathLabel"> + <property name="text"> + <string>&Path:</string> + </property> + <property name="buddy"> + <cstring>pathChooser</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="Utils::PathChooser" name="pathChooser"/> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="displayCountLabel"> + <property name="text"> + <string>&Display:</string> + </property> + <property name="buddy"> + <cstring>displayCountSpinBox</cstring> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="displayCountSpinBox"> + <property name="suffix"> + <string>entries</string> + </property> + <property name="minimum"> + <number>2</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>11</number> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="helpLabel"> + <property name="text"> + <string>The fileshare-based paster protocol allows for sharing code snippets using simple files on a shared network drive. Files are never deleted.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui>