kio Library API Documentation

kicondialog.cpp

00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * This file is part of the KDE project, module kfile. 00004 * Copyright (C) 2000 Geert Jansen <jansen@kde.org> 00005 * (C) 2000 Kurt Granroth <granroth@kde.org> 00006 * (C) 1997 Christoph Neerfeld <chris@kde.org> 00007 * (C) 2002 Carsten Pfeiffer <pfeiffer@kde.org> 00008 * 00009 * This is free software; it comes under the GNU Library General 00010 * Public License, version 2. See the file "COPYING.LIB" for the 00011 * exact licensing terms. 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 * KIconCanvas: Iconview for the iconloader dialog. 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 // disable updates to not trigger paint events when adding child items 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; // so we will emit it once in the beginning 00129 for (it=mFiles.begin(), i=0; it!=mFiles.end(); it++, i++) 00130 { 00131 // Calling kapp->processEvents() makes the iconview flicker like hell 00132 // (it's being repainted once for every new item), so we don't do this. 00133 // Instead, we directly repaint the progress bar without going through 00134 // the event-loop. We do that just once for every 10th item so that 00135 // the progress bar doesn't flicker in turn. (pfeiffer) 00136 if ( emitProgress >= 10 ) { 00137 emit progress(i); 00138 emitProgress = 0; 00139 } 00140 00141 emitProgress++; 00142 // kapp->processEvents(); 00143 if ( !d->m_bLoading ) // user clicked on a button that will load another set of icons 00144 break; 00145 QImage img; 00146 00147 // Use the extension as the format. Works for XPM and PNG, but not for SVG 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 // enable updates since we have to draw the whole view now 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 * KIconDialog: Dialog for selecting icons. Both system and user 00228 * specified icons can be chosen. 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(i18n("Icon Source"), main); 00262 top->addWidget(bgroup); 00263 connect(bgroup, SIGNAL(clicked(int)), SLOT(slotButtonClicked(int))); 00264 QGridLayout *grid = new QGridLayout(bgroup, 3, 2, marginHint(), spacingHint()); 00265 grid->addRowSpacing(0, 15); 00266 mpRb1 = new QRadioButton(i18n("&System icons:"), bgroup); 00267 grid->addWidget(mpRb1, 1, 0); 00268 mpCombo = new QComboBox(bgroup); 00269 connect(mpCombo, SIGNAL(activated(int)), SLOT(slotContext(int))); 00270 grid->addWidget(mpCombo, 1, 1); 00271 mpRb2 = new QRadioButton(i18n("O&ther icons:"), bgroup); 00272 grid->addWidget(mpRb2, 2, 0); 00273 mpBrowseBut = new QPushButton(i18n("&Browse..."), bgroup); 00274 grid->addWidget(mpBrowseBut, 2, 1); 00275 00276 mpCanvas = new KIconCanvas(main); 00277 connect(mpCanvas, SIGNAL(executed(QIconViewItem *)), SLOT(slotAcceptIcons())); 00278 mpCanvas->setMinimumSize(400, 125); 00279 top->addWidget(mpCanvas); 00280 00281 mpProgress = new KProgress(main); 00282 top->addWidget(mpProgress); 00283 connect(mpCanvas, SIGNAL(startLoading(int)), SLOT(slotStartLoading(int))); 00284 connect(mpCanvas, SIGNAL(progress(int)), SLOT(slotProgress(int))); 00285 connect(mpCanvas, SIGNAL(finished()), SLOT(slotFinished())); 00286 00287 // When pressing Ok or Cancel, stop loading icons 00288 connect(this, SIGNAL(hidden()), mpCanvas, SLOT(stopLoading())); 00289 00290 // The order must match the context definitions in KIcon. 00291 mpCombo->insertItem(i18n("Actions")); 00292 mpCombo->insertItem(i18n("Applications")); 00293 mpCombo->insertItem(i18n("Devices")); 00294 mpCombo->insertItem(i18n("Filesystems")); 00295 mpCombo->insertItem(i18n("Mimetypes")); 00296 mpCombo->setFixedSize(mpCombo->sizeHint()); 00297 mpBrowseBut->setFixedWidth(mpCombo->width()); 00298 00299 // Make the dialog a little taller 00300 incInitialSize(QSize(0,100)); 00301 } 00302 00303 00304 KIconDialog::~KIconDialog() 00305 { 00306 delete d; 00307 } 00308 00309 void KIconDialog::slotAcceptIcons() 00310 { 00311 d->custom=QString::null; 00312 slotOk(); 00313 } 00314 00315 void KIconDialog::showIcons() 00316 { 00317 mpCanvas->clear(); 00318 QStringList filelist; 00319 if (mType == 0) 00320 if (d->m_bStrictIconSize) 00321 filelist=mpLoader->queryIcons(mGroupOrSize, mContext); 00322 else 00323 filelist=mpLoader->queryIconsByContext(mGroupOrSize, mContext); 00324 else if ( !d->customLocation.isNull() ) 00325 filelist=mpLoader->queryIconsByDir( d->customLocation ); 00326 else 00327 filelist=mFileList; 00328 00329 QSortedList <IconPath>iconlist; 00330 iconlist.setAutoDelete(true); 00331 QStringList::Iterator it; 00332 for( it = filelist.begin(); it != filelist.end(); ++it ) 00333 iconlist.append(new IconPath(*it)); 00334 00335 iconlist.sort(); 00336 filelist.clear(); 00337 00338 for ( IconPath *ip=iconlist.first(); ip != 0; ip=iconlist.next() ) 00339 filelist.append(*ip); 00340 00341 mpCanvas->loadFiles(filelist); 00342 } 00343 00344 void KIconDialog::setStrictIconSize(bool b) 00345 { 00346 d->m_bStrictIconSize=b; 00347 } 00348 00349 bool KIconDialog::strictIconSize() const 00350 { 00351 return d->m_bStrictIconSize; 00352 } 00353 00354 void KIconDialog::setIconSize( int size ) 00355 { 00356 // see KIconLoader, if you think this is weird 00357 if ( size == 0 ) 00358 mGroupOrSize = KIcon::Desktop; // default Group 00359 else 00360 mGroupOrSize = -size; // yes, KIconLoader::queryIconsByContext is weird 00361 } 00362 00363 int KIconDialog::iconSize() const 00364 { 00365 // 0 or any other value ==> mGroupOrSize is a group, so we return 0 00366 return (mGroupOrSize < 0) ? -mGroupOrSize : 0; 00367 } 00368 00369 #ifndef KDE_NO_COMPAT 00370 QString KIconDialog::selectIcon(KIcon::Group group, KIcon::Context context, bool user) 00371 { 00372 setup( group, context, false, 0, user ); 00373 return openDialog(); 00374 } 00375 #endif 00376 00377 void KIconDialog::setup(KIcon::Group group, KIcon::Context context, 00378 bool strictIconSize, int iconSize, bool user ) 00379 { 00380 d->m_bStrictIconSize = strictIconSize; 00381 mGroupOrSize = (iconSize == 0) ? group : -iconSize; 00382 mType = user ? 1 : 0; 00383 mpRb1->setChecked(!user); 00384 mpRb2->setChecked(user); 00385 mpCombo->setEnabled(!user); 00386 mpBrowseBut->setEnabled(user); 00387 mContext = context; 00388 mpCombo->setCurrentItem(mContext-1); 00389 } 00390 00391 void KIconDialog::setup(KIcon::Group group, KIcon::Context context, 00392 bool strictIconSize, int iconSize, bool user, 00393 bool lockUser, bool lockCustomDir ) 00394 { 00395 d->m_bStrictIconSize = strictIconSize; 00396 d->m_bLockUser = lockUser; 00397 d->m_bLockCustomDir = lockCustomDir; 00398 mGroupOrSize = (iconSize == 0) ? group : -iconSize; 00399 mType = user ? 1 : 0; 00400 mpRb1->setChecked(!user); 00401 mpRb1->setEnabled( !lockUser || !user ); 00402 mpRb2->setChecked(user); 00403 mpRb2->setEnabled( !lockUser || user ); 00404 mpCombo->setEnabled(!user); 00405 mpBrowseBut->setEnabled( user && !lockCustomDir ); 00406 mContext = context; 00407 mpCombo->setCurrentItem(mContext-1); 00408 } 00409 00410 void KIconDialog::setCustomLocation( const QString& location ) 00411 { 00412 d->customLocation = location; 00413 } 00414 00415 QString KIconDialog::openDialog() 00416 { 00417 showIcons(); 00418 00419 if ( exec() == Accepted ) 00420 { 00421 if (!d->custom.isNull()) 00422 return d->custom; 00423 QString name = mpCanvas->getCurrent(); 00424 if (name.isEmpty() || (mType == 1)) 00425 return name; 00426 QFileInfo fi(name); 00427 return fi.baseName(); 00428 } 00429 return QString::null; 00430 } 00431 00432 void KIconDialog::showDialog() 00433 { 00434 setModal(false); 00435 showIcons(); 00436 show(); 00437 } 00438 00439 void KIconDialog::slotOk() 00440 { 00441 QString name; 00442 if (!d->custom.isNull()) 00443 { 00444 name = d->custom; 00445 } 00446 else 00447 { 00448 name = mpCanvas->getCurrent(); 00449 if (!name.isEmpty() && (mType != 1)) 00450 { 00451 QFileInfo fi(name); 00452 name = fi.baseName(); 00453 } 00454 } 00455 00456 emit newIconName(name); 00457 KDialogBase::slotOk(); 00458 } 00459 00460 QString KIconDialog::getIcon(KIcon::Group group, KIcon::Context context, 00461 bool strictIconSize, int iconSize, bool user, 00462 QWidget *parent, const QString &caption) 00463 { 00464 KIconDialog dlg(parent, "icon dialog"); 00465 dlg.setup( group, context, strictIconSize, iconSize, user ); 00466 if (!caption.isNull()) 00467 dlg.setCaption(caption); 00468 00469 return dlg.openDialog(); 00470 } 00471 00472 void KIconDialog::slotButtonClicked(int id) 00473 { 00474 QString file; 00475 00476 switch (id) 00477 { 00478 case 0: 00479 if(mType!=0) 00480 { 00481 mType = 0; 00482 mpBrowseBut->setEnabled(false); 00483 mpCombo->setEnabled(true); 00484 showIcons(); 00485 } 00486 break; 00487 00488 case 1: 00489 if(mType!=1) 00490 { 00491 mType = 1; 00492 mpBrowseBut->setEnabled( !d->m_bLockCustomDir ); 00493 mpCombo->setEnabled(false); 00494 showIcons(); 00495 } 00496 break; 00497 case 2: 00498 { 00499 // Create a file dialog to select a PNG, XPM or SVG file, 00500 // with the image previewer shown. 00501 // KFileDialog::getImageOpenURL doesn't allow svg. 00502 KFileDialog dlg(QString::null, i18n("*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"), 00503 this, "filedialog", true); 00504 dlg.setOperationMode( KFileDialog::Opening ); 00505 dlg.setCaption( i18n("Open") ); 00506 dlg.setMode( KFile::File ); 00507 00508 KImageFilePreview *ip = new KImageFilePreview( &dlg ); 00509 dlg.setPreviewWidget( ip ); 00510 dlg.exec(); 00511 00512 file = dlg.selectedFile(); 00513 if (!file.isEmpty()) 00514 { 00515 d->custom = file; 00516 if ( mType == 1 ) 00517 d->customLocation = QFileInfo( file ).dirPath( true ); 00518 slotOk(); 00519 } 00520 } 00521 break; 00522 } 00523 } 00524 00525 void KIconDialog::slotContext(int id) 00526 { 00527 mContext = static_cast<KIcon::Context>(id+1); 00528 showIcons(); 00529 } 00530 00531 void KIconDialog::slotStartLoading(int steps) 00532 { 00533 if (steps < 10) 00534 mpProgress->hide(); 00535 else 00536 { 00537 mpProgress->setTotalSteps(steps); 00538 mpProgress->setProgress(0); 00539 mpProgress->show(); 00540 } 00541 } 00542 00543 void KIconDialog::slotProgress(int p) 00544 { 00545 mpProgress->setProgress(p); 00546 // commented out the following since setProgress already paints ther 00547 // progress bar. ->repaint() only makes it flicker 00548 //mpProgress->repaint(); 00549 } 00550 00551 void KIconDialog::slotFinished() 00552 { 00553 mpProgress->hide(); 00554 } 00555 00556 class KIconButton::KIconButtonPrivate 00557 { 00558 public: 00559 KIconButtonPrivate() { 00560 m_bStrictIconSize = false; 00561 iconSize = 0; // let KIconLoader choose the default 00562 } 00563 ~KIconButtonPrivate() {} 00564 bool m_bStrictIconSize; 00565 int iconSize; 00566 }; 00567 00568 00569 /* 00570 * KIconButton: A "choose icon" pushbutton. 00571 */ 00572 00573 KIconButton::KIconButton(QWidget *parent, const char *name) 00574 : QPushButton(parent, name) 00575 { 00576 init( KGlobal::iconLoader() ); 00577 } 00578 00579 KIconButton::KIconButton(KIconLoader *loader, 00580 QWidget *parent, const char *name) 00581 : QPushButton(parent, name) 00582 { 00583 init( loader ); 00584 } 00585 00586 void KIconButton::init( KIconLoader *loader ) 00587 { 00588 d = new KIconButtonPrivate; 00589 mGroup = KIcon::Desktop; 00590 mContext = KIcon::Application; 00591 mbUser = false; 00592 00593 mpLoader = loader; 00594 mpDialog = 0L; 00595 connect(this, SIGNAL(clicked()), SLOT(slotChangeIcon())); 00596 } 00597 00598 KIconButton::~KIconButton() 00599 { 00600 delete mpDialog; 00601 delete d; 00602 } 00603 00604 void KIconButton::setStrictIconSize(bool b) 00605 { 00606 d->m_bStrictIconSize=b; 00607 } 00608 00609 bool KIconButton::strictIconSize() const 00610 { 00611 return d->m_bStrictIconSize; 00612 } 00613 00614 void KIconButton::setIconSize( int size ) 00615 { 00616 d->iconSize = size; 00617 } 00618 00619 int KIconButton::iconSize() const 00620 { 00621 return d->iconSize; 00622 } 00623 00624 void KIconButton::setIconType(KIcon::Group group, KIcon::Context context, bool user) 00625 { 00626 mGroup = group; 00627 mContext = context; 00628 mbUser = user; 00629 } 00630 00631 void KIconButton::setIcon(const QString& icon) 00632 { 00633 mIcon = icon; 00634 setPixmap(mpLoader->loadIcon(mIcon, mGroup, d->iconSize)); 00635 00636 if (!mpDialog) 00637 { 00638 mpDialog = new KIconDialog(mpLoader, this); 00639 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&))); 00640 } 00641 00642 if ( mbUser ) 00643 mpDialog->setCustomLocation( QFileInfo( mpLoader->iconPath(mIcon, mGroup, true) ).dirPath( true ) ); 00644 } 00645 00646 void KIconButton::resetIcon() 00647 { 00648 mIcon = QString::null; 00649 setPixmap(QPixmap()); 00650 } 00651 00652 void KIconButton::slotChangeIcon() 00653 { 00654 if (!mpDialog) 00655 { 00656 mpDialog = new KIconDialog(mpLoader, this); 00657 connect(mpDialog, SIGNAL(newIconName(const QString&)), SLOT(newIconName(const QString&))); 00658 } 00659 00660 mpDialog->setup( mGroup, mContext, d->m_bStrictIconSize, d->iconSize, mbUser ); 00661 mpDialog->showDialog(); 00662 } 00663 00664 void KIconButton::newIconName(const QString& name) 00665 { 00666 if (name.isEmpty()) 00667 return; 00668 00669 QPixmap pm = mpLoader->loadIcon(name, mGroup, d->iconSize); 00670 setPixmap(pm); 00671 mIcon = name; 00672 00673 if ( mbUser ) 00674 mpDialog->setCustomLocation( QFileInfo( mpLoader->iconPath(mIcon, mGroup, true) ).dirPath( true ) ); 00675 00676 emit iconChanged(name); 00677 } 00678 00679 void KIconCanvas::virtual_hook( int id, void* data ) 00680 { KIconView::virtual_hook( id, data ); } 00681 00682 void KIconDialog::virtual_hook( int id, void* data ) 00683 { KDialogBase::virtual_hook( id, data ); } 00684 00685 #include "kicondialog.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.3.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 17 11:29:26 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003