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

Skip menu "kdelibs-4.8.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