1 | /*************************************************************************** |
2 | * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> * |
3 | * * |
4 | * This program is free software; you can redistribute it and/or modify * |
5 | * it under the terms of the GNU General Public License as published by * |
6 | * the Free Software Foundation; either version 2 of the License, or * |
7 | * (at your option) any later version. * |
8 | * * |
9 | * This program 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 * |
12 | * GNU General Public License for more details. * |
13 | * * |
14 | * You should have received a copy of the GNU General Public License * |
15 | * along with this program; if not, write to the * |
16 | * Free Software Foundation, Inc., * |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * |
18 | ***************************************************************************/ |
19 | |
20 | #ifndef PLACESITEMMODEL_H |
21 | #define PLACESITEMMODEL_H |
22 | |
23 | #include <config-baloo.h> |
24 | |
25 | #include <kitemviews/kstandarditemmodel.h> |
26 | |
27 | #include <KUrl> |
28 | #include <QHash> |
29 | #include <QList> |
30 | #include <QSet> |
31 | #include <Solid/Predicate> |
32 | #include <Solid/StorageAccess> |
33 | |
34 | class KBookmark; |
35 | class KBookmarkManager; |
36 | class PlacesItem; |
37 | class QAction; |
38 | class QTimer; |
39 | |
40 | // #define PLACESITEMMODEL_DEBUG |
41 | |
42 | /** |
43 | * @brief Model for maintaining the bookmarks of the places panel. |
44 | * |
45 | * It is compatible to the KFilePlacesModel from kdelibs but adds |
46 | * the ability to have groups for places. |
47 | */ |
48 | class PlacesItemModel: public KStandardItemModel |
49 | { |
50 | Q_OBJECT |
51 | |
52 | public: |
53 | explicit PlacesItemModel(QObject* parent = 0); |
54 | virtual ~PlacesItemModel(); |
55 | |
56 | /** |
57 | * @return A new instance of a places item with the given |
58 | * attributes. |
59 | */ |
60 | PlacesItem* createPlacesItem(const QString& text, |
61 | const KUrl& url, |
62 | const QString& iconName = QString()); |
63 | |
64 | PlacesItem* placesItem(int index) const; |
65 | |
66 | /** |
67 | * If set to true, all items that are marked as hidden |
68 | * will be shown in the view. The items will |
69 | * stay marked as hidden, which is visually indicated |
70 | * by the view by desaturating the icon and the text. |
71 | */ |
72 | void setHiddenItemsShown(bool show); |
73 | bool hiddenItemsShown() const; |
74 | |
75 | /** |
76 | * @return Number of items that are marked as hidden. |
77 | * Note that this does not mean that the items |
78 | * are really hidden |
79 | * (see PlacesItemModel::setHiddenItemsShown()). |
80 | */ |
81 | int hiddenCount() const; |
82 | |
83 | /** |
84 | * Search the item which is equal to the URL or at least |
85 | * is a parent URL. If there are more than one possible |
86 | * candidates, return the item which covers the biggest |
87 | * range of the URL. -1 is returned if no closest item |
88 | * could be found. |
89 | */ |
90 | int closestItem(const KUrl& url) const; |
91 | |
92 | /** |
93 | * Appends the item \a item as last element of the group |
94 | * the item belongs to. If no item with the same group is |
95 | * present, the item gets appended as last element of the |
96 | * model. PlacesItemModel takes the ownership |
97 | * of the item. |
98 | */ |
99 | void appendItemToGroup(PlacesItem* item); |
100 | |
101 | QAction* ejectAction(int index) const; |
102 | QAction* teardownAction(int index) const; |
103 | |
104 | void requestEject(int index); |
105 | void requestTeardown(int index); |
106 | |
107 | bool storageSetupNeeded(int index) const; |
108 | void requestStorageSetup(int index); |
109 | |
110 | /** @reimp */ |
111 | virtual QMimeData* createMimeData(const KItemSet& indexes) const; |
112 | |
113 | /** @reimp */ |
114 | virtual bool supportsDropping(int index) const; |
115 | |
116 | void dropMimeDataBefore(int index, const QMimeData* mimeData); |
117 | |
118 | /** |
119 | * @return Converts the URL, which contains "virtual" URLs for system-items like |
120 | * "search:/documents" into a Query-URL that will be handled by |
121 | * the corresponding IO-slave. Virtual URLs for bookmarks are used to |
122 | * be independent from internal format changes. |
123 | */ |
124 | static KUrl convertedUrl(const KUrl& url); |
125 | |
126 | virtual void clear(); |
127 | signals: |
128 | void errorMessage(const QString& message); |
129 | void storageSetupDone(int index, bool success); |
130 | |
131 | protected: |
132 | virtual void onItemInserted(int index); |
133 | virtual void onItemRemoved(int index, KStandardItem* removedItem); |
134 | virtual void onItemChanged(int index, const QSet<QByteArray>& changedRoles); |
135 | |
136 | private slots: |
137 | void slotDeviceAdded(const QString& udi); |
138 | void slotDeviceRemoved(const QString& udi); |
139 | void slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData); |
140 | void slotStorageSetupDone(Solid::ErrorType error, const QVariant& errorData, const QString& udi); |
141 | void hideItem(); |
142 | |
143 | /** |
144 | * Updates the bookmarks from the model corresponding to the changed |
145 | * bookmarks stored by the bookmark-manager. Is called whenever the bookmarks |
146 | * have been changed by another application. |
147 | */ |
148 | void updateBookmarks(); |
149 | |
150 | /** |
151 | * Saves the bookmarks and indicates to other applications that the |
152 | * state of the bookmarks has been changed. Is only called by the |
153 | * timeout of m_saveBookmarksTimer to prevent unnecessary savings. |
154 | */ |
155 | void saveBookmarks(); |
156 | private: |
157 | struct SystemBookmarkData; |
158 | |
159 | /** |
160 | * Loads the bookmarks from the bookmark-manager and creates items for |
161 | * the model or moves hidden items to m_bookmarkedItems. |
162 | */ |
163 | void loadBookmarks(); |
164 | |
165 | /** |
166 | * @return True, if the bookmark can be accepted in the context of the |
167 | * current application (e.g. bookmarks from other applications |
168 | * will be ignored). |
169 | */ |
170 | bool acceptBookmark(const KBookmark& bookmark, |
171 | const QSet<QString>& availableDevices) const; |
172 | |
173 | /** |
174 | * Creates a PlacesItem for a system-bookmark: |
175 | * - PlacesItem::isSystemItem() will return true |
176 | * - Default view-properties will be created for "Search For" items |
177 | * The item is not inserted to the model yet. |
178 | */ |
179 | PlacesItem* createSystemPlacesItem(const SystemBookmarkData& data); |
180 | |
181 | /** |
182 | * Creates system bookmarks that are shown per default and can |
183 | * only be hidden but not removed. The result will be stored |
184 | * in m_systemBookmarks. |
185 | */ |
186 | void createSystemBookmarks(); |
187 | |
188 | void initializeAvailableDevices(); |
189 | |
190 | /** |
191 | * @param index Item index related to the model. |
192 | * @return Corresponding index related to m_bookmarkedItems. |
193 | */ |
194 | int bookmarkIndex(int index) const; |
195 | |
196 | /** |
197 | * Marks the item with the index \a index as hidden and |
198 | * removes it from the model so that it gets invisible. |
199 | */ |
200 | void hideItem(int index); |
201 | |
202 | /** |
203 | * Triggers a delayed saving of bookmarks by starting |
204 | * m_saveBookmarksTimer. |
205 | */ |
206 | void triggerBookmarksSaving(); |
207 | |
208 | QString internalMimeType() const; |
209 | |
210 | /** |
211 | * @return Adjusted drop index which assures that the item is aligned |
212 | * into the same group as specified by PlacesItem::groupType(). |
213 | */ |
214 | int groupedDropIndex(int index, const PlacesItem* item) const; |
215 | |
216 | /** |
217 | * @return True if the bookmarks have the same identifiers. The identifier |
218 | * is the unique "ID"-property in case if no UDI is set, otherwise |
219 | * the UDI is used as identifier. |
220 | */ |
221 | static bool equalBookmarkIdentifiers(const KBookmark& b1, const KBookmark& b2); |
222 | |
223 | /** |
224 | * @return URL using the timeline-protocol for searching (see convertedUrl()). |
225 | */ |
226 | static KUrl createTimelineUrl(const KUrl& url); |
227 | |
228 | /** |
229 | * Helper method for createTimelineUrl(). |
230 | * @return String that represents a date-path in the format that |
231 | * the timeline-protocol expects. |
232 | */ |
233 | static QString timelineDateString(int year, int month, int day = 0); |
234 | |
235 | /** |
236 | * @return URL that can be listed by KIO and results in searching |
237 | * for a given term. The URL \a url represents a places-internal |
238 | * URL like e.g. "search:/documents" (see convertedUrl()). |
239 | */ |
240 | static KUrl createSearchUrl(const KUrl& url); |
241 | |
242 | #ifdef HAVE_BALOO |
243 | /** |
244 | * Helper method for createSearchUrl() |
245 | * @return URL that can be listed by KIO and results in searching |
246 | * for the given type |
247 | */ |
248 | static KUrl searchUrlForType(const QString& type); |
249 | #endif |
250 | |
251 | #ifdef PLACESITEMMODEL_DEBUG |
252 | void showModelState(); |
253 | #endif |
254 | |
255 | private: |
256 | bool m_fileIndexingEnabled; |
257 | bool m_hiddenItemsShown; |
258 | |
259 | QSet<QString> m_availableDevices; |
260 | Solid::Predicate m_predicate; |
261 | KBookmarkManager* m_bookmarkManager; |
262 | |
263 | struct SystemBookmarkData |
264 | { |
265 | SystemBookmarkData(const KUrl& url, |
266 | const QString& icon, |
267 | const QString& text) : |
268 | url(url), icon(icon), text(text) {} |
269 | KUrl url; |
270 | QString icon; |
271 | QString text; |
272 | }; |
273 | |
274 | QList<SystemBookmarkData> m_systemBookmarks; |
275 | QHash<KUrl, int> m_systemBookmarksIndexes; |
276 | |
277 | // Contains hidden and unhidden items that are stored as |
278 | // bookmark (the model itself only contains items that |
279 | // are shown in the view). If an entry is 0, then the |
280 | // places-item is part of the model. If an entry is not |
281 | // 0, the item is hidden and not part of the model. |
282 | QList<PlacesItem*> m_bookmarkedItems; |
283 | |
284 | // Index of the hidden item that should be removed in |
285 | // removeHiddenItem(). The removing must be done |
286 | // asynchronously as in the scope of onItemChanged() |
287 | // removing an item is not allowed. |
288 | int m_hiddenItemToRemove; |
289 | |
290 | QTimer* m_saveBookmarksTimer; |
291 | QTimer* m_updateBookmarksTimer; |
292 | |
293 | QHash<QObject*, int> m_storageSetupInProgress; |
294 | }; |
295 | |
296 | #endif |
297 | |
298 | |
299 | |