diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..16bd4e2
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,8 @@
+# Python Configuration
+PYTHON_PATH=C:/Path/To/Your/Python/python.exe
+
+# Email configuration for suggestion system
+EMAIL_ADDRESS=your_email@gmail.com
+EMAIL_PASSWORD=your_app_password
+EMAIL_SMTP_SERVER=smtp.gmail.com
+EMAIL_SMTP_PORT=587
diff --git a/README.md b/README.md
index e69de29..4ba575b 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,266 @@
+# Python PyQt6 Application Template
+
+A modern, feature-rich template for building desktop applications with PyQt6. This template provides a solid foundation with theming, internationalization, settings management, and a modular architecture.
+
+## Features
+
+- **Modern UI Framework**: Built with PyQt6 for cross-platform compatibility
+- **Theme System**: Dark and light themes with easy customization
+- **Internationalization**: Multi-language support (English and French included)
+- **Settings Management**: Persistent user preferences with QSettings
+- **Modular Architecture**: Clean separation of concerns with managers and observers
+- **Tabbed Interface**: Flexible tab widget system with customizable positioning
+- **Window State Management**: Remembers window size, position, and maximized state
+- **Email Integration**: Built-in suggestion/feedback system with secure email configuration
+- **Build Automation**: Automated building with PyInstaller
+- **Virtual Environment Management**: Automated environment setup
+
+## Project Structure
+
+```
+Template/
+├── app/
+│ ├── core/ # Core application managers
+│ │ ├── main_manager.py # Singleton manager coordinator
+│ │ ├── settings_manager.py # User settings and configuration
+│ │ ├── theme_manager.py # Theme and styling management
+│ │ ├── language_manager.py # Internationalization
+│ │ └── observer_manager.py # Event notification system
+│ ├── ui/
+│ │ ├── main_window.py # Main application window
+│ │ ├── widgets/ # Custom widgets
+│ │ │ └── tabs_widget.py # Customizable tab system
+│ │ └── windows/ # Application windows
+│ │ ├── settings_window.py
+│ │ └── suggestion_window.py
+│ └── utils/
+│ └── paths.py # Path utilities for resources
+├── data/
+│ ├── assets/ # Icons and images
+│ ├── lang/ # Language files (JSON)
+│ ├── themes/ # Theme configuration files
+│ └── others/ # Default settings
+├── tools/ # Build and development tools
+│ ├── build.bat/.sh/.command # Platform-specific build script
+│ └── open.bat/.sh/.command # Platform-specific development setup
+├── config.json # Application configuration
+├── requirements.txt # Python dependencies
+├── BUILD.spec # PyInstaller specification
+└── main.py # Application entry point
+```
+
+### Development Setup
+
+1. **Clone/Download** this template
+2. **Configure** your application in `config.json`:
+ ```json
+ {
+ "app_name": "YourAppName",
+ "python_version": "YourPythonVersion",
+ "app_os": "Windows or Linux or Mac",
+ "app_version": "YourAppVersion",
+ "architecture": "x64 or x32",
+ "icon_path": "data/assets/icon.ico",
+ "main_script": "main.py"
+ }
+ ```
+
+3. **Setup environment configuration**:
+ - Copy `.env.example` to `.env`
+ - Configure your Python path and email credentials:
+ ```env
+ # Python Configuration
+ PYTHON_PATH=C:/Path/To/Your/Python/python.exe
+
+ # Email Configuration (optional)
+ EMAIL_ADDRESS=your_email@gmail.com
+ EMAIL_PASSWORD=your_app_password
+ EMAIL_SMTP_SERVER=smtp.gmail.com
+ EMAIL_SMTP_PORT=587
+ ```
+ - For Gmail, use an [App Password](https://support.google.com/accounts/answer/185833) instead of your regular password
+
+4. **Run development environment**:
+ - **Windows**: `tools\open.bat`
+ - **Linux**: `tools/open.sh`
+ - **macOS**: `tools/open.command`
+
+ This will:
+ - Create a virtual environment
+ - Install dependencies
+ - Open VS Code with proper environment
+
+### Building for Production
+
+- **Windows**: `tools\build.bat`
+- **Linux**: `tools/build.sh`
+- **macOS**: `tools/build.command`
+
+This creates a standalone executable in the `build/` directory.
+
+### Adding Themes
+
+Create JSON files in `data/themes/`. **Important**: Use the predefined color names as they are used throughout the application's styling system.
+
+```json
+{
+ "theme_name": "custom",
+ "colors": {
+ "background": "#FFFFFF", // Main background color
+ "background2": "#F5F5F5", // Secondary background
+ "background3": "#E0E0E0", // Tertiary background
+ "font_color": "#000000", // Text color
+ "selected_icon": "#000000", // Selected icon color
+ "unselected_icon": "#5D5A5A", // Unselected icon color
+ "selected_border_icon": "#000000", // Selected border color
+ "hover_icon": "#000000" // Hover state color
+ }
+}
+```
+
+**Warning**: Do not change the color property names (`background`, `background2`, etc.) as they are hardcoded in the theme system. Only modify the hex color values.
+
+### Adding Languages
+
+Create JSON files in `data/lang/`. **Important**: Use the existing translation keys to ensure proper functionality.
+
+```json
+{
+ "lang_name": "Español",
+ "yes": "Sí",
+ "no": "No",
+ "language": "Idioma:",
+ "settings": "Configuración",
+ "theme": "Tema:",
+ "dark_theme": "Tema Oscuro",
+ "light_theme": "Tema Claro",
+ "suggestion_text": "¿Tienes una pregunta o idea para mejorar esta aplicación?",
+ "suggestion_placeholder": "Escribe tu mensaje aquí...",
+ "send_suggestion": "Enviar",
+ "sending": "Enviando...",
+ "success": "Éxito",
+ "error": "Error",
+ "suggestion_sent_success": "¡Tu mensaje ha sido enviado exitosamente!",
+ "suggestion_send_error": "Error al enviar el mensaje. Inténtalo de nuevo más tarde.",
+ "email_credentials_error": "Credenciales de email no configuradas. Por favor configura tu email y contraseña en el archivo .env."
+}
+```
+
+**Warning**: Do not change the translation keys (left side of the colon) as they are used throughout the application code. Only translate the values (right side).
+
+## Architecture
+
+### Manager Pattern
+
+The application uses a centralized manager system:
+
+- **MainManager**: Singleton coordinator for all managers
+- **SettingsManager**: Handles user preferences and persistence
+- **ThemeManager**: Manages themes and styling
+- **LanguageManager**: Handles internationalization
+- **ObserverManager**: Event notification system
+
+### Observer Pattern
+
+Components can subscribe to events:
+
+```python
+self.observer_manager.subscribe(NotificationType.THEME, self.update_theme)
+self.observer_manager.subscribe(NotificationType.LANGUAGE, self.update_language)
+```
+
+### Tab System
+
+The flexible tab widget supports multiple positioning options:
+
+```python
+# Add a tab with custom positioning
+self.side_menu.add_widget(
+ widget=your_widget,
+ button_text="",
+ icon_path=paths.get_asset_svg_path("icon_name"),
+ position=ButtonPosition.CENTER
+)
+```
+
+## Email Integration
+
+The template includes a suggestion system with email capabilities. Configure in your `.env` file:
+
+**Security Note**: Never commit your `.env` file to version control. It's already included in `.gitignore`.
+
+For Gmail users:
+- Enable 2-factor authentication
+- Generate an App Password specifically for this application
+- Use the App Password in the `EMAIL_PASSWORD` field
+
+## Customization
+
+### Adding New Windows
+
+1. Create window class inheriting from `QWidget`
+2. Subscribe to language notifications
+3. Add to main window tab system
+
+```python
+class YourWindow(QWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.main_manager = MainManager.get_instance()
+ # Subscribe to notifications
+ self.observer_manager.subscribe(NotificationType.LANGUAGE, self.update_language)
+ self.setup_ui()
+```
+
+### Custom Widgets
+
+Place custom widgets in `app/ui/widgets/` and follow the existing patterns for theme integration.
+
+## Dependencies
+
+- **PyQt6**: Modern GUI framework
+- **pyinstaller**: Executable building
+- **python-dotenv**: Environment variable management
+
+Add additional dependencies to `requirements.txt`.
+
+## Building
+
+The build system automatically:
+- Creates virtual environments per architecture
+- Installs dependencies
+- Builds with PyInstaller
+- Names executables with config.json
+- Includes all assets and data files
+
+## Cross-Platform Notes
+
+The template supports multiple platforms with platform-specific scripts:
+- **Windows**: Uses `.bat` files
+- **Linux**: Uses `.sh` files
+- **macOS**: Uses `.command` files
+
+Adjust config.json for your target platform.
+
+## License
+
+MIT License - see LICENSE file for details.
+
+## Contributing
+
+1. Fork the repository
+2. Create a feature branch
+3. Make your changes
+4. Test thoroughly
+5. Submit a pull request
+
+## Support
+
+For issues or questions:
+- Check existing issues
+- Create detailed bug reports
+- Include system information and error logs
+
+---
+
+**Happy coding!** 🚀
\ No newline at end of file
diff --git a/app/ui/windows/suggestion_window.py b/app/ui/windows/suggestion_window.py
index 69c12c0..fc8d7dc 100644
--- a/app/ui/windows/suggestion_window.py
+++ b/app/ui/windows/suggestion_window.py
@@ -5,8 +5,12 @@ import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
+from dotenv import load_dotenv
from app.core.main_manager import MainManager, NotificationType
+# Load environment variables from .env file
+load_dotenv()
+
class EmailSender(QThread):
success = pyqtSignal()
error = pyqtSignal(str)
@@ -19,14 +23,13 @@ class EmailSender(QThread):
def run(self):
try:
# Get email configuration from environment variables
- password = 'xprqegxuqixgljyi'
- email = 'louismazindev@gmail.com'
- smtp_server = 'smtp.gmail.com'
- smtp_port = 587
+ email = os.getenv('EMAIL_ADDRESS')
+ password = os.getenv('EMAIL_PASSWORD')
+ smtp_server = os.getenv('EMAIL_SMTP_SERVER', 'smtp.gmail.com')
+ smtp_port = int(os.getenv('EMAIL_SMTP_PORT', '587'))
- if not password:
- # Fallback to simulation if no credentials are configured
- self._simulate_email_sending()
+ if not email or not password:
+ self.error.emit("password")
return
# Create message
@@ -49,19 +52,8 @@ class EmailSender(QThread):
server.quit()
self.success.emit()
- except Exception as e:
- self.error.emit()
-
- def _simulate_email_sending(self):
- """Fallback simulation when no email credentials are configured"""
- time.sleep(2) # Simulate network delay
-
- print("=== EMAIL SIMULATION (No credentials configured) ===")
- print(f"Subject: {self.subject}")
- print(f"Message: {self.message}")
- print("=" * 55)
-
- self.success.emit()
+ except Exception:
+ self.error.emit("")
class SuggestionWindow(QWidget):
def __init__(self, parent=None):
@@ -132,13 +124,16 @@ class SuggestionWindow(QWidget):
self.language_manager.get_text("suggestion_sent_success"))
self.text_edit.clear()
- def on_email_error(self):
+ def on_email_error(self, error):
self.send_button.setEnabled(True)
self.send_button.setText(self.language_manager.get_text("send_suggestion"))
-
+ if error == "password":
+ message = self.language_manager.get_text("email_credentials_error")
+ else:
+ message = self.language_manager.get_text("suggestion_send_error")
QMessageBox.critical(self,
- self.language_manager.get_text("error"),
- f"{self.language_manager.get_text('suggestion_send_error')}")
+ self.language_manager.get_text("error"),
+ message)
def update_language(self):
self.title_label.setText(self.language_manager.get_text("suggestion_text"))
diff --git a/config.json b/config.json
index 2462d61..c365fe7 100644
--- a/config.json
+++ b/config.json
@@ -5,6 +5,5 @@
"app_version": "1.0.0",
"architecture": "x64",
"icon_path": "data/assets/icon.ico",
- "main_script": "main.py",
- "python_path": "C:/Logiciels/Python/x64/3.11.7/python.exe"
+ "main_script": "main.py"
}
\ No newline at end of file
diff --git a/data/assets/settings.svg b/data/assets/settings.svg
index 3bfe869..c67bfb2 100644
--- a/data/assets/settings.svg
+++ b/data/assets/settings.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/data/assets/suggestion.svg b/data/assets/suggestion.svg
index 6634fc4..f383c8a 100644
--- a/data/assets/suggestion.svg
+++ b/data/assets/suggestion.svg
@@ -1,8 +1,8 @@
-
+
-
+
diff --git a/data/lang/en.json b/data/lang/en.json
index 48dce8e..1f76faa 100644
--- a/data/lang/en.json
+++ b/data/lang/en.json
@@ -14,5 +14,6 @@
"success": "Success",
"error": "Error",
"suggestion_sent_success": "Your message has been sent successfully!",
- "suggestion_send_error": "Error sending message. Try again later."
+ "suggestion_send_error": "Error sending message. Try again later.",
+ "email_credentials_error": "Email credentials not configured. Please set your email and password in the .env file."
}
\ No newline at end of file
diff --git a/data/lang/fr.json b/data/lang/fr.json
index 7897f6c..8677160 100644
--- a/data/lang/fr.json
+++ b/data/lang/fr.json
@@ -14,5 +14,6 @@
"success": "Succès",
"error": "Erreur",
"suggestion_sent_success": "Votre message a été envoyé avec succès !",
- "suggestion_send_error": "Erreur lors de l'envoi du message. Essayez à nouveau plus tard."
+ "suggestion_send_error": "Erreur lors de l'envoi du message. Essayez à nouveau plus tard.",
+ "email_credentials_error": "Identifiants de messagerie non configurés. Veuillez définir votre email et mot de passe dans le fichier .env."
}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 69352a3..2fc62e6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
PyQt6
-pyinstaller
\ No newline at end of file
+pyinstaller
+python-dotenv
\ No newline at end of file
diff --git a/tools/build.bat b/tools/build.bat
index 49fb6b0..8e53c7b 100644
--- a/tools/build.bat
+++ b/tools/build.bat
@@ -4,6 +4,13 @@ setlocal enabledelayedexpansion
REM === PATH SETUP ===
set PARENT_DIR=%~dp0..
set CONFIG_FILE=%PARENT_DIR%\config.json
+set ENV_FILE=%PARENT_DIR%\.env
+
+REM Check if .env file exists
+if not exist "%ENV_FILE%" (
+ echo [ERROR] .env file not found. Please copy .env.example to .env and configure it.
+ exit /b 1
+)
REM === Extract values from config.json ===
for /f "delims=" %%i in ('powershell -NoProfile -Command ^
@@ -14,8 +21,9 @@ for /f "delims=" %%i in ('powershell -NoProfile -Command ^
"Get-Content '%CONFIG_FILE%' | ConvertFrom-Json | Select-Object -ExpandProperty app_name"') do set APP_NAME=%%i
for /f "delims=" %%i in ('powershell -NoProfile -Command ^
"Get-Content '%CONFIG_FILE%' | ConvertFrom-Json | Select-Object -ExpandProperty architecture"') do set ARCHITECTURE=%%i
-for /f "delims=" %%i in ('powershell -NoProfile -Command ^
- "Get-Content '%CONFIG_FILE%' | ConvertFrom-Json | Select-Object -ExpandProperty python_path"') do set SYSTEM_PYTHON=%%i
+
+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%
diff --git a/tools/open.bat b/tools/open.bat
index dd52d62..0878c5c 100644
--- a/tools/open.bat
+++ b/tools/open.bat
@@ -5,6 +5,13 @@ REM Set file paths
set ROOT_DIR=%~dp0..
set CONFIG_FILE=%ROOT_DIR%\config.json
set REQUIREMENTS=%ROOT_DIR%\requirements.txt
+set ENV_FILE=%ROOT_DIR%\.env
+
+REM Check if .env file exists
+if not exist "%ENV_FILE%" (
+ echo [ERROR] .env file not found. Please copy .env.example to .env and configure it.
+ exit /b 1
+)
REM Extract config.json fields using PowerShell
for /f "delims=" %%i in ('powershell -NoProfile -Command ^
@@ -12,9 +19,9 @@ for /f "delims=" %%i in ('powershell -NoProfile -Command ^
for /f "delims=" %%i in ('powershell -NoProfile -Command ^
"Get-Content '%CONFIG_FILE%' | ConvertFrom-Json | Select-Object -ExpandProperty architecture"') do set ARCHITECTURE=%%i
-
-for /f "delims=" %%i in ('powershell -NoProfile -Command ^
- "Get-Content '%CONFIG_FILE%' | ConvertFrom-Json | Select-Object -ExpandProperty python_path"') do set PYTHON_EXEC=%%i
+
+REM Extract python path from .env file
+for /f "usebackq tokens=2 delims==" %%i in (`findstr "PYTHON_PATH" "%ENV_FILE%"`) do set PYTHON_EXEC=%%i
REM Construct python executable path
set ENV_NAME=WINenv_%ARCHITECTURE%
@@ -22,7 +29,7 @@ set ENV_PATH=%ROOT_DIR%\%ENV_NAME%
if not exist "%PYTHON_EXEC%" (
echo [ERROR] Python introuvable à: %PYTHON_EXEC%
- echo Veuillez vérifier votre config.json ou le dossier d'installation.
+ echo Veuillez vérifier votre .env ou le dossier d'installation.
exit /b 1
)