GUI: make it possible to save changes in library editor

This commit is contained in:
Daniel Marjamäki 2015-08-23 12:49:51 +02:00
parent 1b29a99e45
commit ea7209e669
3 changed files with 182 additions and 30 deletions

View File

@ -25,6 +25,7 @@
#include <QDomNodeList> #include <QDomNodeList>
#include <QSettings> #include <QSettings>
#include <QFileDialog> #include <QFileDialog>
#include <QTextStream>
const unsigned int LibraryDialog::Function::Arg::ANY = ~0U; const unsigned int LibraryDialog::Function::Arg::ANY = ~0U;
@ -35,6 +36,7 @@ LibraryDialog::LibraryDialog(QWidget *parent) :
ui(new Ui::LibraryDialog) ui(new Ui::LibraryDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->buttonSave->setEnabled(false);
} }
LibraryDialog::~LibraryDialog() LibraryDialog::~LibraryDialog()
@ -42,14 +44,6 @@ LibraryDialog::~LibraryDialog()
delete ui; delete ui;
} }
void LibraryDialog::updateui()
{
ui->functions->clear();
for (const struct Function &function : functions) {
ui->functions->addItem(function.name);
}
}
static LibraryDialog::Function::Arg loadFunctionArg(const QDomElement &functionArgElement) static LibraryDialog::Function::Arg loadFunctionArg(const QDomElement &functionArgElement)
{ {
LibraryDialog::Function::Arg arg; LibraryDialog::Function::Arg arg;
@ -141,10 +135,86 @@ void LibraryDialog::openCfg()
QFile file(selectedFile); QFile file(selectedFile);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
loadFile(file); loadFile(file);
updateui();
mFileName = selectedFile;
ui->buttonSave->setEnabled(false);
ui->functions->clear();
foreach (const struct Function &function, functions)
ui->functions->addItem(function.name);
}
}
}
static QDomElement FunctionElement(QDomDocument &doc, const LibraryDialog::Function &function)
{
QDomElement functionElement = doc.createElement("function");
functionElement.setAttribute("name", function.name);
if (!function.noreturn) {
QDomElement e = doc.createElement("noreturn");
e.appendChild(doc.createTextNode("false"));
functionElement.appendChild(e);
}
if (function.useretval)
functionElement.appendChild(doc.createElement("useretval"));
if (function.leakignore)
functionElement.appendChild(doc.createElement("leak-ignore"));
// Argument info..
foreach (const LibraryDialog::Function::Arg &arg, function.args) {
QDomElement argElement = doc.createElement("arg");
functionElement.appendChild(argElement);
if (arg.nr == LibraryDialog::Function::Arg::ANY)
argElement.setAttribute("nr", "any");
else
argElement.setAttribute("nr", arg.nr);
if (arg.notbool)
argElement.appendChild(doc.createElement("not-bool"));
if (arg.notnull)
argElement.appendChild(doc.createElement("not-null"));
if (arg.notuninit)
argElement.appendChild(doc.createElement("not-uninit"));
if (arg.strz)
argElement.appendChild(doc.createElement("strz"));
if (arg.formatstr)
argElement.appendChild(doc.createElement("formatstr"));
if (!arg.valid.isEmpty()) {
QDomElement e = doc.createElement("valid");
e.appendChild(doc.createTextNode(arg.valid));
argElement.appendChild(e);
}
if (!arg.minsize.type.isEmpty()) {
QDomElement e = doc.createElement("minsize");
e.setAttribute("type", arg.minsize.type);
e.setAttribute("arg", arg.minsize.arg);
if (!arg.minsize.arg2.isEmpty())
e.setAttribute("arg2", arg.minsize.arg2);
argElement.appendChild(e);
} }
} }
return functionElement;
}
void LibraryDialog::saveCfg()
{
QDomDocument doc;
QDomElement root = doc.createElement("def");
doc.appendChild(root);
root.setAttribute("format","2");
foreach (const Function &function, functions) {
root.appendChild(FunctionElement(doc, function));
}
QFile file(mFileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream ts( &file );
ts << doc.toString();
ui->buttonSave->setEnabled(false);
}
} }
void LibraryDialog::selectFunction(int row) void LibraryDialog::selectFunction(int row)
@ -154,16 +224,29 @@ void LibraryDialog::selectFunction(int row)
ui->useretval->setChecked(function.useretval); ui->useretval->setChecked(function.useretval);
ui->leakignore->setChecked(function.leakignore); ui->leakignore->setChecked(function.leakignore);
ui->arguments->clear(); ui->arguments->clear();
for (const Function::Arg &arg : function.args) { foreach (const Function::Arg &arg, function.args) {
QString s("arg"); QString s("arg");
if (arg.nr != Function::Arg::ANY) if (arg.nr != Function::Arg::ANY)
s += QString::number(arg.nr); s += QString::number(arg.nr);
if (arg.formatstr) if (arg.formatstr)
s += " formatstr"; s += " formatstr";
else if (!arg.strz) else if (arg.strz)
s += " strz"; s += " strz";
else if (!arg.valid.isNull()) else if (!arg.valid.isNull())
s += " " + arg.valid; s += " " + arg.valid;
ui->arguments->addItem(s); ui->arguments->addItem(s);
} }
} }
void LibraryDialog::changeFunction()
{
foreach (const QListWidgetItem *item, ui->functions->selectedItems())
{
Function &function = functions[ui->functions->row(item)];
function.noreturn = !ui->functionreturn->isChecked();
function.useretval = ui->useretval->isChecked();
function.leakignore = ui->leakignore->isChecked();
}
ui->buttonSave->setEnabled(true);
}

View File

@ -34,7 +34,7 @@ public:
~LibraryDialog(); ~LibraryDialog();
struct Function { struct Function {
Function() : noreturn(false), gccPure(false), gccConst(false), Function() : noreturn(true), gccPure(false), gccConst(false),
leakignore(false), useretval(false) { leakignore(false), useretval(false) {
} }
@ -73,7 +73,9 @@ public:
private slots: private slots:
void openCfg(); void openCfg();
void saveCfg();
void selectFunction(int row); void selectFunction(int row);
void changeFunction();
private: private:
Ui::LibraryDialog *ui; Ui::LibraryDialog *ui;
@ -81,6 +83,7 @@ private:
void updateui(); void updateui();
bool loadFile(QFile &file); bool loadFile(QFile &file);
QList<struct Function> functions; QList<struct Function> functions;
QString mFileName;
}; };
#endif // LIBRARYDIALOG_H #endif // LIBRARYDIALOG_H

View File

@ -15,24 +15,18 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<widget class="QLabel" name="label"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="autoFillBackground"> <item>
<bool>false</bool> <widget class="QPushButton" name="buttonOpen">
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color : red; color : blue; }</string>
</property>
<property name="text"> <property name="text">
<string>EXPERIMENTAL</string> <string>Open</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <widget class="QPushButton" name="buttonSave">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text"> <property name="text">
<string>Open</string> <string>Save</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -64,8 +58,14 @@
</item> </item>
<item> <item>
<widget class="QListWidget" name="functions"> <widget class="QListWidget" name="functions">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum> <enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property> </property>
</widget> </widget>
</item> </item>
@ -142,14 +142,14 @@
</hints> </hints>
</connection> </connection>
<connection> <connection>
<sender>pushButton</sender> <sender>buttonOpen</sender>
<signal>clicked()</signal> <signal>clicked()</signal>
<receiver>LibraryDialog</receiver> <receiver>LibraryDialog</receiver>
<slot>openCfg()</slot> <slot>openCfg()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>56</x> <x>61</x>
<y>36</y> <y>27</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>72</x> <x>72</x>
@ -157,9 +157,75 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>functionreturn</sender>
<signal>clicked()</signal>
<receiver>LibraryDialog</receiver>
<slot>changeFunction()</slot>
<hints>
<hint type="sourcelabel">
<x>327</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>353</x>
<y>2</y>
</hint>
</hints>
</connection>
<connection>
<sender>useretval</sender>
<signal>clicked()</signal>
<receiver>LibraryDialog</receiver>
<slot>changeFunction()</slot>
<hints>
<hint type="sourcelabel">
<x>372</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>475</x>
<y>5</y>
</hint>
</hints>
</connection>
<connection>
<sender>leakignore</sender>
<signal>clicked()</signal>
<receiver>LibraryDialog</receiver>
<slot>changeFunction()</slot>
<hints>
<hint type="sourcelabel">
<x>419</x>
<y>99</y>
</hint>
<hint type="destinationlabel">
<x>319</x>
<y>3</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonSave</sender>
<signal>clicked()</signal>
<receiver>LibraryDialog</receiver>
<slot>saveCfg()</slot>
<hints>
<hint type="sourcelabel">
<x>102</x>
<y>9</y>
</hint>
<hint type="destinationlabel">
<x>115</x>
<y>1</y>
</hint>
</hints>
</connection>
</connections> </connections>
<slots> <slots>
<slot>selectFunction(int)</slot> <slot>selectFunction(int)</slot>
<slot>openCfg()</slot> <slot>openCfg()</slot>
<slot>changeFunction()</slot>
<slot>saveCfg()</slot>
</slots> </slots>
</ui> </ui>