KIO
kicondialog.cpp
Go to the documentation of this file.
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 "kicondialog.h" 00015 00016 #include <kio/kio_export.h> 00017 00018 #include <kbuttongroup.h> 00019 #include <kcombobox.h> 00020 #include <klistwidgetsearchline.h> 00021 #include <kapplication.h> 00022 #include <klocale.h> 00023 #include <kstandarddirs.h> 00024 #include <kiconloader.h> 00025 #include <kfiledialog.h> 00026 #include <kimagefilepreview.h> 00027 #ifndef _WIN32_WCE 00028 #include <ksvgrenderer.h> 00029 #endif 00030 00031 #include <QtGui/QLayout> 00032 #include <QtGui/QLabel> 00033 #include <QtCore/QTimer> 00034 #include <QtGui/QRadioButton> 00035 #include <QtCore/QFileInfo> 00036 #include <QtGui/QProgressBar> 00037 #include <QtGui/QPainter> 00038 #include <QtGui/QScrollBar> 00039 00040 00046 class KIconCanvasDelegate : public QAbstractItemDelegate 00047 { 00048 public: 00049 KIconCanvasDelegate(KIconCanvas *parent, QAbstractItemDelegate *defaultDelegate); 00050 ~KIconCanvasDelegate() {}; 00051 void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; 00052 QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; 00053 private: 00054 KIconCanvas *m_iconCanvas; 00055 QAbstractItemDelegate *m_defaultDelegate; 00056 static const int HORIZONTAL_EDGE_PAD = 3; 00057 }; 00058 00059 KIconCanvasDelegate::KIconCanvasDelegate(KIconCanvas *parent, QAbstractItemDelegate *defaultDelegate) 00060 : QAbstractItemDelegate(parent) 00061 { 00062 m_iconCanvas = parent; 00063 m_defaultDelegate = defaultDelegate; 00064 } 00065 00066 void KIconCanvasDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const 00067 { 00068 const int GRID_WIDTH = m_iconCanvas->gridSize().width(); 00069 QStyleOptionViewItem newOption = option; 00070 // Manipulate the width available. 00071 newOption.rect.setX((option.rect.x() / GRID_WIDTH) * GRID_WIDTH + HORIZONTAL_EDGE_PAD); 00072 newOption.rect.setWidth(GRID_WIDTH - 2 * HORIZONTAL_EDGE_PAD); 00073 00074 m_defaultDelegate->paint(painter, newOption, index); 00075 } 00076 00077 QSize KIconCanvasDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const 00078 { 00079 QSize size = m_defaultDelegate->sizeHint(option, index); 00080 const int GRID_WIDTH = m_iconCanvas->gridSize().width(); 00081 size.setWidth(GRID_WIDTH - 2 * HORIZONTAL_EDGE_PAD); 00082 return size; 00083 } 00084 00085 class KIconCanvas::KIconCanvasPrivate 00086 { 00087 public: 00088 KIconCanvasPrivate(KIconCanvas *qq) { q = qq; m_bLoading = false; } 00089 ~KIconCanvasPrivate() {} 00090 KIconCanvas *q; 00091 bool m_bLoading; 00092 QStringList mFiles; 00093 QTimer *mpTimer; 00094 KIconCanvasDelegate *mpDelegate; 00095 00096 // slots 00097 void _k_slotLoadFiles(); 00098 void _k_slotCurrentChanged(QListWidgetItem *item); 00099 }; 00100 00104 class IconPath : public QString 00105 { 00106 protected: 00107 QString m_iconName; 00108 00109 public: 00110 IconPath(const QString &ip) : QString (ip) 00111 { 00112 int n = lastIndexOf('/'); 00113 m_iconName = (n==-1) ? static_cast<QString>(*this) : mid(n+1); 00114 } 00115 00116 00117 IconPath() : QString () 00118 { } 00119 00120 bool operator== (const IconPath &ip) const 00121 { return m_iconName == ip.m_iconName; } 00122 00123 bool operator< (const IconPath &ip) const 00124 { return m_iconName < ip.m_iconName; } 00125 00126 }; 00127 00128 /* 00129 * KIconCanvas: Iconview for the iconloader dialog. 00130 */ 00131 00132 KIconCanvas::KIconCanvas(QWidget *parent) 00133 : KListWidget(parent), d(new KIconCanvasPrivate(this)) 00134 { 00135 setViewMode(IconMode); 00136 setUniformItemSizes(true); 00137 setMovement(Static); 00138 setIconSize(QSize(60, 60)); 00139 d->mpTimer = new QTimer(this); 00140 connect(d->mpTimer, SIGNAL(timeout()), this, SLOT(_k_slotLoadFiles())); 00141 connect(this, SIGNAL( currentItemChanged(QListWidgetItem *, QListWidgetItem *)), 00142 this, SLOT(_k_slotCurrentChanged(QListWidgetItem *))); 00143 setGridSize(QSize(100,80)); 00144 00145 d->mpDelegate = new KIconCanvasDelegate(this, itemDelegate()); 00146 setItemDelegate(d->mpDelegate); 00147 } 00148 00149 KIconCanvas::~KIconCanvas() 00150 { 00151 delete d->mpTimer; 00152 delete d->mpDelegate; 00153 delete d; 00154 } 00155 00156 void KIconCanvas::loadFiles(const QStringList& files) 00157 { 00158 clear(); 00159 d->mFiles = files; 00160 emit startLoading(d->mFiles.count()); 00161 d->mpTimer->setSingleShot(true); 00162 d->mpTimer->start(10); 00163 d->m_bLoading = false; 00164 } 00165 00166 void KIconCanvas::KIconCanvasPrivate::_k_slotLoadFiles() 00167 { 00168 q->setResizeMode(QListWidget::Fixed); 00169 QApplication::setOverrideCursor(Qt::WaitCursor); 00170 00171 // disable updates to not trigger paint events when adding child items, 00172 // but force an initial paint so that we do not get garbage 00173 q->repaint(); 00174 q->setUpdatesEnabled(false); 00175 00176 // Cache these as we will call them frequently. 00177 const int canvasIconWidth = q->iconSize().width(); 00178 const int canvasIconHeight = q->iconSize().width(); 00179 const bool uniformIconSize = q->uniformItemSizes(); 00180 00181 m_bLoading = true; 00182 int i; 00183 QStringList::ConstIterator it; 00184 uint emitProgress = 10; // so we will emit it once in the beginning 00185 QStringList::ConstIterator end(mFiles.constEnd()); 00186 for (it=mFiles.constBegin(), i=0; it!=end; ++it, i++) 00187 { 00188 if ( emitProgress >= 10 ) { 00189 emit q->progress(i); 00190 emitProgress = 0; 00191 } 00192 00193 emitProgress++; 00194 00195 if (!m_bLoading) { // user clicked on a button that will load another set of icons 00196 break; 00197 } 00198 QImage img; 00199 00200 // Use the extension as the format. Works for XPM and PNG, but not for SVG 00201 QString path= *it; 00202 QString ext = path.right(3).toUpper(); 00203 00204 if (ext != "SVG" && ext != "VGZ") 00205 img.load(*it); 00206 else { 00207 #ifndef _WIN32_WCE 00208 // Special stuff for SVG icons 00209 img = QImage(canvasIconWidth, canvasIconHeight, QImage::Format_ARGB32_Premultiplied); 00210 img.fill(0); 00211 KSvgRenderer renderer(*it); 00212 if (renderer.isValid()) { 00213 QPainter p(&img); 00214 renderer.render(&p); 00215 } 00216 #endif 00217 } 00218 00219 if (img.isNull()) 00220 continue; 00221 if (img.width() > canvasIconWidth || img.height() > canvasIconHeight) 00222 { 00223 if (img.width() / (float)canvasIconWidth > img.height() / (float)canvasIconHeight) 00224 { 00225 int height = (int) (((float)canvasIconWidth / img.width()) * img.height()); 00226 img = img.scaled(canvasIconWidth, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 00227 } else 00228 { 00229 int width = (int) (((float)canvasIconHeight / img.height()) * img.width()); 00230 img = img.scaled(width, canvasIconHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 00231 } 00232 } 00233 00234 if (uniformIconSize && (img.width() != canvasIconWidth || img.height() != canvasIconHeight)) 00235 { 00236 // Image is smaller than desired. Draw onto a transparent QImage of the required dimensions. 00237 // (Unpleasant glitches occur if we break the uniformIconSizes() contract). 00238 QImage paddedImage = QImage(canvasIconWidth, canvasIconHeight, QImage::Format_ARGB32_Premultiplied); 00239 paddedImage.fill(0); 00240 QPainter painter(&paddedImage); 00241 painter.drawImage( (canvasIconWidth - img.width()) / 2, (canvasIconHeight - img.height()) / 2, img); 00242 img = paddedImage; 00243 } 00244 00245 QPixmap pm = QPixmap::fromImage(img); 00246 QFileInfo fi(*it); 00247 QListWidgetItem *item = new QListWidgetItem(pm, fi.completeBaseName(), q); 00248 item->setData(Qt::UserRole, *it); 00249 item->setToolTip(fi.completeBaseName()); 00250 } 00251 00252 // enable updates since we have to draw the whole view now 00253 q->setUpdatesEnabled(true); 00254 00255 QApplication::restoreOverrideCursor(); 00256 m_bLoading = false; 00257 emit q->finished(); 00258 q->setResizeMode(QListWidget::Adjust); 00259 } 00260 00261 QString KIconCanvas::getCurrent() const 00262 { 00263 if (!currentItem()) 00264 return QString(); 00265 return currentItem()->data(Qt::UserRole).toString(); 00266 } 00267 00268 void KIconCanvas::stopLoading() 00269 { 00270 d->m_bLoading = false; 00271 } 00272 00273 void KIconCanvas::KIconCanvasPrivate::_k_slotCurrentChanged(QListWidgetItem *item) 00274 { 00275 emit q->nameChanged((item != 0L) ? item->text() : QString()); 00276 } 00277 00278 class KIconDialog::KIconDialogPrivate 00279 { 00280 public: 00281 KIconDialogPrivate(KIconDialog *qq) { 00282 q = qq; 00283 m_bStrictIconSize = true; 00284 m_bLockUser = false; 00285 m_bLockCustomDir = false; 00286 searchLine = 0; 00287 mNumOfSteps = 1; 00288 } 00289 ~KIconDialogPrivate() {} 00290 00291 void init(); 00292 void showIcons(); 00293 void setContext( KIconLoader::Context context ); 00294 00295 // slots 00296 void _k_slotContext(int); 00297 void _k_slotStartLoading(int); 00298 void _k_slotProgress(int); 00299 void _k_slotFinished(); 00300 void _k_slotAcceptIcons(); 00301 void _k_slotBrowse(); 00302 void _k_slotOtherIconClicked(); 00303 void _k_slotSystemIconClicked(); 00304 00305 KIconDialog *q; 00306 00307 int mGroupOrSize; 00308 KIconLoader::Context mContext; 00309 00310 QStringList mFileList; 00311 KComboBox *mpCombo; 00312 QPushButton *mpBrowseBut; 00313 QRadioButton *mpSystemIcons, *mpOtherIcons; 00314 QProgressBar *mpProgress; 00315 int mNumOfSteps; 00316 KIconLoader *mpLoader; 00317 KIconCanvas *mpCanvas; 00318 int mNumContext; 00319 KIconLoader::Context mContextMap[ 12 ]; // must match KIcon::Context size, code has assert 00320 00321 bool m_bStrictIconSize, m_bLockUser, m_bLockCustomDir; 00322 QString custom; 00323 QString customLocation; 00324 KListWidgetSearchLine *searchLine; 00325 }; 00326 00327 /* 00328 * KIconDialog: Dialog for selecting icons. Both system and user 00329 * specified icons can be chosen. 00330 */ 00331 00332 KIconDialog::KIconDialog(QWidget *parent) 00333 : KDialog(parent), d(new KIconDialogPrivate(this)) 00334 { 00335 setModal( true ); 00336 setCaption( i18n("Select Icon") ); 00337 setButtons( Ok | Cancel ); 00338 setDefaultButton( Ok ); 00339 00340 d->mpLoader = KIconLoader::global(); 00341 d->init(); 00342 } 00343 00344 KIconDialog::KIconDialog(KIconLoader *loader, QWidget *parent) 00345 : KDialog(parent), d(new KIconDialogPrivate(this)) 00346 { 00347 setModal( true ); 00348 setCaption( i18n("Select Icon") ); 00349 setButtons( Ok | Cancel ); 00350 setDefaultButton( Ok ); 00351 00352 d->mpLoader = loader; 00353 d->init(); 00354 } 00355 00356 void KIconDialog::KIconDialogPrivate::init() 00357 { 00358 mGroupOrSize = KIconLoader::Desktop; 00359 mContext = KIconLoader::Any; 00360 mFileList = KGlobal::dirs()->findAllResources("appicon", QLatin1String("*.png")); 00361 00362 QWidget *main = new QWidget(q); 00363 q->setMainWidget(main); 00364 00365 QVBoxLayout *top = new QVBoxLayout(main); 00366 top->setMargin(0); 00367 00368 QGroupBox *bgroup = new QGroupBox(main); 00369 bgroup->setTitle(i18n("Icon Source")); 00370 00371 QVBoxLayout *vbox = new QVBoxLayout; 00372 bgroup->setLayout( vbox ); 00373 top->addWidget(bgroup); 00374 00375 QGridLayout *grid = new QGridLayout(); 00376 vbox->addLayout(grid); 00377 00378 mpSystemIcons = new QRadioButton(i18n("S&ystem icons:"), bgroup); 00379 connect(mpSystemIcons, SIGNAL(clicked()), q, SLOT(_k_slotSystemIconClicked())); 00380 grid->addWidget(mpSystemIcons, 1, 0); 00381 mpCombo = new KComboBox(bgroup); 00382 mpCombo->setMaxVisibleItems(12); 00383 connect(mpCombo, SIGNAL(activated(int)), q, SLOT(_k_slotContext(int))); 00384 grid->addWidget(mpCombo, 1, 1); 00385 mpOtherIcons = new QRadioButton(i18n("O&ther icons:"), bgroup); 00386 connect(mpOtherIcons, SIGNAL(clicked()), q, SLOT(_k_slotOtherIconClicked())); 00387 grid->addWidget(mpOtherIcons, 2, 0); 00388 mpBrowseBut = new QPushButton(i18n("&Browse..."), bgroup); 00389 connect(mpBrowseBut, SIGNAL(clicked()), q, SLOT(_k_slotBrowse())); 00390 grid->addWidget(mpBrowseBut, 2, 1); 00391 00392 // 00393 // ADD SEARCHLINE 00394 // 00395 QHBoxLayout *searchLayout = new QHBoxLayout(); 00396 searchLayout->setMargin(0); 00397 top->addLayout(searchLayout); 00398 00399 QLabel *searchLabel = new QLabel(i18n("&Search:"), main); 00400 searchLayout->addWidget(searchLabel); 00401 00402 searchLine = new KListWidgetSearchLine(main); 00403 searchLayout->addWidget(searchLine); 00404 searchLabel->setBuddy(searchLine); 00405 00406 QString wtstr = i18n("Search interactively for icon names (e.g. folder)."); 00407 searchLabel->setWhatsThis(wtstr); 00408 searchLine->setWhatsThis(wtstr); 00409 00410 00411 mpCanvas = new KIconCanvas(main); 00412 connect(mpCanvas, SIGNAL(itemActivated(QListWidgetItem *)), q, SLOT(_k_slotAcceptIcons())); 00413 top->addWidget(mpCanvas); 00414 searchLine->setListWidget(mpCanvas); 00415 00416 // Compute width of canvas with 4 icons displayed in a row 00417 QStyleOption opt; 00418 opt.initFrom(mpCanvas); 00419 int width = 4 * mpCanvas->gridSize().width() + 1; 00420 width += mpCanvas->verticalScrollBar()->sizeHint().width(); 00421 width += 2 * mpCanvas->frameWidth(); 00422 if (mpCanvas->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, mpCanvas)) { 00423 width += mpCanvas->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, mpCanvas); 00424 } 00425 mpCanvas->setMinimumSize(width, 125); 00426 00427 mpProgress = new QProgressBar(main); 00428 top->addWidget(mpProgress); 00429 connect(mpCanvas, SIGNAL(startLoading(int)), q, SLOT(_k_slotStartLoading(int))); 00430 connect(mpCanvas, SIGNAL(progress(int)), q, SLOT(_k_slotProgress(int))); 00431 connect(mpCanvas, SIGNAL(finished()), q, SLOT(_k_slotFinished())); 00432 00433 // When pressing Ok or Cancel, stop loading icons 00434 connect(q, SIGNAL(hidden()), mpCanvas, SLOT(stopLoading())); 00435 00436 static const char* const context_text[] = { 00437 I18N_NOOP( "Actions" ), 00438 I18N_NOOP( "Animations" ), 00439 I18N_NOOP( "Applications" ), 00440 I18N_NOOP( "Categories" ), 00441 I18N_NOOP( "Devices" ), 00442 I18N_NOOP( "Emblems" ), 00443 I18N_NOOP( "Emotes" ), 00444 I18N_NOOP( "Filesystems" ), 00445 I18N_NOOP( "International" ), 00446 I18N_NOOP( "Mimetypes" ), 00447 I18N_NOOP( "Places" ), 00448 I18N_NOOP( "Status" ) }; 00449 static const KIconLoader::Context context_id[] = { 00450 KIconLoader::Action, 00451 KIconLoader::Animation, 00452 KIconLoader::Application, 00453 KIconLoader::Category, 00454 KIconLoader::Device, 00455 KIconLoader::Emblem, 00456 KIconLoader::Emote, 00457 KIconLoader::FileSystem, 00458 KIconLoader::International, 00459 KIconLoader::MimeType, 00460 KIconLoader::Place, 00461 KIconLoader::StatusIcon }; 00462 mNumContext = 0; 00463 int cnt = sizeof( context_text ) / sizeof( context_text[ 0 ] ); 00464 // check all 3 arrays have same sizes 00465 Q_ASSERT( cnt == sizeof( context_id ) / sizeof( context_id[ 0 ] ) 00466 && cnt == sizeof( mContextMap ) / sizeof( mContextMap[ 0 ] )); 00467 for( int i = 0; 00468 i < cnt; 00469 ++i ) 00470 { 00471 if( mpLoader->hasContext( context_id[ i ] )) 00472 { 00473 mpCombo->addItem(i18n( context_text[ i ] )); 00474 mContextMap[ mNumContext++ ] = context_id[ i ]; 00475 } 00476 } 00477 mpCombo->setFixedSize(mpCombo->sizeHint()); 00478 00479 mpBrowseBut->setFixedWidth(mpCombo->width()); 00480 00481 // Make the dialog a little taller 00482 q->incrementInitialSize(QSize(0,100)); 00483 connect(q, SIGNAL(okClicked()), q, SLOT(slotOk())); 00484 } 00485 00486 00487 KIconDialog::~KIconDialog() 00488 { 00489 delete d; 00490 } 00491 00492 void KIconDialog::KIconDialogPrivate::_k_slotAcceptIcons() 00493 { 00494 custom.clear(); 00495 q->slotOk(); 00496 } 00497 00498 void KIconDialog::KIconDialogPrivate::showIcons() 00499 { 00500 mpCanvas->clear(); 00501 QStringList filelist; 00502 if (mpSystemIcons->isChecked()) 00503 if (m_bStrictIconSize) 00504 filelist=mpLoader->queryIcons(mGroupOrSize, mContext); 00505 else 00506 filelist=mpLoader->queryIconsByContext(mGroupOrSize, mContext); 00507 else if (!customLocation.isNull()) { 00508 filelist = mpLoader->queryIconsByDir(customLocation); 00509 } 00510 else 00511 filelist=mFileList; 00512 00513 QList<IconPath> iconlist; 00514 QStringList::const_iterator it; 00515 foreach (const QString &it, filelist) { 00516 iconlist.append(IconPath(it)); 00517 } 00518 00519 qSort(iconlist); 00520 filelist.clear(); 00521 00522 foreach (const IconPath &ip, iconlist) { 00523 filelist.append(ip); 00524 } 00525 00526 searchLine->clear(); 00527 00528 // The KIconCanvas has uniformItemSizes set which really expects 00529 // all added icons to be the same size, otherwise weirdness ensues :) 00530 // Ensure all SVGs are scaled to the desired size and that as few icons 00531 // need to be padded as possible by specifying a sensible size. 00532 if (mGroupOrSize < -1) // mGroupOrSize can be -1 if NoGroup is chosen. 00533 { 00534 // Explicit size. 00535 mpCanvas->setIconSize(QSize(-mGroupOrSize, -mGroupOrSize)); 00536 } 00537 else 00538 { 00539 // Icon group. 00540 int groupSize = mpLoader->currentSize((KIconLoader::Group)mGroupOrSize); 00541 mpCanvas->setIconSize(QSize(groupSize, groupSize)); 00542 } 00543 00544 mpCanvas->loadFiles(filelist); 00545 } 00546 00547 void KIconDialog::setStrictIconSize(bool b) 00548 { 00549 d->m_bStrictIconSize=b; 00550 } 00551 00552 bool KIconDialog::strictIconSize() const 00553 { 00554 return d->m_bStrictIconSize; 00555 } 00556 00557 void KIconDialog::setIconSize( int size ) 00558 { 00559 // see KIconLoader, if you think this is weird 00560 if (size == 0) { 00561 d->mGroupOrSize = KIconLoader::Desktop; // default Group 00562 } else { 00563 d->mGroupOrSize = -size; // yes, KIconLoader::queryIconsByContext is weird 00564 } 00565 } 00566 00567 int KIconDialog::iconSize() const 00568 { 00569 // 0 or any other value ==> mGroupOrSize is a group, so we return 0 00570 return (d->mGroupOrSize < 0) ? -d->mGroupOrSize : 0; 00571 } 00572 00573 void KIconDialog::setup(KIconLoader::Group group, KIconLoader::Context context, 00574 bool strictIconSize, int iconSize, bool user, 00575 bool lockUser, bool lockCustomDir ) 00576 { 00577 d->m_bStrictIconSize = strictIconSize; 00578 d->m_bLockUser = lockUser; 00579 d->m_bLockCustomDir = lockCustomDir; 00580 if (iconSize == 0) 00581 { 00582 if (group == KIconLoader::NoGroup) 00583 { 00584 // NoGroup has numeric value -1, which should 00585 // not really be used with KIconLoader::queryIcons*(...); 00586 // pick a proper group. 00587 d->mGroupOrSize = KIconLoader::Small; 00588 } 00589 else 00590 { 00591 d->mGroupOrSize = group; 00592 } 00593 } 00594 else 00595 { 00596 d->mGroupOrSize = -iconSize; 00597 } 00598 00599 d->mpSystemIcons->setChecked(!user); 00600 d->mpSystemIcons->setEnabled(!lockUser || !user); 00601 d->mpOtherIcons->setChecked(user); 00602 d->mpOtherIcons->setEnabled(!lockUser || user); 00603 d->mpCombo->setEnabled(!user); 00604 d->mpBrowseBut->setEnabled(user && !lockCustomDir); 00605 d->setContext(context); 00606 } 00607 00608 void KIconDialog::KIconDialogPrivate::setContext(KIconLoader::Context context) 00609 { 00610 mContext = context; 00611 for( int i = 0; 00612 i < mNumContext; 00613 ++i ) 00614 if( mContextMap[ i ] == context ) 00615 { 00616 mpCombo->setCurrentIndex( i ); 00617 return; 00618 } 00619 } 00620 00621 void KIconDialog::setCustomLocation( const QString& location ) 00622 { 00623 d->customLocation = location; 00624 } 00625 00626 QString KIconDialog::openDialog() 00627 { 00628 d->showIcons(); 00629 d->searchLine->setFocus(); 00630 00631 if ( exec() == Accepted ) 00632 { 00633 if (!d->custom.isNull()) 00634 return d->custom; 00635 QString name = d->mpCanvas->getCurrent(); 00636 if (name.isEmpty() || d->mpOtherIcons->isChecked()) { 00637 return name; 00638 } 00639 QFileInfo fi(name); 00640 return fi.baseName(); 00641 } 00642 return QString(); 00643 } 00644 00645 void KIconDialog::showDialog() 00646 { 00647 setModal(false); 00648 d->showIcons(); 00649 d->searchLine->setFocus(); 00650 show(); 00651 } 00652 00653 void KIconDialog::slotOk() 00654 { 00655 QString name; 00656 if (!d->custom.isNull()) 00657 { 00658 name = d->custom; 00659 } 00660 else 00661 { 00662 name = d->mpCanvas->getCurrent(); 00663 if (!name.isEmpty() && d->mpSystemIcons->isChecked()) { 00664 QFileInfo fi(name); 00665 name = fi.baseName(); 00666 } 00667 } 00668 00669 emit newIconName(name); 00670 KDialog::accept(); 00671 } 00672 00673 QString KIconDialog::getIcon(KIconLoader::Group group, KIconLoader::Context context, 00674 bool strictIconSize, int iconSize, bool user, 00675 QWidget *parent, const QString &caption) 00676 { 00677 KIconDialog dlg(parent); 00678 dlg.setup( group, context, strictIconSize, iconSize, user ); 00679 if (!caption.isNull()) 00680 dlg.setCaption(caption); 00681 00682 return dlg.openDialog(); 00683 } 00684 00685 void KIconDialog::KIconDialogPrivate::_k_slotBrowse() 00686 { 00687 // Create a file dialog to select a PNG, XPM or SVG file, 00688 // with the image previewer shown. 00689 // KFileDialog::getImageOpenURL doesn't allow svg. 00690 KUrl emptyUrl; 00691 KFileDialog dlg(emptyUrl, i18n("*.png *.xpm *.svg *.svgz|Icon Files (*.png *.xpm *.svg *.svgz)"), q); 00692 dlg.setOperationMode( KFileDialog::Opening ); 00693 dlg.setCaption( i18n("Open") ); 00694 dlg.setMode( KFile::File ); 00695 00696 KImageFilePreview *ip = new KImageFilePreview( &dlg ); 00697 dlg.setPreviewWidget( ip ); 00698 dlg.exec(); 00699 00700 QString file = dlg.selectedFile(); 00701 if (!file.isEmpty()) 00702 { 00703 custom = file; 00704 if (mpSystemIcons->isChecked()) { 00705 customLocation = QFileInfo(file).absolutePath(); 00706 } 00707 q->slotOk(); 00708 } 00709 } 00710 00711 void KIconDialog::KIconDialogPrivate::_k_slotSystemIconClicked() 00712 { 00713 mpBrowseBut->setEnabled(false); 00714 mpCombo->setEnabled(true); 00715 showIcons(); 00716 } 00717 00718 void KIconDialog::KIconDialogPrivate::_k_slotOtherIconClicked() 00719 { 00720 mpBrowseBut->setEnabled(!m_bLockCustomDir); 00721 mpCombo->setEnabled(false); 00722 showIcons(); 00723 } 00724 00725 void KIconDialog::KIconDialogPrivate::_k_slotContext(int id) 00726 { 00727 mContext = static_cast<KIconLoader::Context>( mContextMap[ id ] ); 00728 showIcons(); 00729 } 00730 00731 void KIconDialog::KIconDialogPrivate::_k_slotStartLoading(int steps) 00732 { 00733 if (steps < 10) 00734 mpProgress->hide(); 00735 else 00736 { 00737 mNumOfSteps = steps; 00738 mpProgress->setValue(0); 00739 mpProgress->show(); 00740 } 00741 } 00742 00743 void KIconDialog::KIconDialogPrivate::_k_slotProgress(int p) 00744 { 00745 mpProgress->setValue(static_cast<int>(100.0 * (double)p / (double)mNumOfSteps)); 00746 } 00747 00748 void KIconDialog::KIconDialogPrivate::_k_slotFinished() 00749 { 00750 mNumOfSteps = 1; 00751 mpProgress->hide(); 00752 } 00753 00754 class KIconButton::KIconButtonPrivate 00755 { 00756 public: 00757 KIconButtonPrivate(KIconButton *qq, KIconLoader *loader); 00758 ~KIconButtonPrivate(); 00759 00760 // slots 00761 void _k_slotChangeIcon(); 00762 void _k_newIconName(const QString&); 00763 00764 KIconButton *q; 00765 00766 int iconSize; 00767 int buttonIconSize; 00768 bool m_bStrictIconSize; 00769 00770 bool mbUser; 00771 KIconLoader::Group mGroup; 00772 KIconLoader::Context mContext; 00773 00774 QString mIcon; 00775 KIconDialog *mpDialog; 00776 KIconLoader *mpLoader; 00777 }; 00778 00779 00780 /* 00781 * KIconButton: A "choose icon" pushbutton. 00782 */ 00783 00784 KIconButton::KIconButton(QWidget *parent) 00785 : QPushButton(parent), d(new KIconButtonPrivate(this, KIconLoader::global())) 00786 { 00787 QPushButton::setIconSize(QSize(48, 48)); 00788 } 00789 00790 KIconButton::KIconButton(KIconLoader *loader, QWidget *parent) 00791 : QPushButton(parent), d(new KIconButtonPrivate(this, loader)) 00792 { 00793 QPushButton::setIconSize(QSize(48, 48)); 00794 } 00795 00796 KIconButton::KIconButtonPrivate::KIconButtonPrivate(KIconButton *qq, KIconLoader *loader) 00797 : q(qq) 00798 { 00799 m_bStrictIconSize = false; 00800 iconSize = 0; // let KIconLoader choose the default 00801 buttonIconSize = -1; //When buttonIconSize is -1, iconSize will be used for the button 00802 00803 mGroup = KIconLoader::Desktop; 00804 mContext = KIconLoader::Application; 00805 mbUser = false; 00806 00807 mpLoader = loader; 00808 mpDialog = 0L; 00809 connect(q, SIGNAL(clicked()), q, SLOT(_k_slotChangeIcon())); 00810 } 00811 00812 KIconButton::KIconButtonPrivate::~KIconButtonPrivate() 00813 { 00814 delete mpDialog; 00815 } 00816 00817 KIconButton::~KIconButton() 00818 { 00819 delete d; 00820 } 00821 00822 void KIconButton::setStrictIconSize(bool b) 00823 { 00824 d->m_bStrictIconSize=b; 00825 } 00826 00827 bool KIconButton::strictIconSize() const 00828 { 00829 return d->m_bStrictIconSize; 00830 } 00831 00832 void KIconButton::setIconSize( int size ) 00833 { 00834 if (d->buttonIconSize == -1) { 00835 QPushButton::setIconSize(QSize(size, size)); 00836 } 00837 00838 d->iconSize = size; 00839 } 00840 00841 int KIconButton::iconSize() const 00842 { 00843 return d->iconSize; 00844 } 00845 00846 void KIconButton::setButtonIconSize( int size ) 00847 { 00848 QPushButton::setIconSize(QSize(size, size)); 00849 d->buttonIconSize = size; 00850 } 00851 00852 int KIconButton::buttonIconSize() const 00853 { 00854 return QPushButton::iconSize().height(); 00855 } 00856 00857 void KIconButton::setIconType(KIconLoader::Group group, KIconLoader::Context context, bool user) 00858 { 00859 d->mGroup = group; 00860 d->mContext = context; 00861 d->mbUser = user; 00862 } 00863 00864 void KIconButton::setIcon(const QString& icon) 00865 { 00866 d->mIcon = icon; 00867 setIcon(KIcon(d->mIcon)); 00868 00869 if (!d->mpDialog) { 00870 d->mpDialog = new KIconDialog(d->mpLoader, this); 00871 connect(d->mpDialog, SIGNAL(newIconName(const QString&)), this, SLOT(_k_newIconName(const QString&))); 00872 } 00873 00874 if (d->mbUser) { 00875 d->mpDialog->setCustomLocation(QFileInfo(d->mpLoader->iconPath(d->mIcon, d->mGroup, true) ).absolutePath()); 00876 } 00877 } 00878 00879 void KIconButton::setIcon(const QIcon& icon) 00880 { 00881 QPushButton::setIcon(icon); 00882 } 00883 00884 void KIconButton::resetIcon() 00885 { 00886 d->mIcon.clear(); 00887 setIcon(QIcon()); 00888 } 00889 00890 const QString &KIconButton::icon() const 00891 { 00892 return d->mIcon; 00893 } 00894 00895 void KIconButton::KIconButtonPrivate::_k_slotChangeIcon() 00896 { 00897 if (!mpDialog) 00898 { 00899 mpDialog = new KIconDialog(mpLoader, q); 00900 connect(mpDialog, SIGNAL(newIconName(const QString&)), q, SLOT(_k_newIconName(const QString&))); 00901 } 00902 00903 mpDialog->setup(mGroup, mContext, m_bStrictIconSize, iconSize, mbUser); 00904 mpDialog->showDialog(); 00905 } 00906 00907 void KIconButton::KIconButtonPrivate::_k_newIconName(const QString& name) 00908 { 00909 if (name.isEmpty()) 00910 return; 00911 00912 q->setIcon(KIcon(name)); 00913 mIcon = name; 00914 00915 if (mbUser) { 00916 mpDialog->setCustomLocation(QFileInfo(mpLoader->iconPath(mIcon, mGroup, true)).absolutePath()); 00917 } 00918 00919 emit q->iconChanged(name); 00920 } 00921 00922 #include "kicondialog.moc"
KDE 4.6 API Reference