1
#include "opt_iconset.h"
3
#include "iconwidget.h"
6
#include <qbuttongroup.h>
7
#include <qwhatsthis.h>
9
#include <qradiobutton.h>
10
#include <qcombobox.h>
11
#include <qlineedit.h>
12
#include <qfileinfo.h>
13
#include <qlistview.h>
15
#include <qapplication.h>
19
#include <qprogressbar.h>
22
#include <qtabwidget.h>
24
#include "opt_iconset_emo.h"
25
#include "opt_iconset_system.h"
26
#include "opt_iconset_roster.h"
27
#include "ui_isdetails.h"
29
static void isDetails(const Iconset &is, QWidget *parent)
31
IconsetDetailsDlg *isd = new IconsetDetailsDlg(parent, "IconsetDetailsDlg", true);
37
static QStringList dirs;
39
static int countIconsets(QString addDir, QStringList excludeList)
43
QStringList::Iterator it = dirs.begin();
44
for ( ; it != dirs.end(); ++it) {
45
QString fileName = *it + "/iconsets" + addDir;
48
QStringList list = dir.entryList("*");
49
QStringList::Iterator it2 = list.begin();
50
for ( ; it2 != list.end(); ++it2) {
51
if ( *it2 == "." || *it2 == ".." )
55
QStringList::Iterator it3 = excludeList.begin();
56
for ( ; it3 != excludeList.end(); ++it3) {
74
//----------------------------------------------------------------------------
76
//----------------------------------------------------------------------------
78
class IconsetLoadEvent : public QEvent
81
IconsetLoadEvent(IconsetLoadThread *par, Iconset *i)
82
: QEvent(QEvent::User)
88
IconsetLoadThread *thread() const { return p; }
90
// if iconset() is '0' then it means that iconset wans't loaded successfully
91
Iconset *iconset() const { return is; }
98
//----------------------------------------------------------------------------
100
//----------------------------------------------------------------------------
102
class IconsetFinishEvent : public QEvent
106
: QEvent( (QEvent::Type)(QEvent::User + 1) )
112
//----------------------------------------------------------------------------
113
// IconsetLoadThreadDestroyEvent
114
//----------------------------------------------------------------------------
116
class IconsetLoadThreadDestroyEvent : public QEvent
119
IconsetLoadThreadDestroyEvent(QThread *t)
120
: QEvent( (QEvent::Type)(QEvent::User + 2) )
125
~IconsetLoadThreadDestroyEvent()
135
//----------------------------------------------------------------------------
137
//----------------------------------------------------------------------------
139
class IconsetLoadThread : public QThread
142
IconsetLoadThread(QObject *parent, QString addPath);
143
void excludeIconsets(QStringList);
149
void postEvent(QEvent *);
154
QStringList excludeList;
157
IconsetLoadThread::IconsetLoadThread(QObject *p, QString path)
164
void IconsetLoadThread::excludeIconsets(QStringList l)
169
static QMutex threadCancelled, threadMutex;
171
void IconsetLoadThread::postEvent(QEvent *e)
173
threadCancelled.lock();
174
bool cancel = cancelled;
175
threadCancelled.unlock();
182
QApplication::postEvent(parent, e);
185
void IconsetLoadThread::run()
188
QStringList dirs = ::dirs;
189
threadMutex.unlock();
191
QStringList::Iterator it = dirs.begin();
192
for ( ; it != dirs.end(); ++it) {
193
QString fileName = *it + "/iconsets" + addPath;
196
QStringList list = dir.entryList("*");
197
QStringList::Iterator it2 = list.begin();
198
for ( ; it2 != list.end(); ++it2) {
199
if ( *it2 == "." || *it2 == ".." )
202
threadCancelled.lock();
203
bool cancel = cancelled;
204
threadCancelled.unlock();
210
QStringList::Iterator it3 = excludeList.begin();
211
for ( ; it3 != excludeList.end(); ++it3) {
212
if ( *it2 == *it3 ) {
221
IconsetLoadEvent *event = 0;
222
Iconset *is = new Iconset;
224
if ( is->load (fileName + "/" + *it2) ) {
227
// don't forget to delete iconset in ::event()!
228
event = new IconsetLoadEvent(this, is);
232
event = new IconsetLoadEvent(this, 0);
234
// without excluding corrupted iconset,
235
// counter will go nuts! read more comments
238
// TODO: there is possibility,
239
// that there's a bunch of same-named
240
// iconsets, and some of them are corrupted.
241
// It is possible to write a hack that
242
// loads iconset even in that case.
245
// tried to load iconset --> unable to load
246
// checking if there's same-named iconsets in
248
// emit IconsetLoadEvent() only on success
249
// or when last corrupted iconset was unable
258
postEvent(new IconsetFinishEvent());
259
QApplication::postEvent(qApp, new IconsetLoadThreadDestroyEvent(this)); // self destruct
262
//----------------------------------------------------------------------------
263
// OptionsTabIconsetSystem
264
//----------------------------------------------------------------------------
266
OptionsTabIconsetSystem::OptionsTabIconsetSystem(QObject *parent)
267
: OptionsTab(parent, "iconset_system", "", tr("System Iconset"), tr("Select the system iconset"), "psi/info")
272
if ( dirs.isEmpty() ) {
279
OptionsTabIconsetSystem::~OptionsTabIconsetSystem()
284
QWidget *OptionsTabIconsetSystem::widget()
289
w = new IconsetSystemUI;
290
IconsetSystemUI *d = (IconsetSystemUI *)w;
292
connect(d->pb_sysDetails, SIGNAL(clicked()), SLOT(previewIconset()));
294
// TODO: add QWhatsThis
299
void OptionsTabIconsetSystem::applyOptions(Options *opt)
304
IconsetSystemUI *d = (IconsetSystemUI *)w;
305
const Iconset *is = d->iss_system->iconset();
307
QFileInfo fi( is->fileName() );
308
opt->systemIconset = fi.fileName();
312
void OptionsTabIconsetSystem::restoreOptions(const Options *opt)
318
IconsetSystemUI *d = (IconsetSystemUI *)w;
319
d->iss_system->clear();
322
d->setCursor(WaitCursor);
324
QPalette customPal = d->palette();
325
customPal.setDisabled(customPal.inactive());
326
d->iss_system->setEnabled(false);
327
d->iss_system->setPalette(customPal);
329
d->pb_sysDetails->setEnabled(false);
330
d->pb_sysDetails->setPalette(customPal);
333
d->progress->setProgress( 0 );
335
numIconsets = countIconsets("/system", loaded);
340
thread = new IconsetLoadThread(this, "/system");
344
bool OptionsTabIconsetSystem::event(QEvent *e)
346
IconsetSystemUI *d = (IconsetSystemUI *)w;
347
if ( e->type() == QEvent::User ) { // iconset load event
348
IconsetLoadEvent *le = (IconsetLoadEvent *)e;
350
if ( thread != le->thread() )
355
d->progress->setProgress( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
357
Iconset *i = le->iconset();
359
is->stripFirstAnimFrame(i);
360
d->iss_system->insert(*i);
362
QFileInfo fi( i->fileName() );
363
if ( fi.fileName() == o->systemIconset )
364
d->iss_system->setSelected(d->iss_system->count()-1, true);
371
else if ( e->type() == QEvent::User + 1 ) { // finish event
372
d->iss_system->setEnabled(true);
373
d->iss_system->unsetPalette();
375
d->pb_sysDetails->setEnabled(true);
376
d->pb_sysDetails->unsetPalette();
378
connect(d->iss_system, SIGNAL(selectionChanged()), SIGNAL(dataChanged()));
391
void OptionsTabIconsetSystem::previewIconset()
393
IconsetSystemUI *d = (IconsetSystemUI *)w;
394
const Iconset *is = d->iss_system->iconset();
396
isDetails(*is, parentWidget);
399
void OptionsTabIconsetSystem::setData(PsiCon *, QWidget *p)
404
void OptionsTabIconsetSystem::cancelThread()
407
threadCancelled.lock();
408
thread->cancelled = true;
409
threadCancelled.unlock();
415
//----------------------------------------------------------------------------
416
// OptionsTabIconsetEmoticons
417
//----------------------------------------------------------------------------
419
OptionsTabIconsetEmoticons::OptionsTabIconsetEmoticons(QObject *parent)
420
: OptionsTab(parent, "iconset_emoticons", "", tr("Emoticons"), tr("Select your emoticon iconsets"), "psi/smile")
426
OptionsTabIconsetEmoticons::~OptionsTabIconsetEmoticons()
431
QWidget *OptionsTabIconsetEmoticons::widget()
436
w = new IconsetEmoUI;
437
IconsetEmoUI *d = (IconsetEmoUI *)w;
439
connect(d->pb_emoUp, SIGNAL(clicked()), d->iss_emoticons, SLOT(moveItemUp()));
440
connect(d->pb_emoUp, SIGNAL(clicked()), SIGNAL(dataChanged()));
441
connect(d->pb_emoDown, SIGNAL(clicked()), d->iss_emoticons, SLOT(moveItemDown()));
442
connect(d->pb_emoDown, SIGNAL(clicked()), SIGNAL(dataChanged()));
443
connect(d->pb_emoDetails, SIGNAL(clicked()), SLOT(previewIconset()));
445
QWhatsThis::add(d->ck_useEmoticons,
446
tr("<P>Emoticons are short sequences of characters that are used to convey an emotion or idea.</P>"
447
"<P>Enable this option if you want Psi to replace common emoticons with a graphical image.</P>"
448
"<P>For example, <B>:-)</B> would be relaced by <icon name=\"psi/smile\"></P>"));
450
// TODO: add QWhatsThis
455
void OptionsTabIconsetEmoticons::applyOptions(Options *opt)
460
IconsetEmoUI *d = (IconsetEmoUI *)w;
461
opt->useEmoticons = d->ck_useEmoticons->isChecked();
463
opt->emoticons.clear();
464
IconWidgetItem *item = (IconWidgetItem *)d->iss_emoticons->firstItem();
466
if ( item->isSelected() ) {
467
const Iconset *is = item->iconset();
469
QFileInfo fi( is->fileName() );
470
opt->emoticons << fi.fileName();
474
item = (IconWidgetItem *)item->next();
479
void OptionsTabIconsetEmoticons::restoreOptions(const Options *opt)
484
IconsetEmoUI *d = (IconsetEmoUI *)w;
485
d->ck_useEmoticons->setChecked( opt->useEmoticons );
487
// fill in the iconset view
488
d->iss_emoticons->clear();
491
QPtrListIterator<Iconset> it ( is->emoticons );
493
for ( ; (is = it.current()); ++it) {
494
d->iss_emoticons->insert(*is);
495
d->iss_emoticons->setSelected(d->iss_emoticons->count()-1, true);
503
QPtrListIterator<Iconset> it( is->emoticons );
505
for ( ; (tmp = it.current()); ++it) {
506
QFileInfo fi ( tmp->fileName() );
507
loaded << fi.fileName();
511
d->setCursor(WaitCursor);
513
QPalette customPal = d->palette();
514
customPal.setDisabled(customPal.inactive());
515
d->ck_useEmoticons->setEnabled(false);
516
d->ck_useEmoticons->setPalette(customPal);
518
d->groupBox9->setEnabled(false);
519
d->groupBox9->setPalette(customPal);
522
d->progress->setProgress( 0 );
524
numIconsets = countIconsets("/emoticons", loaded);
529
thread = new IconsetLoadThread(this, "/emoticons");
530
thread->excludeIconsets(loaded);
535
bool OptionsTabIconsetEmoticons::event(QEvent *e)
537
IconsetEmoUI *d = (IconsetEmoUI *)w;
538
if ( e->type() == QEvent::User ) { // iconset load event
539
IconsetLoadEvent *le = (IconsetLoadEvent *)e;
541
if ( thread != le->thread() )
546
d->progress->setProgress( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
548
Iconset *is = le->iconset();
550
PsiIconset::removeAnimation(is);
551
d->iss_emoticons->insert(*is);
557
else if ( e->type() == QEvent::User + 1 ) { // finish event
558
d->ck_useEmoticons->setEnabled(true);
559
d->ck_useEmoticons->unsetPalette();
561
d->groupBox9->setEnabled(true);
562
d->groupBox9->unsetPalette();
564
connect(d->iss_emoticons, SIGNAL(selectionChanged()), SIGNAL(dataChanged()));
566
bool checked = d->ck_useEmoticons->isChecked();
567
d->ck_useEmoticons->setChecked( true );
568
d->ck_useEmoticons->setChecked( checked );
581
void OptionsTabIconsetEmoticons::previewIconset()
583
IconsetEmoUI *d = (IconsetEmoUI *)w;
584
const Iconset *is = d->iss_emoticons->iconset();
586
isDetails(*is, parentWidget);
589
void OptionsTabIconsetEmoticons::setData(PsiCon *, QWidget *p)
594
void OptionsTabIconsetEmoticons::cancelThread()
597
threadCancelled.lock();
598
thread->cancelled = true;
599
threadCancelled.unlock();
605
//----------------------------------------------------------------------------
606
// OptionsTabIconsetRoster
607
//----------------------------------------------------------------------------
609
OptionsTabIconsetRoster::OptionsTabIconsetRoster(QObject *parent)
610
: OptionsTab(parent, "iconset_roster", "", tr("Roster Iconsets"), tr("Select iconsets for your roster"), "psi/www")
616
OptionsTabIconsetRoster::~OptionsTabIconsetRoster()
621
QWidget *OptionsTabIconsetRoster::widget()
626
w = new IconsetRosterUI;
627
IconsetRosterUI *d = (IconsetRosterUI *)w;
629
connect(d->pb_defRosterDetails, SIGNAL(clicked()), SLOT(defaultDetails()));
631
connect(d->iss_servicesRoster, SIGNAL(selectionChanged(QListBoxItem *)), SLOT(isServices_iconsetSelected(QListBoxItem *)));
632
connect(d->lv_isServices, SIGNAL(selectionChanged(QListViewItem *)), SLOT(isServices_selectionChanged(QListViewItem *)));
633
connect(d->pb_servicesDetails, SIGNAL(clicked()), SLOT(servicesDetails()));
634
isServices_selectionChanged(0);
636
connect(d->iss_customRoster, SIGNAL(selectionChanged(QListBoxItem *)), SLOT(isCustom_iconsetSelected(QListBoxItem *)));
637
connect(d->lv_customRoster, SIGNAL(selectionChanged(QListViewItem *)), SLOT(isCustom_selectionChanged(QListViewItem *)));
638
connect(d->pb_customRosterDetails, SIGNAL(clicked()), SLOT(customDetails()));
639
connect(d->le_customRoster, SIGNAL(textChanged(const QString &)), SLOT(isCustom_textChanged()));
640
connect(d->pb_customRosterAdd, SIGNAL(clicked()), SLOT(isCustom_add()));
641
connect(d->pb_customRosterDelete, SIGNAL(clicked()), SLOT(isCustom_delete()));
642
isCustom_selectionChanged(0);
644
QWhatsThis::add(d->ck_useTransportIconsForContacts,
645
tr("Toggles use of transport icons to the contacts, that use that transports."));
647
// TODO: add QWhatsThis
652
void OptionsTabIconsetRoster::applyOptions(Options *opt)
657
IconsetRosterUI *d = (IconsetRosterUI *)w;
658
opt->useTransportIconsForContacts = d->ck_useTransportIconsForContacts->isChecked();
662
const Iconset *is = d->iss_defRoster->iconset();
664
QFileInfo fi( is->fileName() );
665
opt->defaultRosterIconset = fi.fileName();
671
opt->serviceRosterIconset.clear();
673
QListViewItemIterator it( d->lv_isServices );
674
for ( ; it.current(); ++it) {
675
QListViewItem *item = it.current();
677
opt->serviceRosterIconset[item->text(2)] = item->text(3);
683
opt->customRosterIconset.clear();
685
QListViewItemIterator it( d->lv_customRoster );
686
for ( ; it.current(); ++it) {
687
QListViewItem *item = it.current();
689
opt->customRosterIconset[item->text(2)] = item->text(3);
694
void OptionsTabIconsetRoster::restoreOptions(const Options *opt)
700
IconsetRosterUI *d = (IconsetRosterUI *)w;
701
d->ck_useTransportIconsForContacts->setChecked( opt->useTransportIconsForContacts );
703
d->iss_defRoster->clear();
704
d->iss_servicesRoster->clear();
705
d->iss_customRoster->clear();
709
d->setCursor(WaitCursor);
711
QPalette customPal = d->palette();
712
customPal.setDisabled(customPal.inactive());
713
d->tabWidget3->setEnabled(false);
714
d->tabWidget3->setPalette(customPal);
717
d->progress->setProgress( 0 );
719
numIconsets = countIconsets("/roster", loaded);
724
thread = new IconsetLoadThread(this, "/roster");
728
bool OptionsTabIconsetRoster::event(QEvent *e)
730
IconsetRosterUI *d = (IconsetRosterUI *)w;
731
if ( e->type() == QEvent::User ) { // iconset load event
732
IconsetLoadEvent *le = (IconsetLoadEvent *)e;
734
if ( thread != le->thread() )
739
d->progress->setProgress( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
741
Iconset *i = le->iconset();
743
is->stripFirstAnimFrame(i);
744
QFileInfo fi( i->fileName() );
747
d->iss_defRoster->insert(*i);
748
if ( fi.fileName() == o->defaultRosterIconset )
749
d->iss_defRoster->setSelected(d->iss_defRoster->count()-1, true);
752
d->iss_servicesRoster->insert(*i);
755
d->iss_customRoster->insert(*i);
762
else if ( e->type() == QEvent::User + 1 ) { // finish event
765
// fill the QListView
766
QListViewItemIterator it( d->lv_isServices );
767
for ( ; it.current(); ++it) {
768
QListViewItem *i = it.current();
769
if ( !i->text(2).isEmpty() ) {
770
Iconset *iss = is->roster[o->serviceRosterIconset[i->text(2)]];
772
i->setText(1, iss->name());
774
QFileInfo fi ( iss->fileName() );
775
i->setText(3, fi.fileName());
780
QHeader *head = d->lv_isServices->header();
781
head->removeLabel(2);
786
// Then, fill the QListView
787
QListViewItem *last = 0;
788
QMap<QString, QString>::ConstIterator it = o->customRosterIconset.begin();
789
for ( ; it != o->customRosterIconset.end(); ++it) {
790
QListViewItem *item = new QListViewItem(d->lv_customRoster, last);
793
item->setText(0, clipCustomText(it.key())); // RegExp
794
item->setText(2, it.key());
796
Iconset *iss = is->roster[it.data()];
798
item->setText(1, iss->name());
800
QFileInfo fi ( iss->fileName() );
801
item->setText(3, fi.fileName());
806
d->tabWidget3->setEnabled(true);
807
d->tabWidget3->unsetPalette();
809
connect(d->iss_defRoster, SIGNAL(selectionChanged()), SIGNAL(dataChanged()));
810
connect(d->iss_servicesRoster, SIGNAL(selectionChanged()), SIGNAL(dataChanged()));
811
connect(d->iss_customRoster, SIGNAL(selectionChanged()), SIGNAL(dataChanged()));
824
void OptionsTabIconsetRoster::setData(PsiCon *, QWidget *p)
829
void OptionsTabIconsetRoster::defaultDetails()
831
IconsetRosterUI *d = (IconsetRosterUI *)w;
832
const Iconset *is = d->iss_defRoster->iconset();
834
isDetails(*is, parentWidget);
837
void OptionsTabIconsetRoster::servicesDetails()
839
IconsetRosterUI *d = (IconsetRosterUI *)w;
840
const Iconset *is = d->iss_servicesRoster->iconset();
842
isDetails(*is, parentWidget);
845
void OptionsTabIconsetRoster::customDetails()
847
IconsetRosterUI *d = (IconsetRosterUI *)w;
848
const Iconset *is = d->iss_customRoster->iconset();
850
isDetails(*is, parentWidget);
853
//------------------------------------------------------------
855
void OptionsTabIconsetRoster::isServices_iconsetSelected(QListBoxItem *item)
860
IconsetRosterUI *d = (IconsetRosterUI *)w;
861
QListViewItem *it = d->lv_isServices->selectedItem();
865
const Iconset *is = ((IconWidgetItem *)item)->iconset();
869
it->setText(1, is->name());
870
QFileInfo fi ( is->fileName() );
871
it->setText(3, fi.fileName());
874
void OptionsTabIconsetRoster::isServices_selectionChanged(QListViewItem *it)
876
IconsetRosterUI *d = (IconsetRosterUI *)w;
877
d->iss_servicesRoster->setEnabled( it != 0 );
878
d->pb_servicesDetails->setEnabled( it != 0 );
879
d->iss_servicesRoster->clearSelection();
883
if ( it->text(3).isEmpty() )
886
QString name = it->text(3);
889
IconWidgetItem *item = (IconWidgetItem *)d->iss_servicesRoster->firstItem();
890
for ( ; item; item = (IconWidgetItem *)item->next()) {
891
const Iconset *is = item->iconset();
893
QFileInfo fi ( is->fileName() );
894
if ( fi.fileName() == name ) {
896
d->iss_servicesRoster->setSelected(item, true);
897
d->iss_servicesRoster->ensureCurrentVisible();
903
qApp->processEvents();
907
//------------------------------------------------------------
909
void OptionsTabIconsetRoster::isCustom_iconsetSelected(QListBoxItem *item)
914
IconsetRosterUI *d = (IconsetRosterUI *)w;
915
QListViewItem *it = d->lv_customRoster->selectedItem();
919
const Iconset *is = ((IconWidgetItem *)item)->iconset();
923
it->setText(1, is->name());
924
QFileInfo fi ( is->fileName() );
925
it->setText(3, fi.fileName());
928
void OptionsTabIconsetRoster::isCustom_selectionChanged(QListViewItem *it)
930
IconsetRosterUI *d = (IconsetRosterUI *)w;
931
d->iss_customRoster->setEnabled( it != 0 );
932
d->pb_customRosterDetails->setEnabled( it != 0 );
933
//d->pb_customRosterAdd->setEnabled( it != 0 );
934
d->pb_customRosterDelete->setEnabled( it != 0 );
935
d->le_customRoster->setEnabled( it != 0 );
936
d->iss_customRoster->clearSelection();
940
if ( it->text(3).isEmpty() )
944
d->le_customRoster->setText(it->text(2));
945
QString name = it->text(3);
947
IconWidgetItem *item = (IconWidgetItem *)d->iss_customRoster->firstItem();
948
for ( ; item; item = (IconWidgetItem *)item->next()) {
949
const Iconset *is = item->iconset();
951
QFileInfo fi ( is->fileName() );
952
if ( fi.fileName() == name ) {
953
d->iss_customRoster->setSelected(item, true);
954
d->iss_customRoster->ensureCurrentVisible();
959
qApp->processEvents();
963
void OptionsTabIconsetRoster::isCustom_textChanged()
965
IconsetRosterUI *d = (IconsetRosterUI *)w;
966
QListViewItem *item = d->lv_customRoster->selectedItem();
970
item->setText( 0, clipCustomText(d->le_customRoster->text()) );
971
item->setText( 2, d->le_customRoster->text() );
974
void OptionsTabIconsetRoster::isCustom_add()
976
IconsetRosterUI *d = (IconsetRosterUI *)w;
979
const Iconset *iconset = d->iss_defRoster->iconset();
981
QFileInfo fi( iconset->fileName() );
985
qWarning("OptionsTabIconsetRoster::isCustom_add(): 'def' is null!");
987
QListViewItem *item = new QListViewItem(d->lv_customRoster, d->lv_customRoster->lastItem());
988
const Iconset *i = is->roster[def];
990
item->setText(1, i->name());
992
QFileInfo fi(i->fileName());
993
item->setText(3, fi.fileName());
996
d->lv_customRoster->setSelected(item, true);
999
d->le_customRoster->setFocus();
1002
void OptionsTabIconsetRoster::isCustom_delete()
1004
IconsetRosterUI *d = (IconsetRosterUI *)w;
1005
QListViewItem *item = d->lv_customRoster->selectedItem();
1010
isCustom_selectionChanged(0);
1014
QString OptionsTabIconsetRoster::clipCustomText(QString s)
1016
if ( s.length() > 10 ) {
1024
void OptionsTabIconsetRoster::cancelThread()
1027
threadCancelled.lock();
1028
thread->cancelled = true;
1029
threadCancelled.unlock();