1 /***************************************************************************
2 * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
4 * Based on KFilePlacesModel from kdelibs: *
5 * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
6 * Copyright (C) 2007 David Faure <faure@kde.org> *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
22 ***************************************************************************/
24 #include "placesitemmodel.h"
27 #include <KBookmarkGroup>
28 #include <KBookmarkManager>
29 #include <KComponentData>
33 #include <KStandardDirs>
35 #include "placesitem.h"
40 #include <Solid/Device>
41 #include <Solid/DeviceNotifier>
42 #include <Solid/OpticalDisc>
43 #include <Solid/OpticalDrive>
44 #include <Solid/StorageAccess>
45 #include <Solid/StorageDrive>
48 #include <Nepomuk/ResourceManager>
52 // As long as KFilePlacesView from kdelibs is available in parallel, the
53 // system-bookmarks for "Recently Accessed" and "Search For" should be
54 // shown only inside the Places Panel. This is necessary as the stored
55 // URLs needs to get translated to a Nepomuk-search-URL on-the-fly to
56 // be independent from changes in the Nepomuk-search-URL-syntax.
57 // Hence a prefix to the application-name of the stored bookmarks is
58 // added, which is only read by PlacesItemModel.
59 const char* AppNamePrefix
= "-places-panel";
62 PlacesItemModel::PlacesItemModel(QObject
* parent
) :
63 KStandardItemModel(parent
),
64 m_nepomukRunning(false),
65 m_hiddenItemsShown(false),
70 m_systemBookmarksIndexes(),
72 m_hiddenItemToRemove(-1),
73 m_saveBookmarksTimer(0),
74 m_updateBookmarksTimer(0)
77 m_nepomukRunning
= (Nepomuk::ResourceManager::instance()->initialized());
79 const QString file
= KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
80 m_bookmarkManager
= KBookmarkManager::managerForFile(file
, "kfilePlaces");
82 createSystemBookmarks();
83 initializeAvailableDevices();
86 const int syncBookmarksTimeout
= 1000;
88 m_saveBookmarksTimer
= new QTimer(this);
89 m_saveBookmarksTimer
->setInterval(syncBookmarksTimeout
);
90 m_saveBookmarksTimer
->setSingleShot(true);
91 connect(m_saveBookmarksTimer
, SIGNAL(timeout()), this, SLOT(saveBookmarks()));
93 m_updateBookmarksTimer
= new QTimer(this);
94 m_updateBookmarksTimer
->setInterval(syncBookmarksTimeout
);
95 m_updateBookmarksTimer
->setSingleShot(true);
96 connect(m_updateBookmarksTimer
, SIGNAL(timeout()), this, SLOT(updateBookmarks()));
98 connect(m_bookmarkManager
, SIGNAL(changed(QString
,QString
)),
99 m_updateBookmarksTimer
, SLOT(start()));
100 connect(m_bookmarkManager
, SIGNAL(bookmarksChanged(QString
)),
101 m_updateBookmarksTimer
, SLOT(start()));
104 PlacesItemModel::~PlacesItemModel()
107 qDeleteAll(m_bookmarkedItems
);
108 m_bookmarkedItems
.clear();
111 PlacesItem
* PlacesItemModel::createPlacesItem(const QString
& text
,
113 const QString
& iconName
)
115 const KBookmark bookmark
= PlacesItem::createBookmark(m_bookmarkManager
, text
, url
, iconName
);
116 return new PlacesItem(bookmark
);
119 PlacesItem
* PlacesItemModel::placesItem(int index
) const
121 return dynamic_cast<PlacesItem
*>(item(index
));
124 int PlacesItemModel::hiddenCount() const
127 int hiddenItemCount
= 0;
128 foreach (const PlacesItem
* item
, m_bookmarkedItems
) {
132 if (placesItem(modelIndex
)->isHidden()) {
139 return hiddenItemCount
;
142 void PlacesItemModel::setHiddenItemsShown(bool show
)
144 if (m_hiddenItemsShown
== show
) {
148 m_hiddenItemsShown
= show
;
151 // Move all items that are part of m_bookmarkedItems to the model.
153 for (int i
= 0; i
< m_bookmarkedItems
.count(); ++i
) {
154 if (m_bookmarkedItems
[i
]) {
155 PlacesItem
* visibleItem
= new PlacesItem(*m_bookmarkedItems
[i
]);
156 delete m_bookmarkedItems
[i
];
157 m_bookmarkedItems
.removeAt(i
);
158 insertItem(modelIndex
, visibleItem
);
159 Q_ASSERT(!m_bookmarkedItems
[i
]);
164 // Move all items of the model, where the "isHidden" property is true, to
166 Q_ASSERT(m_bookmarkedItems
.count() == count());
167 for (int i
= count() - 1; i
>= 0; --i
) {
168 const PlacesItem
* visibleItem
= placesItem(i
);
169 if (visibleItem
->isHidden()) {
174 #ifdef PLACESITEMMODEL_DEBUG
175 kDebug() << "Changed visibility of hidden items";
180 bool PlacesItemModel::hiddenItemsShown() const
182 return m_hiddenItemsShown
;
185 int PlacesItemModel::closestItem(const KUrl
& url
) const
190 for (int i
= 0; i
< count(); ++i
) {
191 const KUrl itemUrl
= placesItem(i
)->url();
192 if (itemUrl
.isParentOf(url
)) {
193 const int length
= itemUrl
.prettyUrl().length();
194 if (length
> maxLength
) {
204 QAction
* PlacesItemModel::ejectAction(int index
) const
206 const PlacesItem
* item
= placesItem(index
);
207 if (item
&& item
->device().is
<Solid::OpticalDisc
>()) {
208 return new QAction(KIcon("media-eject"), i18nc("@item", "Eject '%1'", item
->text()), 0);
214 QAction
* PlacesItemModel::teardownAction(int index
) const
216 const PlacesItem
* item
= placesItem(index
);
221 Solid::Device device
= item
->device();
222 const bool providesTearDown
= device
.is
<Solid::StorageAccess
>() &&
223 device
.as
<Solid::StorageAccess
>()->isAccessible();
224 if (!providesTearDown
) {
228 Solid::StorageDrive
* drive
= device
.as
<Solid::StorageDrive
>();
230 drive
= device
.parent().as
<Solid::StorageDrive
>();
233 bool hotPluggable
= false;
234 bool removable
= false;
236 hotPluggable
= drive
->isHotpluggable();
237 removable
= drive
->isRemovable();
242 const QString label
= item
->text();
243 if (device
.is
<Solid::OpticalDisc
>()) {
244 text
= i18nc("@item", "Release '%1'", label
);
245 } else if (removable
|| hotPluggable
) {
246 text
= i18nc("@item", "Safely Remove '%1'", label
);
247 iconName
= "media-eject";
249 text
= i18nc("@item", "Unmount '%1'", label
);
250 iconName
= "media-eject";
253 if (iconName
.isEmpty()) {
254 return new QAction(text
, 0);
257 return new QAction(KIcon(iconName
), text
, 0);
260 void PlacesItemModel::requestEject(int index
)
262 const PlacesItem
* item
= placesItem(index
);
264 Solid::OpticalDrive
* drive
= item
->device().parent().as
<Solid::OpticalDrive
>();
266 connect(drive
, SIGNAL(ejectDone(Solid::ErrorType
,QVariant
,QString
)),
267 this, SLOT(slotStorageTeardownDone(Solid::ErrorType
,QVariant
)));
275 void PlacesItemModel::requestTeardown(int index
)
277 const PlacesItem
* item
= placesItem(index
);
279 Solid::StorageAccess
* access
= item
->device().as
<Solid::StorageAccess
>();
281 connect(access
, SIGNAL(teardownDone(Solid::ErrorType
,QVariant
,QString
)),
282 this, SLOT(slotStorageTeardownDone(Solid::ErrorType
,QVariant
)));
285 const QString label
= item
->text();
286 const QString message
= i18nc("@info", "The device '%1' is not a disk and cannot be ejected.", label
);
287 emit
errorMessage(message
);
292 void PlacesItemModel::onItemInserted(int index
)
294 const PlacesItem
* insertedItem
= placesItem(index
);
296 // Take care to apply the PlacesItemModel-order of the inserted item
297 // also to the bookmark-manager.
298 const KBookmark insertedBookmark
= insertedItem
->bookmark();
300 const PlacesItem
* previousItem
= placesItem(index
- 1);
301 KBookmark previousBookmark
;
303 previousBookmark
= previousItem
->bookmark();
306 m_bookmarkManager
->root().moveBookmark(insertedBookmark
, previousBookmark
);
309 if (index
== count() - 1) {
310 // The item has been appended as last item to the list. In this
311 // case assure that it is also appended after the hidden items and
312 // not before (like done otherwise).
313 m_bookmarkedItems
.append(0);
318 int bookmarkIndex
= 0;
319 while (bookmarkIndex
< m_bookmarkedItems
.count()) {
320 if (!m_bookmarkedItems
[bookmarkIndex
]) {
322 if (modelIndex
+ 1 == index
) {
328 m_bookmarkedItems
.insert(bookmarkIndex
, 0);
330 m_saveBookmarksTimer
->start();
332 #ifdef PLACESITEMMODEL_DEBUG
333 kDebug() << "Inserted item" << index
;
338 void PlacesItemModel::onItemRemoved(int index
, KStandardItem
* removedItem
)
340 PlacesItem
* placesItem
= dynamic_cast<PlacesItem
*>(removedItem
);
342 const KBookmark bookmark
= placesItem
->bookmark();
343 m_bookmarkManager
->root().deleteBookmark(bookmark
);
346 const int boomarkIndex
= bookmarkIndex(index
);
347 Q_ASSERT(!m_bookmarkedItems
[boomarkIndex
]);
348 m_bookmarkedItems
.removeAt(boomarkIndex
);
350 m_saveBookmarksTimer
->start();
352 #ifdef PLACESITEMMODEL_DEBUG
353 kDebug() << "Removed item" << index
;
358 void PlacesItemModel::onItemChanged(int index
, const QSet
<QByteArray
>& changedRoles
)
360 const PlacesItem
* changedItem
= placesItem(index
);
362 // Take care to apply the PlacesItemModel-order of the inserted item
363 // also to the bookmark-manager.
364 const KBookmark insertedBookmark
= changedItem
->bookmark();
366 const PlacesItem
* previousItem
= placesItem(index
- 1);
367 KBookmark previousBookmark
;
369 previousBookmark
= previousItem
->bookmark();
372 m_bookmarkManager
->root().moveBookmark(insertedBookmark
, previousBookmark
);
375 if (changedRoles
.contains("isHidden")) {
376 const PlacesItem
* shownItem
= placesItem(index
);
378 if (!m_hiddenItemsShown
&& shownItem
->isHidden()) {
379 m_hiddenItemToRemove
= index
;
380 QTimer::singleShot(0, this, SLOT(hideItem()));
384 m_saveBookmarksTimer
->start();
387 void PlacesItemModel::slotDeviceAdded(const QString
& udi
)
389 const Solid::Device
device(udi
);
390 if (m_predicate
.matches(device
)) {
391 m_availableDevices
<< udi
;
392 const KBookmark bookmark
= PlacesItem::createDeviceBookmark(m_bookmarkManager
, udi
);
393 appendItem(new PlacesItem(bookmark
));
397 void PlacesItemModel::slotDeviceRemoved(const QString
& udi
)
399 if (!m_availableDevices
.contains(udi
)) {
403 for (int i
= 0; i
< m_bookmarkedItems
.count(); ++i
) {
404 PlacesItem
* item
= m_bookmarkedItems
[i
];
405 if (item
&& item
->udi() == udi
) {
406 m_bookmarkedItems
.removeAt(i
);
412 for (int i
= 0; i
< count(); ++i
) {
413 if (placesItem(i
)->udi() == udi
) {
420 void PlacesItemModel::slotStorageTeardownDone(Solid::ErrorType error
, const QVariant
& errorData
)
422 if (error
&& errorData
.isValid()) {
423 emit
errorMessage(errorData
.toString());
427 void PlacesItemModel::hideItem()
429 hideItem(m_hiddenItemToRemove
);
430 m_hiddenItemToRemove
= -1;
433 void PlacesItemModel::updateBookmarks()
435 // Verify whether new bookmarks have been added or existing
436 // bookmarks have been changed.
437 KBookmarkGroup root
= m_bookmarkManager
->root();
438 KBookmark newBookmark
= root
.first();
439 while (!newBookmark
.isNull()) {
440 if (acceptBookmark(newBookmark
)) {
443 for (int i
= 0; i
< m_bookmarkedItems
.count(); ++i
) {
444 PlacesItem
* item
= m_bookmarkedItems
[i
];
446 item
= placesItem(modelIndex
);
450 const KBookmark oldBookmark
= item
->bookmark();
451 if (equalBookmarkIdentifiers(newBookmark
, oldBookmark
)) {
452 // The bookmark has been found in the model or as
453 // a hidden item. The content of the bookmark might
454 // have been changed, so an update is done.
456 if (newBookmark
.metaDataItem("UDI").isEmpty()) {
457 item
->setBookmark(newBookmark
);
464 PlacesItem
* item
= new PlacesItem(newBookmark
);
465 if (item
->isHidden() && !m_hiddenItemsShown
) {
466 m_bookmarkedItems
.append(item
);
473 newBookmark
= root
.next(newBookmark
);
476 // Remove items that are not part of the bookmark-manager anymore
478 for (int i
= m_bookmarkedItems
.count() - 1; i
>= 0; --i
) {
479 PlacesItem
* item
= m_bookmarkedItems
[i
];
480 const bool itemIsPartOfModel
= (item
== 0);
481 if (itemIsPartOfModel
) {
482 item
= placesItem(modelIndex
);
485 bool hasBeenRemoved
= true;
486 const KBookmark oldBookmark
= item
->bookmark();
487 KBookmark newBookmark
= root
.first();
488 while (!newBookmark
.isNull()) {
489 if (equalBookmarkIdentifiers(newBookmark
, oldBookmark
)) {
490 hasBeenRemoved
= false;
493 newBookmark
= root
.next(newBookmark
);
496 if (hasBeenRemoved
) {
497 if (m_bookmarkedItems
[i
]) {
498 delete m_bookmarkedItems
[i
];
499 m_bookmarkedItems
.removeAt(i
);
501 removeItem(modelIndex
);
506 if (itemIsPartOfModel
) {
512 void PlacesItemModel::saveBookmarks()
514 m_bookmarkManager
->emitChanged(m_bookmarkManager
->root());
517 void PlacesItemModel::loadBookmarks()
519 KBookmarkGroup root
= m_bookmarkManager
->root();
520 KBookmark bookmark
= root
.first();
521 QSet
<QString
> devices
= m_availableDevices
;
523 QSet
<KUrl
> missingSystemBookmarks
;
524 foreach (const SystemBookmarkData
& data
, m_systemBookmarks
) {
525 missingSystemBookmarks
.insert(data
.url
);
528 // The bookmarks might have a mixed order of places, devices and search-groups due
529 // to the compatibility with the KFilePlacesPanel. In Dolphin's places panel the
530 // items should always be collected in one group so the items are collected first
531 // in separate lists before inserting them.
532 QList
<PlacesItem
*> placesItems
;
533 QList
<PlacesItem
*> recentlyAccessedItems
;
534 QList
<PlacesItem
*> searchForItems
;
535 QList
<PlacesItem
*> devicesItems
;
537 while (!bookmark
.isNull()) {
538 const bool deviceAvailable
= devices
.remove(bookmark
.metaDataItem("UDI"));
539 if (acceptBookmark(bookmark
)) {
540 PlacesItem
* item
= new PlacesItem(bookmark
);
541 if (deviceAvailable
) {
542 devicesItems
.append(item
);
544 const KUrl url
= bookmark
.url();
545 if (missingSystemBookmarks
.contains(url
)) {
546 missingSystemBookmarks
.remove(url
);
548 // Apply the translated text to the system bookmarks, otherwise an outdated
549 // translation might be shown.
550 const int index
= m_systemBookmarksIndexes
.value(url
);
551 item
->setText(m_systemBookmarks
[index
].text
);
552 item
->setSystemItem(true);
555 switch (item
->groupType()) {
556 case PlacesItem::PlacesType
: placesItems
.append(item
); break;
557 case PlacesItem::RecentlyAccessedType
: recentlyAccessedItems
.append(item
); break;
558 case PlacesItem::SearchForType
: searchForItems
.append(item
); break;
559 case PlacesItem::DevicesType
:
560 default: Q_ASSERT(false); break;
565 bookmark
= root
.next(bookmark
);
568 if (!missingSystemBookmarks
.isEmpty()) {
569 // The current bookmarks don't contain all system-bookmarks. Add the missing
571 foreach (const SystemBookmarkData
& data
, m_systemBookmarks
) {
572 if (missingSystemBookmarks
.contains(data
.url
)) {
573 KBookmark bookmark
= PlacesItem::createBookmark(m_bookmarkManager
,
578 const QString protocol
= data
.url
.protocol();
579 if (protocol
== QLatin1String("timeline") || protocol
== QLatin1String("search")) {
580 // As long as the KFilePlacesView from kdelibs is available, the system-bookmarks
581 // for "Recently Accessed" and "Search For" should be a setting available only
582 // in the Places Panel (see description of AppNamePrefix for more details).
583 const QString appName
= KGlobal::mainComponent().componentName() + AppNamePrefix
;
584 bookmark
.setMetaDataItem("OnlyInApp", appName
);
587 PlacesItem
* item
= new PlacesItem(bookmark
);
588 item
->setSystemItem(true);
590 switch (item
->groupType()) {
591 case PlacesItem::PlacesType
: placesItems
.append(item
); break;
592 case PlacesItem::RecentlyAccessedType
: recentlyAccessedItems
.append(item
); break;
593 case PlacesItem::SearchForType
: searchForItems
.append(item
); break;
594 case PlacesItem::DevicesType
:
595 default: Q_ASSERT(false); break;
601 // Create items for devices that have not been stored as bookmark yet
602 foreach (const QString
& udi
, devices
) {
603 const KBookmark bookmark
= PlacesItem::createDeviceBookmark(m_bookmarkManager
, udi
);
604 devicesItems
.append(new PlacesItem(bookmark
));
607 QList
<PlacesItem
*> items
;
608 items
.append(placesItems
);
609 items
.append(recentlyAccessedItems
);
610 items
.append(searchForItems
);
611 items
.append(devicesItems
);
613 foreach (PlacesItem
* item
, items
) {
614 if (!m_hiddenItemsShown
&& item
->isHidden()) {
615 m_bookmarkedItems
.append(item
);
621 #ifdef PLACESITEMMODEL_DEBUG
622 kDebug() << "Loaded bookmarks";
627 bool PlacesItemModel::acceptBookmark(const KBookmark
& bookmark
) const
629 const QString udi
= bookmark
.metaDataItem("UDI");
630 const KUrl url
= bookmark
.url();
631 const QString appName
= bookmark
.metaDataItem("OnlyInApp");
632 const bool deviceAvailable
= m_availableDevices
.contains(udi
);
634 const bool allowedHere
= (appName
.isEmpty()
635 || appName
== KGlobal::mainComponent().componentName()
636 || appName
== KGlobal::mainComponent().componentName() + AppNamePrefix
)
637 && (m_nepomukRunning
|| (url
.protocol() != QLatin1String("timeline") &&
638 url
.protocol() != QLatin1String("search")));
640 return (udi
.isEmpty() && allowedHere
) || deviceAvailable
;
643 void PlacesItemModel::createSystemBookmarks()
645 Q_ASSERT(m_systemBookmarks
.isEmpty());
646 Q_ASSERT(m_systemBookmarksIndexes
.isEmpty());
648 const QString timeLineIcon
= "package_utility_time"; // TODO: Ask the Oxygen team to create
649 // a custom icon for the timeline-protocol
651 m_systemBookmarks
.append(SystemBookmarkData(KUrl(KUser().homeDir()),
653 i18nc("@item", "Home")));
654 m_systemBookmarks
.append(SystemBookmarkData(KUrl("remote:/"),
656 i18nc("@item", "Network")));
657 m_systemBookmarks
.append(SystemBookmarkData(KUrl("/"),
659 i18nc("@item", "Root")));
660 m_systemBookmarks
.append(SystemBookmarkData(KUrl("trash:/"),
662 i18nc("@item", "Trash")));
664 if (m_nepomukRunning
) {
665 m_systemBookmarks
.append(SystemBookmarkData(KUrl("timeline:/today"),
667 i18nc("@item Recently Accessed", "Today")));
668 m_systemBookmarks
.append(SystemBookmarkData(KUrl("timeline:/yesterday"),
670 i18nc("@item Recently Accessed", "Yesterday")));
671 m_systemBookmarks
.append(SystemBookmarkData(KUrl("timeline:/thismonth"),
673 i18nc("@item Recently Accessed", "This Month")));
674 m_systemBookmarks
.append(SystemBookmarkData(KUrl("timeline:/lastmonth"),
676 i18nc("@item Recently Accessed", "Last Month")));
677 m_systemBookmarks
.append(SystemBookmarkData(KUrl("search:/documents"),
679 i18nc("@item Commonly Accessed", "Documents")));
680 m_systemBookmarks
.append(SystemBookmarkData(KUrl("search:/images"),
682 i18nc("@item Commonly Accessed", "Images")));
683 m_systemBookmarks
.append(SystemBookmarkData(KUrl("search:/audio"),
685 i18nc("@item Commonly Accessed", "Audio Files")));
686 m_systemBookmarks
.append(SystemBookmarkData(KUrl("search:/videos"),
688 i18nc("@item Commonly Accessed", "Videos")));
691 for (int i
= 0; i
< m_systemBookmarks
.count(); ++i
) {
692 m_systemBookmarksIndexes
.insert(m_systemBookmarks
[i
].url
, i
);
696 void PlacesItemModel::initializeAvailableDevices()
698 m_predicate
= Solid::Predicate::fromString(
699 "[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
701 "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]"
703 "OpticalDisc.availableContent & 'Audio' ]"
705 "StorageAccess.ignored == false ]");
706 Q_ASSERT(m_predicate
.isValid());
708 Solid::DeviceNotifier
* notifier
= Solid::DeviceNotifier::instance();
709 connect(notifier
, SIGNAL(deviceAdded(QString
)), this, SLOT(slotDeviceAdded(QString
)));
710 connect(notifier
, SIGNAL(deviceRemoved(QString
)), this, SLOT(slotDeviceRemoved(QString
)));
712 const QList
<Solid::Device
>& deviceList
= Solid::Device::listFromQuery(m_predicate
);
713 foreach(const Solid::Device
& device
, deviceList
) {
714 m_availableDevices
<< device
.udi();
718 int PlacesItemModel::bookmarkIndex(int index
) const
720 int bookmarkIndex
= 0;
722 while (bookmarkIndex
< m_bookmarkedItems
.count()) {
723 if (!m_bookmarkedItems
[bookmarkIndex
]) {
724 if (modelIndex
== index
) {
732 return bookmarkIndex
>= m_bookmarkedItems
.count() ? -1 : bookmarkIndex
;
735 void PlacesItemModel::hideItem(int index
)
737 PlacesItem
* shownItem
= placesItem(index
);
742 shownItem
->setHidden(true);
743 if (m_hiddenItemsShown
) {
744 // Removing items from the model is not allowed if all hidden
745 // items should be shown.
749 const int newIndex
= bookmarkIndex(index
);
751 PlacesItem
* hiddenItem
= new PlacesItem(*shownItem
);
752 const KBookmark hiddenBookmark
= hiddenItem
->bookmark();
754 const PlacesItem
* previousItem
= placesItem(index
- 1);
755 KBookmark previousBookmark
;
757 previousBookmark
= previousItem
->bookmark();
760 const bool updateBookmark
= (m_bookmarkManager
->root().indexOf(hiddenBookmark
) >= 0);
763 if (updateBookmark
) {
764 // removeItem() also removed the bookmark from m_bookmarkManager in
765 // PlacesItemModel::onItemRemoved(). However for hidden items the
766 // bookmark should still be remembered, so readd it again:
767 m_bookmarkManager
->root().addBookmark(hiddenBookmark
);
768 m_bookmarkManager
->root().moveBookmark(hiddenBookmark
, previousBookmark
);
769 m_saveBookmarksTimer
->start();
772 m_bookmarkedItems
.insert(newIndex
, hiddenItem
);
776 bool PlacesItemModel::equalBookmarkIdentifiers(const KBookmark
& b1
, const KBookmark
& b2
)
778 const QString udi1
= b1
.metaDataItem("UDI");
779 const QString udi2
= b2
.metaDataItem("UDI");
780 if (!udi1
.isEmpty() && !udi2
.isEmpty()) {
783 return b1
.metaDataItem("ID") == b2
.metaDataItem("ID");
787 #ifdef PLACESITEMMODEL_DEBUG
788 void PlacesItemModel::showModelState()
790 kDebug() << "=================================";
791 kDebug() << "Model:";
792 kDebug() << "hidden-index model-index text";
794 for (int i
= 0; i
< m_bookmarkedItems
.count(); ++i
) {
795 if (m_bookmarkedItems
[i
]) {
796 kDebug() << i
<< "(Hidden) " << " " << m_bookmarkedItems
[i
]->dataValue("text").toString();
798 if (item(modelIndex
)) {
799 kDebug() << i
<< " " << modelIndex
<< " " << item(modelIndex
)->dataValue("text").toString();
801 kDebug() << i
<< " " << modelIndex
<< " " << "(not available yet)";
808 kDebug() << "Bookmarks:";
810 int bookmarkIndex
= 0;
811 KBookmarkGroup root
= m_bookmarkManager
->root();
812 KBookmark bookmark
= root
.first();
813 while (!bookmark
.isNull()) {
814 const QString udi
= bookmark
.metaDataItem("UDI");
815 const QString text
= udi
.isEmpty() ? bookmark
.text() : udi
;
816 if (bookmark
.metaDataItem("IsHidden") == QLatin1String("true")) {
817 kDebug() << bookmarkIndex
<< "(Hidden)" << text
;
819 kDebug() << bookmarkIndex
<< " " << text
;
822 bookmark
= root
.next(bookmark
);
828 #include "placesitemmodel.moc"