-
-
Notifications
You must be signed in to change notification settings - Fork 0
Settings And Configuration
CppLab IDE provides user-configurable settings for customizing appearance, build behavior, and development preferences.
User Settings File:
Windows: C:\Users\<Username>\.cpplab\settings.json
Linux: ~/.cpplab/settings.json
macOS: ~/.cpplab/settings.json
Format: JSON
Example:
{
"theme": "classic",
"font_size": 10,
"bold_font": false,
"auto_save": true,
"show_line_numbers": true,
"tab_width": 4,
"default_standard_c": "c17",
"default_standard_cpp": "c++17",
"default_toolchain": "mingw64",
"build_before_run": true,
"show_build_time": true
}When Settings Are Saved:
- On settings dialog "OK" button
- On application exit (window position/size)
- On theme change
- On font change
When Settings Are Loaded:
- On application startup
- On settings dialog open
- After settings change
Method 1: Menu
Tools → Settings... (Alt+S)
Method 2: Toolbar
Click ⚙ (Settings) icon
Method 3: Keyboard
Ctrl+Comma
┌─────────────────────────────────────────┐
│ Settings [X] │
├─────────────────────────────────────────┤
│ ┌─────────────────────────────────────┐ │
│ │ [Appearance] [Build] [Editor] [Advanced] │
│ └─────────────────────────────────────┘ │
│ │
│ Theme: [Classic ▼] │
│ Font Size: [10 ▼] │
│ ☑ Bold Font │
│ ☑ Show Line Numbers │
│ │
│ [OK] [Cancel] [Apply] │
└─────────────────────────────────────────┘
Theme:
Options: Classic, Sky Blue, Dark (future)
Default: Classic
Description: Overall color scheme
Font Settings:
Font Size: 8, 9, 10, 11, 12, 14, 16, 18, 20
Default: 10
Description: Size of text in editor and output panels
Font Family: Consolas (fixed)
Description: Monospace font for code
Bold Font: Checkbox
Default: Unchecked
Description: Make all text bold
UI Scale (future):
Options: 100%, 125%, 150%, 200%
Default: 100%
Description: Scale entire UI
Default Standards:
C Standard: C99, C11, C17, C18, C23
Default: C17
Description: Default for new C projects
C++ Standard: C++11, C++14, C++17, C++20, C++23
Default: C++17
Description: Default for new C++ projects
Default Toolchain:
Options: mingw32, mingw64
Default: mingw64
Description: Toolchain for new projects
Build Behavior:
☑ Build Before Run
Default: Checked
Description: Automatically build before running
☑ Show Build Time
Default: Checked
Description: Display elapsed time in status bar
☑ Save All Before Build
Default: Checked
Description: Save all open files before building
☐ Verbose Build Output
Default: Unchecked
Description: Show detailed compiler output
Optimization Level:
Options: -O0 (None), -O1 (Basic), -O2 (Moderate), -O3 (Aggressive)
Default: -O0
Description: Compiler optimization level
Indentation:
Tab Width: 2, 4, 8
Default: 4
Description: Number of spaces per tab
☐ Use Spaces Instead of Tabs
Default: Unchecked
Description: Insert spaces when Tab key pressed
Display:
☑ Show Line Numbers
Default: Checked
Description: Show line numbers in gutter
☐ Show Whitespace
Default: Unchecked
Description: Show spaces and tabs
☑ Highlight Current Line
Default: Checked
Description: Highlight line with cursor
Behavior:
☑ Auto-Indent
Default: Checked
Description: Auto-indent on newline
☑ Auto-Complete Brackets
Default: Checked
Description: Auto-close {}, [], (), ""
☑ Word Wrap
Default: Unchecked
Description: Wrap long lines
Paths:
Toolchain Directory: [Browse...]
Default: compilers/ (relative to exe)
Description: Location of MinGW toolchains
Project Templates Dir: [Browse...]
Default: templates/ (relative to exe)
Description: Custom project templates
Performance:
Max Undo History: 100, 500, 1000, Unlimited
Default: 1000
Description: Number of undo steps
Max File Size: 1 MB, 5 MB, 10 MB, 50 MB
Default: 10 MB
Description: Max file size to open
Debugging:
☐ Enable Debug Logging
Default: Unchecked
Description: Write logs to cpplab.log
☐ Show Internal Errors
Default: Unchecked
Description: Show Python tracebacks
File: src/cpplab/settings.py
from dataclasses import dataclass, asdict
from pathlib import Path
import json
@dataclass
class AppSettings:
"""Application settings."""
# Appearance
theme: str = "classic"
font_size: int = 10
bold_font: bool = False
# Build
default_standard_c: str = "c17"
default_standard_cpp: str = "c++17"
default_toolchain: str = "mingw64"
build_before_run: bool = True
show_build_time: bool = True
optimization_level: str = "-O0"
# Editor
tab_width: int = 4
use_spaces: bool = False
show_line_numbers: bool = True
auto_indent: bool = True
# Advanced
max_undo_history: int = 1000
max_file_size_mb: int = 10
debug_logging: bool = False
def get_settings_path() -> Path:
"""Get path to settings file."""
settings_dir = Path.home() / ".cpplab"
settings_dir.mkdir(exist_ok=True)
return settings_dir / "settings.json"
def load_settings() -> AppSettings:
"""Load settings from JSON file."""
settings_path = get_settings_path()
if not settings_path.exists():
# Return defaults
return AppSettings()
try:
with open(settings_path, 'r', encoding='utf-8') as f:
data = json.load(f)
return AppSettings(**data)
except Exception as e:
print(f"Error loading settings: {e}")
return AppSettings()
def save_settings(settings: AppSettings):
"""Save settings to JSON file."""
settings_path = get_settings_path()
try:
with open(settings_path, 'w', encoding='utf-8') as f:
json.dump(asdict(settings), f, indent=2)
except Exception as e:
print(f"Error saving settings: {e}")File: src/cpplab/settings_dialog.py
from PyQt6.QtWidgets import (
QDialog, QTabWidget, QVBoxLayout, QHBoxLayout,
QLabel, QComboBox, QCheckBox, QPushButton,
QGroupBox, QSpinBox
)
from PyQt6.QtCore import Qt
class SettingsDialog(QDialog):
"""Settings dialog with tabbed interface."""
def __init__(self, current_settings: AppSettings, parent=None):
super().__init__(parent)
self.settings = current_settings
self.setWindowTitle("Settings")
self.resize(500, 400)
# Create layout
layout = QVBoxLayout()
# Create tabs
tabs = QTabWidget()
tabs.addTab(self._create_appearance_tab(), "Appearance")
tabs.addTab(self._create_build_tab(), "Build")
tabs.addTab(self._create_editor_tab(), "Editor")
layout.addWidget(tabs)
# Buttons
button_layout = QHBoxLayout()
button_layout.addStretch()
ok_button = QPushButton("OK")
ok_button.clicked.connect(self.accept)
cancel_button = QPushButton("Cancel")
cancel_button.clicked.connect(self.reject)
apply_button = QPushButton("Apply")
apply_button.clicked.connect(self.apply_settings)
button_layout.addWidget(ok_button)
button_layout.addWidget(cancel_button)
button_layout.addWidget(apply_button)
layout.addLayout(button_layout)
self.setLayout(layout)
def _create_appearance_tab(self):
"""Create appearance settings tab."""
widget = QWidget()
layout = QVBoxLayout()
# Theme
theme_group = QGroupBox("Theme")
theme_layout = QVBoxLayout()
self.theme_combo = QComboBox()
self.theme_combo.addItems(["classic", "sky_blue"])
self.theme_combo.setCurrentText(self.settings.theme)
theme_layout.addWidget(QLabel("Theme:"))
theme_layout.addWidget(self.theme_combo)
theme_group.setLayout(theme_layout)
# Font
font_group = QGroupBox("Font")
font_layout = QVBoxLayout()
self.font_size_spin = QSpinBox()
self.font_size_spin.setRange(8, 20)
self.font_size_spin.setValue(self.settings.font_size)
self.bold_check = QCheckBox("Bold Font")
self.bold_check.setChecked(self.settings.bold_font)
font_layout.addWidget(QLabel("Font Size:"))
font_layout.addWidget(self.font_size_spin)
font_layout.addWidget(self.bold_check)
font_group.setLayout(font_layout)
layout.addWidget(theme_group)
layout.addWidget(font_group)
layout.addStretch()
widget.setLayout(layout)
return widget
def _create_build_tab(self):
"""Create build settings tab."""
# Similar structure...
pass
def apply_settings(self):
"""Apply current settings."""
# Update settings object
self.settings.theme = self.theme_combo.currentText()
self.settings.font_size = self.font_size_spin.value()
self.settings.bold_font = self.bold_check.isChecked()
# Save to disk
save_settings(self.settings)
# Emit signal or call parent method
if self.parent():
self.parent().apply_settings()
def get_settings(self) -> AppSettings:
"""Get modified settings."""
return self.settingsFile: src/cpplab/app.py
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# Load settings on startup
self.settings = load_settings()
self.apply_settings()
def apply_settings(self):
"""Apply current settings to UI."""
# Theme
if self.settings.theme in THEMES:
self.setStyleSheet(THEMES[self.settings.theme])
# Font
font = QFont("Consolas", self.settings.font_size)
if self.settings.bold_font:
font.setBold(True)
self.editor.setFont(font)
self.buildOutputEdit.setFont(font)
self.problemsTextEdit.setFont(font)
self.consoleTextEdit.setFont(font)
# Editor settings
tab_width = self.settings.tab_width * 10 # Pixels
self.editor.setTabStopDistance(tab_width)
# Show/hide line numbers
if self.settings.show_line_numbers:
# Enable line numbers
pass
def show_settings_dialog(self):
"""Show settings dialog."""
dialog = SettingsDialog(self.settings, self)
if dialog.exec() == QDialog.DialogCode.Accepted:
# Get updated settings
self.settings = dialog.get_settings()
save_settings(self.settings)
# Apply changes
self.apply_settings()Classic Theme:
THEMES = {
"classic": """
QMainWindow {
background-color: #f0f0f0;
}
QMenuBar {
background-color: #ffffff;
border-bottom: 1px solid #c0c0c0;
}
QTextEdit {
background-color: #ffffff;
color: #000000;
border: 1px solid #c0c0c0;
}
QPushButton {
background-color: #e1e1e1;
color: #000000;
border: 1px solid #adadad;
padding: 5px 10px;
border-radius: 3px;
}
QPushButton:hover {
background-color: #d0d0d0;
}
QStatusBar {
background-color: #007acc;
color: #ffffff;
}
"""
}Sky Blue Theme:
THEMES["sky_blue"] = """
QMainWindow {
background-color: #e6f2ff;
}
QMenuBar {
background-color: #cce0ff;
border-bottom: 1px solid #99c2ff;
}
QTextEdit {
background-color: #f0f8ff;
color: #003366;
border: 1px solid #99c2ff;
}
QPushButton {
background-color: #4a90d9;
color: #ffffff;
border: none;
padding: 5px 10px;
border-radius: 3px;
}
QPushButton:hover {
background-color: #5fa3e8;
}
QStatusBar {
background-color: #2a5a8a;
color: #ffffff;
}
"""User-Defined Themes:
{
"theme": "custom",
"custom_theme_path": "C:/Users/User/.cpplab/themes/my_theme.qss"
}Theme File (my_theme.qss):
QMainWindow {
background-color: #282c34;
}
QTextEdit {
background-color: #1e2127;
color: #abb2bf;
}Project Settings File:
<project_root>/cpplab_project.json
Example:
{
"name": "MyApp",
"language": "cpp",
"standard": "c++17",
"project_type": "console",
"toolchain": "mingw64",
"compile_flags": ["-Wall", "-Wextra"],
"link_flags": [],
"sources": ["src/main.cpp"]
}User Settings (global):
- Theme
- Font
- Default toolchain
- Default standards
- Editor preferences
Project Settings (per-project):
- Project name
- Language
- Standard (override user default)
- Toolchain (override user default)
- Compile/link flags
- Source files
Priority: Project settings override user settings
Settings → Advanced → [Reset to Defaults] button
Windows:
del C:\Users\<Username>\.cpplab\settings.jsonLinux/macOS:
rm ~/.cpplab/settings.jsonOn Next Launch: Default settings used
# Reset to defaults
settings = AppSettings()
save_settings(settings)Future-Proofing:
{
"version": 1,
"theme": "classic",
...
}def load_settings() -> AppSettings:
"""Load settings with version migration."""
settings_path = get_settings_path()
if not settings_path.exists():
return AppSettings()
with open(settings_path, 'r') as f:
data = json.load(f)
# Check version
version = data.get("version", 0)
if version == 0:
# Migrate from v0 to v1
data = migrate_v0_to_v1(data)
return AppSettings(**data)Next: Performance and Benchmarks
Previous: UI Framework and PyQt6
💡 Found this wiki useful?
⭐ Star the repo
·
💖 Sponsor this project
·
📦 Latest release
·
🐞 Report an issue