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

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs-4.9.5 API Reference

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

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