Advance Wayland and KDE package bring-up
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
add_subdirectory(widgets)
|
||||
|
||||
add_library(KF6Bookmarks)
|
||||
add_library(KF6::Bookmarks ALIAS KF6Bookmarks)
|
||||
|
||||
set_target_properties(KF6Bookmarks PROPERTIES
|
||||
VERSION ${KBOOKMARKS_VERSION}
|
||||
SOVERSION ${KBOOKMARKS_SOVERSION}
|
||||
EXPORT_NAME Bookmarks
|
||||
)
|
||||
|
||||
ecm_create_qm_loader(KF6Bookmarks kbookmarks6_qt)
|
||||
|
||||
target_sources(KF6Bookmarks PRIVATE
|
||||
kbookmarkaction.cpp
|
||||
kbookmarkaction.h
|
||||
kbookmarkactioninterface.cpp
|
||||
kbookmarkactioninterface.h
|
||||
kbookmark.cpp
|
||||
kbookmark.h
|
||||
kbookmarkmanager.cpp
|
||||
kbookmarkmanager.h
|
||||
kbookmarkowner.cpp
|
||||
kbookmarkowner.h
|
||||
keditbookmarks_p.h
|
||||
keditbookmarks.cpp
|
||||
kbookmarksettings.cpp
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(KF6Bookmarks
|
||||
HEADER kbookmarks_debug.h
|
||||
IDENTIFIER KBOOKMARKS_LOG
|
||||
CATEGORY_NAME kf.bookmarks
|
||||
OLD_CATEGORY_NAMES kf5.kbookmarks
|
||||
DESCRIPTION "KBookmarks"
|
||||
EXPORT KBOOKMARKS
|
||||
)
|
||||
|
||||
ecm_generate_export_header(KF6Bookmarks
|
||||
BASE_NAME KBookmarks
|
||||
GROUP_BASE_NAME KF
|
||||
VERSION ${KF_VERSION}
|
||||
USE_VERSION_HEADER
|
||||
DEPRECATED_BASE_VERSION 0
|
||||
DEPRECATION_VERSIONS
|
||||
EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
|
||||
)
|
||||
|
||||
target_include_directories(KF6Bookmarks INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KBookmarks>")
|
||||
|
||||
target_link_libraries(KF6Bookmarks PUBLIC Qt6::Gui Qt6::Xml)
|
||||
target_link_libraries(KF6Bookmarks PRIVATE
|
||||
KF6::CoreAddons # for KStringHandler
|
||||
KF6::ConfigCore # for KConfigGroup
|
||||
)
|
||||
|
||||
ecm_generate_headers(KBookmarks_HEADERS
|
||||
HEADER_NAMES
|
||||
KBookmark
|
||||
KBookmarkAction
|
||||
KBookmarkActionInterface
|
||||
KBookmarkManager
|
||||
KBookmarkOwner
|
||||
|
||||
REQUIRED_HEADERS KBookmarks_HEADERS
|
||||
)
|
||||
|
||||
install(TARGETS KF6Bookmarks EXPORT KF6BookmarksTargets ${KF_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kbookmarks_export.h
|
||||
${KBookmarks_HEADERS}
|
||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KBookmarks COMPONENT Devel
|
||||
)
|
||||
|
||||
ecm_qt_install_logging_categories(
|
||||
EXPORT KBOOKMARKS
|
||||
FILE kbookmarks.categories
|
||||
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
|
||||
)
|
||||
|
||||
if(BUILD_QCH)
|
||||
ecm_add_qch(
|
||||
KF6Bookmarks_QCH
|
||||
NAME KBookmarks
|
||||
BASE_NAME KF6Bookmarks
|
||||
VERSION ${KF_VERSION}
|
||||
ORG_DOMAIN org.kde
|
||||
SOURCES # using only public headers, to cover only public API
|
||||
${KBookmarks_HEADERS}
|
||||
MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md"
|
||||
LINK_QCHS
|
||||
Qt6Widgets_QCH
|
||||
Qt6Xml_QCH
|
||||
KF6WidgetsAddons_QCH
|
||||
INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
BLANK_MACROS
|
||||
KBOOKMARKS_EXPORT
|
||||
KBOOKMARKS_DEPRECATED
|
||||
KBOOKMARKS_DEPRECATED_EXPORT
|
||||
"KBOOKMARKS_DEPRECATED_VERSION(x, y, t)"
|
||||
TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR}
|
||||
QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR}
|
||||
COMPONENT Devel
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Extract strings from all source files.
|
||||
# EXTRACT_TR_STRINGS extracts strings with lupdate and convert them to .pot with
|
||||
# lconvert.
|
||||
$EXTRACT_TR_STRINGS `find . -name \*.cpp -o -name \*.h -o -name \*.ui -o -name \*.qml` -o $podir/kbookmarks6_qt.pot
|
||||
@@ -0,0 +1,725 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
|
||||
SPDX-FileCopyrightText: 2003 Alexander Kellett <lypanov@kde.org>
|
||||
SPDX-FileCopyrightText: 2008 Norbert Frese <nf2@scheinwelt.at>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "kbookmark.h"
|
||||
|
||||
#include <KStringHandler>
|
||||
#include <kurlmimedata.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QMimeDatabase>
|
||||
#include <QStack>
|
||||
#include <QDateTime>
|
||||
#include <QMimeData>
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace Strings
|
||||
{
|
||||
QString metaDataKDEOwner()
|
||||
{
|
||||
return QStringLiteral("http://www.kde.org");
|
||||
}
|
||||
QString metaDataFreedesktopOwner()
|
||||
{
|
||||
return QStringLiteral("http://freedesktop.org");
|
||||
}
|
||||
QString metaDataMimeOwner()
|
||||
{
|
||||
return QStringLiteral("http://www.freedesktop.org/standards/shared-mime-info");
|
||||
}
|
||||
|
||||
QString xbelMimeType()
|
||||
{
|
||||
return QStringLiteral("application/x-xbel");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////// utility functions
|
||||
|
||||
static QDomNode cd(QDomNode node, const QString &name, bool create)
|
||||
{
|
||||
QDomNode subnode = node.namedItem(name);
|
||||
if (create && subnode.isNull()) {
|
||||
subnode = node.ownerDocument().createElement(name);
|
||||
node.appendChild(subnode);
|
||||
}
|
||||
return subnode;
|
||||
}
|
||||
|
||||
static QDomNode cd_or_create(const QDomNode &node, const QString &name)
|
||||
{
|
||||
return cd(node, name, true);
|
||||
}
|
||||
|
||||
static QDomText get_or_create_text(QDomNode node)
|
||||
{
|
||||
QDomNode subnode = node.firstChild();
|
||||
if (subnode.isNull()) {
|
||||
subnode = node.ownerDocument().createTextNode(QLatin1String(""));
|
||||
node.appendChild(subnode);
|
||||
}
|
||||
return subnode.toText();
|
||||
}
|
||||
|
||||
static QDomNode findMetadata(const QString &forOwner, QDomNode &parent, bool create)
|
||||
{
|
||||
const bool forOwnerIsKDE = (forOwner == Strings::metaDataKDEOwner());
|
||||
|
||||
QDomElement metadataElement;
|
||||
for (QDomNode _node = parent.firstChild(); !_node.isNull(); _node = _node.nextSibling()) {
|
||||
QDomElement elem = _node.toElement();
|
||||
if (!elem.isNull() && elem.tagName() == QLatin1String("metadata")) {
|
||||
const QString owner = elem.attribute(QStringLiteral("owner"));
|
||||
if (owner == forOwner) {
|
||||
return elem;
|
||||
}
|
||||
if (owner.isEmpty() && forOwnerIsKDE) {
|
||||
metadataElement = elem;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (create && metadataElement.isNull()) {
|
||||
metadataElement = parent.ownerDocument().createElement(QStringLiteral("metadata"));
|
||||
parent.appendChild(metadataElement);
|
||||
metadataElement.setAttribute(QStringLiteral("owner"), forOwner);
|
||||
|
||||
} else if (!metadataElement.isNull() && forOwnerIsKDE) {
|
||||
// i'm not sure if this is good, we shouldn't take over foreign metadata
|
||||
metadataElement.setAttribute(QStringLiteral("owner"), Strings::metaDataKDEOwner());
|
||||
}
|
||||
return metadataElement;
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
KBookmarkGroup::KBookmarkGroup()
|
||||
: KBookmark(QDomElement())
|
||||
{
|
||||
}
|
||||
|
||||
KBookmarkGroup::KBookmarkGroup(const QDomElement &elem)
|
||||
: KBookmark(elem)
|
||||
{
|
||||
}
|
||||
|
||||
bool KBookmarkGroup::isOpen() const
|
||||
{
|
||||
return element.attribute(QStringLiteral("folded")) == QLatin1String("no"); // default is: folded
|
||||
}
|
||||
|
||||
KBookmark KBookmarkGroup::first() const
|
||||
{
|
||||
return KBookmark(nextKnownTag(element.firstChildElement(), true));
|
||||
}
|
||||
|
||||
KBookmark KBookmarkGroup::previous(const KBookmark ¤t) const
|
||||
{
|
||||
return KBookmark(nextKnownTag(current.element.previousSiblingElement(), false));
|
||||
}
|
||||
|
||||
KBookmark KBookmarkGroup::next(const KBookmark ¤t) const
|
||||
{
|
||||
return KBookmark(nextKnownTag(current.element.nextSiblingElement(), true));
|
||||
}
|
||||
|
||||
int KBookmarkGroup::indexOf(const KBookmark &child) const
|
||||
{
|
||||
int counter = 0;
|
||||
for (KBookmark bk = first(); !bk.isNull(); bk = next(bk), ++counter) {
|
||||
if (bk.element == child.element) {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QDomElement KBookmarkGroup::nextKnownTag(const QDomElement &start, bool goNext) const
|
||||
{
|
||||
for (QDomElement elem = start; !elem.isNull();) {
|
||||
QString tag = elem.tagName();
|
||||
if (tag == QLatin1String("folder") || tag == QLatin1String("bookmark") || tag == QLatin1String("separator")) {
|
||||
return elem;
|
||||
}
|
||||
if (goNext) {
|
||||
elem = elem.nextSiblingElement();
|
||||
} else {
|
||||
elem = elem.previousSiblingElement();
|
||||
}
|
||||
}
|
||||
return QDomElement();
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkGroup::createNewFolder(const QString &text)
|
||||
{
|
||||
if (isNull()) {
|
||||
return KBookmarkGroup();
|
||||
}
|
||||
QDomDocument doc = element.ownerDocument();
|
||||
QDomElement groupElem = doc.createElement(QStringLiteral("folder"));
|
||||
element.appendChild(groupElem);
|
||||
QDomElement textElem = doc.createElement(QStringLiteral("title"));
|
||||
groupElem.appendChild(textElem);
|
||||
textElem.appendChild(doc.createTextNode(text));
|
||||
return KBookmarkGroup(groupElem);
|
||||
}
|
||||
|
||||
KBookmark KBookmarkGroup::createNewSeparator()
|
||||
{
|
||||
if (isNull()) {
|
||||
return KBookmark();
|
||||
}
|
||||
QDomDocument doc = element.ownerDocument();
|
||||
Q_ASSERT(!doc.isNull());
|
||||
QDomElement sepElem = doc.createElement(QStringLiteral("separator"));
|
||||
element.appendChild(sepElem);
|
||||
return KBookmark(sepElem);
|
||||
}
|
||||
|
||||
bool KBookmarkGroup::moveBookmark(const KBookmark &item, const KBookmark &after)
|
||||
{
|
||||
QDomNode n;
|
||||
if (!after.isNull()) {
|
||||
n = element.insertAfter(item.element, after.element);
|
||||
} else { // first child
|
||||
if (element.firstChild().isNull()) { // Empty element -> set as real first child
|
||||
n = element.insertBefore(item.element, QDomElement());
|
||||
}
|
||||
|
||||
// we have to skip everything up to the first valid child
|
||||
QDomElement firstChild = nextKnownTag(element.firstChild().toElement(), true);
|
||||
if (!firstChild.isNull()) {
|
||||
if (firstChild == item.element) { // item is already the first child, done
|
||||
return true;
|
||||
}
|
||||
n = element.insertBefore(item.element, firstChild);
|
||||
} else {
|
||||
// No real first child -> append after the <title> etc.
|
||||
n = element.appendChild(item.element);
|
||||
}
|
||||
}
|
||||
return (!n.isNull());
|
||||
}
|
||||
|
||||
KBookmark KBookmarkGroup::addBookmark(const KBookmark &bm)
|
||||
{
|
||||
element.appendChild(bm.internalElement());
|
||||
return bm;
|
||||
}
|
||||
|
||||
KBookmark KBookmarkGroup::addBookmark(const QString &text, const QUrl &url, const QString &icon)
|
||||
{
|
||||
if (isNull()) {
|
||||
return KBookmark();
|
||||
}
|
||||
QDomDocument doc = element.ownerDocument();
|
||||
QDomElement elem = doc.createElement(QStringLiteral("bookmark"));
|
||||
elem.setAttribute(QStringLiteral("href"), url.toString(QUrl::FullyEncoded));
|
||||
|
||||
QDomElement textElem = doc.createElement(QStringLiteral("title"));
|
||||
elem.appendChild(textElem);
|
||||
textElem.appendChild(doc.createTextNode(text));
|
||||
|
||||
KBookmark newBookmark = addBookmark(KBookmark(elem));
|
||||
|
||||
// as icons are moved to metadata, we have to use the KBookmark API for this
|
||||
newBookmark.setIcon(icon);
|
||||
return newBookmark;
|
||||
}
|
||||
|
||||
void KBookmarkGroup::deleteBookmark(const KBookmark &bk)
|
||||
{
|
||||
element.removeChild(bk.element);
|
||||
}
|
||||
|
||||
bool KBookmarkGroup::isToolbarGroup() const
|
||||
{
|
||||
return (element.attribute(QStringLiteral("toolbar")) == QLatin1String("yes"));
|
||||
}
|
||||
|
||||
QDomElement KBookmarkGroup::findToolbar() const
|
||||
{
|
||||
if (element.attribute(QStringLiteral("toolbar")) == QLatin1String("yes")) {
|
||||
return element;
|
||||
}
|
||||
for (QDomElement e = element.firstChildElement(QStringLiteral("folder")); !e.isNull(); e = e.nextSiblingElement(QStringLiteral("folder"))) {
|
||||
QDomElement result = KBookmarkGroup(e).findToolbar();
|
||||
if (!result.isNull()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return QDomElement();
|
||||
}
|
||||
|
||||
QList<QUrl> KBookmarkGroup::groupUrlList() const
|
||||
{
|
||||
QList<QUrl> urlList;
|
||||
for (KBookmark bm = first(); !bm.isNull(); bm = next(bm)) {
|
||||
if (bm.isSeparator() || bm.isGroup()) {
|
||||
continue;
|
||||
}
|
||||
urlList << bm.url();
|
||||
}
|
||||
return urlList;
|
||||
}
|
||||
|
||||
//////
|
||||
|
||||
KBookmark::KBookmark()
|
||||
{
|
||||
}
|
||||
|
||||
KBookmark::KBookmark(const QDomElement &elem)
|
||||
: element(elem)
|
||||
{
|
||||
}
|
||||
|
||||
bool KBookmark::isGroup() const
|
||||
{
|
||||
QString tag = element.tagName();
|
||||
return tag == QLatin1String("folder") //
|
||||
|| tag == QLatin1String("xbel"); // don't forget the toplevel group
|
||||
}
|
||||
|
||||
bool KBookmark::isSeparator() const
|
||||
{
|
||||
return (element.tagName() == QLatin1String("separator"));
|
||||
}
|
||||
|
||||
bool KBookmark::isNull() const
|
||||
{
|
||||
return element.isNull();
|
||||
}
|
||||
|
||||
bool KBookmark::hasParent() const
|
||||
{
|
||||
QDomElement parent = element.parentNode().toElement();
|
||||
return !parent.isNull();
|
||||
}
|
||||
|
||||
QString KBookmark::text() const
|
||||
{
|
||||
return KStringHandler::csqueeze(fullText());
|
||||
}
|
||||
|
||||
QString KBookmark::fullText() const
|
||||
{
|
||||
if (isSeparator()) {
|
||||
return QCoreApplication::translate("KBookmark", "--- separator ---", "Bookmark separator");
|
||||
}
|
||||
|
||||
QString text = element.namedItem(QStringLiteral("title")).toElement().text();
|
||||
text.replace(QLatin1Char('\n'), QLatin1Char(' ')); // #140673
|
||||
return text;
|
||||
}
|
||||
|
||||
void KBookmark::setFullText(const QString &fullText)
|
||||
{
|
||||
QDomNode titleNode = element.namedItem(QStringLiteral("title"));
|
||||
if (titleNode.isNull()) {
|
||||
titleNode = element.ownerDocument().createElement(QStringLiteral("title"));
|
||||
element.appendChild(titleNode);
|
||||
}
|
||||
|
||||
if (titleNode.firstChild().isNull()) {
|
||||
QDomText domtext = titleNode.ownerDocument().createTextNode(QLatin1String(""));
|
||||
titleNode.appendChild(domtext);
|
||||
}
|
||||
|
||||
QDomText domtext = titleNode.firstChild().toText();
|
||||
domtext.setData(fullText);
|
||||
}
|
||||
|
||||
QUrl KBookmark::url() const
|
||||
{
|
||||
return QUrl(element.attribute(QStringLiteral("href")));
|
||||
}
|
||||
|
||||
void KBookmark::setUrl(const QUrl &url)
|
||||
{
|
||||
element.setAttribute(QStringLiteral("href"), url.toString());
|
||||
}
|
||||
|
||||
QString KBookmark::icon() const
|
||||
{
|
||||
QDomNode metaDataNode = metaData(Strings::metaDataFreedesktopOwner(), false);
|
||||
QDomElement iconElement = cd(metaDataNode, QStringLiteral("bookmark:icon"), false).toElement();
|
||||
|
||||
QString icon = iconElement.attribute(QStringLiteral("name"));
|
||||
|
||||
// migration code
|
||||
if (icon.isEmpty()) {
|
||||
icon = element.attribute(QStringLiteral("icon"));
|
||||
}
|
||||
if (icon == QLatin1String("www")) { // common icon for kde3 bookmarks
|
||||
return QStringLiteral("internet-web-browser");
|
||||
}
|
||||
// end migration code
|
||||
|
||||
if (icon == QLatin1String("bookmark_folder")) {
|
||||
return QStringLiteral("folder-bookmarks");
|
||||
}
|
||||
if (icon.isEmpty()) {
|
||||
// Default icon depends on URL for bookmarks, and is default directory
|
||||
// icon for groups.
|
||||
if (isGroup()) {
|
||||
icon = QStringLiteral("folder-bookmarks");
|
||||
} else {
|
||||
if (isSeparator()) {
|
||||
icon = QStringLiteral("edit-clear"); // whatever
|
||||
} else {
|
||||
// get icon from mimeType
|
||||
QMimeDatabase db;
|
||||
QMimeType mime;
|
||||
QString _mimeType = mimeType();
|
||||
if (!_mimeType.isEmpty()) {
|
||||
mime = db.mimeTypeForName(_mimeType);
|
||||
} else {
|
||||
mime = db.mimeTypeForUrl(url());
|
||||
}
|
||||
if (mime.isValid()) {
|
||||
icon = mime.iconName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
void KBookmark::setIcon(const QString &icon)
|
||||
{
|
||||
QDomNode metaDataNode = metaData(Strings::metaDataFreedesktopOwner(), true);
|
||||
QDomElement iconElement = cd_or_create(metaDataNode, QStringLiteral("bookmark:icon")).toElement();
|
||||
iconElement.setAttribute(QStringLiteral("name"), icon);
|
||||
|
||||
// migration code
|
||||
if (!element.attribute(QStringLiteral("icon")).isEmpty()) {
|
||||
element.removeAttribute(QStringLiteral("icon"));
|
||||
}
|
||||
}
|
||||
|
||||
QString KBookmark::description() const
|
||||
{
|
||||
if (isSeparator()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString description = element.namedItem(QStringLiteral("desc")).toElement().text();
|
||||
description.replace(QLatin1Char('\n'), QLatin1Char(' ')); // #140673
|
||||
return description;
|
||||
}
|
||||
|
||||
void KBookmark::setDescription(const QString &description)
|
||||
{
|
||||
QDomNode descNode = element.namedItem(QStringLiteral("desc"));
|
||||
if (descNode.isNull()) {
|
||||
descNode = element.ownerDocument().createElement(QStringLiteral("desc"));
|
||||
element.appendChild(descNode);
|
||||
}
|
||||
|
||||
if (descNode.firstChild().isNull()) {
|
||||
QDomText domtext = descNode.ownerDocument().createTextNode(QString());
|
||||
descNode.appendChild(domtext);
|
||||
}
|
||||
|
||||
QDomText domtext = descNode.firstChild().toText();
|
||||
domtext.setData(description);
|
||||
}
|
||||
|
||||
QString KBookmark::mimeType() const
|
||||
{
|
||||
QDomNode metaDataNode = metaData(Strings::metaDataMimeOwner(), false);
|
||||
QDomElement mimeTypeElement = cd(metaDataNode, QStringLiteral("mime:mime-type"), false).toElement();
|
||||
return mimeTypeElement.attribute(QStringLiteral("type"));
|
||||
}
|
||||
|
||||
void KBookmark::setMimeType(const QString &mimeType)
|
||||
{
|
||||
QDomNode metaDataNode = metaData(Strings::metaDataMimeOwner(), true);
|
||||
QDomElement iconElement = cd_or_create(metaDataNode, QStringLiteral("mime:mime-type")).toElement();
|
||||
iconElement.setAttribute(QStringLiteral("type"), mimeType);
|
||||
}
|
||||
|
||||
bool KBookmark::showInToolbar() const
|
||||
{
|
||||
if (element.hasAttribute(QStringLiteral("showintoolbar"))) {
|
||||
bool show = element.attribute(QStringLiteral("showintoolbar")) == QLatin1String("yes");
|
||||
const_cast<QDomElement *>(&element)->removeAttribute(QStringLiteral("showintoolbar"));
|
||||
const_cast<KBookmark *>(this)->setShowInToolbar(show);
|
||||
}
|
||||
return metaDataItem(QStringLiteral("showintoolbar")) == QLatin1String("yes");
|
||||
}
|
||||
|
||||
void KBookmark::setShowInToolbar(bool show)
|
||||
{
|
||||
setMetaDataItem(QStringLiteral("showintoolbar"), show ? QStringLiteral("yes") : QStringLiteral("no"));
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmark::parentGroup() const
|
||||
{
|
||||
return KBookmarkGroup(element.parentNode().toElement());
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmark::toGroup() const
|
||||
{
|
||||
Q_ASSERT(isGroup());
|
||||
return KBookmarkGroup(element);
|
||||
}
|
||||
|
||||
QString KBookmark::address() const
|
||||
{
|
||||
if (element.tagName() == QLatin1String("xbel")) {
|
||||
return QLatin1String(""); // not QString() !
|
||||
} else {
|
||||
// Use keditbookmarks's DEBUG_ADDRESSES flag to debug this code :)
|
||||
if (element.parentNode().isNull()) {
|
||||
Q_ASSERT(false);
|
||||
return QStringLiteral("ERROR"); // Avoid an infinite loop
|
||||
}
|
||||
KBookmarkGroup group = parentGroup();
|
||||
QString parentAddress = group.address();
|
||||
int pos = group.indexOf(*this);
|
||||
Q_ASSERT(pos != -1);
|
||||
return parentAddress + QLatin1Char('/') + QString::number(pos);
|
||||
}
|
||||
}
|
||||
|
||||
int KBookmark::positionInParent() const
|
||||
{
|
||||
return parentGroup().indexOf(*this);
|
||||
}
|
||||
|
||||
QDomElement KBookmark::internalElement() const
|
||||
{
|
||||
return element;
|
||||
}
|
||||
|
||||
KBookmark KBookmark::standaloneBookmark(const QString &text, const QUrl &url, const QString &icon)
|
||||
{
|
||||
QDomDocument doc(QStringLiteral("xbel"));
|
||||
QDomElement elem = doc.createElement(QStringLiteral("xbel"));
|
||||
doc.appendChild(elem);
|
||||
KBookmarkGroup grp(elem);
|
||||
grp.addBookmark(text, url, icon);
|
||||
return grp.first();
|
||||
}
|
||||
|
||||
QString KBookmark::commonParent(const QString &first, const QString &second)
|
||||
{
|
||||
QString A = first;
|
||||
QString B = second;
|
||||
QString error(QStringLiteral("ERROR"));
|
||||
if (A == error || B == error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
A += QLatin1Char('/');
|
||||
B += QLatin1Char('/');
|
||||
|
||||
int lastCommonSlash = 0;
|
||||
int lastPos = A.length() < B.length() ? A.length() : B.length();
|
||||
for (int i = 0; i < lastPos; ++i) {
|
||||
if (A[i] != B[i]) {
|
||||
return A.left(lastCommonSlash);
|
||||
}
|
||||
if (A[i] == QLatin1Char('/')) {
|
||||
lastCommonSlash = i;
|
||||
}
|
||||
}
|
||||
return A.left(lastCommonSlash);
|
||||
}
|
||||
|
||||
void KBookmark::updateAccessMetadata()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmark::updateAccessMetadata " << address() << " " << url();
|
||||
|
||||
const uint timet = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
|
||||
setMetaDataItem(QStringLiteral("time_added"), QString::number(timet), DontOverwriteMetaData);
|
||||
setMetaDataItem(QStringLiteral("time_visited"), QString::number(timet));
|
||||
|
||||
QString countStr = metaDataItem(QStringLiteral("visit_count")); // TODO use spec'ed name
|
||||
bool ok;
|
||||
int currentCount = countStr.toInt(&ok);
|
||||
if (!ok) {
|
||||
currentCount = 0;
|
||||
}
|
||||
currentCount++;
|
||||
setMetaDataItem(QStringLiteral("visit_count"), QString::number(currentCount));
|
||||
|
||||
// TODO - time_modified
|
||||
}
|
||||
|
||||
QString KBookmark::parentAddress(const QString &address)
|
||||
{
|
||||
return address.left(address.lastIndexOf(QLatin1Char('/')));
|
||||
}
|
||||
|
||||
uint KBookmark::positionInParent(const QString &address)
|
||||
{
|
||||
return QStringView(address).mid(address.lastIndexOf(QLatin1Char('/')) + 1).toInt();
|
||||
}
|
||||
|
||||
QString KBookmark::previousAddress(const QString &address)
|
||||
{
|
||||
uint pp = positionInParent(address);
|
||||
return pp > 0 ? parentAddress(address) + QLatin1Char('/') + QString::number(pp - 1) : QString();
|
||||
}
|
||||
|
||||
QString KBookmark::nextAddress(const QString &address)
|
||||
{
|
||||
return parentAddress(address) + QLatin1Char('/') + QString::number(positionInParent(address) + 1);
|
||||
}
|
||||
|
||||
QDomNode KBookmark::metaData(const QString &owner, bool create) const
|
||||
{
|
||||
QDomNode infoNode = cd(internalElement(), QStringLiteral("info"), create);
|
||||
if (infoNode.isNull()) {
|
||||
return QDomNode();
|
||||
}
|
||||
return findMetadata(owner, infoNode, create);
|
||||
}
|
||||
|
||||
QString KBookmark::metaDataItem(const QString &key) const
|
||||
{
|
||||
QDomNode metaDataNode = metaData(Strings::metaDataKDEOwner(), false);
|
||||
for (QDomElement e = metaDataNode.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
|
||||
if (e.tagName() == key) {
|
||||
return e.text();
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void KBookmark::setMetaDataItem(const QString &key, const QString &value, MetaDataOverwriteMode mode)
|
||||
{
|
||||
QDomNode metaDataNode = metaData(Strings::metaDataKDEOwner(), true);
|
||||
QDomNode item = cd_or_create(metaDataNode, key);
|
||||
QDomText text = get_or_create_text(item);
|
||||
if (mode == DontOverwriteMetaData && !text.data().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
text.setData(value);
|
||||
}
|
||||
|
||||
bool KBookmark::operator==(const KBookmark &rhs) const
|
||||
{
|
||||
return element == rhs.element;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
KBookmarkGroupTraverser::~KBookmarkGroupTraverser()
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkGroupTraverser::traverse(const KBookmarkGroup &root)
|
||||
{
|
||||
QStack<KBookmarkGroup> stack;
|
||||
stack.push(root);
|
||||
KBookmark bk = root.first();
|
||||
for (;;) {
|
||||
if (bk.isNull()) {
|
||||
if (stack.count() == 1) { // only root is on the stack
|
||||
return;
|
||||
}
|
||||
if (!stack.isEmpty()) {
|
||||
visitLeave(stack.top());
|
||||
bk = stack.pop();
|
||||
}
|
||||
bk = stack.top().next(bk);
|
||||
} else if (bk.isGroup()) {
|
||||
KBookmarkGroup gp = bk.toGroup();
|
||||
visitEnter(gp);
|
||||
bk = gp.first();
|
||||
stack.push(gp);
|
||||
} else {
|
||||
visit(bk);
|
||||
bk = stack.top().next(bk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkGroupTraverser::visit(const KBookmark &)
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkGroupTraverser::visitEnter(const KBookmarkGroup &)
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkGroupTraverser::visitLeave(const KBookmarkGroup &)
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmark::populateMimeData(QMimeData *mimeData) const
|
||||
{
|
||||
KBookmark::List bookmarkList;
|
||||
bookmarkList.append(*this);
|
||||
bookmarkList.populateMimeData(mimeData);
|
||||
}
|
||||
|
||||
KBookmark::List::List()
|
||||
: QList<KBookmark>()
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmark::List::populateMimeData(QMimeData *mimeData) const
|
||||
{
|
||||
QList<QUrl> urls;
|
||||
|
||||
QDomDocument doc(QStringLiteral("xbel"));
|
||||
QDomElement elem = doc.createElement(QStringLiteral("xbel"));
|
||||
doc.appendChild(elem);
|
||||
|
||||
for (const_iterator it = begin(), end = this->end(); it != end; ++it) {
|
||||
urls.append((*it).url());
|
||||
elem.appendChild((*it).internalElement().cloneNode(true /* deep */));
|
||||
}
|
||||
|
||||
// This sets text/uri-list and text/plain into the mimedata
|
||||
mimeData->setUrls(urls);
|
||||
|
||||
mimeData->setData(Strings::xbelMimeType(), doc.toByteArray());
|
||||
}
|
||||
|
||||
bool KBookmark::List::canDecode(const QMimeData *mimeData)
|
||||
{
|
||||
return mimeData->hasFormat(Strings::xbelMimeType()) || mimeData->hasUrls();
|
||||
}
|
||||
|
||||
QStringList KBookmark::List::mimeDataTypes()
|
||||
{
|
||||
return QStringList() << Strings::xbelMimeType() << KUrlMimeData::mimeDataTypes();
|
||||
}
|
||||
|
||||
KBookmark::List KBookmark::List::fromMimeData(const QMimeData *mimeData, QDomDocument &doc)
|
||||
{
|
||||
KBookmark::List bookmarks;
|
||||
const QByteArray payload = mimeData->data(Strings::xbelMimeType());
|
||||
if (!payload.isEmpty()) {
|
||||
doc.setContent(payload);
|
||||
QDomElement elem = doc.documentElement();
|
||||
const QDomNodeList children = elem.childNodes();
|
||||
bookmarks.reserve(children.count());
|
||||
for (int childno = 0; childno < children.count(); childno++) {
|
||||
bookmarks.append(KBookmark(children.item(childno).toElement()));
|
||||
}
|
||||
return bookmarks;
|
||||
}
|
||||
const QList<QUrl> urls = KUrlMimeData::urlsFromMimeData(mimeData);
|
||||
bookmarks.reserve(urls.size());
|
||||
for (int i = 0; i < urls.size(); ++i) {
|
||||
const QUrl url = urls.at(i);
|
||||
bookmarks.append(KBookmark::standaloneBookmark(url.toDisplayString(), url, QString() /*TODO icon*/));
|
||||
}
|
||||
return bookmarks;
|
||||
}
|
||||
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000-2005 David Faure <faure@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
#ifndef __kbookmark_h
|
||||
#define __kbookmark_h
|
||||
|
||||
#include <kbookmarks_export.h>
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
class QMimeData;
|
||||
class KBookmarkGroup;
|
||||
|
||||
/**
|
||||
* @class KBookmark kbookmark.h KBookmark
|
||||
*
|
||||
* A class representing a bookmark.
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmark
|
||||
{
|
||||
friend class KBookmarkGroup;
|
||||
|
||||
public:
|
||||
enum MetaDataOverwriteMode {
|
||||
OverwriteMetaData,
|
||||
DontOverwriteMetaData,
|
||||
};
|
||||
|
||||
/**
|
||||
* KBookmark::List is a QList that contains bookmarks with a few
|
||||
* convenience methods.
|
||||
* @see KBookmark
|
||||
* @see QList
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT List : public QList<KBookmark>
|
||||
{
|
||||
public:
|
||||
List();
|
||||
|
||||
/**
|
||||
* Adds this list of bookmark into the given QMimeData.
|
||||
*
|
||||
* @param mimeData the QMimeData instance used to drag or copy this bookmark
|
||||
*/
|
||||
void populateMimeData(QMimeData *mimeData) const;
|
||||
|
||||
/**
|
||||
* Return true if @p mimeData contains bookmarks
|
||||
*/
|
||||
static bool canDecode(const QMimeData *mimeData);
|
||||
|
||||
/**
|
||||
* Return the list of mimeTypes that can be decoded by fromMimeData
|
||||
*/
|
||||
static QStringList mimeDataTypes();
|
||||
|
||||
/**
|
||||
* Extract a list of bookmarks from the contents of @p mimeData.
|
||||
* Decoding will fail if @p mimeData does not contain any bookmarks.
|
||||
* @param mimeData the mime data to extract from; cannot be 0
|
||||
* @param parentDocument pass an empty QDomDocument here, it will be used as
|
||||
* container for the bookmarks. You just need to make sure it stays alive longer
|
||||
* (or just as long) as the returned bookmarks.
|
||||
* @return the list of bookmarks
|
||||
* @since 4.3.2
|
||||
*/
|
||||
static KBookmark::List fromMimeData(const QMimeData *mimeData, QDomDocument &parentDocument);
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a null bookmark, i.e. a bookmark for which isNull() returns true
|
||||
* If you want to create a new bookmark use eitehr KBookmarkGroup.addBookmark
|
||||
* or if you want an interactive dialog use KBookmarkDialog.
|
||||
*/
|
||||
KBookmark();
|
||||
|
||||
/**
|
||||
* Creates the KBookmark wrapper for @param elem
|
||||
* Mostly for internal usage.
|
||||
*/
|
||||
|
||||
explicit KBookmark(const QDomElement &elem);
|
||||
|
||||
/**
|
||||
* Creates a stand alone bookmark. This is fairly expensive since a new QDom Tree is build.
|
||||
*/
|
||||
static KBookmark standaloneBookmark(const QString &text, const QUrl &url, const QString &icon);
|
||||
|
||||
/**
|
||||
* Whether the bookmark is a group or a normal bookmark
|
||||
*/
|
||||
bool isGroup() const;
|
||||
|
||||
/**
|
||||
* Whether the bookmark is a separator
|
||||
*/
|
||||
bool isSeparator() const;
|
||||
|
||||
/**
|
||||
* @return true if this is a null bookmark. This will never
|
||||
* be the case for a real bookmark (in a menu), but it's used
|
||||
* for instance as the end condition for KBookmarkGroup::next()
|
||||
*/
|
||||
bool isNull() const;
|
||||
|
||||
/**
|
||||
* @return true if bookmark is contained by a QDomDocument,
|
||||
* if not it is most likely that it has become separated and
|
||||
* is thus invalid and/or has been deleted from the bookmarks.
|
||||
*/
|
||||
bool hasParent() const;
|
||||
|
||||
/**
|
||||
* Text shown for the bookmark
|
||||
* If bigger than 40, the text is shortened by
|
||||
* replacing middle characters with "..." (see KStringHandler::csqueeze)
|
||||
*/
|
||||
QString text() const;
|
||||
/**
|
||||
* Text shown for the bookmark, not truncated.
|
||||
* You should not use this - this is mainly for keditbookmarks.
|
||||
*/
|
||||
QString fullText() const;
|
||||
/**
|
||||
* Set the text shown for the bookmark.
|
||||
*
|
||||
* @param fullText the new bookmark title
|
||||
*/
|
||||
void setFullText(const QString &fullText);
|
||||
/**
|
||||
* URL contained by the bookmark
|
||||
*/
|
||||
QUrl url() const;
|
||||
/**
|
||||
* Set the URL of the bookmark
|
||||
*
|
||||
* @param url the new bookmark URL
|
||||
*/
|
||||
void setUrl(const QUrl &url);
|
||||
|
||||
/**
|
||||
* @return the pixmap file for this bookmark
|
||||
* (i.e. the name of the icon)
|
||||
*/
|
||||
QString icon() const;
|
||||
|
||||
/**
|
||||
* Set the icon name of the bookmark
|
||||
*
|
||||
* @param icon the new icon name for this bookmark
|
||||
*/
|
||||
void setIcon(const QString &icon);
|
||||
|
||||
/**
|
||||
* @return Description of the bookmark
|
||||
* @since 4.4
|
||||
*/
|
||||
QString description() const;
|
||||
|
||||
/**
|
||||
* Set the description of the bookmark
|
||||
*
|
||||
* @param description
|
||||
* @since 4.4
|
||||
*/
|
||||
void setDescription(const QString &description);
|
||||
|
||||
/**
|
||||
* @return Mime-Type of this item
|
||||
* @since 4.1
|
||||
*/
|
||||
QString mimeType() const;
|
||||
|
||||
/**
|
||||
* Set the Mime-Type of this item
|
||||
*
|
||||
* @param Mime-Type
|
||||
* @since 4.1
|
||||
*/
|
||||
void setMimeType(const QString &mimeType);
|
||||
|
||||
/**
|
||||
* @return if the bookmark should be shown in the toolbar
|
||||
* (used by the filtered toolbar)
|
||||
*
|
||||
*/
|
||||
bool showInToolbar() const;
|
||||
|
||||
/**
|
||||
* Set whether this bookmark is show in a filterd toolbar
|
||||
*/
|
||||
void setShowInToolbar(bool show);
|
||||
|
||||
/**
|
||||
* @return the group containing this bookmark
|
||||
*/
|
||||
KBookmarkGroup parentGroup() const;
|
||||
|
||||
/**
|
||||
* Convert this to a group - do this only if
|
||||
* isGroup() returns true.
|
||||
*/
|
||||
KBookmarkGroup toGroup() const;
|
||||
|
||||
/**
|
||||
* Return the "address" of this bookmark in the whole tree.
|
||||
* This is used when telling other processes about a change
|
||||
* in a given bookmark. The encoding of the address is "/4/2", for
|
||||
* instance, to designate the 2nd child inside the 4th child of the
|
||||
* root bookmark.
|
||||
*/
|
||||
QString address() const;
|
||||
|
||||
/**
|
||||
* Return the position in the parent, i.e. the last number in the address
|
||||
*/
|
||||
int positionInParent() const;
|
||||
|
||||
/**
|
||||
* @internal for KEditBookmarks
|
||||
*/
|
||||
QDomElement internalElement() const;
|
||||
|
||||
/**
|
||||
* Updates the bookmarks access metadata
|
||||
* Call when a user accesses the bookmark
|
||||
*/
|
||||
void updateAccessMetadata();
|
||||
|
||||
// Utility functions (internal)
|
||||
|
||||
/**
|
||||
* @return address of parent
|
||||
*/
|
||||
static QString parentAddress(const QString &address);
|
||||
|
||||
/**
|
||||
* @return position in parent (e.g. /4/5/2 -> 2)
|
||||
*/
|
||||
static uint positionInParent(const QString &address);
|
||||
|
||||
/**
|
||||
* @return address of previous sibling (e.g. /4/5/2 -> /4/5/1)
|
||||
* Returns QString() for a first child
|
||||
*/
|
||||
static QString previousAddress(const QString &address);
|
||||
|
||||
/**
|
||||
* @return address of next sibling (e.g. /4/5/2 -> /4/5/3)
|
||||
* This doesn't check whether it actually exists
|
||||
*/
|
||||
static QString nextAddress(const QString &address);
|
||||
|
||||
/**
|
||||
* @return the common parent of both addresses which
|
||||
* has the greatest depth
|
||||
*/
|
||||
static QString commonParent(const QString &A, const QString &B);
|
||||
|
||||
/**
|
||||
* @return the metadata container node for a certain metadata owner
|
||||
* @since 4.1
|
||||
*/
|
||||
QDomNode metaData(const QString &owner, bool create) const;
|
||||
|
||||
/**
|
||||
* Get the value of a specific metadata item (owner = "http://www.kde.org").
|
||||
* @param key Name of the metadata item
|
||||
* @return Value of the metadata item. QString() is returned in case
|
||||
* the specified key does not exist.
|
||||
*/
|
||||
QString metaDataItem(const QString &key) const;
|
||||
|
||||
/**
|
||||
* Change the value of a specific metadata item, or create the given item
|
||||
* if it doesn't exist already (owner = "http://www.kde.org").
|
||||
* @param key Name of the metadata item to change
|
||||
* @param value Value to use for the specified metadata item
|
||||
* @param mode Whether to overwrite the item's value if it exists already or not.
|
||||
*/
|
||||
void setMetaDataItem(const QString &key, const QString &value, MetaDataOverwriteMode mode = OverwriteMetaData);
|
||||
|
||||
/**
|
||||
* Adds this bookmark into the given QMimeData.
|
||||
*
|
||||
* WARNING: do not call this method multiple times, use KBookmark::List::populateMimeData instead.
|
||||
*
|
||||
* @param mimeData the QMimeData instance used to drag or copy this bookmark
|
||||
*/
|
||||
void populateMimeData(QMimeData *mimeData) const;
|
||||
|
||||
/**
|
||||
* Comparison operator
|
||||
*/
|
||||
bool operator==(const KBookmark &rhs) const;
|
||||
|
||||
protected:
|
||||
QDomElement element;
|
||||
// Note: you can't add new member variables here.
|
||||
// The KBookmarks are created on the fly, as wrappers
|
||||
// around internal QDomElements. Any additional information
|
||||
// has to be implemented as an attribute of the QDomElement.
|
||||
};
|
||||
|
||||
/**
|
||||
* A group of bookmarks
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmarkGroup : public KBookmark
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create an invalid group. This is mostly for use in QList,
|
||||
* and other places where we need a null group.
|
||||
* Also used as a parent for a bookmark that doesn't have one
|
||||
* (e.g. Netscape bookmarks)
|
||||
*/
|
||||
KBookmarkGroup();
|
||||
|
||||
/**
|
||||
* Create a bookmark group as specified by the given element
|
||||
*/
|
||||
KBookmarkGroup(const QDomElement &elem);
|
||||
|
||||
/**
|
||||
* @return true if the bookmark folder is opened in the bookmark editor
|
||||
*/
|
||||
bool isOpen() const;
|
||||
|
||||
/**
|
||||
* Return the first child bookmark of this group
|
||||
*/
|
||||
KBookmark first() const;
|
||||
/**
|
||||
* Return the previous sibling of a child bookmark of this group
|
||||
* @param current has to be one of our child bookmarks.
|
||||
*/
|
||||
KBookmark previous(const KBookmark ¤t) const;
|
||||
/**
|
||||
* Return the next sibling of a child bookmark of this group
|
||||
* @param current has to be one of our child bookmarks.
|
||||
*/
|
||||
KBookmark next(const KBookmark ¤t) const;
|
||||
|
||||
/**
|
||||
* Return the index of a child bookmark, -1 if not found
|
||||
*/
|
||||
int indexOf(const KBookmark &child) const;
|
||||
|
||||
/**
|
||||
* Create a new bookmark folder, as the last child of this group
|
||||
* @param text for the folder.
|
||||
* If you want an dialog use KBookmarkDialog
|
||||
*/
|
||||
KBookmarkGroup createNewFolder(const QString &text);
|
||||
/**
|
||||
* Create a new bookmark separator
|
||||
* Don't forget to use KBookmarkManager::self()->emitChanged( parentBookmark );
|
||||
*/
|
||||
KBookmark createNewSeparator();
|
||||
|
||||
/**
|
||||
* Create a new bookmark, as the last child of this group
|
||||
* Don't forget to use KBookmarkManager::self()->emitChanged( parentBookmark );
|
||||
* @param bm the bookmark to add
|
||||
*/
|
||||
KBookmark addBookmark(const KBookmark &bm);
|
||||
|
||||
/**
|
||||
* Create a new bookmark, as the last child of this group
|
||||
* Don't forget to use KBookmarkManager::self()->emitChanged( parentBookmark );
|
||||
* @param text for the bookmark
|
||||
* @param url the URL that the bookmark points to.
|
||||
* It will be stored in its QUrl::FullyEncoded string format.
|
||||
* @param icon the name of the icon to associate with the bookmark. A suitable default
|
||||
* will be determined from the URL if not specified.
|
||||
*/
|
||||
KBookmark addBookmark(const QString &text, const QUrl &url, const QString &icon);
|
||||
|
||||
/**
|
||||
* Moves @p bookmark after @p after (which should be a child of ours).
|
||||
* If after is null, @p bookmark is moved as the first child.
|
||||
* Don't forget to use KBookmarkManager::self()->emitChanged( parentBookmark );
|
||||
*/
|
||||
bool moveBookmark(const KBookmark &bookmark, const KBookmark &after);
|
||||
|
||||
/**
|
||||
* Delete a bookmark - it has to be one of our children !
|
||||
* Don't forget to use KBookmarkManager::self()->emitChanged( parentBookmark );
|
||||
*/
|
||||
void deleteBookmark(const KBookmark &bk);
|
||||
|
||||
/**
|
||||
* @return true if this is the toolbar group
|
||||
*/
|
||||
bool isToolbarGroup() const;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
QDomElement findToolbar() const;
|
||||
|
||||
/**
|
||||
* @return the list of urls of bookmarks at top level of the group
|
||||
*/
|
||||
QList<QUrl> groupUrlList() const;
|
||||
|
||||
protected:
|
||||
QDomElement nextKnownTag(const QDomElement &start, bool goNext) const;
|
||||
|
||||
private:
|
||||
// Note: you can't add other member variables here, except for caching info.
|
||||
// The KBookmarks are created on the fly, as wrappers
|
||||
// around internal QDomElements. Any additional information
|
||||
// has to be implemented as an attribute of the QDomElement.
|
||||
};
|
||||
|
||||
/**
|
||||
* A class to traverse bookarm groups
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmarkGroupTraverser
|
||||
{
|
||||
protected:
|
||||
virtual ~KBookmarkGroupTraverser();
|
||||
void traverse(const KBookmarkGroup &);
|
||||
virtual void visit(const KBookmark &);
|
||||
virtual void visitEnter(const KBookmarkGroup &);
|
||||
virtual void visitLeave(const KBookmarkGroup &);
|
||||
};
|
||||
|
||||
#define KIO_KBOOKMARK_METATYPE_DEFINED 1
|
||||
Q_DECLARE_METATYPE(KBookmark)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kbookmarkaction.h"
|
||||
#include "kbookmarkowner.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QGuiApplication>
|
||||
|
||||
KBookmarkAction::KBookmarkAction(const KBookmark &bk, KBookmarkOwner *owner, QObject *parent)
|
||||
: QAction(bk.text().replace(QLatin1Char('&'), QLatin1String("&&")), parent)
|
||||
, KBookmarkActionInterface(bk)
|
||||
, m_pOwner(owner)
|
||||
{
|
||||
setIcon(QIcon::fromTheme(bookmark().icon()));
|
||||
setIconText(text());
|
||||
setToolTip(bookmark().url().toDisplayString(QUrl::PreferLocalFile));
|
||||
setStatusTip(toolTip());
|
||||
setWhatsThis(toolTip());
|
||||
const QString description = bk.description();
|
||||
if (!description.isEmpty()) {
|
||||
setToolTip(description);
|
||||
}
|
||||
connect(this, &QAction::triggered, this, &KBookmarkAction::slotTriggered);
|
||||
}
|
||||
|
||||
KBookmarkAction::~KBookmarkAction()
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkAction::slotTriggered()
|
||||
{
|
||||
slotSelected(QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
|
||||
}
|
||||
|
||||
void KBookmarkAction::slotSelected(Qt::MouseButtons mb, Qt::KeyboardModifiers km)
|
||||
{
|
||||
if (!m_pOwner) {
|
||||
QDesktopServices::openUrl(bookmark().url());
|
||||
} else {
|
||||
m_pOwner->openBookmark(bookmark(), mb, km);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_kbookmarkaction.cpp"
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KBOOKMARKACTION_H
|
||||
#define KBOOKMARKACTION_H
|
||||
|
||||
#include "kbookmarkactioninterface.h"
|
||||
|
||||
#include <QAction>
|
||||
|
||||
class KBookmark;
|
||||
class KBookmarkOwner;
|
||||
|
||||
/**
|
||||
* @class KBookmarkAction kbookmarkaction.h KBookmarkAction
|
||||
*
|
||||
* This class is a QAction for bookmarks.
|
||||
* It provides a nice constructor.
|
||||
* And on triggered uses the owner to open the bookmark.
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmarkAction : public QAction, public KBookmarkActionInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KBookmarkAction(const KBookmark &bk, KBookmarkOwner *owner, QObject *parent);
|
||||
~KBookmarkAction() override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotSelected(Qt::MouseButtons mb, Qt::KeyboardModifiers km);
|
||||
|
||||
private Q_SLOTS:
|
||||
KBOOKMARKS_NO_EXPORT void slotTriggered();
|
||||
|
||||
private:
|
||||
KBookmarkOwner *const m_pOwner;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kbookmarkactioninterface.h"
|
||||
|
||||
KBookmarkActionInterface::KBookmarkActionInterface(const KBookmark &bk)
|
||||
: bm(bk)
|
||||
{
|
||||
}
|
||||
|
||||
KBookmarkActionInterface::~KBookmarkActionInterface()
|
||||
{
|
||||
}
|
||||
|
||||
const KBookmark KBookmarkActionInterface::bookmark() const
|
||||
{
|
||||
return bm;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KBOOKMARKACTIONINTERFACE_H
|
||||
#define KBOOKMARKACTIONINTERFACE_H
|
||||
|
||||
#include "kbookmark.h"
|
||||
|
||||
/**
|
||||
* @class KBookmarkActionInterface kbookmarkactioninterface.h KBookmarkActionInterface
|
||||
*
|
||||
* The interface to implement by actions and menus which represent a bookimark
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmarkActionInterface
|
||||
{
|
||||
public:
|
||||
explicit KBookmarkActionInterface(const KBookmark &bk);
|
||||
virtual ~KBookmarkActionInterface();
|
||||
const KBookmark bookmark() const;
|
||||
|
||||
private:
|
||||
const KBookmark bm;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,391 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
|
||||
SPDX-FileCopyrightText: 2003 Alexander Kellett <lypanov@kde.org>
|
||||
SPDX-FileCopyrightText: 2008 Norbert Frese <nf2@scheinwelt.at>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "kbookmarkmanager.h"
|
||||
#include "kbookmarks_debug.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QRegularExpression>
|
||||
#include <QSaveFile>
|
||||
#include <QStandardPaths>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <KBackup>
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KDirWatch>
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace Strings
|
||||
{
|
||||
QString piData()
|
||||
{
|
||||
return QStringLiteral("version=\"1.0\" encoding=\"UTF-8\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KBookmarkMap : private KBookmarkGroupTraverser
|
||||
{
|
||||
public:
|
||||
KBookmarkMap()
|
||||
: m_mapNeedsUpdate(true)
|
||||
{
|
||||
}
|
||||
void setNeedsUpdate()
|
||||
{
|
||||
m_mapNeedsUpdate = true;
|
||||
}
|
||||
void update(KBookmarkManager *);
|
||||
QList<KBookmark> find(const QString &url) const
|
||||
{
|
||||
return m_bk_map.value(url);
|
||||
}
|
||||
|
||||
private:
|
||||
void visit(const KBookmark &) override;
|
||||
void visitEnter(const KBookmarkGroup &) override
|
||||
{
|
||||
;
|
||||
}
|
||||
void visitLeave(const KBookmarkGroup &) override
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef QList<KBookmark> KBookmarkList;
|
||||
QMap<QString, KBookmarkList> m_bk_map;
|
||||
bool m_mapNeedsUpdate;
|
||||
};
|
||||
|
||||
void KBookmarkMap::update(KBookmarkManager *manager)
|
||||
{
|
||||
if (m_mapNeedsUpdate) {
|
||||
m_mapNeedsUpdate = false;
|
||||
|
||||
m_bk_map.clear();
|
||||
KBookmarkGroup root = manager->root();
|
||||
traverse(root);
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMap::visit(const KBookmark &bk)
|
||||
{
|
||||
if (!bk.isSeparator()) {
|
||||
// add bookmark to url map
|
||||
m_bk_map[bk.internalElement().attribute(QStringLiteral("href"))].append(bk);
|
||||
}
|
||||
}
|
||||
|
||||
// #########################
|
||||
// KBookmarkManagerPrivate
|
||||
class KBookmarkManagerPrivate
|
||||
{
|
||||
public:
|
||||
KBookmarkManagerPrivate(bool bDocIsloaded)
|
||||
: m_doc(QStringLiteral("xbel"))
|
||||
, m_docIsLoaded(bDocIsloaded)
|
||||
, m_dirWatch(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
mutable QDomDocument m_doc;
|
||||
mutable QDomDocument m_toolbarDoc;
|
||||
QString m_bookmarksFile;
|
||||
mutable bool m_docIsLoaded;
|
||||
|
||||
KDirWatch *m_dirWatch; // for monitoring changes on bookmark files
|
||||
|
||||
KBookmarkMap m_map;
|
||||
};
|
||||
|
||||
// ################
|
||||
// KBookmarkManager
|
||||
|
||||
static QDomElement createXbelTopLevelElement(QDomDocument &doc)
|
||||
{
|
||||
QDomElement topLevel = doc.createElement(QStringLiteral("xbel"));
|
||||
topLevel.setAttribute(QStringLiteral("xmlns:mime"), QStringLiteral("http://www.freedesktop.org/standards/shared-mime-info"));
|
||||
topLevel.setAttribute(QStringLiteral("xmlns:bookmark"), QStringLiteral("http://www.freedesktop.org/standards/desktop-bookmarks"));
|
||||
topLevel.setAttribute(QStringLiteral("xmlns:kdepriv"), QStringLiteral("http://www.kde.org/kdepriv"));
|
||||
doc.appendChild(topLevel);
|
||||
doc.insertBefore(doc.createProcessingInstruction(QStringLiteral("xml"), Strings::piData()), topLevel);
|
||||
return topLevel;
|
||||
}
|
||||
|
||||
KBookmarkManager::KBookmarkManager(const QString &bookmarksFile, QObject *parent)
|
||||
: QObject(parent)
|
||||
, d(new KBookmarkManagerPrivate(false))
|
||||
{
|
||||
Q_ASSERT(!bookmarksFile.isEmpty());
|
||||
d->m_bookmarksFile = bookmarksFile;
|
||||
|
||||
if (!QFile::exists(d->m_bookmarksFile)) {
|
||||
createXbelTopLevelElement(d->m_doc);
|
||||
} else {
|
||||
parse();
|
||||
}
|
||||
d->m_docIsLoaded = true;
|
||||
|
||||
// start KDirWatch
|
||||
KDirWatch::self()->addFile(d->m_bookmarksFile);
|
||||
QObject::connect(KDirWatch::self(), &KDirWatch::dirty, this, &KBookmarkManager::slotFileChanged);
|
||||
QObject::connect(KDirWatch::self(), &KDirWatch::created, this, &KBookmarkManager::slotFileChanged);
|
||||
QObject::connect(KDirWatch::self(), &KDirWatch::deleted, this, &KBookmarkManager::slotFileChanged);
|
||||
|
||||
// qCDebug(KBOOKMARKS_LOG) << "starting KDirWatch for" << d->m_bookmarksFile;
|
||||
}
|
||||
|
||||
void KBookmarkManager::slotFileChanged(const QString &path)
|
||||
{
|
||||
if (path == d->m_bookmarksFile) {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "file changed (KDirWatch) " << path ;
|
||||
// Reparse
|
||||
parse();
|
||||
// Tell our GUI
|
||||
// (emit where group is "" to directly mark the root menu as dirty)
|
||||
Q_EMIT changed(QLatin1String(""));
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkManager::~KBookmarkManager()
|
||||
{
|
||||
}
|
||||
|
||||
QDomDocument KBookmarkManager::internalDocument() const
|
||||
{
|
||||
if (!d->m_docIsLoaded) {
|
||||
parse();
|
||||
d->m_toolbarDoc.clear();
|
||||
}
|
||||
return d->m_doc;
|
||||
}
|
||||
|
||||
void KBookmarkManager::parse() const
|
||||
{
|
||||
d->m_docIsLoaded = true;
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::parse " << d->m_bookmarksFile;
|
||||
QFile file(d->m_bookmarksFile);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCWarning(KBOOKMARKS_LOG) << "Can't open" << d->m_bookmarksFile;
|
||||
d->m_doc = QDomDocument(QStringLiteral("xbel"));
|
||||
createXbelTopLevelElement(d->m_doc);
|
||||
return;
|
||||
}
|
||||
d->m_doc = QDomDocument(QStringLiteral("xbel"));
|
||||
d->m_doc.setContent(&file);
|
||||
|
||||
if (d->m_doc.documentElement().isNull()) {
|
||||
qCWarning(KBOOKMARKS_LOG) << "KBookmarkManager::parse : main tag is missing, creating default " << d->m_bookmarksFile;
|
||||
QDomElement element = d->m_doc.createElement(QStringLiteral("xbel"));
|
||||
d->m_doc.appendChild(element);
|
||||
}
|
||||
|
||||
QDomElement docElem = d->m_doc.documentElement();
|
||||
|
||||
QString mainTag = docElem.tagName();
|
||||
if (mainTag != QLatin1String("xbel")) {
|
||||
qCWarning(KBOOKMARKS_LOG) << "KBookmarkManager::parse : unknown main tag " << mainTag;
|
||||
}
|
||||
|
||||
QDomNode n = d->m_doc.documentElement().previousSibling();
|
||||
if (n.isProcessingInstruction()) {
|
||||
QDomProcessingInstruction pi = n.toProcessingInstruction();
|
||||
pi.parentNode().removeChild(pi);
|
||||
}
|
||||
|
||||
QDomProcessingInstruction pi;
|
||||
pi = d->m_doc.createProcessingInstruction(QStringLiteral("xml"), Strings::piData());
|
||||
d->m_doc.insertBefore(pi, docElem);
|
||||
|
||||
file.close();
|
||||
|
||||
d->m_map.setNeedsUpdate();
|
||||
}
|
||||
|
||||
bool KBookmarkManager::save(bool toolbarCache) const
|
||||
{
|
||||
return saveAs(d->m_bookmarksFile, toolbarCache);
|
||||
}
|
||||
|
||||
bool KBookmarkManager::saveAs(const QString &filename, bool toolbarCache) const
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::save " << filename;
|
||||
|
||||
// Save the bookmark toolbar folder for quick loading
|
||||
// but only when it will actually make things quicker
|
||||
const QString cacheFilename = filename + QLatin1String(".tbcache");
|
||||
if (toolbarCache && !root().isToolbarGroup()) {
|
||||
QSaveFile cacheFile(cacheFilename);
|
||||
if (cacheFile.open(QIODevice::WriteOnly)) {
|
||||
QString str;
|
||||
QTextStream stream(&str, QIODevice::WriteOnly);
|
||||
stream << root().findToolbar();
|
||||
const QByteArray cstr = str.toUtf8();
|
||||
cacheFile.write(cstr.data(), cstr.length());
|
||||
cacheFile.commit();
|
||||
}
|
||||
} else { // remove any (now) stale cache
|
||||
QFile::remove(cacheFilename);
|
||||
}
|
||||
|
||||
// Create parent dirs
|
||||
QFileInfo info(filename);
|
||||
QDir().mkpath(info.absolutePath());
|
||||
|
||||
if (filename == d->m_bookmarksFile) {
|
||||
KDirWatch::self()->removeFile(d->m_bookmarksFile);
|
||||
}
|
||||
|
||||
QSaveFile file(filename);
|
||||
bool success = false;
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
KBackup::simpleBackupFile(file.fileName(), QString(), QStringLiteral(".bak"));
|
||||
QTextStream stream(&file);
|
||||
// In Qt6 it's UTF-8 by default
|
||||
stream << internalDocument().toString();
|
||||
stream.flush();
|
||||
success = file.commit();
|
||||
}
|
||||
|
||||
if (filename == d->m_bookmarksFile) {
|
||||
KDirWatch::self()->addFile(d->m_bookmarksFile);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
QString err = tr("Unable to save bookmarks in %1. Reported error was: %2. "
|
||||
"This error message will only be shown once. The cause "
|
||||
"of the error needs to be fixed as quickly as possible, "
|
||||
"which is most likely a full hard drive.")
|
||||
.arg(filename, file.errorString());
|
||||
qCCritical(KBOOKMARKS_LOG)
|
||||
<< QStringLiteral("Unable to save bookmarks in %1. File reported the following error-code: %2.").arg(filename).arg(file.error());
|
||||
Q_EMIT const_cast<KBookmarkManager *>(this)->error(err);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
QString KBookmarkManager::path() const
|
||||
{
|
||||
return d->m_bookmarksFile;
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkManager::root() const
|
||||
{
|
||||
return KBookmarkGroup(internalDocument().documentElement());
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkManager::toolbar()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::toolbar begin";
|
||||
// Only try to read from a toolbar cache if the full document isn't loaded
|
||||
if (!d->m_docIsLoaded) {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::toolbar trying cache";
|
||||
const QString cacheFilename = d->m_bookmarksFile + QLatin1String(".tbcache");
|
||||
QFileInfo bmInfo(d->m_bookmarksFile);
|
||||
QFileInfo cacheInfo(cacheFilename);
|
||||
if (d->m_toolbarDoc.isNull() && QFile::exists(cacheFilename) && bmInfo.lastModified() < cacheInfo.lastModified()) {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::toolbar reading file";
|
||||
QFile file(cacheFilename);
|
||||
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
d->m_toolbarDoc = QDomDocument(QStringLiteral("cache"));
|
||||
d->m_toolbarDoc.setContent(&file);
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::toolbar opened";
|
||||
}
|
||||
}
|
||||
if (!d->m_toolbarDoc.isNull()) {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::toolbar returning element";
|
||||
QDomElement elem = d->m_toolbarDoc.firstChild().toElement();
|
||||
return KBookmarkGroup(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to the normal way if there is no cache or if the bookmark file
|
||||
// is already loaded
|
||||
QDomElement elem = root().findToolbar();
|
||||
if (elem.isNull()) {
|
||||
// Root is the bookmark toolbar if none has been set.
|
||||
// Make it explicit to speed up invocations of findToolbar()
|
||||
root().internalElement().setAttribute(QStringLiteral("toolbar"), QStringLiteral("yes"));
|
||||
return root();
|
||||
} else {
|
||||
return KBookmarkGroup(elem);
|
||||
}
|
||||
}
|
||||
|
||||
KBookmark KBookmarkManager::findByAddress(const QString &address)
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::findByAddress " << address;
|
||||
KBookmark result = root();
|
||||
// The address is something like /5/10/2+
|
||||
static const QRegularExpression separator(QStringLiteral("[/+]"));
|
||||
const QStringList addresses = address.split(separator, Qt::SkipEmptyParts);
|
||||
// qCWarning(KBOOKMARKS_LOG) << addresses.join(",");
|
||||
for (QStringList::const_iterator it = addresses.begin(); it != addresses.end();) {
|
||||
bool append = ((*it) == QLatin1String("+"));
|
||||
uint number = (*it).toUInt();
|
||||
Q_ASSERT(result.isGroup());
|
||||
KBookmarkGroup group = result.toGroup();
|
||||
KBookmark bk = group.first();
|
||||
KBookmark lbk = bk; // last non-null bookmark
|
||||
for (uint i = 0; ((i < number) || append) && !bk.isNull(); ++i) {
|
||||
lbk = bk;
|
||||
bk = group.next(bk);
|
||||
// qCWarning(KBOOKMARKS_LOG) << i;
|
||||
}
|
||||
it++;
|
||||
// qCWarning(KBOOKMARKS_LOG) << "found section";
|
||||
result = bk;
|
||||
}
|
||||
if (result.isNull()) {
|
||||
qCWarning(KBOOKMARKS_LOG) << "KBookmarkManager::findByAddress: couldn't find item " << address;
|
||||
}
|
||||
// qCWarning(KBOOKMARKS_LOG) << "found " << result.address();
|
||||
return result;
|
||||
}
|
||||
|
||||
void KBookmarkManager::emitChanged()
|
||||
{
|
||||
emitChanged(root());
|
||||
}
|
||||
|
||||
void KBookmarkManager::emitChanged(const KBookmarkGroup &group)
|
||||
{
|
||||
(void)save(); // KDE5 TODO: emitChanged should return a bool? Maybe rename it to saveAndEmitChanged?
|
||||
|
||||
// Tell the other processes too
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkManager::emitChanged : broadcasting change " << group.address();
|
||||
|
||||
Q_EMIT changed(group.address());
|
||||
}
|
||||
|
||||
///////
|
||||
bool KBookmarkManager::updateAccessMetadata(const QString &url)
|
||||
{
|
||||
d->m_map.update(this);
|
||||
QList<KBookmark> list = d->m_map.find(url);
|
||||
if (list.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (QList<KBookmark>::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
(*it).updateAccessMetadata();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "moc_kbookmarkmanager.cpp"
|
||||
@@ -0,0 +1,175 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000, 2006 David Faure <faure@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
#ifndef __kbookmarkmanager_h
|
||||
#define __kbookmarkmanager_h
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class KBookmarkManagerPrivate;
|
||||
|
||||
#include "kbookmark.h"
|
||||
|
||||
class KBookmarkGroup;
|
||||
|
||||
/**
|
||||
* @class KBookmarkManager kbookmarkmanager.h KBookmarkManager
|
||||
*
|
||||
* This class implements the reading/writing of bookmarks in XML.
|
||||
* The bookmarks file is read and written using the XBEL standard
|
||||
* (http://pyxml.sourceforge.net/topics/xbel/)
|
||||
*
|
||||
* A sample file looks like this :
|
||||
* \code
|
||||
* <xbel>
|
||||
* <bookmark href="http://techbase.kde.org"><title>Developer Web Site</title></bookmark>
|
||||
* <folder folded="no">
|
||||
* <title>Title of this folder</title>
|
||||
* <bookmark icon="kde" href="http://www.kde.org"><title>KDE Web Site</title></bookmark>
|
||||
* <folder toolbar="yes">
|
||||
* <title>My own bookmarks</title>
|
||||
* <bookmark href="http://www.koffice.org"><title>KOffice Web Site</title></bookmark>
|
||||
* <separator/>
|
||||
* <bookmark href="http://www.kdevelop.org"><title>KDevelop Web Site</title></bookmark>
|
||||
* </folder>
|
||||
* </folder>
|
||||
* </xbel>
|
||||
* \endcode
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmarkManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a KBookmarkManager responsible for the given @p bookmarksFile.
|
||||
*
|
||||
* The manager watches the file for change detection.
|
||||
*
|
||||
* @param bookmarksFile full path to the bookmarks file,
|
||||
* Use ~/.kde/share/apps/konqueror/bookmarks.xml for the konqueror bookmarks
|
||||
*
|
||||
* @since 6.0
|
||||
*
|
||||
*/
|
||||
explicit KBookmarkManager(const QString &bookmarksFile, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~KBookmarkManager() override;
|
||||
|
||||
/**
|
||||
* Save the bookmarks to the given XML file on disk.
|
||||
* @param filename full path to the desired bookmarks file location
|
||||
* @param toolbarCache iff true save a cache of the toolbar folder, too
|
||||
* @return true if saving was successful
|
||||
*/
|
||||
// KF6 TODO: Use an enum and not a bool
|
||||
bool saveAs(const QString &filename, bool toolbarCache = true) const;
|
||||
|
||||
/**
|
||||
* Update access time stamps for a given url.
|
||||
* @param url the viewed url
|
||||
* @return true if any metadata was modified (bookmarks file is not saved automatically)
|
||||
*/
|
||||
bool updateAccessMetadata(const QString &url);
|
||||
|
||||
/**
|
||||
* This will return the path that this manager is using to read
|
||||
* the bookmarks.
|
||||
* @internal
|
||||
* @return the path containing the bookmarks
|
||||
*/
|
||||
QString path() const;
|
||||
|
||||
/**
|
||||
* This will return the root bookmark. It is used to iterate
|
||||
* through the bookmarks manually. It is mostly used internally.
|
||||
*
|
||||
* @return the root (top-level) bookmark
|
||||
*/
|
||||
KBookmarkGroup root() const;
|
||||
|
||||
/**
|
||||
* This returns the root of the toolbar menu.
|
||||
* In the XML, this is the group with the attribute toolbar=yes
|
||||
*
|
||||
* @return the toolbar group
|
||||
*/
|
||||
KBookmarkGroup toolbar();
|
||||
|
||||
/**
|
||||
* @return the bookmark designated by @p address
|
||||
* @param address the address belonging to the bookmark you're looking for
|
||||
* @param tolerate when true tries to find the most tolerable bookmark position
|
||||
* @see KBookmark::address
|
||||
*/
|
||||
KBookmark findByAddress(const QString &address);
|
||||
|
||||
/**
|
||||
* Saves the bookmark file and notifies everyone.
|
||||
*
|
||||
**/
|
||||
void emitChanged();
|
||||
|
||||
/**
|
||||
* Saves the bookmark file and notifies everyone.
|
||||
* @param group the parent of all changed bookmarks
|
||||
*/
|
||||
void emitChanged(const KBookmarkGroup &group);
|
||||
|
||||
/**
|
||||
* Save the bookmarks to an XML file on disk.
|
||||
* You should use emitChanged() instead of this function, it saves
|
||||
* and notifies everyone that the file has changed.
|
||||
* Only use this if you don't want the emitChanged signal.
|
||||
* @param toolbarCache iff true save a cache of the toolbar folder, too
|
||||
* @return true if saving was successful
|
||||
*/
|
||||
// KF6 TODO: Use an enum and not a bool
|
||||
bool save(bool toolbarCache = true) const;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
QDomDocument internalDocument() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Signals that the group (or any of its children) with the address
|
||||
* @p groupAddress (e.g. "/4/5")
|
||||
* has been modified.
|
||||
* connect to this
|
||||
*/
|
||||
void changed(const QString &groupAddress);
|
||||
|
||||
/**
|
||||
* Emitted when an error occurs.
|
||||
* Contains the translated error message.
|
||||
* @since 4.6
|
||||
*/
|
||||
void error(const QString &errorMessage);
|
||||
|
||||
private Q_SLOTS:
|
||||
KBOOKMARKS_NO_EXPORT void slotFileChanged(const QString &path); // external bookmarks
|
||||
|
||||
private:
|
||||
// consts added to avoid a copy-and-paste of internalDocument
|
||||
KBOOKMARKS_NO_EXPORT void parse() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<KBookmarkManagerPrivate> const d;
|
||||
|
||||
friend class KBookmarkGroup;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
|
||||
SPDX-FileCopyrightText: 2003 Alexander Kellett <lypanov@kde.org>
|
||||
SPDX-FileCopyrightText: 2008 Norbert Frese <nf2@scheinwelt.at>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "kbookmarkowner.h"
|
||||
|
||||
class Q_DECL_HIDDEN KBookmarkOwner::FutureBookmarkPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QString title;
|
||||
QUrl url;
|
||||
QString icon;
|
||||
};
|
||||
|
||||
KBookmarkOwner::FutureBookmark::FutureBookmark(const QString &title, const QUrl &url, const QString &icon)
|
||||
: d(new FutureBookmarkPrivate)
|
||||
{
|
||||
d->title = title;
|
||||
d->url = url;
|
||||
d->icon = icon;
|
||||
}
|
||||
|
||||
KBookmarkOwner::FutureBookmark::FutureBookmark(const FutureBookmark &other)
|
||||
: d(other.d)
|
||||
{
|
||||
}
|
||||
|
||||
KBookmarkOwner::FutureBookmark &KBookmarkOwner::FutureBookmark::operator=(const FutureBookmark &other)
|
||||
{
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
KBookmarkOwner::FutureBookmark::~FutureBookmark()
|
||||
{
|
||||
}
|
||||
|
||||
QString KBookmarkOwner::FutureBookmark::title() const
|
||||
{
|
||||
return d->title;
|
||||
}
|
||||
|
||||
QUrl KBookmarkOwner::FutureBookmark::url() const
|
||||
{
|
||||
return d->url;
|
||||
}
|
||||
|
||||
QString KBookmarkOwner::FutureBookmark::icon() const
|
||||
{
|
||||
return d->icon;
|
||||
}
|
||||
|
||||
KBookmarkOwner::KBookmarkOwner()
|
||||
: d(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
KBookmarkOwner::~KBookmarkOwner() = default;
|
||||
|
||||
bool KBookmarkOwner::enableOption(BookmarkOption action) const
|
||||
{
|
||||
if (action == ShowAddBookmark) {
|
||||
return true;
|
||||
}
|
||||
if (action == ShowEditBookmark) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void KBookmarkOwner::openFolderinTabs(const KBookmarkGroup &)
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkOwner::openInNewTab(const KBookmark &bm)
|
||||
{
|
||||
// fallback
|
||||
openBookmark(bm, Qt::LeftButton, Qt::NoModifier);
|
||||
}
|
||||
|
||||
void KBookmarkOwner::openInNewWindow(const KBookmark &bm)
|
||||
{
|
||||
// fallback
|
||||
openBookmark(bm, Qt::LeftButton, Qt::NoModifier);
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000, 2006 David Faure <faure@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
#ifndef KBOOKMARK_OWNER_H
|
||||
#define KBOOKMARK_OWNER_H
|
||||
|
||||
#include "kbookmark.h"
|
||||
|
||||
#include <QSharedDataPointer>
|
||||
#include <QString>
|
||||
|
||||
class QWidget;
|
||||
|
||||
class KBookmarkGroup;
|
||||
|
||||
/**
|
||||
* @class KBookmarkOwner kbookmarkowner.h KBookmarkOwner
|
||||
*
|
||||
* The KBookmarkMenu and KBookmarkBar classes gives the user
|
||||
* the ability to either edit bookmarks or add their own. In the
|
||||
* first case, the app may want to open the bookmark in a special way.
|
||||
* In the second case, the app @em must supply the name and the
|
||||
* URL for the bookmark.
|
||||
*
|
||||
* This class gives the app this callback-like ability.
|
||||
*
|
||||
* If your app does not give the user the ability to add bookmarks and
|
||||
* you don't mind using the default bookmark editor to edit your
|
||||
* bookmarks, then you don't need to overload this class at all.
|
||||
* Rather, just use something like:
|
||||
*
|
||||
* @code
|
||||
* bookmarks = new KBookmarkMenu(manager, nullptr, menu);
|
||||
* @endcode
|
||||
*
|
||||
* If you wish to use your own editor or allow the user to add
|
||||
* bookmarks, you must overload this class.
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT KBookmarkOwner
|
||||
{
|
||||
public:
|
||||
KBookmarkOwner();
|
||||
virtual ~KBookmarkOwner();
|
||||
|
||||
/**
|
||||
* This function is called whenever the user wants to add the
|
||||
* current page to the bookmarks list. The title will become the
|
||||
* "name" of the bookmark. You must overload this function if you
|
||||
* wish to give your users the ability to add bookmarks.
|
||||
* The default returns an empty string.
|
||||
*
|
||||
* @return the title of the current page.
|
||||
*/
|
||||
virtual QString currentTitle() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called whenever the user wants to add the
|
||||
* current page to the bookmarks list. The URL will become the URL
|
||||
* of the bookmark. You must overload this function if you wish to
|
||||
* give your users the ability to add bookmarks.
|
||||
* The default returns an empty string.
|
||||
*
|
||||
* @return the URL of the current page.
|
||||
* Since 5.0 this method returns a QUrl. While porting it, remember to implement currentIcon too.
|
||||
*/
|
||||
virtual QUrl currentUrl() const
|
||||
{
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called whenever the user wants to add the
|
||||
* current page to the bookmarks list. The icon will become the icon
|
||||
* of the bookmark. You must overload this function if you wish to
|
||||
* give your users the ability to add bookmarks.
|
||||
* The default returns an empty string.
|
||||
*
|
||||
* A very common implementation for this method is
|
||||
* return KIO::iconNameForUrl(currentUrl());
|
||||
*
|
||||
* @return the icon name of the current page.
|
||||
* @since 5.0
|
||||
*/
|
||||
virtual QString currentIcon() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns whether the owner supports tabs.
|
||||
* The default returns @c false.
|
||||
*/
|
||||
virtual bool supportsTabs() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
class FutureBookmarkPrivate;
|
||||
/**
|
||||
* Represents the data for a bookmark that will be added.
|
||||
* @since 5.0
|
||||
*/
|
||||
class KBOOKMARKS_EXPORT FutureBookmark
|
||||
{
|
||||
public:
|
||||
FutureBookmark(const QString &title, const QUrl &url, const QString &icon);
|
||||
~FutureBookmark();
|
||||
FutureBookmark(const FutureBookmark &other);
|
||||
FutureBookmark &operator=(const FutureBookmark &other);
|
||||
|
||||
QString title() const;
|
||||
QUrl url() const;
|
||||
QString icon() const;
|
||||
|
||||
private:
|
||||
QSharedDataPointer<FutureBookmarkPrivate> d;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a list of bookmark data for the open tabs.
|
||||
* The default returns an empty list.
|
||||
*/
|
||||
virtual QList<FutureBookmark> currentBookmarkList() const
|
||||
{
|
||||
return QList<FutureBookmark>();
|
||||
}
|
||||
|
||||
enum BookmarkOption { ShowAddBookmark, ShowEditBookmark };
|
||||
|
||||
/** Returns true if \p action should be shown in the menu
|
||||
* The default is to show both a add and editBookmark Entry
|
||||
* //TODO ContextMenuAction? to disable the contextMenu?
|
||||
* Delete and Properties to disable those in the
|
||||
* context menu?
|
||||
*/
|
||||
virtual bool enableOption(BookmarkOption option) const;
|
||||
|
||||
/**
|
||||
* Called if a bookmark is selected. You need to override this.
|
||||
*/
|
||||
virtual void openBookmark(const KBookmark &bm, Qt::MouseButtons mb, Qt::KeyboardModifiers km) = 0;
|
||||
|
||||
/**
|
||||
* Called if the user wants to open every bookmark in this folder in a new tab.
|
||||
* The default implementation does nothing.
|
||||
* This is only called if supportsTabs() returns true
|
||||
*/
|
||||
virtual void openFolderinTabs(const KBookmarkGroup &bm);
|
||||
|
||||
/**
|
||||
* Called when a bookmark should be opened in a new tab.
|
||||
* The default implementation calls openBookmark.
|
||||
* @since 5.0
|
||||
*/
|
||||
virtual void openInNewTab(const KBookmark &bm);
|
||||
|
||||
/**
|
||||
* Called when a bookmark should be opened in a new window.
|
||||
* The default implementation calls openBookmark.
|
||||
* @since 5.0
|
||||
*/
|
||||
virtual void openInNewWindow(const KBookmark &bm);
|
||||
|
||||
private:
|
||||
class KBookmarkOwnerPrivate;
|
||||
KBookmarkOwnerPrivate *d;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
|
||||
SPDX-FileCopyrightText: 2003 Alexander Kellett <lypanov@kde.org>
|
||||
SPDX-FileCopyrightText: 2008 Norbert Frese <nf2@scheinwelt.at>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "kbookmarksettings_p.h"
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
|
||||
KBookmarkSettings *KBookmarkSettings::s_self = nullptr;
|
||||
|
||||
void KBookmarkSettings::readSettings()
|
||||
{
|
||||
KConfig config(QStringLiteral("kbookmarkrc"), KConfig::NoGlobals);
|
||||
KConfigGroup cg(&config, QStringLiteral("Bookmarks"));
|
||||
|
||||
// add bookmark dialog usage - no reparse
|
||||
s_self->m_advancedaddbookmark = cg.readEntry("AdvancedAddBookmarkDialog", false);
|
||||
|
||||
// this one alters the menu, therefore it needs a reparse
|
||||
s_self->m_contextmenu = cg.readEntry("ContextMenuActions", true);
|
||||
}
|
||||
|
||||
KBookmarkSettings *KBookmarkSettings::self()
|
||||
{
|
||||
if (!s_self) {
|
||||
s_self = new KBookmarkSettings;
|
||||
readSettings();
|
||||
}
|
||||
return s_self;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 2003 Alexander Kellett <lypanov@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef __kbookmarksettings_p_h__
|
||||
#define __kbookmarksettings_p_h__
|
||||
|
||||
#include <kbookmarks_export.h>
|
||||
|
||||
class QString;
|
||||
class KBookmark;
|
||||
class KBookmarkGroup;
|
||||
|
||||
#define KEDITBOOKMARKS_BINARY "keditbookmarks"
|
||||
|
||||
class KBOOKMARKS_EXPORT KBookmarkSettings
|
||||
{
|
||||
public:
|
||||
bool m_advancedaddbookmark;
|
||||
bool m_contextmenu;
|
||||
static KBookmarkSettings *s_self;
|
||||
static void readSettings();
|
||||
static KBookmarkSettings *self();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000, 2006 David Faure <faure@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "keditbookmarks_p.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "kbookmarksettings_p.h"
|
||||
|
||||
void KEditBookmarks::setBrowserMode(bool browserMode)
|
||||
{
|
||||
m_browserMode = browserMode;
|
||||
}
|
||||
|
||||
KEditBookmarks::OpenResult KEditBookmarks::openForFile(const QString &file)
|
||||
{
|
||||
QStringList args;
|
||||
args << QStringLiteral("--customcaption") << QGuiApplication::applicationDisplayName();
|
||||
|
||||
if (!m_browserMode) {
|
||||
args << QStringLiteral("--nobrowser");
|
||||
}
|
||||
|
||||
args << file;
|
||||
return startKEditBookmarks(args);
|
||||
}
|
||||
|
||||
KEditBookmarks::OpenResult KEditBookmarks::openForFileAtAddress(const QString &file, const QString &address)
|
||||
{
|
||||
QStringList args;
|
||||
args << QStringLiteral("--customcaption") << QGuiApplication::applicationDisplayName();
|
||||
|
||||
if (!m_browserMode) {
|
||||
args << QStringLiteral("--nobrowser");
|
||||
}
|
||||
|
||||
args << QStringLiteral("--address") << address;
|
||||
|
||||
args << file;
|
||||
return startKEditBookmarks(args);
|
||||
}
|
||||
|
||||
KEditBookmarks::OpenResult KEditBookmarks::startKEditBookmarks(const QStringList &args)
|
||||
{
|
||||
const QString exec = QStandardPaths::findExecutable(QStringLiteral(KEDITBOOKMARKS_BINARY));
|
||||
if (!exec.isEmpty()) {
|
||||
bool success = QProcess::startDetached(exec, args);
|
||||
|
||||
if (!success) {
|
||||
OpenResult result;
|
||||
result.m_sucess = false;
|
||||
result.m_errorMessage = QObject::tr("keditbookmarks could not be started");
|
||||
return result;
|
||||
}
|
||||
|
||||
} else {
|
||||
OpenResult result;
|
||||
result.m_sucess = false;
|
||||
result.m_errorMessage = QObject::tr("The keditbookmarks executable was not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
OpenResult result;
|
||||
result.m_sucess = true;
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2000, 2006 David Faure <faure@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "kbookmarks_export.h"
|
||||
|
||||
class KBOOKMARKS_EXPORT KEditBookmarks
|
||||
{
|
||||
public:
|
||||
class OpenResult
|
||||
{
|
||||
public:
|
||||
bool sucess()
|
||||
{
|
||||
return m_sucess;
|
||||
}
|
||||
|
||||
QString errorMessage() const
|
||||
{
|
||||
return m_errorMessage;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_sucess;
|
||||
QString m_errorMessage;
|
||||
friend KEditBookmarks;
|
||||
};
|
||||
|
||||
void setBrowserMode(bool browserMode);
|
||||
bool browserMode() const;
|
||||
|
||||
OpenResult openForFile(const QString &file);
|
||||
|
||||
OpenResult openForFileAtAddress(const QString &file, const QString &address);
|
||||
|
||||
private:
|
||||
OpenResult startKEditBookmarks(const QStringList &args);
|
||||
|
||||
bool m_browserMode = false;
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
add_library(KF6BookmarksWidgets)
|
||||
add_library(KF6::BookmarksWidgets ALIAS KF6BookmarksWidgets)
|
||||
|
||||
set_target_properties(KF6BookmarksWidgets PROPERTIES
|
||||
VERSION ${KBOOKMARKS_VERSION}
|
||||
SOVERSION ${KBOOKMARKS_SOVERSION}
|
||||
EXPORT_NAME BookmarksWidgets
|
||||
)
|
||||
|
||||
ecm_create_qm_loader(KF6BookmarksWidgets kbookmarkswidgets6_qt)
|
||||
|
||||
target_sources(KF6BookmarksWidgets PRIVATE
|
||||
kbookmarkactionmenu.cpp
|
||||
kbookmarkactionmenu.h
|
||||
kbookmarkcontextmenu.cpp
|
||||
kbookmarkcontextmenu.h
|
||||
kbookmarkdialog.cpp
|
||||
kbookmarkdialog.h
|
||||
kbookmarkdialog_p.h
|
||||
kbookmarkmenu.cpp
|
||||
kbookmarkmenu.h
|
||||
kbookmarkmenu_p.h
|
||||
)
|
||||
|
||||
ecm_qt_declare_logging_category(KF6BookmarksWidgets
|
||||
HEADER kbookmarkswidgets_debug.h
|
||||
IDENTIFIER KBOOKMARKSWIDGETS_LOG
|
||||
CATEGORY_NAME kf.bookmarks.widgets
|
||||
DESCRIPTION "KBookmarks Widgets"
|
||||
EXPORT KBOOKMARKSWIDGETS
|
||||
)
|
||||
|
||||
ecm_generate_export_header(KF6BookmarksWidgets
|
||||
BASE_NAME KBookmarksWidgets
|
||||
GROUP_BASE_NAME KF
|
||||
VERSION ${KF_VERSION}
|
||||
USE_VERSION_HEADER kbookmarks_version.h
|
||||
DEPRECATED_BASE_VERSION 0
|
||||
DEPRECATION_VERSIONS
|
||||
EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT}
|
||||
)
|
||||
|
||||
target_include_directories(KF6BookmarksWidgets INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF}/KBookmarksWidgets>")
|
||||
|
||||
target_link_libraries(KF6BookmarksWidgets PUBLIC Qt6::Widgets KF6::WidgetsAddons)
|
||||
target_link_libraries(KF6BookmarksWidgets PRIVATE
|
||||
KF6::Bookmarks
|
||||
KF6::ConfigCore # for KAuthorized
|
||||
KF6::ConfigGui # for KStandardAction
|
||||
)
|
||||
|
||||
ecm_generate_headers(KBookmarksWidgets_HEADERS
|
||||
HEADER_NAMES
|
||||
KBookmarkActionMenu
|
||||
KBookmarkContextMenu
|
||||
KBookmarkMenu
|
||||
KBookmarkDialog
|
||||
|
||||
REQUIRED_HEADERS KBookmarksWidgets_HEADERS
|
||||
)
|
||||
|
||||
install(TARGETS KF6BookmarksWidgets EXPORT KF6BookmarksTargets ${KF_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kbookmarkswidgets_export.h
|
||||
${KBookmarksWidgets_HEADERS}
|
||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KBookmarksWidgets COMPONENT Devel
|
||||
)
|
||||
|
||||
ecm_qt_install_logging_categories(
|
||||
EXPORT KBOOKMARKSWIDGETS
|
||||
FILE kbookmarkswidgets.categories
|
||||
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
|
||||
)
|
||||
|
||||
if(BUILD_QCH)
|
||||
ecm_add_qch(
|
||||
KF6BookmarksWidgets_QCH
|
||||
NAME KBookmarksWidgets
|
||||
BASE_NAME KF6BookmarksWidgets
|
||||
VERSION ${KF_VERSION}
|
||||
ORG_DOMAIN org.kde
|
||||
SOURCES # using only public headers, to cover only public API
|
||||
${KBookmarksWidgets_HEADERS}
|
||||
MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md"
|
||||
LINK_QCHS
|
||||
Qt6Widgets_QCH
|
||||
Qt6Xml_QCH
|
||||
KF6WidgetsAddons_QCH
|
||||
INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
BLANK_MACROS
|
||||
KBOOKMARKSWIDGETS_EXPORT
|
||||
KBOOKMARKSWIDGETS_DEPRECATED
|
||||
KBOOKMARKSWIDGETS_DEPRECATED_EXPORT
|
||||
"KBOOKMARKS_DEPRECATED_VERSION(x, y, t)"
|
||||
TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR}
|
||||
QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR}
|
||||
COMPONENT Devel
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kbookmarkactionmenu.h"
|
||||
|
||||
KBookmarkActionMenu::KBookmarkActionMenu(const KBookmark &bm, QObject *parent)
|
||||
: KActionMenu(QIcon::fromTheme(bm.icon()), bm.text().replace(QLatin1Char('&'), QLatin1String("&&")), parent)
|
||||
, KBookmarkActionInterface(bm)
|
||||
{
|
||||
setToolTip(bm.description());
|
||||
setIconText(text());
|
||||
}
|
||||
|
||||
KBookmarkActionMenu::KBookmarkActionMenu(const KBookmark &bm, const QString &text, QObject *parent)
|
||||
: KActionMenu(text, parent)
|
||||
, KBookmarkActionInterface(bm)
|
||||
{
|
||||
}
|
||||
|
||||
KBookmarkActionMenu::~KBookmarkActionMenu()
|
||||
{
|
||||
}
|
||||
|
||||
#include "moc_kbookmarkactionmenu.cpp"
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KBOOKMARKACTIONMENU_H
|
||||
#define KBOOKMARKACTIONMENU_H
|
||||
|
||||
#include "kbookmarkactioninterface.h"
|
||||
#include <KActionMenu>
|
||||
#include <kbookmarkswidgets_export.h>
|
||||
|
||||
/**
|
||||
* @class KBookmarkActionMenu kbookmarkactionmenu.h KBookmarkActionMenu
|
||||
*
|
||||
* A wrapper around KActionMenu to provide a nice constructor for bookmark groups.
|
||||
*/
|
||||
class KBOOKMARKSWIDGETS_EXPORT KBookmarkActionMenu : public KActionMenu, public KBookmarkActionInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KBookmarkActionMenu(const KBookmark &bm, QObject *parent);
|
||||
KBookmarkActionMenu(const KBookmark &bm, const QString &text, QObject *parent);
|
||||
~KBookmarkActionMenu() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kbookmarkcontextmenu.h"
|
||||
#include "kbookmarkdialog.h"
|
||||
#include "kbookmarkmanager.h"
|
||||
#include "kbookmarkowner.h"
|
||||
#include "keditbookmarks_p.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
|
||||
KBookmarkContextMenu::KBookmarkContextMenu(const KBookmark &bk, KBookmarkManager *manager, KBookmarkOwner *owner, QWidget *parent)
|
||||
: QMenu(parent)
|
||||
, bm(bk)
|
||||
, m_pManager(manager)
|
||||
, m_pOwner(owner)
|
||||
{
|
||||
connect(this, &QMenu::aboutToShow, this, &KBookmarkContextMenu::slotAboutToShow);
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotAboutToShow()
|
||||
{
|
||||
addActions();
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::addActions()
|
||||
{
|
||||
if (bm.isGroup()) {
|
||||
addOpenFolderInTabs();
|
||||
addBookmark();
|
||||
addFolderActions();
|
||||
} else {
|
||||
addBookmark();
|
||||
addBookmarkActions();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkContextMenu::~KBookmarkContextMenu()
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::addBookmark()
|
||||
{
|
||||
if (m_pOwner && m_pOwner->enableOption(KBookmarkOwner::ShowAddBookmark)) {
|
||||
addAction(QIcon::fromTheme(QStringLiteral("bookmark-new")), tr("Add Bookmark Here", "@action:inmenu"), this, &KBookmarkContextMenu::slotInsert);
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::addFolderActions()
|
||||
{
|
||||
addAction(tr("Open Folder in Bookmark Editor", "@action:inmenu"), this, &KBookmarkContextMenu::slotEditAt);
|
||||
addProperties();
|
||||
addSeparator();
|
||||
addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Delete Folder", "@action:inmenu"), this, &KBookmarkContextMenu::slotRemove);
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::addProperties()
|
||||
{
|
||||
addAction(tr("Properties", "@action:inmenu"), this, &KBookmarkContextMenu::slotProperties);
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::addBookmarkActions()
|
||||
{
|
||||
addAction(tr("Copy Link Address", "@action:inmenu"), this, &KBookmarkContextMenu::slotCopyLocation);
|
||||
addProperties();
|
||||
addSeparator();
|
||||
addAction(QIcon::fromTheme(QStringLiteral("edit-delete")), tr("Delete Bookmark", "@action:inmenu"), this, &KBookmarkContextMenu::slotRemove);
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::addOpenFolderInTabs()
|
||||
{
|
||||
if (m_pOwner->supportsTabs()) {
|
||||
addAction(QIcon::fromTheme(QStringLiteral("tab-new")), tr("Open Folder in Tabs", "@action:inmenu"), this, &KBookmarkContextMenu::slotOpenFolderInTabs);
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotEditAt()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotEditAt" << m_highlightedAddress;
|
||||
KEditBookmarks editBookmarks;
|
||||
editBookmarks.setBrowserMode(m_browserMode);
|
||||
auto result = editBookmarks.openForFileAtAddress(m_pManager->path(), bm.address());
|
||||
|
||||
if (!result.sucess()) {
|
||||
QMessageBox::critical(QApplication::activeWindow(), QApplication::applicationDisplayName(), result.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotProperties()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotProperties" << m_highlightedAddress;
|
||||
|
||||
KBookmarkDialog *dlg = new KBookmarkDialog(m_pManager, QApplication::activeWindow());
|
||||
dlg->editBookmark(bm);
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotInsert()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotInsert" << m_highlightedAddress;
|
||||
|
||||
QUrl url = m_pOwner->currentUrl();
|
||||
if (url.isEmpty()) {
|
||||
QMessageBox::critical(QApplication::activeWindow(), QApplication::applicationName(), tr("Cannot add bookmark with empty URL.", "@info"));
|
||||
return;
|
||||
}
|
||||
QString title = m_pOwner->currentTitle();
|
||||
if (title.isEmpty()) {
|
||||
title = url.toDisplayString();
|
||||
}
|
||||
|
||||
if (bm.isGroup()) {
|
||||
KBookmarkGroup parentBookmark = bm.toGroup();
|
||||
Q_ASSERT(!parentBookmark.isNull());
|
||||
parentBookmark.addBookmark(title, url, m_pOwner->currentIcon());
|
||||
m_pManager->emitChanged(parentBookmark);
|
||||
} else {
|
||||
KBookmarkGroup parentBookmark = bm.parentGroup();
|
||||
Q_ASSERT(!parentBookmark.isNull());
|
||||
KBookmark newBookmark = parentBookmark.addBookmark(title, m_pOwner->currentUrl(), m_pOwner->currentIcon());
|
||||
parentBookmark.moveBookmark(newBookmark, parentBookmark.previous(bm));
|
||||
m_pManager->emitChanged(parentBookmark);
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotRemove()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotRemove" << m_highlightedAddress;
|
||||
|
||||
bool folder = bm.isGroup();
|
||||
|
||||
if (QMessageBox::warning(QApplication::activeWindow(),
|
||||
folder ? tr("Bookmark Folder Deletion", "@title:window") : tr("Bookmark Deletion", "@title:window"),
|
||||
folder ? tr("Are you sure you wish to remove the bookmark folder\n\"%1\"?").arg(bm.text())
|
||||
: tr("Are you sure you wish to remove the bookmark\n\"%1\"?").arg(bm.text()),
|
||||
QMessageBox::Yes | QMessageBox::Cancel)
|
||||
!= QMessageBox::Yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
KBookmarkGroup parentBookmark = bm.parentGroup();
|
||||
parentBookmark.deleteBookmark(bm);
|
||||
m_pManager->emitChanged(parentBookmark);
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotCopyLocation()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotCopyLocation" << m_highlightedAddress;
|
||||
|
||||
if (!bm.isGroup()) {
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
bm.populateMimeData(mimeData);
|
||||
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
|
||||
mimeData = new QMimeData;
|
||||
bm.populateMimeData(mimeData);
|
||||
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::slotOpenFolderInTabs()
|
||||
{
|
||||
owner()->openFolderinTabs(bookmark().toGroup());
|
||||
}
|
||||
|
||||
KBookmarkManager *KBookmarkContextMenu::manager() const
|
||||
{
|
||||
return m_pManager;
|
||||
}
|
||||
|
||||
KBookmarkOwner *KBookmarkContextMenu::owner() const
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
||||
KBookmark KBookmarkContextMenu::bookmark() const
|
||||
{
|
||||
return bm;
|
||||
}
|
||||
|
||||
void KBookmarkContextMenu::setBrowserMode(bool browserMode)
|
||||
{
|
||||
m_browserMode = browserMode;
|
||||
}
|
||||
|
||||
bool KBookmarkContextMenu::browserMode() const
|
||||
{
|
||||
return m_browserMode;
|
||||
}
|
||||
|
||||
#include "moc_kbookmarkcontextmenu.cpp"
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KBOOKMARKCONTEXTMENU_H
|
||||
#define KBOOKMARKCONTEXTMENU_H
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include "kbookmark.h"
|
||||
#include <kbookmarkswidgets_export.h>
|
||||
|
||||
class KBookmarkManager;
|
||||
class KBookmarkOwner;
|
||||
|
||||
/**
|
||||
* @class KBookmarkContextMenu kbookmarkcontextmenu.h KBookmarkContextMenu
|
||||
*
|
||||
* A context menu for a bookmark.
|
||||
*/
|
||||
class KBOOKMARKSWIDGETS_EXPORT KBookmarkContextMenu : public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KBookmarkContextMenu(const KBookmark &bm, KBookmarkManager *manager, KBookmarkOwner *owner, QWidget *parent = nullptr);
|
||||
~KBookmarkContextMenu() override;
|
||||
virtual void addActions();
|
||||
|
||||
/**
|
||||
* Set this to true to make any "Edit Bookmarks" dialog
|
||||
* show UI elements that are specific to browsers.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
void setBrowserMode(bool browserMode);
|
||||
|
||||
/**
|
||||
* Whether any "Edit Bookmarks" dialog shows UI elements
|
||||
* that are specific to browsers.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
bool browserMode() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void slotEditAt();
|
||||
void slotProperties();
|
||||
void slotInsert();
|
||||
void slotRemove();
|
||||
void slotCopyLocation();
|
||||
void slotOpenFolderInTabs();
|
||||
|
||||
protected:
|
||||
void addBookmark();
|
||||
void addFolderActions();
|
||||
void addProperties();
|
||||
void addBookmarkActions();
|
||||
void addOpenFolderInTabs();
|
||||
|
||||
KBookmarkManager *manager() const;
|
||||
KBookmarkOwner *owner() const;
|
||||
KBookmark bookmark() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
KBOOKMARKS_NO_EXPORT void slotAboutToShow();
|
||||
|
||||
private:
|
||||
// TODO KF6 dptr it
|
||||
const KBookmark bm;
|
||||
KBookmarkManager *const m_pManager;
|
||||
KBookmarkOwner *const m_pOwner;
|
||||
bool m_browserMode = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,391 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2007 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
|
||||
#include "kbookmarkdialog.h"
|
||||
#include "kbookmarkdialog_p.h"
|
||||
#include "kbookmarkmanager.h"
|
||||
#include "kbookmarkmenu_p.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFormLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QIcon>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include <KGuiItem>
|
||||
|
||||
KBookmarkDialogPrivate::KBookmarkDialogPrivate(KBookmarkDialog *qq)
|
||||
: q(qq)
|
||||
, folderTree(nullptr)
|
||||
, layout(false)
|
||||
{
|
||||
}
|
||||
|
||||
KBookmarkDialogPrivate::~KBookmarkDialogPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
void KBookmarkDialogPrivate::initLayout()
|
||||
{
|
||||
QBoxLayout *vbox = new QVBoxLayout(q);
|
||||
|
||||
QFormLayout *form = new QFormLayout();
|
||||
vbox->addLayout(form);
|
||||
|
||||
form->addRow(titleLabel, title);
|
||||
form->addRow(urlLabel, url);
|
||||
form->addRow(commentLabel, comment);
|
||||
|
||||
vbox->addWidget(folderTree);
|
||||
vbox->addWidget(buttonBox);
|
||||
}
|
||||
|
||||
void KBookmarkDialogPrivate::initLayoutPrivate()
|
||||
{
|
||||
title = new QLineEdit(q);
|
||||
title->setMinimumWidth(300);
|
||||
titleLabel = new QLabel(KBookmarkDialog::tr("Name:", "@label:textbox"), q);
|
||||
titleLabel->setBuddy(title);
|
||||
|
||||
url = new QLineEdit(q);
|
||||
url->setMinimumWidth(300);
|
||||
urlLabel = new QLabel(KBookmarkDialog::tr("Location:", "@label:textbox"), q);
|
||||
urlLabel->setBuddy(url);
|
||||
|
||||
comment = new QLineEdit(q);
|
||||
comment->setMinimumWidth(300);
|
||||
commentLabel = new QLabel(KBookmarkDialog::tr("Comment:", "@label:textbox"), q);
|
||||
commentLabel->setBuddy(comment);
|
||||
|
||||
folderTree = new QTreeWidget(q);
|
||||
folderTree->setColumnCount(1);
|
||||
folderTree->header()->hide();
|
||||
folderTree->setSortingEnabled(false);
|
||||
folderTree->setSelectionMode(QTreeWidget::SingleSelection);
|
||||
folderTree->setSelectionBehavior(QTreeWidget::SelectRows);
|
||||
folderTree->setMinimumSize(60, 100);
|
||||
QTreeWidgetItem *root = new KBookmarkTreeItem(folderTree);
|
||||
fillGroup(root, mgr->root());
|
||||
|
||||
buttonBox = new QDialogButtonBox(q);
|
||||
buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
q->connect(buttonBox, &QDialogButtonBox::accepted, q, &KBookmarkDialog::accept);
|
||||
q->connect(buttonBox, &QDialogButtonBox::rejected, q, &QDialog::reject);
|
||||
|
||||
initLayout();
|
||||
layout = true;
|
||||
}
|
||||
|
||||
void KBookmarkDialogPrivate::fillGroup(QTreeWidgetItem *parentItem, const KBookmarkGroup &group, const KBookmarkGroup &selectGroup)
|
||||
{
|
||||
for (KBookmark bk = group.first(); !bk.isNull(); bk = group.next(bk)) {
|
||||
if (bk.isGroup()) {
|
||||
const KBookmarkGroup bkGroup = bk.toGroup();
|
||||
QTreeWidgetItem *item = new KBookmarkTreeItem(parentItem, folderTree, bkGroup);
|
||||
if (selectGroup == bkGroup) {
|
||||
folderTree->setCurrentItem(item);
|
||||
}
|
||||
fillGroup(item, bkGroup, selectGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkDialogPrivate::setParentBookmark(const KBookmark &bm)
|
||||
{
|
||||
QString address = bm.address();
|
||||
KBookmarkTreeItem *item = static_cast<KBookmarkTreeItem *>(folderTree->topLevelItem(0));
|
||||
while (true) {
|
||||
if (item->address() == bm.address()) {
|
||||
folderTree->setCurrentItem(item);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < item->childCount(); ++i) {
|
||||
KBookmarkTreeItem *child = static_cast<KBookmarkTreeItem *>(item->child(i));
|
||||
if (KBookmark::commonParent(child->address(), address) == child->address()) {
|
||||
item = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkDialogPrivate::parentBookmark()
|
||||
{
|
||||
KBookmarkTreeItem *item = dynamic_cast<KBookmarkTreeItem *>(folderTree->currentItem());
|
||||
if (!item) {
|
||||
return mgr->root();
|
||||
}
|
||||
const QString &address = item->address();
|
||||
return mgr->findByAddress(address).toGroup();
|
||||
}
|
||||
|
||||
void KBookmarkDialog::accept()
|
||||
{
|
||||
if (d->mode == KBookmarkDialogPrivate::NewFolder) {
|
||||
KBookmarkGroup parent = d->parentBookmark();
|
||||
if (d->title->text().isEmpty()) {
|
||||
d->title->setText(QStringLiteral("New Folder"));
|
||||
}
|
||||
d->bm = parent.createNewFolder(d->title->text());
|
||||
d->bm.setDescription(d->comment->text());
|
||||
d->mgr->emitChanged(parent);
|
||||
} else if (d->mode == KBookmarkDialogPrivate::NewBookmark) {
|
||||
KBookmarkGroup parent = d->parentBookmark();
|
||||
if (d->title->text().isEmpty()) {
|
||||
d->title->setText(QStringLiteral("New Bookmark"));
|
||||
}
|
||||
d->bm = parent.addBookmark(d->title->text(), QUrl(d->url->text()), d->icon);
|
||||
d->bm.setDescription(d->comment->text());
|
||||
d->mgr->emitChanged(parent);
|
||||
} else if (d->mode == KBookmarkDialogPrivate::NewMultipleBookmarks) {
|
||||
KBookmarkGroup parent = d->parentBookmark();
|
||||
if (d->title->text().isEmpty()) {
|
||||
d->title->setText(QStringLiteral("New Folder"));
|
||||
}
|
||||
d->bm = parent.createNewFolder(d->title->text());
|
||||
d->bm.setDescription(d->comment->text());
|
||||
for (const KBookmarkOwner::FutureBookmark &fb : std::as_const(d->list)) {
|
||||
d->bm.toGroup().addBookmark(fb.title(), fb.url(), fb.icon());
|
||||
}
|
||||
d->mgr->emitChanged(parent);
|
||||
} else if (d->mode == KBookmarkDialogPrivate::EditBookmark) {
|
||||
d->bm.setFullText(d->title->text());
|
||||
d->bm.setUrl(QUrl(d->url->text()));
|
||||
d->bm.setDescription(d->comment->text());
|
||||
d->mgr->emitChanged(d->bm.parentGroup());
|
||||
} else if (d->mode == d->SelectFolder) {
|
||||
d->bm = d->parentBookmark();
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
KBookmark KBookmarkDialog::editBookmark(const KBookmark &bm)
|
||||
{
|
||||
if (!d->layout) {
|
||||
d->initLayoutPrivate();
|
||||
}
|
||||
|
||||
KGuiItem::assign(d->buttonBox->button(QDialogButtonBox::Ok), KGuiItem(tr("Update", "@action:button")));
|
||||
setWindowTitle(tr("Bookmark Properties", "@title:window"));
|
||||
d->url->setVisible(!bm.isGroup());
|
||||
d->urlLabel->setVisible(!bm.isGroup());
|
||||
d->bm = bm;
|
||||
d->title->setText(bm.fullText());
|
||||
d->url->setText(bm.url().toString());
|
||||
d->comment->setVisible(true);
|
||||
d->commentLabel->setVisible(true);
|
||||
d->comment->setText(bm.description());
|
||||
d->folderTree->setVisible(false);
|
||||
|
||||
d->mode = KBookmarkDialogPrivate::EditBookmark;
|
||||
|
||||
if (exec() == QDialog::Accepted) {
|
||||
return d->bm;
|
||||
} else {
|
||||
return KBookmark();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmark KBookmarkDialog::addBookmark(const QString &title, const QUrl &url, const QString &icon, KBookmark parent)
|
||||
{
|
||||
if (!d->layout) {
|
||||
d->initLayoutPrivate();
|
||||
}
|
||||
if (parent.isNull()) {
|
||||
parent = d->mgr->root();
|
||||
}
|
||||
|
||||
QPushButton *newButton = new QPushButton;
|
||||
KGuiItem::assign(newButton, KGuiItem(tr("&New Folder…", "@action:button"), QStringLiteral("folder-new")));
|
||||
d->buttonBox->addButton(newButton, QDialogButtonBox::ActionRole);
|
||||
connect(newButton, &QAbstractButton::clicked, this, &KBookmarkDialog::newFolderButton);
|
||||
|
||||
KGuiItem::assign(d->buttonBox->button(QDialogButtonBox::Ok), KGuiItem(tr("Add", "@action:button"), QStringLiteral("bookmark-new")));
|
||||
setWindowTitle(tr("Add Bookmark", "@title:window"));
|
||||
d->url->setVisible(true);
|
||||
d->urlLabel->setVisible(true);
|
||||
d->title->setText(title);
|
||||
d->url->setText(url.toString());
|
||||
d->comment->setText(QString());
|
||||
d->comment->setVisible(true);
|
||||
d->commentLabel->setVisible(true);
|
||||
d->setParentBookmark(parent);
|
||||
d->folderTree->setVisible(true);
|
||||
d->icon = icon;
|
||||
|
||||
d->mode = KBookmarkDialogPrivate::NewBookmark;
|
||||
|
||||
if (exec() == QDialog::Accepted) {
|
||||
return d->bm;
|
||||
} else {
|
||||
return KBookmark();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkDialog::addBookmarks(const QList<KBookmarkOwner::FutureBookmark> &list, const QString &name, KBookmarkGroup parent)
|
||||
{
|
||||
if (!d->layout) {
|
||||
d->initLayoutPrivate();
|
||||
}
|
||||
if (parent.isNull()) {
|
||||
parent = d->mgr->root();
|
||||
}
|
||||
|
||||
d->list = list;
|
||||
|
||||
QPushButton *newButton = new QPushButton;
|
||||
KGuiItem::assign(newButton, KGuiItem(tr("&New Folder…", "@action:button"), QStringLiteral("folder-new")));
|
||||
d->buttonBox->addButton(newButton, QDialogButtonBox::ActionRole);
|
||||
connect(newButton, &QAbstractButton::clicked, this, &KBookmarkDialog::newFolderButton);
|
||||
|
||||
KGuiItem::assign(d->buttonBox->button(QDialogButtonBox::Ok), KGuiItem(tr("Add", "@action:button"), QStringLiteral("bookmark-new")));
|
||||
setWindowTitle(tr("Add Bookmarks", "@title:window"));
|
||||
d->url->setVisible(false);
|
||||
d->urlLabel->setVisible(false);
|
||||
d->title->setText(name);
|
||||
d->comment->setVisible(true);
|
||||
d->commentLabel->setVisible(true);
|
||||
d->comment->setText(QString());
|
||||
d->setParentBookmark(parent);
|
||||
d->folderTree->setVisible(true);
|
||||
|
||||
d->mode = KBookmarkDialogPrivate::NewMultipleBookmarks;
|
||||
|
||||
if (exec() == QDialog::Accepted) {
|
||||
return d->bm.toGroup();
|
||||
} else {
|
||||
return KBookmarkGroup();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkDialog::selectFolder(KBookmark parent)
|
||||
{
|
||||
if (!d->layout) {
|
||||
d->initLayoutPrivate();
|
||||
}
|
||||
if (parent.isNull()) {
|
||||
parent = d->mgr->root();
|
||||
}
|
||||
|
||||
QPushButton *newButton = new QPushButton;
|
||||
KGuiItem::assign(newButton, KGuiItem(tr("&New Folder…", "@action:button"), QStringLiteral("folder-new")));
|
||||
d->buttonBox->addButton(newButton, QDialogButtonBox::ActionRole);
|
||||
connect(newButton, &QAbstractButton::clicked, this, &KBookmarkDialog::newFolderButton);
|
||||
|
||||
setWindowTitle(tr("Select Folder", "@title:window"));
|
||||
d->url->setVisible(false);
|
||||
d->urlLabel->setVisible(false);
|
||||
d->title->setVisible(false);
|
||||
d->titleLabel->setVisible(false);
|
||||
d->comment->setVisible(false);
|
||||
d->commentLabel->setVisible(false);
|
||||
d->setParentBookmark(parent);
|
||||
d->folderTree->setVisible(true);
|
||||
|
||||
d->mode = d->SelectFolder;
|
||||
|
||||
if (exec() == QDialog::Accepted) {
|
||||
return d->bm.toGroup();
|
||||
} else {
|
||||
return KBookmarkGroup();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkGroup KBookmarkDialog::createNewFolder(const QString &name, KBookmark parent)
|
||||
{
|
||||
if (!d->layout) {
|
||||
d->initLayoutPrivate();
|
||||
}
|
||||
if (parent.isNull()) {
|
||||
parent = d->mgr->root();
|
||||
}
|
||||
|
||||
setWindowTitle(tr("New Folder", "@title:window"));
|
||||
d->url->setVisible(false);
|
||||
d->urlLabel->setVisible(false);
|
||||
d->comment->setVisible(true);
|
||||
d->commentLabel->setVisible(true);
|
||||
d->comment->setText(QString());
|
||||
d->title->setText(name);
|
||||
d->setParentBookmark(parent);
|
||||
d->folderTree->setVisible(true);
|
||||
|
||||
d->mode = KBookmarkDialogPrivate::NewFolder;
|
||||
|
||||
if (exec() == QDialog::Accepted) {
|
||||
return d->bm.toGroup();
|
||||
} else {
|
||||
return KBookmarkGroup();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkDialog::KBookmarkDialog(KBookmarkManager *mgr, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, d(new KBookmarkDialogPrivate(this))
|
||||
{
|
||||
d->mgr = mgr;
|
||||
}
|
||||
|
||||
KBookmarkDialog::~KBookmarkDialog() = default;
|
||||
|
||||
void KBookmarkDialog::newFolderButton()
|
||||
{
|
||||
QString caption = d->parentBookmark().fullText().isEmpty() ? tr("Create New Bookmark Folder", "@title:window")
|
||||
: tr("Create New Bookmark Folder in %1", "@title:window").arg(d->parentBookmark().text());
|
||||
bool ok;
|
||||
QString text = QInputDialog::getText(this, caption, tr("New folder:", "@label:textbox"), QLineEdit::Normal, QString(), &ok);
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
KBookmarkGroup group = d->parentBookmark().createNewFolder(text);
|
||||
if (!group.isNull()) {
|
||||
KBookmarkGroup parentGroup = group.parentGroup();
|
||||
d->mgr->emitChanged(parentGroup);
|
||||
d->folderTree->clear();
|
||||
QTreeWidgetItem *root = new KBookmarkTreeItem(d->folderTree);
|
||||
d->fillGroup(root, d->mgr->root(), group);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
KBookmarkTreeItem::KBookmarkTreeItem(QTreeWidget *tree)
|
||||
: QTreeWidgetItem(tree)
|
||||
, m_address(QLatin1String(""))
|
||||
{
|
||||
setText(0, KBookmarkDialog::tr("Bookmarks", "name of the container of all browser bookmarks"));
|
||||
setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks")));
|
||||
tree->expandItem(this);
|
||||
tree->setCurrentItem(this);
|
||||
setSelected(true);
|
||||
}
|
||||
|
||||
KBookmarkTreeItem::KBookmarkTreeItem(QTreeWidgetItem *parent, QTreeWidget *tree, const KBookmarkGroup &bk)
|
||||
: QTreeWidgetItem(parent)
|
||||
{
|
||||
setIcon(0, QIcon::fromTheme(bk.icon()));
|
||||
setText(0, bk.fullText());
|
||||
tree->expandItem(this);
|
||||
m_address = bk.address();
|
||||
}
|
||||
|
||||
KBookmarkTreeItem::~KBookmarkTreeItem()
|
||||
{
|
||||
}
|
||||
|
||||
QString KBookmarkTreeItem::address()
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
#include "moc_kbookmarkdialog.cpp"
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2007 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
#ifndef __kbookmarkdialog_h
|
||||
#define __kbookmarkdialog_h
|
||||
|
||||
#include "kbookmark.h"
|
||||
#include "kbookmarkowner.h"
|
||||
#include <kbookmarkswidgets_export.h>
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
class KBookmarkManager;
|
||||
class KBookmarkDialogPrivate;
|
||||
|
||||
/**
|
||||
* @class KBookmarkDialog kbookmarkdialog.h KBookmarkDialog
|
||||
*
|
||||
* This class provides a Dialog for editing properties, adding Bookmarks and creating new folders.
|
||||
* It can be used to show dialogs for common tasks with bookmarks.
|
||||
*
|
||||
* It is used by KBookmarkMenu to show a dialog for "Properties", "Add Bookmark" and "Create New Folder".
|
||||
* If you want to customize those dialogs, derive from KBookmarkOwner and reimplement bookmarkDialog(),
|
||||
* return a KBookmarkDialog subclass and reimplement initLayout(), aboutToShow() and save().
|
||||
*/
|
||||
class KBOOKMARKSWIDGETS_EXPORT KBookmarkDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a KBookmarkDialog instance
|
||||
*/
|
||||
KBookmarkDialog(KBookmarkManager *manager, QWidget *parent = nullptr);
|
||||
/**
|
||||
* Shows a properties dialog
|
||||
* Note: this updates the bookmark and calls KBookmarkManager::emitChanged
|
||||
*/
|
||||
KBookmark editBookmark(const KBookmark &bm);
|
||||
/**
|
||||
* Shows a "Add Bookmark" dialog
|
||||
* Note: this updates the bookmark and calls KBookmarkManager::emitChanged
|
||||
*/
|
||||
KBookmark addBookmark(const QString &title, const QUrl &url, const QString &icon, KBookmark parent = KBookmark());
|
||||
/**
|
||||
* Creates a folder from a list of bookmarks
|
||||
* Note: this updates the bookmark and calls KBookmarkManager::emitChanged
|
||||
*/
|
||||
KBookmarkGroup addBookmarks(const QList<KBookmarkOwner::FutureBookmark> &list, const QString &name = QString(), KBookmarkGroup parent = KBookmarkGroup());
|
||||
/**
|
||||
* Shows a dialog to create a new folder.
|
||||
*/
|
||||
KBookmarkGroup createNewFolder(const QString &name, KBookmark parent = KBookmark());
|
||||
/**
|
||||
* Shows a dialog to select a folder.
|
||||
*/
|
||||
KBookmarkGroup selectFolder(KBookmark start = KBookmark());
|
||||
|
||||
~KBookmarkDialog() override;
|
||||
|
||||
protected:
|
||||
void accept() override;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void newFolderButton();
|
||||
|
||||
private:
|
||||
std::unique_ptr<KBookmarkDialogPrivate> const d;
|
||||
friend class KBookmarkDialogPrivate;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE libraries
|
||||
SPDX-FileCopyrightText: 2013 Jignesh Kakadiya <jigneshhk1992@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-only
|
||||
*/
|
||||
#ifndef __kbookmarkdialog_p_h__
|
||||
#define __kbookmarkdialog_p_h__
|
||||
|
||||
#include "kbookmark.h"
|
||||
#include "kbookmarkowner.h"
|
||||
#include <QDialog>
|
||||
|
||||
class KBookmarkDialog;
|
||||
class KBookmarkManager;
|
||||
class QDialogButtonBox;
|
||||
class QLabel;
|
||||
class QTreeWidget;
|
||||
class QLineEdit;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
class KBookmarkDialogPrivate
|
||||
{
|
||||
public:
|
||||
explicit KBookmarkDialogPrivate(KBookmarkDialog *qq);
|
||||
~KBookmarkDialogPrivate();
|
||||
|
||||
typedef enum { NewFolder, NewBookmark, EditBookmark, NewMultipleBookmarks, SelectFolder } BookmarkDialogMode;
|
||||
|
||||
void initLayout();
|
||||
void initLayoutPrivate();
|
||||
// selects the specified bookmark in the folder tree
|
||||
void setParentBookmark(const KBookmark &bm);
|
||||
KBookmarkGroup parentBookmark();
|
||||
void fillGroup(QTreeWidgetItem *parentItem, const KBookmarkGroup &group, const KBookmarkGroup &selectGroup = KBookmarkGroup());
|
||||
|
||||
KBookmarkDialog *const q;
|
||||
BookmarkDialogMode mode;
|
||||
QDialogButtonBox *buttonBox = nullptr;
|
||||
QLineEdit *url = nullptr;
|
||||
QLineEdit *title = nullptr;
|
||||
QLineEdit *comment = nullptr;
|
||||
QLabel *titleLabel = nullptr;
|
||||
QLabel *urlLabel = nullptr;
|
||||
QLabel *commentLabel;
|
||||
QString icon;
|
||||
QTreeWidget *folderTree = nullptr;
|
||||
KBookmarkManager *mgr = nullptr;
|
||||
KBookmark bm;
|
||||
QList<KBookmarkOwner::FutureBookmark> list;
|
||||
bool layout;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "kbookmarkmenu.h"
|
||||
#include "kbookmarkmenu_p.h"
|
||||
|
||||
#include "../kbookmarksettings_p.h"
|
||||
#include "kbookmarkaction.h"
|
||||
#include "kbookmarkactionmenu.h"
|
||||
#include "kbookmarkcontextmenu.h"
|
||||
#include "kbookmarkdialog.h"
|
||||
#include "kbookmarkmanager.h"
|
||||
#include "kbookmarkowner.h"
|
||||
#include "kbookmarkswidgets_debug.h"
|
||||
#include "keditbookmarks_p.h"
|
||||
|
||||
#include <KAuthorized>
|
||||
#include <KStandardActions>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardPaths>
|
||||
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
class KBookmarkMenuPrivate
|
||||
{
|
||||
public:
|
||||
QAction *newBookmarkFolderAction = nullptr;
|
||||
QAction *addBookmarkAction = nullptr;
|
||||
QAction *bookmarksToFolderAction = nullptr;
|
||||
QAction *editBookmarksAction = nullptr;
|
||||
bool browserMode = false;
|
||||
bool isRoot;
|
||||
bool dirty;
|
||||
KBookmarkManager *manager;
|
||||
KBookmarkOwner *owner;
|
||||
QMenu *parentMenu;
|
||||
QString parentAddress;
|
||||
};
|
||||
|
||||
KBookmarkMenu::KBookmarkMenu(KBookmarkManager *manager, KBookmarkOwner *_owner, QMenu *_parentMenu)
|
||||
: QObject()
|
||||
, d(new KBookmarkMenuPrivate())
|
||||
{
|
||||
d->isRoot = true;
|
||||
d->manager = manager;
|
||||
d->owner = _owner;
|
||||
d->parentMenu = _parentMenu;
|
||||
d->parentAddress = QString(); // TODO KBookmarkAdress::root
|
||||
// TODO KDE5 find a QMenu equvalnet for this one
|
||||
// m_parentMenu->setKeyboardShortcutsEnabled( true );
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
void KBookmarkMenu::init()
|
||||
{
|
||||
connect(d->parentMenu, &QMenu::aboutToShow, this, &KBookmarkMenu::slotAboutToShow);
|
||||
|
||||
if (KBookmarkSettings::self()->m_contextmenu) {
|
||||
d->parentMenu->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(d->parentMenu, &QWidget::customContextMenuRequested, this, &KBookmarkMenu::slotCustomContextMenu);
|
||||
}
|
||||
|
||||
connect(d->manager, &KBookmarkManager::changed, this, &KBookmarkMenu::slotBookmarksChanged);
|
||||
|
||||
d->dirty = true;
|
||||
addActions();
|
||||
}
|
||||
|
||||
void KBookmarkMenu::addActions()
|
||||
{
|
||||
if (d->isRoot) {
|
||||
addAddBookmark();
|
||||
addAddBookmarksList();
|
||||
addNewFolder();
|
||||
addEditBookmarks();
|
||||
} else {
|
||||
if (!d->parentMenu->actions().isEmpty()) {
|
||||
d->parentMenu->addSeparator();
|
||||
}
|
||||
|
||||
addOpenInTabs();
|
||||
addAddBookmark();
|
||||
addAddBookmarksList();
|
||||
addNewFolder();
|
||||
}
|
||||
}
|
||||
|
||||
KBookmarkMenu::KBookmarkMenu(KBookmarkManager *mgr, KBookmarkOwner *_owner, QMenu *_parentMenu, const QString &parentAddress)
|
||||
: QObject()
|
||||
, d(new KBookmarkMenuPrivate())
|
||||
{
|
||||
d->isRoot = false;
|
||||
d->manager = mgr;
|
||||
d->owner = _owner;
|
||||
d->parentMenu = _parentMenu;
|
||||
d->parentAddress = parentAddress;
|
||||
|
||||
connect(_parentMenu, &QMenu::aboutToShow, this, &KBookmarkMenu::slotAboutToShow);
|
||||
if (KBookmarkSettings::self()->m_contextmenu) {
|
||||
d->parentMenu->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(d->parentMenu, &QWidget::customContextMenuRequested, this, &KBookmarkMenu::slotCustomContextMenu);
|
||||
}
|
||||
d->dirty = true;
|
||||
}
|
||||
|
||||
KBookmarkMenu::~KBookmarkMenu()
|
||||
{
|
||||
qDeleteAll(m_lstSubMenus);
|
||||
qDeleteAll(m_actions);
|
||||
}
|
||||
|
||||
void KBookmarkMenu::ensureUpToDate()
|
||||
{
|
||||
slotAboutToShow();
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotAboutToShow()
|
||||
{
|
||||
// Did the bookmarks change since the last time we showed them ?
|
||||
if (d->dirty) {
|
||||
d->dirty = false;
|
||||
clear();
|
||||
refill();
|
||||
d->parentMenu->adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotCustomContextMenu(const QPoint &pos)
|
||||
{
|
||||
QAction *action = d->parentMenu->actionAt(pos);
|
||||
QMenu *menu = contextMenu(action);
|
||||
if (!menu) {
|
||||
return;
|
||||
}
|
||||
menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
menu->popup(d->parentMenu->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
QMenu *KBookmarkMenu::contextMenu(QAction *action)
|
||||
{
|
||||
KBookmarkActionInterface *act = dynamic_cast<KBookmarkActionInterface *>(action);
|
||||
if (!act) {
|
||||
return nullptr;
|
||||
}
|
||||
return new KBookmarkContextMenu(act->bookmark(), d->manager, d->owner);
|
||||
}
|
||||
|
||||
bool KBookmarkMenu::isRoot() const
|
||||
{
|
||||
return d->isRoot;
|
||||
}
|
||||
|
||||
bool KBookmarkMenu::isDirty() const
|
||||
{
|
||||
return d->dirty;
|
||||
}
|
||||
|
||||
QString KBookmarkMenu::parentAddress() const
|
||||
{
|
||||
return d->parentAddress;
|
||||
}
|
||||
|
||||
KBookmarkManager *KBookmarkMenu::manager() const
|
||||
{
|
||||
return d->manager;
|
||||
}
|
||||
|
||||
KBookmarkOwner *KBookmarkMenu::owner() const
|
||||
{
|
||||
return d->owner;
|
||||
}
|
||||
|
||||
QMenu *KBookmarkMenu::parentMenu() const
|
||||
{
|
||||
return d->parentMenu;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
|
||||
void KBookmarkMenu::slotBookmarksChanged(const QString &groupAddress)
|
||||
{
|
||||
qCDebug(KBOOKMARKSWIDGETS_LOG) << "KBookmarkMenu::slotBookmarksChanged groupAddress: " << groupAddress;
|
||||
if (groupAddress == d->parentAddress) {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotBookmarksChanged -> setting m_bDirty on " << groupAddress;
|
||||
d->dirty = true;
|
||||
} else {
|
||||
// Iterate recursively into child menus
|
||||
for (QList<KBookmarkMenu *>::iterator it = m_lstSubMenus.begin(), end = m_lstSubMenus.end(); it != end; ++it) {
|
||||
(*it)->slotBookmarksChanged(groupAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMenu::clear()
|
||||
{
|
||||
qDeleteAll(m_lstSubMenus);
|
||||
m_lstSubMenus.clear();
|
||||
|
||||
for (QList<QAction *>::iterator it = m_actions.begin(), end = m_actions.end(); it != end; ++it) {
|
||||
d->parentMenu->removeAction(*it);
|
||||
delete *it;
|
||||
}
|
||||
|
||||
d->parentMenu->clear();
|
||||
m_actions.clear();
|
||||
}
|
||||
|
||||
void KBookmarkMenu::refill()
|
||||
{
|
||||
// qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::refill()";
|
||||
if (d->isRoot) {
|
||||
addActions();
|
||||
}
|
||||
fillBookmarks();
|
||||
if (!d->isRoot) {
|
||||
addActions();
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMenu::addOpenInTabs()
|
||||
{
|
||||
if (!d->owner || !d->owner->supportsTabs() || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString title = tr("Open Folder in Tabs", "@action:inmenu");
|
||||
|
||||
QAction *paOpenFolderInTabs = new QAction(title, this);
|
||||
paOpenFolderInTabs->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
|
||||
paOpenFolderInTabs->setToolTip(tr("Open all bookmarks in this folder as a new tab", "@info:tooltip"));
|
||||
paOpenFolderInTabs->setStatusTip(paOpenFolderInTabs->toolTip());
|
||||
connect(paOpenFolderInTabs, &QAction::triggered, this, &KBookmarkMenu::slotOpenFolderInTabs);
|
||||
|
||||
d->parentMenu->addAction(paOpenFolderInTabs);
|
||||
m_actions.append(paOpenFolderInTabs);
|
||||
}
|
||||
|
||||
void KBookmarkMenu::addAddBookmarksList()
|
||||
{
|
||||
if (!d->owner || !d->owner->enableOption(KBookmarkOwner::ShowAddBookmark) || !d->owner->supportsTabs()
|
||||
|| !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->bookmarksToFolderAction) {
|
||||
const QString title = tr("Bookmark Tabs as Folder…", "@action:inmenu");
|
||||
d->bookmarksToFolderAction = new QAction(title, this);
|
||||
|
||||
if (d->isRoot) {
|
||||
d->bookmarksToFolderAction->setObjectName(QStringLiteral("add_bookmarks_list"));
|
||||
}
|
||||
|
||||
d->bookmarksToFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new-list")));
|
||||
d->bookmarksToFolderAction->setToolTip(tr("Add a folder of bookmarks for all open tabs", "@info:tooltip"));
|
||||
d->bookmarksToFolderAction->setStatusTip(d->bookmarksToFolderAction->toolTip());
|
||||
connect(d->bookmarksToFolderAction, &QAction::triggered, this, &KBookmarkMenu::slotAddBookmarksList);
|
||||
}
|
||||
|
||||
d->parentMenu->addAction(d->bookmarksToFolderAction);
|
||||
}
|
||||
|
||||
void KBookmarkMenu::addAddBookmark()
|
||||
{
|
||||
if (!d->owner || !d->owner->enableOption(KBookmarkOwner::ShowAddBookmark) || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->addBookmarkAction) {
|
||||
d->addBookmarkAction = KStandardActions::addBookmark(this, &KBookmarkMenu::slotAddBookmark, this);
|
||||
if (d->isRoot) {
|
||||
d->addBookmarkAction->setObjectName(QStringLiteral("add_bookmark"));
|
||||
}
|
||||
|
||||
if (!d->isRoot) {
|
||||
d->addBookmarkAction->setShortcut(QKeySequence());
|
||||
}
|
||||
}
|
||||
|
||||
d->parentMenu->addAction(d->addBookmarkAction);
|
||||
}
|
||||
|
||||
void KBookmarkMenu::addEditBookmarks()
|
||||
{
|
||||
if ((d->owner && !d->owner->enableOption(KBookmarkOwner::ShowEditBookmark))
|
||||
|| QStandardPaths::findExecutable(QStringLiteral(KEDITBOOKMARKS_BINARY)).isEmpty() || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->editBookmarksAction = KStandardActions::editBookmarks(this, &KBookmarkMenu::slotEditBookmarks, this);
|
||||
d->editBookmarksAction->setObjectName(QStringLiteral("edit_bookmarks"));
|
||||
|
||||
d->parentMenu->addAction(d->editBookmarksAction);
|
||||
d->editBookmarksAction->setToolTip(tr("Edit your bookmark collection in a separate window", "@info:tooltip"));
|
||||
d->editBookmarksAction->setStatusTip(d->editBookmarksAction->toolTip());
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotEditBookmarks()
|
||||
{
|
||||
KEditBookmarks editBookmarks;
|
||||
editBookmarks.setBrowserMode(d->browserMode);
|
||||
auto result = editBookmarks.openForFile(d->manager->path());
|
||||
|
||||
if (!result.sucess()) {
|
||||
QMessageBox::critical(QApplication::activeWindow(), QApplication::applicationDisplayName(), result.errorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMenu::addNewFolder()
|
||||
{
|
||||
if (!d->owner || !d->owner->enableOption(KBookmarkOwner::ShowAddBookmark) || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->newBookmarkFolderAction) {
|
||||
d->newBookmarkFolderAction = new QAction(tr("New Bookmark Folder…", "@action:inmenu"), this);
|
||||
d->newBookmarkFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new")));
|
||||
d->newBookmarkFolderAction->setToolTip(tr("Create a new bookmark folder in this menu", "@info:tooltip"));
|
||||
d->newBookmarkFolderAction->setStatusTip(d->newBookmarkFolderAction->toolTip());
|
||||
|
||||
if (d->isRoot) {
|
||||
d->newBookmarkFolderAction->setObjectName(QStringLiteral("new_bookmark_folder"));
|
||||
}
|
||||
|
||||
connect(d->newBookmarkFolderAction, &QAction::triggered, this, &KBookmarkMenu::slotNewFolder);
|
||||
}
|
||||
|
||||
d->parentMenu->addAction(d->newBookmarkFolderAction);
|
||||
}
|
||||
|
||||
void KBookmarkMenu::fillBookmarks()
|
||||
{
|
||||
KBookmarkGroup parentBookmark = d->manager->findByAddress(d->parentAddress).toGroup();
|
||||
Q_ASSERT(!parentBookmark.isNull());
|
||||
|
||||
if (d->isRoot && !parentBookmark.first().isNull()) { // at least one bookmark
|
||||
d->parentMenu->addSeparator();
|
||||
}
|
||||
|
||||
for (KBookmark bm = parentBookmark.first(); !bm.isNull(); bm = parentBookmark.next(bm)) {
|
||||
d->parentMenu->addAction(actionForBookmark(bm));
|
||||
}
|
||||
}
|
||||
|
||||
QAction *KBookmarkMenu::actionForBookmark(const KBookmark &bm)
|
||||
{
|
||||
if (bm.isGroup()) {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "Creating bookmark submenu named " << bm.text();
|
||||
KActionMenu *actionMenu = new KBookmarkActionMenu(bm, this);
|
||||
m_actions.append(actionMenu);
|
||||
KBookmarkMenu *subMenu = new KBookmarkMenu(d->manager, d->owner, actionMenu->menu(), bm.address());
|
||||
m_lstSubMenus.append(subMenu);
|
||||
return actionMenu;
|
||||
} else if (bm.isSeparator()) {
|
||||
QAction *sa = new QAction(this);
|
||||
sa->setSeparator(true);
|
||||
m_actions.append(sa);
|
||||
return sa;
|
||||
} else {
|
||||
// qCDebug(KBOOKMARKS_LOG) << "Creating bookmark menu item for " << bm.text();
|
||||
QAction *action = new KBookmarkAction(bm, d->owner, this);
|
||||
m_actions.append(action);
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotAddBookmarksList()
|
||||
{
|
||||
if (!d->owner || !d->owner->supportsTabs()) {
|
||||
return;
|
||||
}
|
||||
|
||||
KBookmarkGroup parentBookmark = d->manager->findByAddress(d->parentAddress).toGroup();
|
||||
|
||||
KBookmarkDialog *dlg = new KBookmarkDialog(d->manager, QApplication::activeWindow());
|
||||
dlg->addBookmarks(d->owner->currentBookmarkList(), QLatin1String(""), parentBookmark);
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotAddBookmark()
|
||||
{
|
||||
if (!d->owner) {
|
||||
return;
|
||||
}
|
||||
if (d->owner->currentTitle().isEmpty() && d->owner->currentUrl().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
KBookmarkGroup parentBookmark = d->manager->findByAddress(d->parentAddress).toGroup();
|
||||
|
||||
if (KBookmarkSettings::self()->m_advancedaddbookmark) {
|
||||
KBookmarkDialog *dlg = new KBookmarkDialog(d->manager, QApplication::activeWindow());
|
||||
dlg->addBookmark(d->owner->currentTitle(), d->owner->currentUrl(), d->owner->currentIcon(), parentBookmark);
|
||||
delete dlg;
|
||||
} else {
|
||||
parentBookmark.addBookmark(d->owner->currentTitle(), d->owner->currentUrl(), d->owner->currentIcon());
|
||||
d->manager->emitChanged(parentBookmark);
|
||||
}
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotOpenFolderInTabs()
|
||||
{
|
||||
d->owner->openFolderinTabs(d->manager->findByAddress(d->parentAddress).toGroup());
|
||||
}
|
||||
|
||||
void KBookmarkMenu::slotNewFolder()
|
||||
{
|
||||
if (!d->owner) {
|
||||
return; // this view doesn't handle bookmarks...
|
||||
}
|
||||
KBookmarkGroup parentBookmark = d->manager->findByAddress(d->parentAddress).toGroup();
|
||||
Q_ASSERT(!parentBookmark.isNull());
|
||||
KBookmarkDialog *dlg = new KBookmarkDialog(d->manager, QApplication::activeWindow());
|
||||
dlg->createNewFolder(QLatin1String(""), parentBookmark);
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
QAction *KBookmarkMenu::addBookmarkAction() const
|
||||
{
|
||||
return d->addBookmarkAction;
|
||||
}
|
||||
|
||||
QAction *KBookmarkMenu::bookmarkTabsAsFolderAction() const
|
||||
{
|
||||
return d->bookmarksToFolderAction;
|
||||
}
|
||||
|
||||
QAction *KBookmarkMenu::newBookmarkFolderAction() const
|
||||
{
|
||||
return d->newBookmarkFolderAction;
|
||||
}
|
||||
|
||||
QAction *KBookmarkMenu::editBookmarksAction() const
|
||||
{
|
||||
return d->editBookmarksAction;
|
||||
}
|
||||
|
||||
void KBookmarkMenu::setBrowserMode(bool browserMode)
|
||||
{
|
||||
d->browserMode = browserMode;
|
||||
}
|
||||
|
||||
bool KBookmarkMenu::browserMode() const
|
||||
{
|
||||
return d->browserMode;
|
||||
}
|
||||
|
||||
#include "moc_kbookmarkmenu.cpp"
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
|
||||
SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef __kbookmarkmenu_h__
|
||||
#define __kbookmarkmenu_h__
|
||||
|
||||
#include <kbookmarkswidgets_export.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class KBookmark;
|
||||
class KBookmarkManager;
|
||||
class KBookmarkOwner;
|
||||
class KBookmarkMenu;
|
||||
|
||||
class KBookmarkMenuPrivate;
|
||||
|
||||
/**
|
||||
* @class KBookmarkMenu kbookmarkmenu.h KBookmarkMenu
|
||||
*
|
||||
* This class provides a bookmark menu. It is typically used in
|
||||
* cooperation with KActionMenu but doesn't have to be.
|
||||
*
|
||||
* If you use this class by itself, then it will use KDE defaults for
|
||||
* everything -- the bookmark path, bookmark editor, bookmark launcher..
|
||||
* everything. These defaults reside in the classes
|
||||
* KBookmarkOwner (editing bookmarks) and KBookmarkManager
|
||||
* (almost everything else). If you wish to change the defaults in
|
||||
* any way, you must reimplement either this class or KBookmarkOwner.
|
||||
*
|
||||
* Using this class is very simple:
|
||||
*
|
||||
* 1) Create a popup menu (either KActionMenu or QMenu will do)
|
||||
* 2) Instantiate a new KBookmarkMenu object using the above popup
|
||||
* menu as a parameter
|
||||
* 3) Insert your (now full) popup menu wherever you wish
|
||||
*
|
||||
* The functionality of this class can be disabled with the "action/bookmarks"
|
||||
* Kiosk action (see the KAuthorized namespace).
|
||||
*/
|
||||
class KBOOKMARKSWIDGETS_EXPORT KBookmarkMenu : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Fills a bookmark menu
|
||||
* (one instance of KBookmarkMenu is created for the toplevel menu,
|
||||
* but also one per submenu).
|
||||
*
|
||||
* @param manager the bookmark manager to use (i.e. for reading and writing)
|
||||
* @param owner implementation of the KBookmarkOwner callback interface.
|
||||
* @note If you pass a null KBookmarkOwner to the constructor, the
|
||||
* openBookmark signal is not emitted, instead QDesktopServices::openUrl is used to open the bookmark.
|
||||
* @param parentMenu menu to be filled
|
||||
* @since 5.69
|
||||
*/
|
||||
KBookmarkMenu(KBookmarkManager *manager, KBookmarkOwner *owner, QMenu *parentMenu);
|
||||
|
||||
/**
|
||||
* Creates a bookmark submenu
|
||||
*
|
||||
* @todo KF6: give ownership of the bookmarkmenu to another qobject, e.g. parentMenu.
|
||||
* Currently this is a QObject without a parent, use setParent to benefit from automatic deletion.
|
||||
*/
|
||||
KBookmarkMenu(KBookmarkManager *mgr, KBookmarkOwner *owner, QMenu *parentMenu, const QString &parentAddress);
|
||||
|
||||
~KBookmarkMenu() override;
|
||||
|
||||
/**
|
||||
* Call ensureUpToDate() if you need KBookmarkMenu to adjust to its
|
||||
* final size before it is executed.
|
||||
**/
|
||||
void ensureUpToDate();
|
||||
|
||||
/**
|
||||
* Returns the action for adding a bookmark. If you are using KXmlGui, you can add it to your
|
||||
* action collection.
|
||||
* @code
|
||||
* KBookmarkMenu *menu = new KBookmarkMenu(manager, owner, parentMenu);
|
||||
* QAction *addAction = menu->addBookmarkAction();
|
||||
* actionCollection()->addAction(addAction->objectName(), addAction);
|
||||
* @endcode
|
||||
* @return the action for adding a bookmark.
|
||||
* @since 5.69
|
||||
*/
|
||||
QAction *addBookmarkAction() const;
|
||||
|
||||
/**
|
||||
* Returns the action for adding all current tabs as bookmarks. If you are using KXmlGui, you can
|
||||
* add it to your action collection.
|
||||
* @code
|
||||
* KBookmarkMenu *menu = new KBookmarkMenu(manager, owner, parentMenu);
|
||||
* QAction *bookmarkTabsAction = menu->bookmarkTabsAsFolderAction();
|
||||
* actionCollection()->addAction(bookmarkTabsAction->objectName(), bookmarkTabsAction);
|
||||
* @endcode
|
||||
* @return the action for adding all current tabs as bookmarks.
|
||||
* @since 5.69
|
||||
*/
|
||||
QAction *bookmarkTabsAsFolderAction() const;
|
||||
|
||||
/**
|
||||
* Returns the action for adding a new bookmarks folder. If you are using KXmlGui, you can add it
|
||||
* to your action collection.
|
||||
* @code
|
||||
* KBookmarkMenu *menu = new KBookmarkMenu(manager, owner, parentMenu);
|
||||
* QAction *newBookmarkFolderAction = menu->bookmarkTabsAsFolderAction();
|
||||
* actionCollection()->addAction(newBookmarkFolderAction->objectName(), newBookmarkFolderAction);
|
||||
* @endcode
|
||||
* @return the action for adding a new bookmarks folder
|
||||
* @since 5.70
|
||||
*/
|
||||
QAction *newBookmarkFolderAction() const;
|
||||
|
||||
/**
|
||||
* Returns the action for editing bookmarks. If you are using KXmlGui, you can add it to your
|
||||
* action collection.
|
||||
* @code
|
||||
* KBookmarkMenu *menu = new KBookmarkMenu(manager, owner, parentMenu);
|
||||
* QAction *editAction = menu->editBookmarksAction();
|
||||
* actionCollection()->addAction(editAction->objectName(), editAction);
|
||||
* @endcode
|
||||
* @return the action for editing bookmarks.
|
||||
* @since 5.69
|
||||
*/
|
||||
QAction *editBookmarksAction() const;
|
||||
|
||||
/**
|
||||
* Set this to true to make any "Edit Bookmarks" dialog
|
||||
* show UI elements that are specific to browsers.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
void setBrowserMode(bool browserMode);
|
||||
|
||||
/**
|
||||
* Whether any "Edit Bookmarks" dialog shows UI elements
|
||||
* that are specific to browsers.
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
bool browserMode() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
// public for KonqBookmarkBar
|
||||
void slotBookmarksChanged(const QString &);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void slotAboutToShow();
|
||||
void slotAddBookmarksList();
|
||||
void slotAddBookmark();
|
||||
void slotNewFolder();
|
||||
void slotOpenFolderInTabs();
|
||||
|
||||
protected:
|
||||
virtual void clear();
|
||||
virtual void refill();
|
||||
virtual QAction *actionForBookmark(const KBookmark &bm);
|
||||
virtual QMenu *contextMenu(QAction *action);
|
||||
|
||||
void addActions();
|
||||
void fillBookmarks();
|
||||
void addAddBookmark();
|
||||
void addAddBookmarksList();
|
||||
void addEditBookmarks();
|
||||
void addNewFolder();
|
||||
void addOpenInTabs();
|
||||
|
||||
bool isRoot() const;
|
||||
bool isDirty() const;
|
||||
|
||||
/**
|
||||
* Parent bookmark for this menu.
|
||||
*/
|
||||
QString parentAddress() const;
|
||||
|
||||
KBookmarkManager *manager() const;
|
||||
KBookmarkOwner *owner() const;
|
||||
/**
|
||||
* The menu in which we insert our actions
|
||||
* Supplied in the constructor.
|
||||
*/
|
||||
QMenu *parentMenu() const;
|
||||
|
||||
/**
|
||||
* List of our sub menus
|
||||
*/
|
||||
QList<KBookmarkMenu *> m_lstSubMenus;
|
||||
|
||||
/**
|
||||
* List of our actions.
|
||||
*/
|
||||
QList<QAction *> m_actions;
|
||||
|
||||
private Q_SLOTS:
|
||||
KBOOKMARKSWIDGETS_NO_EXPORT void slotCustomContextMenu(const QPoint &);
|
||||
|
||||
private:
|
||||
void slotEditBookmarks();
|
||||
KBOOKMARKSWIDGETS_NO_EXPORT void init();
|
||||
|
||||
private:
|
||||
std::unique_ptr<KBookmarkMenuPrivate> const d;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
// -*- c-basic-offset:4; indent-tabs-mode:nil -*-
|
||||
/*
|
||||
This file is part of the KDE project
|
||||
SPDX-FileCopyrightText: 2003 Alexander Kellett <lypanov@kde.org>
|
||||
|
||||
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef __kbookmarkmenu_p_h__
|
||||
#define __kbookmarkmenu_p_h__
|
||||
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "kbookmark.h"
|
||||
|
||||
class QString;
|
||||
class KBookmark;
|
||||
class KBookmarkGroup;
|
||||
|
||||
class KBookmarkTreeItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
explicit KBookmarkTreeItem(QTreeWidget *tree);
|
||||
KBookmarkTreeItem(QTreeWidgetItem *parent, QTreeWidget *tree, const KBookmarkGroup &bk);
|
||||
~KBookmarkTreeItem() override;
|
||||
QString address();
|
||||
|
||||
private:
|
||||
QString m_address;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user