2 Copyright 2008 Google Inc.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
17 #include <QtCore/QDir>
18 #include <QtCore/QFile>
19 #include <QtGui/QFontDatabase>
20 #include <QtGui/QMessageBox>
21 #include <kconfiggroup.h>
22 #include <kstandarddirs.h>
23 #include <ggadget/gadget.h>
24 #include <ggadget/gadget_consts.h>
25 #include <ggadget/host_interface.h>
26 #include <ggadget/string_utils.h>
27 #include <ggadget/gadget_manager_interface.h>
28 #include <ggadget/file_manager_interface.h>
29 #include <ggadget/system_utils.h>
30 #include <ggadget/scoped_ptr.h>
31 #include <ggadget/view.h>
32 #include <ggadget/messages.h>
33 #include <ggadget/permissions.h>
34 #include <ggadget/qt/qt_view_host.h>
35 #include <ggadget/qt/utilities.h>
36 #include "ggl_extensions.h"
37 #include "ggl_package.h"
39 using namespace ggadget
;
41 K_EXPORT_PLASMA_PACKAGESTRUCTURE(googlegadget
, GglPackage
)
43 class GadgetBrowserViewHost
: public qt::QtViewHost
{
45 GadgetBrowserViewHost(GglPackage
*package
, Type type
)
46 : QtViewHost(type
, 1.0, FLAG_RECORD_STATES
, 0, NULL
),
49 virtual void CloseView() {
50 package_
->gadgetBrowserClosed();
55 class GadgetBrowserHost
: public ggadget::HostInterface
{
57 GadgetBrowserHost(GglPackage
*package
)
58 : gadget_manager_(NULL
),
61 kDebug() << "Create GadgetBrowserHost:" << this;
62 std::string profile_dir
=
63 ggadget::BuildFilePath(ggadget::GetHomeDirectory().c_str(),
64 ".google/gadgets-plasma", NULL
);
67 if (!ggadget::qt::InitGGL(NULL
, "ggl-plasma", profile_dir
.c_str(),
69 ggadget::qt::GGL_INIT_FLAG_COLLECTOR
, &error
)) {
70 kError() << "Failed to init GGL system:" << error
;
73 gadget_manager_
= GetGadgetManager();
74 connection_
= gadget_manager_
->ConnectOnNewGadgetInstance(
75 NewSlot(this, &GadgetBrowserHost::newGadgetInstanceCallback
));
78 ~GadgetBrowserHost() {
79 kDebug() << "Destroy GadgetBrowserHost:" << this;
80 connection_
->Disconnect();
83 static QString
extractGadgetIcon(const std::string
& gadget_path
,
84 const QString
& dest_dir
) {
85 ggadget::StringMap map
;
87 if (!ggadget::Gadget::GetGadgetManifest(gadget_path
.c_str(), &map
))
90 std::string icon
= map
[ggadget::kManifestIcon
];
91 if (icon
.empty()) return QString();
93 ggadget::scoped_ptr
<ggadget::FileManagerInterface
> fm(
94 ggadget::Gadget::GetGadgetFileManagerForLocale(gadget_path
.c_str(),
97 if (!fm
.get()) return QString();
100 fm
->ReadFile(icon
.c_str(), &data
);
101 if (data
.empty()) return QString();
104 if (pixmap
.loadFromData(reinterpret_cast<const uchar
*>(data
.c_str()),
105 static_cast<int>(data
.length()))) {
106 QString dest
= dest_dir
+ "/icon.png";
107 if (pixmap
.save(dest
, "png"))
113 bool installPlasmaApplet(int id
) {
114 std::string author
, download_url
, title
, description
;
115 if (!gadget_manager_
->GetGadgetInstanceInfo(id
, "", &author
, &download_url
,
116 &title
, &description
))
118 std::string path
= gadget_manager_
->GetGadgetInstancePath(id
).c_str();
119 std::string options
= gadget_manager_
->GetGadgetInstanceOptionsName(id
);
120 QString pkg_name
= QString("ggl_%1").arg(id
);
123 QString plasmods_dir
=
124 KStandardDirs::locateLocal("data", "plasma/plasmoids/");
125 QDir
root(plasmods_dir
);
126 if (!root
.cd(pkg_name
) &&
127 (!root
.mkpath(pkg_name
) || !root
.cd(pkg_name
))) {
128 LOGE("Failed to create package %s",
129 (root
.path() + "/" + pkg_name
).toUtf8().data());
133 QFile
file(root
.path() + "/config.txt");
134 file
.open(QIODevice::WriteOnly
);
135 QTextStream
out(&file
);
136 out
<< QString::fromUtf8(path
.c_str()) << "\n";
137 out
<< QString::fromUtf8(options
.c_str()) << "\n";
141 Plasma::PackageMetadata data
;
142 data
.setPluginName(pkg_name
);
143 data
.setType("Service");
144 data
.setAuthor(QString::fromUtf8(author
.c_str()));
145 data
.setImplementationApi("googlegadgets");
146 data
.setName(QString::fromUtf8(title
.c_str()));
147 data
.setDescription(QString::fromUtf8(description
.c_str()));
150 QString icon
= extractGadgetIcon(path
, root
.path());
152 Plasma::Package::registerPackage(data
, icon
);
156 bool newGadgetInstanceCallback(int id
) {
157 if (ggadget::qt::ConfirmGadget(gadget_manager_
, id
)) {
158 return installPlasmaApplet(id
);
160 QMessageBox::information(
162 QString::fromUtf8(GM_("GOOGLE_GADGETS")),
165 GM_("GADGET_LOAD_FAILURE"),
166 gadget_manager_
->GetGadgetInstancePath(id
).c_str()).c_str()));
171 virtual ViewHostInterface
*NewViewHost(Gadget
*gadget
,
172 ViewHostInterface::Type type
) {
174 return new GadgetBrowserViewHost(package_
, type
);
177 virtual Gadget
*LoadGadget(const char *path
, const char *options_name
,
178 int instance_id
, bool show_debug_console
) {
180 Q_UNUSED(options_name
);
181 Q_UNUSED(instance_id
);
182 Q_UNUSED(show_debug_console
);
186 virtual void RemoveGadget(Gadget
*gadget
, bool save_data
) {
188 gadget_manager_
->RemoveGadgetInstance(gadget
->GetInstanceID());
191 virtual bool LoadFont(const char *filename
) {
192 return QFontDatabase::addApplicationFont(filename
) != -1;
195 virtual void Run() {}
196 virtual void ShowGadgetAboutDialog(Gadget
*) { }
197 virtual void ShowGadgetDebugConsole(Gadget
*) {}
198 virtual int GetDefaultFontSize() { return ggadget::kDefaultFontSize
; }
199 virtual bool OpenURL(const Gadget
*, const char *) { return false; }
201 GadgetManagerInterface
*gadget_manager_
;
202 GglPackage
*package_
;
203 Connection
*connection_
;
206 GglPackage::GglPackage(QObject
*parent
, const QVariantList
&args
)
207 : Plasma::PackageStructure(parent
), host_(NULL
) {
210 setDefaultMimetypes(QStringList() << "application/zip"
211 << "application/x-googlegadget" );
214 GglPackage::~GglPackage() {
218 bool GglPackage::installPackage(const QString
&archive_path
,
219 const QString
&package_root
) {
220 Q_UNUSED(package_root
);
222 host_
= new GadgetBrowserHost(this);
223 if (!host_
|| !host_
->gadget_manager_
) {
229 int result
= host_
->gadget_manager_
->NewGadgetInstanceFromFile(
230 archive_path
.toUtf8().data());
241 void GglPackage::createNewWidgetBrowser(QWidget
*parent
) {
243 host_
= new GadgetBrowserHost(this);
244 if (!host_
|| !host_
->gadget_manager_
) {
245 gadgetBrowserClosed(); // Actually, it's never opened
248 GetGadgetManager()->ShowGadgetBrowserDialog(host_
);
251 void GglPackage::gadgetBrowserClosed() {
254 emit
newWidgetBrowserFinished();