00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <QtCore/QDir>
00018 #include <QtCore/QFile>
00019 #include <QtGui/QFontDatabase>
00020 #include <QtGui/QMessageBox>
00021 #include <kconfiggroup.h>
00022 #include <kstandarddirs.h>
00023 #include <ggadget/gadget.h>
00024 #include <ggadget/gadget_consts.h>
00025 #include <ggadget/host_interface.h>
00026 #include <ggadget/string_utils.h>
00027 #include <ggadget/gadget_manager_interface.h>
00028 #include <ggadget/file_manager_interface.h>
00029 #include <ggadget/system_utils.h>
00030 #include <ggadget/scoped_ptr.h>
00031 #include <ggadget/view.h>
00032 #include <ggadget/messages.h>
00033 #include <ggadget/permissions.h>
00034 #include <ggadget/qt/qt_view_host.h>
00035 #include <ggadget/qt/utilities.h>
00036 #include "ggl_extensions.h"
00037 #include "ggl_package.h"
00038
00039 using namespace ggadget;
00040
00041 K_EXPORT_PLASMA_PACKAGESTRUCTURE(googlegadget, GglPackage)
00042
00043 class GadgetBrowserViewHost : public qt::QtViewHost {
00044 public:
00045 GadgetBrowserViewHost(GglPackage *package, Type type)
00046 : QtViewHost(type, 1.0, FLAG_RECORD_STATES, 0, NULL),
00047 package_(package) {}
00048
00049 virtual void CloseView() {
00050 package_->gadgetBrowserClosed();
00051 }
00052 GglPackage *package_;
00053 };
00054
00055 class GadgetBrowserHost : public ggadget::HostInterface {
00056 public:
00057 GadgetBrowserHost(GglPackage *package)
00058 : gadget_manager_(NULL),
00059 package_(package),
00060 connection_(NULL) {
00061 kDebug() << "Create GadgetBrowserHost:" << this;
00062 std::string profile_dir =
00063 ggadget::BuildFilePath(ggadget::GetHomeDirectory().c_str(),
00064 ".google/gadgets-plasma", NULL);
00065
00066 QString error;
00067 if (!ggadget::qt::InitGGL(NULL, "ggl-plasma", profile_dir.c_str(),
00068 kGlobalExtensions, 0,
00069 ggadget::qt::GGL_INIT_FLAG_COLLECTOR, &error)) {
00070 kError() << "Failed to init GGL system:" << error;
00071 return;
00072 }
00073 gadget_manager_ = GetGadgetManager();
00074 connection_ = gadget_manager_->ConnectOnNewGadgetInstance(
00075 NewSlot(this, &GadgetBrowserHost::newGadgetInstanceCallback));
00076 }
00077
00078 ~GadgetBrowserHost() {
00079 kDebug() << "Destroy GadgetBrowserHost:" << this;
00080 connection_->Disconnect();
00081 }
00082
00083 static QString extractGadgetIcon(const std::string& gadget_path,
00084 const QString& dest_dir) {
00085 ggadget::StringMap map;
00086
00087 if (!ggadget::Gadget::GetGadgetManifest(gadget_path.c_str(), &map))
00088 return QString();
00089
00090 std::string icon = map[ggadget::kManifestIcon];
00091 if (icon.empty()) return QString();
00092
00093 ggadget::scoped_ptr<ggadget::FileManagerInterface> fm(
00094 ggadget::Gadget::GetGadgetFileManagerForLocale(gadget_path.c_str(),
00095 NULL));
00096
00097 if (!fm.get()) return QString();
00098
00099 std::string data;
00100 fm->ReadFile(icon.c_str(), &data);
00101 if (data.empty()) return QString();
00102
00103 QPixmap pixmap;
00104 if (pixmap.loadFromData(reinterpret_cast<const uchar *>(data.c_str()),
00105 static_cast<int>(data.length()))) {
00106 QString dest = dest_dir + "/icon.png";
00107 if (pixmap.save(dest, "png"))
00108 return dest;
00109 }
00110 return QString();
00111 }
00112
00113 bool installPlasmaApplet(int id) {
00114 std::string author, download_url, title, description;
00115 if (!gadget_manager_->GetGadgetInstanceInfo(id, "", &author, &download_url,
00116 &title, &description))
00117 return false;
00118 std::string path = gadget_manager_->GetGadgetInstancePath(id).c_str();
00119 std::string options = gadget_manager_->GetGadgetInstanceOptionsName(id);
00120 QString pkg_name = QString("ggl_%1").arg(id);
00121
00122
00123 QString plasmods_dir =
00124 KStandardDirs::locateLocal("data", "plasma/plasmoids/");
00125 QDir root(plasmods_dir);
00126 if (!root.cd(pkg_name) &&
00127 (!root.mkpath(pkg_name) || !root.cd(pkg_name))) {
00128 LOGE("Failed to create package %s",
00129 (root.path() + "/" + pkg_name).toUtf8().data());
00130 return false;
00131 }
00132 {
00133 QFile file(root.path() + "/config.txt");
00134 file.open(QIODevice::WriteOnly);
00135 QTextStream out(&file);
00136 out << QString::fromUtf8(path.c_str()) << "\n";
00137 out << QString::fromUtf8(options.c_str()) << "\n";
00138 }
00139
00140
00141 Plasma::PackageMetadata data;
00142 data.setPluginName(pkg_name);
00143 data.setType("Service");
00144 data.setAuthor(QString::fromUtf8(author.c_str()));
00145 data.setImplementationApi("googlegadgets");
00146 data.setName(QString::fromUtf8(title.c_str()));
00147 data.setDescription(QString::fromUtf8(description.c_str()));
00148
00149
00150 QString icon = extractGadgetIcon(path, root.path());
00151
00152 Plasma::Package::registerPackage(data, icon);
00153 return true;
00154 }
00155
00156 bool newGadgetInstanceCallback(int id) {
00157 if (ggadget::qt::ConfirmGadget(gadget_manager_, id)) {
00158 return installPlasmaApplet(id);
00159 } else {
00160 QMessageBox::information(
00161 NULL,
00162 QString::fromUtf8(GM_("GOOGLE_GADGETS")),
00163 QString::fromUtf8(
00164 StringPrintf(
00165 GM_("GADGET_LOAD_FAILURE"),
00166 gadget_manager_->GetGadgetInstancePath(id).c_str()).c_str()));
00167 return false;
00168 }
00169 }
00170
00171 virtual ViewHostInterface *NewViewHost(Gadget *gadget,
00172 ViewHostInterface::Type type) {
00173 Q_UNUSED(gadget);
00174 return new GadgetBrowserViewHost(package_, type);
00175 }
00176
00177 virtual Gadget *LoadGadget(const char *path, const char *options_name,
00178 int instance_id, bool show_debug_console) {
00179 Q_UNUSED(path);
00180 Q_UNUSED(options_name);
00181 Q_UNUSED(instance_id);
00182 Q_UNUSED(show_debug_console);
00183 return 0;
00184 }
00185
00186 virtual void RemoveGadget(Gadget *gadget, bool save_data) {
00187 Q_UNUSED(save_data);
00188 gadget_manager_->RemoveGadgetInstance(gadget->GetInstanceID());
00189 }
00190
00191 virtual bool LoadFont(const char *filename) {
00192 return QFontDatabase::addApplicationFont(filename) != -1;
00193 }
00194
00195 virtual void Run() {}
00196 virtual void ShowGadgetAboutDialog(Gadget*) { }
00197 virtual void ShowGadgetDebugConsole(Gadget*) {}
00198 virtual int GetDefaultFontSize() { return ggadget::kDefaultFontSize; }
00199 virtual bool OpenURL(const Gadget *, const char *) { return false; }
00200
00201 GadgetManagerInterface *gadget_manager_;
00202 GglPackage *package_;
00203 Connection *connection_;
00204 };
00205
00206 GglPackage::GglPackage(QObject *parent, const QVariantList &args)
00207 : Plasma::PackageStructure(parent), host_(NULL) {
00208 Q_UNUSED(args);
00209
00210 setDefaultMimetypes(QStringList() << "application/zip"
00211 << "application/x-googlegadget" );
00212 }
00213
00214 GglPackage::~GglPackage() {
00215 delete host_;
00216 }
00217
00218 bool GglPackage::installPackage(const QString &archive_path,
00219 const QString &package_root) {
00220 Q_UNUSED(package_root);
00221 ASSERT(!host_);
00222 host_ = new GadgetBrowserHost(this);
00223 if (!host_ || !host_->gadget_manager_) {
00224 delete host_;
00225 host_ = NULL;
00226 return false;
00227 }
00228
00229 int result = host_->gadget_manager_->NewGadgetInstanceFromFile(
00230 archive_path.toUtf8().data());
00231
00232 delete host_;
00233 host_ = NULL;
00234
00235 if (result == -1)
00236 return false;
00237 else
00238 return true;
00239 }
00240
00241 void GglPackage::createNewWidgetBrowser(QWidget *parent) {
00242 ASSERT(!host_);
00243 host_ = new GadgetBrowserHost(this);
00244 if (!host_ || !host_->gadget_manager_) {
00245 gadgetBrowserClosed();
00246 return;
00247 }
00248 GetGadgetManager()->ShowGadgetBrowserDialog(host_);
00249 }
00250
00251 void GglPackage::gadgetBrowserClosed() {
00252 delete host_;
00253 host_ = NULL;
00254 emit newWidgetBrowserFinished();
00255 }