• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KFile

kfileplacesmodel.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) 2007 David Faure <faure@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 #include "kfileplacesmodel.h"
00021 #include "kfileplacesitem_p.h"
00022 #include "kfileplacessharedbookmarks_p.h"
00023 
00024 #include <QtCore/QMimeData>
00025 #include <QtCore/QTimer>
00026 #include <QtCore/QFile>
00027 #include <QtGui/QColor>
00028 #include <QtGui/QAction>
00029 
00030 #include <kfileitem.h>
00031 #include <kglobal.h>
00032 #include <klocale.h>
00033 #include <kuser.h>
00034 #include <kstandarddirs.h>
00035 #include <kcomponentdata.h>
00036 #include <kicon.h>
00037 #include <kmimetype.h>
00038 #include <kdebug.h>
00039 
00040 #include <kbookmarkmanager.h>
00041 #include <kbookmark.h>
00042 
00043 #include <kio/netaccess.h>
00044 
00045 #include <solid/devicenotifier.h>
00046 #include <solid/storageaccess.h>
00047 #include <solid/storagedrive.h>
00048 #include <solid/storagevolume.h>
00049 #include <solid/opticaldrive.h>
00050 #include <solid/opticaldisc.h>
00051 #include <solid/predicate.h>
00052 
00053 class KFilePlacesModel::Private
00054 {
00055 public:
00056     Private(KFilePlacesModel *self) : q(self), bookmarkManager(0), sharedBookmarks(0) {}
00057     ~Private()
00058     {
00059         delete sharedBookmarks;
00060         qDeleteAll(items);
00061     }
00062 
00063     KFilePlacesModel *q;
00064 
00065     QList<KFilePlacesItem*> items;
00066     QSet<QString> availableDevices;
00067     QMap<QObject*, QPersistentModelIndex> setupInProgress;
00068 
00069     Solid::Predicate predicate;
00070     KBookmarkManager *bookmarkManager;
00071     KFilePlacesSharedBookmarks * sharedBookmarks;
00072 
00073     void reloadAndSignal();
00074     QList<KFilePlacesItem *> loadBookmarkList();
00075 
00076     void _k_initDeviceList();
00077     void _k_deviceAdded(const QString &udi);
00078     void _k_deviceRemoved(const QString &udi);
00079     void _k_itemChanged(const QString &udi);
00080     void _k_reloadBookmarks();
00081     void _k_storageSetupDone(Solid::ErrorType error, QVariant errorData);
00082     void _k_storageTeardownDone(Solid::ErrorType error, QVariant errorData);
00083 };
00084 
00085 KFilePlacesModel::KFilePlacesModel(QObject *parent)
00086     : QAbstractItemModel(parent), d(new Private(this))
00087 {
00088     const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
00089     d->bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
00090 
00091     // Let's put some places in there if it's empty. We have a corner case here:
00092     // Given you have bookmarked some folders (which have been saved on
00093     // ~/.local/share/user-places.xbel (according to freedesktop bookmarks spec), and
00094     // deleted the home directory ~/.kde, the call managerForFile() will return the
00095     // bookmark manager for the fallback "kfilePlaces", making root.first().isNull() being
00096     // false (you have your own items bookmarked), resulting on only being added your own
00097     // bookmarks, and not the default ones too. So, we also check if kfileplaces/bookmarks.xml
00098     // file exists, and if it doesn't, we also add the default places. (ereslibre)
00099     KBookmarkGroup root = d->bookmarkManager->root();
00100     if (root.first().isNull() || !QFile::exists(file)) {
00101         KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
00102                                         i18nc("Home Directory", "Home"), KUrl(KUser().homeDir()), "user-home");
00103         KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
00104                                         i18n("Network"), KUrl("remote:/"), "network-workgroup");
00105 #ifdef Q_OS_WIN
00106     //C:/ as root for windows...forward slashes are valid too and are used in much/most of the KDE code on Windows
00107         KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
00108                                         i18n("Root"), KUrl("C:/"), "folder-red");
00109 #else
00110         KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
00111                                         i18n("Root"), KUrl("/"), "folder-red");
00112 #endif
00113         KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
00114                                         i18n("Trash"), KUrl("trash:/"), "user-trash");
00115 
00116         // Force bookmarks to be saved. If on open/save dialog and the bookmarks are not saved, QFile::exists
00117         // will always return false, which opening/closing all the time the open/save dialog would case the
00118         // bookmarks to be added once each time, having lots of times each bookmark. This forces the defaults
00119         // to be saved on the bookmarks.xml file. Of course, the complete list of bookmarks (those that come from
00120         // user-places.xbel will be filled later). (ereslibre)
00121         d->bookmarkManager->saveAs(file);
00122     }
00123 
00124     // create after, so if we have own places, they are added afterwards, in case of equal priorities
00125     d->sharedBookmarks = new KFilePlacesSharedBookmarks(d->bookmarkManager);
00126 
00127     d->predicate = Solid::Predicate::fromString(
00128         "[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
00129         " OR "
00130         "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]");
00131 
00132     connect(d->bookmarkManager, SIGNAL(changed(const QString&, const QString&)),
00133             this, SLOT(_k_reloadBookmarks()));
00134     connect(d->bookmarkManager, SIGNAL(bookmarksChanged(const QString&)),
00135             this, SLOT(_k_reloadBookmarks()));
00136 
00137     d->_k_reloadBookmarks();
00138     QTimer::singleShot(0, this, SLOT(_k_initDeviceList()));
00139 }
00140 
00141 KFilePlacesModel::~KFilePlacesModel()
00142 {
00143     delete d;
00144 }
00145 
00146 KUrl KFilePlacesModel::url(const QModelIndex &index) const
00147 {
00148     return KUrl(data(index, UrlRole).toUrl());
00149 }
00150 
00151 bool KFilePlacesModel::setupNeeded(const QModelIndex &index) const
00152 {
00153     return data(index, SetupNeededRole).toBool();
00154 }
00155 
00156 KIcon KFilePlacesModel::icon(const QModelIndex &index) const
00157 {
00158     return KIcon(data(index, Qt::DecorationRole).value<QIcon>());
00159 }
00160 
00161 QString KFilePlacesModel::text(const QModelIndex &index) const
00162 {
00163     return data(index, Qt::DisplayRole).toString();
00164 }
00165 
00166 bool KFilePlacesModel::isHidden(const QModelIndex &index) const
00167 {
00168     return data(index, HiddenRole).toBool();
00169 }
00170 
00171 bool KFilePlacesModel::isDevice(const QModelIndex &index) const
00172 {
00173     if (!index.isValid())
00174         return false;
00175 
00176     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00177 
00178     return item->isDevice();
00179 }
00180 
00181 Solid::Device KFilePlacesModel::deviceForIndex(const QModelIndex &index) const
00182 {
00183     if (!index.isValid())
00184         return Solid::Device();
00185 
00186     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00187 
00188     if (item->isDevice()) {
00189         return item->device();
00190     } else {
00191         return Solid::Device();
00192     }
00193 }
00194 
00195 KBookmark KFilePlacesModel::bookmarkForIndex(const QModelIndex &index) const
00196 {
00197     if (!index.isValid())
00198         return KBookmark();
00199 
00200     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00201 
00202     if (!item->isDevice()) {
00203         return item->bookmark();
00204     } else {
00205         return KBookmark();
00206     }
00207 }
00208 
00209 QVariant KFilePlacesModel::data(const QModelIndex &index, int role) const
00210 {
00211     if (!index.isValid())
00212         return QVariant();
00213 
00214     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00215     return item->data(role);
00216 }
00217 
00218 QModelIndex KFilePlacesModel::index(int row, int column, const QModelIndex &parent) const
00219 {
00220     if (row<0 || column!=0 || row>=d->items.size())
00221         return QModelIndex();
00222 
00223     if (parent.isValid())
00224         return QModelIndex();
00225 
00226     return createIndex(row, column, d->items.at(row));
00227 }
00228 
00229 QModelIndex KFilePlacesModel::parent(const QModelIndex &child) const
00230 {
00231     Q_UNUSED(child);
00232     return QModelIndex();
00233 }
00234 
00235 int KFilePlacesModel::rowCount(const QModelIndex &parent) const
00236 {
00237     if (parent.isValid())
00238         return 0;
00239     else
00240         return d->items.size();
00241 }
00242 
00243 int KFilePlacesModel::columnCount(const QModelIndex &parent) const
00244 {
00245     Q_UNUSED(parent)
00246     // We only know 1 piece of information for a particular entry
00247     return 1;
00248 }
00249 
00250 QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const
00251 {
00252     int foundRow = -1;
00253     int maxLength = 0;
00254 
00255     // Search the item which is equal to the URL or at least is a parent URL.
00256     // If there are more than one possible item URL candidates, choose the item
00257     // which covers the bigger range of the URL.
00258     for (int row = 0; row<d->items.size(); ++row) {
00259         KFilePlacesItem *item = d->items[row];
00260         KUrl itemUrl = KUrl(item->data(UrlRole).toUrl());
00261 
00262         if (itemUrl.isParentOf(url)) {
00263             const int length = itemUrl.prettyUrl().length();
00264             if (length > maxLength) {
00265                 foundRow = row;
00266                 maxLength = length;
00267             }
00268         }
00269     }
00270 
00271     if (foundRow==-1)
00272         return QModelIndex();
00273     else
00274         return createIndex(foundRow, 0, d->items[foundRow]);
00275 }
00276 
00277 void KFilePlacesModel::Private::_k_initDeviceList()
00278 {
00279     Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance();
00280 
00281     connect(notifier, SIGNAL(deviceAdded(const QString&)),
00282             q, SLOT(_k_deviceAdded(const QString&)));
00283     connect(notifier, SIGNAL(deviceRemoved(const QString&)),
00284             q, SLOT(_k_deviceRemoved(const QString&)));
00285 
00286     const QList<Solid::Device> &deviceList = Solid::Device::listFromQuery(predicate);
00287 
00288     foreach(const Solid::Device &device, deviceList) {
00289         availableDevices << device.udi();
00290     }
00291 
00292     _k_reloadBookmarks();
00293 }
00294 
00295 void KFilePlacesModel::Private::_k_deviceAdded(const QString &udi)
00296 {
00297     Solid::Device d(udi);
00298 
00299     if (predicate.matches(d)) {
00300         availableDevices << udi;
00301         _k_reloadBookmarks();
00302     }
00303 }
00304 
00305 void KFilePlacesModel::Private::_k_deviceRemoved(const QString &udi)
00306 {
00307     if (availableDevices.contains(udi)) {
00308         availableDevices.remove(udi);
00309         _k_reloadBookmarks();
00310     }
00311 }
00312 
00313 void KFilePlacesModel::Private::_k_itemChanged(const QString &id)
00314 {
00315     for (int row = 0; row<items.size(); ++row) {
00316         if (items.at(row)->id()==id) {
00317             QModelIndex index = q->index(row, 0);
00318             emit q->dataChanged(index, index);
00319         }
00320     }
00321 }
00322 
00323 void KFilePlacesModel::Private::_k_reloadBookmarks()
00324 {
00325     QList<KFilePlacesItem*> currentItems = loadBookmarkList();
00326 
00327     QList<KFilePlacesItem*>::Iterator it_i = items.begin();
00328     QList<KFilePlacesItem*>::Iterator it_c = currentItems.begin();
00329 
00330     QList<KFilePlacesItem*>::Iterator end_i = items.end();
00331     QList<KFilePlacesItem*>::Iterator end_c = currentItems.end();
00332 
00333     while (it_i!=end_i || it_c!=end_c) {
00334         if (it_i==end_i && it_c!=end_c) {
00335             int row = items.count();
00336 
00337             q->beginInsertRows(QModelIndex(), row, row);
00338             it_i = items.insert(it_i, *it_c);
00339             ++it_i;
00340             it_c = currentItems.erase(it_c);
00341 
00342             end_i = items.end();
00343             end_c = currentItems.end();
00344             q->endInsertRows();
00345 
00346         } else if (it_i!=end_i && it_c==end_c) {
00347             int row = items.indexOf(*it_i);
00348 
00349             q->beginRemoveRows(QModelIndex(), row, row);
00350             delete *it_i;
00351             it_i = items.erase(it_i);
00352 
00353             end_i = items.end();
00354             end_c = currentItems.end();
00355             q->endRemoveRows();
00356 
00357         } else if ((*it_i)->id()==(*it_c)->id()) {
00358             bool shouldEmit = !((*it_i)->bookmark()==(*it_c)->bookmark());
00359             (*it_i)->setBookmark((*it_c)->bookmark());
00360             if (shouldEmit) {
00361                 int row = items.indexOf(*it_i);
00362                 QModelIndex idx = q->index(row, 0);
00363                 emit q->dataChanged(idx, idx);
00364             }
00365             ++it_i;
00366             ++it_c;
00367         } else if ((*it_i)->id()!=(*it_c)->id()) {
00368             int row = items.indexOf(*it_i);
00369 
00370             if (it_i+1!=end_i && (*(it_i+1))->id()==(*it_c)->id()) { // if the next one matches, it's a remove
00371                 q->beginRemoveRows(QModelIndex(), row, row);
00372                 delete *it_i;
00373                 it_i = items.erase(it_i);
00374 
00375                 end_i = items.end();
00376                 end_c = currentItems.end();
00377                 q->endRemoveRows();
00378             } else {
00379                 q->beginInsertRows(QModelIndex(), row, row);
00380                 it_i = items.insert(it_i, *it_c);
00381                 ++it_i;
00382                 it_c = currentItems.erase(it_c);
00383 
00384                 end_i = items.end();
00385                 end_c = currentItems.end();
00386                 q->endInsertRows();
00387             }
00388         }
00389     }
00390 
00391     qDeleteAll(currentItems);
00392     currentItems.clear();
00393 }
00394 
00395 QList<KFilePlacesItem *> KFilePlacesModel::Private::loadBookmarkList()
00396 {
00397     QList<KFilePlacesItem*> items;
00398 
00399     KBookmarkGroup root = bookmarkManager->root();
00400     KBookmark bookmark = root.first();
00401     QSet<QString> devices = availableDevices;
00402 
00403     while (!bookmark.isNull()) {
00404         QString udi = bookmark.metaDataItem("UDI");
00405         QString appName = bookmark.metaDataItem("OnlyInApp");
00406         bool deviceAvailable = devices.remove(udi);
00407 
00408         bool allowedHere = appName.isEmpty() || (appName==KGlobal::mainComponent().componentName());
00409 
00410         if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
00411             KFilePlacesItem *item;
00412             if (deviceAvailable) {
00413                 item = new KFilePlacesItem(bookmarkManager, bookmark.address(), udi);
00414                 // TODO: Update bookmark internal element
00415             } else {
00416                 item = new KFilePlacesItem(bookmarkManager, bookmark.address());
00417             }
00418             connect(item, SIGNAL(itemChanged(const QString&)),
00419                     q, SLOT(_k_itemChanged(const QString&)));
00420             items << item;
00421         }
00422 
00423         bookmark = root.next(bookmark);
00424     }
00425 
00426     // Add bookmarks for the remaining devices, they were previously unknown
00427     foreach (const QString &udi, devices) {
00428         bookmark = KFilePlacesItem::createDeviceBookmark(bookmarkManager, udi);
00429         if (!bookmark.isNull()) {
00430             KFilePlacesItem *item = new KFilePlacesItem(bookmarkManager,
00431                                                         bookmark.address(), udi);
00432             connect(item, SIGNAL(itemChanged(const QString&)),
00433                     q, SLOT(_k_itemChanged(const QString&)));
00434             // TODO: Update bookmark internal element
00435             items << item;
00436         }
00437     }
00438 
00439     return items;
00440 }
00441 
00442 void KFilePlacesModel::Private::reloadAndSignal()
00443 {
00444     bookmarkManager->emitChanged(bookmarkManager->root()); // ... we'll get relisted anyway
00445 }
00446 
00447 Qt::DropActions KFilePlacesModel::supportedDropActions() const
00448 {
00449     return Qt::ActionMask;
00450 }
00451 
00452 Qt::ItemFlags KFilePlacesModel::flags(const QModelIndex &index) const
00453 {
00454     Qt::ItemFlags res = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
00455 
00456     if (index.isValid())
00457         res|= Qt::ItemIsDragEnabled;
00458 
00459     if (!index.isValid())
00460         res|= Qt::ItemIsDropEnabled;
00461 
00462     return res;
00463 }
00464 
00465 static QString _k_internalMimetype(const KFilePlacesModel * const self)
00466 {
00467     return QString("application/x-kfileplacesmodel-")+QString::number((long)self);
00468 }
00469 
00470 QStringList KFilePlacesModel::mimeTypes() const
00471 {
00472     QStringList types;
00473 
00474     types << _k_internalMimetype(this) << "text/uri-list";
00475 
00476     return types;
00477 }
00478 
00479 QMimeData *KFilePlacesModel::mimeData(const QModelIndexList &indexes) const
00480 {
00481     KUrl::List urls;
00482     QByteArray itemData;
00483 
00484     QDataStream stream(&itemData, QIODevice::WriteOnly);
00485 
00486     foreach (const QModelIndex &index, indexes) {
00487         KUrl itemUrl = url(index);
00488         if (itemUrl.isValid())
00489             urls << itemUrl;
00490         stream << index.row();
00491     }
00492 
00493     QMimeData *mimeData = new QMimeData();
00494 
00495     if (!urls.isEmpty())
00496         urls.populateMimeData(mimeData);
00497 
00498     mimeData->setData(_k_internalMimetype(this), itemData);
00499 
00500     return mimeData;
00501 }
00502 
00503 bool KFilePlacesModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
00504                                     int row, int column, const QModelIndex &parent)
00505 {
00506     if (action == Qt::IgnoreAction)
00507         return true;
00508 
00509     if (column > 0)
00510         return false;
00511 
00512     if (row==-1 && parent.isValid()) {
00513         return false; // Don't allow to move an item onto another one,
00514                       // too easy for the user to mess something up
00515                       // If we really really want to allow copying files this way,
00516                       // let's do it in the views to get the good old drop menu
00517     }
00518 
00519 
00520     KBookmark afterBookmark;
00521 
00522     if (row==-1) {
00523         // The dropped item is moved or added to the last position
00524 
00525         KFilePlacesItem *lastItem = d->items.last();
00526         afterBookmark = lastItem->bookmark();
00527 
00528     } else {
00529         // The dropped item is moved or added before position 'row', ie after position 'row-1'
00530 
00531         if (row>0) {
00532             KFilePlacesItem *afterItem = d->items[row-1];
00533             afterBookmark = afterItem->bookmark();
00534         }
00535     }
00536 
00537     if (data->hasFormat(_k_internalMimetype(this))) {
00538         // The operation is an internal move
00539         QByteArray itemData = data->data(_k_internalMimetype(this));
00540         QDataStream stream(&itemData, QIODevice::ReadOnly);
00541         int itemRow;
00542 
00543         stream >> itemRow;
00544 
00545         KFilePlacesItem *item = d->items[itemRow];
00546         KBookmark bookmark = item->bookmark();
00547 
00548         d->bookmarkManager->root().moveBookmark(bookmark, afterBookmark);
00549 
00550     } else if (data->hasFormat("text/uri-list")) {
00551         // The operation is an add
00552         KUrl::List urls = KUrl::List::fromMimeData(data);
00553 
00554         KBookmarkGroup group = d->bookmarkManager->root();
00555 
00556         foreach (const KUrl &url, urls) {
00557             KMimeType::Ptr mimetype = KMimeType::mimeType(KIO::NetAccess::mimetype(url, 0));
00558 
00559             if (!mimetype) {
00560                 kWarning() << "URL not added to Places as mimetype could not be determined!";
00561                 continue;
00562             }
00563 
00564             if (!mimetype->is("inode/directory")) {
00565                 // Only directories are allowed
00566                 continue;
00567             }
00568 
00569             KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
00570 
00571             KBookmark bookmark = KFilePlacesItem::createBookmark(d->bookmarkManager,
00572                                                                  url.fileName(), url,
00573                                                                  item.iconName());
00574             group.moveBookmark(bookmark, afterBookmark);
00575             afterBookmark = bookmark;
00576         }
00577 
00578     } else {
00579         // Oops, shouldn't happen thanks to mimeTypes()
00580         kWarning() << ": received wrong mimedata, " << data->formats();
00581         return false;
00582     }
00583 
00584     d->reloadAndSignal();
00585 
00586     return true;
00587 }
00588 
00589 void KFilePlacesModel::addPlace(const QString &text, const KUrl &url,
00590                                 const QString &iconName, const QString &appName)
00591 {
00592     KBookmark bookmark = KFilePlacesItem::createBookmark(d->bookmarkManager,
00593                                                          text, url, iconName);
00594 
00595     if (!appName.isEmpty()) {
00596         bookmark.setMetaDataItem("OnlyInApp", appName);
00597     }
00598 
00599     d->reloadAndSignal();
00600 }
00601 
00602 void KFilePlacesModel::editPlace(const QModelIndex &index, const QString &text, const KUrl &url,
00603                                  const QString &iconName, const QString &appName)
00604 {
00605     if (!index.isValid()) return;
00606 
00607     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00608 
00609     if (item->isDevice()) return;
00610 
00611     KBookmark bookmark = item->bookmark();
00612 
00613     if (bookmark.isNull()) return;
00614 
00615     bookmark.setFullText(text);
00616     bookmark.setUrl(url);
00617     bookmark.setIcon(iconName);
00618     bookmark.setMetaDataItem("OnlyInApp", appName);
00619 
00620     d->reloadAndSignal();
00621     emit dataChanged(index, index);
00622 }
00623 
00624 void KFilePlacesModel::removePlace(const QModelIndex &index) const
00625 {
00626     if (!index.isValid()) return;
00627 
00628     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00629 
00630     if (item->isDevice()) return;
00631 
00632     KBookmark bookmark = item->bookmark();
00633 
00634     if (bookmark.isNull()) return;
00635 
00636     d->bookmarkManager->root().deleteBookmark(bookmark);
00637     d->reloadAndSignal();
00638 }
00639 
00640 void KFilePlacesModel::setPlaceHidden(const QModelIndex &index, bool hidden)
00641 {
00642     if (!index.isValid()) return;
00643 
00644     KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
00645 
00646     KBookmark bookmark = item->bookmark();
00647 
00648     if (bookmark.isNull()) return;
00649 
00650     bookmark.setMetaDataItem("IsHidden", (hidden ? "true" : "false"));
00651 
00652     d->reloadAndSignal();
00653     emit dataChanged(index, index);
00654 }
00655 
00656 int KFilePlacesModel::hiddenCount() const
00657 {
00658     int rows = rowCount();
00659     int hidden = 0;
00660 
00661     for (int i=0; i<rows; ++i) {
00662         if (isHidden(index(i, 0))) {
00663             hidden++;
00664         }
00665     }
00666 
00667     return hidden;
00668 }
00669 
00670 QAction *KFilePlacesModel::teardownActionForIndex(const QModelIndex &index) const
00671 {
00672     Solid::Device device = deviceForIndex(index);
00673 
00674     if (device.is<Solid::StorageAccess>() && device.as<Solid::StorageAccess>()->isAccessible()) {
00675 
00676         Solid::StorageDrive *drive = device.as<Solid::StorageDrive>();
00677 
00678         if (drive==0) {
00679             drive = device.parent().as<Solid::StorageDrive>();
00680         }
00681 
00682         bool hotpluggable = false;
00683         bool removable = false;
00684 
00685         if (drive!=0) {
00686             hotpluggable = drive->isHotpluggable();
00687             removable = drive->isRemovable();
00688         }
00689 
00690         QString iconName;
00691         QString text;
00692         QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
00693 
00694         if (device.is<Solid::OpticalDisc>()) {
00695             text = i18n("&Release '%1'", label);
00696         } else if (removable || hotpluggable) {
00697             text = i18n("&Safely Remove '%1'", label);
00698             iconName = "media-eject";
00699         } else {
00700             text = i18n("&Unmount '%1'", label);
00701             iconName = "media-eject";
00702         }
00703 
00704         if (!iconName.isEmpty()) {
00705             return new QAction(KIcon(iconName), text, 0);
00706         } else {
00707             return new QAction(text, 0);
00708         }
00709     }
00710 
00711     return 0;
00712 }
00713 
00714 QAction *KFilePlacesModel::ejectActionForIndex(const QModelIndex &index) const
00715 {
00716     Solid::Device device = deviceForIndex(index);
00717 
00718     if (device.is<Solid::OpticalDisc>()) {
00719 
00720         QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
00721         QString text = i18n("&Eject '%1'", label);
00722 
00723         return new QAction(KIcon("media-eject"), text, 0);
00724     }
00725 
00726     return 0;
00727 }
00728 
00729 void KFilePlacesModel::requestTeardown(const QModelIndex &index)
00730 {
00731     Solid::Device device = deviceForIndex(index);
00732 
00733     Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
00734 
00735     connect(access, SIGNAL(teardownDone(Solid::ErrorType, QVariant, const QString &)),
00736             this, SLOT(_k_storageTeardownDone(Solid::ErrorType, QVariant)));
00737 
00738     device.as<Solid::StorageAccess>()->teardown();
00739 }
00740 
00741 void KFilePlacesModel::requestEject(const QModelIndex &index)
00742 {
00743     Solid::Device device = deviceForIndex(index);
00744 
00745     Solid::OpticalDrive *drive = device.parent().as<Solid::OpticalDrive>();
00746 
00747     if (drive!=0) {
00748         connect(drive, SIGNAL(ejectDone(Solid::ErrorType, QVariant, const QString &)),
00749                 this, SLOT(_k_storageTeardownDone(Solid::ErrorType, QVariant)));
00750 
00751         drive->eject();
00752     } else {
00753         QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
00754         QString message = i18n("The device '%1' is not a disc and can't be ejected.", label);
00755         emit errorMessage(message);
00756     }
00757 }
00758 
00759 void KFilePlacesModel::requestSetup(const QModelIndex &index)
00760 {
00761     Solid::Device device = deviceForIndex(index);
00762 
00763     if (device.is<Solid::StorageAccess>()
00764      && !d->setupInProgress.contains(device.as<Solid::StorageAccess>())
00765      && !device.as<Solid::StorageAccess>()->isAccessible()) {
00766 
00767         Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
00768 
00769         d->setupInProgress[access] = index;
00770 
00771         connect(access, SIGNAL(setupDone(Solid::ErrorType, QVariant, const QString &)),
00772                 this, SLOT(_k_storageSetupDone(Solid::ErrorType, QVariant)));
00773 
00774         access->setup();
00775     }
00776 }
00777 
00778 void KFilePlacesModel::Private::_k_storageSetupDone(Solid::ErrorType error, QVariant errorData)
00779 {
00780     QPersistentModelIndex index = setupInProgress.take(q->sender());
00781 
00782     if (!index.isValid()) {
00783         return;
00784     }
00785 
00786     if (!error) {
00787         emit q->setupDone(index, true);
00788     } else {
00789         if (errorData.isValid()) {
00790             emit q->errorMessage(i18n("An error occurred while accessing '%1', the system responded: %2",
00791                                       q->text(index),
00792                                       errorData.toString()));
00793         } else {
00794             emit q->errorMessage(i18n("An error occurred while accessing '%1'",
00795                                       q->text(index)));
00796         }
00797         emit q->setupDone(index, false);
00798     }
00799 
00800 }
00801 
00802 void KFilePlacesModel::Private::_k_storageTeardownDone(Solid::ErrorType error, QVariant errorData)
00803 {
00804     if (error && errorData.isValid()) {
00805         emit q->errorMessage(errorData.toString());
00806     }
00807 }
00808 
00809 #include "kfileplacesmodel.moc"

KFile

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal