1 /*
2 KDE Telepathy AdiumxtraProtocolHandler - Install Adiumxtra packages through adiumxtra://-pseudo protocol
3 Copyright (C) 2010 Dominik Schmidt <domme@rautelinux.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "chat-style-installer.h"
20
21 #include "chat-window-style-manager.h"
22 #include "chat-style-plist-file-reader.h"
23
24 #include <QTemporaryFile>
25 #include <QTimer>
26 #include <QDebug>
27
28 #include <KLocalizedString>
29 #include <KArchiveFile>
30 #include <KNotification>
31
32 // FIXME: Part of a hack to let adiumxtra-protocol-handler use the main ktelepathy.notifyrc because
33 // the string freeze does not permit adding a new notifyrc only for adiumxtra-protocol-handler.
34 // Remove this after 0.7 is released.
ktelepathyComponentName()35 static QString ktelepathyComponentName() {
36 return QStringLiteral("ktelepathy");
37 }
38
ChatStyleInstaller(KArchive * archive,QTemporaryFile * tmpFile)39 ChatStyleInstaller::ChatStyleInstaller(KArchive *archive, QTemporaryFile *tmpFile)
40 {
41 m_archive = archive;
42 m_tmpFile = tmpFile;
43 }
44
~ChatStyleInstaller()45 ChatStyleInstaller::~ChatStyleInstaller()
46 {
47 }
48
validate()49 BundleInstaller::BundleStatus ChatStyleInstaller::validate()
50 {
51 KArchiveEntry *currentEntry = 0L;
52 KArchiveDirectory* currentDir = 0L;
53 const KArchiveDirectory* rootDir = m_archive->directory();
54 int validResult = 0;
55 const QStringList entries = rootDir->entries();
56 QStringList::ConstIterator entriesIt;
57
58 for (entriesIt = entries.begin(); entriesIt != entries.end(); ++entriesIt) {
59 currentEntry = const_cast<KArchiveEntry*>(rootDir->entry(*entriesIt));
60 if (currentEntry->isDirectory()) {
61 currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry);
62 if (currentDir) {
63 if (currentDir->entry(QLatin1String("Contents")) &&
64 currentDir->entry(QLatin1String("Contents"))->isDirectory()) {
65 validResult += 1;
66 }
67 if (currentDir->entry(QLatin1String("Contents/Info.plist")) &&
68 currentDir->entry(QLatin1String("Contents/Info.plist"))->isFile()) {
69 KArchiveFile const *info = dynamic_cast<KArchiveFile const *>(
70 currentDir->entry(QLatin1String("Contents/Info.plist"))
71 );
72 QByteArray data = info->data();
73 ChatStylePlistFileReader reader(data);
74 if(m_bundleName.isEmpty()) {
75 m_bundleName = reader.CFBundleName();
76 }
77 validResult += 1;
78 }
79 }
80 }
81 }
82
83 if(validResult >= 2) {
84 return BundleValid;
85 } else {
86 qWarning() << "Bundle is not valid";
87 return BundleNotValid;
88 }
89 }
90
bundleName() const91 QString ChatStyleInstaller::bundleName() const
92 {
93 return m_bundleName;
94 }
95
install()96 BundleInstaller::BundleStatus ChatStyleInstaller::install()
97 {
98 BundleInstaller::BundleStatus status = static_cast<BundleInstaller::BundleStatus>(
99 ChatWindowStyleManager::self()->installStyle(m_archive->fileName())
100 );
101 delete m_tmpFile;
102
103 m_status = status;
104
105 Q_EMIT finished(status);
106
107 return status;
108 }
109
showRequest()110 void ChatStyleInstaller::showRequest()
111 {
112 KNotification *notification = new KNotification(QLatin1String("chatstyleRequest"), NULL, KNotification::Persistent);
113 notification->setText( i18n("Install Chatstyle %1", this->bundleName()) );
114 notification->setActions( QStringList() << i18n("Install") << i18n("Cancel") );
115
116 QObject::connect(notification, SIGNAL(action1Activated()), this, SLOT(install()));
117 QObject::connect(notification, SIGNAL(action1Activated()), notification, SLOT(close()));
118
119 QObject::connect(notification, SIGNAL(ignored()), this, SLOT(ignoreRequest()));
120 QObject::connect(notification, SIGNAL(ignored()), notification, SLOT(close()));
121
122 QObject::connect(notification, SIGNAL(action2Activated()), this, SLOT(ignoreRequest()));
123 QObject::connect(notification, SIGNAL(action2Activated()), notification, SLOT(close()));
124
125 notification->setComponentName(ktelepathyComponentName());
126 notification->sendEvent();
127 }
128
showResult()129 void ChatStyleInstaller::showResult()
130 {
131 KNotification *notification;
132 if(m_status == BundleInstaller::BundleInstallOk) {
133 qDebug() << "Installed Chatstyle" << this->bundleName() << "successfully";
134 notification = new KNotification(QLatin1String("chatstyleSuccess"));
135 notification->setText( i18n("Installed Chatstyle %1 successfully.", this->bundleName()) );
136 } else {
137 qWarning() << "Installation of Chatstyle" << this->bundleName() << "failed";
138 notification = new KNotification(QLatin1String("chatstyleFailure"));
139 notification->setText( i18n("Installation of Chatstyle %1 failed.", this->bundleName()) );
140 }
141 notification->setComponentName(ktelepathyComponentName());
142 notification->sendEvent();
143
144 Q_EMIT showedResult();
145 }
146
ignoreRequest()147 void ChatStyleInstaller::ignoreRequest()
148 {
149 Q_EMIT ignoredRequest();
150 }
151