45
|
1 /****************************************************************************
|
|
2 **
|
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
4 ** Contact: Qt Software Information (qt-info@nokia.com)
|
|
5 **
|
|
6 ** This file is part of the demonstration applications of the Qt Toolkit.
|
|
7 **
|
|
8 ** $QT_BEGIN_LICENSE:LGPL$
|
|
9 ** Commercial Usage
|
|
10 ** Licensees holding valid Qt Commercial licenses may use this file in
|
|
11 ** accordance with the Qt Commercial License Agreement provided with the
|
|
12 ** Software or, alternatively, in accordance with the terms contained in
|
|
13 ** a written agreement between you and Nokia.
|
|
14 **
|
|
15 ** GNU Lesser General Public License Usage
|
|
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
17 ** General Public License version 2.1 as published by the Free Software
|
|
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
19 ** packaging of this file. Please review the following information to
|
|
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
22 **
|
|
23 ** In addition, as a special exception, Nokia gives you certain
|
|
24 ** additional rights. These rights are described in the Nokia Qt LGPL
|
|
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
|
|
26 ** package.
|
|
27 **
|
|
28 ** GNU General Public License Usage
|
|
29 ** Alternatively, this file may be used under the terms of the GNU
|
|
30 ** General Public License version 3.0 as published by the Free Software
|
|
31 ** Foundation and appearing in the file LICENSE.GPL included in the
|
|
32 ** packaging of this file. Please review the following information to
|
|
33 ** ensure the GNU General Public License version 3.0 requirements will be
|
|
34 ** met: http://www.gnu.org/copyleft/gpl.html.
|
|
35 **
|
|
36 ** If you are unsure which license is appropriate for your use, please
|
|
37 ** contact the sales department at qt-sales@nokia.com.
|
|
38 ** $QT_END_LICENSE$
|
|
39 **
|
|
40 ****************************************************************************/
|
|
41
|
|
42 import QtCore.QObject;
|
|
43 import QtCore.QAbstractItemModel;
|
|
44
|
|
45 import QtGui.QUndoCommand;
|
|
46
|
|
47
|
|
48 import bookmarks;
|
|
49
|
|
50 import autosaver;
|
|
51 import browserapplication;
|
|
52 import history;
|
|
53 import xbel;
|
|
54
|
|
55 import QtCore.QBuffer;
|
|
56 import QtCore.QFile;
|
|
57 import QtCore.QMimeData;
|
|
58
|
|
59 import QtGui.QDesktopServices;
|
|
60 import QtGui.QDragEnterEvent;
|
|
61 import QtGui.QFileDialog;
|
|
62 import QtGui.QHeaderView;
|
|
63 import QtGui.QIcon;
|
|
64 import QtGui.QMessageBox;
|
|
65 import QtGui.QToolButton;
|
|
66
|
|
67 import QtWebKit.QWebSettings;
|
|
68
|
|
69 import QtCore.QDebug;
|
|
70
|
|
71 const char[] BOOKMARKBAR = "Bookmarks Bar";
|
|
72 const char[] BOOKMARKMENU = "Bookmarks Menu";
|
|
73
|
|
74
|
|
75 /*!
|
|
76 Bookmark manager, owner of the bookmarks, loads, saves and basic tasks
|
|
77 */
|
|
78 /*
|
|
79 class AutoSaver;
|
|
80 class BookmarkNode;
|
|
81 class BookmarksModel;
|
|
82 */
|
|
83 class BookmarksManager : public QObject
|
|
84 {
|
|
85 Q_OBJECT
|
|
86
|
|
87 signals:
|
|
88 void entryAdded(BookmarkNode *item);
|
|
89 void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item);
|
|
90 void entryChanged(BookmarkNode *item);
|
|
91
|
|
92 public:
|
|
93 BookmarksManager(QObject *parent = null)
|
|
94 {
|
|
95 super(parent);
|
|
96 m_loaded = false;
|
|
97 m_saveTimer = new AutoSaver(this);
|
|
98 m_bookmarkRootNode = null;
|
|
99 m_bookmarkModel = null;
|
|
100 connect(this, SIGNAL(entryAdded(BookmarkNode *)),
|
|
101 m_saveTimer, SLOT(changeOccurred()));
|
|
102 connect(this, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)),
|
|
103 m_saveTimer, SLOT(changeOccurred()));
|
|
104 connect(this, SIGNAL(entryChanged(BookmarkNode *)),
|
|
105 m_saveTimer, SLOT(changeOccurred()));
|
|
106 }
|
|
107
|
|
108
|
|
109 ~this()
|
|
110 {
|
|
111 m_saveTimer.saveIfNeccessary();
|
|
112 }
|
|
113
|
|
114
|
|
115 void addBookmark(BookmarkNode *parent, BookmarkNode *node, int row = -1)
|
|
116 {
|
|
117 if (!m_loaded)
|
|
118 return;
|
|
119 Q_ASSERT(parent);
|
|
120 InsertBookmarksCommand *command = new InsertBookmarksCommand(this, parent, node, row);
|
|
121 m_commands.push(command);
|
|
122 }
|
|
123
|
|
124
|
|
125 void removeBookmark(BookmarkNode *node);
|
|
126 {
|
|
127 if (!m_loaded)
|
|
128 return;
|
|
129
|
|
130 Q_ASSERT(node);
|
|
131 BookmarkNode *parent = node.parent();
|
|
132 int row = parent.children().indexOf(node);
|
|
133 RemoveBookmarksCommand *command = new RemoveBookmarksCommand(this, parent, row);
|
|
134 m_commands.push(command);
|
|
135 }
|
|
136
|
|
137 void setTitle(BookmarkNode *node, QString &newTitle);
|
|
138 {
|
|
139 if (!m_loaded)
|
|
140 return;
|
|
141
|
|
142 Q_ASSERT(node);
|
|
143 ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newTitle, true);
|
|
144 m_commands.push(command);
|
|
145 }
|
|
146
|
|
147
|
|
148 void setUrl(BookmarkNode *node, QString &newUrl);
|
|
149 {
|
|
150 if (!m_loaded)
|
|
151 return;
|
|
152
|
|
153 Q_ASSERT(node);
|
|
154 ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newUrl, false);
|
|
155 m_commands.push(command);
|
|
156 }
|
|
157
|
|
158
|
|
159 void changeExpanded()
|
|
160 {
|
|
161 m_saveTimer.changeOccurred();
|
|
162 }
|
|
163
|
|
164 BookmarkNode *bookmarks();
|
|
165 {
|
|
166 if (!m_loaded)
|
|
167 load();
|
|
168 return m_bookmarkRootNode;
|
|
169 }
|
|
170
|
|
171 BookmarkNode *menu();
|
|
172 {
|
|
173 if (!m_loaded)
|
|
174 load();
|
|
175
|
|
176 for (int i = m_bookmarkRootNode.children().count() - 1; i >= 0; --i) {
|
|
177 BookmarkNode *node = m_bookmarkRootNode.children().at(i);
|
|
178 if (node.title == tr(BOOKMARKMENU))
|
|
179 return node;
|
|
180 }
|
|
181 Q_ASSERT(false);
|
|
182 return 0;
|
|
183 }
|
|
184
|
|
185 BookmarkNode *toolbar();
|
|
186 {
|
|
187 if (!m_loaded)
|
|
188 load();
|
|
189
|
|
190 for (int i = m_bookmarkRootNode.children().count() - 1; i >= 0; --i) {
|
|
191 BookmarkNode *node = m_bookmarkRootNode.children().at(i);
|
|
192 if (node.title == tr(BOOKMARKBAR))
|
|
193 return node;
|
|
194 }
|
|
195 Q_ASSERT(false);
|
|
196 return 0;
|
|
197 }
|
|
198
|
|
199 BookmarksModel* bookmarksModel()
|
|
200 {
|
|
201 if (!m_bookmarkModel)
|
|
202 m_bookmarkModel = new BookmarksModel(this, this);
|
|
203 return m_bookmarkModel;
|
|
204 }
|
|
205
|
|
206 QUndoStack *undoRedoStack() { return &m_commands; };
|
|
207
|
|
208 public slots:
|
|
209 void importBookmarks()
|
|
210 {
|
|
211 QString fileName = QFileDialog::getOpenFileName(0, tr("Open File"),
|
|
212 QString(),
|
|
213 tr("XBEL (*.xbel *.xml)"));
|
|
214 if (fileName.isEmpty())
|
|
215 return;
|
|
216
|
|
217 XbelReader reader;
|
|
218 BookmarkNode *importRootNode = reader.read(fileName);
|
|
219 if (reader.error() != QXmlStreamReader::NoError) {
|
|
220 QMessageBox::warning(0, QLatin1String("Loading Bookmark"),
|
|
221 tr("Error when loading bookmarks on line %1, column %2:\n"
|
|
222 "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
|
|
223 }
|
|
224
|
|
225 importRootNode.setType(BookmarkNode::Folder);
|
|
226 importRootNode.title = (tr("Imported %1").arg(QDate::currentDate().toString(Qt.SystemLocaleShortDate)));
|
|
227 addBookmark(menu(), importRootNode);
|
|
228 }
|
|
229
|
|
230
|
|
231 void exportBookmarks()
|
|
232 {
|
|
233 QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"),
|
|
234 tr("%1 Bookmarks.xbel").arg(QCoreApplication::applicationName()),
|
|
235 tr("XBEL (*.xbel *.xml)"));
|
|
236 if (fileName.isEmpty())
|
|
237 return;
|
|
238
|
|
239 XbelWriter writer;
|
|
240 if (!writer.write(fileName, m_bookmarkRootNode))
|
|
241 QMessageBox::critical(0, tr("Export error"), tr("error saving bookmarks"));
|
|
242 }
|
|
243
|
|
244 private slots:
|
|
245 void save()
|
|
246 {
|
|
247 if (!m_loaded)
|
|
248 return;
|
|
249
|
|
250 XbelWriter writer;
|
|
251 QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
|
252 QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel");
|
|
253 if (!writer.write(bookmarkFile, m_bookmarkRootNode))
|
|
254 qWarning() << "BookmarkManager: error saving to" << bookmarkFile;
|
|
255 }
|
|
256
|
|
257 private:
|
|
258 void load()
|
|
259 {
|
|
260 if (m_loaded)
|
|
261 return;
|
|
262 m_loaded = true;
|
|
263
|
|
264 QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
|
265 QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel");
|
|
266 if (!QFile::exists(bookmarkFile))
|
|
267 bookmarkFile = QLatin1String(":defaultbookmarks.xbel");
|
|
268
|
|
269 XbelReader reader;
|
|
270 m_bookmarkRootNode = reader.read(bookmarkFile);
|
|
271 if (reader.error() != QXmlStreamReader::NoError) {
|
|
272 QMessageBox::warning(0, QLatin1String("Loading Bookmark"),
|
|
273 tr("Error when loading bookmarks on line %1, column %2:\n"
|
|
274 "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString()));
|
|
275 }
|
|
276
|
|
277 BookmarkNode *toolbar = null;
|
|
278 BookmarkNode *menu = null;
|
|
279 QList<BookmarkNode*> others;
|
|
280 for (int i = m_bookmarkRootNode.children().count() - 1; i >= 0; --i) {
|
|
281 BookmarkNode *node = m_bookmarkRootNode.children().at(i);
|
|
282 if (node.type() == BookmarkNode::Folder) {
|
|
283 // Automatically convert
|
|
284 if (node.title == tr("Toolbar Bookmarks") && !toolbar) {
|
|
285 node.title = tr(BOOKMARKBAR);
|
|
286 }
|
|
287 if (node.title == tr(BOOKMARKBAR) && !toolbar) {
|
|
288 toolbar = node;
|
|
289 }
|
|
290
|
|
291 // Automatically convert
|
|
292 if (node.title == tr("Menu") && !menu) {
|
|
293 node.title = tr(BOOKMARKMENU);
|
|
294 }
|
|
295 if (node.title == tr(BOOKMARKMENU) && !menu) {
|
|
296 menu = node;
|
|
297 }
|
|
298 } else {
|
|
299 others.append(node);
|
|
300 }
|
|
301 m_bookmarkRootNode.remove(node);
|
|
302 }
|
|
303 Q_ASSERT(m_bookmarkRootNode.children().count() == 0);
|
|
304 if (!toolbar) {
|
|
305 toolbar = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode);
|
|
306 toolbar.title = tr(BOOKMARKBAR);
|
|
307 } else {
|
|
308 m_bookmarkRootNode.add(toolbar);
|
|
309 }
|
|
310
|
|
311 if (!menu) {
|
|
312 menu = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode);
|
|
313 menu.title = tr(BOOKMARKMENU);
|
|
314 } else {
|
|
315 m_bookmarkRootNode.add(menu);
|
|
316 }
|
|
317
|
|
318 for (int i = 0; i < others.count(); ++i)
|
|
319 menu.add(others.at(i));
|
|
320 }
|
|
321
|
|
322
|
|
323 bool m_loaded;
|
|
324 AutoSaver *m_saveTimer;
|
|
325 BookmarkNode *m_bookmarkRootNode;
|
|
326 BookmarksModel *m_bookmarkModel;
|
|
327 QUndoStack m_commands;
|
|
328
|
|
329 friend class RemoveBookmarksCommand;
|
|
330 friend class ChangeBookmarkCommand;
|
|
331 };
|
|
332
|
|
333 class RemoveBookmarksCommand : public QUndoCommand
|
|
334 {
|
|
335
|
|
336 public:
|
|
337 this(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row)
|
|
338 {
|
|
339 super(BookmarksManager::tr("Remove Bookmark"))
|
|
340 m_row = row;
|
|
341 m_bookmarkManagaer = m_bookmarkManagaer;
|
|
342 m_node = parent.children().value(row);
|
|
343 m_parent = parent;
|
|
344 m_done = false;
|
|
345 }
|
|
346
|
|
347 ~this()
|
|
348 {
|
|
349 if (m_done && !m_node.parent()) {
|
|
350 delete m_node;
|
|
351 }
|
|
352 }
|
|
353
|
|
354 void undo()
|
|
355 {
|
|
356 m_parent.add(m_node, m_row);
|
|
357 emit m_bookmarkManagaer.entryAdded(m_node);
|
|
358 m_done = false;
|
|
359 }
|
|
360
|
|
361 void redo()
|
|
362 {
|
|
363 m_parent.remove(m_node);
|
|
364 emit m_bookmarkManagaer.entryRemoved(m_parent, m_row, m_node);
|
|
365 m_done = true;
|
|
366 }
|
|
367
|
|
368 protected:
|
|
369 int m_row;
|
|
370 BookmarksManager *m_bookmarkManagaer;
|
|
371 BookmarkNode *m_node;
|
|
372 BookmarkNode *m_parent;
|
|
373 bool m_done;
|
|
374 };
|
|
375
|
|
376 class InsertBookmarksCommand : public RemoveBookmarksCommand
|
|
377 {
|
|
378
|
|
379 public:
|
|
380 this(BookmarksManager *m_bookmarkManagaer,
|
|
381 BookmarkNode *parent, BookmarkNode *node, int row)
|
|
382 {
|
|
383 super(m_bookmarkManagaer, parent, row);
|
|
384
|
|
385 setText(BookmarksManager::tr("Insert Bookmark"));
|
|
386 m_node = node;
|
|
387 }
|
|
388
|
|
389 void undo() { RemoveBookmarksCommand::redo(); }
|
|
390 void redo() { RemoveBookmarksCommand::undo(); }
|
|
391 }
|
|
392
|
|
393 class ChangeBookmarkCommand : public QUndoCommand
|
|
394 {
|
|
395
|
|
396 public:
|
|
397 this(BookmarksManager *m_bookmarkManagaer,
|
|
398 BookmarkNode *node, QString &newValue, bool title)
|
|
399 {
|
|
400 super();
|
|
401 m_bookmarkManagaer = m_bookmarkManagaer;
|
|
402 m_title = title;
|
|
403 m_newValue = newValue;
|
|
404 m_node = node;
|
|
405 if (m_title) {
|
|
406 m_oldValue = m_node.title;
|
|
407 setText(BookmarksManager::tr("Name Change"));
|
|
408 } else {
|
|
409 m_oldValue = m_node.url;
|
|
410 setText(BookmarksManager::tr("Address Change"));
|
|
411 }
|
|
412 }
|
|
413
|
|
414 void undo()
|
|
415 {
|
|
416 if (m_title)
|
|
417 m_node.title = m_oldValue;
|
|
418 else
|
|
419 m_node.url = m_oldValue;
|
|
420 emit m_bookmarkManagaer.entryChanged(m_node);
|
|
421 }
|
|
422
|
|
423 void redo()
|
|
424 {
|
|
425 if (m_title)
|
|
426 m_node.title = m_newValue;
|
|
427 else
|
|
428 m_node.url = m_newValue;
|
|
429 emit m_bookmarkManagaer.entryChanged(m_node);
|
|
430 }
|
|
431
|
|
432 private:
|
|
433 BookmarksManager *m_bookmarkManagaer;
|
|
434 bool m_title;
|
|
435 QString m_oldValue;
|
|
436 QString m_newValue;
|
|
437 BookmarkNode *m_node;
|
|
438 }
|
|
439
|
|
440 /*!
|
|
441 BookmarksModel is a QAbstractItemModel wrapper around the BookmarkManager
|
|
442 */
|
|
443 import QtGui/QIcon;
|
|
444 class BookmarksModel : public QAbstractItemModel
|
|
445 {
|
|
446 Q_OBJECT
|
|
447
|
|
448 public slots:
|
|
449 void entryAdded(BookmarkNode *item)
|
|
450 {
|
|
451 Q_ASSERT(item && item.parent());
|
|
452 int row = item.parent().children().indexOf(item);
|
|
453 BookmarkNode *parent = item.parent();
|
|
454 // item was already added so remove beore beginInsertRows is called
|
|
455 parent.remove(item);
|
|
456 beginInsertRows(index(parent), row, row);
|
|
457 parent.add(item, row);
|
|
458 endInsertRows();
|
|
459 }
|
|
460
|
|
461
|
|
462 void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item);
|
|
463 {
|
|
464 // item was already removed, re-add so beginRemoveRows works
|
|
465 parent.add(item, row);
|
|
466 beginRemoveRows(index(parent), row, row);
|
|
467 parent.remove(item);
|
|
468 endRemoveRows();
|
|
469 }
|
|
470
|
|
471 void entryChanged(BookmarkNode *item);
|
|
472 {
|
|
473 QModelIndex idx = index(item);
|
|
474 emit dataChanged(idx, idx);
|
|
475 }
|
|
476 public:
|
|
477 enum Roles {
|
|
478 TypeRole = Qt.UserRole + 1,
|
|
479 UrlRole = Qt.UserRole + 2,
|
|
480 UrlStringRole = Qt.UserRole + 3,
|
|
481 SeparatorRole = Qt.UserRole + 4
|
|
482 };
|
|
483
|
|
484 BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent = null)
|
|
485 {
|
|
486 super(parent)
|
|
487 m_endMacro = false;
|
|
488 m_bookmarksManager = bookmarkManager;
|
|
489 connect(bookmarkManager, SIGNAL(entryAdded(BookmarkNode *)),
|
|
490 this, SLOT(entryAdded(BookmarkNode *)));
|
|
491 connect(bookmarkManager, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)),
|
|
492 this, SLOT(entryRemoved(BookmarkNode *, int, BookmarkNode *)));
|
|
493 connect(bookmarkManager, SIGNAL(entryChanged(BookmarkNode *)),
|
|
494 this, SLOT(entryChanged(BookmarkNode *)));
|
|
495 }
|
|
496
|
|
497
|
|
498 inline BookmarksManager *bookmarksManager() { return m_bookmarksManager; }
|
|
499
|
|
500 QVariant headerData(int section, Qt.Orientation orientation, int role = Qt.DisplayRole);
|
|
501 {
|
|
502 if (orientation == Qt.Horizontal && role == Qt.DisplayRole) {
|
|
503 switch (section) {
|
|
504 case 0: return tr("Title");
|
|
505 case 1: return tr("Address");
|
|
506 }
|
|
507 }
|
|
508 return QAbstractItemModel::headerData(section, orientation, role);
|
|
509 }
|
|
510
|
|
511
|
|
512 QVariant data(QModelIndex &index, int role = Qt.DisplayRole)
|
|
513 {
|
|
514 if (!index.isValid() || index.model() != this)
|
|
515 return QVariant();
|
|
516
|
|
517 BookmarkNode *bookmarkNode = node(index);
|
|
518 switch (role) {
|
|
519 case Qt.EditRole:
|
|
520 case Qt.DisplayRole:
|
|
521 if (bookmarkNode.type() == BookmarkNode::Separator) {
|
|
522 switch (index.column()) {
|
|
523 case 0: return QString(50, 0xB7);
|
|
524 case 1: return QString();
|
|
525 }
|
|
526 }
|
|
527
|
|
528 switch (index.column()) {
|
|
529 case 0: return bookmarkNode.title;
|
|
530 case 1: return bookmarkNode.url;
|
|
531 }
|
|
532 break;
|
|
533 case BookmarksModel::UrlRole:
|
|
534 return QUrl(bookmarkNode.url);
|
|
535 break;
|
|
536 case BookmarksModel::UrlStringRole:
|
|
537 return bookmarkNode.url;
|
|
538 break;
|
|
539 case BookmarksModel::TypeRole:
|
|
540 return bookmarkNode.type();
|
|
541 break;
|
|
542 case BookmarksModel::SeparatorRole:
|
|
543 return (bookmarkNode.type() == BookmarkNode::Separator);
|
|
544 break;
|
|
545 case Qt.DecorationRole:
|
|
546 if (index.column() == 0) {
|
|
547 if (bookmarkNode.type() == BookmarkNode::Folder)
|
|
548 return QApplication::style().standardIcon(QStyle::SP_DirIcon);
|
|
549 return BrowserApplication::instance().icon(bookmarkNode.url);
|
|
550 }
|
|
551 }
|
|
552
|
|
553 return QVariant();
|
|
554 }
|
|
555
|
|
556 int columnCount(QModelIndex &parent = QModelIndex())
|
|
557 {
|
|
558 return (parent.column() > 0) ? 0 : 2;
|
|
559 }
|
|
560
|
|
561 int rowCount(QModelIndex &parent = QModelIndex())
|
|
562 {
|
|
563 if (parent.column() > 0)
|
|
564 return 0;
|
|
565
|
|
566 if (!parent.isValid())
|
|
567 return m_bookmarksManager.bookmarks().children().count();
|
|
568
|
|
569 const BookmarkNode *item = static_cast<BookmarkNode*>(parent.internalPointer());
|
|
570 return item.children().count();
|
|
571 }
|
|
572
|
|
573 QModelIndex index(int, int, QModelIndex& = QModelIndex())
|
|
574 {
|
|
575 if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent))
|
|
576 return QModelIndex();
|
|
577
|
|
578 // get the parent node
|
|
579 BookmarkNode *parentNode = node(parent);
|
|
580 return createIndex(row, column, parentNode.children().at(row));
|
|
581 }
|
|
582
|
|
583 QModelIndex parent(QModelIndex& index= QModelIndex())
|
|
584 {
|
|
585 if (!index.isValid())
|
|
586 return QModelIndex();
|
|
587
|
|
588 BookmarkNode *itemNode = node(index);
|
|
589 BookmarkNode *parentNode = (itemNode ? itemNode.parent() : 0);
|
|
590 if (!parentNode || parentNode == m_bookmarksManager.bookmarks())
|
|
591 return QModelIndex();
|
|
592
|
|
593 // get the parent's row
|
|
594 BookmarkNode *grandParentNode = parentNode.parent();
|
|
595 int parentRow = grandParentNode.children().indexOf(parentNode);
|
|
596 Q_ASSERT(parentRow >= 0);
|
|
597 return createIndex(parentRow, 0, parentNode);
|
|
598 }
|
|
599
|
|
600
|
|
601 Qt.ItemFlags flags(QModelIndex &index)
|
|
602 {
|
|
603 if (!index.isValid())
|
|
604 return Qt.NoItemFlags;
|
|
605
|
|
606 Qt.ItemFlags flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled;
|
|
607
|
|
608 BookmarkNode *bookmarkNode = node(index);
|
|
609
|
|
610 if (bookmarkNode != m_bookmarksManager.menu()
|
|
611 && bookmarkNode != m_bookmarksManager.toolbar()) {
|
|
612 flags |= Qt.ItemIsDragEnabled;
|
|
613 if (bookmarkNode.type() != BookmarkNode::Separator)
|
|
614 flags |= Qt.ItemIsEditable;
|
|
615 }
|
|
616 if (hasChildren(index))
|
|
617 flags |= Qt.ItemIsDropEnabled;
|
|
618 return flags;
|
|
619 }
|
|
620
|
|
621 Qt.DropActions supportedDropActions ();
|
|
622 {
|
|
623 return Qt.CopyAction | Qt.MoveAction;
|
|
624 }
|
|
625
|
|
626
|
|
627 bool removeRows(int row, int count, QModelIndex &parent = QModelIndex());
|
|
628 {
|
|
629 if (row < 0 || count <= 0 || row + count > rowCount(parent))
|
|
630 return false;
|
|
631
|
|
632 BookmarkNode *bookmarkNode = node(parent);
|
|
633 for (int i = row + count - 1; i >= row; --i) {
|
|
634 BookmarkNode *node = bookmarkNode.children().at(i);
|
|
635 if (node == m_bookmarksManager.menu()
|
|
636 || node == m_bookmarksManager.toolbar())
|
|
637 continue;
|
|
638
|
|
639 m_bookmarksManager.removeBookmark(node);
|
|
640 }
|
|
641 if (m_endMacro) {
|
|
642 m_bookmarksManager.undoRedoStack().endMacro();
|
|
643 m_endMacro = false;
|
|
644 }
|
|
645 return true;
|
|
646 }
|
|
647
|
|
648 bool setData(QModelIndex &index, QVariant &value, int role = Qt.EditRole)
|
|
649 {
|
|
650 if (!index.isValid() || (flags(index) & Qt.ItemIsEditable) == 0)
|
|
651 return false;
|
|
652
|
|
653 BookmarkNode *item = node(index);
|
|
654
|
|
655 switch (role) {
|
|
656 case Qt.EditRole:
|
|
657 case Qt.DisplayRole:
|
|
658 if (index.column() == 0) {
|
|
659 m_bookmarksManager.setTitle(item, value.toString());
|
|
660 break;
|
|
661 }
|
|
662 if (index.column() == 1) {
|
|
663 m_bookmarksManager.setUrl(item, value.toString());
|
|
664 break;
|
|
665 }
|
|
666 return false;
|
|
667 case BookmarksModel::UrlRole:
|
|
668 m_bookmarksManager.setUrl(item, value.toUrl().toString());
|
|
669 break;
|
|
670 case BookmarksModel::UrlStringRole:
|
|
671 m_bookmarksManager.setUrl(item, value.toString());
|
|
672 break;
|
|
673 default:
|
|
674 break;
|
|
675 return false;
|
|
676 }
|
|
677
|
|
678 return true;
|
|
679 }
|
|
680
|
|
681
|
|
682 QMimeData *mimeData(QModelIndexList &indexes);
|
|
683 {
|
|
684 QMimeData *mimeData = new QMimeData();
|
|
685 QByteArray data;
|
|
686 QDataStream stream(&data, QIODevice::WriteOnly);
|
|
687 foreach (QModelIndex index, indexes) {
|
|
688 if (index.column() != 0 || !index.isValid())
|
|
689 continue;
|
|
690 QByteArray encodedData;
|
|
691 QBuffer buffer(&encodedData);
|
|
692 buffer.open(QBuffer::ReadWrite);
|
|
693 XbelWriter writer;
|
|
694 const BookmarkNode *parentNode = node(index);
|
|
695 writer.write(&buffer, parentNode);
|
|
696 stream << encodedData;
|
|
697 }
|
|
698 mimeData.setData(MIMETYPE, data);
|
|
699 return mimeData;
|
|
700 }
|
|
701
|
|
702
|
|
703 #define MIMETYPE QLatin1String("application/bookmarks.xbel")
|
|
704
|
|
705 QStringList mimeTypes()
|
|
706 {
|
|
707 QStringList types;
|
|
708 types << MIMETYPE;
|
|
709 return types;
|
|
710 }
|
|
711
|
|
712 bool dropMimeData(QMimeData *data, Qt.DropAction action, int row, int column, QModelIndex &parent)
|
|
713 {
|
|
714 if (action == Qt.IgnoreAction)
|
|
715 return true;
|
|
716
|
|
717 if (!data.hasFormat(MIMETYPE)
|
|
718 || column > 0)
|
|
719 return false;
|
|
720
|
|
721 QByteArray ba = data.data(MIMETYPE);
|
|
722 QDataStream stream(&ba, QIODevice::ReadOnly);
|
|
723 if (stream.atEnd())
|
|
724 return false;
|
|
725
|
|
726 QUndoStack *undoStack = m_bookmarksManager.undoRedoStack();
|
|
727 undoStack.beginMacro(QLatin1String("Move Bookmarks"));
|
|
728
|
|
729 while (!stream.atEnd()) {
|
|
730 QByteArray encodedData;
|
|
731 stream >> encodedData;
|
|
732 QBuffer buffer(&encodedData);
|
|
733 buffer.open(QBuffer::ReadOnly);
|
|
734
|
|
735 XbelReader reader;
|
|
736 BookmarkNode *rootNode = reader.read(&buffer);
|
|
737 QList<BookmarkNode*> children = rootNode.children();
|
|
738 for (int i = 0; i < children.count(); ++i) {
|
|
739 BookmarkNode *bookmarkNode = children.at(i);
|
|
740 rootNode.remove(bookmarkNode);
|
|
741 row = qMax(0, row);
|
|
742 BookmarkNode *parentNode = node(parent);
|
|
743 m_bookmarksManager.addBookmark(parentNode, bookmarkNode, row);
|
|
744 m_endMacro = true;
|
|
745 }
|
|
746 delete rootNode;
|
|
747 }
|
|
748 return true;
|
|
749 }
|
|
750
|
|
751
|
|
752 bool hasChildren(QModelIndex &parent = QModelIndex())
|
|
753 {
|
|
754 if (!parent.isValid())
|
|
755 return true;
|
|
756 const BookmarkNode *parentNode = node(parent);
|
|
757 return (parentNode.type() == BookmarkNode::Folder);
|
|
758 }
|
|
759
|
|
760 BookmarkNode *node(QModelIndex &index)
|
|
761 {
|
|
762 BookmarkNode *itemNode = static_cast<BookmarkNode*>(index.internalPointer());
|
|
763 if (!itemNode)
|
|
764 return m_bookmarksManager.bookmarks();
|
|
765 return itemNode;
|
|
766 }
|
|
767
|
|
768 QModelIndex index(BookmarkNode *node)
|
|
769 {
|
|
770 BookmarkNode *parent = node.parent();
|
|
771 if (!parent)
|
|
772 return QModelIndex();
|
|
773 return createIndex(parent.children().indexOf(node), 0, node);
|
|
774 }
|
|
775
|
|
776 private:
|
|
777
|
|
778 bool m_endMacro;
|
|
779 BookmarksManager *m_bookmarksManager;
|
|
780 }
|
|
781
|
|
782 // Menu that is dynamically populated from the bookmarks
|
|
783 import modelmenu;
|
|
784 class BookmarksMenu : public ModelMenu
|
|
785 {
|
|
786 Q_OBJECT
|
|
787
|
|
788 signals:
|
|
789 void openUrl(QUrl &url);
|
|
790
|
|
791 public:
|
|
792 BookmarksMenu(QWidget *parent = null)
|
|
793 {
|
|
794 super(parent);
|
|
795 m_bookmarksManager = 0;
|
|
796 connect(this, SIGNAL(activated(QModelIndex &)),
|
|
797 this, SLOT(activated(QModelIndex &)));
|
|
798 setMaxRows(-1);
|
|
799 setHoverRole(BookmarksModel::UrlStringRole);
|
|
800 setSeparatorRole(BookmarksModel::SeparatorRole);
|
|
801 }
|
|
802 void setInitialActions(QList<QAction*> actions);
|
|
803 {
|
|
804 m_initialActions = actions;
|
|
805 for (int i = 0; i < m_initialActions.count(); ++i)
|
|
806 addAction(m_initialActions.at(i));
|
|
807 }
|
|
808 protected:
|
|
809 bool prePopulated()
|
|
810 {
|
|
811 m_bookmarksManager = BrowserApplication::bookmarksManager();
|
|
812 setModel(m_bookmarksManager.bookmarksModel());
|
|
813 setRootIndex(m_bookmarksManager.bookmarksModel().index(1, 0));
|
|
814 // initial actions
|
|
815 for (int i = 0; i < m_initialActions.count(); ++i)
|
|
816 addAction(m_initialActions.at(i));
|
|
817 if (!m_initialActions.isEmpty())
|
|
818 addSeparator();
|
|
819 createMenu(model().index(0, 0), 1, this);
|
|
820 return true;
|
|
821 }
|
|
822
|
|
823 private slots:
|
|
824 void activated(QModelIndex &index)
|
|
825 {
|
|
826 emit openUrl(index.data(BookmarksModel::UrlRole).toUrl());
|
|
827 }
|
|
828
|
|
829 private:
|
|
830 BookmarksManager *m_bookmarksManager;
|
|
831 QList<QAction*> m_initialActions;
|
|
832 }
|
|
833
|
|
834 /*
|
|
835 Proxy model that filters out the bookmarks so only the folders
|
|
836 are left behind. Used in the add bookmark dialog combobox.
|
|
837 */
|
|
838 import QtGui/QSortFilterProxyModel;
|
|
839 class AddBookmarkProxyModel : public QSortFilterProxyModel
|
|
840 {
|
|
841 Q_OBJECT
|
|
842 public:
|
|
843 this(QObject * parent = null)
|
|
844 {
|
|
845 super(parent);
|
|
846 }
|
|
847 int columnCount(QModelIndex & parent = QModelIndex())
|
|
848 {
|
|
849 return qMin(1, QSortFilterProxyModel::columnCount(parent));
|
|
850 }
|
|
851 protected:
|
|
852 bool filterAcceptsRow(int source_row, QModelIndex &source_parent)
|
|
853 {
|
|
854 QModelIndex idx = sourceModel().index(source_row, 0, source_parent);
|
|
855 return sourceModel().hasChildren(idx);
|
|
856 }
|
|
857 }
|
|
858
|
|
859 /*!
|
|
860 Add bookmark dialog
|
|
861 */
|
|
862 import ui_addbookmarkdialog;
|
|
863 class AddBookmarkDialog : public QDialog, public Ui_AddBookmarkDialog
|
|
864 {
|
|
865 Q_OBJECT
|
|
866
|
|
867 public:
|
|
868 this(QString &url, QString &title, QWidget *parent = null, BookmarksManager *bookmarkManager = null)
|
|
869 : QDialog(parent)
|
|
870
|
|
871 {
|
|
872 m_url = url;
|
|
873 m_bookmarksManager = bookmarkManager;
|
|
874
|
|
875 setWindowFlags(Qt.Sheet);
|
|
876 if (!m_bookmarksManager)
|
|
877 m_bookmarksManager = BrowserApplication::bookmarksManager();
|
|
878 setupUi(this);
|
|
879 QTreeView *view = new QTreeView(this);
|
|
880 m_proxyModel = new AddBookmarkProxyModel(this);
|
|
881 BookmarksModel *model = m_bookmarksManager.bookmarksModel();
|
|
882 m_proxyModel.setSourceModel(model);
|
|
883 view.setModel(m_proxyModel);
|
|
884 view.expandAll();
|
|
885 view.header().setStretchLastSection(true);
|
|
886 view.header().hide();
|
|
887 view.setItemsExpandable(false);
|
|
888 view.setRootIsDecorated(false);
|
|
889 view.setIndentation(10);
|
|
890 location.setModel(m_proxyModel);
|
|
891 view.show();
|
|
892 location.setView(view);
|
|
893 BookmarkNode *menu = m_bookmarksManager.menu();
|
|
894 QModelIndex idx = m_proxyModel.mapFromSource(model.index(menu));
|
|
895 view.setCurrentIndex(idx);
|
|
896 location.setCurrentIndex(idx.row());
|
|
897 name.setText(title);
|
|
898 }
|
|
899 private slots:
|
|
900
|
|
901 void accept()
|
|
902 {
|
|
903 QModelIndex index = location.view().currentIndex();
|
|
904 index = m_proxyModel.mapToSource(index);
|
|
905 if (!index.isValid())
|
|
906 index = m_bookmarksManager.bookmarksModel().index(0, 0);
|
|
907 BookmarkNode *parent = m_bookmarksManager.bookmarksModel().node(index);
|
|
908 BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark);
|
|
909 bookmark.url = m_url;
|
|
910 bookmark.title = name.text();
|
|
911 m_bookmarksManager.addBookmark(parent, bookmark);
|
|
912 QDialog::accept();
|
|
913 }
|
|
914
|
|
915 private:
|
|
916 QString m_url;
|
|
917 BookmarksManager *m_bookmarksManager;
|
|
918 AddBookmarkProxyModel *m_proxyModel;
|
|
919 }
|
|
920
|
|
921 import ui_bookmarks;
|
|
922
|
|
923 //class TreeProxyModel;
|
|
924 class BookmarksDialog : public QDialog, public Ui_BookmarksDialog
|
|
925 {
|
|
926 Q_OBJECT
|
|
927
|
|
928 signals:
|
|
929 void openUrl(QUrl &url);
|
|
930
|
|
931 public:
|
|
932 this(QWidget *parent = null, BookmarksManager *manager = null)
|
|
933 : QDialog(parent)
|
|
934 {
|
|
935 m_bookmarksManager = manager;
|
|
936 if (!m_bookmarksManager)
|
|
937 m_bookmarksManager = BrowserApplication::bookmarksManager();
|
|
938 setupUi(this);
|
|
939
|
|
940 tree.setUniformRowHeights(true);
|
|
941 tree.setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
942 tree.setSelectionMode(QAbstractItemView::ContiguousSelection);
|
|
943 tree.setTextElideMode(Qt.ElideMiddle);
|
|
944 m_bookmarksModel = m_bookmarksManager.bookmarksModel();
|
|
945 m_proxyModel = new TreeProxyModel(this);
|
|
946 connect(search, SIGNAL(textChanged(QString)),
|
|
947 m_proxyModel, SLOT(setFilterFixedString(QString)));
|
|
948 connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne()));
|
|
949 m_proxyModel.setSourceModel(m_bookmarksModel);
|
|
950 tree.setModel(m_proxyModel);
|
|
951 tree.setDragDropMode(QAbstractItemView::InternalMove);
|
|
952 tree.setExpanded(m_proxyModel.index(0, 0), true);
|
|
953 tree.setAlternatingRowColors(true);
|
|
954 QFontMetrics fm(font());
|
|
955 int header = fm.width(QLatin1Char('m')) * 40;
|
|
956 tree.header().resizeSection(0, header);
|
|
957 tree.header().setStretchLastSection(true);
|
|
958 connect(tree, SIGNAL(activated(QModelIndex&)),
|
|
959 this, SLOT(open()));
|
|
960 tree.setContextMenuPolicy(Qt.CustomContextMenu);
|
|
961 connect(tree, SIGNAL(customContextMenuRequested(QPoint &)),
|
|
962 this, SLOT(customContextMenuRequested(QPoint &)));
|
|
963 connect(addFolderButton, SIGNAL(clicked()),
|
|
964 this, SLOT(newFolder()));
|
|
965 expandNodes(m_bookmarksManager.bookmarks());
|
|
966 setAttribute(Qt.WA_DeleteOnClose);
|
|
967 }
|
|
968 ~this()
|
|
969 {
|
|
970 if (saveExpandedNodes(tree.rootIndex()))
|
|
971 m_bookmarksManager.changeExpanded();
|
|
972 }
|
|
973
|
|
974 private slots:
|
|
975 void customContextMenuRequested(QPoint &pos)
|
|
976 {
|
|
977 QMenu menu;
|
|
978 QModelIndex index = tree.indexAt(pos);
|
|
979 index = index.sibling(index.row(), 0);
|
|
980 if (index.isValid() && !tree.model().hasChildren(index)) {
|
|
981 menu.addAction(tr("Open"), this, SLOT(open()));
|
|
982 menu.addSeparator();
|
|
983 }
|
|
984 menu.addAction(tr("Delete"), tree, SLOT(removeOne()));
|
|
985 menu.exec(QCursor::pos());
|
|
986 }
|
|
987 void open()
|
|
988 {
|
|
989 QModelIndex index = tree.currentIndex();
|
|
990 if (!index.parent().isValid())
|
|
991 return;
|
|
992 emit openUrl(index.sibling(index.row(), 1).data(BookmarksModel::UrlRole).toUrl());
|
|
993 }
|
|
994
|
|
995 void newFolder()
|
|
996 {
|
|
997 QModelIndex currentIndex = tree.currentIndex();
|
|
998 QModelIndex idx = currentIndex;
|
|
999 if (idx.isValid() && !idx.model().hasChildren(idx))
|
|
1000 idx = idx.parent();
|
|
1001 if (!idx.isValid())
|
|
1002 idx = tree.rootIndex();
|
|
1003 idx = m_proxyModel.mapToSource(idx);
|
|
1004 BookmarkNode *parent = m_bookmarksManager.bookmarksModel().node(idx);
|
|
1005 BookmarkNode *node = new BookmarkNode(BookmarkNode::Folder);
|
|
1006 node.title = tr("New Folder");
|
|
1007 m_bookmarksManager.addBookmark(parent, node, currentIndex.row() + 1);
|
|
1008 }
|
|
1009
|
|
1010 private:
|
|
1011 void expandNodes(BookmarkNode *node)
|
|
1012 {
|
|
1013 for (int i = 0; i < node.children().count(); ++i) {
|
|
1014 BookmarkNode *childNode = node.children()[i];
|
|
1015 if (childNode.expanded) {
|
|
1016 QModelIndex idx = m_bookmarksModel.index(childNode);
|
|
1017 idx = m_proxyModel.mapFromSource(idx);
|
|
1018 tree.setExpanded(idx, true);
|
|
1019 expandNodes(childNode);
|
|
1020 }
|
|
1021 }
|
|
1022 }
|
|
1023
|
|
1024 bool saveExpandedNodes(QModelIndex &parent)
|
|
1025 {
|
|
1026 bool changed = false;
|
|
1027 for (int i = 0; i < m_proxyModel.rowCount(parent); ++i) {
|
|
1028 QModelIndex child = m_proxyModel.index(i, 0, parent);
|
|
1029 QModelIndex sourceIndex = m_proxyModel.mapToSource(child);
|
|
1030 BookmarkNode *childNode = m_bookmarksModel.node(sourceIndex);
|
|
1031 bool wasExpanded = childNode.expanded;
|
|
1032 if (tree.isExpanded(child)) {
|
|
1033 childNode.expanded = true;
|
|
1034 changed |= saveExpandedNodes(child);
|
|
1035 } else {
|
|
1036 childNode.expanded = false;
|
|
1037 }
|
|
1038 changed |= (wasExpanded != childNode.expanded);
|
|
1039 }
|
|
1040 return changed;
|
|
1041 }
|
|
1042
|
|
1043 BookmarksManager *m_bookmarksManager;
|
|
1044 BookmarksModel *m_bookmarksModel;
|
|
1045 TreeProxyModel *m_proxyModel;
|
|
1046 };
|
|
1047
|
|
1048 import QtGui/QToolBar;
|
|
1049 class BookmarksToolBar : public QToolBar
|
|
1050 {
|
|
1051 Q_OBJECT
|
|
1052
|
|
1053 signals:
|
|
1054 void openUrl(QUrl &url);
|
|
1055
|
|
1056 public:
|
|
1057 BookmarksToolBar(BookmarksModel *model, QWidget *parent = null)
|
|
1058 {
|
|
1059 super(tr("Bookmark"), parent);
|
|
1060 m_bookmarksModel = model;
|
|
1061 connect(this, SIGNAL(actionTriggered(QAction*)), this, SLOT(triggered(QAction*)));
|
|
1062 setRootIndex(model.index(0, 0));
|
|
1063 connect(m_bookmarksModel, SIGNAL(modelReset()), this, SLOT(build()));
|
|
1064 connect(m_bookmarksModel, SIGNAL(rowsInserted(QModelIndex &, int, int)), this, SLOT(build()));
|
|
1065 connect(m_bookmarksModel, SIGNAL(rowsRemoved(QModelIndex &, int, int)), this, SLOT(build()));
|
|
1066 connect(m_bookmarksModel, SIGNAL(dataChanged(QModelIndex &, QModelIndex &)), this, SLOT(build()));
|
|
1067 setAcceptDrops(true);
|
|
1068 }
|
|
1069
|
|
1070 void setRootIndex(QModelIndex &index);
|
|
1071 {
|
|
1072 m_root = index;
|
|
1073 build();
|
|
1074 }
|
|
1075
|
|
1076 QModelIndex rootIndex()
|
|
1077 {
|
|
1078 return m_root;
|
|
1079 }
|
|
1080
|
|
1081 protected:
|
|
1082 void dragEnterEvent(QDragEnterEvent *event)
|
|
1083 {
|
|
1084 const QMimeData *mimeData = event.mimeData();
|
|
1085 if (mimeData.hasUrls())
|
|
1086 event.acceptProposedAction();
|
|
1087 QToolBar::dragEnterEvent(event);
|
|
1088 }
|
|
1089
|
|
1090 void dropEvent(QDropEvent *event)
|
|
1091 {
|
|
1092 const QMimeData *mimeData = event.mimeData();
|
|
1093 if (mimeData.hasUrls() && mimeData.hasText()) {
|
|
1094 QList<QUrl> urls = mimeData.urls();
|
|
1095 QAction *action = actionAt(event.pos());
|
|
1096 QString dropText;
|
|
1097 if (action)
|
|
1098 dropText = action.text();
|
|
1099 int row = -1;
|
|
1100 QModelIndex parentIndex = m_root;
|
|
1101 for (int i = 0; i < m_bookmarksModel.rowCount(m_root); ++i) {
|
|
1102 QModelIndex idx = m_bookmarksModel.index(i, 0, m_root);
|
|
1103 QString title = idx.data().toString();
|
|
1104 if (title == dropText) {
|
|
1105 row = i;
|
|
1106 if (m_bookmarksModel.hasChildren(idx)) {
|
|
1107 parentIndex = idx;
|
|
1108 row = -1;
|
|
1109 }
|
|
1110 break;
|
|
1111 }
|
|
1112 }
|
|
1113 BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark);
|
|
1114 bookmark.url = urls.at(0).toString();
|
|
1115 bookmark.title = mimeData.text();
|
|
1116
|
|
1117 BookmarkNode *parent = m_bookmarksModel.node(parentIndex);
|
|
1118 BookmarksManager *bookmarksManager = m_bookmarksModel.bookmarksManager();
|
|
1119 bookmarksManager.addBookmark(parent, bookmark, row);
|
|
1120 event.acceptProposedAction();
|
|
1121 }
|
|
1122 QToolBar::dropEvent(event);
|
|
1123 }
|
|
1124
|
|
1125 private slots:
|
|
1126 void triggered(QAction *action)
|
|
1127 {
|
|
1128 QVariant v = action.data();
|
|
1129 if (v.canConvert<QUrl>()) {
|
|
1130 emit openUrl(v.toUrl());
|
|
1131 }
|
|
1132 }
|
|
1133
|
|
1134 void activated(QModelIndex &index)
|
|
1135 {
|
|
1136 emit openUrl(index.data(BookmarksModel::UrlRole).toUrl());
|
|
1137 }
|
|
1138
|
|
1139
|
|
1140 void build()
|
|
1141 {
|
|
1142 clear();
|
|
1143 for (int i = 0; i < m_bookmarksModel.rowCount(m_root); ++i) {
|
|
1144 QModelIndex idx = m_bookmarksModel.index(i, 0, m_root);
|
|
1145 if (m_bookmarksModel.hasChildren(idx)) {
|
|
1146 QToolButton *button = new QToolButton(this);
|
|
1147 button.setPopupMode(QToolButton::InstantPopup);
|
|
1148 button.setArrowType(Qt.DownArrow);
|
|
1149 button.setText(idx.data().toString());
|
|
1150 ModelMenu *menu = new ModelMenu(this);
|
|
1151 connect(menu, SIGNAL(activated(QModelIndex &)),
|
|
1152 this, SLOT(activated(QModelIndex &)));
|
|
1153 menu.setModel(m_bookmarksModel);
|
|
1154 menu.setRootIndex(idx);
|
|
1155 menu.addAction(new QAction(menu));
|
|
1156 button.setMenu(menu);
|
|
1157 button.setToolButtonStyle(Qt.ToolButtonTextOnly);
|
|
1158 QAction *a = addWidget(button);
|
|
1159 a.setText(idx.data().toString());
|
|
1160 } else {
|
|
1161 QAction *action = addAction(idx.data().toString());
|
|
1162 action.setData(idx.data(BookmarksModel::UrlRole));
|
|
1163 }
|
|
1164 }
|
|
1165 }
|
|
1166
|
|
1167 private:
|
|
1168 BookmarksModel *m_bookmarksModel;
|
|
1169 QPersistentModelIndex m_root;
|
|
1170 }
|