A code question

@KjellM (or anyone else :slight_smile: )

In

src/utils/folderutils.cpp

current code:

QString FolderUtils::getTopLevelUserDataStorePath() {
QString path = QSettings(QSettings::IniFormat,QSettings::UserScope,“Fritzing”,“Fritzing”).fileName();
return QFileInfo(path).dir().absolutePath();
}

QString FolderUtils::getTopLevelDocumentsPath() {
// must add a fritzing subfolder
QDir dir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
return dir.absoluteFilePath(“Fritzing”);
}

desired code:

QString FolderUtils::getTopLevelUserDataStorePath() {
QString path = QSettings(QSettings::IniFormat,QSettings::UserScope,m_userFolderPrefix,m_userFolderPrefix).fileName();
return QFileInfo(path).dir().absolutePath();
}

QString FolderUtils::getTopLevelDocumentsPath() {
// must add a fritzing subfolder
QDir dir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
return dir.absoluteFilePath(m_userFolderPrefix);
}

where m_userFolderPrefix is a new protected static variable defined like this in

src/utils/folderutils.h

protected:
static FolderUtils* singleton;
static QString m_openSaveFolder;
static QString m_userFolderPrefix;

which I think should give me a static private variable that can be set to the string “Fritzing” (not done yet!) to specify the user directories (with the intent of later being able to modify the value to change the path to the user directories.) This gets an error

debug/folderutils.o at line 141 in folderutils.cpp undefined reference to FolderUtils::m_userFolderPrefix (where line 141 is the first “Fritzing” I replaced with m_userFolderPrefix)

when compiled, even though m_openSaveFolder defined just above m_userFolderPrefix in the .h file is used in public function FolderUtils::openSaveFolder() and seems to resolve correctly (and thus I think should work here!) Can you tell me what I am doing wrong please?

Peter

Well, what do you want to achieve?

  1. The variable name “userFolderPrefix” suggests me that you want a different prefix for the user folder, which doesn’t make sense. On ubuntu, this prefix is the $HOME directory, and it will cause trouble to try to change that. Other operating systems won’t permit it as well.

  2. From the semantics, with focus on the return value, you want to renaming the Fritzing folder to something else, configured via this variable. However, it is not save to assume that the entire code base uses this exact code snippet for determining the directory, which might lead to confusion and possible loss of user data.

  3. Check the documentation for QSettings, your code is trying to use a different Application name and Organisation name. Again from the variable name I guess this is not intended, and you might end up with ini files (and the Mac and Linux equivalents) at odd locations.

  4. The folder utils are already used as a singleton ( static FolderUtils * singleton) , I see few reason why userFolderPrefix variable should also be static, as it might as well be stored together in memory with its class as a member.

  5. If your original question is still relevant: In folderutils.h you only have the declaration of those variables. You are still missing the definition. Ok, that sounds almost like the compiler error message :slight_smile: The compiler does not yet know which translation unit (=object file) the variable should be stored in. m_openSaveFolder is defined in line 48 in folderutils.cpp.

Greetings, Kjell

The aim is to add a prefix (actually I guess a postfix) to the Fritzing (not change, at least now) the system defined user directory path. I.e. when I’m running a development version, instead of the user directories in

~/Documents/Fritzing/
~/.config/Fritzing

which the production version is using, I want to add a command line flag to add a postfix so it can become

~/Documents/Fritzing-dev/
~/.config/Fritzing-dev

in a development version so both versions can run on the same system without interfering with each other. In the longer term, there have been requests for Fritizng to run self contained from a USB key (although more than this would need to change to do that.) and this could be part of that I expect. For now all I want to do is tag something on the end of the Fritzing at the end of the directory to make it unique. This particular piece of code is what sets the destination of the user directories for everything, I have hard coded the change before and know that it works successfully.

That isn’t part of what I wanted to do for sure. How am I changing that?

Being pretty much entirely ignorant of c++ I usually find a snippit of code doing something similar to what I want to do and copy it, which is what I did here. I made the variable static, because I expect the location of the user directories is queried often and the modified value needs to stick around. I did see the singleton definition, but was not sure what it does. If it allocates static variables then that is probably the correct place to put this. Thanks, I’ll poke at this more tomorrow and see if I can figure it out. I may be back with more questions though :slight_smile: .

Peter

To have separate configurations for development and production version, running on the same system at the same time, it could make sense to change the application name to FritzingDev or similar, and QSettings should sort this out.
However, this is unfortunately not the only place where settings are accessed, the autorouter, the preferences dialog, and the application (fapplication) use it. Mostly they use the default QSettings namespace. Fapplication also has some legacy code for windows xp, to associate .fz files with Fritzing… not sure if that is still effective, but for FritzingDev build running in parallel to a production build, you would want to disable that.

My theory has been that Fritzing is writing to 3 places (that I know of): the code folder it was launched from for the parts db, and sql server and probably more, which is self regulating (the dev version will be in a different folder), the user directories (currently hard coded and thus the same for all instances) and the temp directories which Qt handles (and thus shouldn’t be an issue here I don’t think.) It seems to me that allowing a change to the user directories by a command line flag should work. I had indeed at some point commented out the definition of m_userFolderPrefix (now called m_userFolderPostfix) and forgotten to re enable it. With that fixed and the command line code added it is mostly working. Something that I so far have not been able to trace is creating a directory .config/Fritizng containing a file Fritzing.conf. It appears to be in settings (which I have no idea about), in makeRequestParamsString which should be making a list of the Fritzing parameters as far as I can see. Gdb just skips right over the part that creates the directory and file without stopping on any of it (possibly because it is in a different thread?) Searching for conf or Fritzing with grep in the source code didn’t turn anythign up (that is how I usually find code.) Once I work that out I’ll look at the other stuff to see if I think it will cause a problem. I’m hoping not but we will see.

Edit: after much head scratching, I think the .config/Fritzing.conf is the default if you don’t set a path (which is why I can’t find a reference to the path!) I’ll try setting a path (it looks in a Qt example like it will accept one), and if that works I should be able to set it from m_userFolderPostfix and everything should just work (I hope!)

Peter

OK I’m mostly there I think. On linux, I have something that appears to work and only a couple of questions, Windows as usual is problematic. It looks like the git interface uses its own initializer somewhere (although I don’t know where.) On linux changing

src/version/partschecker.cpp

from (where the commented out settings is what is in place everywhere else):

    for (i = 0; i < remote_heads_len; i++) {
            // we only care about the master branch
            if (strcmp(remote_heads[i]->name, "refs/heads/master") == 0) {
                    char oid[GIT_OID_HEXSZ + 1] = {0};
                    git_oid_fmt(oid, &remote_heads[i]->oid);
                    QString soid(oid);
                    remoteSha = soid;
                    QSettings settings;
//                  QSettings settings(FolderUtils::getTopLevelUserDataStorePath() + "/Fritzing.conf", QSettings::NativeFormat);
                    QString lastPartsSha = settings.value("lastPartsSha", "").toString();

works fine, however changing to this:

    for (i = 0; i < remote_heads_len; i++) {
            // we only care about the master branch
            if (strcmp(remote_heads[i]->name, "refs/heads/master") == 0) {
                    char oid[GIT_OID_HEXSZ + 1] = {0};
                    git_oid_fmt(oid, &remote_heads[i]->oid);
                    QString soid(oid);
                    remoteSha = soid;
//                   QSettings settings;
                    QSettings settings(FolderUtils::getTopLevelUserDataStorePath() + "/Fritzing.conf", QSettings::NativeFormat);
                    QString lastPartsSha = settings.value("lastPartsSha", "").toString();
                    settings.setValue("lastPartsSha", soid);

causes this, which I think is fine, it looks to me like gitlib2 has done something qit specific to settings and I just need to leave this alone to do its thing, but having someone that understands this verify that would be good! I think what is happening is that gitlib2 is changing settings somehow I don’t understand to do git specific things and my change breaks it. With the first code snippit, Fritzing seems to run fine, and does not create a Fritzing/Fritzing.conf file (it is in Fritzing-dev/Fritzing.conf as expected.) So I think this should be fine.

partschecker.o /home/vanepp/fritzing-app/src/version/partschecker.cpp
In file included from /home/vanepp/libgit2/include/git2/clone.h:14:0,
from /home/vanepp/libgit2/include/git2.h:20,
from /home/vanepp/fritzing-app/src/version/partschecker.cpp:37:
/home/vanepp/fritzing-app/src/version/partschecker.cpp: In static member function ‘static bool PartsChecker::newPartsAvailable(const QString&, const QString&, bool, QString&, PartsCheckerResult&)’:
/home/vanepp/libgit2/include/git2/remote.h:567:64: warning: missing initializer for member ‘git_remote_callbacks::sideband_progress’ [-Wmissing-field-initializers]
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
^
/home/vanepp/fritzing-app/src/version/partschecker.cpp:88:35: note: in expansion of macro ‘GIT_REMOTE_CALLBACKS_INIT’
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
^~~~~~~~~~~~~~~~~~~~~~~~~
/home/vanepp/libgit2/include/git2/remote.h:567:64: warning: missing initializer for member ‘git_remote_callbacks::completion’ [-Wmissing-field-initializers]
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
^
/home/vanepp/fritzing-app/src/version/partschecker.cpp:88:35: note: in expansion of macro ‘GIT_REMOTE_CALLBACKS_INIT’
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
^~~~~~~~~~~~~~~~~~~~~~~~~
/home/vanepp/libgit2/include/git2/remote.h:567:64: warning: missing initializer for member ‘git_remote_callbacks::credentials’ [-Wmissing-field-initializers]
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
^
/home/vanepp/fritzing-app/src/version/partschecker.cpp:88:35: note: in expansion of macro ‘GIT_REMOTE_CALLBACKS_INIT’
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
^~~~~~~~~~~~~~~~~~~~~~~~~
/home/vanepp/libgit2/include/git2/remote.h:567:64: warning: missing initializer for member ‘git_remote_callbacks::certificate_check’ [-Wmissing-field-initializers]
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
^
/home/vanepp/fritzing-app/src/version/partschecker.cpp:88:35: note: in expansion of macro ‘GIT_REMOTE_CALLBACKS_INIT’
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
^~~~~~~~~~~~~~~~~~~~~~~~~
/home/vanepp/libgit2/include/git2/remote.h:567:64: warning: missing initializer for member ‘git_remote_callbacks::transfer_progress’ [-Wmissing-field-initializers]
#define GIT_REMOTE_CALLBACKS_INIT {GIT_REMOTE_CALLBACKS_VERSION}
^
/home/vanepp/fritzing-app/src/version/partschecker.cpp:88:35: note: in expansion of macro ‘GIT_REMOTE_CALLBACKS_INIT’
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
^~~~~~~~~~~~~~~~~~~~~~~~~
/home/vanepp/libgit2/include/git2/remote.h:567:64: warning: missing initializer for member ‘git_remote_callbacks::update_tips’ [-Wmissing-field-initializers]

Then on to Windows (still Win7 because my Internet link isn’t in good enough shape to do a download of Qt!). Here I have a couple of questions. Is there a debug mode for phoenix.pro?

When I run it on Win7 it hangs in this line in pri/gitversion.pri

BUILD_DATE = $$system( powershell (Get-Date -Format "o") )

but the command “powershell (Get-Date -Format “o”)” runs fine in a command prompt window, just not when invoced by $$system apparantly. I have worked around this by setting BUILD_DATE to the string the command window delivers but I need to eventually find out what is wrong. Then a problem I haven’t found a workaround for yet. When I add a debug statement here in

src/utils/folderutils.cpp at:

QString FolderUtils::getTopLevelUserDataStorePath() {
QString path = QSettings(QSettings::IniFormat,QSettings::UserScope,“Fritzing”,“Fritzing”).fileName();
//DebugDialog::debug(QString(“getTopLevelUserDataStorePath %1”).arg(QFileInfo(path).dir().absolutePath()) );
DebugDialog::debug(QString("getTopLevelUserDataStorePath "));
return QFileInfo(path).dir().absolutePath();
}

it works on Linux. On Windows I get:

17:55:51: Starting E:\fritzing-dev\debug64\Fritzing…
QWidget: Must construct a QApplication before a QWidget
17:56:22: E:/fritzing-dev/debug64/Fritzing exited with code 3

which seems to be trying to tell me I haven’t initialized the debug widget yet although it works on Linux just fine. I have no idea how to initialize a widget. Windows appears to be using a different directory for the config files than Linux. Nothing gets written in to either of the user directories AppData/Roaming/Fritzing nor User/Docuements/Fritzing in the form of config files, so there must be a third place I don’t know about and that debug statement should tell me where it is if it only worked.
The registry change code for XP shouldn’t be an issue (it should perhaps be updated for Win10, although in a quick search I didn’t find data on how to set this from an application on Win 10, all the instructions are for via the gui.) It is using settings to change the registry and I believe later than XP is ignoring those registy settings so leaving it as is should be fine. If we manage to get it working, it should set the registry to the executable just launched which should be OK, it won’t affect the Fritzing settings values as far as I can see, and that is what we need to avoid.

Peter