10#include <QInputDialog>
12#include <QLoggingCategory>
14#include "RabbitCommonDir.h"
15#include "FrmBookmark.h"
16#include "ui_FrmBookmark.h"
18static Q_LOGGING_CATEGORY(log,
"WebBrowser.Bookmark")
24 , m_pTreeView(
nullptr)
25 , m_pSearchEdit(
nullptr)
27 , m_pModel(new QStandardItemModel(this))
30 setWindowTitle(tr(
"Bookmark"));
37 resize(m_pPara->GetWindowSize());
40CFrmBookmark::~CFrmBookmark()
45void CFrmBookmark::setupUI()
48 QVBoxLayout *pMainLayout =
new QVBoxLayout(
this);
49 if(!pMainLayout)
return;
53 pMainLayout->addWidget(m_pToolBar);
56 QHBoxLayout *pSearchLayout =
new QHBoxLayout;
58 pSearchLayout->addWidget(
new QLabel(tr(
"Search:")));
60 m_pSearchEdit =
new QLineEdit(
this);
62 m_pSearchEdit->setPlaceholderText(tr(
"Input keyword to search boolmark ......"));
63 m_pSearchEdit->setClearButtonEnabled(
true);
64 check = connect(m_pSearchEdit, &QLineEdit::textChanged,
65 this, &CFrmBookmark::onSearchTextChanged);
67 pSearchLayout->addWidget(m_pSearchEdit);
69 pMainLayout->addLayout(pSearchLayout);
74 pMainLayout->addWidget(m_pTreeView);
77 QHBoxLayout *pButtonLayout =
new QHBoxLayout;
79 pButtonLayout->addStretch();
81 QPushButton *closeButton =
new QPushButton(tr(
"Close"),
this);
82 connect(closeButton, &QPushButton::clicked,
this, &CFrmBookmark::close);
83 pButtonLayout->addWidget(closeButton);
85 pMainLayout->addLayout(pButtonLayout);
87 setLayout(pMainLayout);
90void CFrmBookmark::setupToolBar()
93 m_pToolBar =
new QToolBar(
this);
94 if(!m_pToolBar)
return;
97 QAction *addAction = m_pToolBar->addAction(QIcon::fromTheme(
"add"), tr(
"Add bookmark"));
99 check = connect(addAction, &QAction::triggered,
this, &CFrmBookmark::onAddBookmark);
104 QAction *addFolderAction = m_pToolBar->addAction(QIcon::fromTheme(
"folder-new"), tr(
"Add folder"));
105 if(addFolderAction) {
106 check = connect(addFolderAction, &QAction::triggered,
this, &CFrmBookmark::onAddFolder);
110 m_pToolBar->addSeparator();
113 QAction *editAction = m_pToolBar->addAction(QIcon::fromTheme(
"edit"), tr(
"Edit"));
115 check = connect(editAction, &QAction::triggered,
this, &CFrmBookmark::onEditBookmark);
120 QAction *pDeleteAction = m_pToolBar->addAction(QIcon::fromTheme(
"edit-delete"), tr(
"Delete"));
122 check = connect(pDeleteAction, &QAction::triggered,
this, &CFrmBookmark::onDeleteBookmark);
127 QAction *favoriteAction = m_pToolBar->addAction(QIcon::fromTheme(
"favorites"), tr(
"Favorite"));
129 check = connect(favoriteAction, &QAction::triggered,
this, &CFrmBookmark::onSetFavorite);
133 m_pToolBar->addSeparator();
136 QAction *importAction = m_pToolBar->addAction(QIcon::fromTheme(
"import"), tr(
"Import"));
138 check = connect(importAction, &QAction::triggered,
this, &CFrmBookmark::onImportBookmarks);
143 QAction *exportAction = m_pToolBar->addAction(QIcon::fromTheme(
"export"), tr(
"Export"));
145 check = connect(exportAction, &QAction::triggered,
this, &CFrmBookmark::onExportBookmarks);
149 m_pToolBar->addSeparator();
152 QAction *refreshAction = m_pToolBar->addAction(QIcon::fromTheme(
"view-refresh"), tr(
"Refresh"));
154 check = connect(refreshAction, &QAction::triggered,
this, &CFrmBookmark::refresh);
159void CFrmBookmark::setupTreeView()
162 m_pTreeView =
new QTreeView(
this);
163 if(!m_pTreeView)
return;
164 m_pTreeView->setHeaderHidden(
true);
165 m_pTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
166 m_pTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
169 check = connect(m_pTreeView, &QTreeView::doubleClicked,
170 this, &CFrmBookmark::onTreeViewDoubleClicked);
172 check = connect(m_pTreeView, &QTreeView::customContextMenuRequested,
173 this, &CFrmBookmark::onCustomContextMenu);
177 m_pTreeView->setModel(m_pModel);
179 m_pModel->setColumnCount(1);
186void CFrmBookmark::loadBookmarks()
188 if(!m_pDatabase || !m_pModel || !m_pTreeView)
return;
190 m_folderItems.clear();
193 m_pModel->setHorizontalHeaderLabels(QStringList() << tr(
"Title"));
196 QList<BookmarkItem> folders = m_pDatabase->getAllFolders();
199 QStandardItem *rootItem = m_pModel->invisibleRootItem();
201 int nCurrent = m_pPara->GetBookmarkCurrentFolder();
202 QStandardItem* pCurrentItem =
nullptr;
205 for (
const auto &folder : folders) {
206 if (folder.folderId == 0) {
207 QStandardItem *pFolderItem =
new QStandardItem(folder.getIcon(), folder.title);
208 if(!pFolderItem)
continue;
209 pFolderItem->setData(folder.id, ID);
210 pFolderItem->setData(BookmarkType_Folder, Type);
211 rootItem->appendRow(pFolderItem);
212 m_folderItems[folder.id] = pFolderItem;
213 if(folder.id == nCurrent)
214 pCurrentItem = pFolderItem;
218 auto it = m_folderItems.find(folder.folderId);
219 if(m_folderItems.end() == it) {
220 qWarning(log) <<
"The parent of folder is not find:" << folder.folderId;
223 QStandardItem *pFolderItem =
new QStandardItem(folder.getIcon(), folder.title);
224 if(!pFolderItem)
continue;
225 pFolderItem->setData(folder.id, ID);
226 pFolderItem->setData(BookmarkType_Folder, Type);
227 (*it)->appendRow(pFolderItem);
228 m_folderItems[folder.id] = pFolderItem;
229 if(folder.id == nCurrent)
230 pCurrentItem = pFolderItem;
235 auto index = m_pModel->indexFromItem(pCurrentItem);
236 m_pTreeView->setCurrentIndex(index);
240 QList<BookmarkItem> bookmarks = m_pDatabase->getAllBookmarks(-1);
241 for (
const auto &bookmark : bookmarks) {
242 QStandardItem *pParentItem =
nullptr;
244 if (bookmark.folderId > 0 && m_folderItems.contains(bookmark.folderId)) {
245 pParentItem = m_folderItems[bookmark.folderId];
247 pParentItem = rootItem;
250 QStandardItem *bookmarkItem =
new QStandardItem(bookmark.getIcon(), bookmark.title);
251 bookmarkItem->setData(bookmark.id, ID);
252 bookmarkItem->setData(BookmarkType_Bookmark, Type);
253 bookmarkItem->setData(bookmark.url, Url);
256 pParentItem->appendRow(bookmarkItem);
260 m_pTreeView->expandAll();
263void CFrmBookmark::onAddBookmark()
266 QString url = QInputDialog::getText(
this, tr(
"Add bookmark"),
267 tr(
"Url:"), QLineEdit::Normal,
269 if (!ok || url.isEmpty())
return;
271 QString title = QInputDialog::getText(
this, tr(
"Add bookmark"),
272 tr(
"Title:"), QLineEdit::Normal,
278 item.title = title.isEmpty() ? url : title;
279 item.createdTime = QDateTime::currentDateTime();
280 item.lastVisitTime = item.createdTime;
281 item.modifiedTime = item.createdTime;
284 QModelIndex currentIndex = m_pTreeView->currentIndex();
285 if (currentIndex.isValid()) {
286 int type = currentIndex.data(Type).toInt();
287 if (BookmarkType_Folder == type) {
288 item.folderId = currentIndex.data(Qt::UserRole).toInt();
292 if (m_pDatabase->addBookmark(item)) {
297void CFrmBookmark::onAddFolder()
300 QString name = QInputDialog::getText(
this, tr(
"Add folder"),
301 tr(
"Folder name:"), QLineEdit::Normal,
303 if (!ok || name.isEmpty())
return;
306 QModelIndex currentIndex = m_pTreeView->currentIndex();
307 if (currentIndex.isValid()) {
308 int type = currentIndex.data(Type).toInt();
309 if (BookmarkType_Folder == type) {
310 parentId = currentIndex.data(Qt::UserRole).toInt();
314 if (m_pDatabase->addFolder(name, parentId)) {
319void CFrmBookmark::onEditBookmark()
321 QModelIndex index = m_pTreeView->currentIndex();
322 if (!index.isValid())
return;
324 int type = index.data(Type).toInt();
325 int id = index.data(Qt::UserRole).toInt();
327 if (BookmarkType_Bookmark == type) {
329 if (item.id == 0)
return;
332 QString title = QInputDialog::getText(
this, tr(
"Edit bookmark"),
333 tr(
"Title:"), QLineEdit::Normal,
337 QString url = QInputDialog::getText(
this, tr(
"Add bookmark"),
338 tr(
"Url:"), QLineEdit::Normal,
345 if (m_pDatabase->updateBookmark(item)) {
348 }
else if (BookmarkType_Folder == type) {
349 QString oldName = index.data(Qt::DisplayRole).toString();
352 QString newName = QInputDialog::getText(
this, tr(
"Rename folder"),
353 tr(
"Folder name:"), QLineEdit::Normal,
355 if (!ok || newName.isEmpty())
return;
357 if (m_pDatabase->renameFolder(
id, newName)) {
363void CFrmBookmark::onDeleteBookmark()
365 QModelIndex index = m_pTreeView->currentIndex();
366 if (!index.isValid())
return;
368 int type = index.data(Type).toInt();
369 QString name = index.data(Qt::DisplayRole).toString();
370 int id = index.data(Qt::UserRole).toInt();
371 if(1 ==
id && BookmarkType_Folder == type) {
372 QMessageBox::warning(
this, tr(
"Warning"), tr(
"The folder \"%1\" is not delete").arg(name));
377 if (BookmarkType_Bookmark == type) {
378 message = tr(
"Are you sure you want to delete the bookmark \"%1\"?").arg(name);
379 }
else if (BookmarkType_Folder == type) {
380 message = tr(
"Are you sure you want to delete the folder \"%1\"?").arg(name);
385 QMessageBox::StandardButton reply = QMessageBox::question(
386 this, tr(
"Confirm deletion"), message,
387 QMessageBox::Yes | QMessageBox::No,
391 if (reply == QMessageBox::Yes) {
392 if (BookmarkType_Bookmark == type) {
393 m_pDatabase->deleteBookmark(
id);
394 }
else if (BookmarkType_Folder == type) {
395 m_pDatabase->deleteFolder(
id);
401void CFrmBookmark::onSetFavorite()
403 QModelIndex index = m_pTreeView->currentIndex();
404 if (!index.isValid())
return;
406 int type = index.data(Type).toInt();
407 if (type != BookmarkType_Bookmark)
return;
409 int id = index.data(ID).toInt();
411 if (item.id == 0)
return;
413 if (m_pDatabase->updateBookmark(item)) {
418void CFrmBookmark::onImportBookmarks()
420 QString filename = QFileDialog::getOpenFileName(
421 this, tr(
"Import bookmarks"),
422 RabbitCommon::CDir::Instance()->GetDirUserDocument(),
423 tr(
"HTML(*.html);; All files (*.*)"));
425 if (!filename.isEmpty()) {
426 if (m_pDatabase->importFromHtml(filename)) {
427 QMessageBox::information(
this, tr(
"Success"), tr(
"Bookmarks imported successfully"));
430 QMessageBox::warning(
this, tr(
"Failure"), tr(
"Failed to import bookmark"));
435void CFrmBookmark::onExportBookmarks()
437 QString filename = QFileDialog::getSaveFileName(
438 this, tr(
"Export bookmarks"),
439 RabbitCommon::CDir::Instance()->GetDirUserDocument(),
440 tr(
"HTML (*.html);; All files (*.*)"));
442 if (!filename.isEmpty()) {
443 if (m_pDatabase->exportToHtml(filename)) {
444 QMessageBox::information(
this, tr(
"Success"), tr(
"Bookmarks exported successfully"));
446 QMessageBox::warning(
this, tr(
"Failure"), tr(
"Failed to export bookmark"));
451void CFrmBookmark::onSearchTextChanged(
const QString &text)
453 if (text.isEmpty()) {
458 if(!m_pModel)
return;
461 m_folderItems.clear();
463 QList<BookmarkItem> bookmarks = m_pDatabase->searchBookmarks(text);
464 QStandardItem *pRootItem = m_pModel->invisibleRootItem();
465 if(!pRootItem)
return;
467 foreach (
const auto &bookmark, bookmarks) {
468 QStandardItem *item =
new QStandardItem(
469 bookmark.getIcon(), bookmark.title);
470 item->setData(bookmark.id, ID);
471 item->setData(BookmarkType_Bookmark, Type);
472 item->setData(bookmark.url, Url);
474 item->setToolTip(bookmark.url);
476 pRootItem->appendRow(item);
480void CFrmBookmark::onTreeViewDoubleClicked(
const QModelIndex &index)
482 if(!m_pDatabase)
return;
483 int type = index.data(Type).toInt();
484 if (BookmarkType_Bookmark == type) {
485 QString url = index.data(Url).toString();
486 int id = index.data(ID).toInt();
487 if (!url.isEmpty()) {
489 item.lastVisitTime = QDateTime::currentDateTime();
490 m_pDatabase->updateBookmark(item);
491 emit openUrlRequested(url);
497void CFrmBookmark::onCustomContextMenu(
const QPoint &pos)
499 if(!m_pTreeView)
return;
500 QModelIndex index = m_pTreeView->indexAt(pos);
501 if (!index.isValid())
return;
505 int id = index.data(ID).toInt();
506 int type = index.data(Type).toInt();
508 if (BookmarkType_Bookmark == type) {
509 menu.addAction(QIcon::fromTheme(
"document-open"), tr(
"Open"),
this, [
this, index]() {
510 onTreeViewDoubleClicked(index);
513 menu.addAction(QIcon::fromTheme(
"edit"), tr(
"Edit"),
this, &CFrmBookmark::onEditBookmark);
516 QAction *favoriteAction = menu.addAction(QIcon::fromTheme(
"favorites"), tr(
"Favorite"));
517 connect(favoriteAction, &QAction::triggered,
this, &CFrmBookmark::onSetFavorite);
519 menu.addAction(QIcon::fromTheme(
"edit-delete"), tr(
"Delete"),
this, &CFrmBookmark::onDeleteBookmark);
520 }
else if (BookmarkType_Folder == type) {
521 menu.addAction(QIcon::fromTheme(
"Add"), tr(
"Add bookmark"),
this, &CFrmBookmark::onAddBookmark);
522 menu.addAction(QIcon::fromTheme(
"folder-new"), tr(
"Add folder"),
this, &CFrmBookmark::onAddFolder);
524 menu.addAction(QIcon::fromTheme(
"edit"), tr(
"Edit"),
this, &CFrmBookmark::onEditBookmark);
526 menu.addAction(QIcon::fromTheme(
"edit-delete"), tr(
"Delete"),
this, &CFrmBookmark::onDeleteBookmark);
529 menu.exec(m_pTreeView->viewport()->mapToGlobal(pos));
532void CFrmBookmark::refresh()