mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 10:52:53 +00:00
792 lines
24 KiB
C++
792 lines
24 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2007 by Thomas Georgiou <TAGeorgiou@gmail.com> *
|
|
* Artur Duque de Souza <asouza@kde.org> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
|
|
***************************************************************************/
|
|
|
|
#include "pastebin.h"
|
|
|
|
#include <KConfigDialog>
|
|
#include <KStandardAction>
|
|
#include <KToolInvocation>
|
|
#include <KNotification>
|
|
#include <KAction>
|
|
|
|
#include <kmimetype.h>
|
|
#include <KTemporaryFile>
|
|
#include <KIO/MimetypeJob>
|
|
#include <KDebug>
|
|
|
|
#include <kio/global.h>
|
|
#include <kio/job.h>
|
|
|
|
#include <Plasma/Theme>
|
|
#include <Plasma/Service>
|
|
#include <Plasma/ServiceJob>
|
|
|
|
#include <QApplication>
|
|
#include <QClipboard>
|
|
#include <QGraphicsLinearLayout>
|
|
#include <QGraphicsScene>
|
|
#include <QtGui/qgraphicssceneevent.h>
|
|
#include <QFile>
|
|
#include <QBuffer>
|
|
#include <QPainter>
|
|
#include <QPaintEngine>
|
|
#include <QSignalMapper>
|
|
#include <QPropertyAnimation>
|
|
|
|
|
|
Pastebin::Pastebin(QObject *parent, const QVariantList &args)
|
|
: Plasma::Applet(parent, args),
|
|
m_signalMapper(new QSignalMapper()), m_paste(0),
|
|
m_topSeparator(0), m_bottomSeparator(0),
|
|
m_historySize(3)
|
|
{
|
|
setAcceptDrops(true);
|
|
setHasConfigurationInterface(true);
|
|
setAspectRatioMode(Plasma::ConstrainedSquare);
|
|
setMinimumSize(16, 16);
|
|
resize(150, 150);
|
|
m_timer = new QTimer(this);
|
|
connect(m_timer, SIGNAL(timeout()), this, SLOT(showErrors()));
|
|
|
|
connect(m_signalMapper, SIGNAL(mapped(QString)),
|
|
this, SLOT(copyToClipboard(QString)));
|
|
connect(this, SIGNAL(activate()), this, SLOT(postClipboard()));
|
|
|
|
// connect to all sources of our 'share' dataengine
|
|
m_engine = dataEngine("org.kde.plasma.dataengine.share");
|
|
m_engine->connectAllSources(this);
|
|
|
|
// to detect when the mimetypes were added again after a refresh
|
|
connect(m_engine, SIGNAL(sourceAdded(QString)),
|
|
this, SLOT(sourceAdded(QString)));
|
|
connect(m_engine, SIGNAL(sourceRemoved(QString)),
|
|
this, SLOT(sourceRemoved(QString)));
|
|
}
|
|
|
|
// save history of URLs
|
|
void Pastebin::saveHistory()
|
|
{
|
|
QString history;
|
|
const int numberOfActionHistory = m_actionHistory.size();
|
|
for (int i = 0; i < numberOfActionHistory; ++i) {
|
|
history.prepend(m_actionHistory.at(i)->toolTip());
|
|
history.prepend('|');
|
|
}
|
|
|
|
KConfigGroup cg = config();
|
|
cg.writeEntry("History", history);
|
|
}
|
|
|
|
Pastebin::~Pastebin()
|
|
{
|
|
delete m_topSeparator;
|
|
delete m_bottomSeparator;
|
|
|
|
saveHistory();
|
|
const int numberOfActionHistory = m_actionHistory.size();
|
|
for (int i = 0; i < numberOfActionHistory; ++i) {
|
|
delete m_actionHistory.at(i);
|
|
}
|
|
}
|
|
|
|
void Pastebin::init()
|
|
{
|
|
configChanged();
|
|
setActionState(Idle);
|
|
setInteractionState(Waiting);
|
|
|
|
updateTheme();
|
|
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(updateTheme()));
|
|
Plasma::ToolTipManager::self()->registerWidget(this);
|
|
Plasma::ToolTipManager::self()->setContent(this, toolTipData);
|
|
}
|
|
|
|
void Pastebin::dataUpdated(const QString &source, const Plasma::DataEngine::Data &data)
|
|
{
|
|
// update the options
|
|
if (source != "Mimetypes") {
|
|
const QString mimetype = data.value("Mimetypes").toString();
|
|
|
|
if (mimetype.startsWith("text/")) {
|
|
m_txtServers.insert(data.value("Name").toString(), source);
|
|
} else if (mimetype.startsWith("image/")) {
|
|
m_imgServers.insert(data.value("Name").toString(), source);
|
|
} else {
|
|
kDebug() << "Mimetype not supported by this applet";
|
|
}
|
|
}
|
|
}
|
|
|
|
void Pastebin::sourceAdded(const QString &source)
|
|
{
|
|
// update the options
|
|
if (source != "Mimetypes") {
|
|
const Plasma::DataEngine::Data data = m_engine->query(source);
|
|
const QString mimetype = data.value("Mimetypes").toString();
|
|
|
|
if (mimetype.startsWith("text/")) {
|
|
m_txtServers.insert(data.value("Name").toString(), source);
|
|
} else if (mimetype.startsWith("image/")) {
|
|
m_imgServers.insert(data.value("Name").toString(), source);
|
|
} else {
|
|
kDebug() << "Mimetype not supported by this applet";
|
|
}
|
|
}
|
|
}
|
|
|
|
void Pastebin::sourceRemoved(const QString &source)
|
|
{
|
|
// update the options
|
|
if (source != "Mimetypes") {
|
|
QString key = m_txtServers.key(source);
|
|
m_txtServers.remove(key);
|
|
|
|
key = m_imgServers.key(source);
|
|
m_imgServers.remove(key);
|
|
}
|
|
}
|
|
|
|
void Pastebin::setHistorySize(int max)
|
|
{
|
|
if (max <= 0) {
|
|
max = 0;
|
|
}
|
|
while (max < m_actionHistory.count()) {
|
|
delete m_actionHistory.takeFirst();
|
|
}
|
|
|
|
m_historySize = max;
|
|
}
|
|
|
|
void Pastebin::updateTheme()
|
|
{
|
|
m_font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont);
|
|
m_font.setBold(true);
|
|
m_fgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
|
|
m_bgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
|
|
m_linePen = QPen(m_fgColor);
|
|
kDebug() << "Color" << m_bgColor << m_fgColor;
|
|
update();
|
|
}
|
|
|
|
void Pastebin::setInteractionState(InteractionState state)
|
|
{
|
|
switch (state ) {
|
|
case Hovered:
|
|
m_linePen.setStyle(Qt::DotLine);
|
|
m_linePen.setWidth(2);
|
|
showOverlay(true);
|
|
break;
|
|
case Waiting:
|
|
showOverlay(false);
|
|
break;
|
|
case DraggedOver:
|
|
m_linePen.setStyle(Qt::DashLine);
|
|
m_linePen.setWidth(2);
|
|
showOverlay(true);
|
|
break;
|
|
case Rejected:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
m_interactionState = state;
|
|
}
|
|
|
|
void Pastebin::setActionState(ActionState state)
|
|
{
|
|
toolTipData = Plasma::ToolTipContent();
|
|
toolTipData.setAutohide(true);
|
|
|
|
toolTipData.setMainText("Pastebin");
|
|
|
|
//TODO: choose icons for each state
|
|
|
|
switch (state ) {
|
|
case Unset:
|
|
toolTipData.setSubText(i18nc("The status of the applet has not been set - i.e. it is unset.", "Unset"));
|
|
toolTipData.setImage(KIcon("edit-paste"));
|
|
break;
|
|
case Idle:
|
|
setBusy(false);
|
|
toolTipData.setSubText(i18n("Drop text or an image onto me to upload it to Pastebin."));
|
|
toolTipData.setImage(KIcon("edit-paste"));
|
|
break;
|
|
case IdleError:
|
|
setBusy(false);
|
|
toolTipData.setSubText(i18n("Error during upload. Try again."));
|
|
toolTipData.setImage(KIcon("dialog-cancel"));
|
|
// Notification ...
|
|
QTimer::singleShot(15000, this, SLOT(resetActionState()));
|
|
m_timer->stop();
|
|
break;
|
|
case IdleSuccess:
|
|
setBusy(false);
|
|
toolTipData.setSubText(i18n("Successfully uploaded to %1.", m_url));
|
|
toolTipData.setImage(KIcon("dialog-ok"));
|
|
// Notification ...
|
|
QTimer::singleShot(15000, this, SLOT(resetActionState()));
|
|
m_timer->stop();
|
|
break;
|
|
case Sending:
|
|
setBusy(true);
|
|
toolTipData.setSubText(i18n("Sending...."));
|
|
toolTipData.setImage(KIcon("view-history"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Plasma::ToolTipManager::self()->setContent(this, toolTipData);
|
|
m_actionState = state;
|
|
update();
|
|
}
|
|
|
|
void Pastebin::constraintsEvent(Plasma::Constraints constraints)
|
|
{
|
|
if (constraints & Plasma::FormFactorConstraint) {
|
|
if (formFactor() == Plasma::Horizontal || formFactor() == Plasma::Vertical ) {
|
|
setPreferredSize(-1, -1);
|
|
} else {
|
|
setPreferredSize(150, 150);
|
|
}
|
|
}
|
|
}
|
|
|
|
int Pastebin::iconSize()
|
|
{
|
|
// return the biggest fitting icon size from KIconLoader
|
|
int c = qMin(contentsRect().width(), contentsRect().height());
|
|
int s;
|
|
if (c >= KIconLoader::SizeEnormous) { // 128
|
|
s = KIconLoader::SizeEnormous;
|
|
} else if (c >= KIconLoader::SizeHuge) { // 64
|
|
s = KIconLoader::SizeHuge;
|
|
} else if (c >= KIconLoader::SizeLarge) { // 48
|
|
s = KIconLoader::SizeLarge;
|
|
} else if (c >= KIconLoader::SizeMedium) { // 32
|
|
s = KIconLoader::SizeMedium;
|
|
} else if (c >= KIconLoader::SizeSmallMedium) { // 32
|
|
s = KIconLoader::SizeSmallMedium;
|
|
} else { // 16
|
|
s = KIconLoader::SizeSmall;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
void Pastebin::paintPixmap(QPainter *painter, QPixmap &pixmap, const QRectF &rect, qreal opacity)
|
|
{
|
|
int size = pixmap.size().width();
|
|
QPointF iconOrigin = QPointF(rect.left() + (rect.width() - size) / 2,
|
|
rect.top() + (rect.height() - size) / 2);
|
|
|
|
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
|
|
if (!painter->paintEngine()->hasFeature(QPaintEngine::ConstantOpacity)) {
|
|
QPixmap temp(QSize(size, size));
|
|
temp.fill(Qt::transparent);
|
|
|
|
QPainter p;
|
|
p.begin(&temp);
|
|
|
|
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
p.drawPixmap(QPoint(0,0), pixmap);
|
|
|
|
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
|
p.fillRect(pixmap.rect(), QColor(0, 0, 0, opacity * 254));
|
|
p.end();
|
|
|
|
// draw the pixmap
|
|
painter->drawPixmap(iconOrigin, temp);
|
|
} else {
|
|
// FIXME: Works, but makes hw acceleration impossible, use above code path
|
|
qreal old = painter->opacity();
|
|
painter->setOpacity(opacity);
|
|
painter->drawPixmap(iconOrigin, pixmap);
|
|
painter->setOpacity(old);
|
|
}
|
|
}
|
|
|
|
void Pastebin::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *, const QRect &contentsRect)
|
|
{
|
|
if (!contentsRect.isValid() || isBusy()) {
|
|
return;
|
|
}
|
|
|
|
// BusyWidget is being shown
|
|
if (m_actionState == Sending) {
|
|
return;
|
|
}
|
|
|
|
// Fade in the icon on top of it
|
|
int iconsize = iconSize();
|
|
qreal pix_alpha = 1.0 - (0.5 * m_alpha); // Fading out to .5
|
|
|
|
QPointF iconOrigin = QPointF(contentsRect.left() + (contentsRect.width() - iconsize) / 2,
|
|
contentsRect.top() + (contentsRect.height() - iconsize) / 2);
|
|
QRectF iconRect = QRectF(iconOrigin, QSize(iconsize, iconsize));
|
|
|
|
if (m_actionState == IdleSuccess) {
|
|
QPixmap iconok = KIcon("dialog-ok").pixmap(QSize(iconsize, iconsize));
|
|
paintPixmap(p, iconok, iconRect, pix_alpha);
|
|
} else if (m_actionState == IdleError) {
|
|
QPixmap iconok = KIcon("dialog-cancel").pixmap(QSize(iconsize, iconsize));
|
|
paintPixmap(p, iconok, iconRect, pix_alpha);
|
|
} else {
|
|
QPixmap iconpix = KIcon("edit-paste").pixmap(QSize(iconsize, iconsize));
|
|
if (!iconpix.isNull()) {
|
|
paintPixmap(p, iconpix, iconRect, pix_alpha);
|
|
}
|
|
}
|
|
|
|
// Draw background
|
|
if (m_interactionState == DraggedOver) {
|
|
m_fgColor.setAlphaF(m_alpha);
|
|
} else if (m_interactionState == Hovered) {
|
|
m_fgColor.setAlphaF(m_alpha * 0.15);
|
|
} else {
|
|
// Whatever, as long as it goes down to 0
|
|
m_fgColor.setAlphaF(m_alpha * 0.15);
|
|
}
|
|
m_bgColor.setAlphaF(m_alpha * 0.3);
|
|
|
|
p->setBrush(m_bgColor);
|
|
m_linePen.setColor(m_fgColor);
|
|
p->setPen(m_linePen);
|
|
p->setFont(m_font);
|
|
|
|
qreal proportion = contentsRect.width() / contentsRect.height();
|
|
qreal round_radius = 35.0;
|
|
p->drawRoundedRect(contentsRect, round_radius / proportion, round_radius, Qt::RelativeSize);
|
|
}
|
|
|
|
void Pastebin::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|
{
|
|
setInteractionState(Hovered);
|
|
Applet::hoverEnterEvent(event);
|
|
}
|
|
|
|
void Pastebin::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
|
{
|
|
setInteractionState(Waiting);
|
|
Applet::hoverLeaveEvent(event);
|
|
}
|
|
|
|
void Pastebin::showOverlay(bool show)
|
|
{
|
|
if (m_fadeIn == show) {
|
|
return;
|
|
}
|
|
m_fadeIn = show;
|
|
|
|
QPropertyAnimation *animation = m_animation.data();
|
|
if (!animation) {
|
|
animation = new QPropertyAnimation(this, "animationUpdate");
|
|
animation->setDuration(400);
|
|
animation->setStartValue(0.0);
|
|
animation->setEndValue(1.0);
|
|
animation->setEasingCurve(QEasingCurve::Linear);
|
|
m_animation = animation;
|
|
} else if (animation->state() == QAbstractAnimation::Running) {
|
|
animation->pause();
|
|
}
|
|
|
|
if (m_fadeIn) {
|
|
animation->setDirection(QAbstractAnimation::Forward);
|
|
animation->start(QAbstractAnimation::KeepWhenStopped);
|
|
} else {
|
|
animation->setDirection(QAbstractAnimation::Backward);
|
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
|
}
|
|
}
|
|
|
|
qreal Pastebin::animationValue() const
|
|
{
|
|
return m_alpha;
|
|
}
|
|
|
|
void Pastebin::animationUpdate(qreal progress)
|
|
{
|
|
m_alpha = progress;
|
|
update();
|
|
}
|
|
|
|
void Pastebin::refreshConfigDialog()
|
|
{
|
|
// setup text
|
|
uiConfig.textServer->clear();
|
|
uiConfig.textServer->addItems(m_txtServers.keys());
|
|
|
|
// setup image
|
|
uiConfig.imageServer->clear();
|
|
uiConfig.imageServer->addItems(m_imgServers.keys());
|
|
}
|
|
|
|
QString Pastebin::getDefaultTextServer()
|
|
{
|
|
QString defaultServer = "paste.kde.org";
|
|
if ( m_txtServers.contains(defaultServer) ) {
|
|
return defaultServer;
|
|
} else {
|
|
return m_txtServers.keys().at(0);
|
|
}
|
|
}
|
|
|
|
void Pastebin::createConfigurationInterface(KConfigDialog *parent)
|
|
{
|
|
KConfigGroup cg = config();
|
|
|
|
QWidget *general = new QWidget();
|
|
uiConfig.setupUi(general);
|
|
|
|
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
|
|
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
|
|
parent->addPage(general, i18n("General"), Applet::icon());
|
|
|
|
refreshConfigDialog();
|
|
uiConfig.textServer->setCurrentItem(cg.readEntry("TextProvider", getDefaultTextServer()));
|
|
uiConfig.imageServer->setCurrentItem(cg.readEntry("ImageProvider", m_imgServers.keys().at(0)));
|
|
uiConfig.historySize->setValue(m_historySize);
|
|
|
|
connect(uiConfig.textServer , SIGNAL(currentIndexChanged(int)) , parent, SLOT(settingsModified()));
|
|
connect(uiConfig.imageServer , SIGNAL(currentIndexChanged(int)) , parent, SLOT(settingsModified()));
|
|
connect(uiConfig.historySize , SIGNAL(valueChanged(int)) , parent, SLOT(settingsModified()));
|
|
}
|
|
|
|
void Pastebin::configAccepted()
|
|
{
|
|
KConfigGroup cg = config();
|
|
int historySize = uiConfig.historySize->value();
|
|
setHistorySize(historySize);
|
|
|
|
cg.writeEntry("TextProvider", uiConfig.textServer->currentText());
|
|
cg.writeEntry("ImageProvider", uiConfig.imageServer->currentText());
|
|
cg.writeEntry("HistorySize", historySize);
|
|
saveHistory();
|
|
|
|
emit configNeedsSaving();
|
|
}
|
|
|
|
void Pastebin::configChanged()
|
|
{
|
|
KConfigGroup cg = config();
|
|
int historySize = cg.readEntry("HistorySize", "3").toInt();
|
|
QStringList history = cg.readEntry("History", "").split('|', QString::SkipEmptyParts);
|
|
|
|
m_actionHistory.clear();
|
|
setHistorySize(historySize);
|
|
const int numberOfItems = history.size();
|
|
for (int i = 0; i < numberOfItems; ++i) {
|
|
addToHistory(history.at(i));
|
|
}
|
|
}
|
|
|
|
void Pastebin::showResults(const QString &url)
|
|
{
|
|
m_timer->stop();
|
|
m_url = url;
|
|
setActionState(IdleSuccess);
|
|
copyToClipboard(url);
|
|
addToHistory(url);
|
|
}
|
|
|
|
void Pastebin::copyToClipboard(const QString &url)
|
|
{
|
|
QApplication::clipboard()->setText(url, lastMode);
|
|
kDebug() << "Copying:" << url;
|
|
m_oldUrl = url;
|
|
QPixmap pix = KIcon("edit-paste").pixmap(KIconLoader::SizeMedium, KIconLoader::SizeMedium);
|
|
|
|
KNotification *notify = new KNotification("urlcopied");
|
|
notify->setComponentData(KComponentData("plasma_pastebin"));
|
|
notify->setText(i18nc("Notification when the pastebin applet has copied the URL to the clipboard",
|
|
"The URL for your paste has been copied to the clipboard"));
|
|
notify->setPixmap(pix);
|
|
notify->setActions(QStringList(i18n("Open browser")));
|
|
connect(notify, SIGNAL(action1Activated()), this, SLOT(openLink()));
|
|
notify->sendEvent();
|
|
}
|
|
|
|
void Pastebin::showErrors()
|
|
{
|
|
setActionState(IdleError);
|
|
}
|
|
|
|
void Pastebin::openLink(bool old)
|
|
{
|
|
if(old) {
|
|
KToolInvocation::invokeBrowser(m_oldUrl);
|
|
} else {
|
|
KToolInvocation::invokeBrowser(m_url);
|
|
}
|
|
}
|
|
|
|
void Pastebin::resetActionState()
|
|
{
|
|
setActionState(Idle);
|
|
update();
|
|
}
|
|
|
|
void Pastebin::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
if (m_url.isEmpty() || event->button() != Qt::LeftButton) {
|
|
Plasma::Applet::mousePressEvent(event);
|
|
} else {
|
|
openLink(false);
|
|
}
|
|
if (event->button() == Qt::MidButton) {
|
|
if (m_actionState == Idle) {
|
|
// paste clipboard content
|
|
postClipboard(true);
|
|
} else {
|
|
// Now releasing the middlebutton click copies to clipboard
|
|
event->accept();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Pastebin::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
|
|
{
|
|
if (!m_url.isEmpty() && event->button() == Qt::MidButton && m_actionState == IdleSuccess) {
|
|
copyToClipboard(m_url);
|
|
}
|
|
}
|
|
|
|
void Pastebin::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
InteractionState istate = Rejected;
|
|
if (event->mimeData()->hasFormat("text/plain")) {
|
|
event->acceptProposedAction();
|
|
}
|
|
foreach (const QString &f, event->mimeData()->formats()) {
|
|
if (f.indexOf("image/") != -1) {
|
|
istate = DraggedOver;
|
|
}
|
|
}
|
|
if (event->mimeData()->hasImage() || event->mimeData()->hasText()) {
|
|
istate = DraggedOver;
|
|
}
|
|
setInteractionState(istate);
|
|
}
|
|
|
|
void Pastebin::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
Q_UNUSED(event);
|
|
setInteractionState(Waiting);
|
|
}
|
|
|
|
void Pastebin::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
event->accept();
|
|
}
|
|
|
|
void Pastebin::dropEvent(QGraphicsSceneDragDropEvent *event)
|
|
{
|
|
if (event->mimeData()->objectName() != QString("Pastebin-applet")) {
|
|
lastMode = QClipboard::Clipboard;
|
|
#ifdef Q_WS_WIN
|
|
// Apparently, Windows doesn't pass any actual image data when drag'n'dropping
|
|
// image files. Though, it does provide us with those files' Urls. Since posting
|
|
// multiple images isn't yet implemented - we'll use first Url from list
|
|
QImage image;
|
|
QString imageFileName;
|
|
if (event->mimeData()->hasUrls()) {
|
|
imageFileName = event->mimeData()->urls().at(0).toLocalFile();
|
|
image.load(imageFileName);
|
|
postContent(imageFileName, image);
|
|
} else {
|
|
postContent(event->mimeData()->text(), image);
|
|
};
|
|
#else
|
|
QImage image = qvariant_cast<QImage>(event->mimeData()->imageData());
|
|
postContent(event->mimeData()->text(), image);
|
|
#endif //Q_WS_WIN
|
|
event->acceptProposedAction();
|
|
}
|
|
}
|
|
|
|
void Pastebin::addToHistory(const QString &url)
|
|
{
|
|
if (m_historySize <= 0) {
|
|
return;
|
|
}
|
|
|
|
if (m_actionHistory.size() >= m_historySize) {
|
|
delete m_actionHistory.takeLast();
|
|
}
|
|
|
|
QAction *ac = new QAction(url, this);
|
|
m_actionHistory.insert(0, ac);
|
|
m_signalMapper->setMapping(ac, url);
|
|
connect(ac, SIGNAL(triggered(bool)), m_signalMapper, SLOT(map()));
|
|
}
|
|
|
|
QList<QAction*> Pastebin::contextualActions()
|
|
{
|
|
if (!m_paste) {
|
|
m_paste = KStandardAction::paste(this);
|
|
connect(m_paste, SIGNAL(triggered(bool)), this, SLOT(postClipboard()));
|
|
}
|
|
if (!m_topSeparator) {
|
|
m_topSeparator = new QAction(this);
|
|
m_topSeparator->setSeparator(true);
|
|
}
|
|
if (!m_bottomSeparator) {
|
|
m_bottomSeparator = new QAction(this);
|
|
m_bottomSeparator->setSeparator(true);
|
|
}
|
|
|
|
m_contextualActions.clear();
|
|
|
|
m_contextualActions.append(m_paste);
|
|
m_contextualActions.append(m_topSeparator);
|
|
m_contextualActions.append(m_actionHistory);
|
|
|
|
if (!m_actionHistory.isEmpty()) {
|
|
m_contextualActions.append(m_bottomSeparator);
|
|
}
|
|
|
|
return m_contextualActions;
|
|
}
|
|
|
|
void Pastebin::postClipboard()
|
|
{
|
|
postClipboard(false);
|
|
}
|
|
|
|
void Pastebin::postClipboard(bool preferSelection)
|
|
{
|
|
lastMode = QClipboard::Clipboard;
|
|
#ifdef Q_WS_WIN
|
|
// Same as for D'n'D, Windows doesn't pass any actual image data when pasting
|
|
// image files. Though, it does provide us with those files' Urls. Since posting
|
|
// multiple images isn't yet implemented - we'll use first Url from list
|
|
QImage image;
|
|
QString imageFileName;
|
|
if (QApplication::clipboard()->mimeData()->hasUrls()) {
|
|
imageFileName = QApplication::clipboard()->mimeData()->urls().at(0).toLocalFile();
|
|
image.load(imageFileName);
|
|
postContent(imageFileName, image);
|
|
} else {
|
|
postContent(QApplication::clipboard()->mimeData()->text(), image);
|
|
};
|
|
#else
|
|
if (preferSelection) {
|
|
lastMode = QApplication::clipboard()->supportsSelection() ? QClipboard::Selection : QClipboard::Clipboard;
|
|
postContent(QApplication::clipboard()->text(lastMode), QApplication::clipboard()->image(lastMode));
|
|
} else {
|
|
postContent(QApplication::clipboard()->text(), QApplication::clipboard()->image());
|
|
}
|
|
#endif //Q_WS_WIN
|
|
}
|
|
|
|
void Pastebin::postContent(QString text, const QImage& imageData)
|
|
{
|
|
QString sourceName;
|
|
KUrl testPath(text);
|
|
bool validPath = true;
|
|
|
|
// use KIO to check if the file exists using mimetype job
|
|
KIO::MimetypeJob *mjob = KIO::mimetype(testPath);
|
|
if (!mjob->exec()) {
|
|
// it's not a file - usually this happens when we are
|
|
// just sharing plain text or image
|
|
validPath = false;
|
|
}
|
|
|
|
KConfigGroup cg = config();
|
|
// This is needed to provide smooth transition between old config and new one
|
|
const QString txtProvider = cg.readEntry("TextProvider", getDefaultTextServer());
|
|
const QString imgProvider = cg.readEntry("ImageProvider", m_imgServers.keys().at(0));
|
|
|
|
bool isTemporary = false;
|
|
if (validPath) {
|
|
KMimeType::Ptr type = KMimeType::findByPath(testPath.path());
|
|
|
|
if (type->name().indexOf("image/") != -1) {
|
|
// its image
|
|
sourceName = m_imgServers.value(imgProvider);
|
|
} else {
|
|
// its text
|
|
sourceName = m_txtServers.value(txtProvider);
|
|
}
|
|
} else if (imageData.isNull()) {
|
|
sourceName = m_txtServers.value(txtProvider);
|
|
} else {
|
|
sourceName = m_imgServers.value(imgProvider);
|
|
|
|
KTemporaryFile tempFile;
|
|
tempFile.setSuffix(".png");
|
|
if (tempFile.open()) {
|
|
tempFile.setAutoRemove(false);
|
|
|
|
imageData.save(&tempFile, "PNG");
|
|
tempFile.close();
|
|
|
|
text = tempFile.fileName();
|
|
|
|
isTemporary = true;
|
|
} else {
|
|
setActionState(IdleError);
|
|
return;
|
|
}
|
|
}
|
|
|
|
kDebug() << "Is valid path: " << validPath;
|
|
kDebug() << "Provider used: " << sourceName;
|
|
|
|
if (sourceName.isEmpty()) {
|
|
// no provider was configured
|
|
showErrors();
|
|
return;
|
|
}
|
|
|
|
m_postingService = m_engine->serviceForSource(sourceName);
|
|
KConfigGroup ops = m_postingService->operationDescription("share");
|
|
ops.writeEntry("content", text);
|
|
|
|
Plasma::ServiceJob *job = m_postingService->startOperationCall(ops);
|
|
if (isTemporary) // Store tempfile-job mapping for cleanup when finished.
|
|
m_pendingTempFileJobs[job] = text;
|
|
connect(job, SIGNAL(finished(KJob*)), this, SLOT(postingFinished(KJob*)));
|
|
|
|
setActionState(Sending);
|
|
m_timer->start(20000);
|
|
}
|
|
|
|
void Pastebin::postingFinished(KJob *job)
|
|
{
|
|
Plasma::ServiceJob *sjob = static_cast<Plasma::ServiceJob*>(job);
|
|
if (sjob->error()) {
|
|
showErrors();
|
|
} else {
|
|
showResults(sjob->result().toString());
|
|
}
|
|
|
|
// Cleanup of temp file...
|
|
QString tempUrl = m_pendingTempFileJobs.take(job);
|
|
if (!tempUrl.isEmpty())
|
|
KIO::file_delete(KUrl(tempUrl), KIO::HideProgressInfo);
|
|
}
|
|
|
|
|
|
|
|
#include "moc_pastebin.cpp"
|