Skip to content

Commit 115bb19

Browse files
authored
Merge pull request #44 from jessielw/v2-stable
V2 stable
2 parents 5a32bfe + 2b0e716 commit 115bb19

File tree

8 files changed

+106
-15
lines changed

8 files changed

+106
-15
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.0.0] - 2025-12-18
9+
10+
### Added
11+
12+
- Settings panel is now split into tabs
13+
- General tab is the same as settings was previously
14+
- Added about tab with some misc information about the program
15+
16+
### Changed
17+
18+
- Now shows version on title bar
19+
20+
### Fixed
21+
22+
- Don't attempt to add job to queue with no output path
23+
824
## [2.0.0-rc4] - 2025-12-16
925

1026
### Added

core/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
program_name = "Mp4Forge"
44
program_url = "https://github.com/jessielw/MP4-Mux-Tool"
5-
__version__ = VersionInfo.parse("2.0.0-dev")
5+
__version__ = VersionInfo.parse("2.0.0")

core/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from dotenv import load_dotenv
77
from tomlkit.toml_document import TOMLDocument
88

9+
from core.__version__ import __version__
910
from core.logger import LogLevel
1011
from core.utils.working_dir import CONFIG_DIR
1112

@@ -23,6 +24,9 @@ def __init__(self, config_path: Path | None = None) -> None:
2324
self.config_path.parent.mkdir(parents=True, exist_ok=True)
2425
self._config: TOMLDocument = self._load()
2526

27+
# instance variables for easy access
28+
self.version = str(__version__)
29+
2630
def _load(self) -> TOMLDocument:
2731
"""Load configuration from file or create default"""
2832
if self.config_path.exists():

frontend_desktop/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
class MainWindow(QMainWindow):
3838
def __init__(self):
3939
super().__init__()
40-
self.setWindowTitle("Mp4Forge")
40+
self.setWindowTitle(f"Mp4Forge {Conf.version}")
4141

4242
# initialize exception handling
4343
self._setup_exception_hooks()

frontend_desktop/navigation/tabs/output.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,16 @@ def _browse_output_file(self) -> None:
268268
@Slot()
269269
def _add_current_job(self) -> None:
270270
"""Add current tab states to queue as a new job"""
271+
# if nothing in output tab simply return
272+
out_path = self.output_entry.toPlainText().strip()
273+
if not out_path:
274+
GSigs().main_window_update_status_tip.emit(
275+
"Please select an output file", 3000
276+
)
277+
return
278+
271279
# check if output path exists and ask to overwrite if needed
272-
output_path = Path(self.output_entry.toPlainText().strip())
280+
output_path = Path(out_path)
273281
if output_path.exists():
274282
if (
275283
QMessageBox.question(

frontend_desktop/navigation/tabs/settings.py

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
QLineEdit,
1111
QPushButton,
1212
QScrollArea,
13+
QTabWidget,
1314
QToolButton,
1415
QVBoxLayout,
1516
QWidget,
@@ -25,14 +26,15 @@
2526
from frontend_desktop.widgets.utils import build_h_line
2627

2728

28-
class SettingsTab(QWidget):
29+
class GeneralSettingsTab(QWidget):
30+
"""General settings tab with scrollable content."""
31+
2932
def __init__(self, parent=None) -> None:
3033
super().__init__(parent)
3134

3235
# create scroll area
3336
scroll_area = QScrollArea(self, widgetResizable=True)
34-
scroll_area.setFrameShape(QFrame.Shape.Box)
35-
scroll_area.setFrameShadow(QFrame.Shadow.Sunken)
37+
scroll_area.setFrameShape(QFrame.Shape.NoFrame)
3638

3739
# create content widget
3840
content_widget = QWidget()
@@ -134,15 +136,12 @@ def __init__(self, parent=None) -> None:
134136
self.save_btn = QPushButton("Save Settings", self)
135137
self.save_btn.clicked.connect(self._save_settings)
136138

137-
save_layout = QHBoxLayout()
138-
save_layout.addStretch()
139-
save_layout.addWidget(self.save_btn)
140-
141139
# main layout
142140
self.main_layout = QVBoxLayout(self)
143141
self.main_layout.setContentsMargins(0, 0, 0, 0)
144142
self.main_layout.addWidget(scroll_area)
145-
self.main_layout.addLayout(save_layout)
143+
self.main_layout.addWidget(self.save_btn, alignment=Qt.AlignmentFlag.AlignRight)
144+
self.main_layout.addSpacing(6)
146145

147146
@Slot(int)
148147
def _change_theme(self, _: int | None = None) -> None:
@@ -201,3 +200,67 @@ def _reload_preset_editors(self) -> None:
201200
self.audio_titles_editor.set_titles(Conf.audio_preset_titles)
202201
self.subtitle_titles_editor.set_titles(Conf.subtitle_preset_titles)
203202
GSigs().main_window_update_status_tip.emit("Settings saved successfully", 2000)
203+
204+
205+
class AboutTab(QWidget):
206+
"""About tab with scrollable content."""
207+
208+
def __init__(self, parent=None) -> None:
209+
super().__init__(parent)
210+
211+
# create scroll area
212+
scroll_area = QScrollArea(self, widgetResizable=True)
213+
scroll_area.setFrameShape(QFrame.Shape.NoFrame)
214+
215+
# create content widget
216+
content_widget = QWidget()
217+
218+
####### UI elements #######
219+
app_info_lbl = QLabel(
220+
f"""<h2 style="text-align: center;">Mp4Forge</h2>
221+
<span style="font-weight: bold;">Version:</span> {Conf.version}<br>
222+
<span style="font-weight: bold;">Homepage:</span><a href="https://github.com/jessielw/MP4Forge">
223+
https://github.com/jessielw/MP4Forge</a><br>
224+
<span style="font-weight: bold;">Help:</span> <a href="https://github.com/jessielw/MP4Forge/issues">
225+
https://github.com/jessielw/MP4Forge/issues</a>""",
226+
content_widget,
227+
wordWrap=True,
228+
openExternalLinks=True,
229+
)
230+
####### UI elements #######
231+
232+
# content layout
233+
content_layout = QVBoxLayout(content_widget)
234+
content_layout.addWidget(app_info_lbl)
235+
content_layout.addStretch()
236+
237+
# set content widget in scroll area
238+
scroll_area.setWidget(content_widget)
239+
240+
# main layout
241+
self.main_layout = QVBoxLayout(self)
242+
self.main_layout.setContentsMargins(0, 0, 0, 0)
243+
self.main_layout.addWidget(scroll_area)
244+
245+
246+
class SettingsTab(QWidget):
247+
"""Main settings tab with notebook interface."""
248+
249+
def __init__(self, parent=None) -> None:
250+
super().__init__(parent)
251+
252+
# create tab widget
253+
self.tab_widget = QTabWidget(self)
254+
255+
# create tabs
256+
self.general_settings_tab = GeneralSettingsTab(self)
257+
self.about_tab = AboutTab(self)
258+
259+
# add tabs to widget
260+
self.tab_widget.addTab(self.general_settings_tab, "General")
261+
self.tab_widget.addTab(self.about_tab, "About")
262+
263+
# main layout
264+
self.main_layout = QVBoxLayout(self)
265+
self.main_layout.setContentsMargins(0, 0, 0, 0)
266+
self.main_layout.addWidget(self.tab_widget)

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
2-
name = "mp4-forge"
3-
version = "2.0.0-rc4"
2+
name = "mp4forge"
3+
version = "2.0.0"
44
description = "MP4 muxing tool with desktop and web interfaces"
55
requires-python = ">=3.11,<3.14"
66

uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)