Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [NEWBIE] Parsing XML to strings
Forum Updated to NodeBB v4.3 + New Features

[NEWBIE] Parsing XML to strings

Scheduled Pinned Locked Moved General and Desktop
20 Posts 5 Posters 10.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    HowyHappy
    wrote on 13 Aug 2011, 20:34 last edited by
    #1

    Yeah, as the title suggests, I'm trying to parse XML to strings. Please keep in mind that I'm a noob in Qt right now, and I've been coding in the dark. (Metaphorically, not literally.) I don't want it put into a visual tree or anything, I want to be able to work with the strings taken from an XML document for further use within my program. So far, I've written this:
    Source file:
    @#include "xmlinterpret.h"
    #include <QtXml>
    #include <QtXml/QXmlStreamReader>
    #include <QIODevice>
    #include <QString>
    #include <QDomDocument>
    #include <QFile>

    QString gameName = "Title: ";
    QString globalObjectsFile;
    QString globalActorsFile;
    QString globalTerrainFile;
    QString globalMusicFile;
    QString globalSoundsFile;
    QString globalItemsFile;

    void LaunchPad::parseXmlFile() {
    QFile xmlFile("zgame.xml");
    if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
    return;

    QString xmlFileText;
    QTextStream xmlFileStream(&xmlFile);
    while (!xmlFileStream.atEnd()) {
        xmlFileText = xmlFileStream.readAll();
    }
    QXmlStreamReader xml(xmlFileText);
    
    while(!xml.atEnd()) {
        QXmlStreamReader::TokenType token = xml.readNext();
        if(token == QXmlStreamReader::StartDocument) {
            if (token == QXmlStreamReader::StartElement) {
                if(xml.name() == "zgame") {
                    continue;
                }
                if (xml.name() == "title") {
                    gameName.append(this->parseTitle(xml));
                }
                if(xml.name() == "index") {
                    continue;
                }
                if(xml.name() == "objects") {
                    globalObjectsFile.append(this->parseIndexFiles(xml));
                }
                if (xml.name() == "actors") {
                    globalActorsFile.append(this->parseIndexFiles(xml));
                }
                if (xml.name() == "terrains") {
    
                    globalTerrainFile.append(this->parseIndexFiles(xml));
                }
                if (xml.name() == "music") {
                    globalMusicFile.append(this->parseIndexFiles(xml));
                }
                if (xml.name() == "sounds") {
                    globalSoundsFile.append(this->parseIndexFiles(xml));
                }
                if (xml.name() == "items") {
                    globalItemsFile.append(this->parseIndexFiles(xml));
                }
            }
        }
    }
    xml.clear();
    

    }

    void LaunchPad::parseTitle(QXmlStreamReader& xml) {
    if (xml.tokenType() != QXmlStreamReader::StartElement && xml.name() == "gamename") {
    return title;
    }
    while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == "gamename")) {
    if(xml.tokenType() == QXmlStreamReader::StartElement) {
    QString gamePrefix = xml.name().toString();
    gameName.append(gamePrefix);
    }
    }
    }

    void LaunchPad::parseIndexFiles(QXmlStreamReader& xml) {

    }

    void LaunchPad::buildIndex() {
    //Object index
    QFile globalObjectsXmlFile(globalObjectsFile);
    globalObjectsXmlFile.open(QIODevice::readAll());
    QByteArray globalObjectsData(globalObjectsXmlFile);
    objectIndex.setContent(globalObjectsData);

    //Actor index
    QFile globalActorsXmlFile&#40;globalActorsFile&#41;;
    globalActorsXmlFile.open(QIODevice::ReadOnly);
    QByteArray globalActorsData(QFile::readAll(globalActorsXmlFile));
    actorIndex.setContent(globalActorsData);
    
    //Terrain index
    QFile globalTerrainXmlFile&#40;globalTerrainFile&#41;;
    globalTerrainXmlFile.open(QIODevice::ReadOnly);
    QByteArray globalTerrainData(QFile::readAll(globalTerrainXmlFile));
    terrainIndex.setContent(globalTerrainData);
    
    //Music index
    QFile globalMusicFileXmlFile&#40;globalMusicFile&#41;;
    globalMusicFileXmlFile.open(QIODevice::ReadOnly);
    QByteArray globalMusicData(QFile::readAll(globalMusicFileXmlFile));
    musicIndex.setContent(globalMusicData);
    
    //Sound index
    QFile globalSoundsXmlFile&#40;globalSoundsFile&#41;;
    globalSoundsXmlFile.open(QIODevice::ReadOnly);
    QByteArray globalSoundsData(QFile::readAll(globalSoundsXmlFile));
    soundIndex.setContent(globalSoundsData);
    
    //Item index
    QFile globalItemsXmlFile&#40;globalItemsFile&#41;;
    globalItemsXmlFile.open(QIODevice::ReadOnly);
    QByteArray globalItemsData(QFile::readAll(globalItemsXmlFile));
    itemIndex.setContent(globalItemsData);
    

    }
    @
    Header:
    @#ifndef XMLINTERPRET_H
    #define XMLINTERPRET_H

    #include <QtXml/QXmlStreamReader>

    #include <QObject>
    #include <QWidget>
    #include <QDomDocument>

    class LaunchPad : public QObject {
    Q_OBJECT

    public:
    explicit LaunchPad(QObject *parent = 0);
    ~LaunchPad();

    signals:

    public slots:

    private slots:
    void parseXmlFile();
    void parseIndexFiles();
    void parseTitle();
    void buildIndex();
    void parseObject();
    void parseActors();
    void parseTerrain();
    void parseMusic();
    void parseSounds();
    void parseItems();

    private:

    QDomDocument objectIndex;
    QDomDocument actorIndex;
    QDomDocument terrainIndex;
    QDomDocument musicIndex;
    QDomDocument soundIndex;
    QDomDocument itemIndex;
    

    };

    #endif // XMLINTERPRET_H
    @
    What I'm trying to do is this: The initial xml file (zgame.xml) contains the names of other Xml files and also a title. These other Xml files contain an index of objects with multiple child values that I want to put in a non-visual DOM-tree so that they can be imported by other parts of the program. What I've tried to do is parse the text from the initial Xml file, assign it to QStrings, and use them as file location for QIODevices.
    The main problem I have is that I don't understand how QXmlStreamReader works... When I use all those ifs and that stuff, does it forward the string or a piece of the Xml to be parsed?
    All the examples I've seen haven't described this way of working with the Xml, but rather just putting it into some visual component like a tree of nodes.
    I'd really appreciate some help on this.

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on 14 Aug 2011, 05:18 last edited by
      #2

      Hi HowyHappy,

      bq. The main problem I have is that I don’t understand how QXmlStreamReader works… When I use all those ifs and that stuff, does it forward the string or a piece of the Xml to be parsed?
      All the examples I’ve seen haven’t described this way of working with the Xml, but rather just putting it into some visual component like a tree of nodes.

      the difference between the examples and your code then is only the target, where the strings go to. So from XML parsing and reading, it should be the same.

      As you post here, it seems not to work, so what do you see? did you debug it?

      I saw one bug:

      @
      while(!xml.atEnd()) {
      QXmlStreamReader::TokenType token = xml.readNext();
      if(token == QXmlStreamReader::StartDocument) {
      if (token == QXmlStreamReader::StartElement) {
      @

      you only check for a StartElement if it's also the StartDocument, all otrher iterations are ignored?

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • H Offline
        H Offline
        HowyHappy
        wrote on 14 Aug 2011, 11:11 last edited by
        #3

        I get an error that reoccurs for all the instances I've used the other functions:
        @../xml-interpret/xmlinterpret.cpp:39:57: error: no matching function for call to ‘LaunchPad::parseTitle(QXmlStreamReader&)’@
        And also a "candidate is: void::parseTitle()"
        I also get:
        @../xml-interpret/xmlinterpret.cpp:68:6: error: prototype for ‘void LaunchPad::parseTitle(QXmlStreamReader&)’ does not match any in class ‘LaunchPad’@
        have I forgotten to add something when declaring the function?
        I also have this ginormous error about QByteArray:
        @../xml-interpret/xmlinterpret.cpp:88:50: error: cannot call member function ‘QByteArray QIODevice::readAll()’ without object
        ../xml-interpret/xmlinterpret.cpp:89:54: error: no matching function for call to ‘QByteArray::QByteArray(QFile&)’
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:369:5: note: candidates are: QByteArray::QByteArray(QByteArray::Data*, int, int)
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:421:8: note: QByteArray::QByteArray(const QByteArray&)
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:141:5: note: QByteArray::QByteArray(int, Qt::Initialization)
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:140:5: note: QByteArray::QByteArray(int, char)
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:139:5: note: QByteArray::QByteArray(const char*, int)
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:138:5: note: QByteArray::QByteArray(const char*)
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qbytearray.h:382:8: note: QByteArray::QByteArray()
        ../xml-interpret/xmlinterpret.cpp:95:67: error: no matching function for call to ‘QIODevice::readAll(QFile&)’
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qiodevice.h:119:16: note: candidate is: QByteArray QIODevice::readAll()
        ../xml-interpret/xmlinterpret.cpp:101:69: error: no matching function for call to ‘QIODevice::readAll(QFile&)’
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qiodevice.h:119:16: note: candidate is: QByteArray QIODevice::readAll()
        ../xml-interpret/xmlinterpret.cpp:107:69: error: no matching function for call to ‘QIODevice::readAll(QFile&)’
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qiodevice.h:119:16: note: candidate is: QByteArray QIODevice::readAll()
        ../xml-interpret/xmlinterpret.cpp:113:67: error: no matching function for call to ‘QIODevice::readAll(QFile&)’
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qiodevice.h:119:16: note: candidate is: QByteArray QIODevice::readAll()
        ../xml-interpret/xmlinterpret.cpp:119:65: error: no matching function for call to ‘QIODevice::readAll(QFile&)’
        ../../../QtSDK11/Desktop/Qt/473/gcc/include/QtCore/qiodevice.h:119:16: note: candidate is: QByteArray QIODevice::readAll()@
        I'm sorry if all this looks hopeless...

        But I did read something about QXmlStreamReader just now. As I see it, I have to transfer the tokenString from the parsed text and possibly append it to a string? I tried this:
        @void LaunchPad::parseIndexFiles(QXmlStreamReader& xml) {
        if (xml.name() == "gamename")
        xml.tokenString().append(gameName);
        }
        @
        And it didn't output any specific error, but the error about "no matching function for call to" persisted.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mlong
          wrote on 14 Aug 2011, 12:45 last edited by
          #4

          In your header, you have the section of code:
          @
          private slots:
          void parseXmlFile();
          void parseIndexFiles();
          void parseTitle();
          void buildIndex();
          void parseObject();
          void parseActors();
          void parseTerrain();
          void parseMusic();
          void parseSounds();
          void parseItems();
          @

          Couple of things...

          These don't need to be slots. Just make them "private:"

          You're not declaring the parameter types that they take.

          If you have
          @void LaunchPad::parseIndexFiles(QXmlStreamReader& xml) @
          in your cpp file, then you need to have the declaration match in your header:
          @ void parseIndexFiles(QXmlStreamReader& xml); @

          Software Engineer
          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mlong
            wrote on 14 Aug 2011, 12:49 last edited by
            #5

            Also, make sure that in your header you reference the QXmlStreamReader type.

            Either add the line
            @ class QXmlStreamReader; @ before the beginning of your Launchpad declaration, or (much less preferably) add @ #include <QtXml/QXmlStreamReader> @ in the header.

            Edit: Nevermind. I see you already have done this. (At any rate, the first option would still be preferable.)

            Software Engineer
            My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              loladiro
              wrote on 14 Aug 2011, 12:58 last edited by
              #6

              or even better
              @
              QT_BEGIN_NAMESPACE
              class QXmlStreamReader;
              QT_END_NAMESPACE
              @

              1 Reply Last reply
              0
              • H Offline
                H Offline
                HowyHappy
                wrote on 14 Aug 2011, 19:02 last edited by
                #7

                Ok, I kept "#include <QXmlStreamReader>" because using "class QXmlStreamReader;" broke everything. And... Why would you prefer that the class definition was used?
                As I see it, from my unexperienced view, you define a class called QXmlStreamReader. Not necessarily what I want to use, which is the streaming functionality... Or does it serve the same purpose?
                And in what way is using #include inferior to defining the class?

                Anyway... When I made the same declarations in the header, I got these errors:
                @../xml-interpret/xmlinterpret.cpp:38:54: error: invalid use of void expression@
                They appear for all the times I refer to other functions, instead of "no function for call to".
                This is a piece of code where the error occurs:
                @gameName.append(this->parseTitle(xml));@
                It's in the if-stack. What have I done wrong this time?

                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  loladiro
                  wrote on 14 Aug 2011, 20:12 last edited by
                  #8

                  @this->parseTitle(xml);@
                  does not return anything and you can therefore not append it to gameName.
                  I suggest you read up on the basics of C++ before continuing.

                  [quote]
                  Ok, I kept “#include <QXmlStreamReader>” because using “class QXmlStreamReader;” broke everything. And… Why would you prefer that the class definition was used?
                  As I see it, from my unexperienced view, you define a class called QXmlStreamReader. Not necessarily what I want to use, which is the streaming functionality… Or does it serve the same purpose?
                  And in what way is using #include inferior to defining the class?
                  [/quote]
                  It's called forward declaration and speeds up compilation. The #include <QXmlStreamReader> should go in the .cpp file.
                  "On when to use forward declaration":http://www-subatech.in2p3.fr/~photons/subatech/soft/carnac/CPP-INC-1.shtml

                  1 Reply Last reply
                  0
                  • H Offline
                    H Offline
                    HowyHappy
                    wrote on 14 Aug 2011, 20:34 last edited by
                    #9

                    [quote author="loladiro" date="1313352748"]
                    I suggest you read up on the basics of C++ before continuing.
                    [/quote]
                    Now that was a very helpful suggestion. (I mean it.) My C++ is as good as rusted away/I don't know much C++.
                    I'm sorry for bothering all of you with this, but I'll be back in this thread when I understand more of how C++ works.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      loladiro
                      wrote on 14 Aug 2011, 20:40 last edited by
                      #10

                      [quote author="HowyHappy" date="1313354049"]
                      [quote author="loladiro" date="1313352748"]
                      I suggest you read up on the basics of C++ before continuing.
                      [/quote]
                      Now that was a very helpful suggestion. (I mean it.) My C++ is as good as rusted away/I don't know much C++.
                      I'm sorry for bothering all of you with this, but I'll be back in this thread when I understand more of how C++ works.[/quote]

                      No problem. We will be more than glad to help when you're back :) .

                      1 Reply Last reply
                      0
                      • H Offline
                        H Offline
                        HowyHappy
                        wrote on 15 Aug 2011, 19:12 last edited by
                        #11

                        Wow, quickly reading through the basics helped a lot. Now, I have the initial Xml parsed to strings, and I'm ready to proceed with building DOM-trees.
                        ...When I learn how to build them.
                        I must say: QXmlStreamReader is simple to use once you understand how it works.

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mlong
                          wrote on 15 Aug 2011, 19:34 last edited by
                          #12

                          [quote author="HowyHappy" date="1313435556"]Now, I have the initial Xml parsed to strings, and I'm ready to proceed with building DOM-trees.[/quote]

                          If you're wanting a DOM tree, perhaps your best bet would be simply using "QDomDocument":http://doc.qt.nokia.com/latest/qdomdocument.html rather than building one from scratch with strings read from an QXmlStreamReader.

                          But, it all depends on your use case.

                          Software Engineer
                          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                          1 Reply Last reply
                          0
                          • H Offline
                            H Offline
                            HowyHappy
                            wrote on 16 Aug 2011, 00:31 last edited by
                            #13

                            Well, of course, I won't use QXmlStreamReader to build a DOM tree. It wouldn't be sufficient for the amounts of data this program should be able to handle. In this usecase, I want there to be indexes for different kinds of objects that can be pulled easily into a renderer and other components. So, f.ex., you'd be able to pull trees of all sorts, and it will load the different properties of it like texture and model without further fuzz.
                            For this purpose, a QDomDocument will do perfectly.
                            I have all the features and ways of doing it planned well. The thing missing is writing it.

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              mlong
                              wrote on 16 Aug 2011, 16:29 last edited by
                              #14

                              Ok... I was just making sure you knew the options. Since you'd self-proclaimed yourself as a "newbie" then there was a little room for interpretation (and guessing) about what you knew about and what you didn't. :-)

                              Good luck with your coding!

                              Software Engineer
                              My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                              1 Reply Last reply
                              0
                              • H Offline
                                H Offline
                                HowyHappy
                                wrote on 16 Aug 2011, 18:25 last edited by
                                #15

                                I think I've made some progress, but so far I've taken it after my own perception of what does what.
                                This is the code:
                                @void LaunchPad::parseActors() {
                                //Open the file and assign it to the document
                                QFile actorFile(globalActorsFile);
                                actorFile.open(QIODevice::ReadOnly | QIODevice::Text);
                                actorIndex.setContent(&actorFile);

                                //Start building the DOM tree
                                QDomElement actorElement;
                                QDomNodeList actors = actorElement.elementsByTagName("sysName");
                                

                                }@
                                Will this build me a usable DOM tree?
                                This is an example of the target document:
                                @<actors>
                                <actor name="hero" sysName="hero">
                                <model>act_hero_001.zact</model>
                                <texture>act_hero_001.ztex</texture>
                                </actor>
                                <actor name="Princess" sysName="princess">
                                <type>NPC</type>
                                <model>act_princess_001.zact</model>
                                <texture>act_princess_001.ztex</texture>
                                <talk>true</talk>
                                <logic>act_princess.zlgc</logic>
                                </actor>
                                </actors>@
                                Would I be able to fetch all the child nodes of the actor called "hero"?
                                Or am I only halfway?

                                And I'm also trying to draw a test-window, just to see that the text gets parsed. So I put in this function:
                                @void LaunchPad::drawTestWindow() {
                                QWidget titleWindow;
                                titleWindow.setWindowTitle(gameName);
                                titleWindow.show();
                                }@
                                But it doesn't seem to work well so far.
                                I get this weird error, it says:
                                @/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/../../../crt1.o: In function _start': (.text+0x20): undefined reference to main'
                                collect2: ld returned 1 exit status@
                                I bet that I've forgotten to enter something that is required by QWidget or displaying something in general..?

                                1 Reply Last reply
                                0
                                • M Offline
                                  M Offline
                                  mlong
                                  wrote on 16 Aug 2011, 18:30 last edited by
                                  #16

                                  Where is your main()? Looks like the linker can't find it.

                                  Software Engineer
                                  My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                                  1 Reply Last reply
                                  0
                                  • H Offline
                                    H Offline
                                    HowyHappy
                                    wrote on 16 Aug 2011, 23:15 last edited by
                                    #17

                                    I'm having a problem with main()...
                                    I don't know how to use it.
                                    I've written this so far:
                                    @#include <QtGui/QApplication>
                                    #include <QWidget>

                                    #include "xmlinterpret.h"

                                    int main(int argc, char *argv[]) {
                                    QApplication app(argc, argv);

                                    return app.exec();
                                    

                                    }
                                    @
                                    But I don't understand how to make it show the widget I configured...
                                    I assume that I have to use a pointer somewhere?

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      mlong
                                      wrote on 16 Aug 2011, 23:17 last edited by
                                      #18

                                      @
                                      #include <QtGui/QApplication>
                                      #include "somewidget.h"

                                      int main(int argc, char *argv[])
                                      {
                                      QApplication app(argc, argv);

                                      SomeWidget sw;  
                                      sw.show();
                                      
                                      return app.exec&#40;&#41;;
                                      

                                      }
                                      @

                                      or just look at pretty much any of the examples in the docs.

                                      Software Engineer
                                      My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                                      1 Reply Last reply
                                      0
                                      • H Offline
                                        H Offline
                                        HowyHappy
                                        wrote on 19 Aug 2011, 00:22 last edited by
                                        #19

                                        I've successfully implemented the int main function now. I chose to put it in the same file, because then I won't have to use pointers, and this is basicly the launchpad for the engine where it all begins.

                                        Ok, new problem:
                                        The program is nicely written now, but I'm not entirely sure on how to use QFile.
                                        So far, I've used it this way:
                                        @QFile xmlFile;
                                        xmlFile.setFileName("game.xml");@
                                        And:
                                        @QFile actorFile(globalActorsFile);@
                                        I also set QDir to the current directory in main() like so:
                                        @QDir::setCurrent(".");@
                                        But when I try to start the program, I get "QFSFileEngine::open: No file name specified".
                                        What have I done wrong?

                                        1 Reply Last reply
                                        0
                                        • G Offline
                                          G Offline
                                          goetz
                                          wrote on 22 Aug 2011, 14:47 last edited by
                                          #20

                                          Relative paths are resolved relative to the current directory. The dot "." represents the current directory. So our setCurrent is nothing else than "change the current directory to the current directory".

                                          I guess you want to set the current directory to that folder that holds the executable. If so, then use this:

                                          @
                                          QDir::setCurrent(qApp->applicationDirPath());
                                          @

                                          Or better prepend your file path with that string.

                                          http://www.catb.org/~esr/faqs/smart-questions.html

                                          1 Reply Last reply
                                          0

                                          6/20

                                          14 Aug 2011, 12:58

                                          topic:navigator.unread, 14
                                          • Login

                                          • Login or register to search.
                                          6 out of 20
                                          • First post
                                            6/20
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved