Updated the README file with some contributor tips.
[basket4.git] / src / kicondialog.cpp
blob7973cfd33efd02fdbf0c6864c08ac77a5e240405
1 /* vi: ts=8 sts=4 sw=4
2 * kate: space-indent on; indent-width 4; mixedindent off; indent-mode cstyle;
4 * This file is part of the KDE project, module kfile.
5 * Copyright (C) 2006 Luke Sandell <lasandell@gmail.com>
6 * (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org>
7 * (C) 2000 Geert Jansen <jansen@kde.org>
8 * (C) 2000 Kurt Granroth <granroth@kde.org>
9 * (C) 1997 Christoph Neerfeld <chris@kde.org>
11 * This is free software; it comes under the GNU Library General
12 * Public License, version 2. See the file "COPYING.LIB" for the
13 * exact licensing terms.
16 #include "kicondialogui.h"
17 #include "kicondialog.h"
18 #include "kiconcanvas.h"
20 #include <config.h>
22 #include <kiconviewsearchline.h>
24 #include <kdebug.h>
25 #include <kapplication.h>
26 #include <klocale.h>
27 #include <kglobal.h>
28 #include <kstandarddirs.h>
29 #include <kiconloader.h>
30 #include <kprogressdialog.h>
31 #include <k3iconview.h>
32 #include <kfiledialog.h>
33 #include <kimagefilepreview.h>
34 #include <kpushbutton.h>
35 #include <kmessagebox.h>
37 #include <qstring.h>
38 #include <qstringlist.h>
39 #include <q3sortedlist.h>
40 #include <qimage.h>
41 #include <qpixmap.h>
42 #include <qlabel.h>
43 #include <qcombobox.h>
44 #include <qtimer.h>
45 #include <q3buttongroup.h>
46 #include <qradiobutton.h>
47 #include <qfileinfo.h>
48 #include <qtoolbutton.h>
49 #include <q3whatsthis.h>
50 #include <qhbuttongroup.h>
51 #include <q3dragobject.h>
53 /* NOTE: Must be in the same order as listbox */
54 enum ExtendedContext
56 ALL = 0,
57 RECENT = 1,
58 // Action thru MimeType, subtract 1 to convert to KIcon::Context
59 OTHER = 7
62 class KIconDialog::KIconDialogPrivate
64 public:
65 KIconDialogPrivate() {
66 m_bStrictIconSize = true;
68 ~KIconDialogPrivate() {}
69 bool m_bStrictIconSize;
70 QString custom;
71 QString customLocation;
72 int recentMax;
73 QStringList recentList;
74 ExtendedContext extendedContext;
75 KIconDialogUI *ui; /* FIXME: KDE4 probably move this to the main class */
79 * KIconDialog: Dialog for selecting icons. Both system and user
80 * specified icons can be chosen.
83 KIconDialog::KIconDialog(QWidget *parent, const char*)
84 : KDialog(parent)
86 // Dialog init
87 setObjectName("IconDialog");
88 setModal(true);
89 setCaption(i18n("Select Icon"));
90 setButtons(Ok | Cancel);
91 setDefaultButton(Ok);
93 d = new KIconDialogPrivate;
94 mpLoader = KIconLoader::global();
95 init();
96 resize(minimumSize());
99 KIconDialog::KIconDialog(KIconLoader *loader, QWidget *parent,
100 const char *name)
101 : KDialog(parent)
103 // Dialog init
104 setObjectName(name);
105 setModal(true);
106 setCaption(i18n("Select Icon"));
107 setButtons(Ok | Cancel);
108 setDefaultButton(Ok);
110 d = new KIconDialogPrivate;
111 mpLoader = loader;
112 init();
115 void KIconDialog::init()
117 mGroupOrSize = KIconLoader::Desktop;
118 d->extendedContext = ALL;
119 mType = 0;
120 setCustomLocation(QString::null); // Initialize mFileList
122 // Read configuration
123 KConfig *config = KGlobal::config();
124 KConfigGroupSaver saver(config, "KIconDialog");
125 d->recentMax = config->readNumEntry("RecentMax", 10);
126 d->recentList = config->readPathEntry("RecentIcons", QStringList());
128 d->ui = new KIconDialogUI( this );
129 setMainWidget(d->ui);
131 d->ui->searchLine->setIconView(d->ui->iconCanvas);
132 d->ui->searchLine->setCaseSensitive(false);
134 // Hack standard Gui item, as KDevDesigner won't let us
135 d->ui->browseButton->setText(i18n("&Browse..."));
137 connect(d->ui->browseButton, SIGNAL(clicked()), SLOT(slotBrowse()));
138 connect(d->ui->listBox, SIGNAL(highlighted(int)), SLOT(slotContext(int)));
139 connect(d->ui->iconCanvas, SIGNAL(executed(Q3IconViewItem *)), SLOT(slotOk()));
140 connect(d->ui->iconCanvas, SIGNAL(returnPressed(Q3IconViewItem *)), SLOT(slotOk()));
141 connect(d->ui->iconCanvas, SIGNAL(startLoading(int)), SLOT(slotStartLoading(int)));
142 connect(d->ui->iconCanvas, SIGNAL(progress(int)), SLOT(slotProgress(int)));
143 connect(d->ui->iconCanvas, SIGNAL(finished()), SLOT(slotFinished()));
144 connect(this, SIGNAL(hidden()), d->ui->iconCanvas, SLOT(stopLoading()));
145 connect(this, SIGNAL(okClicked()), SLOT(slotOk()));
147 // NOTE: this must be consistent with the IconType enum (see above)
148 d->ui->listBox->insertItem(i18n("(All Icons)"));
149 d->ui->listBox->insertItem(i18n("(Recent)"));
150 d->ui->listBox->insertItem(i18n("Actions"));
151 d->ui->listBox->insertItem(i18n("Applications"));
152 d->ui->listBox->insertItem(i18n("Devices"));
153 d->ui->listBox->insertItem(i18n("Filesystem"));
154 d->ui->listBox->insertItem(i18n("File Types"));
155 d->ui->listBox->insertItem(i18n("Miscellaneous"));
158 KIconDialog::~KIconDialog()
160 // Write configuration
161 KConfig *config = KGlobal::config();
162 KConfigGroupSaver saver(config, "KIconDialog");
163 config->writeEntry("RecentMax", d->recentMax, true, true);
164 config->writePathEntry("RecentIcons", d->recentList, ',', true, true);
166 delete d;
169 void KIconDialog::slotAcceptIcons()
171 //FIXME: not used anymore
174 void KIconDialog::showIcons()
176 d->ui->iconCanvas->clear();
177 QStringList filelist;
179 KIcon::Context context = static_cast<KIcon::Context>(d->extendedContext - 1);
180 switch (d->extendedContext)
182 case RECENT:
183 filelist = d->recentList;
184 break;
185 case OTHER:
186 filelist = mFileList;
187 break;
188 case ALL:
189 filelist = mFileList;
190 context = KIcon::Any;
191 // ** Fallthrough to next case **
192 default:
193 QStringList list;
194 if (d->m_bStrictIconSize)
195 list=mpLoader->queryIcons(mGroupOrSize, context);
196 else
197 list=mpLoader->queryIconsByContext(mGroupOrSize, context);
199 // Remove path & extension
200 for ( QStringList::iterator it = list.begin(); it != list.end(); ++it)
201 filelist.append(QFileInfo(*it).baseName());
204 // Remove duplicate icons FIXME: Qt4 we can just use QSet
205 filelist.sort();
206 QString prev;
207 for ( QStringList::iterator it = filelist.begin(); it != filelist.end(); )
209 if (*it == prev)
211 it = filelist.remove(it);
213 else
215 prev = *it;
216 ++it;
220 d->ui->iconCanvas->setGroupOrSize(mGroupOrSize);
221 d->ui->iconCanvas->loadFiles(filelist);
224 void KIconDialog::setStrictIconSize(bool b)
226 d->m_bStrictIconSize=b;
229 bool KIconDialog::strictIconSize() const
231 return d->m_bStrictIconSize;
234 void KIconDialog::setIconSize( int size )
236 // see KIconLoader, if you think this is weird
237 if ( size == 0 )
238 mGroupOrSize = KIconLoader::Desktop; // default Group
239 else
240 mGroupOrSize = -size; // yes, KIconLoader::queryIconsByContext is weird
243 int KIconDialog::iconSize() const
245 // 0 or any other value ==> mGroupOrSize is a group, so we return 0
246 return (mGroupOrSize < 0) ? -mGroupOrSize : 0;
249 #ifndef KDE_NO_COMPAT
250 QString KIconDialog::selectIcon(KIcon::Group group, KIcon::Context context, bool user)
252 setup( group, context, false, 0, user );
253 return openDialog();
255 #endif
257 void KIconDialog::setup(KIcon::Group group, KIcon::Context context,
258 bool strictIconSize, int iconSize, bool user )
260 setup(group, context, strictIconSize, iconSize, user, false, false);
263 void KIconDialog::setup(KIcon::Group group, KIcon::Context context,
264 bool strictIconSize, int iconSize, bool user,
265 bool lockContext, bool lockBrowse )
267 d->m_bStrictIconSize = strictIconSize;
268 d->ui->iconCanvas->setStrictIconSize(strictIconSize);
269 mGroupOrSize = (iconSize == 0) ? group : -iconSize;
270 mType = user;
272 d->extendedContext = static_cast<ExtendedContext>( ( context == KIcon::Any ) ? ALL : context + 1 );
274 // We cannot change layout because it is protected ;-(
275 // FIXME: Qt4 we will be able to inherit from both QDialog and our GUI
276 d->ui->listBox->setEnabled(!lockContext);
277 d->ui->browseButton->setEnabled(!lockBrowse);
278 d->ui->listBox->setHidden(lockContext && lockBrowse);
279 d->ui->browseButton->setHidden(lockContext && lockBrowse);
281 d->ui->listBox->setCurrentItem(d->extendedContext);
284 const QString & KIconDialog::customLocation( ) const
286 return d->customLocation;
289 void KIconDialog::setCustomLocation( const QString& location )
291 d->customLocation = location;
293 if (location.isEmpty())
295 mFileList = KGlobal::dirs()->findAllResources("appicon", QString::fromLatin1("*.png"));
296 } else {
297 mFileList = mpLoader->queryIconsByDir(location);
301 QString KIconDialog::openDialog()
303 showIcons();
305 if ( exec() == Accepted )
307 if (!d->custom.isEmpty())
308 return d->custom;
309 else
310 return d->ui->iconCanvas->getCurrent();
312 else
314 return QString::null;
318 void KIconDialog::showDialog()
320 d->custom = QString::null;
322 // Make it so minimumSize returns correct value
323 d->ui->filterLabel->hide();
324 d->ui->searchLine->hide();
325 d->ui->progressBar->show();
327 setModal(false);
328 show();
330 // FIXME: this should be before show() but it doesn't work ;-(
331 resize(minimumSize());
333 showIcons();
336 void KIconDialog::slotOk()
338 QString key = !d->custom.isEmpty() ? d->custom : d->ui->iconCanvas->getCurrent();
340 // Append to list of recent icons
341 if (!d->recentList.contains(key))
343 d->recentList.push_back(key);
345 // Limit recent list in size
346 while ( (int)d->recentList.size() > d->recentMax )
347 d->recentList.pop_front();
350 emit newIconName(key);
353 QString KIconDialog::getIcon(KIcon::Group group, KIcon::Context context,
354 bool strictIconSize, int iconSize, bool user,
355 QWidget *parent, const QString &caption)
357 KIconDialog dlg(parent, "icon dialog");
358 dlg.setup( group, context, strictIconSize, iconSize, user );
359 if (!caption.isNull())
360 dlg.setCaption(caption);
362 return dlg.openDialog();
365 void KIconDialog::slotBrowse()
367 // Create a file dialog to select a PNG, XPM or SVG file,
368 // with the image previewer shown.
369 // KFileDialog::getImageOpenUrl doesn't allow svg.
370 KFileDialog dlg(QString::null, i18n("*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"),
371 this, "filedialog", true);
372 dlg.setOperationMode( KFileDialog::Opening );
373 dlg.setCaption( i18n("Open") );
374 dlg.setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly );
375 KImageFilePreview *ip = new KImageFilePreview( &dlg );
376 dlg.setPreviewWidget( ip );
377 dlg.exec();
379 QString file = dlg.selectedFile();
380 if (!file.isEmpty())
382 d->custom = file;
383 if ( mType == 1 )
384 setCustomLocation(QFileInfo( file ).absolutePath());
385 slotOk();
389 void KIconDialog::slotContext(int id)
391 d->extendedContext = static_cast<ExtendedContext>(id);
392 showIcons();
395 void KIconDialog::slotStartLoading(int steps)
397 if (steps < 10)
398 d->ui->progressBar->hide();
399 else
401 d->ui->progressBar->setTotalSteps(steps);
402 d->ui->progressBar->setProgress(0);
403 d->ui->progressBar->show();
404 d->ui->filterLabel->hide();
405 d->ui->searchLine->hide();
409 void KIconDialog::slotProgress(int p)
411 d->ui->progressBar->setProgress(p);
414 void KIconDialog::slotFinished()
416 d->ui->progressBar->hide();
417 d->ui->filterLabel->show();
418 d->ui->searchLine->show();
421 class KIconButton::KIconButtonPrivate
423 public:
424 KIconButtonPrivate() {
425 m_bStrictIconSize = false;
426 iconSize = 0; // let KIconLoader choose the default
428 ~KIconButtonPrivate() {}
429 bool m_bStrictIconSize;
430 bool lockUser;
431 bool lockCustom;
432 int iconSize;
437 * KIconButton: A "choose icon" pushbutton.
440 KIconButton::KIconButton(QWidget *parent, const char *name)
441 : QPushButton(parent, name)
443 init( KIconLoader::global() );
446 KIconButton::KIconButton(KIconLoader *loader,
447 QWidget *parent, const char *name)
448 : QPushButton(parent, name)
450 init( loader );
453 void KIconButton::init( KIconLoader *loader )
455 d = new KIconButtonPrivate;
456 mGroup = KIconLoader::Desktop;
457 mContext = KIcon::Application;
458 mbUser = false;
460 mpLoader = loader;
461 mpDialog = 0L;
462 connect(this, SIGNAL(clicked()), SLOT(slotChangeIcon()));
465 KIconButton::~KIconButton()
467 delete mpDialog;
468 delete d;
471 void KIconButton::setStrictIconSize(bool b)
473 d->m_bStrictIconSize=b;
476 bool KIconButton::strictIconSize() const
478 return d->m_bStrictIconSize;
481 void KIconButton::setIconSize( int size )
483 d->iconSize = size;
486 int KIconButton::iconSize() const
488 return d->iconSize;
491 void KIconButton::setIconType(KIcon::Group group, KIcon::Context context, bool user)
493 mGroup = group;
494 mContext = context;
495 mbUser = user;
496 d->lockUser = false;
497 d->lockCustom = false;
500 void KIconButton::setIconType(KIcon::Group group, KIcon::Context context, bool user, bool lockUser, bool lockCustom)
502 mGroup = group;
503 mContext = context;
504 mbUser = user;
505 d->lockUser = lockUser;
506 d->lockCustom = lockCustom;
509 void KIconButton::setIcon(const QString& icon)
511 mIcon = icon;
512 setIconSet(mpLoader->loadIconSet(mIcon, mGroup, d->iconSize));
514 if (!mpDialog)
516 mpDialog = new KIconDialog(mpLoader, this);
517 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&)));
521 const QString & KIconButton::customLocation( ) const
523 return mpDialog ? mpDialog->customLocation() : QString::null;
526 void KIconButton::setCustomLocation(const QString &custom)
528 if (!mpDialog)
530 mpDialog = new KIconDialog(mpLoader, this);
531 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&)));
534 mpDialog->setCustomLocation(custom);
537 void KIconButton::resetIcon()
539 mIcon = QString::null;
540 setIconSet(QIcon());
543 void KIconButton::slotChangeIcon()
545 if (!mpDialog)
547 mpDialog = new KIconDialog(mpLoader, this);
548 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&)));
551 mpDialog->setup( mGroup, mContext, d->m_bStrictIconSize, d->iconSize, mbUser, d->lockUser, d->lockCustom );
552 mpDialog->showDialog();
555 void KIconButton::newIconName(const QString& name)
557 if (name.isEmpty())
558 return;
560 QIcon iconset = mpLoader->loadIconSet(name, mGroup, d->iconSize);
561 setIconSet(iconset);
562 mIcon = name;
564 emit iconChanged(name);
567 void KIconCanvas::virtual_hook( int id, void* data )
568 { K3IconView::virtual_hook( id, data ); }
570 void KIconDialog::virtual_hook( int id, void* data )
571 { KDialog::virtual_hook( id, data ); }