diff --git a/cellacdc/__init__.py b/cellacdc/__init__.py index e00f7c7e..95c74b52 100755 --- a/cellacdc/__init__.py +++ b/cellacdc/__init__.py @@ -142,6 +142,7 @@ def printl(*objects, pretty=False, is_decorator=False, **kwargs): sys.stdout = current_stdout user_path = pathlib.Path.home() +site_packages = os.path.dirname(os.path.dirname(np.__file__)) parent_path = os.path.dirname(cellacdc_path) html_path = os.path.join(cellacdc_path, '_html') data_path = os.path.join(parent_path, 'data') @@ -153,6 +154,7 @@ def printl(*objects, pretty=False, is_decorator=False, **kwargs): resources_path = os.path.join(cellacdc_path, 'resources.qrc') models_list_file_path = os.path.join(temp_path, 'custom_models_paths.ini') user_manual_url = 'https://github.com/SchmollerLab/Cell_ACDC/blob/main/UserManual/Cell-ACDC_User_Manual.pdf' +github_home_url = 'https://github.com/SchmollerLab/Cell_ACDC' # Use to get the acdc_output file name from `segm_filename` as # `m = re.sub(segm_re_pattern, '_acdc_output', segm_filename)` diff --git a/cellacdc/gui.py b/cellacdc/gui.py index 6d18c453..b1ae44d0 100755 --- a/cellacdc/gui.py +++ b/cellacdc/gui.py @@ -78,7 +78,7 @@ from .trackers.CellACDC import CellACDC_tracker from .cca_functions import _calc_rot_vol from .myutils import exec_time, setupLogger -from .help import welcome +from .help import welcome, about if os.name == 'nt': try: @@ -1300,7 +1300,8 @@ def gui_createMenuBar(self): helpMenu = menuBar.addMenu("&Help") helpMenu.addAction(self.tipsAction) helpMenu.addAction(self.UserManualAction) - # helpMenu.addAction(self.aboutAction) + helpMenu.addSeparator() + helpMenu.addAction(self.aboutAction) def gui_createToolBars(self): # File toolbar @@ -2575,6 +2576,7 @@ def gui_createActions(self): # Help actions self.tipsAction = QAction("Tips and tricks...", self) self.UserManualAction = QAction("User Manual...", self) + self.aboutAction = QAction("About Cell-ACDC", self) # self.aboutAction = QAction("&About...", self) # Assign mother to bud button @@ -2817,6 +2819,7 @@ def gui_connectActions(self): # Connect Help actions self.tipsAction.triggered.connect(self.showTipsAndTricks) self.UserManualAction.triggered.connect(myutils.showUserManual) + self.aboutAction.triggered.connect(self.showAbout) # Connect Open Recent to dynamically populate it # self.openRecentMenu.aboutToShow.connect(self.populateOpenRecent) self.checkableQButtonsGroup.buttonClicked.connect(self.uncheckQButton) @@ -21139,6 +21142,10 @@ def pasteContent(self): def cutContent(self): pass + + def showAbout(self): + self.aboutWin = about.QDialogAbout(parent=self) + self.aboutWin.show() def showTipsAndTricks(self): self.welcomeWin = welcome.welcomeWin() diff --git a/cellacdc/help/about.py b/cellacdc/help/about.py index 8b0466e9..042a9417 100755 --- a/cellacdc/help/about.py +++ b/cellacdc/help/about.py @@ -4,12 +4,14 @@ from functools import partial from qtpy.QtWidgets import ( - QDialog, QLabel, QGridLayout, QHBoxLayout, QSpacerItem + QDialog, QLabel, QGridLayout, QHBoxLayout, QSpacerItem, QWidget, QVBoxLayout ) from qtpy.QtGui import QPixmap from qtpy.QtCore import Qt from ..myutils import read_version +from ..myutils import get_pip_install_cellacdc_version_command +from ..myutils import get_git_pull_checkout_cellacdc_version_commands from .. import widgets, myutils from .. import html_utils from .. import qrc_resources @@ -40,17 +42,31 @@ def __init__(self, parent=None): titleLabel.setText(txt) - commandWidget = None - if version.find('.dev') != -1: - # '{next_version}.dev{distance}+{scm letter}{revision hash}' - commit_hash = re.findall(r'\+g(.+)\.', version)[0] - command = f'pip install "git+https://github.com/SchmollerLab/Cell_ACDC.git@{commit_hash}"' - commandLabel = QLabel(html_utils.paragraph( - f'To install this specific version run the following command:', - font_size='11px' - )) - commandWidget = widgets.CopiableCommandWidget( - command=command, font_size='11px' + # '{next_version}.dev{distance}+{scm letter}{revision hash}' + commit_hash = re.findall(r'\+g(.+)\.', version)[0] + command = get_pip_install_cellacdc_version_command(version=version) + commandLabel = QLabel(html_utils.paragraph( + f'To install this specific version ' + f'on a new environment or to upgrade/downgrade in an ' + 'environment where you already have Cell-ACDC
' + 'installed with pip run the following command:' + )) + commandWidget = widgets.CopiableCommandWidget( + command=command, font_size='11px' + ) + + commandWidgetsGit = [] + git_commands = get_git_pull_checkout_cellacdc_version_commands(version) + if git_commands: + commandLabelGit = QLabel(html_utils.paragraph( + f'

To upgrade/downgrade the Cell-ACDC version in an ' + 'environment where you installed it by first cloning with ' + 'git
' + 'run the following commands one by one:' + )) + for command in git_commands: + commandWidgetsGit.append( + widgets.CopiableCommandWidget(command=command, font_size='11px') ) iconPixmap = QPixmap(":icon.ico") @@ -74,6 +90,13 @@ def __init__(self, parent=None): Installed in: {cellacdc_path} """, font_size='12px') installedLabel.setText(txt) + + self.showHowToInstallButton = widgets.helpPushButton( + 'How to install this version' + ) + self.showHowToInstallButton.clicked.connect( + self.showHotToInstallInstructions + ) button = widgets.showInFileManagerButton( myutils.get_open_filemaneger_os_string() @@ -82,21 +105,55 @@ def __init__(self, parent=None): button.clicked.connect(func) installedLayout.addWidget(installedLabel) installedLayout.addStretch(1) + installedLayout.addWidget(self.showHowToInstallButton) installedLayout.addWidget(button) - layout.addWidget(iconLabel, 0, 0) - layout.addWidget(titleLabel, 0, 1, alignment=Qt.AlignLeft) - layout.addWidget(infoLabel, 1, 1, alignment=Qt.AlignLeft) - if commandWidget is not None: - layout.addWidget(commandLabel, 2, 1, alignment=Qt.AlignLeft) - layout.addWidget(commandWidget, 3, 1, alignment=Qt.AlignLeft) + row = 0 + layout.addWidget(iconLabel, row, 0) + layout.addWidget(titleLabel, row, 1, alignment=Qt.AlignLeft) + + row += 1 + layout.addWidget(infoLabel, row, 1, alignment=Qt.AlignLeft) + + row += 1 layout.setColumnStretch(2,1) - layout.addItem(QSpacerItem(10,20), 4, 1) - layout.setRowStretch(5,1) - layout.addLayout(installedLayout, 6, 0, 1, 3) + layout.addItem(QSpacerItem(10,20), row, 1) + + row += 1 + layout.setRowStretch(row,1) + + row += 1 + layout.addLayout(installedLayout, row, 0, 1, 3) + + row += 1 + self.howToInstallDialog = QDialog(self) + self.howToInstallDialog.setWindowTitle( + f'How to install Cell-ACDC v{version}' + ) + howToInstallLayout = QVBoxLayout() + self.howToInstallDialog.setLayout(howToInstallLayout) + + howToInstallOkButton = widgets.okPushButton(' Ok ') + buttonsLayout = QHBoxLayout() + buttonsLayout.addStretch(1) + buttonsLayout.addWidget(howToInstallOkButton) + howToInstallOkButton.clicked.connect(self.howToInstallDialog.close) + + howToInstallLayout.addWidget(commandLabel, alignment=Qt.AlignLeft) + howToInstallLayout.addWidget(commandWidget, alignment=Qt.AlignLeft) + + if git_commands: + howToInstallLayout.addWidget(commandLabelGit, alignment=Qt.AlignLeft) + for widget in commandWidgetsGit: + howToInstallLayout.addWidget(widget, alignment=Qt.AlignLeft) + # layout.addWidget(self.howToInstallWidget, row, 0, 1, 3) + howToInstallLayout.addLayout(buttonsLayout) + self.howToInstallDialog.hide() - self.setLayout(layout) + + def showHotToInstallInstructions(self): + self.howToInstallDialog.show() def _test(): import sys diff --git a/cellacdc/myutils.py b/cellacdc/myutils.py index 30b0e823..14e4f025 100644 --- a/cellacdc/myutils.py +++ b/cellacdc/myutils.py @@ -42,6 +42,7 @@ from . import html_utils, is_linux, is_win, is_mac, issues_url, is_mac_arm64 from . import cellacdc_path, printl, temp_path, logs_path from . import config, models_list_file_path +from . import github_home_url def get_module_name(script_file_path): parts = pathlib.Path(script_file_path).parts @@ -1931,6 +1932,30 @@ def get_slices_local_into_global_arr(bbox_coords, global_shape): return tuple(slice_global_to_local), tuple(slice_crop_local) +def get_pip_install_cellacdc_version_command(version=None): + if version is None: + version = read_version() + is_dev_version = version.find('.dev') != -1 + if is_dev_version: + commit_hash = re.findall(r'\+g(.+)\.', version)[0] + command = f'pip install --upgrade "git+{github_home_url}.git@{commit_hash}"' + else: + command = f'pip install --upgrade cellacdc=={version}' + return command + +def get_git_pull_checkout_cellacdc_version_commands(version=None): + if version is None: + version = read_version() + is_dev_version = version.find('.dev') != -1 + if not is_dev_version: + return [] + commit_hash = re.findall(r'\+g(.+)\.', version)[0] + commands = ( + f'cd "{cellacdc_path}"', + 'git pull', + f'git checkout {commit_hash}' + ) + return commands if __name__ == '__main__': print(get_list_of_models()) diff --git a/cellacdc/widgets.py b/cellacdc/widgets.py index b7b459bb..fc99f3b5 100755 --- a/cellacdc/widgets.py +++ b/cellacdc/widgets.py @@ -441,14 +441,15 @@ def setDefaultText(self): self.setText(self._text) class showDetailsButton(PushButton): - def __init__(self, *args, txt='Show details...', **kwargs): - super().__init__(*args, **kwargs) - self.setText(txt) + def __init__(self, *args, txt='Show details...', parent=None): + super().__init__(txt, parent) + # self.setText(txt) self.txt = txt self.checkedIcon = QIcon(':hideUp.svg') self.uncheckedIcon = QIcon(':showDown.svg') self.setIcon(self.uncheckedIcon) self.toggled.connect(self.onClicked) + self.setCheckable(True) w = self.sizeHint().width() self.setFixedWidth(w)