From 8e6b1538b6de391bbdf2197ae81f6894eb051244 Mon Sep 17 00:00:00 2001
From: Doug Massay <dougmassay@users.noreply.github.com>
Date: Thu, 4 Aug 2016 09:31:32 -0400
Subject: [PATCH] Refactor mapreri's pull request as discussed

---
 docs/BuildingOnLinux.html                          |  5 +--
 docs/BuildingOnLinux.md                            |  6 ++--
 src/CMakeLists.txt                                 |  9 ++++-
 src/Dialogs/PluginRunner.cpp                       |  3 ++
 src/Misc/SpellCheck.cpp                            | 20 +----------
 src/Misc/Utility.cpp                               | 36 +++++++++++++++++++
 src/Misc/Utility.h                                 |  5 +++
 .../plugin_launchers/python/wrapper.py             | 42 +++-------------------
 src/sigil_constants.cpp                            |  4 ++-
 src/sigil_constants.h                              |  4 ++-
 10 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/docs/BuildingOnLinux.html b/docs/BuildingOnLinux.html
index 8871a22..f05b2d4 100644
--- a/docs/BuildingOnLinux.html
+++ b/docs/BuildingOnLinux.html
@@ -153,7 +153,8 @@
 <p>-DSHARE_INSTALL_PREFIX=<code>&lt;path&gt;</code> Configures the prefix where Sigil's support files will be installed to (default is /usr/local meaning the support files will be installed in /usr/local/share/sigil)</p>
 <p>-DUSE_SYSTEM_LIBS=(0|1) Tells cmake to try and use the system libraries when building Sigil instead of the ones bundled with Sigil in the 3rdParty directory. If a system version of a 3rd-party can't be found, Sigil falls back on the bundled version -- unless -DSYSTEM_LIBS_REQUIRED=1 is also specified (default is 0).</p>
 <p>-DSYSTEM_LIBS_REQUIRED=(0|1) When used in conjunction with -DUSE_SYSTEM_LIBS=1, the Sigil build process will fail if all the necessary libraries can't be located on the system, instead of falling back on the bundled versions (default is 0).</p>
-<p>-DINSTALL_BUNDLED_DICTS=(0|1) Can be used to enable/disable the installation of the bundled Hunspell dictionaries used for spellchecking. If this is disabled (-DINSTALL_BUNDLED_DICTS=0) then the user will need to specify the location of the hunspell dictionaries they want Sigil to use by setting an environment variable named SIGIL_DICTIONARIES.</p>
+<p>-DINSTALL_BUNDLED_DICTS=(0|1) Default is 1. Can be used to enable/disable the installation of the bundled Hunspell dictionaries used for spellchecking. If this is disabled (-DINSTALL_BUNDLED_DICTS=0), then the standard system spell-check dictionary location of /usr/share/hunspell will be searched for eligible dictionaries. If additional system paths need to be searched for dictionaries, they can be added using the -DEXTRA_DICT_DIRS option.</p>
+<p>-DEXTRA_DICT_DIRS=<code>&lt;path1&gt;</code>:<code>&lt;path2&gt;</code> Path(s) that should be searched for eligible spellcheck dictionaries (in addition to /usr/share/hunspell). Multiple paths should be separated by colons. This option is only relevant if -DINSTALL_BUNDLED_DICTS=0 is also specified.</p>
 <p>The following three cmake options are used to manually specify which Python3 you want to use when building Sigil instead of relying on the included cmake utilities to try and automatically find a suitable version.</p>
 <p>-DPYTHON_LIBRARY=<code>&lt;the path to the python3.4 shared library&gt;</code></p>
 <p>-DPYTHON_INCLUDE_DIR=<code>&lt;the path to the directory where python3.4's header files can be found&gt;</code></p>
@@ -161,7 +162,7 @@
 <p>The following are environment variables that can be set at runtime to affect how Sigil is run after building/installing. They are commonly set by manually editing Sigil's launch script (<code>&lt;CMAKE_INSTALL_PREFIX&gt;</code>/bin/sigil).</p>
 <p>SIGIL_PREFS_DIR - Changes where sigil looks for and updates its user preference data. Needs to specify a full path in a directory where the user has write privileges.</p>
 <p>SIGIL_EXTRA_ROOT - Handy for relocating the Sigil support files. For instance you can move the <code>&lt;CMAKE_SHARE_PREFIX&gt;/share/sigil</code> directory anywhere you like. You just have to set SIGIL_EXTRA_ROOT to the path where you moved <code>&lt;CMAKE_SHARE_PREFIX&gt;/share/sigil</code> to.</p>
-<p>SIGIL_DICTIONARIES - Used to tell Sigil what directories are to be searched for Hunspell dictionary files. Multiple directories can be specified by separating the paths with a colon. i.e. SIGIL_DICTIONARIES="/usr/share/hunspell" or SIGIL_DICTIONARIES="/usr/share/hunspell:/usr/share/hunspellextra"</p>
+<p>SIGIL_DICTIONARIES - Used to tell Sigil what directories are to be searched for Hunspell dictionary files. Multiple directories can be specified by separating the paths with a colon. i.e. SIGIL_DICTIONARIES="/usr/share/hunspell" or SIGIL_DICTIONARIES="/usr/share/hunspell:/usr/share/hunspellextra" Setting this variable at run time will override all compile-time dictionary search paths (except for any user-supplied dictionaries manually added to their preference directory's hunspell_dictionary location).</p>
 <p>The Sigil launch script also sets a SIGIL_SHARE_PREFIX environment variable, but it is automatically set to be the same as the cmake SHARE_INSTALL_PREFIX build-time option. It would be unwise to change this environment variable. Use the SIGIL_EXTRA_ROOT environment variable instead, if you need to alter the location of Sigil's support files after building Sigil.</p>
 </body>
 </html>
diff --git a/docs/BuildingOnLinux.md b/docs/BuildingOnLinux.md
index afbdcf2..10e4d10 100644
--- a/docs/BuildingOnLinux.md
+++ b/docs/BuildingOnLinux.md
@@ -181,7 +181,9 @@ There are several configuration and environment variable options that can tailor
 
 -DSYSTEM_LIBS_REQUIRED=(0|1) When used in conjunction with -DUSE_SYSTEM_LIBS=1, the Sigil build process will fail if all the necessary libraries can't be located on the system, instead of falling back on the bundled versions (default is 0).
 
--DINSTALL_BUNDLED_DICTS=(0|1) Can be used to enable/disable the installation of the bundled Hunspell dictionaries used for spellchecking. If this is disabled (-DINSTALL_BUNDLED_DICTS=0) then the user will need to specify the location of the hunspell dictionaries they want Sigil to use by setting an environment variable named SIGIL_DICTIONARIES.
+-DINSTALL_BUNDLED_DICTS=(0|1) Default is 1. Can be used to enable/disable the installation of the bundled Hunspell dictionaries used for spellchecking. If this is disabled (-DINSTALL_BUNDLED_DICTS=0), then the standard system spell-check dictionary location of /usr/share/hunspell will be searched for eligible dictionaries. If additional system paths need to be searched for dictionaries, they can be added using the -DEXTRA_DICT_DIRS option.
+
+-DEXTRA_DICT_DIRS=`<path1>`:`<path2>` Path(s) that should be searched for eligible spellcheck dictionaries (in addition to /usr/share/hunspell). Multiple paths should be separated by colons. This option is only relevant if -DINSTALL_BUNDLED_DICTS=0 is also specified.
 
 The following three cmake options are used to manually specify which Python3 you want to use when building Sigil instead of relying on the included cmake utilities to try and automatically find a suitable version.
 
@@ -197,6 +199,6 @@ SIGIL_PREFS_DIR - Changes where sigil looks for and updates its user preference
 
 SIGIL_EXTRA_ROOT - Handy for relocating the Sigil support files. For instance you can move the `<CMAKE_SHARE_PREFIX>/share/sigil` directory anywhere you like. You just have to set SIGIL_EXTRA_ROOT to the path where you moved `<CMAKE_SHARE_PREFIX>/share/sigil` to.
 
-SIGIL_DICTIONARIES - Used to tell Sigil what directories are to be searched for Hunspell dictionary files. Multiple directories can be specified by separating the paths with a colon. i.e. SIGIL_DICTIONARIES="/usr/share/hunspell" or SIGIL_DICTIONARIES="/usr/share/hunspell:/usr/share/hunspellextra"
+SIGIL_DICTIONARIES - Used to tell Sigil what directories are to be searched for Hunspell dictionary files. Multiple directories can be specified by separating the paths with a colon. i.e. SIGIL_DICTIONARIES="/usr/share/hunspell" or SIGIL_DICTIONARIES="/usr/share/hunspell:/usr/share/hunspellextra" Setting this variable at run time will override all compile-time dictionary search paths (except for any user-supplied dictionaries manually added to their preference directory's hunspell_dictionary location).
 
 The Sigil launch script also sets a SIGIL_SHARE_PREFIX environment variable, but it is automatically set to be the same as the cmake SHARE_INSTALL_PREFIX build-time option. It would be unwise to change this environment variable. Use the SIGIL_EXTRA_ROOT environment variable instead, if you need to alter the location of Sigil's support files after building Sigil.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 93046b6..34fff60 100755
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -969,8 +969,15 @@ if( UNIX AND NOT APPLE )
     if ( NOT SHARE_INSTALL_PREFIX )
         set ( SHARE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} )
     endif()
+
     set ( SIGIL_SHARE_ROOT "${SHARE_INSTALL_PREFIX}/share/sigil" )
-    set_source_files_properties( sigil_constants.cpp PROPERTIES COMPILE_DEFINITIONS SIGIL_SHARE_ROOT="${SIGIL_SHARE_ROOT}" )
+
+    # Set some defines that sigil_constants.cpp can then access
+    set_property (
+        SOURCE sigil_constants.cpp
+        PROPERTY COMPILE_DEFINITIONS
+        SIGIL_SHARE_ROOT="${SIGIL_SHARE_ROOT}" DICTS_ARE_BUNDLED=${INSTALL_BUNDLED_DICTS} EXTRA_DICT_DIRS="${EXTRA_DICT_DIRS}"
+    )
 
     # Launch script for sigil
     set( LINUX_LAUNCH_INSTALL_SCRIPT_CONFIGURED ${CMAKE_BINARY_DIR}/sigil-sh_install_configured )
diff --git a/src/Dialogs/PluginRunner.cpp b/src/Dialogs/PluginRunner.cpp
index 171fa48..2dd3229 100644
--- a/src/Dialogs/PluginRunner.cpp
+++ b/src/Dialogs/PluginRunner.cpp
@@ -193,6 +193,9 @@ void PluginRunner::writeSigilCFG()
 {
     QStringList cfg = QStringList() << QCoreApplication::applicationDirPath();
     cfg << Utility::DefinePrefsDir();
+#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
+    cfg << Utility::LinuxHunspellDictionaryDirs().join(":");
+#endif
     QList <Resource *> selected_resources = m_bookBrowser->AllSelectedResources();
     foreach(Resource * resource, selected_resources) {
         cfg << resource->GetRelativePathToRoot();
diff --git a/src/Misc/SpellCheck.cpp b/src/Misc/SpellCheck.cpp
index eeb47e3..6771d98 100644
--- a/src/Misc/SpellCheck.cpp
+++ b/src/Misc/SpellCheck.cpp
@@ -334,25 +334,7 @@ void SpellCheck::loadDictionaryNames()
 #elif defined(Q_OS_WIN32)
     paths << QCoreApplication::applicationDirPath() + "/hunspell_dictionaries";
 #elif !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
-    // prefer the directory specified by the env var SIGIL_DICTIONARIES above all else.
-    if (!system_hunspell_dicts.isEmpty()) {
-        // Handle multiple colon-delimited paths
-        foreach (QString s, system_hunspell_dicts.split(":")) {
-            paths << s.trimmed();
-        }
-    }
-    // else use the env var runtime overridden 'share/sigil/hunspell_dictionaries/' location.
-    else {
-        if (!sigil_extra_root.isEmpty()) {
-            paths.append(sigil_extra_root + "/hunspell_dictionaries/");
-        } else {
-            // prepend the usual places where hunspell dictionaries are located in unix systems
-            paths.append("/usr/share/myspell/");
-            paths.append("/usr/share/hunspell/");
-            // else use the standard build time 'share/sigil/hunspell_dictionaries/'location.
-            paths.append(sigil_share_root + "/hunspell_dictionaries/");
-        }
-    }
+    paths << Utility::LinuxHunspellDictionaryDirs();
 #endif
     // Add the user dictionary directory last because anything in here
     // will override installation supplied dictionaries.
diff --git a/src/Misc/Utility.cpp b/src/Misc/Utility.cpp
index 49a3c62..314f15a 100644
--- a/src/Misc/Utility.cpp
+++ b/src/Misc/Utility.cpp
@@ -100,6 +100,42 @@ QString Utility::DefinePrefsDir()
 }
 
 
+#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
+// Return correct path(s) for Linux hunspell dictionaries
+QStringList Utility::LinuxHunspellDictionaryDirs()
+{
+    QStringList paths;
+    // prefer the directory specified by the env var SIGIL_DICTIONARIES above all else.
+    if (!hunspell_dicts_override.isEmpty()) {
+        // Handle multiple colon-delimited paths
+        foreach (QString s, hunspell_dicts_override.split(":")) {
+            paths << s.trimmed();
+        }
+    }
+    // else use the env var runtime overridden 'share/sigil/hunspell_dictionaries/' location.
+    else if (!sigil_extra_root.isEmpty()) {
+        paths.append(sigil_extra_root + "/hunspell_dictionaries/");
+    }
+    // Bundled dicts were not installed use standard system dictionary location.
+    else if (!dicts_are_bundled) {
+        paths.append("/usr/share/hunspell");
+        // Add additional hunspell dictionary directories. Provided at compile
+        // time via the cmake option EXTRA_DICT_DIRS (colon separated list).
+        if (!extra_dict_dirs.isEmpty()) {
+            foreach (QString s, extra_dict_dirs.split(":")) {
+                paths << s.trimmed();
+            }
+        }
+    }
+    else {
+        // else use the standard build time 'share/sigil/hunspell_dictionaries/'location.
+        paths.append(sigil_share_root + "/hunspell_dictionaries/");
+    }
+    return paths;
+}
+#endif
+
+
 // Uses QUuid to generate a random UUID but also removes
 // the curly braces that QUuid::createUuid() adds
 QString Utility::CreateUUID()
diff --git a/src/Misc/Utility.h b/src/Misc/Utility.h
index b4f03ff..f3d3c54 100644
--- a/src/Misc/Utility.h
+++ b/src/Misc/Utility.h
@@ -50,6 +50,11 @@ class Utility
     // Define the user preferences location to be used
     static QString DefinePrefsDir();
 
+#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
+    // Return correct path(s) for Linux hunspell dictionaries
+    static QStringList LinuxHunspellDictionaryDirs();
+#endif
+
     // Uses QUuid to generate a random UUID but also removes
     // the curly braces that QUuid::createUuid() adds
     static QString CreateUUID();
diff --git a/src/Resource_Files/plugin_launchers/python/wrapper.py b/src/Resource_Files/plugin_launchers/python/wrapper.py
index a1be0eb..84bb343 100644
--- a/src/Resource_Files/plugin_launchers/python/wrapper.py
+++ b/src/Resource_Files/plugin_launchers/python/wrapper.py
@@ -122,6 +122,7 @@ def __init__(self, ebook_root, outdir, op, plugin_dir, plugin_name, debug = Fals
         # initialize the sigil cofiguration info passed in outdir with sigil.cfg
         self.appdir = None
         self.usrsupdir = None
+        self.linux_hunspell_dict_dirs = []
         self.selected = []
         cfg = ''
         with open(os.path.join(self.outdir, 'sigil.cfg'), 'rb') as f:
@@ -131,6 +132,8 @@ def __init__(self, ebook_root, outdir, op, plugin_dir, plugin_name, debug = Fals
         if len(cfg_lst) >= 2:
             self.appdir = cfg_lst.pop(0)
             self.usrsupdir = cfg_lst.pop(0)
+            if not sys.platform.startswith('darwin') and not sys.platform.startswith('win'):
+                self.linux_hunspell_dict_dirs = cfg_lst.pop(0).split(":")
             self.selected = cfg_lst
         os.environ['SigilGumboLibPath'] = self.get_gumbo_path()
 
@@ -797,42 +800,8 @@ def get_dictionary_dirs(self):
             apaths.append(unipath.abspath(os.path.join(self.usrsupdir,"hunspell_dictionaries")))
         else:
             # Linux
-            system_hunspell_dicts = ''
-            share_prefix = ''
-            share_override = ''
-
-            # get the env var SIGIL_DICTIONARIES set at launch time.
-            if 'SIGIL_DICTIONARIES' in os.environ.keys():
-                system_hunspell_dicts = os.environ['SIGIL_DICTIONARIES']
-
-            # Runtime env var override of 'share/sigil' directory.
-            if 'SIGIL_EXTRA_ROOT' in os.environ.keys():
-                share_override = os.environ['SIGIL_EXTRA_ROOT']
-
-            # The sigil launch script in <install_prefix>/bin knows where Sigil's build time
-            # share prefix is and sets the env var SIGIL_SHARE_PREFIX to its value.
-            if 'SIGIL_SHARE_PREFIX' in os.environ.keys():
-                share_prefix = os.environ['SIGIL_SHARE_PREFIX']
-
-            # If someone didn't launch Sigil with its launch script, this may save the
-            # day (as long as the user didn't override SHARE_INSTALL_PREFIX at compile time).
-            if not len(share_prefix) and not len(share_override):
-                share_prefix = unipath.abspath(os.path.join(self.appdir,"..",".."))
-
-            # If the SIGIL_DICTIONARIES env var has content, use it for the dictionary location.
-            if len(system_hunspell_dicts):
-                for path in system_hunspell_dicts.split(':'):
-                    apaths.append(unipath.abspath(path.strip()))
-            else:
-                # If the 'share/sigil' location has indeed been overridden at runtime, use that.
-                if len(share_override):
-                    apaths.append(unipath.abspath(os.path.join(share_override, "hunspell_dictionaries")))
-                else:
-                    # prepend usual places where hunspell dictionaries are located in unix systems
-                    apaths.append(os.path.join(os.sep, 'usr', 'share', 'myspell')
-                    apaths.append(os.path.join(os.sep, 'usr', 'share', 'hunspell')
-                    # Otherwise, use Sigil's bundled hunspell dictionary location.
-                    apaths.append(unipath.abspath(os.path.join(share_prefix, "share", 'sigil', "hunspell_dictionaries")))
+            for path in self.linux_hunspell_dict_dirs:
+                apaths.append(unipath.abspath(path.strip()))
             apaths.append(unipath.abspath(os.path.join(self.usrsupdir,"hunspell_dictionaries")))
         return apaths
 
@@ -859,4 +828,3 @@ def get_hunspell_path(self):
             lib_dir = unipath.abspath(self.appdir)
             lib_name = 'libhunspell.so'
         return os.path.join(lib_dir, lib_name)
-
diff --git a/src/sigil_constants.cpp b/src/sigil_constants.cpp
index 96a1710..0813005 100644
--- a/src/sigil_constants.cpp
+++ b/src/sigil_constants.cpp
@@ -27,10 +27,12 @@ const QString PATH_LIST_DELIM = ":";
 // Runtime env var override of Sigil's 'share/sigil' directory
 const QString sigil_extra_root = QString(getenv("SIGIL_EXTRA_ROOT"));
 // Runtime env var override of hunspell dictionaries directory to use
-const QString system_hunspell_dicts = QString(getenv("SIGIL_DICTIONARIES"));
+const QString hunspell_dicts_override = QString(getenv("SIGIL_DICTIONARIES"));
 // Standard build-time location of Sigil's 'share/sigil' directory. Set in src/CMakeLists.txt with the line:
 // set_source_files_properties( sigil_constants.cpp PROPERTIES COMPILE_DEFINITIONS SIGIL_SHARE_ROOT="${SIGIL_SHARE_ROOT}" )
 const QString sigil_share_root = QString(SIGIL_SHARE_ROOT);
+const bool dicts_are_bundled = DICTS_ARE_BUNDLED;
+const QString extra_dict_dirs = QString(EXTRA_DICT_DIRS);
 const QString PYTHON_MAIN_PATH = "/python3/lib/python3.4";
 #if __x86_64__ || __ppc64__
 const QStringList PYTHON_SYS_PATHS = QStringList () << "/plat-x86_64-linux-gnu" << "/plat-linux" << "/lib-dynload" << "/site-packages";
diff --git a/src/sigil_constants.h b/src/sigil_constants.h
index eaf89e8..fc38330 100644
--- a/src/sigil_constants.h
+++ b/src/sigil_constants.h
@@ -123,9 +123,11 @@ extern const QString PYTHON_MAIN_BIN_PATH;
 extern const QStringList PYTHON_SYS_PATHS;
 
 #if !defined(_WIN32) && !defined(__APPLE__)
-extern const QString system_hunspell_dicts;
 extern const QString sigil_extra_root;
+extern const QString hunspell_dicts_override;
 extern const QString sigil_share_root;
+extern const bool dicts_are_bundled;
+extern const QString extra_dict_dirs;
 #endif
 
 #endif // SG_CONSTANTS_H
