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