Page 1 of 1

[Caveats] Modernizing + cross-platforming hard-coded stuff

Posted: Sat Mar 30, 2019 9:10 pm
by Tim E. Real
To help with the cross-platform effort going on, I am replacing calls to getenv/setenv
with Qt equivalents qgetenv/qsetenv and if supported the newer qEnvironmentVariable().
I am also replacing hard-coded paths, like for example the all-important config location in globals.cpp:

Code: Select all

QString configName = QString(getenv("HOME")) + QString("/.config/MusE/MusE.cfg");
I am replacing them using Qt's QStandardPaths::writableLocation().
Also the plugin cache path will use the same function to look up the correct user cache location on the OS.
I incorrectly put the cache files in ~./config/MusE/scanner when it should have been ~./cache/MusE/scanner (on Linux).

Also, I want to replace all 18 calls to QSettings("MusE", "MusE-qt") with the nifty new convenience feature in Qt 5:
Call QApplication::setApplicationName() and setOrganizationName(), and then all calls to the new QSettings() constructor
automatically fill in the organization name and application name with those set values.
These QSettings were added at some point in our Qt4 history. The reason we had to do it that way is unique to MusE: We already
had a configuration file named "MusE.cfg". Thus the author decided best to call the QSettings app name "MusE-qt" to avoid confusion,
otherwise we would have both "MusE.cfg" and "MusE.conf" in the same folder. So instead it's called "MusE-qt.conf".
So I tried QApplication::setApplicationName("MusE-qt") and setOrganizationName("MusE") so that the new QSettings() constructor works.

I also call QApplication::setOrganizationDomain(""). See the docs about Mac preferring the domain over org name.

But... I've reached a problem, convoluted so stay with me:
When I use QStandardPaths before the QApplication is instantiated, the <APPNAME> portion of the various returned paths is blank (see docs).
After the QApplication is created, the <APPNAME> is filled with the application name (which defaults to exe name since Qt 5).
This makes sense, I suppose. Certain OS example paths in the given chart need that APPNAME. Seems undocumented though.
But... Also seems undocumented, QStandardPaths::writableLocation() actually returns paths that include the organization name.
Thus if I ask for the new-ish 'AppConfigLocation', I get ~./config/MusE/MusE-qt.

So, yes there are ways I can get around make it exactly like it is now without changing config locations.
I can ask for the older 'GenericConfigLocation' and tack on our organization name ie. "~./config/MusE".
But... Here's my dilemma: I would really like to let Qt compose the 'full' path for much ease and to be consistent
ie. "~./config/MusE/MusE" or "~./config/MusE/MusE-qt" or say "~./config/MusE/MusE-seq".
That way:
a) I won't have to use QSettings("MusE", "MusE-qt") or whatever, just QSettings().
b) QStandardPaths will just work, using the app name and organization name or domain.
c) Consider if the "MusE" organization were to produce a second app, it would then go to "~./config/MusE/FancyNewApp".
(Note that wherever you see strings like "MusE", I've really moved them all into our config.h file to be a central place
housing string literals like our organization name, package name, app name, domain, and/or QSettings app name. All as #defines.)

To do so I MUST move our configuration and cache locations to the above mentioned places.
I will of course make it copy existing config and cache files to the new locations, such as user-defined instruments, cache files, settings etc.
This would be a one-time trick when you first start MusE with these changes applied.
Here I must warn that is then NOT backwards compatible with older MusE versions.
Starting an older version will not find any config stuff and thus start from fresh.
But I could leave the old config files in place so that older versions can use them (heck it will write there anyway!)
but of course the older versions won't find anything new that you add to the new config location.

Whew. Hopefully we'll sort this out.
But if there are any objections or views on the situation, speak up.
Just warnin' y'all. I might go ahead and do it. Time is short.

Re: [Caveats] Modernizing + cross-platforming hard-coded stuff

Posted: Sat Mar 30, 2019 9:34 pm
by Tim E. Real
If I understand, the user experimenting with the Windows build never actually reached the running stage.
If he did, those hard-coded paths might cause problems.
So hopefully these proposed changes will help.

I forgot to mention we do a trick with our plugin path lists (QStringList) concatinating them with a hard-coded ':' to be
set as environment variables such as our internal LADSPA_PATH or LV2_PATH variables.

The Windows contributor added some win32 code to do the same but left the ':' in there. I think it's supposed to be ';' correct?
So I used QDir::listSeparator() if supported, to get the correct separator. Otherwise it's good ol' hard-coded ':' vs. ';'
I noted that there is no c/c++ way except with c++17's official file support or the older experimental file support.

Re: [Caveats] Modernizing + cross-platforming hard-coded stuff

Posted: Tue Sep 03, 2019 8:34 pm
by Tim E. Real
Just a heads up!
I have gone ahead and done this, in git master.
Please be aware that MusE config locations and file names have changed.

From ChangeLog:

Code: Select all

      - Replaced all hard-coded paths in main.cpp with QStandardPaths. (Tim)
        *** NOTE: This means the location of MusE config files and names have changed!
        Everything has been moved to ~/.config/MusE/MusE EXCEPT the qt config file
         which remains in ~/.config/MusE. The MusE config file 'MusE.cfg' has been
         renamed 'MusE-seq.cfg'. The MusE qt config file 'MusE-qt.conf' has been
         renamed 'MusE.conf'. The QApplication now has an organization name,
         application name, and organization domain. All QSettings usages now defer
         to these values instead of hard-coding QSettings("MusE", "MusE-qt").
        These changes comply with QStandardPaths policies and QSettings behaviour.
      - Replaced getenv with qEnvironmentVariable or qgetenv in main.cpp
      - Disabled loading of default template files 'MusE-seq.cfg' and 'MusE.conf'
         when either was not found. They should not be required. All default values
         housed in the global config struct or other classes are now honoured.