diff --git a/src/modules/connections-tree/items/databaseitem.cpp b/src/modules/connections-tree/items/databaseitem.cpp index 712a35c29..75d42af09 100644 --- a/src/modules/connections-tree/items/databaseitem.cpp +++ b/src/modules/connections-tree/items/databaseitem.cpp @@ -98,12 +98,6 @@ QString DatabaseItem::getDisplayName() const .arg(liveUpdate); } -QString DatabaseItem::getIconUrl() const -{ - if (isLocked()) return QString("qrc:/images/wait.svg"); - return QString("qrc:/images/db.svg"); -} - bool DatabaseItem::isEnabled() const {return true;} void DatabaseItem::notifyModel() @@ -141,20 +135,16 @@ void DatabaseItem::loadKeys(std::function callback) if (callback) { callback(); - } else { - emit m_model.itemChanged(getSelf()); } }); } -QVariant DatabaseItem::metadata(const QString &key) +QVariantMap DatabaseItem::metadata() const { - if (key == "filter") - return m_filter.pattern(); - if (key == "live_update") - return m_liveUpdateTimer.isActive(); - - return QVariant(); + QVariantMap metadata = TreeItem::metadata(); + metadata["filter"] = m_filter.pattern(); + metadata["live_update"] = m_liveUpdateTimer.isActive(); + return metadata; } void DatabaseItem::setMetadata(const QString &key, QVariant value) @@ -194,8 +184,7 @@ void DatabaseItem::unload() m_operations->notifyDbWasUnloaded(m_dbIndex); - unlock(); - emit m_model.itemChanged(getSelf()); + unlock(); } void DatabaseItem::reload() diff --git a/src/modules/connections-tree/items/databaseitem.h b/src/modules/connections-tree/items/databaseitem.h index 1dacf7f76..34defab3d 100644 --- a/src/modules/connections-tree/items/databaseitem.h +++ b/src/modules/connections-tree/items/databaseitem.h @@ -22,11 +22,7 @@ class DatabaseItem : public QObject, public AbstractNamespaceItem QString getDisplayName() const override; - QString getIconUrl() const override; - - QString getType() const override { return "database"; } - - int itemDepth() const override { return 1; } + QString getType() const override { return "database"; } bool isEnabled() const override; @@ -34,9 +30,9 @@ class DatabaseItem : public QObject, public AbstractNamespaceItem void loadKeys(std::function callback=std::function()); - void unload(); + void unload(); - QVariant metadata(const QString&) override; + QVariantMap metadata() const override; void setMetadata(const QString&, QVariant) override; diff --git a/src/modules/connections-tree/items/keyitem.cpp b/src/modules/connections-tree/items/keyitem.cpp index 3ff557aab..ee53eec8d 100644 --- a/src/modules/connections-tree/items/keyitem.cpp +++ b/src/modules/connections-tree/items/keyitem.cpp @@ -3,6 +3,7 @@ #include #include +#include "connections-tree/model.h" #include "connections-tree/utils.h" using namespace ConnectionsTree; @@ -48,11 +49,6 @@ QByteArray KeyItem::getName() const return m_fullPath; } -QString KeyItem::getIconUrl() const -{ - return QString("qrc:/images/key.svg"); -} - QList> KeyItem::getAllChilds() const { return QList>(); @@ -100,4 +96,6 @@ int KeyItem::getDbIndex() const void KeyItem::setRemoved() { m_removed = true; + + emit m_model.itemChanged(getSelf()); } diff --git a/src/modules/connections-tree/items/keyitem.h b/src/modules/connections-tree/items/keyitem.h index f172c57fe..03b67370e 100644 --- a/src/modules/connections-tree/items/keyitem.h +++ b/src/modules/connections-tree/items/keyitem.h @@ -16,13 +16,9 @@ class KeyItem : public TreeItem QString getDisplayName() const override; - QByteArray getName() const override; + QByteArray getName() const override; - QString getIconUrl() const override; - - QString getType() const override { return "key"; } - - int itemDepth() const override { return m_fullPath.count(m_operations->getNamespaceSeparator().toUtf8()) + 2; } + QString getType() const override { return "key"; } QList> getAllChilds() const override; diff --git a/src/modules/connections-tree/items/namespaceitem.cpp b/src/modules/connections-tree/items/namespaceitem.cpp index f433efe97..6cdf592c2 100644 --- a/src/modules/connections-tree/items/namespaceitem.cpp +++ b/src/modules/connections-tree/items/namespaceitem.cpp @@ -19,32 +19,26 @@ NamespaceItem::NamespaceItem(const QByteArray &fullPath, m_displayName = m_fullPath.mid(m_fullPath.lastIndexOf(m_operations->getNamespaceSeparator()) + 1); m_eventHandlers.insert("click", [this]() { - - if (m_childItems.size() == 0) { - QString nsFilter = QString("%1%2*").arg(QString::fromUtf8(m_fullPath)).arg(m_operations->getNamespaceSeparator()); - - qDebug() << "NS Filter" << nsFilter; - + if (m_childItems.size() == 0) { lock(); - emit m_model.itemChanged(getSelf()); - - m_operations->loadNamespaceItems(qSharedPointerDynamicCast(getSelf()), - nsFilter, [this](const QString& err) { - unlock(); - if (!err.isEmpty()) - return showLoadingError(err); - - setExpanded(true); - emit m_model.itemChanged(getSelf()); - emit m_model.expandItem(getSelf()); - }); - } else { + load(); + } else if (!isExpanded()) { setExpanded(true); emit m_model.itemChanged(getSelf()); emit m_model.expandItem(getSelf()); } }); + m_eventHandlers.insert("reload", [this]() { + lock(); + + if (m_childItems.size()) { + clear(); + } + + load(); + }); + m_eventHandlers.insert("delete", [this]() { m_operations->deleteDbNamespace(*this); }); @@ -60,16 +54,6 @@ QByteArray NamespaceItem::getName() const return m_displayName; } -QString NamespaceItem::getIconUrl() const -{ - if (isLocked()) return QString("qrc:/images/wait.svg"); - return QString("qrc:/images/namespace.svg"); -} - -int NamespaceItem::itemDepth() const { - return m_fullPath.count(m_operations->getNamespaceSeparator().toUtf8()) + 2; -} - bool NamespaceItem::isEnabled() const { return m_removed == false; @@ -82,5 +66,25 @@ QByteArray NamespaceItem::getFullPath() const void NamespaceItem::setRemoved() { - m_removed = true; + m_removed = true; + + clear(); + + emit m_model.itemChanged(getSelf()); +} + +void NamespaceItem::load() +{ + QString nsFilter = QString("%1%2*").arg(QString::fromUtf8(m_fullPath)).arg(m_operations->getNamespaceSeparator()); + + m_operations->loadNamespaceItems(qSharedPointerDynamicCast(getSelf()), + nsFilter, [this](const QString& err) { + unlock(); + if (!err.isEmpty()) + return showLoadingError(err); + + setExpanded(true); + emit m_model.itemChanged(getSelf()); + emit m_model.expandItem(getSelf()); + }); } diff --git a/src/modules/connections-tree/items/namespaceitem.h b/src/modules/connections-tree/items/namespaceitem.h index 625599a17..ce17e4c5b 100644 --- a/src/modules/connections-tree/items/namespaceitem.h +++ b/src/modules/connections-tree/items/namespaceitem.h @@ -20,16 +20,15 @@ class NamespaceItem : public QObject, public AbstractNamespaceItem QByteArray getFullPath() const; - QString getIconUrl() const override; - - QString getType() const override { return "namespace"; } - - int itemDepth() const override; + QString getType() const override { return "namespace"; } bool isEnabled() const override; void setRemoved(); +protected: + void load(); + private: QByteArray m_fullPath; QByteArray m_displayName; diff --git a/src/modules/connections-tree/items/serveritem.cpp b/src/modules/connections-tree/items/serveritem.cpp index 551e5f7ca..de570149d 100644 --- a/src/modules/connections-tree/items/serveritem.cpp +++ b/src/modules/connections-tree/items/serveritem.cpp @@ -72,21 +72,6 @@ QString ServerItem::getDisplayName() const return m_name; } -QString ServerItem::getIconUrl() const -{ - if (isLocked()) return QString("qrc:/images/wait.svg"); - if (isDatabaseListLoaded()) { - if (m_operations->mode() == "cluster") { - return QString("qrc:/images/cluster.svg"); - } else if (m_operations->mode() == "sentinel") { - return QString("qrc:/images/sentinel.svg"); - } else { - return QString("qrc:/images/server.svg"); - } - } - return QString("qrc:/images/server_offline.svg"); -} - QList > ServerItem::getAllChilds() const { return m_databases; @@ -133,8 +118,7 @@ bool ServerItem::isDatabaseListLoaded() const void ServerItem::load() { - lock(); - emit m_model.itemChanged(m_self); + lock(); std::function callback = [this](RedisClient::DatabaseList databases) { @@ -154,15 +138,13 @@ void ServerItem::load() emit m_model.itemChildsLoaded(m_self); - unlock(); - emit m_model.itemChanged(m_self); + unlock(); }; try { m_operations->getDatabases(callback); } catch (const ConnectionsTree::Operations::Exception& e) { - unlock(); - emit m_model.itemChanged(m_self); + unlock(); emit m_model.error(QObject::tr("Cannot load databases:\n\n") + QString(e.what())); } } @@ -214,3 +196,16 @@ void ServerItem::setWeakPointer(QWeakPointer self) { m_self = self; } + +QVariantMap ConnectionsTree::ServerItem::metadata() const +{ + QVariantMap meta = TreeItem::metadata(); + + if (isDatabaseListLoaded()) { + meta["server_type"] = m_operations->mode(); + } else { + meta["server_type"] = "unknown"; + } + + return meta; +} diff --git a/src/modules/connections-tree/items/serveritem.h b/src/modules/connections-tree/items/serveritem.h index 59776a4c1..8f41a1dd4 100644 --- a/src/modules/connections-tree/items/serveritem.h +++ b/src/modules/connections-tree/items/serveritem.h @@ -18,13 +18,11 @@ class ServerItem : public QObject, public TreeItem ~ServerItem(); - QString getDisplayName() const override; + QString getDisplayName() const override; - QString getIconUrl() const override; + QString getType() const override { return "server"; } - QString getType() const override { return "server"; } - - int itemDepth() const override { return 0; } + QVariantMap metadata() const; QList> getAllChilds() const override; diff --git a/src/modules/connections-tree/items/treeitem.cpp b/src/modules/connections-tree/items/treeitem.cpp index 1399d0b7a..4efedf462 100644 --- a/src/modules/connections-tree/items/treeitem.cpp +++ b/src/modules/connections-tree/items/treeitem.cpp @@ -7,6 +7,25 @@ ConnectionsTree::TreeItem::TreeItem(Model &m) } +QVariant ConnectionsTree::TreeItem::metadata(const QString &key) const +{ + if (!metadata().contains(key)) + return QVariant(); + + return metadata()[key]; +} + +QVariantMap ConnectionsTree::TreeItem::metadata() const +{ + QVariantMap meta; + meta["name"] = getDisplayName(); + meta["full_name"] = getName(); + meta["type"] = getType(); + meta["locked"] = isLocked(); + meta["state"] = isEnabled(); + return meta; +} + int ConnectionsTree::TreeItem::row() const { if (!parent()) @@ -49,11 +68,13 @@ ConnectionsTree::Model &ConnectionsTree::TreeItem::model() void ConnectionsTree::TreeItem::lock() { m_locked = true; + emit m_model.itemChanged(getSelf()); } void ConnectionsTree::TreeItem::unlock() { m_locked = false; + emit m_model.itemChanged(getSelf()); } void ConnectionsTree::TreeItem::handleEvent(QString event) diff --git a/src/modules/connections-tree/items/treeitem.h b/src/modules/connections-tree/items/treeitem.h index 393fd0316..ba35eea91 100644 --- a/src/modules/connections-tree/items/treeitem.h +++ b/src/modules/connections-tree/items/treeitem.h @@ -28,11 +28,7 @@ class TreeItem { virtual QByteArray getFullPath() const { return QByteArray(); } - virtual QString getIconUrl() const = 0; - - virtual QString getType() const = 0; - - virtual int itemDepth() const = 0; + virtual QString getType() const = 0; virtual QList> getAllChilds() const = 0; @@ -44,7 +40,9 @@ class TreeItem { virtual bool supportChildItems() const { return true; } - virtual QVariant metadata(const QString&) { return QVariant(); } + virtual QVariant metadata(const QString& key) const; + + virtual QVariantMap metadata() const; virtual void setMetadata(const QString&, QVariant) {} diff --git a/src/modules/connections-tree/model.cpp b/src/modules/connections-tree/model.cpp index 0b4a74aa6..ac0ef67a4 100644 --- a/src/modules/connections-tree/model.cpp +++ b/src/modules/connections-tree/model.cpp @@ -28,13 +28,10 @@ QVariant Model::data(const QModelIndex &index, int role) const return QVariant(); switch (role) { - case itemName: return item->getDisplayName(); - case Qt::DecorationRole: return item->getIconUrl(); - case itemType: return item->getType(); - case itemOriginalName: return item->getName(); - case itemIsInitiallyExpanded: return item->isExpanded(); - case itemDepth: return item->itemDepth(); - case itemState: return item->isEnabled(); + case itemName: return item->getDisplayName(); + case itemType: return item->getType(); + case itemIsInitiallyExpanded: return item->isExpanded(); + case itemMetaData: return item->metadata(); } return QVariant(); @@ -43,12 +40,9 @@ QVariant Model::data(const QModelIndex &index, int role) const QHash Model::roleNames() const { QHash roles; - roles[itemName] = "name"; - roles[itemType] = "type"; + roles[itemName] = "name"; roles[itemIsInitiallyExpanded] = "expanded"; - roles[Qt::DecorationRole] = "icon"; - roles[itemState] = "state"; - roles[itemDepth] = "depth"; + roles[itemMetaData] = "metadata"; return roles; } @@ -229,17 +223,6 @@ void Model::onExpandItem(QWeakPointer item) emit expand(index); } - -QVariant Model::getItemData(const QModelIndex &index, const QString& dataKey) -{ - QList result = roleNames().keys(dataKey.toLatin1()); - - if (result.size() == 0) - return QVariant(); - - return data(index, result[0]); -} - QVariant Model::getMetadata(const QModelIndex &index, const QString &metaKey) { TreeItem *item = getItemFromIndex(index); diff --git a/src/modules/connections-tree/model.h b/src/modules/connections-tree/model.h index 2fc4e5b90..ef9680b47 100644 --- a/src/modules/connections-tree/model.h +++ b/src/modules/connections-tree/model.h @@ -17,13 +17,10 @@ namespace ConnectionsTree { Q_OBJECT public: enum Roles { - itemName = Qt::UserRole + 1, - itemOriginalName, - itemType, - itemFullPath, - itemIsInitiallyExpanded, - itemDepth, - itemState + itemName = Qt::UserRole + 1, + itemType, + itemIsInitiallyExpanded, + itemMetaData, }; public: @@ -97,9 +94,7 @@ namespace ConnectionsTree { void onExpandItem(QWeakPointer item); - public slots: - QVariant getItemData(const QModelIndex &index, const QString& dataKey); - + public slots: QVariant getMetadata(const QModelIndex &index, const QString& metaKey); void setMetadata(const QModelIndex &index, const QString& metaKey, QVariant value); diff --git a/src/qml/common/ImageButton.qml b/src/qml/common/ImageButton.qml index 18abce18c..2d21f5d35 100644 --- a/src/qml/common/ImageButton.qml +++ b/src/qml/common/ImageButton.qml @@ -1,14 +1,17 @@ -import QtQuick 2.0 +import QtQuick 2.9 +import QtQuick.Controls 2.2 + +Button { + id: root -Item { - id: root implicitWidth: 18 implicitHeight: 18 property alias imgWidth: img.width property alias imgHeight: img.height - property alias imgSource: img.source + property alias imgSource: img.source + property alias iconSource: img.source - signal clicked + property string tooltip Image { id: img @@ -20,10 +23,18 @@ Item { sourceSize.height: height * 2 } - MouseArea { - id: marea - anchors.fill: parent - onClicked: root.clicked() - } + background: Rectangle { + implicitWidth: root.implicitWidth + 3 + implicitHeight: root.implicitHeight + 3 + opacity: enabled ? 1 : 0.3 + color: root.hovered ? "#eee" : "transparent" + border.width: root.hovered ? 1 : 0 + border.color: "#eee" + radius: 5 + } + + ToolTip.visible: hovered + ToolTip.text: root.tooltip + } diff --git a/src/qml/connections-tree/BetterTreeView.qml b/src/qml/connections-tree/BetterTreeView.qml index 7e2b3c187..ba00dab5b 100644 --- a/src/qml/connections-tree/BetterTreeView.qml +++ b/src/qml/connections-tree/BetterTreeView.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.1 +import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.2 import QtQml.Models 2.2 import QtQuick.Window 2.2 @@ -16,126 +16,125 @@ TreeView { horizontalScrollBarPolicy: Qt.ScrollBarAsNeeded verticalScrollBarPolicy: Qt.ScrollBarAsNeeded - TableViewColumn { - title: "item" - role: "icon" - width: 25 - delegate: Item { - - Image { - anchors.centerIn: parent - sourceSize.width: 25 - sourceSize.height: 25 - source: styleData.value - cache: true - asynchronous: true - } + model: connectionsManager + + style: TreeViewStyle { + indentation: 12 + + rowDelegate: Rectangle { + height: PlatformUtils.isOSXRetina(Screen) ? 25 : 30 + color: styleData.selected ? "#e2e2e2" : "white" } } TableViewColumn { id: itemColumn title: "item" - role: "name" - width: root.width - 50 - } - - itemDelegate: FocusScope { - id: itemRoot + role: "metadata" - Item { - id: wrapper - objectName: "rdm_tree_view_item" - height: PlatformUtils.isOSXRetina(Screen) ? 20 : 30 - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - anchors.rightMargin: 10 + delegate: FocusScope { + id: itemRoot - property bool itemEnabled: connectionsManager? connectionsManager.getItemData(styleData.index, "state") : true - - Text { - objectName: "rdm_tree_view_item_text" + Item { + id: wrapper + objectName: "rdm_tree_view_item" + height: PlatformUtils.isOSXRetina(Screen) ? 20 : 30 anchors.left: parent.left + anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter - //elide: styleData.elideMode - text: wrapper.itemEnabled ? styleData.value : styleData.value + qsTr(" (Removed)") - color: wrapper.itemEnabled ? "black": "#ccc" - anchors.leftMargin: { - if (connectionsManager) { - var itemDepth = connectionsManager.getItemData(styleData.index, "depth") - return itemDepth * 10 + 15 - } else { - return 35 + anchors.rightMargin: 10 + + property bool itemEnabled: styleData.value["state"] === true + + Image { + id: itemIcon + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + sourceSize.width: 25 + sourceSize.height: 25 + source: { + var locked = styleData.value["locked"] + + if (locked === true) { + return "qrc:/images/wait.svg" + } + + var type = styleData.value["type"] + + if (type == "server") { + var server_type = styleData.value["server_type"] + + if (server_type == "unknown") { + return "qrc:/images/server_offline.svg" + } else if (server_type == "standalone") { + return "qrc:/images/" + type + ".svg" + } else { + return "qrc:/images/" + server_type + ".svg" + } + } else if (type == "namespace" && styleData.isExpanded) { + return "qrc:/images/" + type + "_open.svg" + } else { + return "qrc:/images/" + type + ".svg" + } + } + cache: true + asynchronous: true } - } - Timer { - id: selectionTimer - interval: 1000; - running: styleData.index && styleData.selected && wrapper.itemEnabled - repeat: true - triggeredOnStart: true - onTriggered: wrapper.itemEnabled = connectionsManager.getItemData(styleData.index, "state") - } + Text { + objectName: "rdm_tree_view_item_text" + anchors.left: itemIcon.right + anchors.verticalCenter: parent.verticalCenter + text: wrapper.itemEnabled ? styleData.value["name"] : styleData.value["name"] + qsTr(" (Removed)") + color: wrapper.itemEnabled ? "black": "#ccc" + } + + Loader { + id: menuLoader + anchors { right: wrapper.right; top: wrapper.top; bottom: wrapper.bottom; rightMargin: 20 } + height: parent.height + visible: styleData.selected && wrapper.itemEnabled + asynchronous: true - Loader { - id: menuLoader - anchors {right: wrapper.right; top: wrapper.top; bottom: wrapper.bottom; } - anchors.rightMargin: 20 - height: parent.height - visible: styleData.selected && wrapper.itemEnabled - asynchronous: true - - source: { - if (!styleData.selected - || !connectionsManager - || !styleData.index) - return "" - - var type = connectionsManager.getItemData(styleData.index, "type") - - if (type != undefined) { - return "./menu/" + type + ".qml" - } else { - return "" + source: { + if (!(styleData.selected && styleData.value["type"])) + return "" + + return "./menu/" + styleData.value["type"] + ".qml" } - } - onLoaded: { - wrapper.forceActiveFocus() + onLoaded: wrapper.forceActiveFocus() } - } - MouseArea { - anchors.fill: parent + MouseArea { + anchors.fill: parent - acceptedButtons: Qt.RightButton | Qt.MiddleButton + acceptedButtons: Qt.RightButton | Qt.MiddleButton - onClicked: { - console.log("Catch event to item") + onClicked: { + console.log("Catch event to item") - if(mouse.button == Qt.RightButton) { - mouse.accepted = true - connectionTreeSelectionModel.setCurrentIndex(styleData.index, 1) - connectionsManager.sendEvent(styleData.index, "right-click") - return - } + if(mouse.button == Qt.RightButton) { + mouse.accepted = true + connectionTreeSelectionModel.setCurrentIndex(styleData.index, 1) + connectionsManager.sendEvent(styleData.index, "right-click") + return + } - if (mouse.button == Qt.MiddleButton) { - mouse.accepted = true - connectionsManager.sendEvent(styleData.index, "mid-click") - return + if (mouse.button == Qt.MiddleButton) { + mouse.accepted = true + connectionsManager.sendEvent(styleData.index, "mid-click") + return + } } } - } - - focus: true - Keys.forwardTo: menuLoader.item ? [menuLoader.item] : [] + focus: true + Keys.forwardTo: menuLoader.item ? [menuLoader.item] : [] + } } - } + } selectionMode: SelectionMode.SingleSelection @@ -144,29 +143,12 @@ TreeView { model: connectionsManager } - model: connectionsManager - - rowDelegate: Rectangle { - height: PlatformUtils.isOSXRetina(Screen) ? 25 : 30 - color: styleData.selected ? "#e2e2e2" : "white" - } - - onClicked: { - if (!connectionsManager) - return - - connectionsManager.sendEvent(index, "click") - } - + onClicked: connectionsManager && connectionsManager.sendEvent(index, "click") onExpanded: connectionsManager.setExpanded(index) onCollapsed: connectionsManager.setCollapsed(index) Connections { - target: connectionsManager; - onExpand: { - if (!root.isExpanded(index)) { - root.expand(index) - } - } + target: connectionsManager + onExpand: !root.isExpanded(index) && root.expand(index) } } diff --git a/src/qml/connections-tree/menu/InlineMenu.qml b/src/qml/connections-tree/menu/InlineMenu.qml index c5ec05416..fedc0c3b7 100644 --- a/src/qml/connections-tree/menu/InlineMenu.qml +++ b/src/qml/connections-tree/menu/InlineMenu.qml @@ -1,13 +1,15 @@ -import QtQuick 2.3 +import QtQuick 2.5 import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 import QtQuick.Window 2.2 +import QtQuick.Controls.Styles 1.4 import "./../../common/platformutils.js" as PlatformUtils import "./../../" +import "./../../common/" RowLayout { id: root - property alias model: repeater.model + property alias model: repeater.model property var callbacks function sendEvent(e) { @@ -24,25 +26,37 @@ RowLayout { Repeater { id: repeater - ToolButton { - - property variant data: modelData || model - - iconSource: data['icon'] - + Item { Layout.preferredWidth: PlatformUtils.isOSXRetina(Screen)? 20 : 25 Layout.preferredHeight: PlatformUtils.isOSXRetina(Screen)? 20 : 25 Layout.maximumHeight: PlatformUtils.isOSXRetina(Screen)? 20 : 25 - onClicked: { - if (data['callback'] != undefined) - return root.callCallback(data['callback']) - else - return root.sendEvent(data['event']) + ImageButton { + id: actionButton + anchors.fill: parent + + iconSource: modelData['icon'] + imgWidth: PlatformUtils.isOSXRetina(Screen)? 20 : 25 + imgHeight: PlatformUtils.isOSXRetina(Screen)? 20 : 25 + + onClicked: handleClick() + + function handleClick() { + if (modelData['callback'] != undefined) + return root.callCallback(modelData['callback']) + else + return root.sendEvent(modelData['event']) + } + + tooltip: modelData['help'] != undefined ? modelData['help'] + " (" + modelData["shortcut"] + ")" : "" + objectName: modelData['event'] != undefined ? "rdm_inline_menu_button_" + modelData['event'] : "" + } - tooltip: data['help'] != undefined ? data['help'] : "" - objectName: data['event'] != undefined ? "rdm_inline_menu_button_" + data['event'] : "" + Shortcut { + sequence: modelData["shortcut"] + onActivated: actionButton.handleClick() + } } } } diff --git a/src/qml/connections-tree/menu/database.qml b/src/qml/connections-tree/menu/database.qml index 14a9c0d7d..6933b96bd 100644 --- a/src/qml/connections-tree/menu/database.qml +++ b/src/qml/connections-tree/menu/database.qml @@ -9,217 +9,129 @@ RowLayout { id: root focus: true - implicitHeight: itemHeight - property int itemHeight: PlatformUtils.isOSXRetina(Screen)? 20 : 25 - - Keys.onPressed: { - if (state == "filter" && event.key == Qt.Key_Escape) { - state = "menu" - } - } - - property var shortcuts: { - 'add': PlatformUtils.isOSX()? "Meta+N" : "Ctrl+N", - 'reload': PlatformUtils.isOSX()? "Meta+R" : "Ctrl+R", - 'filter': PlatformUtils.isOSX()? "Meta+F" : "Ctrl+F", - 'live': PlatformUtils.isOSX()? "Meta+L" : "Ctrl+L", - 'flush': PlatformUtils.isOSX()? "Meta+Del" : "Ctrl+Del", - } - - function sc(t, a) { - return t + " (" + root.shortcuts[a] + ")" - } - - Shortcut { - sequence: root.shortcuts['add'] - onActivated: { - dbMenu.sendEvent('add_key') - } - } - - Shortcut { - sequence: root.shortcuts['reload'] - onActivated: { - dbMenu.sendEvent('reload') - } - } - - Shortcut { - sequence: root.shortcuts['filter'] - onActivated: root.state = "filter" - } - - Shortcut { - sequence: root.shortcuts['live'] - onActivated: { - liveButton.processClick() - } - } - - Shortcut { - sequence: root.shortcuts['flush'] - onActivated: { - dbMenu.sendEvent('flush') - } - } state: "menu" states: [ State { name: "menu" - PropertyChanges { target: root; spacing: 5;} PropertyChanges { target: dbMenu; visible: true;} - PropertyChanges { target: filterText; visible: false;} - PropertyChanges { target: filterOk; visible: false;} - PropertyChanges { target: filterHelp; visible: false;} - PropertyChanges { target: filterCancel; visible: false;} + PropertyChanges { target: filterMenu; visible: false;} }, State { name: "filter" - PropertyChanges { target: root; spacing: 0;} PropertyChanges { target: dbMenu; visible: false;} - PropertyChanges { target: filterText; visible: true;} - PropertyChanges { target: filterOk; visible: true;} - PropertyChanges { target: filterHelp; visible: true;} - PropertyChanges { target: filterCancel; visible: true;} + PropertyChanges { target: filterMenu; visible: true;} } ] - RowLayout { - id: dbMenu - - function sendEvent(e) { - if (!connectionsManager) - return - - connectionsManager.sendEvent(styleData.index, e) - } - - ToolButton { - tooltip: sc(qsTr("Open Keys Filter"), 'filter') - iconSource: "qrc:/images/filter.svg" - objectName: "rdm_inline_menu_button_filter" - - Layout.preferredWidth: root.itemHeight - Layout.preferredHeight: root.itemHeight - - onClicked: root.state = "filter" - } - - ToolButton { - tooltip: sc(qsTr("Reload Keys in Database"), 'reload') - iconSource: "qrc:/images/refresh.svg" - objectName: "rdm_inline_menu_button_reload_db" - - Layout.preferredWidth: root.itemHeight - Layout.preferredHeight: root.itemHeight - - onClicked: dbMenu.sendEvent("reload") - } - - ToolButton { - tooltip: sc(qsTr("Add New Key"), 'add') - iconSource: "qrc:/images/add.svg" - objectName: "rdm_inline_menu_button_add_key" - - Layout.preferredWidth: root.itemHeight - Layout.preferredHeight: root.itemHeight - - onClicked: dbMenu.sendEvent("add_key") + Keys.onPressed: { + if (state == "filter" && event.key == Qt.Key_Escape) { + state = "menu" } + } - ToolButton { - id: liveButton - - property bool liveUpdateEnabled: false - tooltip: liveUpdateEnabled? qsTr("Disable Live Update") : sc(qsTr("Enable Live Update"), 'live') - iconSource: liveUpdateEnabled? "qrc:/images/live_update_disable.svg" : "qrc:/images/live_update.svg" - objectName: "rdm_inline_menu_button_live_update" - - Layout.preferredWidth: root.itemHeight - Layout.preferredHeight: root.itemHeight + InlineMenu { + id: dbMenu - onClicked: processClick() + Layout.fillWidth: true - function processClick() { - if (liveUpdateEnabled) { + callbacks: { + "filter": function() { + root.state = "filter" + }, + "live_update": function () { + if (styleData.value["live_update"]) { connectionsManager.setMetadata(styleData.index, "live_update", '') } else { connectionsManager.setMetadata(styleData.index, "live_update", true) } - - liveUpdateEnabled = connectionsManager.getMetadata(styleData.index, "live_update") - } - - Component.onCompleted: { - liveUpdateEnabled = connectionsManager.getMetadata(styleData.index, "live_update") } } - ToolButton { - tooltip: sc(qsTr("Flush DB"), 'flush') - iconSource: "qrc:/images/cleanup.svg" - objectName: "rdm_inline_menu_button_flush_db" + model: [ + { + 'icon': "qrc:/images/filter.svg", 'callback': 'filter', "help": qsTr("Open Keys Filter"), + "shortcut": PlatformUtils.isOSX()? "Meta+F" : "Ctrl+F", + }, + { + 'icon': "qrc:/images/refresh.svg", 'event': 'reload', "help": qsTr("Reload Keys in Database"), + "shortcut": PlatformUtils.isOSX()? "Meta+R" : "Ctrl+R", + }, + { + 'icon': "qrc:/images/add.svg", 'event': 'add_key', "help": qsTr("Add New Key"), + "shortcut": PlatformUtils.isOSX()? "Meta+N" : "Ctrl+N", + }, + { + 'icon': styleData.value["live_update"]? "qrc:/images/live_update_disable.svg" : "qrc:/images/live_update.svg", + 'callback': 'live_update', + "help": styleData.value["live_update"]? qsTr("Disable Live Update") : qsTr("Enable Live Update"), + "shortcut": PlatformUtils.isOSX()? "Meta+L" : "Ctrl+L", + }, + { + 'icon': "qrc:/images/cleanup.svg", 'event': 'flush', "help": qsTr("Flush DB"), + "shortcut": PlatformUtils.isOSX()? "Meta+Del" : "Ctrl+Del", + }, + ] + } - Layout.preferredWidth: root.itemHeight - Layout.preferredHeight: root.itemHeight + RowLayout { + id: filterMenu - onClicked: dbMenu.sendEvent("flush") - } - } + spacing: 0 - TextField { - id: filterText - placeholderText: qsTr("Enter Filter") - objectName: "rdm_inline_menu_filter_field" + Layout.fillWidth: true - text: { - if (!connectionsManager) - return + TextField { + id: filterText - return connectionsManager.getMetadata(styleData.index, "filter") - } + Layout.fillWidth: true + + placeholderText: qsTr("Enter Filter") + objectName: "rdm_inline_menu_filter_field" - onAccepted: { - filterOk.setFilter() - focus = false + text: styleData.value["filter"] + + onAccepted: { + filterOk.setFilter() + focus = false + } } - } - ToolButton { - id: filterOk - iconSource: "qrc:/images/ok.svg" - objectName: "rdm_inline_menu_button_apply_filter" + ToolButton { + id: filterOk + iconSource: "qrc:/images/ok.svg" + objectName: "rdm_inline_menu_button_apply_filter" - onClicked: setFilter() + onClicked: setFilter() - function setFilter() { - if (!connectionsManager) - return + function setFilter() { + if (!connectionsManager) + return - connectionsManager.setMetadata(styleData.index, "filter", filterText.text) - root.state = "menu" + connectionsManager.setMetadata(styleData.index, "filter", filterText.text) + root.state = "menu" + } } - } - ToolButton { - id: filterHelp - iconSource: "qrc:/images/help.svg" - onClicked: Qt.openUrlExternally("https://github.com/uglide/RedisDesktopManager/wiki/Features#Filter") - } + ToolButton { + id: filterHelp + iconSource: "qrc:/images/help.svg" + onClicked: Qt.openUrlExternally("http://docs.redisdesktop.com/en/latest/features/#search-in-connection-tree") + } - ToolButton { - id: filterCancel - iconSource: "qrc:/images/clear.svg" - objectName: "rdm_inline_menu_button_reset_filter" + ToolButton { + id: filterCancel + iconSource: "qrc:/images/clear.svg" + objectName: "rdm_inline_menu_button_reset_filter" - onClicked: { - if (!connectionsManager) - return + onClicked: { + if (!connectionsManager) + return - connectionsManager.setMetadata(styleData.index, "filter", "") - root.state = "menu" + connectionsManager.setMetadata(styleData.index, "filter", "") + root.state = "menu" + } } } } diff --git a/src/qml/connections-tree/menu/key.qml b/src/qml/connections-tree/menu/key.qml index 801750715..c245887ed 100644 --- a/src/qml/connections-tree/menu/key.qml +++ b/src/qml/connections-tree/menu/key.qml @@ -3,29 +3,22 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 import "." -RowLayout { +InlineMenu { id: root + callbacks: { + "copy": function() { + var result = styleData.value["full_name"] - InlineMenu { - callbacks: { - "copy": function() { - if (!connectionsManager) - return - - var result = connectionsManager.data(styleData.index, 258) // 258 - original name role - - if (result) { - qmlUtils.copyToClipboard(result) - } - }, - } - - model: - [ - {'icon': "qrc:/images/copy.svg", "callback": "copy", "help": qsTr("Copy Key Name")}, - {'icon': "qrc:/images/delete.svg", "event": "delete", "help": qsTr("Delete Key")} - ] + if (result) { + qmlUtils.copyToClipboard(result) + } + }, } + model: + [ + {'icon': "qrc:/images/copy.svg", "callback": "copy", "help": qsTr("Copy Key Name")}, + {'icon': "qrc:/images/delete.svg", "event": "delete", "help": qsTr("Delete Key")} + ] } diff --git a/src/qml/connections-tree/menu/namespace.qml b/src/qml/connections-tree/menu/namespace.qml index 4cc4468f2..96bbac05e 100644 --- a/src/qml/connections-tree/menu/namespace.qml +++ b/src/qml/connections-tree/menu/namespace.qml @@ -3,29 +3,24 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 import "." -RowLayout { +InlineMenu { id: root + callbacks: { + "copy": function() { + var result = styleData.value["full_name"] - InlineMenu { - callbacks: { - "copy": function() { - if (!connectionsManager) - return - - var result = connectionsManager.data(styleData.index, 258) // 258 - original name role - - if (result) { - qmlUtils.copyToClipboard(result + ":*") - } - }, - } - - model: - [ - {'icon': "qrc:/images/copy.svg", "callback": "copy", "help": qsTr("Copy Namespace Pattern")}, - {'icon': "qrc:/images/delete.svg", "event": "delete", "help": qsTr("Delete Namespace")} - ] + if (result) { + qmlUtils.copyToClipboard(result + ":*") + } + }, } + model: + [ + {'icon': "qrc:/images/refresh.svg", "event": "reload", "help": qsTr("Reload Namespace")}, + {'icon': "qrc:/images/copy.svg", "callback": "copy", "help": qsTr("Copy Namespace Pattern")}, + {'icon': "qrc:/images/delete.svg", "event": "delete", "help": qsTr("Delete Namespace")} + ] } + diff --git a/src/qml/connections-tree/menu/server.qml b/src/qml/connections-tree/menu/server.qml index 90278318f..2e84bb574 100644 --- a/src/qml/connections-tree/menu/server.qml +++ b/src/qml/connections-tree/menu/server.qml @@ -3,73 +3,33 @@ import QtQuick.Layouts 1.1 import QtQuick.Controls 1.4 import "." -RowLayout { +InlineMenu { id: root - property var shortcuts: { - 'server_info': Qt.platform.os == "osx"? "Meta+I" : "Ctrl+I", - 'console': Qt.platform.os == "osx"? "Meta+T" : "Ctrl+T", - 'reload': Qt.platform.os == "osx"? "Meta+R" : "Ctrl+R", - 'unload': Qt.platform.os == "osx"? "Meta+U" : "Ctrl+U", - 'edit': Qt.platform.os == "osx"? "Meta+E" : "Ctrl+E", - 'delete': Qt.platform.os == "osx"? "Meta+Del" : "Ctrl+Del", - } - - function sc(t, a) { - return t + " (" + root.shortcuts[a] + ")" - } - - InlineMenu { - id: serverMenu - model: [ - {'icon': "qrc:/images/log.svg", 'event': 'server_info', "help": sc(qsTr("Server Info"), 'server_info')}, - {'icon': "qrc:/images/console.svg", 'event': 'console', "help": sc(qsTr("Open Console"), 'console')}, - {'icon': "qrc:/images/refresh.svg", 'event': 'reload', "help": sc(qsTr("Reload Server"), 'reload')}, - {'icon': "qrc:/images/offline.svg", 'event': 'unload', "help": sc(qsTr("Unload All Data"), 'unload')}, - {'icon': "qrc:/images/editdb.svg", 'event': 'edit', "help": sc(qsTr("Edit Connection Settings"), 'edit')}, - {'icon': "qrc:/images/delete.svg", 'event': 'delete', "help": sc(qsTr("Delete Connection"), 'delete')}, - ] - } - - Shortcut { - sequence: root.shortcuts['server_info'] - onActivated: { - serverMenu.sendEvent('server_info') - } - } - - Shortcut { - sequence: root.shortcuts['console'] - onActivated: { - serverMenu.sendEvent('console') - } - } - - Shortcut { - sequence: root.shortcuts['reload'] - onActivated: { - serverMenu.sendEvent('reload') - } - } - - Shortcut { - sequence: root.shortcuts['unload'] - onActivated: { - serverMenu.sendEvent('unload') - } - } - - Shortcut { - sequence: root.shortcuts['edit'] - onActivated: { - serverMenu.sendEvent('edit') - } - } - - Shortcut { - sequence: root.shortcuts['delete'] - onActivated: { - serverMenu.sendEvent('delete') - } - } + model: [ + { + 'icon': "qrc:/images/log.svg", 'event': 'server_info', "help": qsTr("Server Info"), + "shortcut": Qt.platform.os == "osx"? "Meta+I" : "Ctrl+I" + }, + { + 'icon': "qrc:/images/console.svg", 'event': 'console', "help": qsTr("Open Console"), + "shortcut": Qt.platform.os == "osx"? "Meta+T" : "Ctrl+T", + }, + { + 'icon': "qrc:/images/refresh.svg", 'event': 'reload', "help": qsTr("Reload Server"), + "shortcut": Qt.platform.os == "osx"? "Meta+R" : "Ctrl+R", + }, + { + 'icon': "qrc:/images/offline.svg", 'event': 'unload', "help": qsTr("Unload All Data"), + "shortcut": Qt.platform.os == "osx"? "Meta+U" : "Ctrl+U", + }, + { + 'icon': "qrc:/images/editdb.svg", 'event': 'edit', "help": qsTr("Edit Connection Settings"), + "shortcut": Qt.platform.os == "osx"? "Meta+E" : "Ctrl+E", + }, + { + 'icon': "qrc:/images/delete.svg", 'event': 'delete', "help": qsTr("Delete Connection"), + "shortcut": Qt.platform.os == "osx"? "Meta+Del" : "Ctrl+Del", + }, + ] } diff --git a/src/resources/images.qrc b/src/resources/images.qrc index c245ffda2..59e848484 100644 --- a/src/resources/images.qrc +++ b/src/resources/images.qrc @@ -7,8 +7,9 @@ images/ok.svg images/clear.svg images/wait.svg - images/db.svg + images/database.svg images/namespace.svg + images/namespace_open.svg images/key.svg images/help.svg images/alert.svg diff --git a/src/resources/images/db.svg b/src/resources/images/database.svg similarity index 100% rename from src/resources/images/db.svg rename to src/resources/images/database.svg diff --git a/src/resources/images/namespace_open.svg b/src/resources/images/namespace_open.svg new file mode 100644 index 000000000..1d9dad27c --- /dev/null +++ b/src/resources/images/namespace_open.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/unit_tests/testcases/connections-tree/test_databaseitem.cpp b/tests/unit_tests/testcases/connections-tree/test_databaseitem.cpp index bed0a5762..4fd44345e 100644 --- a/tests/unit_tests/testcases/connections-tree/test_databaseitem.cpp +++ b/tests/unit_tests/testcases/connections-tree/test_databaseitem.cpp @@ -44,8 +44,7 @@ void TestDatabaseItem::testLoadKeys() //then QCOMPARE(spy.count(), 1); QCOMPARE(item->childCount(), (unsigned int)100002); - QCOMPARE(item->getDisplayName(), QString("db0 (55) ")); - QCOMPARE(item->getIconUrl().isNull(), false); + QCOMPARE(item->getDisplayName(), QString("db0 (55) ")); QCOMPARE(item->getAllChilds().isEmpty(), false); QCOMPARE(item->isEnabled(), true); QCOMPARE(item->isLocked(), false); diff --git a/tests/unit_tests/testcases/connections-tree/test_serveritem.cpp b/tests/unit_tests/testcases/connections-tree/test_serveritem.cpp index b2cace969..9632b2afe 100644 --- a/tests/unit_tests/testcases/connections-tree/test_serveritem.cpp +++ b/tests/unit_tests/testcases/connections-tree/test_serveritem.cpp @@ -95,8 +95,7 @@ void TestServerItem::testBasicMethods() ServerItem item("test", (QSharedPointer(dynamic_cast(operations))), dummyModel); //then - QCOMPARE(item.getDisplayName(), QString("test")); - QCOMPARE(item.getIconUrl().isNull(), false); + QCOMPARE(item.getDisplayName(), QString("test")); QCOMPARE(item.parent() == nullptr, true); QCOMPARE(item.isEnabled(), true); QCOMPARE(item.isLocked(), false);