diff --git a/installers/installer.iss b/installers/installer.iss index a48e4af3a9..1d607659b0 100644 --- a/installers/installer.iss +++ b/installers/installer.iss @@ -26,7 +26,7 @@ UsedUserAreasWarning=no LicenseFile=license.txt ArchitecturesInstallIn64BitMode=x64 OutputBaseFilename=setupSasView -SetupIconFile=dist\sasview\_internal\images\ball.ico +SetupIconFile=dist\sasview\images\ball.ico ; Uncomment the following line to run in non administrative install mode (install for current user only.) @@ -55,9 +55,8 @@ end; [Files] Source: "dist\sasview\sasview.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "dist\sasview\plugin_models\*"; DestDir: "{%USERPROFILE}\.sasview\plugin_models" Source: "dist\sasview\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs -Source: "dist\sasview\_internal\plugin_models\*"; DestDir: "{%USERPROFILE}\.sasview\plugin_models" -Source: "dist\sasview\_internal\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs [Icons] Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon diff --git a/installers/sasview.spec b/installers/sasview.spec index f19ebcbf7c..94bb53a9a8 100644 --- a/installers/sasview.spec +++ b/installers/sasview.spec @@ -102,6 +102,7 @@ if platform.system() == 'Darwin': a.scripts, exclude_binaries=True, name='sasview', + contents_directory='.', debug=False, upx=True, icon=os.path.join("../src/sas/qtgui/images","ball.icns"), @@ -114,6 +115,7 @@ else: [], exclude_binaries=True, name='sasview', + contents_directory='.', debug=False, bootloader_ignore_signals=False, icon=os.path.join("../src/sas/qtgui/images","ball.ico"), diff --git a/src/sas/qtgui/Utilities/DocViewWidget.py b/src/sas/qtgui/Utilities/DocViewWidget.py index 3be303b81a..7b6e84e8bc 100644 --- a/src/sas/qtgui/Utilities/DocViewWidget.py +++ b/src/sas/qtgui/Utilities/DocViewWidget.py @@ -1,6 +1,7 @@ import sys import os import logging +import time from pathlib import Path from PySide6 import QtCore, QtWidgets, QtWebEngineCore @@ -9,7 +10,9 @@ from .UI.DocViewWidgetUI import Ui_DocViewerWindow from sas.qtgui.Utilities.TabbedModelEditor import TabbedModelEditor from sas.sascalc.fit import models -from sas.sascalc.doc_regen.makedocumentation import make_documentation, HELP_DIRECTORY_LOCATION, MAIN_DOC_SRC, PATH_LIKE +from sas.sascalc.data_util.calcthread import CalcThread +from sas.sascalc.doc_regen.makedocumentation import (make_documentation, create_user_files_if_needed, + HELP_DIRECTORY_LOCATION, MAIN_DOC_SRC, PATH_LIKE) HTML_404 = ''' @@ -21,6 +24,39 @@ ''' +class DocGenThread(CalcThread): + """Thread performing the fit """ + + def __init__(self, + target, + completefn=None, + updatefn=None, + yieldtime=0.03, + worktime=0.03, + reset_flag=False): + CalcThread.__init__(self, + completefn, + updatefn, + yieldtime, + worktime) + self.starttime = time.time() + self.updatefn = updatefn + self.reset_flag = reset_flag + self.target = Path(target) + + def compute(self): + """ + Regen the docs in a separate thread + """ + try: + if self.target.exists(): + make_documentation(self.target) + else: + return + except KeyboardInterrupt as msg: + logging.log(0, msg) + + class DocViewWindow(QtWidgets.QDialog, Ui_DocViewerWindow): """ Instantiates a window to view documentation using a QWebEngineViewer widget @@ -102,6 +138,7 @@ def regenerateIfNeeded(self): rst_path = MAIN_DOC_SRC base_path = self.source.parent.parts url_str = str(self.source) + create_user_files_if_needed() if not MAIN_DOC_SRC.exists() and not HELP_DIRECTORY_LOCATION.exists(): # The user docs were never built - disable edit button and do not attempt doc regen @@ -220,7 +257,13 @@ def regenerateDocs(target: PATH_LIKE = None): :param target: A file-path like object that needs regeneration. """ - make_documentation(target) + thread = DocGenThread(target=target) + thread.queue() + thread.ready(2.5) + while not thread.isrunning(): + time.sleep(0.1) + while thread.isrunning(): + time.sleep(0.1) def docRegenComplete(self, return_val): """Tells Qt that regeneration of docs is done and emits signal tied to opening documentation viewer window. diff --git a/src/sas/sascalc/doc_regen/makedocumentation.py b/src/sas/sascalc/doc_regen/makedocumentation.py index 1beec1494f..feea24052a 100644 --- a/src/sas/sascalc/doc_regen/makedocumentation.py +++ b/src/sas/sascalc/doc_regen/makedocumentation.py @@ -38,6 +38,10 @@ # This is the directory structure for the installed version of SasView (primary for times when both exist) BASE_DIR = SAS_DIR / "doc" ORIGINAL_DOCS_SRC = BASE_DIR / "source" +elif os.path.exists(SAS_DIR / '..' / 'Frameworks' / 'doc'): + # In the MacOS bundle, the executable and packages are in parallel directories + BASE_DIR = SAS_DIR / '..' / 'Frameworks' / 'doc' + ORIGINAL_DOCS_SRC = BASE_DIR / "source" else: # This is the directory structure for developers BASE_DIR = SAS_DIR / "docs" / "sphinx-docs" @@ -99,6 +103,7 @@ def call_regenmodel(filepath: list[PATH_LIKE]): :param filepath: A file-path like object or list of file-path like objects to regenerate. """ + create_user_files_if_needed() from sas.sascalc.doc_regen.regenmodel import run_sphinx, process_model filepaths = [Path(path) for path in filepath] rst_files = [Path(process_model(py_file, True)) for py_file in filepaths] @@ -184,6 +189,7 @@ def make_documentation(target: PATH_LIKE = "."): :param target: A file name that needs the html regenerated. """ + create_user_files_if_needed() # Ensure target is a path object if target: target = Path(target)