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