Plasma
accessappletjob.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2009 Rob Scheepmaker <r.scheepmaker@student.utwente.nl> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "accessappletjob.h" 00021 00022 #include "service.h" 00023 #include "servicejob.h" 00024 #include "applet.h" 00025 00026 #include "config-plasma.h" 00027 00028 #include <kzip.h> 00029 #include <kdebug.h> 00030 #include <kmessagebox.h> 00031 #include <ktempdir.h> 00032 #include <kdesktopfile.h> 00033 #include "package.h" 00034 #include <qtimer.h> 00035 #include "private/applet_p.h" 00036 00037 namespace Plasma 00038 { 00039 00040 class AccessAppletJobPrivate 00041 { 00042 public: 00043 AccessAppletJobPrivate(const KUrl &location, AccessAppletJob *owner) 00044 : q(owner), 00045 location(location), 00046 applet(0) 00047 { 00048 } 00049 00050 void slotStart() 00051 { 00052 q->start(); 00053 } 00054 00055 void slotServiceReady(Plasma::Service *service) 00056 { 00057 KConfigGroup op = service->operationDescription("GetPackage"); 00058 service->startOperationCall(op); 00059 q->connect(service, SIGNAL(finished(Plasma::ServiceJob*)), 00060 q, SLOT(slotPackageDownloaded(Plasma::ServiceJob*))); 00061 } 00062 00063 void slotPackageDownloaded(Plasma::ServiceJob *job) 00064 { 00065 if (job->error()) { 00066 kDebug() << "Plasmoid Access Job triggers an error."; 00067 q->setError(job->error()); 00068 q->setErrorText(job->errorText()); 00069 } 00070 00071 //TODO: there's some duplication with installPackage, but we don't want to actually install 00072 //the fetched package. Just extract the archive somewhere in a temp directory. 00073 if (job->result().type() == QVariant::String) { 00074 QString pluginName = job->result().toString(); 00075 kDebug() << "Server responded with a pluginname, trying to load: " << pluginName; 00076 00077 applet = Applet::load(pluginName); 00078 if (applet) { 00079 applet->d->remoteLocation = location.prettyUrl(); 00080 } else { 00081 q->setError(-1); 00082 q->setErrorText(i18n("The \"%1\" widget is not installed.", pluginName)); 00083 } 00084 00085 q->emitResult(); 00086 } else { 00087 kDebug() << "Server responded with a plasmoid package"; 00088 //read, and extract the plasmoid package to a temporary directory 00089 QByteArray package = job->result().toByteArray(); 00090 QDataStream stream(&package, QIODevice::ReadOnly); 00091 00092 KZip archive(stream.device()); 00093 if (!archive.open(QIODevice::ReadOnly)) { 00094 kWarning() << "Could not open package file"; 00095 q->setError(-1); 00096 q->setErrorText(i18n("Server sent an invalid plasmoid package.")); 00097 q->emitResult(); 00098 return; 00099 } 00100 00101 const KArchiveDirectory *source = archive.directory(); 00102 00103 KTempDir tempDir; 00104 tempDir.setAutoRemove(false); 00105 QString path = tempDir.name(); 00106 source->copyTo(path); 00107 00108 KDesktopFile metadata(path + "/metadata.desktop"); 00109 KConfigGroup group = metadata.desktopGroup(); 00110 00111 QString iconName = group.readEntry("Icon"); 00112 QString message = i18n("You are about to open a remote widget on your system.<br>"); 00113 message+= i18n("<table width=\"100%\">"); 00114 message+= i18n("<tr><td align=\"right\"><b>Name:</b></td><td> %1</td></tr>", group.readEntry("Name")); 00115 message+= i18n("<tr><td align=\"right\"><b>Description:</b></td><td> %1</td></tr>", group.readEntry("Comment")); 00116 message+= i18n("<tr><td align=\"right\"><b>Author:</b></td><td> %1 <%2></td></tr>", 00117 group.readEntry("X-KDE-PluginInfo-Author"), 00118 group.readEntry("X-KDE-PluginInfo-Email")); 00119 message+= i18n("<tr><td align=\"right\"><b>Server:</b></td><td> %1</td></tr>", location.host()); 00120 message+= i18n("</table>"); 00121 message+= i18n("<br><br>Are you sure you want to open this widget on your system?"); 00122 00123 KDialog *dialog = new KDialog; 00124 dialog->setWindowTitle(i18n("Remote Widget")); 00125 dialog->setButtons(KDialog::Yes|KDialog::No); 00126 dialog->setButtonText(KDialog::Yes, i18n("Open Widget")); 00127 dialog->setButtonText(KDialog::No, i18n("Reject Widget")); 00128 00129 int answer = KMessageBox::createKMessageBox(dialog, KIcon(iconName), message, 00130 QStringList(), QString(), 0, 00131 KMessageBox::Dangerous); 00132 //int answer = KMessageBox::questionYesNo(0, message, i18n("Remote Widget")); 00133 00134 if (answer!=KDialog::Yes) { 00135 q->setError(-1); 00136 q->setErrorText(i18n("User rejected")); 00137 q->emitResult(); 00138 return; 00139 } 00140 00149 applet = Applet::loadPlasmoid(path); 00150 if (applet) { 00151 applet->d->remoteLocation = location.prettyUrl(); 00152 } else { 00153 q->setError(-1); 00154 } 00155 00156 q->emitResult(); 00157 } 00158 } 00159 00160 void slotTimeout() 00161 { 00162 kWarning() << "Plasmoid access job timed out"; 00163 q->setError(-1); 00164 q->setErrorText(i18n("Timeout")); 00165 q->emitResult(); 00166 } 00167 00168 AccessAppletJob *q; 00169 KUrl location; 00170 Applet *applet; 00171 }; 00172 00173 AccessAppletJob::AccessAppletJob(const KUrl &location, QObject *parent) 00174 : KJob(parent), 00175 d(new AccessAppletJobPrivate(location, this)) 00176 { 00177 QTimer::singleShot(30000, this, SLOT(slotTimeout())); 00178 } 00179 00180 AccessAppletJob::~AccessAppletJob() 00181 { 00182 delete d; 00183 } 00184 00185 Applet *AccessAppletJob::applet() const 00186 { 00187 return d->applet; 00188 } 00189 00190 void AccessAppletJob::start() 00191 { 00192 #ifdef ENABLE_REMOTE_WIDGETS 00193 kDebug() << "fetching a plasmoid from location = " << d->location.prettyUrl(); 00194 Service *service = Service::access(d->location); 00195 connect(service, SIGNAL(serviceReady(Plasma::Service*)), 00196 this, SLOT(slotServiceReady(Plasma::Service*))); 00197 #else 00198 kWarning() << "libplasma was compiled without support for remote services. Accessing remote applet failed because of that."; 00199 setError(-1); 00200 setErrorText(i18n("Your system does not provide support for the 'remote widgets' feature. Access Failed.")); 00201 emitResult(); 00202 #endif 00203 } 00204 00205 } // namespace Plasma 00206 00207 #include "accessappletjob.moc" 00208
KDE 4.7 API Reference