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
38QT_BEGIN_NAMESPACE
39
40BookmarkDialog::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(which: QDialogButtonBox::Ok)->setDefault(true);
53
54 connect(sender: ui.buttonBox, signal: &QDialogButtonBox::accepted, receiver: this, slot: &BookmarkDialog::accepted);
55 connect(sender: ui.buttonBox, signal: &QDialogButtonBox::rejected, receiver: this, slot: &BookmarkDialog::rejected);
56 connect(sender: ui.newFolderButton, signal: &QAbstractButton::clicked, receiver: this, slot: &BookmarkDialog::addFolder);
57 connect(sender: ui.toolButton, signal: &QAbstractButton::clicked, receiver: this, slot: &BookmarkDialog::toolButtonClicked);
58 connect(sender: ui.bookmarkEdit, signal: &QLineEdit::textChanged, receiver: this, slot: &BookmarkDialog::textChanged);
59
60 bookmarkProxyModel = new BookmarkFilterModel(this);
61 bookmarkProxyModel->setSourceModel(bookmarkModel);
62 ui.bookmarkFolders->setModel(bookmarkProxyModel);
63 connect(sender: ui.bookmarkFolders, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
64 receiver: this, slot: QOverload<int>::of(ptr: &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(filterObj: this);
73 ui.treeView->viewport()->installEventFilter(filterObj: this);
74 ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
75
76 connect(sender: ui.treeView, signal: &QWidget::customContextMenuRequested,
77 receiver: this, slot: &BookmarkDialog::customContextMenuRequested);
78 connect(sender: ui.treeView->selectionModel(), signal: &QItemSelectionModel::currentChanged,
79 receiver: this, slot: QOverload<const QModelIndex &>::of(ptr: &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
88BookmarkDialog::~BookmarkDialog()
89{
90 TRACE_OBJ
91}
92
93bool BookmarkDialog::isRootItem(const QModelIndex &index) const
94{
95 return !bookmarkTreeModel->parent(child: index).isValid();
96}
97
98bool BookmarkDialog::eventFilter(QObject *object, QEvent *event)
99{
100 TRACE_OBJ
101 if (object != ui.treeView && object != ui.treeView->viewport())
102 return QWidget::eventFilter(watched: 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(watched: object, event);
120}
121
122void BookmarkDialog::currentIndexChanged(int row)
123{
124 TRACE_OBJ
125 QModelIndex next = bookmarkProxyModel->index(row, column: 0, parent: QModelIndex());
126 if (next.isValid()) {
127 next = bookmarkProxyModel->mapToSource(proxyIndex: next);
128 ui.treeView->setCurrentIndex(bookmarkTreeModel->mapFromSource(sourceIndex: next));
129 }
130}
131
132void BookmarkDialog::currentIndexChanged(const QModelIndex &index)
133{
134 TRACE_OBJ
135 const QModelIndex current = bookmarkTreeModel->mapToSource(proxyIndex: index);
136 if (current.isValid()) {
137 const int row = bookmarkProxyModel->mapFromSource(sourceIndex: current).row();
138 ui.bookmarkFolders->setCurrentIndex(row);
139 }
140}
141
142void BookmarkDialog::accepted()
143{
144 TRACE_OBJ
145 QModelIndex index = ui.treeView->currentIndex();
146 if (index.isValid()) {
147 index = bookmarkModel->addItem(parent: bookmarkTreeModel->mapToSource(proxyIndex: index));
148 bookmarkModel->setData(index, data: DataVector() << m_title << m_url << false);
149 } else
150 rejected();
151
152 accept();
153}
154
155void BookmarkDialog::rejected()
156{
157 TRACE_OBJ
158 for (const QPersistentModelIndex &index : qAsConst(t&: cache))
159 bookmarkModel->removeItem(index);
160 reject();
161}
162
163void BookmarkDialog::addFolder()
164{
165 TRACE_OBJ
166 QModelIndex index = ui.treeView->currentIndex();
167 if (index.isValid()) {
168 index = bookmarkModel->addItem(parent: bookmarkTreeModel->mapToSource(proxyIndex: index),
169 isFolder: true);
170 cache.append(t: index);
171
172 index = bookmarkTreeModel->mapFromSource(sourceIndex: 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
183void 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(w: width(), h: minimumHeight());
195 ui.toolButton->setText(QLatin1String("+"));
196 }
197}
198
199void BookmarkDialog::textChanged(const QString& text)
200{
201 m_title = text;
202}
203
204void 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(text: tr(s: "Rename Folder"));
213
214 QAction *picked = menu.exec(pos: ui.treeView->mapToGlobal(point));
215 if (picked == renameItem) {
216 bookmarkModel->setItemsEditable(true);
217 ui.treeView->edit(index);
218 bookmarkModel->setItemsEditable(false);
219 }
220}
221
222QT_END_NAMESPACE
223

source code of qttools/src/assistant/assistant/bookmarkdialog.cpp