00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "kicondialog.h"
00015
00016 #include <config.h>
00017
00018 #include <kiconviewsearchline.h>
00019
00020 #include <kapplication.h>
00021 #include <klocale.h>
00022 #include <kglobal.h>
00023 #include <kstandarddirs.h>
00024 #include <kiconloader.h>
00025 #include <kprogress.h>
00026 #include <kiconview.h>
00027 #include <kfiledialog.h>
00028 #include <kimagefilepreview.h>
00029
00030 #include <qlayout.h>
00031 #include <qstring.h>
00032 #include <qstringlist.h>
00033 #include <qsortedlist.h>
00034 #include <qimage.h>
00035 #include <qpixmap.h>
00036 #include <qlabel.h>
00037 #include <qcombobox.h>
00038 #include <qtimer.h>
00039 #include <qbuttongroup.h>
00040 #include <qradiobutton.h>
00041 #include <qfileinfo.h>
00042 #include <qtoolbutton.h>
00043 #include <qwhatsthis.h>
00044
00045 #ifdef HAVE_LIBART
00046 #include <svgicons/ksvgiconengine.h>
00047 #include <svgicons/ksvgiconpainter.h>
00048 #endif
00049
00050 class KIconCanvas::KIconCanvasPrivate
00051 {
00052 public:
00053 KIconCanvasPrivate() { m_bLoading = false; }
00054 ~KIconCanvasPrivate() {}
00055 bool m_bLoading;
00056 };
00057
00061 class IconPath : public QString
00062 {
00063 protected:
00064 QString m_iconName;
00065
00066 public:
00067 IconPath(const QString &ip) : QString (ip)
00068 {
00069 int n = findRev('/');
00070 m_iconName = (n==-1) ? static_cast<QString>(*this) : mid(n+1);
00071 }
00072
00073
00074 IconPath() : QString ()
00075 { }
00076
00077 bool operator== (const IconPath &ip) const
00078 { return m_iconName == ip.m_iconName; }
00079
00080 bool operator< (const IconPath &ip) const
00081 { return m_iconName < ip.m_iconName; }
00082
00083 };
00084
00085
00086
00087
00088
00089 KIconCanvas::KIconCanvas(QWidget *parent, const char *name)
00090 : KIconView(parent, name)
00091 {
00092 d = new KIconCanvasPrivate;
00093 mpLoader = KGlobal::iconLoader();
00094 mpTimer = new QTimer(this);
00095 connect(mpTimer, SIGNAL(timeout()), SLOT(slotLoadFiles()));
00096 connect(this, SIGNAL(currentChanged(QIconViewItem *)),
00097 SLOT(slotCurrentChanged(QIconViewItem *)));
00098 setGridX(80);
00099 setWordWrapIconText(false);
00100 setShowToolTips(true);
00101 }
00102
00103 KIconCanvas::~KIconCanvas()
00104 {
00105 delete mpTimer;
00106 delete d;
00107 }
00108
00109 void KIconCanvas::loadFiles(const QStringList& files)
00110 {
00111 clear();
00112 mFiles = files;
00113 emit startLoading(mFiles.count());
00114 mpTimer->start(10, true);
00115 d->m_bLoading = false;
00116 }
00117
00118 void KIconCanvas::slotLoadFiles()
00119 {
00120 setResizeMode(Fixed);
00121 QApplication::setOverrideCursor(waitCursor);
00122
00123
00124 setUpdatesEnabled( false );
00125
00126 #ifdef HAVE_LIBART
00127 KSVGIconEngine *svgEngine = new KSVGIconEngine();
00128 #endif
00129
00130 d->m_bLoading = true;
00131 int i;
00132 QStringList::ConstIterator it;
00133 uint emitProgress = 10;
00134 QStringList::ConstIterator end(mFiles.end());
00135 for (it=mFiles.begin(), i=0; it!=end; ++it, i++)
00136 {
00137
00138
00139
00140
00141
00142 if ( emitProgress >= 10 ) {
00143 emit progress(i);
00144 emitProgress = 0;
00145 }
00146
00147 emitProgress++;
00148
00149 if ( !d->m_bLoading )
00150 break;
00151 QImage img;
00152
00153
00154 QString path= *it;
00155 QString ext = path.right(3).upper();
00156
00157 if (ext != "SVG" && ext != "VGZ")
00158 img.load(*it);
00159 #ifdef HAVE_LIBART
00160 else
00161 if (svgEngine->load(60, 60, *it))
00162 img = *svgEngine->painter()->image();
00163 #endif
00164
00165 if (img.isNull())
00166 continue;
00167 if (img.width() > 60 || img.height() > 60)
00168 {
00169 if (img.width() > img.height())
00170 {
00171 int height = (int) ((60.0 / img.width()) * img.height());
00172 img = img.smoothScale(60, height);
00173 } else
00174 {
00175 int width = (int) ((60.0 / img.height()) * img.width());
00176 img = img.smoothScale(width, 60);
00177 }
00178 }
00179 QPixmap pm;
00180 pm.convertFromImage(img);
00181 QFileInfo fi(*it);
00182 QIconViewItem *item = new QIconViewItem(this, fi.baseName(), pm);
00183 item->setKey(*it);
00184 item->setDragEnabled(false);
00185 item->setDropEnabled(false);
00186 }
00187
00188 #ifdef HAVE_LIBART
00189 delete svgEngine;
00190 #endif
00191
00192
00193 setUpdatesEnabled( true );
00194
00195 QApplication::restoreOverrideCursor();
00196 d->m_bLoading = false;
00197 emit finished();
00198 setResizeMode(Adjust);
00199 }
00200
00201 QString KIconCanvas::getCurrent() const
00202 {
00203 if (!currentItem())
00204 return QString::null;
00205 return currentItem()->key();
00206 }
00207
00208 void KIconCanvas::stopLoading()
00209 {
00210 d->m_bLoading = false;
00211 }
00212
00213 void KIconCanvas::slotCurrentChanged(QIconViewItem *item)
00214 {
00215 emit nameChanged((item != 0L) ? item->text() : QString::null);
00216 }
00217
00218 class KIconDialog::KIconDialogPrivate
00219 {
00220 public:
00221 KIconDialogPrivate() {
00222 m_bStrictIconSize = true;
00223 m_bLockUser = false;
00224 m_bLockCustomDir = false;
00225 searchLine = 0;
00226 }
00227 ~KIconDialogPrivate() {}
00228 bool m_bStrictIconSize, m_bLockUser, m_bLockCustomDir;
00229 QString custom;
00230 QString customLocation;
00231 KIconViewSearchLine *searchLine;
00232 };
00233
00234
00235
00236
00237
00238
00239 KIconDialog::KIconDialog(QWidget *parent, const char *name)
00240 : KDialogBase(parent, name, true, i18n("Select Icon"), Ok|Cancel, Ok)
00241 {
00242 d = new KIconDialogPrivate;
00243 mpLoader = KGlobal::iconLoader();
00244 init();
00245 }
00246
00247 KIconDialog::KIconDialog(KIconLoader *loader, QWidget *parent,
00248 const char *name)
00249 : KDialogBase(parent, name, true, i18n("Select Icon"), Ok|Cancel, Ok)
00250 {
00251 d = new KIconDialogPrivate;
00252 mpLoader = loader;
00253 init();
00254 }
00255
00256 void KIconDialog::init()
00257 {
00258 mGroupOrSize = KIcon::Desktop;
00259 mContext = KIcon::Any;
00260 mType = 0;
00261 mFileList = KGlobal::dirs()->findAllResources("appicon", QString::fromLatin1("*.png"));
00262
00263 QWidget *main = new QWidget( this );
00264 setMainWidget(main);
00265
00266 QVBoxLayout *top = new QVBoxLayout(main);
00267 top->setSpacing( spacingHint() );
00268
00269 QButtonGroup *bgroup = new QButtonGroup(0, Qt::Vertical, i18n("Icon Source"), main);
00270 bgroup->layout()->setSpacing(KDialog::spacingHint());
00271 bgroup->layout()->setMargin(KDialog::marginHint());
00272 top->addWidget(bgroup);
00273 connect(bgroup, SIGNAL(clicked(int)), SLOT(slotButtonClicked(int)));
00274 QGridLayout *grid = new QGridLayout(bgroup->layout(), 3, 2);
00275 mpRb1 = new QRadioButton(i18n("S&ystem icons:"), bgroup);
00276 grid->addWidget(mpRb1, 1, 0);
00277 mpCombo = new QComboBox(bgroup);
00278 connect(mpCombo, SIGNAL(activated(int)), SLOT(slotContext(int)));
00279 grid->addWidget(mpCombo, 1, 1);
00280 mpRb2 = new QRadioButton(i18n("O&ther icons:"), bgroup);
00281 grid->addWidget(mpRb2, 2, 0);
00282 mpBrowseBut = new QPushButton(i18n("&Browse..."), bgroup);
00283 grid->addWidget(mpBrowseBut, 2, 1);
00284
00285
00286
00287
00288 QHBoxLayout *searchLayout = new QHBoxLayout(0, 0, KDialog::spacingHint());
00289 top->addLayout(searchLayout);
00290
00291 QToolButton *clearSearch = new QToolButton(main);
00292 clearSearch->setTextLabel(i18n("Clear Search"), true);
00293 clearSearch->setIconSet(SmallIconSet(QApplication::reverseLayout() ? "clear_left" :"locationbar_erase"));
00294 searchLayout->addWidget(clearSearch);
00295
00296 QLabel *searchLabel = new QLabel(i18n("&Search:"), main);
00297 searchLayout->addWidget(searchLabel);
00298
00299 d->searchLine = new KIconViewSearchLine(main, "searchLine");
00300 searchLayout->addWidget(d->searchLine);
00301 searchLabel->setBuddy(d->searchLine);
00302
00303
00304
00305 connect(clearSearch, SIGNAL(clicked()), d->searchLine, SLOT(clear()));
00306
00307 QString wtstr = i18n("Search interactively for icon names (e.g. folder).");
00308 QWhatsThis::add(searchLabel, wtstr);
00309 QWhatsThis::add(d->searchLine, wtstr);
00310
00311
00312 mpCanvas = new KIconCanvas(main);
00313 connect(mpCanvas, SIGNAL(executed(QIconViewItem *)), SLOT(slotAcceptIcons()));
00314 connect(mpCanvas, SIGNAL(returnPressed(QIconViewItem *)), SLOT(slotAcceptIcons()));
00315 mpCanvas->setMinimumSize(400, 125);
00316 top->addWidget(mpCanvas);
00317 d->searchLine->setIconView(mpCanvas);
00318
00319 mpProgress = new KProgress(main);
00320 top->addWidget(mpProgress);
00321 connect(mpCanvas, SIGNAL(startLoading(int)), SLOT(slotStartLoading(int)));
00322 connect(mpCanvas, SIGNAL(progress(int)), SLOT(slotProgress(int)));
00323 connect(mpCanvas, SIGNAL(finished()), SLOT(slotFinished()));
00324
00325
00326 connect(this, SIGNAL(hidden()), mpCanvas, SLOT(stopLoading()));
00327
00328
00329 mpCombo->insertItem(i18n("Actions"));
00330 mpCombo->insertItem(i18n("Applications"));
00331 mpCombo->insertItem(i18n("Devices"));
00332 mpCombo->insertItem(i18n("Filesystems"));
00333 mpCombo->insertItem(i18n("Mimetypes"));
00334 mpCombo->setFixedSize(mpCombo->sizeHint());
00335 mpBrowseBut->setFixedWidth(mpCombo->width());
00336
00337
00338 incInitialSize(QSize(0,100));
00339 }
00340
00341
00342 KIconDialog::~KIconDialog()
00343 {
00344 delete d;
00345 }
00346
00347 void KIconDialog::slotAcceptIcons()
00348 {
00349 d->custom=QString::null;
00350 slotOk();
00351 }
00352
00353 void KIconDialog::showIcons()
00354 {
00355 mpCanvas->clear();
00356 QStringList filelist;
00357 if (mType == 0)
00358 if (d->m_bStrictIconSize)
00359 filelist=mpLoader->queryIcons(mGroupOrSize, mContext);
00360 else
00361 filelist=mpLoader->queryIconsByContext(mGroupOrSize, mContext);
00362 else if ( !d->customLocation.isNull() )
00363 filelist=mpLoader->queryIconsByDir( d->customLocation );
00364 else
00365 filelist=mFileList;
00366
00367 QSortedList <IconPath>iconlist;
00368 iconlist.setAutoDelete(true);
00369 QStringList::Iterator it;
00370 for( it = filelist.begin(); it != filelist.end(); ++it )
00371 iconlist.append(new IconPath(*it));
00372
00373 iconlist.sort();
00374 filelist.clear();
00375
00376 for ( IconPath *ip=iconlist.first(); ip != 0; ip=iconlist.next() )
00377 filelist.append(*ip);
00378
00379 d->searchLine->clear();
00380 mpCanvas->loadFiles(filelist);
00381 }
00382
00383 void KIconDialog::setStrictIconSize(bool b)
00384 {
00385 d->m_bStrictIconSize=b;
00386 }
00387
00388 bool KIconDialog::strictIconSize() const
00389 {
00390 return d->m_bStrictIconSize;
00391 }
00392
00393 void KIconDialog::setIconSize( int size )
00394 {
00395
00396 if ( size == 0 )
00397 mGroupOrSize = KIcon::Desktop;
00398 else
00399 mGroupOrSize = -size;
00400 }
00401
00402 int KIconDialog::iconSize() const
00403 {
00404
00405 return (mGroupOrSize < 0) ? -mGroupOrSize : 0;
00406 }
00407
00408 #ifndef KDE_NO_COMPAT
00409 QString KIconDialog::selectIcon(KIcon::Group group, KIcon::Context context, bool user)
00410 {
00411 setup( group, context, false, 0, user );
00412 return openDialog();
00413 }
00414 #endif
00415
00416 void KIconDialog::setup(KIcon::Group group, KIcon::Context context,
00417 bool strictIconSize, int iconSize, bool user )
00418 {
00419 d->m_bStrictIconSize = strictIconSize;
00420 mGroupOrSize = (iconSize == 0) ? group : -iconSize;
00421 mType = user ? 1 : 0;
00422 mpRb1->setChecked(!user);
00423 mpRb2->setChecked(user);
00424 mpCombo->setEnabled(!user);
00425 mpBrowseBut->setEnabled(user);
00426 mContext = context;
00427 mpCombo->setCurrentItem(mContext-1);
00428 }
00429
00430 void KIconDialog::setup(KIcon::Group group, KIcon::Context context,
00431 bool strictIconSize, int iconSize, bool user,
00432 bool lockUser, bool lockCustomDir )
00433 {
00434 d->m_bStrictIconSize = strictIconSize;
00435 d->m_bLockUser = lockUser;
00436 d->m_bLockCustomDir = lockCustomDir;
00437 mGroupOrSize = (iconSize == 0) ? group : -iconSize;
00438 mType = user ? 1 : 0;
00439 mpRb1->setChecked(!user);
00440 mpRb1->setEnabled( !lockUser || !user );
00441 mpRb2->setChecked(user);
00442 mpRb2->setEnabled( !lockUser || user );
00443 mpCombo->setEnabled(!user);
00444 mpBrowseBut->setEnabled( user && !lockCustomDir );
00445 mContext = context;
00446 mpCombo->setCurrentItem(mContext-1);
00447 }
00448
00449 void KIconDialog::setCustomLocation( const QString& location )
00450 {
00451 d->customLocation = location;
00452 }
00453
00454 QString KIconDialog::openDialog()
00455 {
00456 showIcons();
00457
00458 if ( exec() == Accepted )
00459 {
00460 if (!d->custom.isNull())
00461 return d->custom;
00462 QString name = mpCanvas->getCurrent();
00463 if (name.isEmpty() || (mType == 1))
00464 return name;
00465 QFileInfo fi(name);
00466 return fi.baseName();
00467 }
00468 return QString::null;
00469 }
00470
00471 void KIconDialog::showDialog()
00472 {
00473 setModal(false);
00474 showIcons();
00475 show();
00476 }
00477
00478 void KIconDialog::slotOk()
00479 {
00480 QString name;
00481 if (!d->custom.isNull())
00482 {
00483 name = d->custom;
00484 }
00485 else
00486 {
00487 name = mpCanvas->getCurrent();
00488 if (!name.isEmpty() && (mType != 1))
00489 {
00490 QFileInfo fi(name);
00491 name = fi.baseName();
00492 }
00493 }
00494
00495 emit newIconName(name);
00496 KDialogBase::slotOk();
00497 }
00498
00499 QString KIconDialog::getIcon(KIcon::Group group, KIcon::Context context,
00500 bool strictIconSize, int iconSize, bool user,
00501 QWidget *parent, const QString &caption)
00502 {
00503 KIconDialog dlg(parent, "icon dialog");
00504 dlg.setup( group, context, strictIconSize, iconSize, user );
00505 if (!caption.isNull())
00506 dlg.setCaption(caption);
00507
00508 return dlg.openDialog();
00509 }
00510
00511 void KIconDialog::slotButtonClicked(int id)
00512 {
00513 QString file;
00514
00515 switch (id)
00516 {
00517 case 0:
00518 if(mType!=0)
00519 {
00520 mType = 0;
00521 mpBrowseBut->setEnabled(false);
00522 mpCombo->setEnabled(true);
00523 showIcons();
00524 }
00525 break;
00526
00527 case 1:
00528 if(mType!=1)
00529 {
00530 mType = 1;
00531 mpBrowseBut->setEnabled( !d->m_bLockCustomDir );
00532 mpCombo->setEnabled(false);
00533 showIcons();
00534 }
00535 break;
00536 case 2:
00537 {
00538
00539
00540
00541 KFileDialog dlg(QString::null, i18n("*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"),
00542 this, "filedialog", true);
00543 dlg.setOperationMode( KFileDialog::Opening );
00544 dlg.setCaption( i18n("Open") );
00545 dlg.setMode( KFile::File );
00546
00547 KImageFilePreview *ip = new KImageFilePreview( &dlg );
00548 dlg.setPreviewWidget( ip );
00549 dlg.exec();
00550
00551 file = dlg.selectedFile();
00552 if (!file.isEmpty())
00553 {
00554 d->custom = file;
00555 if ( mType == 1 )
00556 d->customLocation = QFileInfo( file ).dirPath( true );
00557 slotOk();
00558 }
00559 }
00560 break;
00561 }
00562 }
00563
00564 void KIconDialog::slotContext(int id)
00565 {
00566 mContext = static_cast<KIcon::Context>(id+1);
00567 showIcons();
00568 }
00569
00570 void KIconDialog::slotStartLoading(int steps)
00571 {
00572 if (steps < 10)
00573 mpProgress->hide();
00574 else
00575 {
00576 mpProgress->setTotalSteps(steps);
00577 mpProgress->setProgress(0);
00578 mpProgress->show();
00579 }
00580 }
00581
00582 void KIconDialog::slotProgress(int p)
00583 {
00584 mpProgress->setProgress(p);
00585
00586
00587
00588 }
00589
00590 void KIconDialog::slotFinished()
00591 {
00592 mpProgress->hide();
00593 }
00594
00595 class KIconButton::KIconButtonPrivate
00596 {
00597 public:
00598 KIconButtonPrivate() {
00599 m_bStrictIconSize = false;
00600 iconSize = 0;
00601 }
00602 ~KIconButtonPrivate() {}
00603 bool m_bStrictIconSize;
00604 int iconSize;
00605 };
00606
00607
00608
00609
00610
00611
00612 KIconButton::KIconButton(QWidget *parent, const char *name)
00613 : QPushButton(parent, name)
00614 {
00615 init( KGlobal::iconLoader() );
00616 }
00617
00618 KIconButton::KIconButton(KIconLoader *loader,
00619 QWidget *parent, const char *name)
00620 : QPushButton(parent, name)
00621 {
00622 init( loader );
00623 }
00624
00625 void KIconButton::init( KIconLoader *loader )
00626 {
00627 d = new KIconButtonPrivate;
00628 mGroup = KIcon::Desktop;
00629 mContext = KIcon::Application;
00630 mbUser = false;
00631
00632 mpLoader = loader;
00633 mpDialog = 0L;
00634 connect(this, SIGNAL(clicked()), SLOT(slotChangeIcon()));
00635 }
00636
00637 KIconButton::~KIconButton()
00638 {
00639 delete mpDialog;
00640 delete d;
00641 }
00642
00643 void KIconButton::setStrictIconSize(bool b)
00644 {
00645 d->m_bStrictIconSize=b;
00646 }
00647
00648 bool KIconButton::strictIconSize() const
00649 {
00650 return d->m_bStrictIconSize;
00651 }
00652
00653 void KIconButton::setIconSize( int size )
00654 {
00655 d->iconSize = size;
00656 }
00657
00658 int KIconButton::iconSize() const
00659 {
00660 return d->iconSize;
00661 }
00662
00663 void KIconButton::setIconType(KIcon::Group group, KIcon::Context context, bool user)
00664 {
00665 mGroup = group;
00666 mContext = context;
00667 mbUser = user;
00668 }
00669
00670 void KIconButton::setIcon(const QString& icon)
00671 {
00672 mIcon = icon;
00673 setIconSet(mpLoader->loadIconSet(mIcon, mGroup, d->iconSize));
00674
00675 if (!mpDialog)
00676 {
00677 mpDialog = new KIconDialog(mpLoader, this);
00678 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&)));
00679 }
00680
00681 if ( mbUser )
00682 mpDialog->setCustomLocation( QFileInfo( mpLoader->iconPath(mIcon, mGroup, true) ).dirPath( true ) );
00683 }
00684
00685 void KIconButton::resetIcon()
00686 {
00687 mIcon = QString::null;
00688 setIconSet(QIconSet());
00689 }
00690
00691 void KIconButton::slotChangeIcon()
00692 {
00693 if (!mpDialog)
00694 {
00695 mpDialog = new KIconDialog(mpLoader, this);
00696 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&)));
00697 }
00698
00699 mpDialog->setup( mGroup, mContext, d->m_bStrictIconSize, d->iconSize, mbUser );
00700 mpDialog->showDialog();
00701 }
00702
00703 void KIconButton::newIconName(const QString& name)
00704 {
00705 if (name.isEmpty())
00706 return;
00707
00708 QIconSet iconset = mpLoader->loadIconSet(name, mGroup, d->iconSize);
00709 setIconSet(iconset);
00710 mIcon = name;
00711
00712 if ( mbUser )
00713 mpDialog->setCustomLocation( QFileInfo( mpLoader->iconPath(mIcon, mGroup, true) ).dirPath( true ) );
00714
00715 emit iconChanged(name);
00716 }
00717
00718 void KIconCanvas::virtual_hook( int id, void* data )
00719 { KIconView::virtual_hook( id, data ); }
00720
00721 void KIconDialog::virtual_hook( int id, void* data )
00722 { KDialogBase::virtual_hook( id, data ); }
00723
00724 #include "kicondialog.moc"