mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 08:37:26 +00:00
Use CutterJson for Signatures and rewrite JsonModel (#2997)
This fixes a double-free in getSignatureInfo() when the string was already freed by the intermediate CutterJson. But actually just using this CutterJson makes more sense than the string anyway, so let's do that. The old JsonModel rebuilt the entire structure, defeating the main purpose of a custom model in comparison to the existing QTreeWidget. And since we are holding the json structures ourselves anyway, such a custom model does not have many benefits anyway.
This commit is contained in:
parent
51c0a3d469
commit
db0d4d85a6
@ -72,7 +72,6 @@ set(SOURCES
|
|||||||
widgets/CutterTreeWidget.cpp
|
widgets/CutterTreeWidget.cpp
|
||||||
widgets/GraphWidget.cpp
|
widgets/GraphWidget.cpp
|
||||||
widgets/OverviewWidget.cpp
|
widgets/OverviewWidget.cpp
|
||||||
common/JsonTreeItem.cpp
|
|
||||||
common/JsonModel.cpp
|
common/JsonModel.cpp
|
||||||
dialogs/VersionInfoDialog.cpp
|
dialogs/VersionInfoDialog.cpp
|
||||||
widgets/FlirtWidget.cpp
|
widgets/FlirtWidget.cpp
|
||||||
@ -222,7 +221,6 @@ set(HEADER_FILES
|
|||||||
widgets/CutterTreeWidget.h
|
widgets/CutterTreeWidget.h
|
||||||
widgets/GraphWidget.h
|
widgets/GraphWidget.h
|
||||||
widgets/OverviewWidget.h
|
widgets/OverviewWidget.h
|
||||||
common/JsonTreeItem.h
|
|
||||||
common/JsonModel.h
|
common/JsonModel.h
|
||||||
dialogs/VersionInfoDialog.h
|
dialogs/VersionInfoDialog.h
|
||||||
widgets/FlirtWidget.h
|
widgets/FlirtWidget.h
|
||||||
|
@ -1,123 +1,38 @@
|
|||||||
#include "JsonModel.h"
|
#include "JsonModel.h"
|
||||||
|
|
||||||
#include <QIODevice>
|
QTreeWidgetItem *Cutter::jsonTreeWidgetItem(const QString &key, const CutterJson &json)
|
||||||
|
|
||||||
JsonModel::JsonModel(QObject *parent) : QAbstractItemModel(parent)
|
|
||||||
{
|
{
|
||||||
mRootItem = new JsonTreeItem;
|
QString val;
|
||||||
mHeaders.append("key");
|
switch (json.type()) {
|
||||||
mHeaders.append("value");
|
case RZ_JSON_STRING:
|
||||||
}
|
val = json.toString();
|
||||||
|
break;
|
||||||
JsonModel::~JsonModel()
|
case RZ_JSON_BOOLEAN:
|
||||||
{
|
val = json.toBool() ? "true" : "false";
|
||||||
delete mRootItem;
|
break;
|
||||||
}
|
case RZ_JSON_DOUBLE:
|
||||||
|
val = QString::number(json.lowLevelValue()->num.dbl_value);
|
||||||
bool JsonModel::load(QIODevice *device)
|
break;
|
||||||
{
|
case RZ_JSON_INTEGER:
|
||||||
return loadJson(device->readAll());
|
val = QString::number(json.toUt64());
|
||||||
}
|
break;
|
||||||
|
case RZ_JSON_NULL:
|
||||||
bool JsonModel::loadJson(const QByteArray &json)
|
val = "null";
|
||||||
{
|
break;
|
||||||
mDocument = QJsonDocument::fromJson(json);
|
case RZ_JSON_OBJECT:
|
||||||
|
case RZ_JSON_ARRAY:
|
||||||
if (!mDocument.isNull()) {
|
break;
|
||||||
beginResetModel();
|
}
|
||||||
delete mRootItem;
|
auto r = new QTreeWidgetItem(QStringList({ key, val }));
|
||||||
if (mDocument.isArray()) {
|
if (json.type() == RZ_JSON_ARRAY) {
|
||||||
mRootItem = JsonTreeItem::load(QJsonValue(mDocument.array()));
|
size_t i = 0;
|
||||||
} else {
|
for (const auto &child : json) {
|
||||||
mRootItem = JsonTreeItem::load(QJsonValue(mDocument.object()));
|
r->addChild(jsonTreeWidgetItem(QString::number(i++), child));
|
||||||
|
}
|
||||||
|
} else if (json.type() == RZ_JSON_OBJECT) {
|
||||||
|
for (const auto &child : json) {
|
||||||
|
r->addChild(jsonTreeWidgetItem(child.key(), child));
|
||||||
}
|
}
|
||||||
endResetModel();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return r;
|
||||||
}
|
|
||||||
|
|
||||||
QVariant JsonModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!index.isValid())
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
JsonTreeItem *item = static_cast<JsonTreeItem *>(index.internalPointer());
|
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
|
||||||
|
|
||||||
if (index.column() == 0)
|
|
||||||
return QString("%1").arg(item->key());
|
|
||||||
|
|
||||||
if (index.column() == 1)
|
|
||||||
return QString("%1").arg(item->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant JsonModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
||||||
{
|
|
||||||
if (role != Qt::DisplayRole)
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
if (orientation == Qt::Horizontal) {
|
|
||||||
|
|
||||||
return mHeaders.value(section);
|
|
||||||
} else
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex JsonModel::index(int row, int column, const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
if (!hasIndex(row, column, parent))
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
JsonTreeItem *parentItem;
|
|
||||||
|
|
||||||
if (!parent.isValid())
|
|
||||||
parentItem = mRootItem;
|
|
||||||
else
|
|
||||||
parentItem = static_cast<JsonTreeItem *>(parent.internalPointer());
|
|
||||||
|
|
||||||
JsonTreeItem *childItem = parentItem->child(row);
|
|
||||||
if (childItem)
|
|
||||||
return createIndex(row, column, childItem);
|
|
||||||
else
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex JsonModel::parent(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
if (!index.isValid())
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
JsonTreeItem *childItem = static_cast<JsonTreeItem *>(index.internalPointer());
|
|
||||||
JsonTreeItem *parentItem = childItem->parent();
|
|
||||||
|
|
||||||
if (parentItem == mRootItem)
|
|
||||||
return QModelIndex();
|
|
||||||
|
|
||||||
return createIndex(parentItem->row(), 0, parentItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
int JsonModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
JsonTreeItem *parentItem;
|
|
||||||
if (parent.column() > 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!parent.isValid())
|
|
||||||
parentItem = mRootItem;
|
|
||||||
else
|
|
||||||
parentItem = static_cast<JsonTreeItem *>(parent.internalPointer());
|
|
||||||
|
|
||||||
return parentItem->childCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
int JsonModel::columnCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(parent)
|
|
||||||
return 2;
|
|
||||||
}
|
}
|
||||||
|
@ -2,37 +2,13 @@
|
|||||||
#ifndef JSONMODEL_H
|
#ifndef JSONMODEL_H
|
||||||
#define JSONMODEL_H
|
#define JSONMODEL_H
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QTreeWidgetItem>
|
||||||
#include <QJsonDocument>
|
#include "CutterJson.h"
|
||||||
#include <QJsonValue>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QIcon>
|
|
||||||
|
|
||||||
#include "JsonTreeItem.h"
|
namespace Cutter {
|
||||||
|
|
||||||
class JsonTreeItem;
|
QTreeWidgetItem *jsonTreeWidgetItem(const QString &key, const CutterJson &json);
|
||||||
|
|
||||||
class JsonModel : public QAbstractItemModel
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit JsonModel(QObject *parent = nullptr);
|
|
||||||
bool load(QIODevice *device);
|
|
||||||
bool loadJson(const QByteArray &json);
|
|
||||||
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
|
|
||||||
QModelIndex index(int row, int column,
|
|
||||||
const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
|
||||||
QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE;
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
|
||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
|
||||||
~JsonModel();
|
|
||||||
|
|
||||||
private:
|
|
||||||
JsonTreeItem *mRootItem;
|
|
||||||
QJsonDocument mDocument;
|
|
||||||
QStringList mHeaders;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // JSONMODEL_H
|
#endif // JSONMODEL_H
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
#include "JsonTreeItem.h"
|
|
||||||
|
|
||||||
JsonTreeItem::JsonTreeItem(JsonTreeItem *parent)
|
|
||||||
{
|
|
||||||
mParent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonTreeItem::~JsonTreeItem()
|
|
||||||
{
|
|
||||||
qDeleteAll(mChilds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonTreeItem::appendChild(JsonTreeItem *item)
|
|
||||||
{
|
|
||||||
mChilds.append(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonTreeItem *JsonTreeItem::child(int row)
|
|
||||||
{
|
|
||||||
return mChilds.value(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonTreeItem *JsonTreeItem::parent()
|
|
||||||
{
|
|
||||||
return mParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
int JsonTreeItem::childCount() const
|
|
||||||
{
|
|
||||||
return mChilds.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int JsonTreeItem::row() const
|
|
||||||
{
|
|
||||||
if (mParent)
|
|
||||||
return mParent->mChilds.indexOf(const_cast<JsonTreeItem *>(this));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonTreeItem::setKey(const QString &key)
|
|
||||||
{
|
|
||||||
mKey = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonTreeItem::setValue(const QString &value)
|
|
||||||
{
|
|
||||||
mValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonTreeItem::setType(const QJsonValue::Type &type)
|
|
||||||
{
|
|
||||||
mType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString JsonTreeItem::key() const
|
|
||||||
{
|
|
||||||
return mKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString JsonTreeItem::value() const
|
|
||||||
{
|
|
||||||
return mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonValue::Type JsonTreeItem::type() const
|
|
||||||
{
|
|
||||||
return mType;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonTreeItem *JsonTreeItem::load(const QJsonValue &value, JsonTreeItem *parent)
|
|
||||||
{
|
|
||||||
JsonTreeItem *rootItem = new JsonTreeItem(parent);
|
|
||||||
rootItem->setKey("root");
|
|
||||||
|
|
||||||
if (value.isObject()) {
|
|
||||||
|
|
||||||
// Get all QJsonValue childs
|
|
||||||
for (const QString &key : value.toObject().keys()) {
|
|
||||||
QJsonValue v = value.toObject().value(key);
|
|
||||||
JsonTreeItem *child = load(v, rootItem);
|
|
||||||
child->setKey(key);
|
|
||||||
child->setType(v.type());
|
|
||||||
rootItem->appendChild(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (value.isArray()) {
|
|
||||||
// Get all QJsonValue childs
|
|
||||||
int index = 0;
|
|
||||||
for (const QJsonValue &v : value.toArray()) {
|
|
||||||
|
|
||||||
JsonTreeItem *child = load(v, rootItem);
|
|
||||||
child->setKey(QString::number(index));
|
|
||||||
child->setType(v.type());
|
|
||||||
rootItem->appendChild(child);
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rootItem->setValue(value.toVariant().toString());
|
|
||||||
rootItem->setType(value.type());
|
|
||||||
}
|
|
||||||
|
|
||||||
return rootItem;
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
#ifndef JSONTREEITEM_H
|
|
||||||
#define JSONTREEITEM_H
|
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonValue>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QIcon>
|
|
||||||
|
|
||||||
#include "JsonModel.h"
|
|
||||||
|
|
||||||
class JsonTreeItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
JsonTreeItem(JsonTreeItem *parent = nullptr);
|
|
||||||
~JsonTreeItem();
|
|
||||||
void appendChild(JsonTreeItem *item);
|
|
||||||
JsonTreeItem *child(int row);
|
|
||||||
JsonTreeItem *parent();
|
|
||||||
int childCount() const;
|
|
||||||
int row() const;
|
|
||||||
void setKey(const QString &key);
|
|
||||||
void setValue(const QString &value);
|
|
||||||
void setType(const QJsonValue::Type &type);
|
|
||||||
QString key() const;
|
|
||||||
QString value() const;
|
|
||||||
QJsonValue::Type type() const;
|
|
||||||
static JsonTreeItem *load(const QJsonValue &value, JsonTreeItem *parent = nullptr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString mKey;
|
|
||||||
QString mValue;
|
|
||||||
QJsonValue::Type mType;
|
|
||||||
QList<JsonTreeItem *> mChilds;
|
|
||||||
JsonTreeItem *mParent;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // JSONTREEITEM_H
|
|
@ -1440,7 +1440,7 @@ bool CutterCore::registerDecompiler(Decompiler *decompiler)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CutterCore::getSignatureInfo()
|
CutterJson CutterCore::getSignatureInfo()
|
||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
RzBinFile *cur = rz_bin_cur(core->bin);
|
RzBinFile *cur = rz_bin_cur(core->bin);
|
||||||
@ -1452,11 +1452,7 @@ QString CutterCore::getSignatureInfo()
|
|||||||
if (!signature) {
|
if (!signature) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto sig = parseJson(signature, nullptr);
|
return parseJson(signature, nullptr);
|
||||||
if (sig.size() == 0) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return fromOwnedCharPtr(signature);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CutterCore::existsFileInfo()
|
bool CutterCore::existsFileInfo()
|
||||||
|
@ -569,7 +569,7 @@ public:
|
|||||||
bool registerDecompiler(Decompiler *decompiler);
|
bool registerDecompiler(Decompiler *decompiler);
|
||||||
|
|
||||||
RVA getOffsetJump(RVA addr);
|
RVA getOffsetJump(RVA addr);
|
||||||
QString getSignatureInfo();
|
CutterJson getSignatureInfo();
|
||||||
bool existsFileInfo();
|
bool existsFileInfo();
|
||||||
void setGraphEmpty(bool empty);
|
void setGraphEmpty(bool empty);
|
||||||
bool isGraphEmpty();
|
bool isGraphEmpty();
|
||||||
|
@ -70,7 +70,6 @@ public:
|
|||||||
iterator end() const { return iterator(nullptr, nullptr); }
|
iterator end() const { return iterator(nullptr, nullptr); }
|
||||||
|
|
||||||
bool toBool() const { return value && value->type == RZ_JSON_BOOLEAN && value->num.u_value; }
|
bool toBool() const { return value && value->type == RZ_JSON_BOOLEAN && value->num.u_value; }
|
||||||
QString toJson() const { return rz_json_as_string(value); }
|
|
||||||
st64 toSt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.s_value : 0; }
|
st64 toSt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.s_value : 0; }
|
||||||
ut64 toUt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.u_value : 0; }
|
ut64 toUt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.u_value : 0; }
|
||||||
|
|
||||||
|
@ -4,8 +4,13 @@
|
|||||||
CutterTreeView::CutterTreeView(QWidget *parent) : QTreeView(parent), ui(new Ui::CutterTreeView())
|
CutterTreeView::CutterTreeView(QWidget *parent) : QTreeView(parent), ui(new Ui::CutterTreeView())
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
applyCutterStyle(this);
|
||||||
this->setUniformRowHeights(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterTreeView::~CutterTreeView() {}
|
CutterTreeView::~CutterTreeView() {}
|
||||||
|
|
||||||
|
void CutterTreeView::applyCutterStyle(QTreeView *view)
|
||||||
|
{
|
||||||
|
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
view->setUniformRowHeights(true);
|
||||||
|
}
|
||||||
|
@ -19,6 +19,8 @@ public:
|
|||||||
explicit CutterTreeView(QWidget *parent = nullptr);
|
explicit CutterTreeView(QWidget *parent = nullptr);
|
||||||
~CutterTreeView();
|
~CutterTreeView();
|
||||||
|
|
||||||
|
static void applyCutterStyle(QTreeView *view);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::CutterTreeView> ui;
|
std::unique_ptr<Ui::CutterTreeView> ui;
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include "ui_Dashboard.h"
|
#include "ui_Dashboard.h"
|
||||||
#include "common/Helpers.h"
|
#include "common/Helpers.h"
|
||||||
#include "common/JsonModel.h"
|
#include "common/JsonModel.h"
|
||||||
#include "common/JsonTreeItem.h"
|
|
||||||
#include "common/TempConfig.h"
|
#include "common/TempConfig.h"
|
||||||
#include "dialogs/VersionInfoDialog.h"
|
#include "dialogs/VersionInfoDialog.h"
|
||||||
|
|
||||||
@ -162,7 +161,7 @@ void Dashboard::updateContents()
|
|||||||
ui->verticalLayout_2->addSpacerItem(spacer);
|
ui->verticalLayout_2->addSpacerItem(spacer);
|
||||||
|
|
||||||
// Check if signature info and version info available
|
// Check if signature info and version info available
|
||||||
if (Core()->getSignatureInfo().isEmpty()) {
|
if (!Core()->getSignatureInfo().size()) {
|
||||||
ui->certificateButton->setEnabled(false);
|
ui->certificateButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
ui->versioninfoButton->setEnabled(Core()->existsFileInfo());
|
ui->versioninfoButton->setEnabled(Core()->existsFileInfo());
|
||||||
@ -170,33 +169,24 @@ void Dashboard::updateContents()
|
|||||||
|
|
||||||
void Dashboard::on_certificateButton_clicked()
|
void Dashboard::on_certificateButton_clicked()
|
||||||
{
|
{
|
||||||
static QDialog *viewDialog = nullptr;
|
QDialog dialog(this);
|
||||||
static CutterTreeView *view = nullptr;
|
auto view = new QTreeWidget(&dialog);
|
||||||
static JsonModel *model = nullptr;
|
view->setHeaderLabels({ tr("Key"), tr("Value") });
|
||||||
static QString qstrCertificates;
|
view->addTopLevelItem(Cutter::jsonTreeWidgetItem(QString("<%1>").arg(tr("root")),
|
||||||
if (!viewDialog) {
|
Core()->getSignatureInfo()));
|
||||||
viewDialog = new QDialog(this);
|
CutterTreeView::applyCutterStyle(view);
|
||||||
view = new CutterTreeView(viewDialog);
|
view->expandAll();
|
||||||
model = new JsonModel();
|
view->resize(900, 600);
|
||||||
qstrCertificates = Core()->getSignatureInfo();
|
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
}
|
sizePolicy.setHorizontalStretch(0);
|
||||||
if (!viewDialog->isVisible()) {
|
sizePolicy.setVerticalStretch(0);
|
||||||
std::string strCertificates = qstrCertificates.toUtf8().constData();
|
sizePolicy.setHeightForWidth(view->sizePolicy().hasHeightForWidth());
|
||||||
model->loadJson(QByteArray::fromStdString(strCertificates));
|
dialog.setSizePolicy(sizePolicy);
|
||||||
view->setModel(model);
|
dialog.setMinimumSize(QSize(900, 600));
|
||||||
view->expandAll();
|
dialog.setMaximumSize(QSize(900, 600));
|
||||||
view->resize(900, 600);
|
dialog.setSizeGripEnabled(false);
|
||||||
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
dialog.setWindowTitle("Certificates");
|
||||||
sizePolicy.setHorizontalStretch(0);
|
dialog.exec();
|
||||||
sizePolicy.setVerticalStretch(0);
|
|
||||||
sizePolicy.setHeightForWidth(view->sizePolicy().hasHeightForWidth());
|
|
||||||
viewDialog->setSizePolicy(sizePolicy);
|
|
||||||
viewDialog->setMinimumSize(QSize(900, 600));
|
|
||||||
viewDialog->setMaximumSize(QSize(900, 600));
|
|
||||||
viewDialog->setSizeGripEnabled(false);
|
|
||||||
viewDialog->setWindowTitle("Certificates");
|
|
||||||
viewDialog->show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dashboard::on_versioninfoButton_clicked()
|
void Dashboard::on_versioninfoButton_clicked()
|
||||||
|
Loading…
Reference in New Issue
Block a user