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