1 /***************************************************************************
2 * Copyright (C) 2007 by Carlo Segato <brandon.ml@gmail.com> *
3 * Copyright (C) 2008 Montel Laurent <montel@kde.org> *
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. *
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. *
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"
26 #include <QListWidgetItem>
27 #include <KMessageBox>
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
)
46 EditDialog::EditDialog(QWidget
*parent
, const QString
&name
, QListWidgetItem
*itm
, const QString
&file
)
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);
69 hb
->addWidget(btnIcon
);
70 hb
->addWidget(leText
);
74 connect(btnIcon
, SIGNAL(clicked()), this, SLOT(btnIconClicked()));
75 connect(leText
, SIGNAL(textChanged(const QString
&)), this, SLOT(updateOkButton()));
80 void EditDialog::btnIconClicked()
82 KUrl url
= KFileDialog::getImageOpenUrl();
84 if (!url
.isLocalFile())
87 emoticon
= url
.path();
89 if (emoticon
.isEmpty())
92 btnIcon
->setIcon(QPixmap(emoticon
));
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");
109 // setButtons(Apply | Help);
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()
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);
162 cbStrict
->setChecked(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
) {
179 if (themeList
->currentItem()) {
180 kEmoticons
.setTheme(themeList
->currentItem()->text());
183 if (cbStrict
->isChecked()) {
184 kEmoticons
.setParseMode((kEmoticons
.parseMode() |= KEmoticonsTheme::StrictParse
) &= ~KEmoticonsTheme::RelaxedParse
);
186 kEmoticons
.setParseMode((kEmoticons
.parseMode() |= KEmoticonsTheme::RelaxedParse
) &= ~KEmoticonsTheme::StrictParse
);
190 void EmoticonList::somethingChanged()
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);
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();
213 if (!themeList
->currentItem()) {
218 if (!themeList
->currentItem()) {
219 themeList
->currentItem()->setSelected(true);
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
) {
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
);
241 void EmoticonList::btRemoveThemeClicked()
243 if (!themeList
->currentItem()) {
247 QString name
= themeList
->currentItem()->text();
249 delFiles
.append(KGlobal::dirs()->findResource("emoticons", name
+ QDir::separator()));
250 delete themeList
->currentItem();
255 void EmoticonList::installEmoticonTheme()
257 KUrl themeURL
= KUrlRequesterDialog::getUrl(QString(), this, i18n("Drag or Type Emoticon Theme URL"));
258 if (themeURL
.isEmpty())
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"));
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()) {
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
);
287 themeList
->currentItem()->setIcon(QIcon(previewEmoticon(theme
)));
292 void EmoticonList::addEmoticon()
294 if (!themeList
->currentItem())
297 EditDialog
*dlg
= new EditDialog(this, i18n("Add Emoticon"));
299 if (dlg
->exec() == QDialog::Rejected
) {
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
)));
313 void EmoticonList::editEmoticon()
315 if (!themeList
->currentItem() || !emoList
->currentItem())
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
) {
328 QString emo
= dlg
->getEmoticon();
329 if (path
!= dlg
->getEmoticon()) {
334 KStandardDirs
*dir
= KGlobal::dirs();
335 emo
= dir
->findResource("emoticons", themeList
->currentItem()->text() + QDir::separator() + f
);
338 emo
= dir
->findResource("emoticons", themeList
->currentItem()->text() + QDir::separator() + f
+ ".mng");
340 emo
= dir
->findResource("emoticons", themeList
->currentItem()->text() + QDir::separator() + f
+ ".png");
342 emo
= dir
->findResource("emoticons", themeList
->currentItem()->text() + QDir::separator() + f
+ ".gif");
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
);
361 void EmoticonList::newTheme()
363 QString name
= KInputDialog::getText(i18n("New Emoticon Theme"), i18n("Enter the name of the new emoticon theme:"));
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
));
371 QString
constraint("(exist Library)");
372 KService::List srv
= KServiceTypeTrader::self()->query("KEmoticons", constraint
);
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()) {
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
));
399 void EmoticonList::loadTheme(const QString
&name
)
404 if (emoMap
.contains(name
)) {
406 QList
<QListWidgetItem
*>ls
= themeList
->findItems(name
, Qt::MatchExactly
);
412 KEmoticonsTheme emo
= kEmoticons
.theme(name
);
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);
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);
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()
468 // kate: space-indent on; indent-width 4; replace-tabs on;