Git commit f9824efbf8e2ee84c3752c0a14edec7836d0e873 by Giorgos Tsiapaliwkas. Committed on 30/06/2012 at 15:36. Pushed by tsiapaliwkas into branch 'terietor/kconfigxt'. Populate the ui of kconfigxteditor and make it read "real" data from the xml M +114 -6 editors/kconfigxt/kconfigxteditor.cpp M +42 -0 editors/kconfigxt/kconfigxteditor.h M +41 -32 editors/kconfigxt/kconfigxteditor.ui M +194 -56 editors/kconfigxt/kconfigxtparser.cpp M +42 -15 editors/kconfigxt/kconfigxtparser.h M +10 -12 editors/kconfigxt/standalone/plasmakconfigxteditor.cpp M +1 -1 editors/kconfigxt/standalone/plasmakconfigxteditor.h M +0 -1 mainwindow.cpp http://commits.kde.org/plasmate/f9824efbf8e2ee84c3752c0a14edec7836d0e873 diff --git a/editors/kconfigxt/kconfigxteditor.cpp b/editors/kconfigxt/kcon= figxteditor.cpp index 3ea1ee9..8f48282 100644 --- a/editors/kconfigxt/kconfigxteditor.cpp +++ b/editors/kconfigxt/kconfigxteditor.cpp @@ -31,12 +31,15 @@ KConfigXtEditor::KConfigXtEditor(QWidget *parent) { m_ui.setupUi(this); = - m_ui.twKeyValues->header()->setResizeMode(QHeaderView::ResizeToContent= s); + m_ui.twEntries->header()->setResizeMode(QHeaderView::ResizeToContents); m_ui.twGroups->header()->setResizeMode(QHeaderView::ResizeToContents); = m_ui.lblHintIcon->setPixmap(KIcon("dialog-information").pixmap(16, 16)= ); = - connect(m_ui.pbAddGroup, SIGNAL(clicked()), SLOT(createNewGroup())); + connect(m_ui.pbAddGroup, SIGNAL(clicked()), this, SLOT(createNewGroup(= ))); + connect(m_ui.twGroups, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTr= eeWidgetItem*)), + this, SLOT(setupWidgetsForEntries(QTreeWidgetItem*))); + connect(m_ui.pbDeleteGroup, SIGNAL(clicked()), this, SLOT(removeGroup(= ))); = //hide the source related ui stuff m_ui.srcLabel1->setVisible(false); @@ -57,15 +60,17 @@ void KConfigXtEditor::readFile() return; } = + //check if the xml exists if (!QFile::exists(m_filename.pathOrUrl())) { setupWidgetsForNewFile(); return; } else { m_parser.setConfigXmlFile(m_filename.pathOrUrl()); + //parse the xml m_parser.parse(); + takeDataFromParser(); + setupWidgetsForOldFile(); } - - // TODO: reading goes here } = void KConfigXtEditor::writeFile() @@ -79,8 +84,14 @@ void KConfigXtEditor::setupWidgetsForNewFile() createNewGroup(); } = +void KConfigXtEditor::setupWidgetsForOldFile() +{ + setupWidgetsForGroups(); +} + void KConfigXtEditor::createNewGroup() { + m_ui.twEntries->clear(); QString newGroupName; if (m_groups.isEmpty()) { newGroupName =3D "General"; @@ -95,12 +106,109 @@ void KConfigXtEditor::createNewGroup() = m_groups.append(newGroupName); = - QTreeWidgetItem* item =3D new QTreeWidgetItem; - item->setText(0, newGroupName); + addGroupToUi(newGroupName); +} + + +void KConfigXtEditor::setupWidgetsForGroups() +{ + foreach(const QString& group, m_groups) { + addGroupToUi(group); + } +} + +void KConfigXtEditor::setupWidgetsForEntries(QTreeWidgetItem *item) +{ + //the currectIndex of m_ui.twGroups has changed. + //this means that we need to load the data for the new + //group so remove the old items + m_ui.twEntries->clear(); + + if (!item) { + return; + } + + //take keys,values and types for the specified group + takeDataFromParser(item->text(0)); + + addEntryToUi(m_keysValuesTypes.entryName(), m_keysValuesTypes.entryTyp= e(), m_keysValuesTypes.entryValue()); + +} + +void KConfigXtEditor::takeDataFromParser(const QString& group) +{ + foreach(const KConfigXtParserItem& item, m_parser.dataList()) { + + //take the name of the groups + if (!item.groupName().isEmpty()) { + m_groups << item.groupName(); + } + + if (!group.isEmpty()) { + if (item.groupName() =3D=3D group) { + //we have specified a group + //so probably we want to populate the + //m_ui.twEntries. + m_keysValuesTypes =3D item; + } else { + //we haven't specified a group. + //So we don't want populate the m_ui.twEntries. + //clear the item. + m_keysValuesTypes =3D KConfigXtParserItem(); + } + } + } + +} + +void KConfigXtEditor::addGroupToUi(const QString& group) +{ + QTreeWidgetItem *item =3D new QTreeWidgetItem(); + item->setText(0, group); item->setFlags(item->flags() | Qt::ItemIsEditable); = m_ui.twGroups->addTopLevelItem(item); = m_ui.twGroups->setCurrentItem(item); m_ui.twGroups->editItem(item); + //TODO mem leak? +} + +void KConfigXtEditor::addEntryToUi(const QString& key, const QString& type= , const QString& value) +{ + qDebug() << "key:" + key; + qDebug() << "type:" + type; + qDebug() << "value:" + value; + QTreeWidgetItem *item =3D new QTreeWidgetItem(); + item->setText(0, key); + item->setText(1, type); + item->setText(2, value); + item->setFlags(item->flags() | Qt::ItemIsEditable); + + m_ui.twEntries->addTopLevelItem(item); +} + +void KConfigXtEditor::removeGroup() +{ + QByteArray array; + = + QTreeWidgetItem *item =3D m_ui.twGroups->currentItem(); + + QString group =3D "text(0) + "\">"; + + QFile xmlFile(m_filename.pathOrUrl()); + if(!xmlFile.open(QIODevice::ReadWrite)) { + return; + } + + QTextStream text(&xmlFile); + + while (!text.atEnd()) { + QString line =3D text.readLine(); + if (line =3D=3D group) { + while (line !=3D "") { + array.replace(line,""); + } + } + } } diff --git a/editors/kconfigxt/kconfigxteditor.h b/editors/kconfigxt/kconfi= gxteditor.h index 64ba101..d137e9a 100644 --- a/editors/kconfigxt/kconfigxteditor.h +++ b/editors/kconfigxt/kconfigxteditor.h @@ -27,6 +27,8 @@ #include #include = +class QTreeWidgetItem; + class KConfigXtEditor : public QWidget { Q_OBJECT @@ -58,18 +60,58 @@ private slots: */ void createNewGroup(); = + /** + * Sets up editor widgets for + * the groups. This method should be called every time that the + * a group is modified/deleted/etc. + **/ + void setupWidgetsForGroups(); + + /** + * Sets up editor widgets for + * the entries. This method should be called every time that the + * an entry is modified/deleted/etc. + **/ + void setupWidgetsForEntries(QTreeWidgetItem *item); + + /** + * Removes a group from the xml file + **/ + void removeGroup(); + protected: Ui::KConfigXtEditor m_ui; = private: /** + * Sets up editor widgets for an existing file + * (e.g. creates a default group etc) + */ + void setupWidgetsForOldFile(); + + /** * Sets up editor widgets for a new file * (e.g. creates a default group etc) */ void setupWidgetsForNewFile(); = + /** + * This method takes the groups from the parser + * If group is specified it will also take the + * keys,values and types from the parser for the specified group + **/ + void takeDataFromParser(const QString& group =3D QString()); + + //with this method we avoid duplication + void addGroupToUi(const QString& group); + + //with this method we can avoid duplication + void addEntryToUi(const QString& entryName, + const QString& entryType, const QString& e= ntryValue); + KUrl m_filename; QStringList m_groups; + KConfigXtParserItem m_keysValuesTypes; = KConfigXtParser m_parser; }; diff --git a/editors/kconfigxt/kconfigxteditor.ui b/editors/kconfigxt/kconf= igxteditor.ui index 4d2a9c1..370d4b2 100644 --- a/editors/kconfigxt/kconfigxteditor.ui +++ b/editors/kconfigxt/kconfigxteditor.ui @@ -44,11 +44,25 @@ - - + + + + Add Entry + + + + + + + Delete Entry + + + + + - 1 + 2 0 @@ -57,7 +71,17 @@ - Group + Key + + + + + Type + + + + + Value @@ -69,35 +93,33 @@ - - + + - 2 + 1 0 + + false + - Key - - - - - Value + Group - + - Add Key + Delete Grop - - + + Qt::Horizontal @@ -109,8 +131,8 @@ - - + + Qt::Horizontal @@ -173,19 +195,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/editors/kconfigxt/kconfigxtparser.cpp b/editors/kconfigxt/kcon= figxtparser.cpp index 82926ab..990eed8 100644 --- a/editors/kconfigxt/kconfigxtparser.cpp +++ b/editors/kconfigxt/kconfigxtparser.cpp @@ -25,11 +25,90 @@ = #include #include -/*#include -#include */ + +#include +KConfigXtParserItem::KConfigXtParserItem(QObject* parent) +{ +} + +QString KConfigXtParserItem::groupName() const +{ + return m_groupName; +} + +QString KConfigXtParserItem::entryName() const +{ + return m_entryName; +} + +QString KConfigXtParserItem::entryType() const +{ + return m_entryType; +} + +QString KConfigXtParserItem::entryValue() const +{ + return m_entryValue; +} + +void KConfigXtParserItem::setGroupName(const QString& groupName) +{ + m_groupName =3D groupName; + qDebug() << "groupName:" + groupName; +} + +void KConfigXtParserItem::setEntryName(const QString& entryName) +{ + m_entryName =3D entryName; + qDebug() << "entryName:" + entryName; +} + +void KConfigXtParserItem::setEntryType(const QString& entryType) +{ + //those are the possible types + QStringList types; + types << "string" + <<"String" + <<"StringList" + <<"Font" + <<"Rect" + <<"Size" + <<"Color" + <<"Point" + <<"Int" + <<"UInt" + <<"Bool" + <<"Double" + <<"DateTime" + <<"LongLong" + <<"ULongLong" + <<"IntList" + <<"Enum" + <<"Path" + <<"PathList" + <<"Password" + <<"Url" + <<"UrlList"; + + //check if the entryType is valid + foreach(const QString& type, types) { + if (type =3D=3D entryType) { + //its a type + m_entryType =3D type; + } + } + qDebug() << "entryType:" + entryType; +} + +void KConfigXtParserItem::setEntryValue(const QString& entryValue) +{ + m_entryValue =3D entryValue; + qDebug() << "m_entryValue:" + m_entryValue; +} = KConfigXtParser::KConfigXtParser(QObject *parent) - : QObject(parent) + : QObject(parent), + m_parseResult(false) { = } @@ -38,81 +117,140 @@ void KConfigXtParser::setConfigXmlFile(const QString&= filename) { m_filename =3D filename; } -#include -void KConfigXtParser::parse() + +bool KConfigXtParser::parse() { QFile xmlFile(m_filename); = if (!xmlFile.open(QIODevice::ReadWrite)) { KMessageBox::error(0, i18n("The xml file isn't writable")); - return; + return false; } = - //we need a temporary hash - QHash tmpHash; - QXmlStreamReader reader; reader.setDevice(&xmlFile); -QStringList groups; -QStringList entries; -QStringList elses; - - QStringList groupNameList; - QStringList entriesList; - - while (!reader.atEnd()) { - //for as long as we are still in the same element take the data - if (reader.readNextStartElement()) { - //ignore all the elements that are - //named "kcfg" and "kcgfile" or they are "" - //we don't want those to appear in the ui - if (reader.name() !=3D "kcfg" && reader.name() !=3D "kcfgfile"= && !reader.name().isEmpty()) { - //qDebug() << "element text" <value().toString(); - // qDebug() << "element name" << reader.name().toString() - if (reader.name() =3D=3D "group") { - //we have a new group - // tmpHash["group"] =3D reader.attributes().data()->val= ue().toString(); - groupNameList << reader.attributes().data()->value().t= oString(); - } else if(reader.name() =3D=3D "entry") { - //we have a new entry - entriesList << reader.attributes().data()->value().toS= tring(); - } else { - // reader.readNext(); - elses << reader.name().toString() + ":" + reader.attr= ibutes().data()->value().toString(); - //QVector vector =3D reader.attri= butes().data(); - qDebug() << "qualifiedName:" + reader.qualifiedName().= toString(); - qDebug() << "qualifiedValue:" << reader.attributes().v= alue(reader.qualifiedName().toString()); - } + + //we will parse the file unti its end or until an error occurs + while (!reader.atEnd() && !reader.hasError()) { + //we need the token in order to check what is the element + QXmlStreamReader::TokenType token =3D reader.readNext(); + + //we have an element + if(token =3D=3D QXmlStreamReader::StartElement) { + //we have a new group + if(reader.name() =3D=3D "group") { + parseGroup(reader); } + } } = + if(reader.hasError()) { + //an error has occured + KMessageBox::error(0, i18n("The xml parsing has failed")); = - foreach(const QString& groupName, groupNameList) { - foreach(const QString& entry, entriesList) { - m_groups[groupName] << entry; - } + //clear the reader + reader.clear(); + //the parse has failed + m_parseResult =3D false; } - = - = - foreach(QString g, groupNameList) { - qDebug() << "groups:" < exists + if(reader.attributes().hasAttribute("name")) { + // We'll add it to the hash + m_data.setGroupName(reader.attributes().value("name").toString()); + qDebug() << "auto einai to name tou group:" + reader.attributes().valu= e("name").toString(); } - = - foreach(QString e, elses) { - qDebug() << "elses:"<< e; + + + //we are still in the group element so let's go the next element + reader.readNext(); + //we will loop over the group element until its end + while(!(reader.tokenType() =3D=3D QXmlStreamReader::EndElement && + reader.name() =3D=3D "group")) { + if(reader.tokenType() =3D=3D QXmlStreamReader::StartElement) { + //check if this is an entry element + if(reader.name() =3D=3D "entry") { + parseEntry(reader); + } + } + reader.readNext(); } } = -QHash KConfigXtParser::groups() const +void KConfigXtParser::parseEntry(QXmlStreamReader& reader) { - return m_groups; + // Check if we are inside an element like + if(reader.tokenType() !=3D QXmlStreamReader::StartElement) { + return; + } + + //check if there is a type attribute + //if there isn't fail! + if (reader.attributes().hasAttribute("type")) { + qDebug() << "auto einai to attribute type tou entry:" + reader.at= tributes().value("type").toString(); + //now we can take the entry's name and type + m_data.setEntryName(reader.attributes().value("name").toString()); + m_data.setEntryType(reader.attributes().value("type").toString()); + + m_parseResult =3D true; + + qDebug() << "entry name:" + reader.name().toString(); + qDebug() << "entry type:" + reader.attributes().value("type").toSt= ring(); + } else { + //there is no type, fail + m_parseResult =3D false; + return; + } + + //go ahead! + reader.readNext(); + + //for as long as we are inside the entry element + //we need to search for its value + int counter =3D 0; + while(!(reader.tokenType() =3D=3D QXmlStreamReader::EndElement && + reader.name() =3D=3D "entry")) { + + //we have a default element + if (reader.name().toString() =3D=3D "default") { + qDebug() << "mpike!!!"; + + //go ahead one more! + reader.readNext(); + + //we need the text of default + QString defaultText =3D reader.text().toString(); + + //check if we have characters + if(reader.tokenType() !=3D QXmlStreamReader::Characters) { + return; + } + m_data.setEntryValue(reader.text().toString()); + + } + reader.readNext(); + } } = -QHash KConfigXtParser::keysAndValues() const +QList KConfigXtParser::dataList() const { - return m_keysAndValues; + return m_dataList; } + diff --git a/editors/kconfigxt/kconfigxtparser.h b/editors/kconfigxt/kconfi= gxtparser.h index 709c256..73aaedd 100644 --- a/editors/kconfigxt/kconfigxtparser.h +++ b/editors/kconfigxt/kconfigxtparser.h @@ -21,12 +21,41 @@ #ifndef KCONFIGXTPARSER_H #define KCONFIGXTPARSER_H = -#include -#include +#include #include +#include +#include + +class KConfigXtParserItem +{ + +public: + KConfigXtParserItem(QObject* parent =3D 0); + + QString groupName() const; + void setGroupName(const QString& groupName); + + QString entryName() const; + void setEntryName(const QString& entryName); + + QString entryType() const; + void setEntryType(const QString& entryType); + + QString entryValue() const; + void setEntryValue(const QString& entryValue); + +private: + QString m_groupName; + QString m_entryName; + QString m_entryType; + QString m_entryValue; +}; + = class KConfigXtParser : public QObject { + + Q_OBJECT public: KConfigXtParser(QObject *parent =3D 0); = @@ -36,24 +65,22 @@ public: * Parses a kcfg file. * Should be called after setConfigXmlFile() */ - void parse(); + bool parse(); = - /* - * Returns a list of group names from config file. - * Valid only after a successful call to parse() - */ - QHash groups() const; - - /* - * Returns a map of keys and values from config file. + /** + * Returns the data from the xml file. * Valid only after a successful call to parse() - */ - QHash keysAndValues() const; + **/ + QList dataList() const; = private: + void parseGroup(QXmlStreamReader& reader); + void parseEntry(QXmlStreamReader& reader); + bool m_parseResult; + QString m_filename; - QHash m_groups; - QHash m_keysAndValues; + QList m_dataList; + KConfigXtParserItem m_data; }; = #endif diff --git a/editors/kconfigxt/standalone/plasmakconfigxteditor.cpp b/edito= rs/kconfigxt/standalone/plasmakconfigxteditor.cpp index cd4d588..ddf7842 100644 --- a/editors/kconfigxt/standalone/plasmakconfigxteditor.cpp +++ b/editors/kconfigxt/standalone/plasmakconfigxteditor.cpp @@ -18,7 +18,7 @@ PlasmaKConfigXtEditor::PlasmaKConfigXtEditor(QWidget* par= ent) m_ui.srcRequester->setFilter("*.xml"); = //disable the widgets. The user hasn't give a path yet. - disableWidgets(); + enableWidgets(false); = //we want the source relative ui to be visible. m_ui.srcLabel1->setVisible(true); @@ -35,22 +35,20 @@ void PlasmaKConfigXtEditor::checkProjectPath(const QStr= ing& path) = //check if the files is an xml if(path.endsWith(".xml")) { - m_ui.twKeyValues->setEnabled(true); - m_ui.twGroups->setEnabled(true); - m_ui.pbAddGroup->setEnabled(true); - m_ui.pbAddKey->setEnabled(true); + enableWidgets(true); setFilename(path); - } else { - disableWidgets(); + enableWidgets(false); } } = -void PlasmaKConfigXtEditor::disableWidgets() +void PlasmaKConfigXtEditor::enableWidgets(bool enable) { - m_ui.twKeyValues->setEnabled(false); - m_ui.twGroups->setEnabled(false); - m_ui.pbAddGroup->setEnabled(false); - m_ui.pbAddKey->setEnabled(false); + m_ui.twEntries->setEnabled(enable); + m_ui.twGroups->setEnabled(enable); + m_ui.pbAddGroup->setEnabled(enable); + m_ui.pbDeleteGroup->setEnabled(enable); + m_ui.pbAddEntry->setEnabled(enable); + m_ui.pbDeleteEntry->setEnabled(enable); } = diff --git a/editors/kconfigxt/standalone/plasmakconfigxteditor.h b/editors= /kconfigxt/standalone/plasmakconfigxteditor.h index 568d6fe..0287e04 100644 --- a/editors/kconfigxt/standalone/plasmakconfigxteditor.h +++ b/editors/kconfigxt/standalone/plasmakconfigxteditor.h @@ -22,7 +22,7 @@ public Q_SLOTS: void checkProjectPath(const QString& path); = private: - void disableWidgets(); + void enableWidgets(bool enable); }; = #endif // PUBLISHER_H diff --git a/mainwindow.cpp b/mainwindow.cpp index ca8ce39..3b5b180 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -634,7 +634,6 @@ void MainWindow::loadKConfigXtEditor(const KUrl& target) } = m_kconfigXtEditor->setFilename(target); - qDebug() << "xmllllllllllllllll" << target.pathOrUrl(); m_kconfigXtEditor->readFile(); m_central->switchTo(m_kconfigXtEditor); =