1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Assistant of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 #include "bookmarkdialog.h"
29 #include "bookmarkfiltermodel.h"
30 #include "bookmarkitem.h"
31 #include "bookmarkmodel.h"
32 #include "helpenginewrapper.h"
33 #include "tracer.h"
34
35 #include <QtGui/QKeyEvent>
36 #include <QtWidgets/QMenu>
37
38 QT_BEGIN_NAMESPACE
39
BookmarkDialog(BookmarkModel * sourceModel,const QString & title,const QString & url,QWidget * parent)40 BookmarkDialog::BookmarkDialog(BookmarkModel *sourceModel, const QString &title,
41 const QString &url, QWidget *parent)
42 : QDialog(parent)
43 , m_url(url)
44 , m_title(title)
45 , bookmarkModel(sourceModel)
46 {
47 TRACE_OBJ
48 ui.setupUi(this);
49
50 ui.bookmarkEdit->setText(m_title);
51 ui.newFolderButton->setVisible(false);
52 ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
53
54 connect(ui.buttonBox, &QDialogButtonBox::accepted, this, &BookmarkDialog::accepted);
55 connect(ui.buttonBox, &QDialogButtonBox::rejected, this, &BookmarkDialog::rejected);
56 connect(ui.newFolderButton, &QAbstractButton::clicked, this, &BookmarkDialog::addFolder);
57 connect(ui.toolButton, &QAbstractButton::clicked, this, &BookmarkDialog::toolButtonClicked);
58 connect(ui.bookmarkEdit, &QLineEdit::textChanged, this, &BookmarkDialog::textChanged);
59
60 bookmarkProxyModel = new BookmarkFilterModel(this);
61 bookmarkProxyModel->setSourceModel(bookmarkModel);
62 ui.bookmarkFolders->setModel(bookmarkProxyModel);
63 connect(ui.bookmarkFolders, QOverload<int>::of(&QComboBox::currentIndexChanged),
64 this, QOverload<int>::of(&BookmarkDialog::currentIndexChanged));
65
66 bookmarkTreeModel = new BookmarkTreeModel(this);
67 bookmarkTreeModel->setSourceModel(bookmarkModel);
68 ui.treeView->setModel(bookmarkTreeModel);
69
70 ui.treeView->expandAll();
71 ui.treeView->setVisible(false);
72 ui.treeView->installEventFilter(this);
73 ui.treeView->viewport()->installEventFilter(this);
74 ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
75
76 connect(ui.treeView, &QWidget::customContextMenuRequested,
77 this, &BookmarkDialog::customContextMenuRequested);
78 connect(ui.treeView->selectionModel(), &QItemSelectionModel::currentChanged,
79 this, QOverload<const QModelIndex &>::of(&BookmarkDialog::currentIndexChanged));
80
81 ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->count() > 1 ? 1 : 0);
82
83 const HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
84 if (helpEngine.usesAppFont())
85 setFont(helpEngine.appFont());
86 }
87
~BookmarkDialog()88 BookmarkDialog::~BookmarkDialog()
89 {
90 TRACE_OBJ
91 }
92
isRootItem(const QModelIndex & index) const93 bool BookmarkDialog::isRootItem(const QModelIndex &index) const
94 {
95 return !bookmarkTreeModel->parent(index).isValid();
96 }
97
eventFilter(QObject * object,QEvent * event)98 bool BookmarkDialog::eventFilter(QObject *object, QEvent *event)
99 {
100 TRACE_OBJ
101 if (object != ui.treeView && object != ui.treeView->viewport())
102 return QWidget::eventFilter(object, event);
103
104 if (event->type() == QEvent::KeyPress) {
105 QKeyEvent *ke = static_cast<QKeyEvent*>(event);
106 switch (ke->key()) {
107 case Qt::Key_F2: {
108 const QModelIndex &index = ui.treeView->currentIndex();
109 if (!isRootItem(index)) {
110 bookmarkModel->setItemsEditable(true);
111 ui.treeView->edit(index);
112 bookmarkModel->setItemsEditable(false);
113 }
114 } break;
115 default: break;
116 }
117 }
118
119 return QObject::eventFilter(object, event);
120 }
121
currentIndexChanged(int row)122 void BookmarkDialog::currentIndexChanged(int row)
123 {
124 TRACE_OBJ
125 QModelIndex next = bookmarkProxyModel->index(row, 0, QModelIndex());
126 if (next.isValid()) {
127 next = bookmarkProxyModel->mapToSource(next);
128 ui.treeView->setCurrentIndex(bookmarkTreeModel->mapFromSource(next));
129 }
130 }
131
currentIndexChanged(const QModelIndex & index)132 void BookmarkDialog::currentIndexChanged(const QModelIndex &index)
133 {
134 TRACE_OBJ
135 const QModelIndex current = bookmarkTreeModel->mapToSource(index);
136 if (current.isValid()) {
137 const int row = bookmarkProxyModel->mapFromSource(current).row();
138 ui.bookmarkFolders->setCurrentIndex(row);
139 }
140 }
141
accepted()142 void BookmarkDialog::accepted()
143 {
144 TRACE_OBJ
145 QModelIndex index = ui.treeView->currentIndex();
146 if (index.isValid()) {
147 index = bookmarkModel->addItem(bookmarkTreeModel->mapToSource(index));
148 bookmarkModel->setData(index, DataVector() << m_title << m_url << false);
149 } else
150 rejected();
151
152 accept();
153 }
154
rejected()155 void BookmarkDialog::rejected()
156 {
157 TRACE_OBJ
158 for (const QPersistentModelIndex &index : qAsConst(cache))
159 bookmarkModel->removeItem(index);
160 reject();
161 }
162
addFolder()163 void BookmarkDialog::addFolder()
164 {
165 TRACE_OBJ
166 QModelIndex index = ui.treeView->currentIndex();
167 if (index.isValid()) {
168 index = bookmarkModel->addItem(bookmarkTreeModel->mapToSource(index),
169 true);
170 cache.append(index);
171
172 index = bookmarkTreeModel->mapFromSource(index);
173 if (index.isValid()) {
174 bookmarkModel->setItemsEditable(true);
175 ui.treeView->edit(index);
176 ui.treeView->expand(index);
177 ui.treeView->setCurrentIndex(index);
178 bookmarkModel->setItemsEditable(false);
179 }
180 }
181 }
182
toolButtonClicked()183 void BookmarkDialog::toolButtonClicked()
184 {
185 TRACE_OBJ
186 const bool visible = !ui.treeView->isVisible();
187 ui.treeView->setVisible(visible);
188 ui.newFolderButton->setVisible(visible);
189
190 if (visible) {
191 resize(QSize(width(), 400));
192 ui.toolButton->setText(QLatin1String("-"));
193 } else {
194 resize(width(), minimumHeight());
195 ui.toolButton->setText(QLatin1String("+"));
196 }
197 }
198
textChanged(const QString & text)199 void BookmarkDialog::textChanged(const QString& text)
200 {
201 m_title = text;
202 }
203
customContextMenuRequested(const QPoint & point)204 void BookmarkDialog::customContextMenuRequested(const QPoint &point)
205 {
206 TRACE_OBJ
207 const QModelIndex &index = ui.treeView->currentIndex();
208 if (isRootItem(index))
209 return; // check if we go to rename the "Bookmarks Menu", bail
210
211 QMenu menu(QString(), this);
212 QAction *renameItem = menu.addAction(tr("Rename Folder"));
213
214 QAction *picked = menu.exec(ui.treeView->mapToGlobal(point));
215 if (picked == renameItem) {
216 bookmarkModel->setItemsEditable(true);
217 ui.treeView->edit(index);
218 bookmarkModel->setItemsEditable(false);
219 }
220 }
221
222 QT_END_NAMESPACE
223