1 | // -*- c-basic-offset:4; indent-tabs-mode:nil -*- |
2 | /* |
3 | This file is part of the KDE libraries |
4 | SPDX-FileCopyrightText: 2007 Daniel Teske <teske@squorn.de> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-only |
7 | */ |
8 | |
9 | #include "kbookmarkdialog.h" |
10 | #include "kbookmarkdialog_p.h" |
11 | #include "kbookmarkmanager.h" |
12 | #include "kbookmarkmenu_p.h" |
13 | |
14 | #include <QDialogButtonBox> |
15 | #include <QFormLayout> |
16 | #include <QHeaderView> |
17 | #include <QIcon> |
18 | #include <QInputDialog> |
19 | #include <QLabel> |
20 | #include <QLineEdit> |
21 | #include <QPushButton> |
22 | #include <QTreeWidget> |
23 | |
24 | #include <KGuiItem> |
25 | |
26 | KBookmarkDialogPrivate::KBookmarkDialogPrivate(KBookmarkDialog *qq) |
27 | : q(qq) |
28 | , folderTree(nullptr) |
29 | , layout(false) |
30 | { |
31 | } |
32 | |
33 | KBookmarkDialogPrivate::~KBookmarkDialogPrivate() |
34 | { |
35 | } |
36 | |
37 | void KBookmarkDialogPrivate::initLayout() |
38 | { |
39 | QBoxLayout *vbox = new QVBoxLayout(q); |
40 | |
41 | QFormLayout *form = new QFormLayout(); |
42 | vbox->addLayout(layout: form); |
43 | |
44 | form->addRow(label: titleLabel, field: title); |
45 | form->addRow(label: urlLabel, field: url); |
46 | form->addRow(label: commentLabel, field: comment); |
47 | |
48 | vbox->addWidget(folderTree); |
49 | vbox->addWidget(buttonBox); |
50 | } |
51 | |
52 | void KBookmarkDialogPrivate::initLayoutPrivate() |
53 | { |
54 | title = new QLineEdit(q); |
55 | title->setMinimumWidth(300); |
56 | titleLabel = new QLabel(KBookmarkDialog::tr(s: "Name:" , c: "@label:textbox" ), q); |
57 | titleLabel->setBuddy(title); |
58 | |
59 | url = new QLineEdit(q); |
60 | url->setMinimumWidth(300); |
61 | urlLabel = new QLabel(KBookmarkDialog::tr(s: "Location:" , c: "@label:textbox" ), q); |
62 | urlLabel->setBuddy(url); |
63 | |
64 | comment = new QLineEdit(q); |
65 | comment->setMinimumWidth(300); |
66 | commentLabel = new QLabel(KBookmarkDialog::tr(s: "Comment:" , c: "@label:textbox" ), q); |
67 | commentLabel->setBuddy(comment); |
68 | |
69 | folderTree = new QTreeWidget(q); |
70 | folderTree->setColumnCount(1); |
71 | folderTree->header()->hide(); |
72 | folderTree->setSortingEnabled(false); |
73 | folderTree->setSelectionMode(QTreeWidget::SingleSelection); |
74 | folderTree->setSelectionBehavior(QTreeWidget::SelectRows); |
75 | folderTree->setMinimumSize(minw: 60, minh: 100); |
76 | QTreeWidgetItem *root = new KBookmarkTreeItem(folderTree); |
77 | fillGroup(parentItem: root, group: mgr->root()); |
78 | |
79 | buttonBox = new QDialogButtonBox(q); |
80 | buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
81 | q->connect(sender: buttonBox, signal: &QDialogButtonBox::accepted, context: q, slot: &KBookmarkDialog::accept); |
82 | q->connect(sender: buttonBox, signal: &QDialogButtonBox::rejected, context: q, slot: &QDialog::reject); |
83 | |
84 | initLayout(); |
85 | layout = true; |
86 | } |
87 | |
88 | void KBookmarkDialogPrivate::fillGroup(QTreeWidgetItem *parentItem, const KBookmarkGroup &group, const KBookmarkGroup &selectGroup) |
89 | { |
90 | for (KBookmark bk = group.first(); !bk.isNull(); bk = group.next(current: bk)) { |
91 | if (bk.isGroup()) { |
92 | const KBookmarkGroup bkGroup = bk.toGroup(); |
93 | QTreeWidgetItem *item = new KBookmarkTreeItem(parentItem, folderTree, bkGroup); |
94 | if (selectGroup == bkGroup) { |
95 | folderTree->setCurrentItem(item); |
96 | } |
97 | fillGroup(parentItem: item, group: bkGroup, selectGroup); |
98 | } |
99 | } |
100 | } |
101 | |
102 | void KBookmarkDialogPrivate::setParentBookmark(const KBookmark &bm) |
103 | { |
104 | QString address = bm.address(); |
105 | KBookmarkTreeItem *item = static_cast<KBookmarkTreeItem *>(folderTree->topLevelItem(index: 0)); |
106 | while (true) { |
107 | if (item->address() == bm.address()) { |
108 | folderTree->setCurrentItem(item); |
109 | return; |
110 | } |
111 | for (int i = 0; i < item->childCount(); ++i) { |
112 | KBookmarkTreeItem *child = static_cast<KBookmarkTreeItem *>(item->child(index: i)); |
113 | if (KBookmark::commonParent(A: child->address(), B: address) == child->address()) { |
114 | item = child; |
115 | break; |
116 | } |
117 | } |
118 | } |
119 | } |
120 | |
121 | KBookmarkGroup KBookmarkDialogPrivate::parentBookmark() |
122 | { |
123 | KBookmarkTreeItem *item = dynamic_cast<KBookmarkTreeItem *>(folderTree->currentItem()); |
124 | if (!item) { |
125 | return mgr->root(); |
126 | } |
127 | const QString &address = item->address(); |
128 | return mgr->findByAddress(address).toGroup(); |
129 | } |
130 | |
131 | void KBookmarkDialog::accept() |
132 | { |
133 | if (d->mode == KBookmarkDialogPrivate::NewFolder) { |
134 | KBookmarkGroup parent = d->parentBookmark(); |
135 | if (d->title->text().isEmpty()) { |
136 | d->title->setText(QStringLiteral("New Folder" )); |
137 | } |
138 | d->bm = parent.createNewFolder(text: d->title->text()); |
139 | d->bm.setDescription(d->comment->text()); |
140 | d->mgr->emitChanged(group: parent); |
141 | } else if (d->mode == KBookmarkDialogPrivate::NewBookmark) { |
142 | KBookmarkGroup parent = d->parentBookmark(); |
143 | if (d->title->text().isEmpty()) { |
144 | d->title->setText(QStringLiteral("New Bookmark" )); |
145 | } |
146 | d->bm = parent.addBookmark(text: d->title->text(), url: QUrl(d->url->text()), icon: d->icon); |
147 | d->bm.setDescription(d->comment->text()); |
148 | d->mgr->emitChanged(group: parent); |
149 | } else if (d->mode == KBookmarkDialogPrivate::NewMultipleBookmarks) { |
150 | KBookmarkGroup parent = d->parentBookmark(); |
151 | if (d->title->text().isEmpty()) { |
152 | d->title->setText(QStringLiteral("New Folder" )); |
153 | } |
154 | d->bm = parent.createNewFolder(text: d->title->text()); |
155 | d->bm.setDescription(d->comment->text()); |
156 | for (const KBookmarkOwner::FutureBookmark &fb : std::as_const(t&: d->list)) { |
157 | d->bm.toGroup().addBookmark(text: fb.title(), url: fb.url(), icon: fb.icon()); |
158 | } |
159 | d->mgr->emitChanged(group: parent); |
160 | } else if (d->mode == KBookmarkDialogPrivate::EditBookmark) { |
161 | d->bm.setFullText(d->title->text()); |
162 | d->bm.setUrl(QUrl(d->url->text())); |
163 | d->bm.setDescription(d->comment->text()); |
164 | d->mgr->emitChanged(group: d->bm.parentGroup()); |
165 | } else if (d->mode == d->SelectFolder) { |
166 | d->bm = d->parentBookmark(); |
167 | } |
168 | QDialog::accept(); |
169 | } |
170 | |
171 | KBookmark KBookmarkDialog::editBookmark(const KBookmark &bm) |
172 | { |
173 | if (!d->layout) { |
174 | d->initLayoutPrivate(); |
175 | } |
176 | |
177 | KGuiItem::assign(button: d->buttonBox->button(which: QDialogButtonBox::Ok), item: KGuiItem(tr(s: "Update" , c: "@action:button" ))); |
178 | setWindowTitle(tr(s: "Bookmark Properties" , c: "@title:window" )); |
179 | d->url->setVisible(!bm.isGroup()); |
180 | d->urlLabel->setVisible(!bm.isGroup()); |
181 | d->bm = bm; |
182 | d->title->setText(bm.fullText()); |
183 | d->url->setText(bm.url().toString()); |
184 | d->comment->setVisible(true); |
185 | d->commentLabel->setVisible(true); |
186 | d->comment->setText(bm.description()); |
187 | d->folderTree->setVisible(false); |
188 | |
189 | d->mode = KBookmarkDialogPrivate::EditBookmark; |
190 | |
191 | if (exec() == QDialog::Accepted) { |
192 | return d->bm; |
193 | } else { |
194 | return KBookmark(); |
195 | } |
196 | } |
197 | |
198 | KBookmark KBookmarkDialog::addBookmark(const QString &title, const QUrl &url, const QString &icon, KBookmark parent) |
199 | { |
200 | if (!d->layout) { |
201 | d->initLayoutPrivate(); |
202 | } |
203 | if (parent.isNull()) { |
204 | parent = d->mgr->root(); |
205 | } |
206 | |
207 | QPushButton *newButton = new QPushButton; |
208 | KGuiItem::assign(button: newButton, item: KGuiItem(tr(s: "&New Folder..." , c: "@action:button" ), QStringLiteral("folder-new" ))); |
209 | d->buttonBox->addButton(button: newButton, role: QDialogButtonBox::ActionRole); |
210 | connect(sender: newButton, signal: &QAbstractButton::clicked, context: this, slot: &KBookmarkDialog::newFolderButton); |
211 | |
212 | KGuiItem::assign(button: d->buttonBox->button(which: QDialogButtonBox::Ok), item: KGuiItem(tr(s: "Add" , c: "@action:button" ), QStringLiteral("bookmark-new" ))); |
213 | setWindowTitle(tr(s: "Add Bookmark" , c: "@title:window" )); |
214 | d->url->setVisible(true); |
215 | d->urlLabel->setVisible(true); |
216 | d->title->setText(title); |
217 | d->url->setText(url.toString()); |
218 | d->comment->setText(QString()); |
219 | d->comment->setVisible(true); |
220 | d->commentLabel->setVisible(true); |
221 | d->setParentBookmark(parent); |
222 | d->folderTree->setVisible(true); |
223 | d->icon = icon; |
224 | |
225 | d->mode = KBookmarkDialogPrivate::NewBookmark; |
226 | |
227 | if (exec() == QDialog::Accepted) { |
228 | return d->bm; |
229 | } else { |
230 | return KBookmark(); |
231 | } |
232 | } |
233 | |
234 | KBookmarkGroup KBookmarkDialog::addBookmarks(const QList<KBookmarkOwner::FutureBookmark> &list, const QString &name, KBookmarkGroup parent) |
235 | { |
236 | if (!d->layout) { |
237 | d->initLayoutPrivate(); |
238 | } |
239 | if (parent.isNull()) { |
240 | parent = d->mgr->root(); |
241 | } |
242 | |
243 | d->list = list; |
244 | |
245 | QPushButton *newButton = new QPushButton; |
246 | KGuiItem::assign(button: newButton, item: KGuiItem(tr(s: "&New Folder..." , c: "@action:button" ), QStringLiteral("folder-new" ))); |
247 | d->buttonBox->addButton(button: newButton, role: QDialogButtonBox::ActionRole); |
248 | connect(sender: newButton, signal: &QAbstractButton::clicked, context: this, slot: &KBookmarkDialog::newFolderButton); |
249 | |
250 | KGuiItem::assign(button: d->buttonBox->button(which: QDialogButtonBox::Ok), item: KGuiItem(tr(s: "Add" , c: "@action:button" ), QStringLiteral("bookmark-new" ))); |
251 | setWindowTitle(tr(s: "Add Bookmarks" , c: "@title:window" )); |
252 | d->url->setVisible(false); |
253 | d->urlLabel->setVisible(false); |
254 | d->title->setText(name); |
255 | d->comment->setVisible(true); |
256 | d->commentLabel->setVisible(true); |
257 | d->comment->setText(QString()); |
258 | d->setParentBookmark(parent); |
259 | d->folderTree->setVisible(true); |
260 | |
261 | d->mode = KBookmarkDialogPrivate::NewMultipleBookmarks; |
262 | |
263 | if (exec() == QDialog::Accepted) { |
264 | return d->bm.toGroup(); |
265 | } else { |
266 | return KBookmarkGroup(); |
267 | } |
268 | } |
269 | |
270 | KBookmarkGroup KBookmarkDialog::selectFolder(KBookmark parent) |
271 | { |
272 | if (!d->layout) { |
273 | d->initLayoutPrivate(); |
274 | } |
275 | if (parent.isNull()) { |
276 | parent = d->mgr->root(); |
277 | } |
278 | |
279 | QPushButton *newButton = new QPushButton; |
280 | KGuiItem::assign(button: newButton, item: KGuiItem(tr(s: "&New Folder..." , c: "@action:button" ), QStringLiteral("folder-new" ))); |
281 | d->buttonBox->addButton(button: newButton, role: QDialogButtonBox::ActionRole); |
282 | connect(sender: newButton, signal: &QAbstractButton::clicked, context: this, slot: &KBookmarkDialog::newFolderButton); |
283 | |
284 | setWindowTitle(tr(s: "Select Folder" , c: "@title:window" )); |
285 | d->url->setVisible(false); |
286 | d->urlLabel->setVisible(false); |
287 | d->title->setVisible(false); |
288 | d->titleLabel->setVisible(false); |
289 | d->comment->setVisible(false); |
290 | d->commentLabel->setVisible(false); |
291 | d->setParentBookmark(parent); |
292 | d->folderTree->setVisible(true); |
293 | |
294 | d->mode = d->SelectFolder; |
295 | |
296 | if (exec() == QDialog::Accepted) { |
297 | return d->bm.toGroup(); |
298 | } else { |
299 | return KBookmarkGroup(); |
300 | } |
301 | } |
302 | |
303 | KBookmarkGroup KBookmarkDialog::createNewFolder(const QString &name, KBookmark parent) |
304 | { |
305 | if (!d->layout) { |
306 | d->initLayoutPrivate(); |
307 | } |
308 | if (parent.isNull()) { |
309 | parent = d->mgr->root(); |
310 | } |
311 | |
312 | setWindowTitle(tr(s: "New Folder" , c: "@title:window" )); |
313 | d->url->setVisible(false); |
314 | d->urlLabel->setVisible(false); |
315 | d->comment->setVisible(true); |
316 | d->commentLabel->setVisible(true); |
317 | d->comment->setText(QString()); |
318 | d->title->setText(name); |
319 | d->setParentBookmark(parent); |
320 | d->folderTree->setVisible(true); |
321 | |
322 | d->mode = KBookmarkDialogPrivate::NewFolder; |
323 | |
324 | if (exec() == QDialog::Accepted) { |
325 | return d->bm.toGroup(); |
326 | } else { |
327 | return KBookmarkGroup(); |
328 | } |
329 | } |
330 | |
331 | KBookmarkDialog::KBookmarkDialog(KBookmarkManager *mgr, QWidget *parent) |
332 | : QDialog(parent) |
333 | , d(new KBookmarkDialogPrivate(this)) |
334 | { |
335 | d->mgr = mgr; |
336 | } |
337 | |
338 | KBookmarkDialog::~KBookmarkDialog() = default; |
339 | |
340 | void KBookmarkDialog::newFolderButton() |
341 | { |
342 | QString caption = d->parentBookmark().fullText().isEmpty() ? tr(s: "Create New Bookmark Folder" , c: "@title:window" ) |
343 | : tr(s: "Create New Bookmark Folder in %1" , c: "@title:window" ).arg(a: d->parentBookmark().text()); |
344 | bool ok; |
345 | QString text = QInputDialog::getText(parent: this, title: caption, label: tr(s: "New folder:" , c: "@label:textbox" ), echo: QLineEdit::Normal, text: QString(), ok: &ok); |
346 | if (!ok) { |
347 | return; |
348 | } |
349 | |
350 | KBookmarkGroup group = d->parentBookmark().createNewFolder(text); |
351 | if (!group.isNull()) { |
352 | KBookmarkGroup parentGroup = group.parentGroup(); |
353 | d->mgr->emitChanged(group: parentGroup); |
354 | d->folderTree->clear(); |
355 | QTreeWidgetItem *root = new KBookmarkTreeItem(d->folderTree); |
356 | d->fillGroup(parentItem: root, group: d->mgr->root(), selectGroup: group); |
357 | } |
358 | } |
359 | |
360 | /********************************************************************/ |
361 | |
362 | KBookmarkTreeItem::KBookmarkTreeItem(QTreeWidget *tree) |
363 | : QTreeWidgetItem(tree) |
364 | , m_address(QLatin1String("" )) |
365 | { |
366 | setText(column: 0, atext: KBookmarkDialog::tr(s: "Bookmarks" , c: "name of the container of all browser bookmarks" )); |
367 | setIcon(column: 0, aicon: QIcon::fromTheme(QStringLiteral("bookmarks" ))); |
368 | tree->expandItem(item: this); |
369 | tree->setCurrentItem(this); |
370 | setSelected(true); |
371 | } |
372 | |
373 | KBookmarkTreeItem::KBookmarkTreeItem(QTreeWidgetItem *parent, QTreeWidget *tree, const KBookmarkGroup &bk) |
374 | : QTreeWidgetItem(parent) |
375 | { |
376 | setIcon(column: 0, aicon: QIcon::fromTheme(name: bk.icon())); |
377 | setText(column: 0, atext: bk.fullText()); |
378 | tree->expandItem(item: this); |
379 | m_address = bk.address(); |
380 | } |
381 | |
382 | KBookmarkTreeItem::~KBookmarkTreeItem() |
383 | { |
384 | } |
385 | |
386 | QString KBookmarkTreeItem::address() |
387 | { |
388 | return m_address; |
389 | } |
390 | |
391 | #include "moc_kbookmarkdialog.cpp" |
392 | |