• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KFile

  • kfile
kfileplacesmodel.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
3 Copyright (C) 2007 David Faure <faure@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18
19*/
20#include "kfileplacesmodel.h"
21#include "kfileplacesitem_p.h"
22
23#ifdef _WIN32_WCE
24#include "Windows.h"
25#include "WinBase.h"
26#include <QtCore/QDir>
27#endif
28
29#include <QtCore/QMimeData>
30#include <QtCore/QTimer>
31#include <QtCore/QFile>
32#include <QtGui/QColor>
33#include <QtGui/QAction>
34
35#include <kfileitem.h>
36#include <kglobal.h>
37#include <klocale.h>
38#include <kuser.h>
39#include <kstandarddirs.h>
40#include <kcomponentdata.h>
41#include <kicon.h>
42#include <kmimetype.h>
43#include <kdebug.h>
44
45#include <kbookmarkmanager.h>
46#include <kbookmark.h>
47
48#include <kio/netaccess.h>
49#include <kprotocolinfo.h>
50
51#include <solid/devicenotifier.h>
52#include <solid/storageaccess.h>
53#include <solid/storagedrive.h>
54#include <solid/storagevolume.h>
55#include <solid/opticaldrive.h>
56#include <solid/opticaldisc.h>
57#include <solid/portablemediaplayer.h>
58#include <solid/predicate.h>
59
60class KFilePlacesModel::Private
61{
62public:
63 Private(KFilePlacesModel *self) : q(self), bookmarkManager(0) {}
64 ~Private()
65 {
66 qDeleteAll(items);
67 }
68
69 KFilePlacesModel *q;
70
71 QList<KFilePlacesItem*> items;
72 QSet<QString> availableDevices;
73 QMap<QObject*, QPersistentModelIndex> setupInProgress;
74
75 Solid::Predicate predicate;
76 KBookmarkManager *bookmarkManager;
77
78 void reloadAndSignal();
79 QList<KFilePlacesItem *> loadBookmarkList();
80
81 void _k_initDeviceList();
82 void _k_deviceAdded(const QString &udi);
83 void _k_deviceRemoved(const QString &udi);
84 void _k_itemChanged(const QString &udi);
85 void _k_reloadBookmarks();
86 void _k_storageSetupDone(Solid::ErrorType error, QVariant errorData);
87 void _k_storageTeardownDone(Solid::ErrorType error, QVariant errorData);
88};
89
90KFilePlacesModel::KFilePlacesModel(QObject *parent)
91 : QAbstractItemModel(parent), d(new Private(this))
92{
93 const QString file = KStandardDirs().localxdgdatadir() + "user-places.xbel";
94 d->bookmarkManager = KBookmarkManager::managerForExternalFile(file);
95
96 // Let's put some places in there if it's empty. We have a corner case here:
97 // Given you have bookmarked some folders (which have been saved on
98 // ~/.local/share/user-places.xbel (according to freedesktop bookmarks spec), and
99 // deleted the home directory ~/.kde, the call managerForFile() will return the
100 // bookmark manager for the fallback "kfilePlaces", making root.first().isNull() being
101 // false (you have your own items bookmarked), resulting on only being added your own
102 // bookmarks, and not the default ones too. So, we also check if kfileplaces/bookmarks.xml
103 // file exists, and if it doesn't, we also add the default places. (ereslibre)
104 KBookmarkGroup root = d->bookmarkManager->root();
105 if (root.first().isNull() || !QFile::exists(file)) {
106
107 // NOTE: The context for these I18N_NOOP2 calls has to be "KFile System Bookmarks".
108 // The real i18nc call is made later, with this context, so the two must match.
109 //
110 // createSystemBookmark actually does nothing with its third argument,
111 // but we have to give it something so the I18N_NOOP2 calls stay here for now.
112 //
113 // (coles, 13th May 2009)
114
115 KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
116 "Home", I18N_NOOP2("KFile System Bookmarks", "Home"),
117 KUrl(KUser().homeDir()), "user-home");
118 KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
119 "Network", I18N_NOOP2("KFile System Bookmarks", "Network"),
120 KUrl("remote:/"), "network-workgroup");
121#if defined(_WIN32_WCE)
122 // adding drives
123 foreach ( const QFileInfo& info, QDir::drives() ) {
124 QString driveIcon = "drive-harddisk";
125 KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
126 info.absoluteFilePath(), info.absoluteFilePath(),
127 KUrl(info.absoluteFilePath()), driveIcon);
128 }
129#elif !defined(Q_OS_WIN)
130 KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
131 "Root", I18N_NOOP2("KFile System Bookmarks", "Root"),
132 KUrl("/"), "folder-red");
133#endif
134 KFilePlacesItem::createSystemBookmark(d->bookmarkManager,
135 "Trash", I18N_NOOP2("KFile System Bookmarks", "Trash"),
136 KUrl("trash:/"), "user-trash");
137
138 // Force bookmarks to be saved. If on open/save dialog and the bookmarks are not saved, QFile::exists
139 // will always return false, which opening/closing all the time the open/save dialog would case the
140 // bookmarks to be added once each time, having lots of times each bookmark. This forces the defaults
141 // to be saved on the bookmarks.xml file. Of course, the complete list of bookmarks (those that come from
142 // user-places.xbel will be filled later). (ereslibre)
143 d->bookmarkManager->saveAs(file);
144 }
145
146 QString predicate("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
147 " OR "
148 "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]"
149 " OR "
150 "OpticalDisc.availableContent & 'Audio' ]"
151 " OR "
152 "StorageAccess.ignored == false ]");
153
154 if (KProtocolInfo::isKnownProtocol("mtp")) {
155 predicate.prepend("[");
156 predicate.append(" OR PortableMediaPlayer.supportedProtocols == 'mtp']");
157 }
158
159 d->predicate = Solid::Predicate::fromString(predicate);
160
161 Q_ASSERT(d->predicate.isValid());
162
163 connect(d->bookmarkManager, SIGNAL(changed(QString,QString)),
164 this, SLOT(_k_reloadBookmarks()));
165 connect(d->bookmarkManager, SIGNAL(bookmarksChanged(QString)),
166 this, SLOT(_k_reloadBookmarks()));
167
168 d->_k_reloadBookmarks();
169 QTimer::singleShot(0, this, SLOT(_k_initDeviceList()));
170}
171
172KFilePlacesModel::~KFilePlacesModel()
173{
174 delete d;
175}
176
177KUrl KFilePlacesModel::url(const QModelIndex &index) const
178{
179 return KUrl(data(index, UrlRole).toUrl());
180}
181
182bool KFilePlacesModel::setupNeeded(const QModelIndex &index) const
183{
184 return data(index, SetupNeededRole).toBool();
185}
186
187KIcon KFilePlacesModel::icon(const QModelIndex &index) const
188{
189 return KIcon(data(index, Qt::DecorationRole).value<QIcon>());
190}
191
192QString KFilePlacesModel::text(const QModelIndex &index) const
193{
194 return data(index, Qt::DisplayRole).toString();
195}
196
197bool KFilePlacesModel::isHidden(const QModelIndex &index) const
198{
199 return data(index, HiddenRole).toBool();
200}
201
202bool KFilePlacesModel::isDevice(const QModelIndex &index) const
203{
204 if (!index.isValid())
205 return false;
206
207 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
208
209 return item->isDevice();
210}
211
212Solid::Device KFilePlacesModel::deviceForIndex(const QModelIndex &index) const
213{
214 if (!index.isValid())
215 return Solid::Device();
216
217 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
218
219 if (item->isDevice()) {
220 return item->device();
221 } else {
222 return Solid::Device();
223 }
224}
225
226KBookmark KFilePlacesModel::bookmarkForIndex(const QModelIndex &index) const
227{
228 if (!index.isValid())
229 return KBookmark();
230
231 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
232
233 if (!item->isDevice()) {
234 return item->bookmark();
235 } else {
236 return KBookmark();
237 }
238}
239
240QVariant KFilePlacesModel::data(const QModelIndex &index, int role) const
241{
242 if (!index.isValid())
243 return QVariant();
244
245 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
246 return item->data(role);
247}
248
249QModelIndex KFilePlacesModel::index(int row, int column, const QModelIndex &parent) const
250{
251 if (row<0 || column!=0 || row>=d->items.size())
252 return QModelIndex();
253
254 if (parent.isValid())
255 return QModelIndex();
256
257 return createIndex(row, column, d->items.at(row));
258}
259
260QModelIndex KFilePlacesModel::parent(const QModelIndex &child) const
261{
262 Q_UNUSED(child);
263 return QModelIndex();
264}
265
266int KFilePlacesModel::rowCount(const QModelIndex &parent) const
267{
268 if (parent.isValid())
269 return 0;
270 else
271 return d->items.size();
272}
273
274int KFilePlacesModel::columnCount(const QModelIndex &parent) const
275{
276 Q_UNUSED(parent)
277 // We only know 1 piece of information for a particular entry
278 return 1;
279}
280
281QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const
282{
283 int foundRow = -1;
284 int maxLength = 0;
285
286 // Search the item which is equal to the URL or at least is a parent URL.
287 // If there are more than one possible item URL candidates, choose the item
288 // which covers the bigger range of the URL.
289 for (int row = 0; row<d->items.size(); ++row) {
290 KFilePlacesItem *item = d->items[row];
291 KUrl itemUrl = KUrl(item->data(UrlRole).toUrl());
292
293 if (itemUrl.isParentOf(url)) {
294 const int length = itemUrl.prettyUrl().length();
295 if (length > maxLength) {
296 foundRow = row;
297 maxLength = length;
298 }
299 }
300 }
301
302 if (foundRow==-1)
303 return QModelIndex();
304 else
305 return createIndex(foundRow, 0, d->items[foundRow]);
306}
307
308void KFilePlacesModel::Private::_k_initDeviceList()
309{
310 Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance();
311
312 connect(notifier, SIGNAL(deviceAdded(QString)),
313 q, SLOT(_k_deviceAdded(QString)));
314 connect(notifier, SIGNAL(deviceRemoved(QString)),
315 q, SLOT(_k_deviceRemoved(QString)));
316
317 const QList<Solid::Device> &deviceList = Solid::Device::listFromQuery(predicate);
318
319 foreach(const Solid::Device &device, deviceList) {
320 availableDevices << device.udi();
321 }
322
323 _k_reloadBookmarks();
324}
325
326void KFilePlacesModel::Private::_k_deviceAdded(const QString &udi)
327{
328 Solid::Device d(udi);
329
330 if (predicate.matches(d)) {
331 availableDevices << udi;
332 _k_reloadBookmarks();
333 }
334}
335
336void KFilePlacesModel::Private::_k_deviceRemoved(const QString &udi)
337{
338 if (availableDevices.contains(udi)) {
339 availableDevices.remove(udi);
340 _k_reloadBookmarks();
341 }
342}
343
344void KFilePlacesModel::Private::_k_itemChanged(const QString &id)
345{
346 for (int row = 0; row<items.size(); ++row) {
347 if (items.at(row)->id()==id) {
348 QModelIndex index = q->index(row, 0);
349 emit q->dataChanged(index, index);
350 }
351 }
352}
353
354void KFilePlacesModel::Private::_k_reloadBookmarks()
355{
356 QList<KFilePlacesItem*> currentItems = loadBookmarkList();
357
358 QList<KFilePlacesItem*>::Iterator it_i = items.begin();
359 QList<KFilePlacesItem*>::Iterator it_c = currentItems.begin();
360
361 QList<KFilePlacesItem*>::Iterator end_i = items.end();
362 QList<KFilePlacesItem*>::Iterator end_c = currentItems.end();
363
364 while (it_i!=end_i || it_c!=end_c) {
365 if (it_i==end_i && it_c!=end_c) {
366 int row = items.count();
367
368 q->beginInsertRows(QModelIndex(), row, row);
369 it_i = items.insert(it_i, *it_c);
370 ++it_i;
371 it_c = currentItems.erase(it_c);
372
373 end_i = items.end();
374 end_c = currentItems.end();
375 q->endInsertRows();
376
377 } else if (it_i!=end_i && it_c==end_c) {
378 int row = items.indexOf(*it_i);
379
380 q->beginRemoveRows(QModelIndex(), row, row);
381 delete *it_i;
382 it_i = items.erase(it_i);
383
384 end_i = items.end();
385 end_c = currentItems.end();
386 q->endRemoveRows();
387
388 } else if ((*it_i)->id()==(*it_c)->id()) {
389 bool shouldEmit = !((*it_i)->bookmark()==(*it_c)->bookmark());
390 (*it_i)->setBookmark((*it_c)->bookmark());
391 if (shouldEmit) {
392 int row = items.indexOf(*it_i);
393 QModelIndex idx = q->index(row, 0);
394 emit q->dataChanged(idx, idx);
395 }
396 ++it_i;
397 ++it_c;
398 } else if ((*it_i)->id()!=(*it_c)->id()) {
399 int row = items.indexOf(*it_i);
400
401 if (it_i+1!=end_i && (*(it_i+1))->id()==(*it_c)->id()) { // if the next one matches, it's a remove
402 q->beginRemoveRows(QModelIndex(), row, row);
403 delete *it_i;
404 it_i = items.erase(it_i);
405
406 end_i = items.end();
407 end_c = currentItems.end();
408 q->endRemoveRows();
409 } else {
410 q->beginInsertRows(QModelIndex(), row, row);
411 it_i = items.insert(it_i, *it_c);
412 ++it_i;
413 it_c = currentItems.erase(it_c);
414
415 end_i = items.end();
416 end_c = currentItems.end();
417 q->endInsertRows();
418 }
419 }
420 }
421
422 qDeleteAll(currentItems);
423 currentItems.clear();
424}
425
426QList<KFilePlacesItem *> KFilePlacesModel::Private::loadBookmarkList()
427{
428 QList<KFilePlacesItem*> items;
429
430 KBookmarkGroup root = bookmarkManager->root();
431 KBookmark bookmark = root.first();
432 QSet<QString> devices = availableDevices;
433
434 while (!bookmark.isNull()) {
435 QString udi = bookmark.metaDataItem("UDI");
436 QString appName = bookmark.metaDataItem("OnlyInApp");
437 bool deviceAvailable = devices.remove(udi);
438
439 bool allowedHere = appName.isEmpty() || (appName==KGlobal::mainComponent().componentName());
440
441 if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
442 KFilePlacesItem *item;
443 if (deviceAvailable) {
444 item = new KFilePlacesItem(bookmarkManager, bookmark.address(), udi);
445 // TODO: Update bookmark internal element
446 } else {
447 item = new KFilePlacesItem(bookmarkManager, bookmark.address());
448 }
449 connect(item, SIGNAL(itemChanged(QString)),
450 q, SLOT(_k_itemChanged(QString)));
451 items << item;
452 }
453
454 bookmark = root.next(bookmark);
455 }
456
457 // Add bookmarks for the remaining devices, they were previously unknown
458 foreach (const QString &udi, devices) {
459 bookmark = KFilePlacesItem::createDeviceBookmark(bookmarkManager, udi);
460 if (!bookmark.isNull()) {
461 KFilePlacesItem *item = new KFilePlacesItem(bookmarkManager,
462 bookmark.address(), udi);
463 connect(item, SIGNAL(itemChanged(QString)),
464 q, SLOT(_k_itemChanged(QString)));
465 // TODO: Update bookmark internal element
466 items << item;
467 }
468 }
469
470 return items;
471}
472
473void KFilePlacesModel::Private::reloadAndSignal()
474{
475 bookmarkManager->emitChanged(bookmarkManager->root()); // ... we'll get relisted anyway
476}
477
478Qt::DropActions KFilePlacesModel::supportedDropActions() const
479{
480 return Qt::ActionMask;
481}
482
483Qt::ItemFlags KFilePlacesModel::flags(const QModelIndex &index) const
484{
485 Qt::ItemFlags res = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
486
487 if (index.isValid())
488 res|= Qt::ItemIsDragEnabled;
489
490 if (!index.isValid())
491 res|= Qt::ItemIsDropEnabled;
492
493 return res;
494}
495
496static QString _k_internalMimetype(const KFilePlacesModel * const self)
497{
498 return QString("application/x-kfileplacesmodel-")+QString::number((qptrdiff)self);
499}
500
501QStringList KFilePlacesModel::mimeTypes() const
502{
503 QStringList types;
504
505 types << _k_internalMimetype(this) << "text/uri-list";
506
507 return types;
508}
509
510QMimeData *KFilePlacesModel::mimeData(const QModelIndexList &indexes) const
511{
512 KUrl::List urls;
513 QByteArray itemData;
514
515 QDataStream stream(&itemData, QIODevice::WriteOnly);
516
517 foreach (const QModelIndex &index, indexes) {
518 KUrl itemUrl = url(index);
519 if (itemUrl.isValid())
520 urls << itemUrl;
521 stream << index.row();
522 }
523
524 QMimeData *mimeData = new QMimeData();
525
526 if (!urls.isEmpty())
527 urls.populateMimeData(mimeData);
528
529 mimeData->setData(_k_internalMimetype(this), itemData);
530
531 return mimeData;
532}
533
534bool KFilePlacesModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
535 int row, int column, const QModelIndex &parent)
536{
537 if (action == Qt::IgnoreAction)
538 return true;
539
540 if (column > 0)
541 return false;
542
543 if (row==-1 && parent.isValid()) {
544 return false; // Don't allow to move an item onto another one,
545 // too easy for the user to mess something up
546 // If we really really want to allow copying files this way,
547 // let's do it in the views to get the good old drop menu
548 }
549
550
551 KBookmark afterBookmark;
552
553 if (row==-1) {
554 // The dropped item is moved or added to the last position
555
556 KFilePlacesItem *lastItem = d->items.last();
557 afterBookmark = lastItem->bookmark();
558
559 } else {
560 // The dropped item is moved or added before position 'row', ie after position 'row-1'
561
562 if (row>0) {
563 KFilePlacesItem *afterItem = d->items[row-1];
564 afterBookmark = afterItem->bookmark();
565 }
566 }
567
568 if (data->hasFormat(_k_internalMimetype(this))) {
569 // The operation is an internal move
570 QByteArray itemData = data->data(_k_internalMimetype(this));
571 QDataStream stream(&itemData, QIODevice::ReadOnly);
572 int itemRow;
573
574 stream >> itemRow;
575
576 KFilePlacesItem *item = d->items[itemRow];
577 KBookmark bookmark = item->bookmark();
578
579 int destRow = row == -1 ? d->items.count() : row;
580 // The item is not moved when the drop indicator is on either item edge
581 if (itemRow == destRow || itemRow + 1 == destRow) {
582 return false;
583 }
584
585 beginMoveRows(QModelIndex(), itemRow, itemRow, QModelIndex(), destRow);
586 d->bookmarkManager->root().moveBookmark(bookmark, afterBookmark);
587 // Move item ourselves so that _k_reloadBookmarks() does not consider
588 // the move as a remove + insert.
589 //
590 // 2nd argument of QList::move() expects the final destination index,
591 // but 'row' is the value of the destination index before the moved
592 // item has been removed from its original position. That is why we
593 // adjust if necessary.
594 d->items.move(itemRow, itemRow < destRow ? (destRow - 1) : destRow);
595 endMoveRows();
596 } else if (data->hasFormat("text/uri-list")) {
597 // The operation is an add
598 KUrl::List urls = KUrl::List::fromMimeData(data);
599
600 KBookmarkGroup group = d->bookmarkManager->root();
601
602 foreach (const KUrl &url, urls) {
603 // TODO: use KIO::stat in order to get the UDS_DISPLAY_NAME too
604 KMimeType::Ptr mimetype = KMimeType::mimeType(KIO::NetAccess::mimetype(url, 0));
605
606 if (!mimetype) {
607 kWarning() << "URL not added to Places as mimetype could not be determined!";
608 continue;
609 }
610
611 if (!mimetype->is("inode/directory")) {
612 // Only directories are allowed
613 continue;
614 }
615
616 KBookmark bookmark = KFilePlacesItem::createBookmark(d->bookmarkManager,
617 url.fileName(), url,
618 mimetype->iconName(url));
619 group.moveBookmark(bookmark, afterBookmark);
620 afterBookmark = bookmark;
621 }
622
623 } else {
624 // Oops, shouldn't happen thanks to mimeTypes()
625 kWarning() << ": received wrong mimedata, " << data->formats();
626 return false;
627 }
628
629 d->reloadAndSignal();
630
631 return true;
632}
633
634void KFilePlacesModel::addPlace(const QString &text, const KUrl &url,
635 const QString &iconName, const QString &appName)
636{
637 addPlace(text, url, iconName, appName, QModelIndex());
638}
639
640void KFilePlacesModel::addPlace(const QString &text, const KUrl &url,
641 const QString &iconName, const QString &appName,
642 const QModelIndex &after)
643{
644 KBookmark bookmark = KFilePlacesItem::createBookmark(d->bookmarkManager,
645 text, url, iconName);
646
647 if (!appName.isEmpty()) {
648 bookmark.setMetaDataItem("OnlyInApp", appName);
649 }
650
651 if (after.isValid()) {
652 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(after.internalPointer());
653 d->bookmarkManager->root().moveBookmark(bookmark, item->bookmark());
654 }
655
656 d->reloadAndSignal();
657}
658
659void KFilePlacesModel::editPlace(const QModelIndex &index, const QString &text, const KUrl &url,
660 const QString &iconName, const QString &appName)
661{
662 if (!index.isValid()) return;
663
664 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
665
666 if (item->isDevice()) return;
667
668 KBookmark bookmark = item->bookmark();
669
670 if (bookmark.isNull()) return;
671
672 bookmark.setFullText(text);
673 bookmark.setUrl(url);
674 bookmark.setIcon(iconName);
675 bookmark.setMetaDataItem("OnlyInApp", appName);
676
677 d->reloadAndSignal();
678 emit dataChanged(index, index);
679}
680
681void KFilePlacesModel::removePlace(const QModelIndex &index) const
682{
683 if (!index.isValid()) return;
684
685 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
686
687 if (item->isDevice()) return;
688
689 KBookmark bookmark = item->bookmark();
690
691 if (bookmark.isNull()) return;
692
693 d->bookmarkManager->root().deleteBookmark(bookmark);
694 d->reloadAndSignal();
695}
696
697void KFilePlacesModel::setPlaceHidden(const QModelIndex &index, bool hidden)
698{
699 if (!index.isValid()) return;
700
701 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
702
703 KBookmark bookmark = item->bookmark();
704
705 if (bookmark.isNull()) return;
706
707 bookmark.setMetaDataItem("IsHidden", (hidden ? "true" : "false"));
708
709 d->reloadAndSignal();
710 emit dataChanged(index, index);
711}
712
713int KFilePlacesModel::hiddenCount() const
714{
715 int rows = rowCount();
716 int hidden = 0;
717
718 for (int i=0; i<rows; ++i) {
719 if (isHidden(index(i, 0))) {
720 hidden++;
721 }
722 }
723
724 return hidden;
725}
726
727QAction *KFilePlacesModel::teardownActionForIndex(const QModelIndex &index) const
728{
729 Solid::Device device = deviceForIndex(index);
730
731 if (device.is<Solid::StorageAccess>() && device.as<Solid::StorageAccess>()->isAccessible()) {
732
733 Solid::StorageDrive *drive = device.as<Solid::StorageDrive>();
734
735 if (drive==0) {
736 drive = device.parent().as<Solid::StorageDrive>();
737 }
738
739 bool hotpluggable = false;
740 bool removable = false;
741
742 if (drive!=0) {
743 hotpluggable = drive->isHotpluggable();
744 removable = drive->isRemovable();
745 }
746
747 QString iconName;
748 QString text;
749 QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
750
751 if (device.is<Solid::OpticalDisc>()) {
752 text = i18n("&Release '%1'", label);
753 } else if (removable || hotpluggable) {
754 text = i18n("&Safely Remove '%1'", label);
755 iconName = "media-eject";
756 } else {
757 text = i18n("&Unmount '%1'", label);
758 iconName = "media-eject";
759 }
760
761 if (!iconName.isEmpty()) {
762 return new QAction(KIcon(iconName), text, 0);
763 } else {
764 return new QAction(text, 0);
765 }
766 }
767
768 return 0;
769}
770
771QAction *KFilePlacesModel::ejectActionForIndex(const QModelIndex &index) const
772{
773 Solid::Device device = deviceForIndex(index);
774
775 if (device.is<Solid::OpticalDisc>()) {
776
777 QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
778 QString text = i18n("&Eject '%1'", label);
779
780 return new QAction(KIcon("media-eject"), text, 0);
781 }
782
783 return 0;
784}
785
786void KFilePlacesModel::requestTeardown(const QModelIndex &index)
787{
788 Solid::Device device = deviceForIndex(index);
789 Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
790
791 if (access!=0) {
792 connect(access, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString)),
793 this, SLOT(_k_storageTeardownDone(Solid::ErrorType,QVariant)));
794
795 access->teardown();
796 }
797}
798
799void KFilePlacesModel::requestEject(const QModelIndex &index)
800{
801 Solid::Device device = deviceForIndex(index);
802
803 Solid::OpticalDrive *drive = device.parent().as<Solid::OpticalDrive>();
804
805 if (drive!=0) {
806 connect(drive, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString)),
807 this, SLOT(_k_storageTeardownDone(Solid::ErrorType,QVariant)));
808
809 drive->eject();
810 } else {
811 QString label = data(index, Qt::DisplayRole).toString().replace('&',"&&");
812 QString message = i18n("The device '%1' is not a disk and cannot be ejected.", label);
813 emit errorMessage(message);
814 }
815}
816
817void KFilePlacesModel::requestSetup(const QModelIndex &index)
818{
819 Solid::Device device = deviceForIndex(index);
820
821 if (device.is<Solid::StorageAccess>()
822 && !d->setupInProgress.contains(device.as<Solid::StorageAccess>())
823 && !device.as<Solid::StorageAccess>()->isAccessible()) {
824
825 Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
826
827 d->setupInProgress[access] = index;
828
829 connect(access, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString)),
830 this, SLOT(_k_storageSetupDone(Solid::ErrorType,QVariant)));
831
832 access->setup();
833 }
834}
835
836void KFilePlacesModel::Private::_k_storageSetupDone(Solid::ErrorType error, QVariant errorData)
837{
838 QPersistentModelIndex index = setupInProgress.take(q->sender());
839
840 if (!index.isValid()) {
841 return;
842 }
843
844 if (!error) {
845 emit q->setupDone(index, true);
846 } else {
847 if (errorData.isValid()) {
848 emit q->errorMessage(i18n("An error occurred while accessing '%1', the system responded: %2",
849 q->text(index),
850 errorData.toString()));
851 } else {
852 emit q->errorMessage(i18n("An error occurred while accessing '%1'",
853 q->text(index)));
854 }
855 emit q->setupDone(index, false);
856 }
857
858}
859
860void KFilePlacesModel::Private::_k_storageTeardownDone(Solid::ErrorType error, QVariant errorData)
861{
862 if (error && errorData.isValid()) {
863 emit q->errorMessage(errorData.toString());
864 }
865}
866
867#include "kfileplacesmodel.moc"
KBookmarkGroup
KBookmarkGroup::next
KBookmark next(const KBookmark &current) const
KBookmarkGroup::first
KBookmark first() const
KBookmarkManager
KBookmarkManager::managerForExternalFile
static KBookmarkManager * managerForExternalFile(const QString &bookmarksFile)
KBookmark
KBookmark::setMetaDataItem
void setMetaDataItem(const QString &key, const QString &value, MetaDataOverwriteMode mode=OverwriteMetaData)
KBookmark::isNull
bool isNull() const
KBookmark::setUrl
void setUrl(const KUrl &url)
KBookmark::setFullText
void setFullText(const QString &fullText)
KBookmark::address
QString address() const
KBookmark::setIcon
void setIcon(const QString &icon)
KBookmark::metaDataItem
QString metaDataItem(const QString &key) const
KComponentData::componentName
QString componentName() const
KFilePlacesItem
Definition: kfileplacesitem_p.h:41
KFilePlacesItem::createDeviceBookmark
static KBookmark createDeviceBookmark(KBookmarkManager *manager, const QString &udi)
Definition: kfileplacesitem.cpp:277
KFilePlacesItem::createSystemBookmark
static KBookmark createSystemBookmark(KBookmarkManager *manager, const QString &untranslatedLabel, const QString &translatedLabel, const KUrl &url, const QString &iconName)
Definition: kfileplacesitem.cpp:261
KFilePlacesItem::bookmark
KBookmark bookmark() const
Definition: kfileplacesitem.cpp:91
KFilePlacesItem::isDevice
bool isDevice() const
Definition: kfileplacesitem.cpp:86
KFilePlacesItem::device
Solid::Device device() const
Definition: kfileplacesitem.cpp:112
KFilePlacesItem::createBookmark
static KBookmark createBookmark(KBookmarkManager *manager, const QString &label, const KUrl &url, const QString &iconName, KFilePlacesItem *after=0)
Definition: kfileplacesitem.cpp:234
KFilePlacesItem::data
QVariant data(int role) const
Definition: kfileplacesitem.cpp:131
KFilePlacesModel
This class is a list view model.
Definition: kfileplacesmodel.h:41
KFilePlacesModel::isDevice
bool isDevice(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:202
KFilePlacesModel::ejectActionForIndex
QAction * ejectActionForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:771
KFilePlacesModel::isHidden
bool isHidden(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:197
KFilePlacesModel::requestSetup
void requestSetup(const QModelIndex &index)
Definition: kfileplacesmodel.cpp:817
KFilePlacesModel::setupNeeded
bool setupNeeded(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:182
KFilePlacesModel::removePlace
void removePlace(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:681
KFilePlacesModel::data
QVariant data(const QModelIndex &index, int role) const
Get a visible data based on Qt role for the given index.
Definition: kfileplacesmodel.cpp:240
KFilePlacesModel::teardownActionForIndex
QAction * teardownActionForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:727
KFilePlacesModel::deviceForIndex
Solid::Device deviceForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:212
KFilePlacesModel::parent
QModelIndex parent(const QModelIndex &child) const
Get the parent QModelIndex for the given model child.
Definition: kfileplacesmodel.cpp:260
KFilePlacesModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
Get the number of rows for a model index.
Definition: kfileplacesmodel.cpp:266
KFilePlacesModel::mimeData
QMimeData * mimeData(const QModelIndexList &indexes) const
Definition: kfileplacesmodel.cpp:510
KFilePlacesModel::dropMimeData
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Definition: kfileplacesmodel.cpp:534
KFilePlacesModel::bookmarkForIndex
KBookmark bookmarkForIndex(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:226
KFilePlacesModel::requestTeardown
void requestTeardown(const QModelIndex &index)
Definition: kfileplacesmodel.cpp:786
KFilePlacesModel::hiddenCount
int hiddenCount() const
Definition: kfileplacesmodel.cpp:713
KFilePlacesModel::icon
KIcon icon(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:187
KFilePlacesModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const
Get the number of columns for a model index.
Definition: kfileplacesmodel.cpp:274
KFilePlacesModel::closestItem
QModelIndex closestItem(const KUrl &url) const
Returns the closest item for the URL url.
Definition: kfileplacesmodel.cpp:281
KFilePlacesModel::HiddenRole
@ HiddenRole
Definition: kfileplacesmodel.h:46
KFilePlacesModel::SetupNeededRole
@ SetupNeededRole
Definition: kfileplacesmodel.h:47
KFilePlacesModel::UrlRole
@ UrlRole
Definition: kfileplacesmodel.h:45
KFilePlacesModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:483
KFilePlacesModel::addPlace
void addPlace(const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
Definition: kfileplacesmodel.cpp:634
KFilePlacesModel::editPlace
void editPlace(const QModelIndex &index, const QString &text, const KUrl &url, const QString &iconName=QString(), const QString &appName=QString())
Definition: kfileplacesmodel.cpp:659
KFilePlacesModel::mimeTypes
QStringList mimeTypes() const
Definition: kfileplacesmodel.cpp:501
KFilePlacesModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Get the children model index for the given row and column.
Definition: kfileplacesmodel.cpp:249
KFilePlacesModel::setupDone
void setupDone(const QModelIndex &index, bool success)
KFilePlacesModel::supportedDropActions
Qt::DropActions supportedDropActions() const
Definition: kfileplacesmodel.cpp:478
KFilePlacesModel::url
KUrl url(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:177
KFilePlacesModel::text
QString text(const QModelIndex &index) const
Definition: kfileplacesmodel.cpp:192
KFilePlacesModel::~KFilePlacesModel
~KFilePlacesModel()
Definition: kfileplacesmodel.cpp:172
KFilePlacesModel::KFilePlacesModel
KFilePlacesModel(QObject *parent=0)
Definition: kfileplacesmodel.cpp:90
KFilePlacesModel::requestEject
void requestEject(const QModelIndex &index)
Definition: kfileplacesmodel.cpp:799
KFilePlacesModel::errorMessage
void errorMessage(const QString &message)
KFilePlacesModel::setPlaceHidden
void setPlaceHidden(const QModelIndex &index, bool hidden)
Definition: kfileplacesmodel.cpp:697
KIO::NetAccess::mimetype
static QString mimetype(const KUrl &url, QWidget *window)
KIcon
KMimeType::mimeType
static Ptr mimeType(const QString &name, FindByNameOption options=ResolveAliases)
KSharedPtr
KStandardDirs
KStandardDirs::localxdgdatadir
QString localxdgdatadir() const
KUrl::List
KUrl::List::populateMimeData
void populateMimeData(const KUrl::List &mostLocalUrls, QMimeData *mimeData, const KUrl::MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
KUrl::List::fromMimeData
static KUrl::List fromMimeData(const QMimeData *mimeData, DecodeOptions decodeOptions, KUrl::MetaDataMap *metaData=0)
KUrl
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
KUser
QAbstractItemModel
QAction
QList
QMap
QObject
QSet
Solid::DeviceNotifier
Solid::DeviceNotifier::instance
static DeviceNotifier * instance()
Solid::Device
Solid::Device::udi
QString udi() const
Solid::Device::parent
Device parent() const
Solid::Device::is
bool is() const
Solid::Device::listFromQuery
static QList< Device > listFromQuery(const Predicate &predicate, const QString &parentUdi=QString())
Solid::Device::as
DevIface * as()
Solid::OpticalDisc
Solid::OpticalDrive
Solid::OpticalDrive::eject
bool eject()
Solid::Predicate
Solid::Predicate::fromString
static Predicate fromString(const QString &predicate)
Solid::StorageAccess
Solid::StorageAccess::isAccessible
bool isAccessible() const
Solid::StorageDrive
Solid::StorageDrive::isHotpluggable
bool isHotpluggable() const
Solid::StorageDrive::isRemovable
bool isRemovable() const
devicenotifier.h
kWarning
#define kWarning
kbookmark.h
kbookmarkmanager.h
I18N_NOOP2
I18N_NOOP2("KCharSelect section name", "African Scripts")
kcomponentdata.h
kdebug.h
kfileitem.h
kfileplacesitem_p.h
_k_internalMimetype
static QString _k_internalMimetype(const KFilePlacesModel *const self)
Definition: kfileplacesmodel.cpp:496
kfileplacesmodel.h
kglobal.h
kicon.h
klocale.h
i18n
QString i18n(const char *text)
kmimetype.h
kprotocolinfo.h
kstandarddirs.h
kuser.h
access
int access(const QString &path, int mode)
KGlobal::mainComponent
const KComponentData & mainComponent()
mimetype
MimetypeJob * mimetype(const KUrl &url, JobFlags flags=DefaultFlags)
types
QStringList types(Mode mode=Writing)
group
group
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
homeDir
QString homeDir(const QString &user)
label
QString label(StandardShortcut id)
notifier
SOLID_EXPORT Notifier * notifier()
Solid::ErrorType
ErrorType
netaccess.h
opticaldisc.h
opticaldrive.h
portablemediaplayer.h
predicate.h
storageaccess.h
storagedrive.h
storagevolume.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KFile

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

kdelibs-4.14.38 API Reference

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