Developer forums (C::B DEVELOPMENT STRICTLY!) > Development

New switch --user-config

<< < (2/5) > >>

dmoore:
I started exactly as you suggest, by copying prefix more or less. But the problem is that CfgMgrBldr is constructed as a side effect of the first manager::get so using configmanager::write to set it from the main App (as is done for prefix) is too late.

These are static functions/members so I guess I can move them back to ConfigManager,  but CfgMgrBldr will still need to access them. What do you think?

Also, will probably rename the switch --user data dir since it applies to config files and other user data.

dmoore:
New version of patch...


1. Switch is now called --user-data-dir


--- Code: ---codeblocks --user-data-dir=/my/writeable/path

--- End code ---

2. The new methods and members are now part of ConfigManager. The members are private, the methods are protected to prevent them being touched by other parts of the source or plugins. For this to work I had to add CodeblocksApp as a friend class of ConfigManager.

TODO: Could make sure directory is writeable and quit if not.


--- Code: ---Index: src/include/configmanager.h
===================================================================
--- src/include/configmanager.h (revision 9594)
+++ src/include/configmanager.h (working copy)
@@ -87,6 +87,7 @@
 };
 
 
+class CodeBlocksApp;
 
 /* ------------------------------------------------------------------------------------------------------------------
 *  ConfigManager class
@@ -94,6 +95,7 @@
 class DLLIMPORT ConfigManager
 {
     friend class CfgMgrBldr;
+    friend class CodeBlocksApp;
 
     TiXmlDocument *doc;
     TiXmlElement* root;
@@ -106,18 +108,30 @@
     inline void Collapse(wxString& str) const;
     wxString InvalidNameMessage(const wxString& what, const wxString& sub, TiXmlElement *localPath) const;
     static void InitPaths();
+    static inline wxString GetUserConfigDir();
 
     static wxString config_folder;
     static wxString home_folder;
     static wxString data_path_user;
     static wxString data_path_global;
+
 #ifdef CB_AUTOCONF
     static wxString plugin_path_global;
 #endif
     static wxString app_path;
     static wxString temp_folder;
     static bool relo;
+    static wxString alternate_user_data_path;
+    static bool has_alternate_user_data_path;
 
+protected:
+    //For use by the CodeBlocksApp when the --user-data-dir switch is set
+    //all of the user config and user plugin data will be set relative to this path
+    static void SetUserDataFolder(const wxString &user_data_path);
+
+    //Used by CfgMgrBldr internally by ConfigManager
+    static wxString GetUserDataFolder();
+
 public:
 
     /* -----------------------------------------------------------------------------------------------------
Index: src/sdk/configmanager.cpp
===================================================================
--- src/sdk/configmanager.cpp (revision 9594)
+++ src/sdk/configmanager.cpp (working copy)
@@ -53,6 +53,9 @@
 template<> CfgMgrBldr* Mgr<CfgMgrBldr>::instance = nullptr;
 template<> bool  Mgr<CfgMgrBldr>::isShutdown = false;
 
+wxString ConfigManager::alternate_user_data_path;
+bool ConfigManager::has_alternate_user_data_path=false;
+
 wxString ConfigManager::config_folder;
 wxString ConfigManager::home_folder;
 wxString ConfigManager::data_path_user;
@@ -64,6 +67,8 @@
 wxString ConfigManager::temp_folder;
 bool ConfigManager::relo = 0;
 
+
+
 #ifdef __WINDOWS__
 inline wxString GetPortableConfigDir()
 {
@@ -71,7 +76,7 @@
     if (::GetEnvironmentVariable(_T("APPDATA"), buffer, MAX_PATH))
         return wxString::Format(_T("%s\\CodeBlocks"), buffer);
     else
-        return wxStandardPathsBase::Get().GetUserDataDir();
+        return ConfigManager::GetUserDataFolder();
 }
 #endif
 
@@ -194,7 +199,7 @@
         #ifdef __WINDOWS__
         cfg = GetPortableConfigDir() + wxFILE_SEP_PATH + personality + _T(".conf");
         #else
-        cfg = wxStandardPathsBase::Get().GetUserDataDir() + wxFILE_SEP_PATH + personality + _T(".conf");
+        cfg = ConfigManager::GetUserDataFolder() + wxFILE_SEP_PATH + personality + _T(".conf");
         #endif
         doc = new TiXmlDocument();
         doc->InsertEndChild(TiXmlDeclaration("1.0", "UTF-8", "yes"));
@@ -213,7 +218,7 @@
 #ifdef __WINDOWS__
     wxString u(GetPortableConfigDir() + wxFILE_SEP_PATH + filename);
 #else
-    wxString u(wxStandardPathsBase::Get().GetUserDataDir() + wxFILE_SEP_PATH + filename);
+    wxString u(ConfigManager::GetUserDataFolder() + wxFILE_SEP_PATH + filename);
 #endif
     wxString e(::DetermineExecutablePath() + wxFILE_SEP_PATH + filename);
 
@@ -439,7 +444,6 @@
     return c;
 }
 
-
 /*
 *  Hack to enable Turkish language. wxString::Upper will convert lowercase 'i' to \u0130 instead of \u0069 in Turkish locale,
 *  which will break the config file when used in a tag
@@ -552,6 +556,20 @@
     }
 }
 
+inline wxString ConfigManager::GetUserDataFolder()
+{
+    if (has_alternate_user_data_path)
+        return alternate_user_data_path;
+    return wxStandardPathsBase::Get().GetUserDataDir();
+}
+
+void ConfigManager::SetUserDataFolder(const wxString &user_data_path)
+{
+    //TODO: Check that this is a valid writeable path
+    has_alternate_user_data_path = true;
+    ConfigManager::alternate_user_data_path = user_data_path;
+}
+
 wxString ConfigManager::LocateDataFile(const wxString& filename, int search_dirs)
 {
     wxPathList searchPaths;
@@ -1440,7 +1458,7 @@
 #ifdef __WINDOWS__
     ConfigManager::config_folder = GetPortableConfigDir();
 #else
-    ConfigManager::config_folder = wxStandardPathsBase::Get().GetUserDataDir();
+    ConfigManager::config_folder = ConfigManager::GetUserDataFolder();
 #endif
     ConfigManager::home_folder = wxStandardPathsBase::Get().GetUserConfigDir();
     ConfigManager::app_path = ::DetermineExecutablePath();
Index: src/src/app.cpp
===================================================================
--- src/src/app.cpp (revision 9594)
+++ src/src/app.cpp (working copy)
@@ -212,6 +212,8 @@
       wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
     { wxCMD_LINE_OPTION, CMD_ENTRY(""),   CMD_ENTRY("prefix"),                CMD_ENTRY("the shared data dir prefix"),
       wxCMD_LINE_VAL_STRING, wxCMD_LINE_NEEDS_SEPARATOR },
+    { wxCMD_LINE_OPTION, CMD_ENTRY(""),   CMD_ENTRY("user-data-dir"),                CMD_ENTRY("set a custom location for user configuration files"),
+      wxCMD_LINE_VAL_STRING, wxCMD_LINE_NEEDS_SEPARATOR },
     { wxCMD_LINE_OPTION, CMD_ENTRY("p"),  CMD_ENTRY("personality"),           CMD_ENTRY("the personality to use: \"ask\" or <personality-name>"),
       wxCMD_LINE_VAL_STRING, wxCMD_LINE_NEEDS_SEPARATOR },
     { wxCMD_LINE_SWITCH, CMD_ENTRY(""),   CMD_ENTRY("no-log"),                CMD_ENTRY("turn off the application log"),
@@ -313,6 +315,11 @@
     if (ParseCmdLine(nullptr) == -1) // only abort if '--help' was passed in the command line
         return false;
 
+    if (m_UserDataDir!=wxEmptyString)
+        ConfigManager::SetUserDataFolder(m_UserDataDir); // if --user-data-dir=path was specified we tell
+                                                     //ConfigManager (and CfgMgrBldr) about it, which will propagate
+                                                     //it through config manager
+
     ConfigManager *cfg = Manager::Get()->GetConfigManager(_T("app"));
 
     wxString data(wxT(APP_PREFIX));
@@ -1100,6 +1107,7 @@
                 {
                     wxString val;
                     parser.Found(_T("prefix"), &m_Prefix);
+                    parser.Found(_T("user-data-dir"), &m_UserDataDir);
 #ifdef __WXMSW__
                     m_DDE = !parser.Found(_T("no-dde"));
                     m_Assocs = !parser.Found(_T("no-check-associations"));
Index: src/src/app.h
===================================================================
--- src/src/app.h (revision 9594)
+++ src/src/app.h (working copy)
@@ -69,7 +69,8 @@
         void SetupPersonality(const wxString& personality);
 
 
-        wxString m_Prefix; // --prefix switch
+        wxString m_Prefix; // directory specified in --prefix switch
+        wxString m_UserDataDir; // directory specified in --user-data-dir switch
         wxString m_BatchTarget;
         wxString m_Script;
         wxString m_AutoFile; // --file foo.cpp[:line]

--- End code ---


[attachment deleted by admin]

oBFusCATed:

--- Quote from: dmoore on January 21, 2014, 08:28:09 pm ---For this to work I had to add CodeblocksApp as a friend class of ConfigManager.

--- End quote ---
This sounds bad. As far as I know the ConfigManager is in libcodeblocks and CodeblocksApp is in codeblocks.exe, seems dangerous to me.
Why don't you just stick a big comment above them, explicitly stating that they should be called only by the main application linking libcodeblocks.
Keep in mind that it is possible to have multiple codeblocks.exe versions. For example Jens has a branch where there are two such executables.

dmoore:

--- Quote from: oBFusCATed on January 21, 2014, 08:58:19 pm ---
--- Quote from: dmoore on January 21, 2014, 08:28:09 pm ---For this to work I had to add CodeblocksApp as a friend class of ConfigManager.

--- End quote ---
This sounds bad. As far as I know the ConfigManager is in libcodeblocks and CodeblocksApp is in codeblocks.exe, seems dangerous to me.
Why don't you just stick a big comment above them, explicitly stating that they should be called only by the main application linking libcodeblocks.
Keep in mind that it is possible to have multiple codeblocks.exe versions. For example Jens has a branch where there are two such executables.

--- End quote ---

Making them public kind of defeats the purpose of all this builder/singleton pattern nonsense in the first place. But really, I don't care, I just want the feature. (Btw, friend class doesn't require the class actually exists right? It just prevents non-friends from using the methods.)

oBFusCATed:
I think you need to have it forward declared.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version