Custom file system implementation in Qt - c++

I am researching a way of implementing a simple file system UI. The requirement is that I have an in-memory tree (custom data structure), similar to a file system. But this is not the real file system of the computer. So, I want to represent this internal implementation to the user to react with that like adding new files, deleting files, editing files, adding folders, i.e. the basic operations.
I have no idea how to achieve this using Qt UIs. Is that a good idea to represent these files/folders using QLabel and setting pixmap for them?
If I implement it like this, it is lot of work, like, once the folder is clicked, the frame should be cleared and the new set of labels should be loaded in the same frame.
What will be the easiest way?

Related

How to make a more complex wxWidgets save system

I'm making a desktop app with wxWidgets but I can't figure out how it can have a more complex save system. For example, a project in Sony Vegas is saved in one file, and it's a (.veg). My save system will have to save mostly text from user, but in different areas. To be able to do this, do I need to save each thing I need separatly and load them all when I wish to re-enter the app? Sorry if this question seems obvious, I'm new fairly new at using wxWidgets.
Saving data to one or more files depends on how you organize your app.
It may read data from a file only when needed. Different tasks may use different files.
It may store everything in a single file. Read it all once. Or read parts of it for different tasks. If the file is too much big (my opinion, greater than 50 MB), obviously this is not the best option.
For the second option you may use std <fstream> functions. Or some of those provided by wxWidgets, which you will appreciate if you need to deal with text encodings, or other features as well.
Also, wxFileConfig may be useful if you wish to set several "sections" of your data.

Using an Icon across user downloads

So I'm in the final stages of a project I've been working on. I went ahead and created an ICO file for my shortcut but now I'm not sure how to preserve the ICO file as the background.
When I compress the file and send it to someone else, they open it but the shortcut doesn't work, since the shortcut links to a difference space inside their local storage. The ICO is also not preserved- presumably because it is stored locally.
My question is this- what is the best/fastest way to create a shortcut that is persistent across all users computers, without forcing them to make their own? In a perfect world an ICO file could be embedded in a link, but it doesn't look like that's possible. I have no idea how you would go about addressing the issue with the hard drive, since a user's file layout could be different from my own. It seems that this would have to be accomplished programmatically.
I'm not clear on what you mean by "preserve the ICO file as the background".
You could possibly add the ICO file as a resource in you C++ project.
How to add the ICO as a resource will depend on your C++ IDE.
When you create a shortcut to the application it should use the first ICO file it can find in the .exe file.

multiple dialogs inside one dfm

I'm developing an application with a lot of small, custom dialogs.
These dialogs are e.g. giving choices, displaying graphs or offer additional interfaces. Mostly they require very little markup-code and have few child elements.
Currently I'm using embarcadero'c XE2 RAD Studio's C++ Builder, which works with VCL and generates for every form a .dfm file, a .h file and a .cpp file.
Now I would like to keep an overview over the files produced and merge e.g. the .dfm files of multiple small dialogs. (maybe even the .cpp and .h, too).
However, I also want to use C++-Builder's VCL designer.
Is there a way to merge .dfm files and still have the IDE's designer working as usual?
Or should I just dynamically generate those dialogs during runtime?
Now I would like to keep an overview over the files produced and merge e.g. the .dfm files of multiple small dialogs. (maybe even the .cpp and .h, too). However, I also want to use C++-Builder's VCL designer.
Is there a way to merge .dfm files and still have the IDE's designer working as usual?
It is possible (but not recommended) to move design-time generated event handler implementations from one .cpp file to another .cpp file (don't move their declarations in .h files, though). So it is conceivable to have 1 .cpp file with all your event handler implementations, and the app will work fine. I do the opposite in one of my projects - I have a TForm with a LOT of event handlers on it, so I move them into separate .cpp files grouped by functionality (yes, I should use TFrame to manage that, but I am not at liberty to change that at this stage of development).
There is a side effect, though - if you try to double-click on an assigned event in the Object Inspector, it won't be able to find the handler's implementation code if you move it.
However, regarding DFMs, every TForm, TFrame, and TDataModule class that is created at design-time must have its own individual DFM. The IDE and the DFM streaming system both expect that. DFM resources in the final executable are identified by class name, and the DFM streaming system reads an entire DFM resource from start to end when loading a DFM into a single root object instance. Besides, the DFM data format does not support multiple DFMs in a single resource stream.
So no, you cannot merge multiple DFMs together.
Or should I just dynamically generate those dialogs during runtime?
Yes. Or just live with letting the dialogs use individiual DFM resources. If your dialogs really are as small on content as you say, the overhead to your executable should be minimal.
You can use "legacy" TNotebook component ("Win3.1" page in RAD2007) to simulate many small dialogs in one file; it works like page control without tab buttons. Create required number of pages in the component and activate needed page in constructor of the form.

Qt : Avoid Rebuilding Applications incase strings change

I wanted to know what my options are for storing strings in a QT application.
One of my major requirements in not re-building the entire project or any file in-case one string changes and also have all the strings in one place.In short I would like to have the strings in one place and extract them during Application startup
I've used all of the elements talked about in above answers.
XML, JSON, QSettings w/ Ini files, tr()
All of them can do it just fine. I've put together some notes on the different options:
QTranslator
Qt Linguist and the tr() tags are designed to take your stock language and translate it into another language. Keeping track of multiple versions of the english translation and modifying/releasing without Qt Linguist is almost impossible. Qt Linguist is required to "release" your translations and convert them from a TS file (translation source) to an optimized QM file.
The QM file format is a compact binary format that is used by the localized application. It provides extremely fast lookups for translations.
Here is what using a translation file looks like:
QTranslator translator;
translator.load("hellotr_la");
app.installTranslator(&translator);
http://qt-project.org/doc/qt-4.8/qtranslator.html#details
I think using QTranslator for a few string changes may be a weird use case, unless you are using for localizing your program. But like the docs say, it is optimized for very fast look ups of string replacements.
QXMLStreamReader
The stream reader is "recommended" way to access XML files, or at least with better support. You write your own files for organizing it, or you write code to generate the XML.
<STRING_1>Some string</STRING_1>
Here is what it looks like to navigate into xml.
QXmlStreamReader xml;
...
while (!xml.atEnd()) {
xml.readNext();
... // do processing
}
if (xml.hasError()) {
... // do error handling
}
XML is very similar to Json, but with larger files and the start and end tags are longer. There are a lot more stock readers out there for XML. It is also a lot more human readable in many cases because so many people know html and they are very similar.
QJsonDocument
The JSON suppport in Qt 5 looks really good. I haven't built a project with it quite yet It is as easy as it looks, and as far as accessing and setting, it looks just like using a dictionary or a map or a vector.
UPDATE: You just pass around a pointer into your QJsonDocument or your QJsonObject or your QJsonArray as you are navigating deeper or appending more onto your Json file. And when you are done you can save it as a binary file, or as a clear text, human readable file, with proper indentation and everything!
How to create/read/write JSon files in Qt5
Json seems to be turning into the replacement for XML for many people. I like the example of using Json to save and load the state of a role playing game.
http://qt-project.org/doc/qt-5/qtcore-savegame-example.html
QSettings
QSettings is one of my favorites, just because it has been supported for so long, and it is how most persistent settings should be saved and accessed.
When I use it, to take advantage of the defaults and fall back mechanisms, I put this in my main.cpp:
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
And because I sometimes find a need to edit these setting by hand in windows, I use the Ini format.
QSettings::setDefaultFormat(QSettings::IniFormat); // also in main.cpp
Then when I deploy my exe, and I want to have particular value loaded instead of the hardcoded defaults, the installer drops the main fallback into
C:/ProgramData/MySoft/Star Runner.ini
And when the program saves a change at runtime, it gets saved to:
C:/Users/<username>/AppData/Roaming/MySoft/Star Runner.ini
And then throughout my program if I need to get a setting or set a setting, it takes 3 lines of code or less.
// setting the value
QSettings s;
s.setValue("Strings/string_1", "new string");
// getting the value
QString str;
QSettings s;
str = s.value("Strings/string_1", "default string").toString();
And here is what your ini file would look like:
[Strings]
string_1=default string
QSettings is the way to go if you are storing a few strings you want to change on deployment or at runtime. (or if a checkbox is now checked, or your window size and position, or the recent files list or whatever).
QSettings has been optimized quite a bit and is well thought out. The ini support is awesome, with the exception that it sometimes reorders groups and keys (usually alphabetically), and it may drop any comments you put in it. I think ini comments are either started with a ; or a #.
Hope that helps.
One way to do this would be to put it in a shared library. This way you can only recompile the shared library, but not the whole project. Another approach would be to put it in a file or a database and load it at runtime.
And of course you have to check your include dependencies. If you are including the headers everywhere, the compiler will rebuild everything that depends on it, even if the header is not really needed.
Another possible solution is to replace all strings with default ones inside tr() calls and use Qt Linguist to manage all the strings.
You'll also be able to load all the "translations" from external .qm file on startup.
It is simple: Store your volatile strings in QSettings http://qt-project.org/doc/qt-4.8/qsettings.html (you can use ini files or registry) or an XML file which will make you application configurable.
Edit: Well, after thinking about it a few more minutes, Guilherme's comment is right. QSettings will need to be initialized somehow (either manually or from some default values in your code)... and to be honest manual editing registry to change a few strings is not the brightest idea. So I conclude that XML or JSON is definitely better. It has advantages, for example you can keep several config files which allow you for switching languages at runtime etc.

Edit an existing file in C++

I have preferences file for my application in Qt.
Whenever I launch the application it loads the file & depending the contents creates the widgets accordingly. I have given some customisation option for the user. Now when my application is closed I am checking whether the preferences are changed. If yes then I am opening the preferences file again & then just adding everything again in it. I am not creating a temporary file, I am directly editing the file. Is this method an efficient one? or am I doing it wrong? because I found these threads:
1. What is the best way to edit the middle of an existing flat file?
http://qt-project.org/forums/viewthread/25924/
Should use I binary file? Currently I am using ASCII file.
Thanks.
UPDATE: In the stackoverflow link above the correct answer has
If you're stuck using flat, then you're stuck using the old fashioned
way of updating them
I meant to ask whether the method I am using is old fashioned & is there a better method used nowadays? & what does flat file mean?
Don't try to edit the file. Rewrite the whole thing
Rewrite by using a temporary file. i.e. write the current state of preferences into temp file. And then move/rename the file to your actual preference file after making sure the temp file has been written successfully. This helps in case there is a crash when you rewriting the file. If you rewrite it directly, you will be left with neither the old one nor a good new one. In case you do it through a temp file, then do it this way ensures that in case of a crash, you atleast have a good preferences file(though it contains the old preferences).
Text/Binary doesn't make much difference unless it's a really huge file. Text will help to hand edit it if required.
That's a perfectly fine way of doing it. Since you already seem to have all of the preferences loaded into memory and you have edited them there, you don't need to bother with a temporary file (unless you want to ensure safety if your program fails during writing). Just write all of the preferences back into the original file.
Whether you choose a binary file or text file is up to you. Preferences tend to be text files because they have the added benefit of being human readable with just a text editor, rather than some specialised software for viewing them. A binary file may, however, have slightly better performance due to simpler decoding.