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