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.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed May 12 09:06:15 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003