1 #include "opt_iconset.h"
2 #include "common.h"
3 #include "iconwidget.h"
4 #include "applicationinfo.h"
5 #include "psiiconset.h"
6 #include "psicon.h"
7 #include "psioptions.h"
8 
9 #include <QDir>
10 #include <QCheckBox>
11 #include <QRadioButton>
12 #include <QComboBox>
13 #include <QLineEdit>
14 #include <QFileInfo>
15 #include <QApplication>
16 #include <QThread>
17 #include <QMutex>
18 #include <QEvent>
19 #include <QCursor>
20 #include <QPalette>
21 #include <QTabWidget>
22 #include <QFont>
23 #include <QTreeWidget>
24 
25 #include "ui_opt_iconset_emo.h"
26 #include "ui_opt_iconset_mood.h"
27 #include "ui_opt_iconset_activity.h"
28 #include "ui_opt_iconset_client.h"
29 #include "ui_opt_iconset_system.h"
30 #include "ui_opt_iconset_roster.h"
31 #include "ui_opt_iconset_affiliation.h"
32 #include "ui_ui_isdetails.h"
33 
34 class IconsetEmoUI : public QWidget, public Ui::IconsetEmo
35 {
36 public:
IconsetEmoUI()37 	IconsetEmoUI() : QWidget() { setupUi(this); }
38 };
39 
40 class IconsetMoodUI : public QWidget, public Ui::IconsetMood
41 {
42 public:
IconsetMoodUI()43 	IconsetMoodUI() : QWidget() { setupUi(this); }
44 };
45 
46 class IconsetClientUI : public QWidget, public Ui::IconsetClient
47 {
48 public:
IconsetClientUI()49 	IconsetClientUI() : QWidget() { setupUi(this); }
50 };
51 
52 class IconsetActivityUI : public QWidget, public Ui::IconsetActivity
53 {
54 public:
IconsetActivityUI()55 	IconsetActivityUI() : QWidget() { setupUi(this); }
56 };
57 
58 class IconsetSystemUI : public QWidget, public Ui::IconsetSystem
59 {
60 public:
IconsetSystemUI()61 	IconsetSystemUI() : QWidget() { setupUi(this); }
62 };
63 
64 class IconsetAffiliationUI : public QWidget, public Ui::IconsetAffiliation
65 {
66   public:
IconsetAffiliationUI()67     IconsetAffiliationUI() : QWidget() { setupUi(this); }
68 };
69 
70 class IconsetRosterUI : public QWidget, public Ui::IconsetRoster
71 {
72 public:
IconsetRosterUI()73 	IconsetRosterUI() : QWidget() { setupUi(this); }
74 };
75 
76 class IconsetDetailsDlg : public QDialog, public Ui::IconsetDetailsDlg
77 {
78 public:
IconsetDetailsDlg(PsiCon * psicon,QWidget * parent,const char * name,bool modal)79 	IconsetDetailsDlg(PsiCon *psicon, QWidget* parent, const char* name, bool modal)
80 		: QDialog(parent)
81 		, psi(psicon)
82 	{
83 		setAttribute(Qt::WA_DeleteOnClose);
84 		setupUi(this);
85 
86 		psi->dialogRegister(this);
87 
88 		QStringList bold_labels;
89 		bold_labels << "lb_name2";
90 		bold_labels << "lb_version2";
91 		bold_labels << "lb_date2";
92 		bold_labels << "lb_home2";
93 		bold_labels << "lb_desc2";
94 		bold_labels << "lb_authors";
95 
96 		QList<QLabel *> labels = findChildren<QLabel *>();
97 		foreach (QLabel *l, labels) {
98 			if (bold_labels.contains(l->objectName())) {
99 				QFont font = l->font();
100 				font.setBold(true);
101 				l->setFont(font);
102 			}
103 		}
104 
105 		setObjectName(name);
106 		setModal(modal);
107 	}
108 
~IconsetDetailsDlg()109 	~IconsetDetailsDlg()
110 	{
111 		psi->dialogUnregister(this);
112 	}
113 
setIconset(const Iconset & is)114 	void setIconset( const Iconset &is ) {
115 		setWindowTitle(windowTitle().arg(is.name()));
116 
117 		lb_name->setText(is.name());
118 		lb_version->setText(is.version());
119 
120 		if ( is.description().isEmpty() ) {
121 			lb_desc->hide();
122 			lb_desc2->hide();
123 		}
124 		else
125 			lb_desc->setText(is.description());
126 
127 		if ( !is.homeUrl().isEmpty() ) {
128 			lb_home->setTitle(is.homeUrl());
129 			lb_home->setUrl(is.homeUrl());
130 		}
131 		else {
132 			lb_home->hide();
133 			lb_home2->hide();
134 		}
135 
136 		if ( is.creation().isEmpty() ) {
137 			lb_date->hide();
138 			lb_date2->hide();
139 		}
140 		else {
141 			QDate date = QDate::fromString(is.creation(), Qt::ISODate);
142 			lb_date->setText(date.toString(Qt::LocalDate));
143 		}
144 
145 		if ( is.authors().count() == 0 ) {
146 			ptv_authors->hide();
147 			lb_authors->hide();
148 		}
149 		else {
150 			QString authors;
151 			QStringList::ConstIterator it = is.authors().begin();
152 			for ( ; it != is.authors().end(); ++it) {
153 				if ( !authors.isEmpty() )
154 					authors += "<br><br>";
155 				authors += *it;
156 			}
157 			ptv_authors->setText( "<qt><nobr>" + authors + "</nobr></qt>" );
158 		}
159 
160 		isd_iconset->setIconset(is);
161 
162 		resize(sizeHint());
163 	}
164 
165 private:
166 	PsiCon *psi;
167 };
168 
isDetails(const Iconset & is,QWidget * parent,PsiCon * psi)169 static void isDetails(const Iconset &is, QWidget *parent, PsiCon *psi)
170 {
171 	IconsetDetailsDlg *isd = new IconsetDetailsDlg(psi, parent, "IconsetDetailsDlg", false);
172 	isd->setIconset(is);
173 	isd->show();
174 }
175 
countIconsets(QString addDir,QStringList excludeList)176 static int countIconsets(QString addDir, QStringList excludeList)
177 {
178 	int count = 0;
179 
180 	foreach (const QString &dataDir,  ApplicationInfo::dataDirs()) {
181 		QDir dir (dataDir + "/iconsets" + addDir);
182 
183 		foreach (const QFileInfo &fi,
184 				 dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries))
185 		{
186 			QString iconsetId = fi.absoluteFilePath().section('/', -2);
187 			if ( excludeList.contains(iconsetId) || !Iconset::isSourceAllowed(fi))
188 				continue;
189 
190 			count++;
191 			excludeList << iconsetId;
192 		}
193 	}
194 
195 	return count;
196 }
197 
198 //----------------------------------------------------------------------------
199 // IconsetLoadEvent
200 //----------------------------------------------------------------------------
201 
202 class IconsetLoadEvent : public QEvent
203 {
204 public:
IconsetLoadEvent(IconsetLoadThread * par,Iconset * i)205 	IconsetLoadEvent(IconsetLoadThread *par, Iconset *i)
206 		: QEvent(QEvent::User)
207 		, p(par)
208 		, is(i)
209 	{
210 	}
211 
thread() const212 	IconsetLoadThread *thread() const { return p; }
213 
214 	// if iconset() is '0' then it means that iconset wasn't loaded successfully
iconset() const215 	Iconset *iconset() const { return is; }
216 
217 private:
218 	IconsetLoadThread *p;
219 	Iconset *is;
220 };
221 
222 //----------------------------------------------------------------------------
223 // IconsetFinishEvent
224 //----------------------------------------------------------------------------
225 
226 class IconsetFinishEvent : public QEvent
227 {
228 public:
IconsetFinishEvent()229 	IconsetFinishEvent()
230 		: QEvent( (QEvent::Type)(QEvent::User + 1) )
231 	{
232 	}
233 };
234 
235 
236 //----------------------------------------------------------------------------
237 // IconsetLoadThreadDestroyEvent
238 //----------------------------------------------------------------------------
239 
240 class IconsetLoadThreadDestroyEvent : public QEvent
241 {
242 public:
IconsetLoadThreadDestroyEvent(QThread * t)243 	IconsetLoadThreadDestroyEvent(QThread *t)
244 		: QEvent( (QEvent::Type)(QEvent::User + 2) )
245 		, thread(t)
246 	{
247 	}
248 
~IconsetLoadThreadDestroyEvent()249 	~IconsetLoadThreadDestroyEvent()
250 	{
251 		thread->wait();
252 		delete thread;
253 	}
254 
255 private:
256 	QThread *thread;
257 };
258 
259 //----------------------------------------------------------------------------
260 // IconsetLoadThread
261 //----------------------------------------------------------------------------
262 
263 class IconsetLoadThread : public QThread
264 {
265 public:
266 	IconsetLoadThread(QObject *parent, QString addPath);
267 	void excludeIconsets(QStringList);
268 
269 	bool cancelled;
270 
271 protected:
272 	void run();
273 	void postEvent(QEvent *);
274 
275 private:
276 	QObject *parent;
277 	QString addPath;
278 	QStringList excludeList;
279 };
280 
IconsetLoadThread(QObject * p,QString path)281 IconsetLoadThread::IconsetLoadThread(QObject *p, QString path)
282 	: cancelled(false)
283 	, parent(p)
284 	, addPath(path)
285 {
286 }
287 
excludeIconsets(QStringList l)288 void IconsetLoadThread::excludeIconsets(QStringList l)
289 {
290 	excludeList += l;
291 }
292 
293 static QMutex threadCancelled, threadMutex;
294 
postEvent(QEvent * e)295 void IconsetLoadThread::postEvent(QEvent *e)
296 {
297 	threadCancelled.lock();
298 	bool cancel = cancelled;
299 	threadCancelled.unlock();
300 
301 	if ( cancel ) {
302 		delete e;
303 		return;
304 	}
305 
306 	QApplication::postEvent(parent, e);
307 }
308 
run()309 void IconsetLoadThread::run()
310 {
311 	threadMutex.lock();
312 	QStringList dirs = ApplicationInfo::dataDirs();
313 	threadMutex.unlock();
314 
315 	QStringList failedList;
316 	foreach (const QString &dataDir, dirs) {
317 		QDir dir(dataDir + "/iconsets" + addPath);
318 		foreach (const QFileInfo &iconsetFI,
319 				 dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries))
320 		{
321 			if (!Iconset::isSourceAllowed(iconsetFI))
322 				continue;
323 
324 			threadCancelled.lock();
325 			bool cancel = cancelled;
326 			threadCancelled.unlock();
327 
328 			if ( cancel )
329 				goto getout;
330 
331 			QString iconsetId = iconsetFI.absoluteFilePath().section('/', -2);
332 			if (excludeList.contains(iconsetId))
333 				continue;
334 
335 			Iconset *is = new Iconset;
336 
337 			if ( is->load (iconsetFI.absoluteFilePath()) ) {
338 				failedList.removeOne(is->id());
339 				excludeList << is->id();
340 
341 				// don't forget to delete iconset in ::event()!
342 				postEvent(new IconsetLoadEvent(this, is));
343 			}
344 			else {
345 				delete is;
346 				failedList << iconsetId;
347 			}
348 		}
349 	}
350 
351 	for(int i = 0; i < failedList.size(); i++) {
352 		postEvent(new IconsetLoadEvent(this, 0));
353 	}
354 
355 getout:
356 	postEvent(new IconsetFinishEvent());
357 	QApplication::postEvent(qApp, new IconsetLoadThreadDestroyEvent(this)); // self destruct
358 }
359 
360 //----------------------------------------------------------------------------
361 // OptionsTabIconsetSystem
362 //----------------------------------------------------------------------------
363 
OptionsTabIconsetSystem(QObject * parent)364 OptionsTabIconsetSystem::OptionsTabIconsetSystem(QObject *parent)
365 	: OptionsTab(parent, "iconset_system", "", tr("System Icons"), tr("Select the system iconset"))
366 	, w(0)
367 	, thread(0)
368 {
369 }
370 
~OptionsTabIconsetSystem()371 OptionsTabIconsetSystem::~OptionsTabIconsetSystem()
372 {
373 	cancelThread();
374 }
375 
widget()376 QWidget *OptionsTabIconsetSystem::widget()
377 {
378 	if ( w )
379 		return 0;
380 
381 	w = new IconsetSystemUI;
382 	IconsetSystemUI *d = (IconsetSystemUI *)w;
383 
384 	connect(d->pb_sysDetails, SIGNAL(clicked()), SLOT(previewIconset()));
385 
386 	// TODO: add QWhatsThis
387 
388 	return w;
389 }
390 
applyOptions()391 void OptionsTabIconsetSystem::applyOptions()
392 {
393 	if ( !w || thread )
394 		return;
395 
396 	IconsetSystemUI *d = (IconsetSystemUI *)w;
397 	const Iconset *is = d->iss_system->iconset();
398 	if ( is ) {
399 		QFileInfo fi( is->fileName() );
400 		PsiOptions::instance()->setOption("options.iconsets.system", fi.fileName());
401 	}
402 }
403 
restoreOptions()404 void OptionsTabIconsetSystem::restoreOptions()
405 {
406 	if ( !w || thread )
407 		return;
408 
409 	IconsetSystemUI *d = (IconsetSystemUI *)w;
410 	d->iss_system->clear();
411 	QStringList loaded;
412 
413 	d->setCursor(Qt::WaitCursor);
414 
415 	d->iss_system->setEnabled(false);
416 	d->pb_sysDetails->setEnabled(false);
417 
418 	d->progress->show();
419 	d->progress->setValue( 0 );
420 
421 	numIconsets = countIconsets("/system", loaded);
422 	iconsetsLoaded = 0;
423 
424 	cancelThread();
425 
426 	thread = new IconsetLoadThread(this, "/system");
427 	thread->start();
428 }
429 
event(QEvent * e)430 bool OptionsTabIconsetSystem::event(QEvent *e)
431 {
432 	IconsetSystemUI *d = (IconsetSystemUI *)w;
433 	if ( e->type() == QEvent::User ) { // iconset load event
434 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
435 
436 		if ( thread != le->thread() )
437 			return false;
438 
439 		if ( !numIconsets )
440 			numIconsets = 1;
441 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
442 
443 		Iconset *i = le->iconset();
444 		if ( i ) {
445 			PsiIconset::instance()->stripFirstAnimFrame(i);
446 			d->iss_system->insert(*i);
447 
448 			QFileInfo fi( i->fileName() );
449 			if ( fi.fileName() == PsiOptions::instance()->getOption("options.iconsets.system").toString() )
450 				d->iss_system->setItemSelected(d->iss_system->lastItem(), true);
451 
452 			delete i;
453 		}
454 
455 		return true;
456 	}
457 	else if ( e->type() == QEvent::User + 1 ) { // finish event
458 		d->iss_system->setEnabled(true);
459 		d->pb_sysDetails->setEnabled(true);
460 
461 		connect(d->iss_system, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
462 
463 		d->progress->hide();
464 
465 		d->unsetCursor();
466 		thread = 0;
467 
468 		return true;
469 	}
470 
471 	return false;
472 }
473 
previewIconset()474 void OptionsTabIconsetSystem::previewIconset()
475 {
476 	IconsetSystemUI *d = (IconsetSystemUI *)w;
477 	const Iconset *is = d->iss_system->iconset();
478 	if (is) {
479 		isDetails(*is, parentWidget->parentWidget(), psi);
480 	}
481 }
482 
setData(PsiCon * psicon,QWidget * p)483 void OptionsTabIconsetSystem::setData(PsiCon *psicon, QWidget *p)
484 {
485 	psi = psicon;
486 	parentWidget = p;
487 }
488 
cancelThread()489 void OptionsTabIconsetSystem::cancelThread()
490 {
491 	if ( thread ) {
492 		threadCancelled.lock();
493 		thread->cancelled = true;
494 		threadCancelled.unlock();
495 
496 		thread = 0;
497 	}
498 }
499 
500 //----------------------------------------------------------------------------
501 // OptionsTabIconsetEmoticons
502 //----------------------------------------------------------------------------
503 
OptionsTabIconsetEmoticons(QObject * parent)504 OptionsTabIconsetEmoticons::OptionsTabIconsetEmoticons(QObject *parent)
505 	: OptionsTab(parent, "iconset_emoticons", "", tr("Emoticons"), tr("Select your emoticon iconsets"))
506 	, w(0)
507 	, thread(0)
508 {
509 }
510 
~OptionsTabIconsetEmoticons()511 OptionsTabIconsetEmoticons::~OptionsTabIconsetEmoticons()
512 {
513 	cancelThread();
514 }
515 
widget()516 QWidget *OptionsTabIconsetEmoticons::widget()
517 {
518 	if ( w )
519 		return 0;
520 
521 	w = new IconsetEmoUI;
522 	IconsetEmoUI *d = (IconsetEmoUI *)w;
523 
524 	connect(d->pb_emoUp, SIGNAL(clicked()), d->iss_emoticons, SLOT(moveItemUp()));
525 	connect(d->pb_emoUp, SIGNAL(clicked()), SIGNAL(dataChanged()));
526 	connect(d->pb_emoDown, SIGNAL(clicked()), d->iss_emoticons, SLOT(moveItemDown()));
527 	connect(d->pb_emoDown, SIGNAL(clicked()), SIGNAL(dataChanged()));
528 	connect(d->pb_emoDetails, SIGNAL(clicked()), SLOT(previewIconset()));
529 
530 	d->ck_useEmoticons->setWhatsThis(
531 		tr("<P>Emoticons are short sequences of characters that are used to convey an emotion or idea.</P>"
532 		"<P>Enable this option if you want Psi to replace common emoticons with a graphical image.</P>"
533 		"<P>For example, <B>:-)</B> would be replaced by <icon name=\"psi/smile\"></P>"));
534 
535 	// TODO: add QWhatsThis
536 
537 	return w;
538 }
539 
applyOptions()540 void OptionsTabIconsetEmoticons::applyOptions()
541 {
542 	if ( !w || thread )
543 		return;
544 
545 	IconsetEmoUI *d = (IconsetEmoUI *)w;
546 	PsiOptions::instance()->setOption("options.ui.emoticons.use-emoticons", d->ck_useEmoticons->isChecked());
547 
548 	QStringList list;
549 	for (int row = 0; row < d->iss_emoticons->count(); row++) {
550 		IconWidgetItem *item = (IconWidgetItem *)d->iss_emoticons->item(row);
551 
552 		if ( d->iss_emoticons->isItemSelected(item) ) {
553 			const Iconset *is = item->iconset();
554 			if ( is ) {
555 				QFileInfo fi( is->fileName() );
556 				list << fi.fileName();
557 			}
558 		}
559 	}
560 	PsiOptions::instance()->setOption("options.iconsets.emoticons", list);
561 }
562 
restoreOptions()563 void OptionsTabIconsetEmoticons::restoreOptions()
564 {
565 	if ( !w || thread )
566 		return;
567 
568 	IconsetEmoUI *d = (IconsetEmoUI *)w;
569 	d->ck_useEmoticons->setChecked( PsiOptions::instance()->getOption("options.ui.emoticons.use-emoticons").toBool() );
570 
571 	// fill in the iconset view
572 	d->iss_emoticons->clear();
573 
574 	{
575 		foreach(Iconset* is, PsiIconset::instance()->emoticons) {
576 			d->iss_emoticons->insert(*is);
577 			d->iss_emoticons->setItemSelected(d->iss_emoticons->lastItem(), true);
578 		}
579 	}
580 
581 
582 	{
583 		QStringList loaded;
584 		{
585 			foreach(Iconset* tmp, PsiIconset::instance()->emoticons) {
586 				loaded << tmp->id();
587 			}
588 		}
589 
590 		d->setCursor(Qt::WaitCursor);
591 
592 		d->ck_useEmoticons->setEnabled(false);
593 		d->groupBox9->setEnabled(false);
594 
595 		d->progress->show();
596 		d->progress->setValue( 0 );
597 
598 		numIconsets = countIconsets("/emoticons", loaded);
599 		iconsetsLoaded = 0;
600 
601 		cancelThread();
602 
603 		thread = new IconsetLoadThread(this, "/emoticons");
604 		thread->excludeIconsets(loaded);
605 		thread->start();
606 	}
607 }
608 
event(QEvent * e)609 bool OptionsTabIconsetEmoticons::event(QEvent *e)
610 {
611 	IconsetEmoUI *d = (IconsetEmoUI *)w;
612 	if ( e->type() == QEvent::User ) { // iconset load event
613 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
614 
615 		if ( thread != le->thread() )
616 			return false;
617 
618 		if ( !numIconsets )
619 			numIconsets = 1;
620 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
621 
622 		Iconset *is = le->iconset();
623 		if ( is ) {
624 			PsiIconset::removeAnimation(is);
625 			d->iss_emoticons->insert(*is);
626 			delete is;
627 		}
628 
629 		return true;
630 	}
631 	else if ( e->type() == QEvent::User + 1 ) { // finish event
632 		d->ck_useEmoticons->setEnabled(true);
633 		d->groupBox9->setEnabled(true);
634 
635 		connect(d->iss_emoticons, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
636 
637 		bool checked = d->ck_useEmoticons->isChecked();
638 		d->ck_useEmoticons->setChecked( true );
639 		d->ck_useEmoticons->setChecked( checked );
640 
641 		d->progress->hide();
642 
643 		d->unsetCursor();
644 		thread = 0;
645 
646 		return true;
647 	}
648 
649 	return false;
650 }
651 
previewIconset()652 void OptionsTabIconsetEmoticons::previewIconset()
653 {
654 	IconsetEmoUI *d = (IconsetEmoUI *)w;
655 	const Iconset *is = d->iss_emoticons->iconset();
656 	if (is) {
657 		isDetails(*is, parentWidget->parentWidget(), psi);
658 	}
659 }
660 
setData(PsiCon * psicon,QWidget * p)661 void OptionsTabIconsetEmoticons::setData(PsiCon *psicon, QWidget *p)
662 {
663 	psi = psicon;
664 	parentWidget = p;
665 }
666 
cancelThread()667 void OptionsTabIconsetEmoticons::cancelThread()
668 {
669 	if ( thread ) {
670 		threadCancelled.lock();
671 		thread->cancelled = true;
672 		threadCancelled.unlock();
673 
674 		thread = 0;
675 	}
676 }
677 
678 
679 //----------------------------------------------------------------------------
680 // OptionsTabIconsetMoods
681 //----------------------------------------------------------------------------
682 
OptionsTabIconsetMoods(QObject * parent)683 OptionsTabIconsetMoods::OptionsTabIconsetMoods(QObject *parent)
684 	: OptionsTab(parent, "iconset_moods", "", tr("Moods"), tr("Select your mood iconset"))
685 	, w(0)
686 	, thread(0)
687 {
688 }
689 
~OptionsTabIconsetMoods()690 OptionsTabIconsetMoods::~OptionsTabIconsetMoods()
691 {
692 	cancelThread();
693 }
694 
widget()695 QWidget *OptionsTabIconsetMoods::widget()
696 {
697 	if ( w )
698 		return 0;
699 
700 	w = new IconsetMoodUI;
701 	IconsetMoodUI *d = (IconsetMoodUI *)w;
702 
703 	connect(d->pb_moodDetails, SIGNAL(clicked()), SLOT(previewIconset()));
704 
705 	return w;
706 }
707 
applyOptions()708 void OptionsTabIconsetMoods::applyOptions()
709 {
710 	if ( !w || thread )
711 		return;
712 
713 	IconsetMoodUI *d = (IconsetMoodUI *)w;
714 
715 	const Iconset *is = d->iss_moods->iconset();
716 	if ( is ) {
717 		QFileInfo fi( is->fileName() );
718 		PsiOptions::instance()->setOption("options.iconsets.moods", fi.fileName());
719 	}
720 }
721 
restoreOptions()722 void OptionsTabIconsetMoods::restoreOptions()
723 {
724 	if ( !w || thread )
725 		return;
726 
727 	IconsetMoodUI *d = (IconsetMoodUI *)w;
728 
729 	d->iss_moods->clear();
730 	QStringList loaded;
731 
732 	d->setCursor(Qt::WaitCursor);
733 
734 	QPalette customPal = d->palette();
735 	customPal.setCurrentColorGroup(QPalette::Inactive);
736 	d->iss_moods->setEnabled(false);
737 	d->iss_moods->setPalette(customPal);
738 
739 	d->pb_moodDetails->setEnabled(false);
740 	d->pb_moodDetails->setPalette(customPal);
741 
742 	d->progress->show();
743 	d->progress->setValue( 0 );
744 
745 	numIconsets = countIconsets("/moods", loaded);
746 	iconsetsLoaded = 0;
747 
748 	cancelThread();
749 
750 	thread = new IconsetLoadThread(this, "/moods");
751 	thread->start();
752 }
753 
event(QEvent * e)754 bool OptionsTabIconsetMoods::event(QEvent *e)
755 {
756 	IconsetMoodUI *d = (IconsetMoodUI *)w;
757 	if ( e->type() == QEvent::User ) { // iconset load event
758 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
759 
760 		if ( thread != le->thread() )
761 			return false;
762 
763 		if ( !numIconsets )
764 			numIconsets = 1;
765 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
766 
767 		Iconset *i = le->iconset();
768 		if ( i ) {
769 			PsiIconset::instance()->stripFirstAnimFrame(i);
770 			d->iss_moods->insert(*i);
771 
772 			QFileInfo fi( i->fileName() );
773 			if ( fi.fileName() == PsiOptions::instance()->getOption("options.iconsets.moods").toString() )
774 				d->iss_moods->setItemSelected(d->iss_moods->lastItem(), true);
775 
776 			delete i;
777 		}
778 
779 		return true;
780 	}
781 	else if ( e->type() == QEvent::User + 1 ) { // finish event
782 		d->iss_moods->setEnabled(true);
783 		d->iss_moods->setPalette(QPalette());
784 
785 		d->pb_moodDetails->setEnabled(true);
786 		d->pb_moodDetails->setPalette(QPalette());
787 
788 		connect(d->iss_moods, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
789 
790 		d->progress->hide();
791 
792 		d->unsetCursor();
793 		thread = 0;
794 
795 		return true;
796 	}
797 
798 	return false;
799 }
800 
previewIconset()801 void OptionsTabIconsetMoods::previewIconset()
802 {
803 	IconsetMoodUI *d = (IconsetMoodUI *)w;
804 	const Iconset *is = d->iss_moods->iconset();
805 	if (is) {
806 		isDetails(*is, parentWidget->parentWidget(), psi);
807 	}
808 }
809 
setData(PsiCon * psicon,QWidget * p)810 void OptionsTabIconsetMoods::setData(PsiCon *psicon, QWidget *p)
811 {
812 	psi = psicon;
813 	parentWidget = p;
814 }
815 
cancelThread()816 void OptionsTabIconsetMoods::cancelThread()
817 {
818 	if ( thread ) {
819 		threadCancelled.lock();
820 		thread->cancelled = true;
821 		threadCancelled.unlock();
822 
823 		thread = 0;
824 	}
825 }
826 //----------------------------------------------------------------------------
827 // OptionsTabIconsetActivity
828 //----------------------------------------------------------------------------
829 
OptionsTabIconsetActivity(QObject * parent)830 OptionsTabIconsetActivity::OptionsTabIconsetActivity(QObject *parent)
831 	: OptionsTab(parent, "iconset_activities", "", tr("Activity"), tr("Select your activity iconset"))
832 	, w(0)
833 	, thread(0)
834 {
835 }
836 
~OptionsTabIconsetActivity()837 OptionsTabIconsetActivity::~OptionsTabIconsetActivity()
838 {
839 	cancelThread();
840 }
841 
widget()842 QWidget *OptionsTabIconsetActivity::widget()
843 {
844 	if ( w )
845 		return 0;
846 
847 	w = new IconsetActivityUI;
848 	IconsetActivityUI *d = (IconsetActivityUI *)w;
849 
850 	connect(d->pb_activityDetails, SIGNAL(clicked()), SLOT(previewIconset()));
851 
852 	return w;
853 }
854 
applyOptions()855 void OptionsTabIconsetActivity::applyOptions()
856 {
857 	if ( !w || thread )
858 		return;
859 
860 	IconsetActivityUI *d = (IconsetActivityUI *)w;
861 
862 	const Iconset *is = d->iss_activity->iconset();
863 	if ( is ) {
864 		QFileInfo fi( is->fileName() );
865 		PsiOptions::instance()->setOption("options.iconsets.activities", fi.fileName());
866 	}
867 }
868 
restoreOptions()869 void OptionsTabIconsetActivity::restoreOptions()
870 {
871 	if ( !w || thread )
872 		return;
873 
874 	IconsetActivityUI *d = (IconsetActivityUI *)w;
875 
876 	d->iss_activity->clear();
877 	QStringList loaded;
878 
879 	d->setCursor(Qt::WaitCursor);
880 
881 	QPalette customPal = d->palette();
882 	customPal.setCurrentColorGroup(QPalette::Inactive);
883 	d->iss_activity->setEnabled(false);
884 	d->iss_activity->setPalette(customPal);
885 
886 	d->pb_activityDetails->setEnabled(false);
887 	d->pb_activityDetails->setPalette(customPal);
888 
889 	d->progress->show();
890 	d->progress->setValue( 0 );
891 
892 	numIconsets = countIconsets("/activities", loaded);
893 	iconsetsLoaded = 0;
894 
895 	cancelThread();
896 
897 	thread = new IconsetLoadThread(this, "/activities");
898 	thread->start();
899 }
900 
event(QEvent * e)901 bool OptionsTabIconsetActivity::event(QEvent *e)
902 {
903 	IconsetActivityUI *d = (IconsetActivityUI *)w;
904 	if ( e->type() == QEvent::User ) { // iconset load event
905 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
906 
907 		if ( thread != le->thread() )
908 			return false;
909 
910 		if ( !numIconsets )
911 			numIconsets = 1;
912 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
913 
914 		Iconset *i = le->iconset();
915 		if ( i ) {
916 			PsiIconset::instance()->stripFirstAnimFrame(i);
917 			d->iss_activity->insert(*i);
918 
919 			QFileInfo fi( i->fileName() );
920 			if ( fi.fileName() == PsiOptions::instance()->getOption("options.iconsets.activities").toString() )
921 				d->iss_activity->setItemSelected(d->iss_activity->lastItem(), true);
922 
923 			delete i;
924 		}
925 
926 		return true;
927 	}
928 	else if ( e->type() == QEvent::User + 1 ) { // finish event
929 		d->iss_activity->setEnabled(true);
930 		d->iss_activity->setPalette(QPalette());
931 
932 		d->pb_activityDetails->setEnabled(true);
933 		d->pb_activityDetails->setPalette(QPalette());
934 
935 		connect(d->iss_activity, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
936 
937 		d->progress->hide();
938 
939 		d->unsetCursor();
940 		thread = 0;
941 
942 		return true;
943 	}
944 
945 	return false;
946 }
947 
previewIconset()948 void OptionsTabIconsetActivity::previewIconset()
949 {
950 	IconsetActivityUI *d = (IconsetActivityUI *)w;
951 	const Iconset *is = d->iss_activity->iconset();
952 	if (is) {
953 		isDetails(*is, parentWidget->parentWidget(), psi);
954 	}
955 }
956 
setData(PsiCon * psicon,QWidget * p)957 void OptionsTabIconsetActivity::setData(PsiCon *psicon, QWidget *p)
958 {
959 	psi = psicon;
960 	parentWidget = p;
961 }
962 
cancelThread()963 void OptionsTabIconsetActivity::cancelThread()
964 {
965 	if ( thread ) {
966 		threadCancelled.lock();
967 		thread->cancelled = true;
968 		threadCancelled.unlock();
969 
970 		thread = 0;
971 	}
972 }
973 //----------------------------------------------------------------------------
974 // OptionsTabIconsetAffiliations
975 //----------------------------------------------------------------------------
976 
OptionsTabIconsetAffiliations(QObject * parent)977 OptionsTabIconsetAffiliations::OptionsTabIconsetAffiliations(QObject *parent)
978 	: OptionsTab(parent, "iconset_affiliations", "", tr("Affiliations"), tr("Select your affiliations iconset"))
979 	, w(0)
980 	, thread(0)
981 {
982 }
983 
~OptionsTabIconsetAffiliations()984 OptionsTabIconsetAffiliations::~OptionsTabIconsetAffiliations()
985 {
986 	cancelThread();
987 }
988 
widget()989 QWidget *OptionsTabIconsetAffiliations::widget()
990 {
991 	if ( w )
992 		return 0;
993 
994 	w = new IconsetAffiliationUI;
995 	IconsetAffiliationUI *d = (IconsetAffiliationUI *)w;
996 
997 	connect(d->pb_affiliationDetails, SIGNAL(clicked()), SLOT(previewIconset()));
998 
999 	return w;
1000 }
1001 
applyOptions()1002 void OptionsTabIconsetAffiliations::applyOptions()
1003 {
1004 	if ( !w || thread )
1005 		return;
1006 
1007 	IconsetAffiliationUI *d = (IconsetAffiliationUI *)w;
1008 
1009 	const Iconset *is = d->iss_affiliation->iconset();
1010 	if ( is ) {
1011 		QFileInfo fi( is->fileName() );
1012 		PsiOptions::instance()->setOption("options.iconsets.affiliations", fi.fileName());
1013 	}
1014 }
1015 
restoreOptions()1016 void OptionsTabIconsetAffiliations::restoreOptions()
1017 {
1018 	if ( !w || thread )
1019 		return;
1020 
1021 	IconsetAffiliationUI *d = (IconsetAffiliationUI *)w;
1022 
1023 	d->iss_affiliation->clear();
1024 	QStringList loaded;
1025 
1026 	d->setCursor(Qt::WaitCursor);
1027 
1028 	QPalette customPal = d->palette();
1029 	customPal.setCurrentColorGroup(QPalette::Inactive);
1030 	d->iss_affiliation->setEnabled(false);
1031 	d->iss_affiliation->setPalette(customPal);
1032 
1033 	d->pb_affiliationDetails->setEnabled(false);
1034 	d->pb_affiliationDetails->setPalette(customPal);
1035 
1036 	d->progress->show();
1037 	d->progress->setValue( 0 );
1038 
1039 	numIconsets = countIconsets("/affiliations", loaded);
1040 	iconsetsLoaded = 0;
1041 
1042 	cancelThread();
1043 
1044 	thread = new IconsetLoadThread(this, "/affiliations");
1045 	thread->start();
1046 }
1047 
event(QEvent * e)1048 bool OptionsTabIconsetAffiliations::event(QEvent *e)
1049 {
1050 	IconsetAffiliationUI *d = (IconsetAffiliationUI *)w;
1051 	if ( e->type() == QEvent::User ) { // iconset load event
1052 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
1053 
1054 		if ( thread != le->thread() )
1055 			return false;
1056 
1057 		if ( !numIconsets )
1058 			numIconsets = 1;
1059 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
1060 
1061 		Iconset *i = le->iconset();
1062 		if ( i ) {
1063 			PsiIconset::instance()->stripFirstAnimFrame(i);
1064 			d->iss_affiliation->insert(*i);
1065 
1066 			QFileInfo fi( i->fileName() );
1067 			if ( fi.fileName() == PsiOptions::instance()->getOption("options.iconsets.affiliations").toString() )
1068 				d->iss_affiliation->setItemSelected(d->iss_affiliation->lastItem(), true);
1069 
1070 			delete i;
1071 		}
1072 
1073 		return true;
1074 	}
1075 	else if ( e->type() == QEvent::User + 1 ) { // finish event
1076 		d->iss_affiliation->setEnabled(true);
1077 		d->iss_affiliation->setPalette(QPalette());
1078 
1079 		d->pb_affiliationDetails->setEnabled(true);
1080 		d->pb_affiliationDetails->setPalette(QPalette());
1081 
1082 		connect(d->iss_affiliation, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
1083 
1084 		d->progress->hide();
1085 
1086 		d->unsetCursor();
1087 		thread = 0;
1088 
1089 		return true;
1090 	}
1091 
1092 	return false;
1093 }
1094 
previewIconset()1095 void OptionsTabIconsetAffiliations::previewIconset()
1096 {
1097 	IconsetAffiliationUI *d = (IconsetAffiliationUI *)w;
1098 	const Iconset *is = d->iss_affiliation->iconset();
1099 	if (is) {
1100 		isDetails(*is, parentWidget->parentWidget(), psi);
1101 	}
1102 }
1103 
setData(PsiCon * psicon,QWidget * p)1104 void OptionsTabIconsetAffiliations::setData(PsiCon *psicon, QWidget *p)
1105 {
1106 	psi = psicon;
1107 	parentWidget = p;
1108 }
1109 
cancelThread()1110 void OptionsTabIconsetAffiliations::cancelThread()
1111 {
1112 	if ( thread ) {
1113 		threadCancelled.lock();
1114 		thread->cancelled = true;
1115 		threadCancelled.unlock();
1116 
1117 		thread = 0;
1118 	}
1119 }
1120 
1121 //----------------------------------------------------------------------------
1122 // OptionsTabIconsetClients
1123 //----------------------------------------------------------------------------
1124 
OptionsTabIconsetClients(QObject * parent)1125 OptionsTabIconsetClients::OptionsTabIconsetClients(QObject *parent)
1126 	: OptionsTab(parent, "iconset_clients", "", tr("Clients"), tr("Select your clients iconset"))
1127 	, w(0)
1128 	, thread(0)
1129 {
1130 }
1131 
~OptionsTabIconsetClients()1132 OptionsTabIconsetClients::~OptionsTabIconsetClients()
1133 {
1134 	cancelThread();
1135 }
1136 
widget()1137 QWidget *OptionsTabIconsetClients::widget()
1138 {
1139 	if ( w )
1140 		return 0;
1141 
1142 	w = new IconsetClientUI;
1143 	IconsetClientUI *d = (IconsetClientUI *)w;
1144 
1145 	connect(d->pb_clientDetails, SIGNAL(clicked()), SLOT(previewIconset()));
1146 
1147 	return w;
1148 }
1149 
applyOptions()1150 void OptionsTabIconsetClients::applyOptions()
1151 {
1152 	if ( !w || thread )
1153 		return;
1154 
1155 	IconsetClientUI *d = (IconsetClientUI *)w;
1156 
1157 	const Iconset *is = d->iss_clients->iconset();
1158 	if ( is ) {
1159 		QFileInfo fi( is->fileName() );
1160 		PsiOptions::instance()->setOption("options.iconsets.clients", fi.fileName());
1161 	}
1162 }
1163 
restoreOptions()1164 void OptionsTabIconsetClients::restoreOptions()
1165 {
1166 	if ( !w || thread )
1167 		return;
1168 
1169 	IconsetClientUI *d = (IconsetClientUI *)w;
1170 
1171 	d->iss_clients->clear();
1172 	QStringList loaded;
1173 
1174 	d->setCursor(Qt::WaitCursor);
1175 
1176 	QPalette customPal = d->palette();
1177 	customPal.setCurrentColorGroup(QPalette::Inactive);
1178 	d->iss_clients->setEnabled(false);
1179 	d->iss_clients->setPalette(customPal);
1180 
1181 	d->pb_clientDetails->setEnabled(false);
1182 	d->pb_clientDetails->setPalette(customPal);
1183 
1184 	d->progress->show();
1185 	d->progress->setValue( 0 );
1186 
1187 	numIconsets = countIconsets("/clients", loaded);
1188 	iconsetsLoaded = 0;
1189 
1190 	cancelThread();
1191 
1192 	thread = new IconsetLoadThread(this, "/clients");
1193 	thread->start();
1194 }
1195 
event(QEvent * e)1196 bool OptionsTabIconsetClients::event(QEvent *e)
1197 {
1198 	IconsetClientUI *d = (IconsetClientUI *)w;
1199 	if ( e->type() == QEvent::User ) { // iconset load event
1200 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
1201 
1202 		if ( thread != le->thread() )
1203 			return false;
1204 
1205 		if ( !numIconsets )
1206 			numIconsets = 1;
1207 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
1208 
1209 		Iconset *i = le->iconset();
1210 		if ( i ) {
1211 			PsiIconset::instance()->stripFirstAnimFrame(i);
1212 			d->iss_clients->insert(*i);
1213 
1214 			QFileInfo fi( i->fileName() );
1215 			if ( fi.fileName() == PsiOptions::instance()->getOption("options.iconsets.clients").toString() )
1216 				d->iss_clients->setItemSelected(d->iss_clients->lastItem(), true);
1217 
1218 			delete i;
1219 		}
1220 
1221 		return true;
1222 	}
1223 	else if ( e->type() == QEvent::User + 1 ) { // finish event
1224 		d->iss_clients->setEnabled(true);
1225 		d->iss_clients->setPalette(QPalette());
1226 
1227 		d->pb_clientDetails->setEnabled(true);
1228 		d->pb_clientDetails->setPalette(QPalette());
1229 
1230 		connect(d->iss_clients, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
1231 
1232 		d->progress->hide();
1233 
1234 		d->unsetCursor();
1235 		thread = 0;
1236 
1237 		return true;
1238 	}
1239 
1240 	return false;
1241 }
1242 
previewIconset()1243 void OptionsTabIconsetClients::previewIconset()
1244 {
1245 	IconsetClientUI *d = (IconsetClientUI *)w;
1246 	const Iconset *is = d->iss_clients->iconset();
1247 	if (is) {
1248 		isDetails(*is, parentWidget->parentWidget(), psi);
1249 	}
1250 }
1251 
setData(PsiCon * psicon,QWidget * p)1252 void OptionsTabIconsetClients::setData(PsiCon *psicon, QWidget *p)
1253 {
1254 	psi = psicon;
1255 	parentWidget = p;
1256 }
1257 
cancelThread()1258 void OptionsTabIconsetClients::cancelThread()
1259 {
1260 	if ( thread ) {
1261 		threadCancelled.lock();
1262 		thread->cancelled = true;
1263 		threadCancelled.unlock();
1264 
1265 		thread = 0;
1266 	}
1267 }
1268 
1269 //----------------------------------------------------------------------------
1270 // OptionsTabIconsetRoster
1271 //----------------------------------------------------------------------------
1272 
OptionsTabIconsetRoster(QObject * parent)1273 OptionsTabIconsetRoster::OptionsTabIconsetRoster(QObject *parent)
1274 	: OptionsTab(parent, "iconset_roster", "", tr("Roster Icons"), tr("Select iconsets for your roster"))
1275 	, w(0)
1276 	, thread(0)
1277 {
1278 }
1279 
~OptionsTabIconsetRoster()1280 OptionsTabIconsetRoster::~OptionsTabIconsetRoster()
1281 {
1282 	cancelThread();
1283 }
1284 
addService(const QString & id,const QString & name)1285 void OptionsTabIconsetRoster::addService(const QString& id, const QString& name)
1286 {
1287 	IconsetRosterUI*d = (IconsetRosterUI*)w;
1288 	QTreeWidgetItem* item = new QTreeWidgetItem(d->tw_isServices, QStringList(QString(name)));
1289 	item->setData(0, ServiceRole, QVariant(QString(id)));
1290 	d->tw_isServices->addTopLevelItem(item);
1291 }
1292 
widget()1293 QWidget *OptionsTabIconsetRoster::widget()
1294 {
1295 	if ( w )
1296 		return 0;
1297 
1298 	w = new IconsetRosterUI;
1299 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1300 
1301 	// Initialize transport iconsets
1302 	addService("aim", "AIM");
1303 	addService("muc", "Chat (MUC)");
1304 	addService("gadugadu", "Gadu-Gadu");
1305 	addService("icq", "ICQ");
1306 	addService("irc", "IRC");
1307 	addService("disk", "Jabber Disk");
1308 	addService("mrim", "Mail.Ru-IM");
1309 	addService("msn", "MSN");
1310 	addService("rss", "RSS");
1311 	addService("sms", "SMS");
1312 	addService("smtp", "SMTP");
1313 	addService("transport", tr("Transport"));
1314 	addService("vkontakte", tr("vk.com"));
1315 	addService("weather", tr("Weather"));
1316 	addService("xmpp", "XMPP");
1317 	addService("yahoo", "Yahoo!");
1318 
1319 	d->tw_isServices->resizeColumnToContents(0);
1320 
1321 	connect(d->pb_defRosterDetails, SIGNAL(clicked()), SLOT(defaultDetails()));
1322 
1323 	connect(d->iss_servicesRoster, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), SLOT(isServices_iconsetSelected(QListWidgetItem *, QListWidgetItem *)));
1324 	connect(d->tw_isServices, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), SLOT(isServices_selectionChanged(QTreeWidgetItem *)));
1325 	connect(d->pb_servicesDetails, SIGNAL(clicked()), SLOT(servicesDetails()));
1326 	isServices_selectionChanged(0);
1327 
1328 	connect(d->iss_customRoster, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), SLOT(isCustom_iconsetSelected(QListWidgetItem *, QListWidgetItem *)));
1329 	connect(d->tw_customRoster, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), SLOT(isCustom_selectionChanged(QTreeWidgetItem *)));
1330 	connect(d->tw_customRoster, SIGNAL(itemClicked(QTreeWidgetItem *, int )), SLOT(isCustom_selectionChanged(QTreeWidgetItem *)));
1331 
1332 	connect(d->pb_customRosterDetails, SIGNAL(clicked()), SLOT(customDetails()));
1333 	connect(d->le_customRoster, SIGNAL(textChanged(const QString &)), SLOT(isCustom_textChanged()));
1334 	connect(d->pb_customRosterAdd, SIGNAL(clicked()), SLOT(isCustom_add()));
1335 	connect(d->pb_customRosterDelete, SIGNAL(clicked()), SLOT(isCustom_delete()));
1336 	isCustom_selectionChanged(0);
1337 
1338 	d->ck_useTransportIconsForContacts->setWhatsThis(
1339 		tr("Toggles use of transport icons to the contacts, that use that transports."));
1340 
1341 	// TODO: add QWhatsThis
1342 
1343 	return w;
1344 }
1345 
applyOptions()1346 void OptionsTabIconsetRoster::applyOptions()
1347 {
1348 	if (!w || thread)
1349 		return;
1350 
1351 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1352 	PsiOptions::instance()->setOption("options.ui.contactlist.use-transport-icons", d->ck_useTransportIconsForContacts->isChecked());
1353 
1354 	// roster - default
1355 	{
1356 		const Iconset *is = d->iss_defRoster->iconset();
1357 		if (is) {
1358 			QFileInfo fi(is->fileName());
1359 			PsiOptions::instance()->setOption("options.iconsets.status", fi.fileName());
1360 		}
1361 	}
1362 
1363 	// roster - services
1364 	{
1365 		QString baseServicesPath = "options.iconsets.service-status";
1366 		PsiOptions::instance()->removeOption(baseServicesPath, true);
1367 
1368 		QTreeWidgetItemIterator it(d->tw_isServices);
1369 		while (*it) {
1370 			QString path = PsiOptions::instance()->mapPut(baseServicesPath, (*it)->data(0, ServiceRole).toString());
1371 			PsiOptions::instance()->setOption(path + ".iconset", (*it)->data(0, IconsetRole).toString());
1372 			++it;
1373 		}
1374 	}
1375 
1376 	// roster - custom
1377 	{
1378 		QString baseCustomStatusPath = "options.iconsets.custom-status";
1379 		PsiOptions::instance()->removeOption(baseCustomStatusPath, true);
1380 
1381 		int index = 0;
1382 		QTreeWidgetItemIterator it(d->tw_customRoster);
1383 		while (*it) {
1384 			QString path = baseCustomStatusPath + ".a" + QString::number(index++);
1385 			PsiOptions::instance()->setOption(path + ".regexp", (*it)->data(0, RegexpRole).toString());
1386 			PsiOptions::instance()->setOption(path + ".iconset", (*it)->data(0, IconsetRole).toString());
1387 			++it;
1388 		}
1389 	}
1390 }
1391 
restoreOptions()1392 void OptionsTabIconsetRoster::restoreOptions()
1393 {
1394 	if ( !w || thread )
1395 		return;
1396 
1397 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1398 	d->ck_useTransportIconsForContacts->setChecked( PsiOptions::instance()->getOption("options.ui.contactlist.use-transport-icons").toBool() );
1399 
1400 	d->iss_defRoster->clear();
1401 	d->iss_servicesRoster->clear();
1402 	d->iss_customRoster->clear();
1403 
1404 	QStringList loaded;
1405 
1406 	d->setCursor(Qt::WaitCursor);
1407 
1408 	QPalette customPal = d->palette();
1409 	// customPal.setDisabled(customPal.inactive());
1410 	d->tabWidget3->setEnabled(false);
1411 	d->tabWidget3->setPalette(customPal);
1412 
1413 	d->progress->show();
1414 	d->progress->setValue( 0 );
1415 
1416 	numIconsets = countIconsets("/roster", loaded);
1417 	iconsetsLoaded = 0;
1418 
1419 	cancelThread();
1420 
1421 	thread = new IconsetLoadThread(this, "/roster");
1422 	thread->start();
1423 }
1424 
event(QEvent * e)1425 bool OptionsTabIconsetRoster::event(QEvent *e)
1426 {
1427 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1428 	if ( e->type() == QEvent::User ) { // iconset load event
1429 		IconsetLoadEvent *le = (IconsetLoadEvent *)e;
1430 
1431 		if ( thread != le->thread() )
1432 			return false;
1433 
1434 		if ( !numIconsets )
1435 			numIconsets = 1;
1436 		d->progress->setValue( (int)((float)100 * ++iconsetsLoaded / numIconsets) );
1437 
1438 		Iconset *i = le->iconset();
1439 		if ( i ) {
1440 			PsiIconset::instance()->stripFirstAnimFrame(i);
1441 			QFileInfo fi( i->fileName() );
1442 
1443 			// roster - default
1444 			d->iss_defRoster->insert(*i);
1445 			if ( fi.fileName() == PsiOptions::instance()->getOption("options.iconsets.status"))
1446 				d->iss_defRoster->setItemSelected(d->iss_defRoster->lastItem(), true);
1447 
1448 			// roster - service
1449 			d->iss_servicesRoster->insert(*i);
1450 
1451 			// roster - custom
1452 			d->iss_customRoster->insert(*i);
1453 
1454 			delete i;
1455 		}
1456 
1457 		return true;
1458 	}
1459 	else if ( e->type() == QEvent::User + 1 ) { // finish event
1460 		// roster - service
1461 		{
1462 			// fill the QTreeWidget
1463 			QTreeWidgetItemIterator it(d->tw_isServices);
1464 			while (*it) {
1465 				QTreeWidgetItem *i = *it;
1466 				if (!i->data(0, ServiceRole).toString().isEmpty()) {
1467 					Iconset *iss = PsiIconset::instance()->roster[
1468 					                   PsiOptions::instance()->getOption(
1469 					                       PsiOptions::instance()->mapLookup(
1470 					                           "options.iconsets.service-status",
1471 					                           i->data(0, ServiceRole).toString())+".iconset").toString()];
1472 					if (iss) {
1473 						i->setText(1, iss->name());
1474 						QFileInfo fi(iss->fileName());
1475 						i->setData(0, IconsetRole, fi.fileName());
1476 					}
1477 				}
1478 				++it;
1479 			}
1480 		}
1481 
1482 		// roster - custom
1483 		{
1484 			// Then, fill the QListView
1485 			QTreeWidgetItem *last = 0;
1486 			QStringList customicons = PsiOptions::instance()->getChildOptionNames("options.iconsets.custom-status", true, true);
1487 			foreach(QString base, customicons) {
1488 				QString regexp = PsiOptions::instance()->getOption(base + ".regexp").toString();
1489 				QString icoset = PsiOptions::instance()->getOption(base + ".iconset").toString();
1490 				QTreeWidgetItem *item = new QTreeWidgetItem(d->tw_customRoster, last);
1491 				last = item;
1492 
1493 				item->setText(0, clipCustomText(regexp));
1494 				item->setData(0, RegexpRole, regexp);
1495 
1496 				Iconset *iss = PsiIconset::instance()->roster[icoset];
1497 				if ( iss ) {
1498 					item->setText(1, iss->name());
1499 					QFileInfo fi ( iss->fileName() );
1500 					item->setData(0, IconsetRole, fi.fileName());
1501 				}
1502 			}
1503 			d->tw_customRoster->resizeColumnToContents(0);
1504 		}
1505 
1506 		d->tabWidget3->setEnabled(true);
1507 		// d->tabWidget3->setPalette(QPalette());
1508 
1509 		connect(d->iss_defRoster, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
1510 		connect(d->iss_servicesRoster, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
1511 		connect(d->iss_customRoster, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), SIGNAL(dataChanged()));
1512 
1513 		d->progress->hide();
1514 
1515 		d->unsetCursor();
1516 		thread = 0;
1517 
1518 		return true;
1519 	}
1520 
1521 	return false;
1522 }
1523 
setData(PsiCon * psicon,QWidget * p)1524 void OptionsTabIconsetRoster::setData(PsiCon *psicon, QWidget *p)
1525 {
1526 	psi = psicon;
1527 	parentWidget = p;
1528 }
1529 
defaultDetails()1530 void OptionsTabIconsetRoster::defaultDetails()
1531 {
1532 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1533 	const Iconset *is = d->iss_defRoster->iconset();
1534 	if (is) {
1535 		isDetails(*is, parentWidget->parentWidget(), psi);
1536 	}
1537 }
1538 
servicesDetails()1539 void OptionsTabIconsetRoster::servicesDetails()
1540 {
1541 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1542 	const Iconset *is = d->iss_servicesRoster->iconset();
1543 	if (is) {
1544 		isDetails(*is, parentWidget->parentWidget(), psi);
1545 	}
1546 }
1547 
customDetails()1548 void OptionsTabIconsetRoster::customDetails()
1549 {
1550 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1551 	const Iconset *is = d->iss_customRoster->iconset();
1552 	if (is) {
1553 		isDetails(*is, parentWidget->parentWidget(), psi);
1554 	}
1555 }
1556 
1557 //------------------------------------------------------------
1558 
isServices_iconsetSelected(QListWidgetItem * item,QListWidgetItem *)1559 void OptionsTabIconsetRoster::isServices_iconsetSelected(QListWidgetItem *item, QListWidgetItem *)
1560 {
1561 	if ( !item )
1562 		return;
1563 
1564 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1565 	QTreeWidgetItem *it = d->tw_isServices->currentItem();
1566 	if ( !it )
1567 		return;
1568 
1569 	const Iconset *is = ((IconWidgetItem *)item)->iconset();
1570 	if ( !is )
1571 		return;
1572 
1573 	it->setText(1, is->name());
1574 	QFileInfo fi ( is->fileName() );
1575 	it->setData(0, IconsetRole, fi.fileName());
1576 }
1577 
isServices_selectionChanged(QTreeWidgetItem * it)1578 void OptionsTabIconsetRoster::isServices_selectionChanged(QTreeWidgetItem *it)
1579 {
1580 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1581 	d->iss_servicesRoster->setEnabled( it != 0 );
1582 	d->pb_servicesDetails->setEnabled( it != 0 );
1583 	d->iss_servicesRoster->clearSelection();
1584 	if ( !it )
1585 		return;
1586 
1587 	QString name = it->data(0, IconsetRole).toString();
1588 	if (name.isEmpty())
1589 		return;
1590 
1591 	emit noDirty(true);
1592 	for (int row = 0; row < d->iss_servicesRoster->count(); row++) {
1593 		IconWidgetItem *item = (IconWidgetItem *)d->iss_servicesRoster->item(row);
1594 		const Iconset *is = item->iconset();
1595 		if ( is ) {
1596 			QFileInfo fi ( is->fileName() );
1597 			if ( fi.fileName() == name ) {
1598 				emit noDirty(true);
1599 				d->iss_servicesRoster->setItemSelected(item, true);
1600 				d->iss_servicesRoster->scrollToItem(item);
1601 				emit noDirty(false);
1602 				break;
1603 			}
1604 		}
1605 	}
1606 	qApp->processEvents();
1607 	emit noDirty(false);
1608 }
1609 
1610 //------------------------------------------------------------
1611 
isCustom_iconsetSelected(QListWidgetItem * item,QListWidgetItem *)1612 void OptionsTabIconsetRoster::isCustom_iconsetSelected(QListWidgetItem *item, QListWidgetItem *)
1613 {
1614 	if ( !item )
1615 		return;
1616 
1617 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1618 	QTreeWidgetItem *it = d->tw_customRoster->currentItem();
1619 	if ( !it )
1620 		return;
1621 
1622 	const Iconset *is = ((IconWidgetItem *)item)->iconset();
1623 	if ( !is )
1624 		return;
1625 
1626 	it->setText(1, is->name());
1627 	QFileInfo fi ( is->fileName() );
1628 	it->setData(0, IconsetRole, fi.fileName());
1629 }
1630 
isCustom_selectionChanged(QTreeWidgetItem * it)1631 void OptionsTabIconsetRoster::isCustom_selectionChanged(QTreeWidgetItem *it)
1632 {
1633 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1634 	d->iss_customRoster->setEnabled( it != 0 );
1635 	d->pb_customRosterDetails->setEnabled( it != 0 );
1636 	//d->pb_customRosterAdd->setEnabled( it != 0 );
1637 	d->pb_customRosterDelete->setEnabled( it != 0 );
1638 	d->le_customRoster->setEnabled( it != 0 );
1639 	d->iss_customRoster->clearSelection();
1640 	if ( !it )
1641 		return;
1642 
1643 	QString name = it->data(0, IconsetRole).toString();
1644 	if (name.isEmpty())
1645 		return;
1646 
1647 	emit noDirty(true);
1648 	d->le_customRoster->setText(it->data(0, RegexpRole).toString());
1649 
1650 	for (int row = 0; row < d->iss_customRoster->count(); row++) {
1651 		IconWidgetItem *item = (IconWidgetItem *)d->iss_customRoster->item(row);
1652 		const Iconset *is = item->iconset();
1653 		if ( is ) {
1654 			QFileInfo fi ( is->fileName() );
1655 			if ( fi.fileName() == name ) {
1656 				d->iss_customRoster->setItemSelected(item, true);
1657 				d->iss_customRoster->scrollToItem(item);
1658 				break;
1659 			}
1660 		}
1661 	}
1662 	qApp->processEvents();
1663 	emit noDirty(false);
1664 }
1665 
isCustom_textChanged()1666 void OptionsTabIconsetRoster::isCustom_textChanged()
1667 {
1668 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1669 	QTreeWidgetItem *item = d->tw_customRoster->currentItem();
1670 	if ( !item )
1671 		return;
1672 
1673 	item->setText(0, clipCustomText(d->le_customRoster->text()));
1674 	item->setData(0, RegexpRole, d->le_customRoster->text());
1675 }
1676 
isCustom_add()1677 void OptionsTabIconsetRoster::isCustom_add()
1678 {
1679 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1680 
1681 	QString def;
1682 	const Iconset *iconset = d->iss_defRoster->iconset();
1683 	if ( iconset ) {
1684 		QFileInfo fi( iconset->fileName() );
1685 		def = fi.fileName();
1686 	}
1687 	else
1688 		qWarning("OptionsTabIconsetRoster::isCustom_add(): 'def' is null!");
1689 
1690 	QTreeWidgetItem *item = new QTreeWidgetItem(d->tw_customRoster);
1691 	const Iconset *i = PsiIconset::instance()->roster[def];
1692 	if ( i ) {
1693 		item->setText(1, i->name());
1694 
1695 		QFileInfo fi(i->fileName());
1696 		item->setData(0, IconsetRole, fi.fileName());
1697 	}
1698 
1699 	d->tw_customRoster->setCurrentItem(item);
1700 	emit dataChanged();
1701 
1702 	d->le_customRoster->setFocus();
1703 }
1704 
isCustom_delete()1705 void OptionsTabIconsetRoster::isCustom_delete()
1706 {
1707 	IconsetRosterUI *d = (IconsetRosterUI *)w;
1708 	QTreeWidgetItem *item = d->tw_customRoster->currentItem();
1709 	if ( !item )
1710 		return;
1711 
1712 	delete item;
1713 	isCustom_selectionChanged(0);
1714 	d->tw_customRoster->clearSelection();
1715 	emit dataChanged();
1716 }
1717 
clipCustomText(QString s)1718 QString OptionsTabIconsetRoster::clipCustomText(QString s)
1719 {
1720 	if ( s.length() > 10 ) {
1721 		s = s.left(9);
1722 		s += "...";
1723 	}
1724 
1725 	return s;
1726 }
1727 
cancelThread()1728 void OptionsTabIconsetRoster::cancelThread()
1729 {
1730 	if ( thread ) {
1731 		threadCancelled.lock();
1732 		thread->cancelled = true;
1733 		threadCancelled.unlock();
1734 
1735 		thread = 0;
1736 	}
1737 }
1738