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