add more spacing
[personal-kdebase.git] / runtime / kcontrol / emoticons / emoticonslist.cpp
blob9bf4ded51367d2e721995a7be4405f4685fe5069
1 /***************************************************************************
2 * Copyright (C) 2007 by Carlo Segato <brandon.ml@gmail.com> *
3 * Copyright (C) 2008 Montel Laurent <montel@kde.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, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
21 #include "emoticonslist.h"
22 #include <QString>
23 #include <QDir>
24 #include <QIcon>
25 #include <QLabel>
26 #include <QListWidgetItem>
27 #include <KMessageBox>
28 #include <KIcon>
29 #include <KAboutData>
30 #include <KStandardDirs>
31 #include <KFileDialog>
32 #include <KInputDialog>
33 #include <KUrlRequesterDialog>
34 #include <kdecore_export.h>
35 #include <kio/netaccess.h>
36 #include <kgenericfactory.h>
37 #include <knewstuff2/engine.h>
39 EditDialog::EditDialog(QWidget *parent, const QString &name)
40 : KDialog(parent)
42 setCaption(name);
43 setupDlg();
46 EditDialog::EditDialog(QWidget *parent, const QString &name, QListWidgetItem *itm, const QString &file)
47 : KDialog(parent)
49 setCaption(name);
50 emoticon = file;
51 setupDlg();
52 leText->setText(itm->text());
53 btnIcon->setIcon(itm->icon());
56 void EditDialog::setupDlg()
58 wdg = new QWidget(this);
59 QVBoxLayout *vl = new QVBoxLayout;
60 QHBoxLayout *hb = new QHBoxLayout;
61 leText = new KLineEdit(this);
62 btnIcon = new QPushButton(this);
63 btnIcon->setFixedSize(QSize(64, 64));
64 btnIcon->setIconSize(QSize(64, 64));
66 QLabel *lab = new QLabel(wdg);
67 lab->setWordWrap(true);
68 vl->addWidget(lab);
69 hb->addWidget(btnIcon);
70 hb->addWidget(leText);
71 vl->addLayout(hb);
72 wdg->setLayout(vl);
73 setMainWidget(wdg);
74 connect(btnIcon, SIGNAL(clicked()), this, SLOT(btnIconClicked()));
75 connect(leText, SIGNAL(textChanged(const QString &)), this, SLOT(updateOkButton()));
76 updateOkButton();
77 leText->setFocus();
80 void EditDialog::btnIconClicked()
82 KUrl url = KFileDialog::getImageOpenUrl();
84 if (!url.isLocalFile())
85 return;
87 emoticon = url.path();
89 if (emoticon.isEmpty())
90 return;
92 btnIcon->setIcon(QPixmap(emoticon));
93 updateOkButton();
96 void EditDialog::updateOkButton()
98 enableButtonOk(!leText->text().isEmpty() && !emoticon.isEmpty());
101 K_PLUGIN_FACTORY(EmoticonsFactory, registerPlugin<EmoticonList>();)
102 K_EXPORT_PLUGIN(EmoticonsFactory("emoticons", "kcm_emoticons"))
104 EmoticonList::EmoticonList(QWidget *parent, const QVariantList &args)
105 : KCModule(EmoticonsFactory::componentData(), parent, args)
107 KAboutData *about = new KAboutData("kcm_emoticons", 0, ki18n("Emoticons"), "1.0");
108 setAboutData(about);
109 // setButtons(Apply | Help);
110 setupUi(this);
111 btAdd->setIcon(KIcon("list-add"));
112 btEdit->setIcon(KIcon("edit-rename"));
113 btRemoveEmoticon->setIcon(KIcon("edit-delete"));
114 btNew->setIcon(KIcon("document-new"));
115 btGetNew->setIcon(KIcon("get-hot-new-stuff"));
116 btInstall->setIcon(KIcon("document-import"));
117 btRemoveTheme->setIcon(KIcon("edit-delete"));
119 connect(themeList, SIGNAL(itemSelectionChanged()), this, SLOT(selectTheme()));
120 connect(themeList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButton()));
121 connect(btRemoveTheme, SIGNAL(clicked()), this, SLOT(btRemoveThemeClicked()));
122 connect(btInstall, SIGNAL(clicked()), this, SLOT(installEmoticonTheme()));
123 connect(btNew, SIGNAL(clicked()), this, SLOT(newTheme()));
124 connect(btGetNew, SIGNAL(clicked()), this, SLOT(getNewStuff()));
125 connect(cbStrict, SIGNAL(clicked()), this, SLOT(somethingChanged()));
127 connect(btAdd, SIGNAL(clicked()), this, SLOT(addEmoticon()));
128 connect(btEdit, SIGNAL(clicked()), this, SLOT(editEmoticon()));
129 connect(btRemoveEmoticon, SIGNAL(clicked()), this, SLOT(btRemoveEmoticonClicked()));
130 connect(emoList, SIGNAL(itemSelectionChanged()), this, SLOT(updateButton()));
131 connect(emoList, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(editEmoticon()));
134 EmoticonList::~EmoticonList()
138 bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
140 return (QString::localeAwareCompare(s1, s2) < 0);
143 void EmoticonList::load()
145 KStandardDirs dir;
147 delFiles.clear();
148 themeList->clear();
149 emoMap.clear();
150 emoList->clear();
152 QStringList themeList = kEmoticons.themeList();
153 qSort(themeList.begin(), themeList.end(), caseInsensitiveLessThan);
155 for (int i = 0; i < themeList.count(); i++) {
156 loadTheme(themeList.at(i));
159 if (kEmoticons.parseMode() & KEmoticonsTheme::StrictParse) {
160 cbStrict->setChecked(true);
161 } else {
162 cbStrict->setChecked(false);
165 updateButton();
166 emit changed(false);
169 void EmoticonList::save()
171 for (int i = 0; i < delFiles.size(); i++) {
172 KIO::NetAccess::del(delFiles.at(i), this);
175 foreach (KEmoticonsTheme t, emoMap) {
176 t.save();
179 if (themeList->currentItem()) {
180 kEmoticons.setTheme(themeList->currentItem()->text());
183 if (cbStrict->isChecked()) {
184 kEmoticons.setParseMode((kEmoticons.parseMode() |= KEmoticonsTheme::StrictParse) &= ~KEmoticonsTheme::RelaxedParse);
185 } else {
186 kEmoticons.setParseMode((kEmoticons.parseMode() |= KEmoticonsTheme::RelaxedParse) &= ~KEmoticonsTheme::StrictParse);
190 void EmoticonList::somethingChanged()
192 emit changed(true);
195 void EmoticonList::updateButton()
197 btRemoveEmoticon->setEnabled(themeList->currentItem() && emoList->selectedItems().size());
198 if (themeList->currentItem() && themeList->currentItem()->text() != "kde4" && themeList->count() > 1) {
199 btRemoveTheme->setEnabled(true);
200 } else {
201 btRemoveTheme->setEnabled(false);
203 btEdit->setEnabled(themeList->currentItem() && emoList->selectedItems().size());
204 btAdd->setEnabled(themeList->currentItem());
207 void EmoticonList::selectTheme()
210 kDebug() << "current_item: " << themeList->currentItem();
212 updateButton();
213 if (!themeList->currentItem()) {
214 emoList->clear();
215 return;
218 if (!themeList->currentItem()) {
219 themeList->currentItem()->setSelected(true);
220 return;
222 emoList->clear();
224 KEmoticonsTheme em = emoMap.value(themeList->currentItem()->text());
225 QHash<QString, QStringList>::const_iterator it = em.emoticonsMap().constBegin();
227 for (; it != em.emoticonsMap().constEnd(); ++it) {
228 QString text;
229 if (it.value().size()) {
230 text = it.value().at(0);
231 for (int i = 1; i < it.value().size(); i++) {
232 text += ' ' + it.value().at(i);
236 new QListWidgetItem(QIcon(it.key()), text, emoList);
238 emit changed();
241 void EmoticonList::btRemoveThemeClicked()
243 if (!themeList->currentItem()) {
244 return;
247 QString name = themeList->currentItem()->text();
249 delFiles.append(KGlobal::dirs()->findResource("emoticons", name + QDir::separator()));
250 delete themeList->currentItem();
251 emoMap.remove(name);
252 emit changed();
255 void EmoticonList::installEmoticonTheme()
257 KUrl themeURL = KUrlRequesterDialog::getUrl(QString(), this, i18n("Drag or Type Emoticon Theme URL"));
258 if (themeURL.isEmpty())
259 return;
261 if (!themeURL.isLocalFile()) {
262 KMessageBox::queuedMessageBox(this, KMessageBox::Error, i18n("Emoticon themes must be installed from local files."),
263 i18n("Could Not Install Emoticon Theme"));
264 return;
266 QStringList installed = kEmoticons.installTheme(themeURL.path());
267 for (int i = 0; i < installed.size(); i++)
268 loadTheme(installed.at(i));
271 void EmoticonList::btRemoveEmoticonClicked()
273 if (!emoList->currentItem()) {
274 return;
277 QListWidgetItem *itm = emoList->currentItem();
278 KEmoticonsTheme theme = emoMap.value(themeList->currentItem()->text());
279 QString fPath = theme.emoticonsMap().key(itm->text().split(" "));
280 if (theme.removeEmoticon(itm->text())) {
281 int ret = KMessageBox::questionYesNo(this, i18n("Do you want to remove %1 too?", fPath), i18n("Delete emoticon"));
282 if (ret == KMessageBox::Yes) {
283 delFiles.append(fPath);
286 delete itm;
287 themeList->currentItem()->setIcon(QIcon(previewEmoticon(theme)));
288 emit changed();
292 void EmoticonList::addEmoticon()
294 if (!themeList->currentItem())
295 return;
297 EditDialog *dlg = new EditDialog(this, i18n("Add Emoticon"));
299 if (dlg->exec() == QDialog::Rejected) {
300 delete dlg;
301 return;
304 KEmoticonsTheme theme = emoMap.value(themeList->currentItem()->text());
305 if (theme.addEmoticon(dlg->getEmoticon(), dlg->getText(), KEmoticonsProvider::Copy)) {
306 new QListWidgetItem(QPixmap(dlg->getEmoticon()), dlg->getText(), emoList);
307 themeList->currentItem()->setIcon(QIcon(previewEmoticon(theme)));
308 emit changed();
310 delete dlg;
313 void EmoticonList::editEmoticon()
315 if (!themeList->currentItem() || !emoList->currentItem())
316 return;
318 KEmoticonsTheme theme = emoMap.value(themeList->currentItem()->text());
319 QString path = theme.emoticonsMap().key(emoList->currentItem()->text().split(' '));
320 QString f = QFileInfo(path).baseName();
321 EditDialog *dlg = new EditDialog(this, i18n("Edit Emoticon"), emoList->currentItem(), path);
323 if (dlg->exec() == QDialog::Rejected) {
324 delete dlg;
325 return;
327 bool copy;
328 QString emo = dlg->getEmoticon();
329 if (path != dlg->getEmoticon()) {
330 copy = true;
331 } else {
332 copy = false;
334 KStandardDirs *dir = KGlobal::dirs();
335 emo = dir->findResource("emoticons", themeList->currentItem()->text() + QDir::separator() + f);
337 if (emo.isNull())
338 emo = dir->findResource("emoticons", themeList->currentItem()->text() + QDir::separator() + f + ".mng");
339 if (emo.isNull())
340 emo = dir->findResource("emoticons", themeList->currentItem()->text() + QDir::separator() + f + ".png");
341 if (emo.isNull())
342 emo = dir->findResource("emoticons", themeList->currentItem()->text() + QDir::separator() + f + ".gif");
343 if (emo.isNull()) {
344 delete dlg;
345 return;
349 if (theme.removeEmoticon(emoList->currentItem()->text())) {
350 delete emoList->currentItem();
353 if (theme.addEmoticon(emo, dlg->getText(), copy ? KEmoticonsProvider::Copy : KEmoticonsProvider::DoNotCopy)) {
354 new QListWidgetItem(QPixmap(emo), dlg->getText(), emoList);
357 emit changed();
358 delete dlg;
361 void EmoticonList::newTheme()
363 QString name = KInputDialog::getText(i18n("New Emoticon Theme"), i18n("Enter the name of the new emoticon theme:"));
364 if (name.isEmpty())
365 return;
366 QString path = KGlobal::dirs()->saveLocation("emoticons", name, false);
368 if (KIO::NetAccess::exists(path, KIO::NetAccess::SourceSide, this)) {
369 KMessageBox::error(this, i18n("%1 theme already exists", name));
370 } else {
371 QString constraint("(exist Library)");
372 KService::List srv = KServiceTypeTrader::self()->query("KEmoticons", constraint);
374 QStringList ls;
375 int current = 0;
377 for (int i = 0; i < srv.size(); ++i) {
378 ls << srv.at(i)->name();
380 if (srv.at(i)->property("X-KDE-Priority").toInt() > srv.at(current)->property("X-KDE-Priority").toInt()) {
381 current = i;
385 bool ok;
386 QString type = KInputDialog::getItem(i18n("New Emoticon Theme"), i18n("Choose the type of emoticon theme to create"), ls, current, false, &ok, this);
388 if (ok && !type.isEmpty()) {
389 KIO::NetAccess::mkdir(KUrl(path), this);
391 int index = ls.indexOf(type);
392 kEmoticons.newTheme(name, srv.at(index));
394 loadTheme(name);
399 void EmoticonList::loadTheme(const QString &name)
401 if (name.isEmpty())
402 return;
404 if (emoMap.contains(name)) {
405 emoMap.remove(name);
406 QList<QListWidgetItem *>ls = themeList->findItems(name, Qt::MatchExactly);
407 if (ls.size()) {
408 delete ls.at(0);
412 KEmoticonsTheme emo = kEmoticons.theme(name);
413 if (!emo.isNull()) {
414 emoMap[name] = emo;
415 QIcon previewIcon = QIcon(previewEmoticon(emo));
416 QListWidgetItem *itm = new QListWidgetItem(previewIcon, name, themeList);
418 if (name == kEmoticons.currentThemeName()) {
419 themeList->setCurrentItem(itm);
424 void EmoticonList::getNewStuff()
426 KNS::Engine engine(this);
427 if (engine.init("emoticons.knsrc")) {
428 KNS::Entry::List entries = engine.downloadDialogModal(this);
430 for (int i = 0; i < entries.size(); i ++) {
431 if (entries.at(i)->status() == KNS::Entry::Installed) {
432 QString name = entries.at(i)->installedFiles().at(0).section('/', -2, -2);
433 loadTheme(name);
439 QString EmoticonList::previewEmoticon(const KEmoticonsTheme &theme)
441 QString path = theme.tokenize(":)")[0].picPath;
442 if (path.isEmpty()) {
443 path = theme.emoticonsMap().keys().value(0);
445 return path;
451 void EmoticonList::initDefaults()
454 QList<QListWidgetItem *>ls = themeList->findItems("kde4", Qt::MatchExactly);
455 themeList->setCurrentItem( ls.first() );
457 cbStrict->setChecked(false);
461 void EmoticonList::defaults()
463 initDefaults();
464 selectTheme();
465 emit changed(true);
468 // kate: space-indent on; indent-width 4; replace-tabs on;