fix some issues

This commit is contained in:
Louis Mazin 2025-11-07 11:26:14 +01:00
parent a9dfbee1a8
commit 2d89c95a23
6 changed files with 126 additions and 137 deletions

View File

@ -18,7 +18,7 @@ os_name = config.get("app_os", sys.platform)
app_name = config.get("app_name", "Application")
# --- Construct dynamic name ---
name = f"{app_name}-{os_name}-{arch}-v{version}"
name = f"{app_name}"
# --- Optional icon path ---
icon = getenv("ICON_PATH", "")

View File

@ -32,7 +32,7 @@ class DragDropFrame(QFrame):
urls = event.mimeData().urls()
if urls and self.parent_window:
file_path = urls[0].toLocalFile()
self.parent_window.set_dicom_from_files(file_path)
self.parent_window.find_dicoms_from_files(file_path)
def getDragIndicator(self) -> QLabel:
drag_indicator = QLabel(self)

View File

@ -128,6 +128,11 @@ class ExportWindow(QWidget):
# disable automatic stretch and fit col 1 to its contents
tree.header().setStretchLastSection(False)
tree.header().setSectionResizeMode(1, QHeaderView.ResizeMode.ResizeToContents)
# Install event filter to handle clicks on items
tree.viewport().installEventFilter(self)
self._current_tree = tree # Store reference for event filter
popup.layout().addWidget(tree)
for dicom, sub_dicoms in dicom_list:
@ -188,8 +193,9 @@ class ExportWindow(QWidget):
self.show_color_dialog(item, btn, cols))
tree.setItemWidget(child_item, 1, color_button)
# single connection to handle both directions
# Connect signals - itemChanged handles all checkbox state changes
tree.itemChanged.connect(self.on_item_changed)
tree.resizeColumnToContents(0) # Resize first column to fit content
tree.setColumnWidth(0, max(200, tree.columnWidth(0))) # Ensure minimum 200px for first column
tree.setColumnWidth(1, 20) # Exact width for button
@ -202,17 +208,54 @@ class ExportWindow(QWidget):
popup.layout().addWidget(confirm_button)
popup.exec()
# Clean up reference
self._current_tree = None
def toggle_child_items(self, item):
if item.childCount() > 0: # Check if the item has children
for i in range(item.childCount()):
child = item.child(i)
child.setCheckState(0, item.checkState(0)) # Set child state to match parent state
def eventFilter(self, source, event):
# Handle tree widget clicks
if hasattr(self, '_current_tree') and self._current_tree and source == self._current_tree.viewport():
if event.type() == QEvent.Type.MouseButtonPress and event.button() == Qt.MouseButton.LeftButton:
pos = event.pos()
item = self._current_tree.itemAt(pos)
if item:
# Get the column that was clicked
column = self._current_tree.header().logicalIndexAt(pos.x())
if column == 0: # Only on first column
# Get the visual rect for the item
visual_rect = self._current_tree.visualItemRect(item)
# Calculate the indentation and branch indicator area
# The branch indicator (arrow) is typically in the first ~20 pixels
indent = self._current_tree.indentation()
item_depth = 0
parent = item.parent()
while parent:
item_depth += 1
parent = parent.parent()
# Calculate where the branch indicator starts
branch_start = item_depth * indent
branch_end = branch_start + indent
# If click is NOT in the branch indicator area, toggle checkbox
if pos.x() < branch_start or pos.x() > branch_end:
current_state = item.checkState(0)
new_state = Qt.CheckState.Unchecked if current_state == Qt.CheckState.Checked else Qt.CheckState.Checked
item.setCheckState(0, new_state)
return True # Event handled
# Handle combobox wheel events
if isinstance(source, QComboBox) and event.type() == QEvent.Type.Wheel:
return True
return super().eventFilter(source, event)
def show_color_dialog(self, item, button, colors):
dialog = QDialog(self)
dialog.setWindowFlags(Qt.WindowType.Popup)
dialog.setFixedSize(200, 40) # Increased height for labels
dialog.setFixedSize(200, 20) # Reduced height since no labels
# Position dialog to the left of the button
button_pos = button.mapToGlobal(button.rect().topLeft())
@ -237,12 +280,6 @@ class ExportWindow(QWidget):
color_btn.setToolTip(ExportCategory.get_name(color))
color_btn.clicked.connect(lambda _, c=color: self.select_color(item, button, c, dialog))
layout.addWidget(color_btn, 0, i)
# Add label below button
label = QLabel(ExportCategory.get_name(color)[:3]) # First 3 letters
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
label.setStyleSheet("font-size: 8px; color: black;")
layout.addWidget(label, 1, i)
dialog.exec()
@ -338,8 +375,43 @@ class ExportWindow(QWidget):
self.alert_manager.show_error("export_error")
def eventFilter(self, source, event):
# Handle tree widget clicks
if hasattr(self, '_current_tree') and self._current_tree and source == self._current_tree.viewport():
if event.type() == QEvent.Type.MouseButtonPress and event.button() == Qt.MouseButton.LeftButton:
pos = event.pos()
item = self._current_tree.itemAt(pos)
if item:
# Get the column that was clicked
column = self._current_tree.header().logicalIndexAt(pos.x())
if column == 0: # Only on first column
# Get the visual rect for the item
visual_rect = self._current_tree.visualItemRect(item)
# Calculate the indentation and branch indicator area
# The branch indicator (arrow) is typically in the first ~20 pixels
indent = self._current_tree.indentation()
item_depth = 0
parent = item.parent()
while parent:
item_depth += 1
parent = parent.parent()
# Calculate where the branch indicator starts
branch_start = item_depth * indent
branch_end = branch_start + indent
# If click is NOT in the branch indicator area, toggle checkbox
if pos.x() < branch_start or pos.x() > branch_end:
current_state = item.checkState(0)
new_state = Qt.CheckState.Unchecked if current_state == Qt.CheckState.Checked else Qt.CheckState.Checked
item.setCheckState(0, new_state)
return True # Event handled
# Handle combobox wheel events
if isinstance(source, QComboBox) and event.type() == QEvent.Type.Wheel:
return True
return super().eventFilter(source, event)
def on_item_changed(self, item, column):

View File

@ -4,6 +4,7 @@ setlocal enabledelayedexpansion
REM === PATH SETUP ===
set PARENT_DIR=%~dp0..
set CONFIG_FILE=%PARENT_DIR%\config.json
set ICON_FILE=%PARENT_DIR%\data\assets\icon.png
set ENV_FILE=%PARENT_DIR%\.env
REM Check if .env file exists
@ -24,8 +25,10 @@ REM === Extract python path from .env file ===
for /f "usebackq tokens=2 delims==" %%i in (`findstr "PYTHON_PATH" "%ENV_FILE%"`) do set SYSTEM_PYTHON=%%i
set VENV_PATH=%PARENT_DIR%\WINenv_%ARCHITECTURE%
set EXE_NAME=%APP_NAME%-Windows-%ARCHITECTURE%
set EXE_NAME=%APP_NAME%.exe
set PYTHON_IN_VENV=%VENV_PATH%\Scripts\python.exe
set BUILD_DIR=%PARENT_DIR%\build
set ZIP_FILE=%BUILD_DIR%\%APP_NAME%.zip
REM === Verify Python existence ===
if not exist "%SYSTEM_PYTHON%" (
@ -45,12 +48,44 @@ if not exist "%VENV_PATH%\Scripts\activate.bat" (
REM === Run PyInstaller ===
"%PYTHON_IN_VENV%" -m PyInstaller ^
--distpath "%PARENT_DIR%\build" ^
--workpath "%PARENT_DIR%\build\dist" ^
--distpath "%BUILD_DIR%" ^
--workpath "%BUILD_DIR%\dist" ^
--clean ^
"%PARENT_DIR%\BUILD.spec"
REM === Clean build cache ===
rmdir /s /q "%PARENT_DIR%\build\dist"
rmdir /s /q "%BUILD_DIR%\dist"
REM === Create ZIP ===
echo [INFO] Creating ZIP archive...
set TEMP_ZIP_DIR=%BUILD_DIR%\temp_zip
REM Remove old temp dir if exists
if exist "%TEMP_ZIP_DIR%" rmdir /s /q "%TEMP_ZIP_DIR%"
mkdir "%TEMP_ZIP_DIR%"
REM Copy compiled app - tout le contenu du build sauf les ZIP existants
move /Y "%BUILD_DIR%\%EXE_NAME%" "%TEMP_ZIP_DIR%\"
REM Copy config.json
copy "%CONFIG_FILE%" "%TEMP_ZIP_DIR%\" /Y
REM Copy icon.png
copy "%ICON_FILE%" "%TEMP_ZIP_DIR%\" /Y
REM Copy data/lang
xcopy /E /I /Y "%PARENT_DIR%\data\lang" "%TEMP_ZIP_DIR%\lang"
REM Remove old ZIP if exists
if exist "%ZIP_FILE%" del "%ZIP_FILE%"
REM Create ZIP
powershell -NoProfile -Command "Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('%TEMP_ZIP_DIR%', '%ZIP_FILE%')"
REM Remove temp folder
rmdir /s /q "%TEMP_ZIP_DIR%"
echo [INFO] ZIP created at: %ZIP_FILE%
endlocal

View File

@ -1,59 +0,0 @@
#!/bin/bash
set -e
# === PATH SETUP ===
PARENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG_FILE="$PARENT_DIR/config.json"
ENV_FILE="$PARENT_DIR/.env"
# --- Check .env file ---
if [[ ! -f "$ENV_FILE" ]]; then
echo "[ERROR] .env file not found. Please copy .env.example to .env and configure it."
exit 1
fi
# --- Check jq availability ---
if ! command -v jq &>/dev/null; then
echo "[ERROR] 'jq' is required. Install it with: brew install jq"
exit 1
fi
# --- Extract values from config.json ---
ICON_PATH=$(jq -r '.icon_path' "$CONFIG_FILE")
APP_NAME=$(jq -r '.app_name' "$CONFIG_FILE")
ARCHITECTURE=$(jq -r '.architecture' "$CONFIG_FILE")
# --- Extract PYTHON_PATH from .env ---
SYSTEM_PYTHON=$(grep -E "^PYTHON_PATH=" "$ENV_FILE" | cut -d '=' -f2)
VENV_PATH="$PARENT_DIR/MACenv_$ARCHITECTURE"
EXE_NAME="${APP_NAME}-MacOS-${ARCHITECTURE}"
PYTHON_IN_VENV="$VENV_PATH/bin/python"
# --- Verify Python existence ---
if [[ ! -x "$SYSTEM_PYTHON" ]]; then
echo "[ERROR] Python not found at: $SYSTEM_PYTHON"
exit 1
fi
# --- Check if virtual environment exists ---
if [[ ! -f "$VENV_PATH/bin/activate" ]]; then
echo "[INFO] Virtual environment not found. Creating..."
"$SYSTEM_PYTHON" -m venv "$VENV_PATH"
"$PYTHON_IN_VENV" -m pip install --upgrade pip
"$PYTHON_IN_VENV" -m pip install -r "$PARENT_DIR/requirements.txt"
else
echo "[INFO] Virtual environment found."
fi
# --- Run PyInstaller ---
"$PYTHON_IN_VENV" -m PyInstaller \
--distpath "$PARENT_DIR/build" \
--workpath "$PARENT_DIR/build/dist" \
--clean \
"$PARENT_DIR/BUILD.spec"
# --- Clean build cache ---
rm -rf "$PARENT_DIR/build/dist"
echo "[INFO] Build complete: $EXE_NAME"

View File

@ -1,59 +0,0 @@
#!/bin/bash
set -e
# Root paths
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG_FILE="$ROOT_DIR/config.json"
REQUIREMENTS="$ROOT_DIR/requirements.txt"
ENV_FILE="$ROOT_DIR/.env"
# Check if .env exists
if [[ ! -f "$ENV_FILE" ]]; then
echo "[ERROR] .env file not found. Please copy .env.example to .env and configure it."
exit 1
fi
# Extract architecture from config.json (requires jq)
if ! command -v jq &>/dev/null; then
echo "[ERROR] 'jq' is required. Install it with: brew install jq"
exit 1
fi
ARCHITECTURE=$(jq -r '.architecture' "$CONFIG_FILE")
# Extract python path from .env
PYTHON_EXEC=$(grep -E "^PYTHON_PATH=" "$ENV_FILE" | cut -d '=' -f2)
# Construct venv path
ENV_NAME="MACenv_$ARCHITECTURE"
ENV_PATH="$ROOT_DIR/$ENV_NAME"
# Check python executable
if [[ ! -x "$PYTHON_EXEC" ]]; then
echo "[ERROR] Python not found at: $PYTHON_EXEC"
echo "Please check your .env or installation path."
exit 1
fi
# Show info
echo "[INFO] Configuration:"
echo " Python: $PYTHON_EXEC"
echo " Env: $ENV_NAME"
# Create virtual env if missing
if [[ ! -d "$ENV_PATH/bin" ]]; then
echo "[INFO] Virtual environment not found, creating..."
"$PYTHON_EXEC" -m venv "$ENV_PATH"
echo "[INFO] Installing dependencies..."
"$ENV_PATH/bin/python" -m pip install --upgrade pip
"$ENV_PATH/bin/pip" install -r "$REQUIREMENTS"
else
echo "[INFO] Virtual environment found."
fi
# Activate and launch VS Code
echo "[INFO] Launching VS Code..."
# shellcheck source=/dev/null
source "$ENV_PATH/bin/activate"
open -a "Visual Studio Code" "$ROOT_DIR"
exit 0