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
26KBookmarkDialogPrivate::KBookmarkDialogPrivate(KBookmarkDialog *qq)
27 : q(qq)
28 , folderTree(nullptr)
29 , layout(false)
30{
31}
32
33KBookmarkDialogPrivate::~KBookmarkDialogPrivate()
34{
35}
36
37void 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
52void 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
88void 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
102void 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
121KBookmarkGroup 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
131void 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
171KBookmark 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
198KBookmark 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
234KBookmarkGroup 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
270KBookmarkGroup 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
303KBookmarkGroup 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
331KBookmarkDialog::KBookmarkDialog(KBookmarkManager *mgr, QWidget *parent)
332 : QDialog(parent)
333 , d(new KBookmarkDialogPrivate(this))
334{
335 d->mgr = mgr;
336}
337
338KBookmarkDialog::~KBookmarkDialog() = default;
339
340void 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
362KBookmarkTreeItem::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
373KBookmarkTreeItem::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
382KBookmarkTreeItem::~KBookmarkTreeItem()
383{
384}
385
386QString KBookmarkTreeItem::address()
387{
388 return m_address;
389}
390
391#include "moc_kbookmarkdialog.cpp"
392

source code of kbookmarks/src/widgets/kbookmarkdialog.cpp