kicondialog.cpp Source File (kio Library)

| # kio Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# kicondialog.cpp

    00001 /* vi: ts=8 sts=4 sw=4
    00002  *
    00003  * $Id: kicondialog.cpp,v 1.30 2002/05/06 02:16:06 nhasan 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->setFixedSize(QSize(mpCombo->width(), mpCombo->height()+6));
    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   accept();
    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 QString KIconDialog::getIcon(KIcon::Group group, KIcon::Context context,
    00381                              bool strictIconSize, int iconSize, bool user,
    00382                              QWidget *parent, const QString &caption)
    00383 {
    00384     KIconDialog dlg(parent, "icon dialog");
    00385     dlg.setup( group, context, strictIconSize, iconSize, user );
    00386     if (!caption.isNull())
    00387         dlg.setCaption(caption);
    00388
    00389     return dlg.openDialog();
    00390 }
    00391
    00392 void KIconDialog::slotButtonClicked(int id)
    00393 {
    00394     QString file;
    00395
    00396     switch (id)
    00397     {
    00398     case 0:
    00399         if(mType!=0)
    00400         {
    00401             mType = 0;
    00402             mpBrowseBut->setEnabled(false);
    00403             mpCombo->setEnabled(true);
    00404             showIcons();
    00405         }
    00406         break;
    00407
    00408     case 1:
    00409         if(mType!=1)
    00410         {
    00411             mType = 1;
    00412             mpBrowseBut->setEnabled(true);
    00413             mpCombo->setEnabled(false);
    00414             showIcons();
    00415         }
    00416         break;
    00417     case 2:
    00418         file = KFileDialog::getOpenFileName(QString::null,
    00419                 i18n("*.png *.xpm|Icon Files (*.png *.xpm)"), this);
    00420         if (!file.isEmpty())
    00421         {
    00422             d->custom = file;
    00423             if ( mType == 1 )
    00424               d->customLocation = QFileInfo( file ).dirPath( true );
    00425             accept();
    00426         }
    00427         break;
    00428     }
    00429 }
    00430
    00431 void KIconDialog::slotContext(int id)
    00432 {
    00433     mContext = static_cast<KIcon::Context>(id+1);
    00434     showIcons();
    00435 }
    00436
    00437 void KIconDialog::slotStartLoading(int steps)
    00438 {
    00439     if (steps < 10)
    00440         mpProgress->hide();
    00441     else
    00442     {
    00443         mpProgress->setTotalSteps(steps);
    00444         mpProgress->setProgress(0);
    00445         mpProgress->show();
    00446     }
    00447 }
    00448
    00449 void KIconDialog::slotProgress(int p)
    00450 {
    00451     mpProgress->setProgress(p);
    00452     mpProgress->repaint();
    00453 }
    00454
    00455 void KIconDialog::slotFinished()
    00456 {
    00457     mpProgress->hide();
    00458 }
    00459
    00460 class KIconButton::KIconButtonPrivate
    00461 {
    00462   public:
    00463     KIconButtonPrivate() {
    00464         m_bStrictIconSize = false;
    00465         iconSize = 0; // let KIconLoader choose the default
    00466     }
    00467     ~KIconButtonPrivate() {}
    00468     bool m_bStrictIconSize;
    00469     int iconSize;
    00470 };
    00471
    00472
    00473 /*
    00474  * KIconButton: A "choose icon" pushbutton.
    00475  */
    00476
    00477 KIconButton::KIconButton(QWidget *parent, const char *name)
    00478     : QPushButton(parent, name)
    00479 {
    00480     d = new KIconButtonPrivate;
    00481     // arbitrary
    00482     mGroup = KIcon::Desktop;
    00483     mContext = KIcon::Application;
    00484     mbUser = false;
    00485
    00486     mpLoader = KGlobal::iconLoader();
    00487     mpDialog = 0L;
    00488     connect(this, SIGNAL(clicked()), SLOT(slotChangeIcon()));
    00489 }
    00490
    00491 KIconButton::KIconButton(KIconLoader *loader,
    00492         QWidget *parent, const char *name)
    00493     : QPushButton(parent, name)
    00494 {
    00495     d = new KIconButtonPrivate;
    00496     mGroup = KIcon::Desktop;
    00497     mContext = KIcon::Application;
    00498     mbUser = false;
    00499
    00500     mpLoader = loader;
    00501     mpDialog = 0L;
    00502     connect(this, SIGNAL(clicked()), SLOT(slotChangeIcon()));
    00503 }
    00504
    00505 KIconButton::~KIconButton()
    00506 {
    00507     delete mpDialog;
    00508     delete d;
    00509 }
    00510
    00511 void KIconButton::setStrictIconSize(bool b)
    00512 {
    00513     d->m_bStrictIconSize=b;
    00514 }
    00515
    00516 bool KIconButton::strictIconSize() const
    00517 {
    00518     return d->m_bStrictIconSize;
    00519 }
    00520
    00521 void KIconButton::setIconSize( int size )
    00522 {
    00523     d->iconSize = size;
    00524 }
    00525
    00526 int KIconButton::iconSize() const
    00527 {
    00528     return d->iconSize;
    00529 }
    00530
    00531 void KIconButton::setIconType(KIcon::Group group, KIcon::Context context, bool user)
    00532 {
    00533     mGroup = group;
    00534     mContext = context;
    00535     mbUser = user;
    00536 }
    00537
    00538 void KIconButton::setIcon(const QString& icon)
    00539 {
    00540     mIcon = icon;
    00541     setPixmap(mpLoader->loadIcon(mIcon, mGroup, d->iconSize));
    00542     if (!mpDialog)
    00543         mpDialog = new KIconDialog(mpLoader, this);
    00544     if ( mbUser )
    00545       mpDialog->setCustomLocation( QFileInfo( mpLoader->iconPath(mIcon, mGroup, true) ).dirPath( true ) );
    00546 }
    00547
    00548 void KIconButton::resetIcon()
    00549 {
    00550     mIcon = QString::null;
    00551     setPixmap(QPixmap());
    00552 }
    00553
    00554 void KIconButton::slotChangeIcon()
    00555 {
    00556     if (!mpDialog)
    00557         mpDialog = new KIconDialog(mpLoader, this);
    00558
    00559     mpDialog->setup( mGroup, mContext, d->m_bStrictIconSize, d->iconSize,
    00560                      mbUser );
    00561
    00562     QString name = mpDialog->openDialog();
    00563     if (name.isEmpty())
    00564         return;
    00565     QPixmap pm = mpLoader->loadIcon(name, mGroup, d->iconSize);
    00566     setPixmap(pm);
    00567     mIcon = name;
    00568     if ( mbUser )
    00569       mpDialog->setCustomLocation( QFileInfo( mpLoader->iconPath(mIcon, mGroup, true) ).dirPath( true ) );
    00570     emit iconChanged(name);
    00571 }
    00572
    00573 void KIconCanvas::virtual_hook( int id, void* data )
    00574 { KIconView::virtual_hook( id, data ); }
    00575
    00576 void KIconDialog::virtual_hook( int id, void* data )
    00577 { KDialogBase::virtual_hook( id, data ); }
    00578
    00579 #include "kicondialog.moc"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:13:36 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001