mirror of
https://github.com/redis/RedisDesktopManager.git
synced 2026-10-29 11:36:44 +08:00
Update value-editor module
This commit is contained in:
@@ -41,6 +41,8 @@ void ConnectionsManager::addNewConnection(const RedisClient::ConnectionConfig &c
|
||||
|
||||
QObject::connect(treeModel.data(), &TreeOperations::openValueTab,
|
||||
m_values.data(), &ValueEditor::ViewModel::openTab);
|
||||
QObject::connect(treeModel.data(), &TreeOperations::newKeyDialog,
|
||||
m_values.data(), &ValueEditor::ViewModel::openNewKeyDialog);
|
||||
|
||||
QSharedPointer<ServerItem> serverItem = QSharedPointer<ServerItem>(
|
||||
new ServerItem(config.name,
|
||||
|
||||
@@ -215,45 +215,6 @@ bool ListLikeKeyModel::isMultiRow() const
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVariant valueToEscapedString(const QByteArray &value)
|
||||
{
|
||||
QString val = QString::fromStdString(value.toStdString());
|
||||
|
||||
for(int index=0; index < val.length(); ++index) {
|
||||
|
||||
QChar c(val.at(index));
|
||||
|
||||
if (c.category() == QChar::Other_Control) {
|
||||
QString num = QString::number(c.toLatin1(), 16);
|
||||
|
||||
QString replace = QString("\\x%1%2").arg(num.size() == 1 ? "0": "").arg(num);
|
||||
val.replace(index, 1, replace);
|
||||
index += replace.size();
|
||||
}
|
||||
}
|
||||
return QVariant(val);
|
||||
}
|
||||
|
||||
|
||||
QByteArray escapedStringToValue(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
QRegExp rx("\\" "\\" "x([0-9]{2,2})");
|
||||
int pos = 0;
|
||||
|
||||
while ((pos = rx.indexIn(result, pos)) != -1) {
|
||||
QString found = rx.cap(1);
|
||||
QString after(QChar(found.toInt(nullptr, 16)));
|
||||
|
||||
result.replace(pos, rx.matchedLength(), after);
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
return result.toUtf8();
|
||||
}
|
||||
|
||||
|
||||
QVariant valueToBinary(const QByteArray &value)
|
||||
{
|
||||
QVariantList list;
|
||||
|
||||
@@ -63,5 +63,3 @@ protected:
|
||||
};
|
||||
|
||||
QVariant valueToBinary(const QByteArray&value);
|
||||
QVariant valueToEscapedString(const QByteArray&);
|
||||
QByteArray escapedStringToValue(const QString&);
|
||||
|
||||
@@ -39,17 +39,7 @@ void KeyFactory::loadKey(QSharedPointer<RedisClient::Connection> connection,
|
||||
ttl = ttlResult.getValue().toInt();
|
||||
}
|
||||
|
||||
if (type == "string") {
|
||||
result = QSharedPointer<ValueEditor::Model>(new StringKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "list") {
|
||||
result = QSharedPointer<ValueEditor::Model>(new ListKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "set") {
|
||||
result = QSharedPointer<ValueEditor::Model>(new SetKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "zset") {
|
||||
result = QSharedPointer<ValueEditor::Model>(new SortedSetKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "hash") {
|
||||
result = QSharedPointer<ValueEditor::Model>(new HashKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
}
|
||||
result = createModel(type, connection, keyFullPath, dbIndex, ttl);
|
||||
|
||||
callback(result);
|
||||
|
||||
@@ -58,3 +48,32 @@ void KeyFactory::loadKey(QSharedPointer<RedisClient::Connection> connection,
|
||||
connection->runCommand(typeCmd);
|
||||
}
|
||||
|
||||
void KeyFactory::addKey(QSharedPointer<RedisClient::Connection> connection, QString keyFullPath, int dbIndex,
|
||||
QString type, const QVariantMap &row)
|
||||
{
|
||||
QSharedPointer<ValueEditor::Model> result = createModel(type, connection, keyFullPath, dbIndex, -1);
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
||||
result->addRow(row);
|
||||
}
|
||||
|
||||
QSharedPointer<ValueEditor::Model> KeyFactory::createModel(QString type, QSharedPointer<RedisClient::Connection> connection,
|
||||
QString keyFullPath, int dbIndex, int ttl)
|
||||
{
|
||||
if (type == "string") {
|
||||
return QSharedPointer<ValueEditor::Model>(new StringKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "list") {
|
||||
return QSharedPointer<ValueEditor::Model>(new ListKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "set") {
|
||||
return QSharedPointer<ValueEditor::Model>(new SetKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "zset") {
|
||||
return QSharedPointer<ValueEditor::Model>(new SortedSetKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
} else if (type == "hash") {
|
||||
return QSharedPointer<ValueEditor::Model>(new HashKeyModel(connection, keyFullPath, dbIndex, ttl));
|
||||
}
|
||||
|
||||
return QSharedPointer<ValueEditor::Model>();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@ public:
|
||||
void loadKey(QSharedPointer<RedisClient::Connection> connection,
|
||||
QString keyFullPath, int dbIndex,
|
||||
std::function<void(QSharedPointer<ValueEditor::Model>)> callback) override;
|
||||
|
||||
void addKey(QSharedPointer<RedisClient::Connection> connection,
|
||||
QString keyFullPath, int dbIndex, QString type,
|
||||
const QVariantMap &row) override;
|
||||
|
||||
private:
|
||||
QSharedPointer<ValueEditor::Model> createModel(QString type, QSharedPointer<RedisClient::Connection> connection,
|
||||
QString keyFullPath, int dbIndex, int ttl);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,13 +42,9 @@ QVariant StringKeyModel::getData(int rowIndex, int dataRole)
|
||||
void StringKeyModel::updateRow(int rowIndex, const QVariantMap &row)
|
||||
{
|
||||
if (rowIndex > 0 || !isRowValid(row))
|
||||
return;
|
||||
return;
|
||||
|
||||
QString escapedString = row.value("value").toString();
|
||||
qDebug() << "escaped string: " << escapedString;
|
||||
|
||||
QByteArray value = escapedStringToValue(escapedString);
|
||||
qDebug() << "value: " << value.toHex();
|
||||
QByteArray value = row.value("value").toByteArray();
|
||||
|
||||
if (value.isEmpty())
|
||||
return;
|
||||
@@ -63,9 +59,9 @@ void StringKeyModel::updateRow(int rowIndex, const QVariantMap &row)
|
||||
}
|
||||
}
|
||||
|
||||
void StringKeyModel::addRow(const QVariantMap &)
|
||||
void StringKeyModel::addRow(const QVariantMap &row)
|
||||
{
|
||||
return;
|
||||
updateRow(0, row);
|
||||
}
|
||||
|
||||
unsigned long StringKeyModel::rowsCount()
|
||||
|
||||
@@ -115,3 +115,9 @@ void TreeOperations::openConsoleTab()
|
||||
QSharedPointer<Console::ConsoleTab> tab(new Console::ConsoleTab(model.staticCast<Console::Operations>()));
|
||||
m_consoleTabs.addTab(tab.staticCast<BaseTab>());
|
||||
}
|
||||
|
||||
void TreeOperations::openNewKeyDialog(int dbIndex, QString keyPrefix)
|
||||
{
|
||||
qDebug() << "new key";
|
||||
emit newKeyDialog(m_connection, dbIndex, keyPrefix);
|
||||
}
|
||||
|
||||
@@ -24,14 +24,19 @@ public:
|
||||
|
||||
QString getNamespaceSeparator() override;
|
||||
|
||||
virtual void openKeyTab(ConnectionsTree::KeyItem& key, bool openInNewTab = false) override;
|
||||
void openKeyTab(ConnectionsTree::KeyItem& key, bool openInNewTab = false) override;
|
||||
|
||||
virtual void openConsoleTab() override;
|
||||
void openConsoleTab() override;
|
||||
|
||||
void openNewKeyDialog(int dbIndex, QString keyPrefix = QString()) override;
|
||||
|
||||
signals:
|
||||
void openValueTab(QSharedPointer<RedisClient::Connection> connection,
|
||||
ConnectionsTree::KeyItem& key, bool inNewTab);
|
||||
|
||||
void newKeyDialog(QSharedPointer<RedisClient::Connection> connection,
|
||||
int dbIndex, QString keyPrefix);
|
||||
|
||||
private:
|
||||
QSharedPointer<RedisClient::Connection> m_connection;
|
||||
ConsoleTabs& m_consoleTabs;
|
||||
|
||||
@@ -76,8 +76,20 @@ void DatabaseItem::onWheelClick(TreeItem::ParentView&)
|
||||
QSharedPointer<QMenu> DatabaseItem::getContextMenu(TreeItem::ParentView& treeView)
|
||||
{
|
||||
Q_UNUSED(treeView);
|
||||
QSharedPointer<QMenu> menu(new QMenu());
|
||||
|
||||
return QSharedPointer<QMenu>(new QMenu());
|
||||
//new key action
|
||||
QAction* newKey = new QAction(QIcon(":/images/terminal.png"), "Add new key", menu.data());
|
||||
QObject::connect(newKey, &QAction::triggered, this, [this]() { m_operations->openNewKeyDialog(m_index); });
|
||||
menu->addAction(newKey);
|
||||
menu->addSeparator();
|
||||
|
||||
//reload action
|
||||
QAction* reload = new QAction(QIcon(":/images/refreshdb.png"), "Reload", menu.data());
|
||||
QObject::connect(reload, &QAction::triggered, this, [this] { this->reload(); });
|
||||
menu->addAction(reload);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
void DatabaseItem::loadKeys()
|
||||
@@ -120,6 +132,24 @@ void DatabaseItem::onKeysRendered()
|
||||
emit keysLoaded(m_index);
|
||||
}
|
||||
|
||||
void DatabaseItem::unload()
|
||||
{
|
||||
if (m_keys.size() == 0)
|
||||
return;
|
||||
|
||||
m_locked = true;
|
||||
emit unloadStarted(m_index);
|
||||
|
||||
m_keys.clear();
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
void DatabaseItem::reload()
|
||||
{
|
||||
unload();
|
||||
loadKeys();
|
||||
}
|
||||
|
||||
QList<QSharedPointer<TreeItem> >
|
||||
DatabaseItem::KeysTreeRenderer::renderKeys(QSharedPointer<Operations> operations,
|
||||
Operations::RawKeysList keys,
|
||||
|
||||
@@ -38,10 +38,15 @@ public:
|
||||
|
||||
signals:
|
||||
void keysLoaded(unsigned int dbIndex);
|
||||
void unloadStarted(unsigned int dbIndex);
|
||||
|
||||
protected slots:
|
||||
void onKeysRendered();
|
||||
|
||||
protected:
|
||||
void unload();
|
||||
void reload();
|
||||
|
||||
private:
|
||||
class KeysTreeRenderer
|
||||
{
|
||||
|
||||
@@ -179,6 +179,8 @@ void ServerItem::load()
|
||||
|
||||
QObject::connect(dynamic_cast<QObject*>(database.data()), SIGNAL(keysLoaded(unsigned int)),
|
||||
this, SIGNAL(keysLoadedInDatabase(unsigned int)));
|
||||
QObject::connect(dynamic_cast<QObject*>(database.data()), SIGNAL(unloadStarted(unsigned int)),
|
||||
this, SIGNAL(unloadStartedInDatabase(unsigned int)));
|
||||
|
||||
m_databases.push_back(database);
|
||||
++db;
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace ConnectionsTree {
|
||||
void editActionRequested();
|
||||
void deleteActionRequested();
|
||||
void keysLoadedInDatabase(unsigned int dbIndex);
|
||||
void unloadStartedInDatabase(unsigned int dbIndex);
|
||||
|
||||
/*signals:
|
||||
void keysLoaded(unsigned int dbIndex);*/
|
||||
|
||||
@@ -142,6 +142,14 @@ void Model::addRootItem(QSharedPointer<ServerItem> item)
|
||||
emit endInsertRows();
|
||||
});
|
||||
|
||||
connect(item.data(), &ServerItem::unloadStartedInDatabase,
|
||||
this, [this, itemIndex, item](unsigned int dbIndex)
|
||||
{
|
||||
QModelIndex dbModelIndex = index(dbIndex, 0, itemIndex);
|
||||
emit beginRemoveRows(dbModelIndex, 0, item->child(dbIndex)->childCount() - 1);
|
||||
emit endRemoveRows();
|
||||
});
|
||||
|
||||
emit endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ namespace ConnectionsTree {
|
||||
|
||||
virtual void openConsoleTab() = 0;
|
||||
|
||||
virtual void openNewKeyDialog(int dbIndex, QString keyPrefix = QString()) = 0;
|
||||
|
||||
virtual ~Operations() {}
|
||||
|
||||
};
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <QVariant>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
QString binaryStringToEscapedString(const QByteArray&);
|
||||
QByteArray escapedStringToBinaryString(const QString&);
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "hex_untils.h"
|
||||
|
||||
|
||||
QString binaryStringToEscapedString(const QByteArray &value)
|
||||
{
|
||||
QString val = QString::fromStdString(value.toStdString());
|
||||
|
||||
for(int index=0; index < val.length(); ++index) {
|
||||
|
||||
QChar c(val.at(index));
|
||||
|
||||
if (c.category() == QChar::Other_Control) {
|
||||
QString num = QString::number(c.toLatin1(), 16);
|
||||
|
||||
QString replace = QString("\\x%1%2").arg(num.size() == 1 ? "0": "").arg(num);
|
||||
val.replace(index, 1, replace);
|
||||
index += replace.size();
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
QByteArray escapedStringToBinaryString(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
QRegExp rx("\\" "\\" "x([0-9]{2,2})");
|
||||
int pos = 0;
|
||||
|
||||
while ((pos = rx.indexIn(result, pos)) != -1) {
|
||||
QString found = rx.cap(1);
|
||||
QString after(QChar(found.toInt(nullptr, 16)));
|
||||
|
||||
result.replace(pos, rx.matchedLength(), after);
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
return result.toUtf8();
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
#include <QSharedPointer>
|
||||
#include <functional>
|
||||
#include "keymodel.h"
|
||||
@@ -18,6 +19,10 @@ public:
|
||||
QString keyFullPath, int dbIndex,
|
||||
std::function<void(QSharedPointer<Model>)> callback) = 0;
|
||||
|
||||
virtual void addKey(QSharedPointer<RedisClient::Connection> connection,
|
||||
QString keyFullPath, int dbIndex, QString type,
|
||||
const QVariantMap &row) = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "viewmodel.h"
|
||||
#include "connections-tree/items/keyitem.h"
|
||||
#include "value-editor/valueviewmodel.h"
|
||||
#include "redisclient/connection.h"
|
||||
#include <QDebug>
|
||||
|
||||
ValueEditor::ViewModel::ViewModel(QSharedPointer<AbstractKeyFactory> keyFactory)
|
||||
@@ -86,6 +87,13 @@ QHash<int, QByteArray> ValueEditor::ViewModel::roleNames() const
|
||||
return roles;
|
||||
}
|
||||
|
||||
void ValueEditor::ViewModel::addKey(QString keyName, QString keyType, const QVariantMap &row)
|
||||
{
|
||||
m_keyFactory->addKey(m_newKeyRequest.first,
|
||||
keyName, m_newKeyRequest.second,
|
||||
keyType, row);
|
||||
}
|
||||
|
||||
void ValueEditor::ViewModel::renameKey(int i, const QString& newKeyName)
|
||||
{
|
||||
if (!isIndexValid(index(i, 0)))
|
||||
@@ -155,6 +163,19 @@ QObject* ValueEditor::ViewModel::getValue(int i)
|
||||
return valueEditors[0];
|
||||
}
|
||||
|
||||
void ValueEditor::ViewModel::openNewKeyDialog(QSharedPointer<RedisClient::Connection> connection,
|
||||
int dbIndex, QString keyPrefix)
|
||||
{
|
||||
if (connection.isNull() || dbIndex < 0)
|
||||
return;
|
||||
|
||||
m_newKeyRequest = qMakePair(connection, dbIndex);
|
||||
|
||||
QString dbId= QString("%1:db%2").arg(connection->getConfig().name).arg(dbIndex);
|
||||
|
||||
emit newKeyDialog(dbId, keyPrefix);
|
||||
}
|
||||
|
||||
bool ValueEditor::ViewModel::isIndexValid(const QModelIndex &index) const
|
||||
{
|
||||
return 0 <= index.row() && index.row() < rowCount();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QString>
|
||||
#include <QPair>
|
||||
#include <QByteArray>
|
||||
#include <QSharedPointer>
|
||||
#include "abstractkeyfactory.h"
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
|
||||
|
||||
public: // methods exported to QML
|
||||
Q_INVOKABLE void addKey(QString keyName, QString keyType, const QVariantMap &row);
|
||||
Q_INVOKABLE void renameKey(int index, const QString& newKeyName);
|
||||
Q_INVOKABLE void removeKey(int i);
|
||||
Q_INVOKABLE void closeTab(int i);
|
||||
@@ -50,8 +52,11 @@ signals:
|
||||
void keyError(int index, const QString& error);
|
||||
void replaceTab(int index);
|
||||
void closeWelcomeTab();
|
||||
void newKeyDialog(QString dbIdentificationString, QString keyPrefix);
|
||||
|
||||
public slots:
|
||||
void openNewKeyDialog(QSharedPointer<RedisClient::Connection> connection, int dbIndex,
|
||||
QString keyPrefix);
|
||||
void openTab(QSharedPointer<RedisClient::Connection> connection,
|
||||
ConnectionsTree::KeyItem& key, bool inNewTab);
|
||||
|
||||
@@ -60,6 +65,8 @@ private:
|
||||
QSharedPointer<AbstractKeyFactory> m_keyFactory;
|
||||
int m_currentTabIndex;
|
||||
|
||||
QPair<QSharedPointer<RedisClient::Connection>, int> m_newKeyRequest;
|
||||
|
||||
bool isIndexValid(const QModelIndex &index) const;
|
||||
void loadModel(QSharedPointer<Model> model, bool openNewTab = false);
|
||||
void removeModel(QSharedPointer<Model> model);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
width: 100
|
||||
height: 62
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Dialogs 1.2
|
||||
import "./editors/editor.js" as Editor
|
||||
|
||||
Item {
|
||||
function open() {
|
||||
root.open()
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: root
|
||||
title: "Add New Key"
|
||||
|
||||
width: 520
|
||||
height: 450
|
||||
modality: Qt.ApplicationModal
|
||||
|
||||
ColumnLayout {
|
||||
implicitWidth: 500
|
||||
implicitHeight: 100
|
||||
width: 500
|
||||
|
||||
Text { text: "Key:" }
|
||||
TextField {
|
||||
id: newKeyName
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text { text: "Type:" }
|
||||
ComboBox {
|
||||
id: typeSelector
|
||||
model: Editor.getSupportedKeyTypes()
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Text { text: "Value:" }
|
||||
Loader {
|
||||
id: valueAddEditor
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 300
|
||||
|
||||
source: Editor.getEditorByTypeString(typeSelector.model[typeSelector.currentIndex])
|
||||
|
||||
onLoaded: {
|
||||
item.state = "new"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (!valueAddEditor.item)
|
||||
return false
|
||||
|
||||
if (!valueAddEditor.item.isValueValid()
|
||||
|| newKeyName.text.length == 0) {
|
||||
valueAddEditor.item.markInvalidFields()
|
||||
return open()
|
||||
}
|
||||
|
||||
var row = valueAddEditor.item.getValue()
|
||||
viewModel.addKey(newKeyName.text,
|
||||
typeSelector.model[typeSelector.currentIndex],
|
||||
row)
|
||||
|
||||
addConfirmation.text = "Key was added!"
|
||||
addConfirmation.open()
|
||||
}
|
||||
|
||||
visible: false
|
||||
standardButtons: StandardButton.Save | StandardButton.Cancel
|
||||
|
||||
}
|
||||
MessageDialog {
|
||||
id: addConfirmation
|
||||
title: "Save value"
|
||||
text: ""
|
||||
visible: false
|
||||
modality: Qt.ApplicationModal
|
||||
icon: StandardIcon.Information
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import QtQuick.Controls 1.2
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Window 2.2
|
||||
import "./editors/editor.js" as Editor
|
||||
import "./parts"
|
||||
|
||||
|
||||
Repeater {
|
||||
@@ -86,11 +88,17 @@ Repeater {
|
||||
width: 500
|
||||
|
||||
Text { text: "New name:" }
|
||||
TextField { id: newKeyName; Layout.fillWidth: true;}
|
||||
TextField {
|
||||
id: newKeyName;
|
||||
Layout.fillWidth: true;
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
console.log(newKeyName.text)
|
||||
if (newKeyName.text.length == 0) {
|
||||
return open()
|
||||
}
|
||||
|
||||
viewModel.renameKey(keyTab.keyIndex, newKeyName.text)
|
||||
}
|
||||
|
||||
@@ -182,25 +190,12 @@ Repeater {
|
||||
width: 500
|
||||
height: 350
|
||||
anchors.centerIn: parent
|
||||
|
||||
property int currentRow: -1
|
||||
|
||||
source: {
|
||||
if (keyType === "string") {
|
||||
return "./editors/SingleItemEditor.qml"
|
||||
} else if (keyType === "list" || keyType === "set") {
|
||||
return "./editors/SingleItemEditor.qml"
|
||||
} else if (keyType === "zset") {
|
||||
return "./editors/SortedSetItemEditor.qml"
|
||||
} else if (keyType === "hash") {
|
||||
return "./editors/HashItemEditor.qml"
|
||||
} else {
|
||||
console.error("Editor for type " + keyType + " is not defined!")
|
||||
}
|
||||
}
|
||||
source: Editor.getEditorByTypeString(keyType)
|
||||
|
||||
onLoaded: {
|
||||
item.editingMode = false
|
||||
item.state = "add"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,39 +398,12 @@ Repeater {
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Pagination {
|
||||
id: pagination
|
||||
visible: showValueNavigation
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 40
|
||||
Layout.minimumHeight: 40
|
||||
Button {
|
||||
text: "⇤"
|
||||
onClicked: table.goToFirstPage()
|
||||
}
|
||||
Button {
|
||||
text: "⇦"
|
||||
onClicked: table.goToPrevPage()
|
||||
}
|
||||
Text {
|
||||
text: "Page " + table.currentPage + " of " + table.totalPages
|
||||
+ " (Items:" + (table.currentStart+1) + "-"
|
||||
+ (table.currentStart+table.rowCount)
|
||||
+ " of " + table.model.totalRowCount() + ")"
|
||||
}
|
||||
TextField { text: "1"; Layout.fillWidth: true; readOnly: false}
|
||||
Button {
|
||||
text: "Goto Page"
|
||||
onClicked: {}
|
||||
}
|
||||
Button {
|
||||
text: "⇨"
|
||||
onClicked: table.goToNextPage()
|
||||
}
|
||||
Button {
|
||||
text: "⇥"
|
||||
onClicked: table.goToLastPage()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
@@ -476,27 +444,15 @@ Repeater {
|
||||
property int currentRow: -1
|
||||
|
||||
source: {
|
||||
if (keyType === "string") {
|
||||
table.loadValue()
|
||||
return "./editors/SingleItemEditor.qml"
|
||||
} else if (keyType === "list" || keyType === "set") {
|
||||
return "./editors/SingleItemEditor.qml"
|
||||
} else if (keyType === "zset") {
|
||||
return "./editors/SortedSetItemEditor.qml"
|
||||
} else if (keyType === "hash") {
|
||||
return "./editors/HashItemEditor.qml"
|
||||
} else {
|
||||
console.error("Editor for type " + keyType + " is not defined!")
|
||||
}
|
||||
if (keyType === "string")
|
||||
table.loadValue()
|
||||
|
||||
return Editor.getEditorByTypeString(keyType)
|
||||
}
|
||||
|
||||
onLoaded: {
|
||||
console.log("VALUE EDITOR LOADED!")
|
||||
|
||||
if (keyType === "string") {
|
||||
if (keyType === "string")
|
||||
valueEditor.loadRowValue(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function loadRowValue(row) {
|
||||
@@ -539,11 +495,10 @@ Repeater {
|
||||
text: ""
|
||||
visible: false
|
||||
modality: Qt.ApplicationModal
|
||||
icon: StandardIcon.Warning
|
||||
icon: StandardIcon.Information
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,13 @@ import QtQuick.Dialogs 1.2
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
property bool editingMode: true
|
||||
state: "edit"
|
||||
|
||||
states: [
|
||||
State { name: "new"},
|
||||
State { name: "add"},
|
||||
State { name: "edit"}
|
||||
]
|
||||
|
||||
function isValueChanged() {
|
||||
console.exception("Not implemented")
|
||||
|
||||
@@ -22,7 +22,7 @@ AbstractEditor {
|
||||
Layout.minimumHeight: 35
|
||||
|
||||
text: ""
|
||||
enabled: originalValue != "" || !editingMode
|
||||
enabled: originalValue != "" || state !== "edit"
|
||||
property string originalValue: ""
|
||||
|
||||
style: TextFieldStyle {
|
||||
@@ -48,8 +48,9 @@ AbstractEditor {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: ""
|
||||
enabled: originalValue != "" || !editingMode
|
||||
enabled: originalValue != "" || state !== "edit"
|
||||
property string originalValue: ""
|
||||
showFormatters: root.state != "new"
|
||||
|
||||
style: TextAreaStyle {
|
||||
backgroundColor: (textArea.text=="" && textArea.enabled
|
||||
|
||||
@@ -12,12 +12,15 @@ ColumnLayout
|
||||
property alias enabled: textArea.enabled
|
||||
property alias textColor: textArea.textColor
|
||||
property alias style: textArea.style
|
||||
property bool showFormatters: true
|
||||
|
||||
function getText() {
|
||||
return textArea.formatter.getRaw(textArea.text)
|
||||
}
|
||||
|
||||
RowLayout{
|
||||
visible: showFormatters
|
||||
|
||||
Text {
|
||||
text: "View value as:"
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ AbstractEditor {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: ""
|
||||
enabled: originalValue != "" || !editingMode
|
||||
enabled: originalValue != "" || state !== "edit"
|
||||
showFormatters: root.state != "new"
|
||||
}
|
||||
|
||||
function setValue(rowValue) {
|
||||
|
||||
@@ -22,7 +22,7 @@ AbstractEditor {
|
||||
Layout.minimumHeight: 35
|
||||
|
||||
text: ""
|
||||
enabled: originalValue != "" || !editingMode
|
||||
enabled: originalValue != "" || state !== "edit"
|
||||
property string originalValue: ""
|
||||
placeholderText: "Score"
|
||||
validator: DoubleValidator { locale: "C" } // force point as decimal separator
|
||||
@@ -38,7 +38,8 @@ AbstractEditor {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: ""
|
||||
enabled: originalValue != "" || !editingMode
|
||||
enabled: originalValue != "" || state !== "edit"
|
||||
showFormatters: root.state != "new"
|
||||
property string originalValue: ""
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ AbstractEditor {
|
||||
}
|
||||
|
||||
function markInvalidFields() {
|
||||
keyText.textColor = "black"
|
||||
scoreText.textColor = "black"
|
||||
textArea.textColor = "black"
|
||||
// Fixme
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
function getSupportedKeyTypes() {
|
||||
return ["string", "list", "set", "zset", "hash"]
|
||||
}
|
||||
|
||||
function getEditorByTypeString(keyType) {
|
||||
if (keyType === "string") {
|
||||
return "./editors/SingleItemEditor.qml"
|
||||
} else if (keyType === "list" || keyType === "set") {
|
||||
return "./editors/SingleItemEditor.qml"
|
||||
} else if (keyType === "zset") {
|
||||
return "./editors/SortedSetItemEditor.qml"
|
||||
} else if (keyType === "hash") {
|
||||
return "./editors/HashItemEditor.qml"
|
||||
} else {
|
||||
console.error("Editor for type " + keyType + " is not defined!")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import QtQuick 2.3
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
RowLayout {
|
||||
id: pagination
|
||||
visible: showValueNavigation
|
||||
|
||||
Button {
|
||||
text: "⇤"
|
||||
onClicked: table.goToFirstPage()
|
||||
}
|
||||
Button {
|
||||
text: "⇦"
|
||||
onClicked: table.goToPrevPage()
|
||||
}
|
||||
Text {
|
||||
text: "Page " + table.currentPage + " of " + table.totalPages
|
||||
+ " (Items:" + (table.currentStart+1) + "-"
|
||||
+ (table.currentStart+table.rowCount)
|
||||
+ " of " + table.model.totalRowCount() + ")"
|
||||
}
|
||||
TextField { text: "1"; Layout.fillWidth: true; readOnly: false}
|
||||
Button {
|
||||
text: "Goto Page"
|
||||
onClicked: {}
|
||||
}
|
||||
Button {
|
||||
text: "⇨"
|
||||
onClicked: table.goToNextPage()
|
||||
}
|
||||
Button {
|
||||
text: "⇥"
|
||||
onClicked: table.goToLastPage()
|
||||
}
|
||||
}
|
||||
@@ -69,24 +69,21 @@ Rectangle {
|
||||
color: "red"
|
||||
text: styleData.title
|
||||
}
|
||||
Button {
|
||||
text: "x"
|
||||
Layout.maximumWidth: 18
|
||||
Layout.maximumHeight: 18
|
||||
Item {
|
||||
Layout.preferredWidth: 18
|
||||
Layout.preferredHeight: 18
|
||||
onClicked: {
|
||||
tabs.getTab(styleData.index).close(styleData.index)
|
||||
}
|
||||
|
||||
style: ButtonStyle {
|
||||
background: Rectangle {
|
||||
border.width: control.hovered? 1 : 0
|
||||
border.color: control.hovered? "#000" : "#fff"
|
||||
radius: 0
|
||||
color: control.hovered? "red" : "#fff"
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 2
|
||||
source: "qrc:/images/clear.png"
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
tabs.getTab(styleData.index).close(styleData.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,6 +114,10 @@ Rectangle {
|
||||
standardButtons: StandardButton.Ok
|
||||
}
|
||||
|
||||
AddKeyDialog {
|
||||
id: addNewKeyDialog
|
||||
visible: false
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: viewModel
|
||||
@@ -132,5 +133,10 @@ Rectangle {
|
||||
if (welcomeTab && welcomeTab.not_mapped)
|
||||
tabs.removeTab(0)
|
||||
}
|
||||
|
||||
onNewKeyDialog: {
|
||||
console.log(dbIdentificationString, keyPrefix)
|
||||
addNewKeyDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,5 +41,8 @@
|
||||
<file>qml/editors/formatters/php-unserialize.js</file>
|
||||
<file>qml/editors/formatters/php-serialize.js</file>
|
||||
<file>qml/editors/formatters/hexy.js</file>
|
||||
<file>qml/editors/editor.js</file>
|
||||
<file>qml/parts/Pagination.qml</file>
|
||||
<file>qml/AddKeyDialog.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -4,29 +4,7 @@
|
||||
#include "test_abstractkey.h"
|
||||
#include "app/models/key-models/abstractkey.h"
|
||||
|
||||
void TestAbstractKey::testValueToEscapedString()
|
||||
void TestAbstractKey::testValueToBinary()
|
||||
{
|
||||
// given
|
||||
QByteArray test("123");
|
||||
test.append('\0');
|
||||
test.append("\u2605");
|
||||
test.append("456");
|
||||
|
||||
// when
|
||||
QVariant actualResult = valueToEscapedString(test);
|
||||
|
||||
// then
|
||||
QCOMPARE(actualResult.toString(), QString("123\\x00\u2605456"));
|
||||
}
|
||||
|
||||
void TestAbstractKey::testEscapedStringToValue()
|
||||
{
|
||||
// given
|
||||
QString test("123\\x00\u2605456");
|
||||
|
||||
// when
|
||||
QByteArray actualResult = escapedStringToValue(test);
|
||||
|
||||
// then
|
||||
QCOMPARE(actualResult.size(), 10);
|
||||
// TODO:
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ class TestAbstractKey : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void testValueToEscapedString();
|
||||
void testEscapedStringToValue();
|
||||
//void testValueToBinary();
|
||||
void testValueToBinary();
|
||||
|
||||
};
|
||||
|
||||
@@ -29,4 +29,5 @@ public:
|
||||
|
||||
virtual void openKeyTab(ConnectionsTree::KeyItem&, bool) override {}
|
||||
virtual void openConsoleTab() override {}
|
||||
void openNewKeyDialog(int, QString = QString()) override {}
|
||||
};
|
||||
|
||||
@@ -5,9 +5,11 @@ HEADERS += \
|
||||
$$PWD/mocks/*.h \
|
||||
$$CONSOLE_SRC_DIR/consoletab.h \
|
||||
$$CONSOLE_SRC_DIR/operations.h \
|
||||
$$CONSOLE_SRC_DIR/hex_utils.h \
|
||||
$$CONSOLE_SRC_DIR/../basetab.h \
|
||||
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/*.cpp \
|
||||
$$CONSOLE_SRC_DIR/consoletab.cpp \
|
||||
$$CONSOLE_SRC_DIR/hex_utils.cpp \
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "test_console.h"
|
||||
#include "console/consoletab.h"
|
||||
#include "console/hex_untils.h"
|
||||
#include "mocks/consoleoperations.h"
|
||||
#include <QTest>
|
||||
|
||||
@@ -19,3 +20,20 @@ void TestConsole::testWidget()
|
||||
//then
|
||||
QCOMPARE(tab.getTitle(), operations->getConsoleName());
|
||||
}
|
||||
|
||||
void TestConsole::testHexUtils()
|
||||
{
|
||||
// given
|
||||
QByteArray test("123");
|
||||
test.append('\0');
|
||||
test.append("\u2605");
|
||||
test.append("456");
|
||||
|
||||
// when
|
||||
QString actualResult = binaryStringToEscapedString(test);
|
||||
QByteArray actualResult2 = escapedStringToBinaryString(actualResult);
|
||||
|
||||
// then
|
||||
QCOMPARE(actualResult, QString("123\\x00\u2605456"));
|
||||
QCOMPARE(actualResult2, test);
|
||||
}
|
||||
|
||||
@@ -10,5 +10,6 @@ public:
|
||||
|
||||
private slots:
|
||||
void testWidget();
|
||||
void testHexUtils();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user