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

KFile

Skip menu "KFile"
  • Main Page
  • 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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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