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