• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.9.5 API Reference
  • KDE Home
  • Contact Us
 

KFile

kfileplacesview.cpp
Go to the documentation of this file.
00001 /*  This file is part of the KDE project
00002     Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
00003     Copyright (C) 2008 Rafael Fernández López <ereslibre@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License version 2 as published by the Free Software Foundation.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 
00019 */
00020 
00021 #include "kfileplacesview.h"
00022 #include "kfileplacesview_p.h"
00023 
00024 #include <QtCore/QTimeLine>
00025 #include <QtCore/QTimer>
00026 #include <QtGui/QPainter>
00027 #include <QtGui/QAbstractItemDelegate>
00028 #include <QtGui/QKeyEvent>
00029 #include <QtGui/QApplication>
00030 #include <QtGui/QScrollBar>
00031 
00032 #include <kdebug.h>
00033 
00034 #include <kmenu.h>
00035 #include <kcomponentdata.h>
00036 #include <kdirnotify.h>
00037 #include <kglobalsettings.h>
00038 #include <kiconloader.h>
00039 #include <klocale.h>
00040 #include <kmessagebox.h>
00041 #include <knotification.h>
00042 #include <kio/job.h>
00043 #include <kio/jobuidelegate.h>
00044 #include <kjob.h>
00045 #include <kcapacitybar.h>
00046 #include <kdiskfreespaceinfo.h>
00047 #include <solid/storageaccess.h>
00048 #include <solid/storagedrive.h>
00049 #include <solid/storagevolume.h>
00050 #include <solid/opticaldrive.h>
00051 #include <solid/opticaldisc.h>
00052 
00053 #include "kfileplaceeditdialog.h"
00054 #include "kfileplacesmodel.h"
00055 
00056 #define LATERAL_MARGIN 4
00057 #define CAPACITYBAR_HEIGHT 6
00058 
00059 class KFilePlacesViewDelegate : public QAbstractItemDelegate
00060 {
00061 public:
00062     KFilePlacesViewDelegate(KFilePlacesView *parent);
00063     virtual ~KFilePlacesViewDelegate();
00064     virtual QSize sizeHint(const QStyleOptionViewItem &option,
00065                            const QModelIndex &index) const;
00066     virtual void paint(QPainter *painter,
00067                        const QStyleOptionViewItem &option,
00068                        const QModelIndex &index) const;
00069 
00070     int iconSize() const;
00071     void setIconSize(int newSize);
00072 
00073     void addAppearingItem(const QModelIndex &index);
00074     void setAppearingItemProgress(qreal value);
00075     void addDisappearingItem(const QModelIndex &index);
00076     void setDisappearingItemProgress(qreal value);
00077 
00078     void setShowHoverIndication(bool show);
00079 
00080     void addFadeAnimation(const QModelIndex &index, QTimeLine *timeLine);
00081     void removeFadeAnimation(const QModelIndex &index);
00082     QModelIndex indexForFadeAnimation(QTimeLine *timeLine) const;
00083     QTimeLine *fadeAnimationForIndex(const QModelIndex &index) const;
00084 
00085     qreal contentsOpacity(const QModelIndex &index) const;
00086 
00087 private:
00088     KFilePlacesView *m_view;
00089     int m_iconSize;
00090 
00091     QList<QPersistentModelIndex> m_appearingItems;
00092     int m_appearingIconSize;
00093     qreal m_appearingOpacity;
00094 
00095     QList<QPersistentModelIndex> m_disappearingItems;
00096     int m_disappearingIconSize;
00097     qreal m_disappearingOpacity;
00098 
00099     bool m_showHoverIndication;
00100 
00101     QMap<QPersistentModelIndex, QTimeLine*> m_timeLineMap;
00102     QMap<QTimeLine*, QPersistentModelIndex> m_timeLineInverseMap;
00103 };
00104 
00105 KFilePlacesViewDelegate::KFilePlacesViewDelegate(KFilePlacesView *parent) :
00106     QAbstractItemDelegate(parent),
00107     m_view(parent),
00108     m_iconSize(48),
00109     m_appearingIconSize(0),
00110     m_appearingOpacity(0.0),
00111     m_disappearingIconSize(0),
00112     m_disappearingOpacity(0.0),
00113     m_showHoverIndication(true)
00114 {
00115 }
00116 
00117 KFilePlacesViewDelegate::~KFilePlacesViewDelegate()
00118 {
00119 }
00120 
00121 QSize KFilePlacesViewDelegate::sizeHint(const QStyleOptionViewItem &option,
00122                                         const QModelIndex &index) const
00123 {
00124     int iconSize = m_iconSize;
00125     if (m_appearingItems.contains(index)) {
00126         iconSize = m_appearingIconSize;
00127     } else if (m_disappearingItems.contains(index)) {
00128         iconSize = m_disappearingIconSize;
00129     }
00130 
00131     const KFilePlacesModel *filePlacesModel = static_cast<const KFilePlacesModel*>(index.model());
00132     Solid::Device device = filePlacesModel->deviceForIndex(index);
00133 
00134     return QSize(option.rect.width(), option.fontMetrics.height() / 2 + qMax(iconSize, option.fontMetrics.height()));
00135 }
00136 
00137 void KFilePlacesViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
00138 {
00139     painter->save();
00140 
00141     if (m_appearingItems.contains(index)) {
00142         painter->setOpacity(m_appearingOpacity);
00143     } else if (m_disappearingItems.contains(index)) {
00144         painter->setOpacity(m_disappearingOpacity);
00145     }
00146 
00147     QStyleOptionViewItemV4 opt = option;
00148     if (!m_showHoverIndication) {
00149         opt.state &= ~QStyle::State_MouseOver;
00150     }
00151     QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter);
00152     const KFilePlacesModel *placesModel = static_cast<const KFilePlacesModel*>(index.model());
00153 
00154     bool isLTR = option.direction == Qt::LeftToRight;
00155 
00156     QIcon icon = index.model()->data(index, Qt::DecorationRole).value<QIcon>();
00157     QPixmap pm = icon.pixmap(m_iconSize, m_iconSize);
00158     QPoint point(isLTR ? option.rect.left() + LATERAL_MARGIN
00159                        : option.rect.right() - LATERAL_MARGIN - m_iconSize, option.rect.top() + (option.rect.height() - m_iconSize) / 2);
00160     painter->drawPixmap(point, pm);
00161 
00162     if (option.state & QStyle::State_Selected) {
00163         QPalette::ColorGroup cg = QPalette::Active;
00164         if (!(option.state & QStyle::State_Enabled)) {
00165             cg = QPalette::Disabled;
00166         } else if (!(option.state & QStyle::State_Active)) {
00167             cg = QPalette::Inactive;
00168         }
00169         painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
00170     }
00171 
00172     QRect rectText;
00173 
00174     const KUrl url = placesModel->url(index);
00175     bool drawCapacityBar = false;
00176     if (url.isLocalFile()) {
00177         const QString mountPointPath = placesModel->url(index).toLocalFile();
00178         const KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(mountPointPath);
00179         drawCapacityBar = info.size() != 0 &&
00180                 placesModel->data(index, KFilePlacesModel::CapacityBarRecommendedRole).toBool();
00181 
00182         if (drawCapacityBar && contentsOpacity(index) > 0)
00183         {
00184             painter->save();
00185             painter->setOpacity(painter->opacity() * contentsOpacity(index));
00186 
00187             int height = option.fontMetrics.height() + CAPACITYBAR_HEIGHT;
00188             rectText = QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + option.rect.left()
00189                                    : 0, option.rect.top() + (option.rect.height() / 2 - height / 2), option.rect.width() - m_iconSize - LATERAL_MARGIN * 2, option.fontMetrics.height());
00190             painter->drawText(rectText, Qt::AlignLeft | Qt::AlignTop, option.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width()));
00191             QRect capacityRect(isLTR ? rectText.x() : LATERAL_MARGIN, rectText.bottom() - 1, rectText.width() - LATERAL_MARGIN, CAPACITYBAR_HEIGHT);
00192             KCapacityBar capacityBar(KCapacityBar::DrawTextInline);
00193             capacityBar.setValue((info.used() * 100) / info.size());
00194             capacityBar.drawCapacityBar(painter, capacityRect);
00195 
00196             painter->restore();
00197 
00198             painter->save();
00199             painter->setOpacity(painter->opacity() * (1 - contentsOpacity(index)));
00200         }
00201     }
00202 
00203     rectText = QRect(isLTR ? m_iconSize + LATERAL_MARGIN * 2 + option.rect.left()
00204                            : 0, option.rect.top(), option.rect.width() - m_iconSize - LATERAL_MARGIN * 2, option.rect.height());
00205     painter->drawText(rectText, Qt::AlignLeft | Qt::AlignVCenter, option.fontMetrics.elidedText(index.model()->data(index).toString(), Qt::ElideRight, rectText.width()));
00206 
00207     if (drawCapacityBar && contentsOpacity(index) > 0) {
00208         painter->restore();
00209     }
00210 
00211     painter->restore();
00212 }
00213 
00214 int KFilePlacesViewDelegate::iconSize() const
00215 {
00216     return m_iconSize;
00217 }
00218 
00219 void KFilePlacesViewDelegate::setIconSize(int newSize)
00220 {
00221     m_iconSize = newSize;
00222 }
00223 
00224 void KFilePlacesViewDelegate::addAppearingItem(const QModelIndex &index)
00225 {
00226     m_appearingItems << index;
00227 }
00228 
00229 void KFilePlacesViewDelegate::setAppearingItemProgress(qreal value)
00230 {
00231     if (value<=0.25) {
00232         m_appearingOpacity = 0.0;
00233         m_appearingIconSize = iconSize()*value*4;
00234 
00235         if (m_appearingIconSize>=m_iconSize) {
00236             m_appearingIconSize = m_iconSize;
00237         }
00238     } else {
00239         m_appearingIconSize = m_iconSize;
00240         m_appearingOpacity = (value-0.25)*4/3;
00241 
00242         if (value>=1.0) {
00243             m_appearingItems.clear();
00244         }
00245     }
00246 }
00247 
00248 void KFilePlacesViewDelegate::addDisappearingItem(const QModelIndex &index)
00249 {
00250     m_disappearingItems << index;
00251 }
00252 
00253 void KFilePlacesViewDelegate::setDisappearingItemProgress(qreal value)
00254 {
00255     value = 1.0 - value;
00256 
00257     if (value<=0.25) {
00258         m_disappearingOpacity = 0.0;
00259         m_disappearingIconSize = iconSize()*value*4;
00260 
00261         if (m_disappearingIconSize>=m_iconSize) {
00262             m_disappearingIconSize = m_iconSize;
00263         }
00264 
00265         if (value<=0.0) {
00266             m_disappearingItems.clear();
00267         }
00268     } else {
00269         m_disappearingIconSize = m_iconSize;
00270         m_disappearingOpacity = (value-0.25)*4/3;
00271     }
00272 }
00273 
00274 void KFilePlacesViewDelegate::setShowHoverIndication(bool show)
00275 {
00276     m_showHoverIndication = show;
00277 }
00278 
00279 void KFilePlacesViewDelegate::addFadeAnimation(const QModelIndex &index, QTimeLine *timeLine)
00280 {
00281     m_timeLineMap.insert(index, timeLine);
00282     m_timeLineInverseMap.insert(timeLine, index);
00283 }
00284 
00285 void KFilePlacesViewDelegate::removeFadeAnimation(const QModelIndex &index)
00286 {
00287     QTimeLine *timeLine = m_timeLineMap.value(index, 0);
00288     m_timeLineMap.remove(index);
00289     m_timeLineInverseMap.remove(timeLine);
00290 }
00291 
00292 QModelIndex KFilePlacesViewDelegate::indexForFadeAnimation(QTimeLine *timeLine) const
00293 {
00294     return m_timeLineInverseMap.value(timeLine, QModelIndex());
00295 }
00296 
00297 QTimeLine *KFilePlacesViewDelegate::fadeAnimationForIndex(const QModelIndex &index) const
00298 {
00299     return m_timeLineMap.value(index, 0);
00300 }
00301 
00302 qreal KFilePlacesViewDelegate::contentsOpacity(const QModelIndex &index) const
00303 {
00304     QTimeLine *timeLine = fadeAnimationForIndex(index);
00305     if (timeLine) {
00306         return timeLine->currentValue();
00307     }
00308     return 0;
00309 }
00310 
00311 class KFilePlacesView::Private
00312 {
00313 public:
00314     Private(KFilePlacesView *parent) : q(parent), watcher(new KFilePlacesEventWatcher(q)) { }
00315 
00316     enum FadeType {
00317         FadeIn = 0,
00318         FadeOut
00319     };
00320 
00321     KFilePlacesView * const q;
00322 
00323     KUrl currentUrl;
00324     bool autoResizeItems;
00325     bool showAll;
00326     bool smoothItemResizing;
00327     bool dropOnPlace;
00328     bool dragging;
00329     Solid::StorageAccess *lastClickedStorage;
00330     QPersistentModelIndex lastClickedIndex;
00331 
00332     QRect dropRect;
00333 
00334     void setCurrentIndex(const QModelIndex &index);
00335     void adaptItemSize();
00336     void updateHiddenRows();
00337     bool insertAbove(const QRect &itemRect, const QPoint &pos) const;
00338     bool insertBelow(const QRect &itemRect, const QPoint &pos) const;
00339     int insertIndicatorHeight(int itemHeight) const;
00340     void fadeCapacityBar(const QModelIndex &index, FadeType fadeType);
00341 
00342     void _k_placeClicked(const QModelIndex &index);
00343     void _k_placeEntered(const QModelIndex &index);
00344     void _k_placeLeft(const QModelIndex &index);
00345     void _k_storageSetupDone(const QModelIndex &index, bool success);
00346     void _k_adaptItemsUpdate(qreal value);
00347     void _k_itemAppearUpdate(qreal value);
00348     void _k_itemDisappearUpdate(qreal value);
00349     void _k_enableSmoothItemResizing();
00350     void _k_trashUpdated(KJob *job);
00351     void _k_capacityBarFadeValueChanged();
00352     void _k_triggerDevicePolling();
00353 
00354     QTimeLine adaptItemsTimeline;
00355     int oldSize, endSize;
00356 
00357     QTimeLine itemAppearTimeline;
00358     QTimeLine itemDisappearTimeline;
00359 
00360     KFilePlacesEventWatcher *const watcher;
00361     KFilePlacesViewDelegate *delegate;
00362     QTimer pollDevices;
00363     int pollingRequestCount;
00364 };
00365 
00366 KFilePlacesView::KFilePlacesView(QWidget *parent)
00367     : QListView(parent), d(new Private(this))
00368 {
00369     d->showAll = false;
00370     d->smoothItemResizing = false;
00371     d->dropOnPlace = false;
00372     d->autoResizeItems = true;
00373     d->dragging = false;
00374     d->lastClickedStorage = 0;
00375     d->pollingRequestCount = 0;
00376     d->delegate = new KFilePlacesViewDelegate(this);
00377 
00378     setSelectionRectVisible(false);
00379     setSelectionMode(SingleSelection);
00380 
00381     setDragEnabled(true);
00382     setAcceptDrops(true);
00383     setMouseTracking(true);
00384     setDropIndicatorShown(false);
00385     setFrameStyle(QFrame::NoFrame);
00386 
00387     setResizeMode(Adjust);
00388     setItemDelegate(d->delegate);
00389 
00390     QPalette palette = viewport()->palette();
00391     palette.setColor(viewport()->backgroundRole(), Qt::transparent);
00392     palette.setColor(viewport()->foregroundRole(), palette.color(QPalette::WindowText));
00393     viewport()->setPalette(palette);
00394 
00395     connect(this, SIGNAL(clicked(QModelIndex)),
00396             this, SLOT(_k_placeClicked(QModelIndex)));
00397     // Note: Don't connect to the activated() signal, as the behavior when it is
00398     // committed depends on the used widget style. The click behavior of
00399     // KFilePlacesView should be style independent.
00400 
00401     connect(&d->adaptItemsTimeline, SIGNAL(valueChanged(qreal)),
00402             this, SLOT(_k_adaptItemsUpdate(qreal)));
00403     d->adaptItemsTimeline.setDuration(500);
00404     d->adaptItemsTimeline.setUpdateInterval(5);
00405     d->adaptItemsTimeline.setCurveShape(QTimeLine::EaseInOutCurve);
00406 
00407     connect(&d->itemAppearTimeline, SIGNAL(valueChanged(qreal)),
00408             this, SLOT(_k_itemAppearUpdate(qreal)));
00409     d->itemAppearTimeline.setDuration(500);
00410     d->itemAppearTimeline.setUpdateInterval(5);
00411     d->itemAppearTimeline.setCurveShape(QTimeLine::EaseInOutCurve);
00412 
00413     connect(&d->itemDisappearTimeline, SIGNAL(valueChanged(qreal)),
00414             this, SLOT(_k_itemDisappearUpdate(qreal)));
00415     d->itemDisappearTimeline.setDuration(500);
00416     d->itemDisappearTimeline.setUpdateInterval(5);
00417     d->itemDisappearTimeline.setCurveShape(QTimeLine::EaseInOutCurve);
00418 
00419     viewport()->installEventFilter(d->watcher);
00420     connect(d->watcher, SIGNAL(entryEntered(QModelIndex)),
00421             this, SLOT(_k_placeEntered(QModelIndex)));
00422     connect(d->watcher, SIGNAL(entryLeft(QModelIndex)),
00423             this, SLOT(_k_placeLeft(QModelIndex)));
00424 
00425     d->pollDevices.setInterval(5000);
00426     connect(&d->pollDevices, SIGNAL(timeout()), this, SLOT(_k_triggerDevicePolling()));
00427 
00428     // FIXME: this is necessary to avoid flashes of black with some widget styles.
00429     // could be a bug in Qt (e.g. QAbstractScrollArea) or KFilePlacesView, but has not
00430     // yet been tracked down yet. until then, this works and is harmlessly enough.
00431     // in fact, some QStyle (Oxygen, Skulpture, others?) do this already internally.
00432     // See br #242358 for more information
00433     verticalScrollBar()->setAttribute(Qt::WA_OpaquePaintEvent, false);
00434 }
00435 
00436 KFilePlacesView::~KFilePlacesView()
00437 {
00438     delete d;
00439 }
00440 
00441 void KFilePlacesView::setDropOnPlaceEnabled(bool enabled)
00442 {
00443     d->dropOnPlace = enabled;
00444 }
00445 
00446 bool KFilePlacesView::isDropOnPlaceEnabled() const
00447 {
00448     return d->dropOnPlace;
00449 }
00450 
00451 void KFilePlacesView::setAutoResizeItemsEnabled(bool enabled)
00452 {
00453     d->autoResizeItems = enabled;
00454 }
00455 
00456 bool KFilePlacesView::isAutoResizeItemsEnabled() const
00457 {
00458     return d->autoResizeItems;
00459 }
00460 
00461 void KFilePlacesView::setUrl(const KUrl &url)
00462 {
00463     KUrl oldUrl = d->currentUrl;
00464     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(model());
00465 
00466     if (placesModel==0) return;
00467 
00468     QModelIndex index = placesModel->closestItem(url);
00469     QModelIndex current = selectionModel()->currentIndex();
00470 
00471     if (index.isValid()) {
00472         if (current!=index && placesModel->isHidden(current) && !d->showAll) {
00473             KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00474             delegate->addDisappearingItem(current);
00475 
00476             if (d->itemDisappearTimeline.state()!=QTimeLine::Running) {
00477                 delegate->setDisappearingItemProgress(0.0);
00478                 d->itemDisappearTimeline.start();
00479             }
00480         }
00481 
00482         if (current!=index && placesModel->isHidden(index) && !d->showAll) {
00483             KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00484             delegate->addAppearingItem(index);
00485 
00486             if (d->itemAppearTimeline.state()!=QTimeLine::Running) {
00487                 delegate->setAppearingItemProgress(0.0);
00488                 d->itemAppearTimeline.start();
00489             }
00490 
00491             setRowHidden(index.row(), false);
00492         }
00493 
00494         d->currentUrl = url;
00495         selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
00496     } else {
00497         d->currentUrl = KUrl();
00498         selectionModel()->clear();
00499     }
00500 
00501     if (!current.isValid()) {
00502         d->updateHiddenRows();
00503     }
00504 }
00505 
00506 void KFilePlacesView::setShowAll(bool showAll)
00507 {
00508     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(model());
00509 
00510     if (placesModel==0) return;
00511 
00512     d->showAll = showAll;
00513 
00514     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00515 
00516     int rowCount = placesModel->rowCount();
00517     QModelIndex current = placesModel->closestItem(d->currentUrl);
00518 
00519     if (showAll) {
00520         d->updateHiddenRows();
00521 
00522         for (int i=0; i<rowCount; ++i) {
00523             QModelIndex index = placesModel->index(i, 0);
00524             if (index!=current && placesModel->isHidden(index)) {
00525                 delegate->addAppearingItem(index);
00526             }
00527         }
00528 
00529         if (d->itemAppearTimeline.state()!=QTimeLine::Running) {
00530             delegate->setAppearingItemProgress(0.0);
00531             d->itemAppearTimeline.start();
00532         }
00533     } else {
00534         for (int i=0; i<rowCount; ++i) {
00535             QModelIndex index = placesModel->index(i, 0);
00536             if (index!=current && placesModel->isHidden(index)) {
00537                 delegate->addDisappearingItem(index);
00538             }
00539         }
00540 
00541         if (d->itemDisappearTimeline.state()!=QTimeLine::Running) {
00542             delegate->setDisappearingItemProgress(0.0);
00543             d->itemDisappearTimeline.start();
00544         }
00545     }
00546 }
00547 
00548 void KFilePlacesView::keyPressEvent(QKeyEvent *event)
00549 {
00550     QListView::keyPressEvent(event);
00551     if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Enter)) {
00552         d->_k_placeClicked(currentIndex());
00553     }
00554 }
00555 
00556 void KFilePlacesView::contextMenuEvent(QContextMenuEvent *event)
00557 {
00558     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(model());
00559     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00560 
00561     if (placesModel==0) return;
00562 
00563     QModelIndex index = indexAt(event->pos());
00564     QString label = placesModel->text(index).replace('&',"&&");
00565 
00566     KMenu menu;
00567 
00568     QAction *edit = 0;
00569     QAction *hide = 0;
00570     QAction *emptyTrash = 0;
00571     QAction *eject = 0;
00572     QAction *teardown = 0;
00573     QAction *add = 0;
00574     QAction *mainSeparator = 0;
00575 
00576     if (index.isValid()) {
00577         if (!placesModel->isDevice(index)) {
00578             if (placesModel->url(index) == KUrl("trash:/")) {
00579                 emptyTrash = menu.addAction(KIcon("trash-empty"), i18nc("@action:inmenu", "Empty Trash"));
00580                 KConfig trashConfig("trashrc", KConfig::SimpleConfig);
00581                 emptyTrash->setEnabled(!trashConfig.group("Status").readEntry("Empty", true));
00582                 menu.addSeparator();
00583             }
00584             add = menu.addAction(KIcon("document-new"), i18n("Add Entry..."));
00585             mainSeparator = menu.addSeparator();
00586             edit = menu.addAction(KIcon("document-properties"), i18n("&Edit Entry '%1'...", label));
00587         } else {
00588             eject = placesModel->ejectActionForIndex(index);
00589             if (eject!=0) {
00590                 eject->setParent(&menu);
00591                 menu.addAction(eject);
00592             }
00593 
00594             teardown = placesModel->teardownActionForIndex(index);
00595             if (teardown!=0) {
00596                 teardown->setParent(&menu);
00597                 menu.addAction(teardown);
00598             }
00599 
00600             if (teardown!=0 || eject!=0) {
00601                 mainSeparator = menu.addSeparator();
00602             }
00603         }
00604         if (add == 0) {
00605             add = menu.addAction(KIcon("document-new"), i18n("Add Entry..."));
00606         }
00607 
00608         hide = menu.addAction(i18n("&Hide Entry '%1'", label));
00609         hide->setCheckable(true);
00610         hide->setChecked(placesModel->isHidden(index));
00611     } else {
00612         add = menu.addAction(KIcon("document-new"), i18n("Add Entry..."));
00613     }
00614 
00615     QAction *showAll = 0;
00616     if (placesModel->hiddenCount()>0) {
00617         showAll = new QAction(i18n("&Show All Entries"), &menu);
00618         showAll->setCheckable(true);
00619         showAll->setChecked(d->showAll);
00620         if (mainSeparator == 0) {
00621             mainSeparator = menu.addSeparator();
00622         }
00623         menu.insertAction(mainSeparator, showAll);
00624     }
00625 
00626     QAction* remove = 0;
00627     if (index.isValid() && !placesModel->isDevice(index)) {
00628         remove = menu.addAction( KIcon("edit-delete"), i18n("&Remove Entry '%1'", label));
00629     }
00630 
00631     menu.addActions(actions());
00632 
00633     if (menu.isEmpty()) {
00634         return;
00635     }
00636 
00637     QAction *result = menu.exec(event->globalPos());
00638 
00639     if (emptyTrash != 0 && result == emptyTrash) {
00640         const QString text = i18nc("@info", "Do you really want to empty the Trash? All items will be deleted.");
00641         const bool del = KMessageBox::warningContinueCancel(window(),
00642                                                             text,
00643                                                             QString(),
00644                                                             KGuiItem(i18nc("@action:button", "Empty Trash"),
00645                                                                      KIcon("user-trash"))
00646                                                            ) == KMessageBox::Continue;
00647         if (del) {
00648             QByteArray packedArgs;
00649             QDataStream stream(&packedArgs, QIODevice::WriteOnly);
00650             stream << int(1);
00651             KIO::Job *job = KIO::special(KUrl("trash:/"), packedArgs);
00652             KNotification::event("Trash: emptied", QString() , QPixmap() , 0, KNotification::DefaultEvent);
00653             job->ui()->setWindow(parentWidget());
00654             connect(job, SIGNAL(result(KJob*)), SLOT(_k_trashUpdated(KJob*)));
00655         }
00656     } else if (edit != 0 && result == edit) {
00657         KBookmark bookmark = placesModel->bookmarkForIndex(index);
00658         KUrl url = bookmark.url();
00659         QString label = bookmark.text();
00660         QString iconName = bookmark.icon();
00661         bool appLocal = !bookmark.metaDataItem("OnlyInApp").isEmpty();
00662 
00663         if (KFilePlaceEditDialog::getInformation(true, url, label,
00664                                                  iconName, false, appLocal, 64, this))
00665         {
00666             QString appName;
00667             if (appLocal) appName = KGlobal::mainComponent().componentName();
00668 
00669             placesModel->editPlace(index, label, url, iconName, appName);
00670         }
00671 
00672     } else if (remove != 0 && result == remove) {
00673         placesModel->removePlace(index);
00674     } else if (hide != 0 && result == hide) {
00675         placesModel->setPlaceHidden(index, hide->isChecked());
00676         QModelIndex current = placesModel->closestItem(d->currentUrl);
00677 
00678         if (index!=current && !d->showAll && hide->isChecked()) {
00679             delegate->addDisappearingItem(index);
00680 
00681             if (d->itemDisappearTimeline.state()!=QTimeLine::Running) {
00682                 delegate->setDisappearingItemProgress(0.0);
00683                 d->itemDisappearTimeline.start();
00684             }
00685         }
00686     } else if (showAll != 0 && result == showAll) {
00687         setShowAll(showAll->isChecked());
00688     } else if (teardown != 0 && result == teardown) {
00689         placesModel->requestTeardown(index);
00690     } else if (eject != 0 && result == eject) {
00691         placesModel->requestEject(index);
00692     } else if (add != 0 && result == add) {
00693         KUrl url = d->currentUrl;
00694         QString label;
00695         QString iconName = "folder";
00696         bool appLocal = true;
00697         if (KFilePlaceEditDialog::getInformation(true, url, label,
00698                                                  iconName, true, appLocal, 64, this))
00699         {
00700             QString appName;
00701             if (appLocal) appName = KGlobal::mainComponent().componentName();
00702 
00703             placesModel->addPlace(label, url, iconName, appName, index);
00704         }
00705     }
00706 
00707     index = placesModel->closestItem(d->currentUrl);
00708     selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
00709 }
00710 
00711 void KFilePlacesView::resizeEvent(QResizeEvent *event)
00712 {
00713     QListView::resizeEvent(event);
00714     d->adaptItemSize();
00715 }
00716 
00717 void KFilePlacesView::showEvent(QShowEvent *event)
00718 {
00719     QListView::showEvent(event);
00720     QTimer::singleShot(100, this, SLOT(_k_enableSmoothItemResizing()));
00721 }
00722 
00723 void KFilePlacesView::hideEvent(QHideEvent *event)
00724 {
00725     QListView::hideEvent(event);
00726     d->smoothItemResizing = false;
00727 }
00728 
00729 void KFilePlacesView::dragEnterEvent(QDragEnterEvent *event)
00730 {
00731     QListView::dragEnterEvent(event);
00732     d->dragging = true;
00733 
00734     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00735     delegate->setShowHoverIndication(false);
00736 
00737     d->dropRect = QRect();
00738 }
00739 
00740 void KFilePlacesView::dragLeaveEvent(QDragLeaveEvent *event)
00741 {
00742     QListView::dragLeaveEvent(event);
00743     d->dragging = false;
00744 
00745     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00746     delegate->setShowHoverIndication(true);
00747 
00748     setDirtyRegion(d->dropRect);
00749 }
00750 
00751 void KFilePlacesView::dragMoveEvent(QDragMoveEvent *event)
00752 {
00753     QListView::dragMoveEvent(event);
00754 
00755     // update the drop indicator
00756     const QPoint pos = event->pos();
00757     const QModelIndex index = indexAt(pos);
00758     setDirtyRegion(d->dropRect);
00759     if (index.isValid()) {
00760         const QRect rect = visualRect(index);
00761         const int gap = d->insertIndicatorHeight(rect.height());
00762         if (d->insertAbove(rect, pos)) {
00763             // indicate that the item will be inserted above the current place
00764             d->dropRect = QRect(rect.left(), rect.top() - gap / 2,
00765                                 rect.width(), gap);
00766         } else if (d->insertBelow(rect, pos)) {
00767             // indicate that the item will be inserted below the current place
00768             d->dropRect = QRect(rect.left(), rect.bottom() + 1 -  gap / 2,
00769                                 rect.width(), gap);
00770         } else {
00771             // indicate that the item be dropped above the current place
00772             d->dropRect = rect;
00773         }
00774     }
00775 
00776     setDirtyRegion(d->dropRect);
00777 }
00778 
00779 void KFilePlacesView::dropEvent(QDropEvent *event)
00780 {
00781     const QPoint pos = event->pos();
00782     const QModelIndex index = indexAt(pos);
00783     if (index.isValid()) {
00784         const QRect rect = visualRect(index);
00785         if (!d->insertAbove(rect, pos) && !d->insertBelow(rect, pos)) {
00786             KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(model());
00787             Q_ASSERT(placesModel != 0);
00788             emit urlsDropped(placesModel->url(index), event, this);
00789             event->acceptProposedAction();
00790         }
00791     }
00792 
00793     QListView::dropEvent(event);
00794     d->dragging = false;
00795 
00796     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00797     delegate->setShowHoverIndication(true);
00798 }
00799 
00800 void KFilePlacesView::paintEvent(QPaintEvent* event)
00801 {
00802     QListView::paintEvent(event);
00803     if (d->dragging && !d->dropRect.isEmpty()) {
00804         // draw drop indicator
00805         QPainter painter(viewport());
00806 
00807         const QModelIndex index = indexAt(d->dropRect.topLeft());
00808         const QRect itemRect = visualRect(index);
00809         const bool drawInsertIndicator = !d->dropOnPlace ||
00810                                          d->dropRect.height() <= d->insertIndicatorHeight(itemRect.height());
00811 
00812         if (drawInsertIndicator) {
00813             // draw indicator for inserting items
00814             QBrush blendedBrush = viewOptions().palette.brush(QPalette::Normal, QPalette::Highlight);
00815             QColor color = blendedBrush.color();
00816 
00817             const int y = (d->dropRect.top() + d->dropRect.bottom()) / 2;
00818             const int thickness = d->dropRect.height() / 2;
00819             Q_ASSERT(thickness >= 1);
00820             int alpha = 255;
00821             const int alphaDec = alpha / (thickness + 1);
00822             for (int i = 0; i < thickness; i++) {
00823                 color.setAlpha(alpha);
00824                 alpha -= alphaDec;
00825                 painter.setPen(color);
00826                 painter.drawLine(d->dropRect.left(), y - i, d->dropRect.right(), y - i);
00827                 painter.drawLine(d->dropRect.left(), y + i, d->dropRect.right(), y + i);
00828             }
00829         } else {
00830             // draw indicator for copying/moving/linking to items
00831             QStyleOptionViewItemV4 opt;
00832             opt.initFrom(this);
00833             opt.rect = itemRect;
00834             opt.state = QStyle::State_Enabled | QStyle::State_MouseOver;
00835             style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &painter, this);
00836         }
00837     }
00838 }
00839 
00840 void KFilePlacesView::setModel(QAbstractItemModel *model)
00841 {
00842     QListView::setModel(model);
00843     d->updateHiddenRows();
00844     // Uses Qt::QueuedConnection to delay the time when the slot will be
00845     // called. In case of an item move the remove+add will be done before
00846     // we adapt the item size (otherwise we'd get it wrong as we'd execute
00847     // it after the remove only).
00848     connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
00849             this, SLOT(adaptItemSize()), Qt::QueuedConnection);
00850     connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
00851             d->watcher, SLOT(currentIndexChanged(QModelIndex)));
00852 }
00853 
00854 void KFilePlacesView::rowsInserted(const QModelIndex &parent, int start, int end)
00855 {
00856     QListView::rowsInserted(parent, start, end);
00857     setUrl(d->currentUrl);
00858 
00859     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(itemDelegate());
00860     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(model());
00861 
00862     for (int i=start; i<=end; ++i) {
00863         QModelIndex index = placesModel->index(i, 0, parent);
00864         if (d->showAll || !placesModel->isHidden(index)) {
00865             delegate->addAppearingItem(index);
00866         } else {
00867             setRowHidden(i, true);
00868         }
00869     }
00870 
00871     if (d->itemAppearTimeline.state()!=QTimeLine::Running) {
00872         delegate->setAppearingItemProgress(0.0);
00873         d->itemAppearTimeline.start();
00874     }
00875 
00876     d->adaptItemSize();
00877 }
00878 
00879 QSize KFilePlacesView::sizeHint() const
00880 {
00881     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(model());
00882     if (!placesModel) {
00883         return QListView::sizeHint();
00884     }
00885     const int height = QListView::sizeHint().height();
00886     QFontMetrics fm = d->q->fontMetrics();
00887     int textWidth = 0;
00888 
00889     for (int i=0; i<placesModel->rowCount(); ++i) {
00890         QModelIndex index = placesModel->index(i, 0);
00891         if (!placesModel->isHidden(index))
00892            textWidth = qMax(textWidth,fm.width(index.data(Qt::DisplayRole).toString()));
00893     }
00894 
00895     const int iconSize = KIconLoader::global()->currentSize(KIconLoader::Small) + 3 * LATERAL_MARGIN;
00896     return QSize(iconSize + textWidth + fm.height() / 2, height);
00897 }
00898 
00899 void KFilePlacesView::Private::setCurrentIndex(const QModelIndex &index)
00900 {
00901     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(q->model());
00902 
00903     if (placesModel==0) return;
00904 
00905     KUrl url = placesModel->url(index);
00906 
00907     if (url.isValid()) {
00908         currentUrl = url;
00909         updateHiddenRows();
00910         emit q->urlChanged(url);
00911         if (showAll) {
00912             q->setShowAll(false);
00913         }
00914     } else {
00915         q->setUrl(currentUrl);
00916     }
00917 }
00918 
00919 void KFilePlacesView::Private::adaptItemSize()
00920 {
00921     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(q->itemDelegate());
00922     if (!delegate) return;
00923 
00924     if (!autoResizeItems) {
00925         int size = q->iconSize().width(); // Assume width == height
00926         delegate->setIconSize(size);
00927         q->scheduleDelayedItemsLayout();
00928         return;
00929     }
00930 
00931     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(q->model());
00932 
00933     if (placesModel==0) return;
00934 
00935     int rowCount = placesModel->rowCount();
00936 
00937     if (!showAll) {
00938         rowCount-= placesModel->hiddenCount();
00939 
00940         QModelIndex current = placesModel->closestItem(currentUrl);
00941 
00942         if (placesModel->isHidden(current)) {
00943             rowCount++;
00944         }
00945     }
00946 
00947     if (rowCount==0) return; // We've nothing to display anyway
00948 
00949     const int minSize = IconSize(KIconLoader::Small);
00950     const int maxSize = 64;
00951 
00952     int textWidth = 0;
00953     QFontMetrics fm = q->fontMetrics();
00954     for (int i=0; i<placesModel->rowCount(); ++i) {
00955         QModelIndex index = placesModel->index(i, 0);
00956 
00957         if (!placesModel->isHidden(index))
00958            textWidth = qMax(textWidth,fm.width(index.data(Qt::DisplayRole).toString()));
00959     }
00960 
00961     const int margin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, q) + 1;
00962     const int maxWidth = q->viewport()->width() - textWidth - 4 * margin - 1;
00963     const int maxHeight = ((q->height() - (fm.height() / 2) * rowCount) / rowCount) - 1;
00964 
00965     int size = qMin(maxHeight, maxWidth);
00966 
00967     if (size<minSize) {
00968         size = minSize;
00969     } else if (size>maxSize) {
00970         size = maxSize;
00971     } else {
00972         // Make it a multiple of 16
00973         size &= ~0xf;
00974     }
00975 
00976     if (size==delegate->iconSize()) return;
00977 
00978     if (smoothItemResizing) {
00979         oldSize = delegate->iconSize();
00980         endSize = size;
00981         if (adaptItemsTimeline.state()!=QTimeLine::Running) {
00982             adaptItemsTimeline.start();
00983         }
00984     } else {
00985         delegate->setIconSize(size);
00986         q->scheduleDelayedItemsLayout();
00987     }
00988 }
00989 
00990 void KFilePlacesView::Private::updateHiddenRows()
00991 {
00992     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(q->model());
00993 
00994     if (placesModel==0) return;
00995 
00996     int rowCount = placesModel->rowCount();
00997     QModelIndex current = placesModel->closestItem(currentUrl);
00998 
00999     for (int i=0; i<rowCount; ++i) {
01000         QModelIndex index = placesModel->index(i, 0);
01001         if (index!=current && placesModel->isHidden(index) && !showAll) {
01002             q->setRowHidden(i, true);
01003         } else {
01004             q->setRowHidden(i, false);
01005         }
01006     }
01007 
01008     adaptItemSize();
01009 }
01010 
01011 bool KFilePlacesView::Private::insertAbove(const QRect &itemRect, const QPoint &pos) const
01012 {
01013     if (dropOnPlace) {
01014         return pos.y() < itemRect.top() + insertIndicatorHeight(itemRect.height()) / 2;
01015     }
01016 
01017     return pos.y() < itemRect.top() + (itemRect.height() / 2);
01018 }
01019 
01020 bool KFilePlacesView::Private::insertBelow(const QRect &itemRect, const QPoint &pos) const
01021 {
01022     if (dropOnPlace) {
01023         return pos.y() > itemRect.bottom() - insertIndicatorHeight(itemRect.height()) / 2;
01024     }
01025 
01026     return pos.y() >= itemRect.top() + (itemRect.height() / 2);
01027 }
01028 
01029 int KFilePlacesView::Private::insertIndicatorHeight(int itemHeight) const
01030 {
01031     const int min = 4;
01032     const int max = 12;
01033 
01034     int height = itemHeight / 4;
01035     if (height < min) {
01036         height = min;
01037     } else if (height > max) {
01038         height = max;
01039     }
01040     return height;
01041 }
01042 
01043 void KFilePlacesView::Private::fadeCapacityBar(const QModelIndex &index, FadeType fadeType)
01044 {
01045     QTimeLine *timeLine = delegate->fadeAnimationForIndex(index);
01046     delete timeLine;
01047     delegate->removeFadeAnimation(index);
01048     timeLine = new QTimeLine(250, q);
01049     connect(timeLine, SIGNAL(valueChanged(qreal)), q, SLOT(_k_capacityBarFadeValueChanged()));
01050     if (fadeType == FadeIn) {
01051         timeLine->setDirection(QTimeLine::Forward);
01052         timeLine->setCurrentTime(0);
01053     } else {
01054         timeLine->setDirection(QTimeLine::Backward);
01055         timeLine->setCurrentTime(250);
01056     }
01057     delegate->addFadeAnimation(index, timeLine);
01058     timeLine->start();
01059 }
01060 
01061 void KFilePlacesView::Private::_k_placeClicked(const QModelIndex &index)
01062 {
01063     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(q->model());
01064 
01065     if (placesModel==0) return;
01066 
01067     lastClickedIndex = QPersistentModelIndex();
01068 
01069     if (placesModel->setupNeeded(index)) {
01070         QObject::connect(placesModel, SIGNAL(setupDone(QModelIndex,bool)),
01071                          q, SLOT(_k_storageSetupDone(QModelIndex,bool)));
01072 
01073         lastClickedIndex = index;
01074         placesModel->requestSetup(index);
01075         return;
01076     }
01077 
01078     setCurrentIndex(index);
01079 }
01080 
01081 void KFilePlacesView::Private::_k_placeEntered(const QModelIndex &index)
01082 {
01083     fadeCapacityBar(index, FadeIn);
01084     pollingRequestCount++;
01085     if (pollingRequestCount == 1) {
01086         pollDevices.start();
01087     }
01088 }
01089 
01090 void KFilePlacesView::Private::_k_placeLeft(const QModelIndex &index)
01091 {
01092     fadeCapacityBar(index, FadeOut);
01093     pollingRequestCount--;
01094     if (!pollingRequestCount) {
01095         pollDevices.stop();
01096     }
01097 }
01098 
01099 void KFilePlacesView::Private::_k_storageSetupDone(const QModelIndex &index, bool success)
01100 {
01101     if (index!=lastClickedIndex) {
01102         return;
01103     }
01104 
01105     KFilePlacesModel *placesModel = qobject_cast<KFilePlacesModel*>(q->model());
01106 
01107     QObject::disconnect(placesModel, SIGNAL(setupDone(QModelIndex,bool)),
01108                         q, SLOT(_k_storageSetupDone(QModelIndex,bool)));
01109 
01110     if (success) {
01111         setCurrentIndex(lastClickedIndex);
01112     } else {
01113         q->setUrl(currentUrl);
01114     }
01115 
01116     lastClickedIndex = QPersistentModelIndex();
01117 }
01118 
01119 void KFilePlacesView::Private::_k_adaptItemsUpdate(qreal value)
01120 {
01121     int add = (endSize-oldSize)*value;
01122 
01123     int size = oldSize+add;
01124 
01125     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(q->itemDelegate());
01126     delegate->setIconSize(size);
01127     q->scheduleDelayedItemsLayout();
01128 }
01129 
01130 void KFilePlacesView::Private::_k_itemAppearUpdate(qreal value)
01131 {
01132     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(q->itemDelegate());
01133 
01134     delegate->setAppearingItemProgress(value);
01135     q->scheduleDelayedItemsLayout();
01136 }
01137 
01138 void KFilePlacesView::Private::_k_itemDisappearUpdate(qreal value)
01139 {
01140     KFilePlacesViewDelegate *delegate = dynamic_cast<KFilePlacesViewDelegate*>(q->itemDelegate());
01141 
01142     delegate->setDisappearingItemProgress(value);
01143 
01144     if (value>=1.0) {
01145         updateHiddenRows();
01146     }
01147 
01148     q->scheduleDelayedItemsLayout();
01149 }
01150 
01151 void KFilePlacesView::Private::_k_enableSmoothItemResizing()
01152 {
01153     smoothItemResizing = true;
01154 }
01155 
01156 void KFilePlacesView::Private::_k_trashUpdated(KJob *job)
01157 {
01158     if (job->error()) {
01159         static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
01160     }
01161     org::kde::KDirNotify::emitFilesAdded("trash:/");
01162 }
01163 
01164 void KFilePlacesView::Private::_k_capacityBarFadeValueChanged()
01165 {
01166     const QModelIndex index = delegate->indexForFadeAnimation(static_cast<QTimeLine*>(q->sender()));
01167     if (!index.isValid()) {
01168         return;
01169     }
01170     q->update(index);
01171 }
01172 
01173 void KFilePlacesView::Private::_k_triggerDevicePolling()
01174 {
01175     const QModelIndex hoveredIndex = watcher->hoveredIndex();
01176     if (hoveredIndex.isValid()) {
01177         const KFilePlacesModel *placesModel = static_cast<const KFilePlacesModel*>(hoveredIndex.model());
01178         if (placesModel->isDevice(hoveredIndex)) {
01179             q->update(hoveredIndex);
01180         }
01181     }
01182     const QModelIndex focusedIndex = watcher->focusedIndex();
01183     if (focusedIndex.isValid() && focusedIndex != hoveredIndex) {
01184         const KFilePlacesModel *placesModel = static_cast<const KFilePlacesModel*>(focusedIndex.model());
01185         if (placesModel->isDevice(focusedIndex)) {
01186             q->update(focusedIndex);
01187         }
01188     }
01189 }
01190 
01191 void KFilePlacesView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
01192 {
01193     QListView::dataChanged(topLeft, bottomRight);
01194     d->adaptItemSize();
01195 }
01196 
01197 #include "kfileplacesview.moc"
01198 #include "kfileplacesview_p.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:40:57 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KFile

Skip menu "KFile"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.9.5 API Reference

Skip menu "kdelibs-4.9.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal