kio Library API Documentation

kicondialog.cpp

00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * $Id: kicondialog.cpp,v 1.32.2.1 2004/02/01 19:10:48 lukas Exp $ 00004 * 00005 * This file is part of the KDE project, module kfile. 00006 * Copyright (C) 2000 Geert Jansen <jansen@kde.org> 00007 * (C) 2000 Kurt Granroth <granroth@kde.org> 00008 * (C) 1997 Christoph Neerfeld <chris@kde.org> 00009 * (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org> 00010 * 00011 * This is free software; it comes under the GNU Library General 00012 * Public License, version 2. See the file "COPYING.LIB" for the 00013 * exact licensing terms. 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 * KIconCanvas: Iconview for the iconloader dialog. 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; // so we will emit it once in the beginning 00117 for (it=mFiles.begin(), i=0; it!=mFiles.end(); it++, i++) 00118 { 00119 // Calling kapp->processEvents() makes the iconview flicker like hell 00120 // (it's being repainted once for every new item), so we don't do this. 00121 // Instead, we directly repaint the progress bar without going through 00122 // the event-loop. We do that just once for every 10th item so that 00123 // the progress bar doesn't flicker in turn. (pfeiffer) 00124 if ( emitProgress >= 10 ) { 00125 emit progress(i); 00126 emitProgress = 0; 00127 } 00128 00129 emitProgress++; 00130 // kapp->processEvents(); 00131 if ( !d->m_bLoading ) // user clicked on a button that will load another set of icons 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 * KIconDialog: Dialog for selecting icons. Both system and user 00195 * specified icons can be chosen. 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 // When pressing Ok or Cancel, stop loading icons 00255 connect(this, SIGNAL(hidden()), mpCanvas, SLOT(stopLoading())); 00256 00257 // The order must match the context definitions in KIcon. 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 // Make the dialog a little taller 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 // see KIconLoader, if you think this is weird 00324 if ( size == 0 ) 00325 mGroupOrSize = KIcon::Desktop; // default Group 00326 else 00327 mGroupOrSize = -size; // yes, KIconLoader::queryIconsByContext is weird 00328 } 00329 00330 int KIconDialog::iconSize() const 00331 { 00332 // 0 or any other value ==> mGroupOrSize is a group, so we return 0 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; // let KIconLoader choose the default 00494 } 00495 ~KIconButtonPrivate() {} 00496 bool m_bStrictIconSize; 00497 int iconSize; 00498 }; 00499 00500 00501 /* 00502 * KIconButton: A "choose icon" pushbutton. 00503 */ 00504 00505 KIconButton::KIconButton(QWidget *parent, const char *name) 00506 : QPushButton(parent, name) 00507 { 00508 d = new KIconButtonPrivate; 00509 // arbitrary 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"
KDE Logo
This file is part of the documentation for kio Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Aug 30 22:54:40 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003