Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds drag-and-drop .wpress handling and OS-level “open with” integration, and introduces a command-line extraction path intended for headless use.
Changes:
- Adds a
DropOverlaywidget and updates the main window UI/logic for drag-drop selection, clearing, and status display. - Adds a CLI extraction mode via
QCommandLineParser, with progress/error output and optional password support. - Improves platform integration/metadata for
.wpressfile association (macOS Info.plist + Windows resources/installer script changes).
Reviewed changes
Copilot reviewed 14 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| win32.rc | Adds Windows version/icon + .wpress string table resource (currently appears unused by build). |
| packages/com.servmask.traktor/meta/package.xml | Enables installer scripting via <Script>installscript.qs</Script>. |
| packages/com.servmask.traktor/meta/installscript.qs | Adds Windows shortcuts + .wpress association registration during install. |
| mainwindow.ui | Replaces label-based file selection with DropOverlay, adds Clear button/menu action, adjusts layout. |
| mainwindow.h / mainwindow.cpp | Wires up DropOverlay signals, adds open/clear/extract helpers, and file-open handling. |
| main.cpp | Adds CLI parsing + headless extraction path; installs app-level file-open delegate for GUI mode. |
| dropoverlay.h / dropoverlay.cpp | New custom widget implementing drag-drop + clickable “open” behavior with custom painting. |
| appdelegate.h / appdelegate.cpp | New application event filter to handle OS “open file” events. |
| Traktor_resource.rc | Updates Windows version string metadata. |
| Qtraktor.pro | Adds new sources/headers, sets macOS Info.plist and Windows target metadata. |
| Info.plist | Declares .wpress document type and exported UTI for macOS. |
| icons/file.png / icons/file.ico | Adds icon assets for .wpress / file association. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!source.isEmpty() && !destination.isEmpty()) { | ||
| QTimer::singleShot(0, &w, [&w, destination]() { | ||
| w.extractToPath(destination); | ||
| }); | ||
| } | ||
|
|
There was a problem hiding this comment.
The QTimer::singleShot auto-extract block in GUI mode is unreachable because the function returns from the earlier “CLI mode” branch whenever both source and destination are provided. Either remove this block or change the mode-selection logic (e.g., add an explicit --cli / --headless flag) so the intended behavior is actually reachable.
| if (!source.isEmpty() && !destination.isEmpty()) { | |
| QTimer::singleShot(0, &w, [&w, destination]() { | |
| w.extractToPath(destination); | |
| }); | |
| } |
| void MainWindow::openBackupFile(const QString &filename) | ||
| { | ||
| backupFilename = filename; | ||
| QFileInfo fileInfo(backupFilename); | ||
|
|
||
| if (!fileInfo.isReadable()) { | ||
| QMessageBox::warning(this, tr("Unable to open file"), | ||
| tr("Unable to open file: %1").arg(backupFilename), | ||
| QMessageBox::StandardButton::Ok); | ||
| return; | ||
| } | ||
|
|
||
| ui->dropZone->setFileName(fileInfo.fileName()); | ||
| ui->extractBackupButton->setEnabled(true); | ||
| ui->clearButton->setVisible(true); | ||
| } |
There was a problem hiding this comment.
openBackupFile() assigns backupFilename = filename before validating readability. If the file isn’t readable, the function returns without restoring the previous state or disabling extraction, leaving the UI enabled but pointing at an invalid path. Validate first (or clear/disable state on failure) and only update backupFilename/UI once the file is accepted.
| if (event->type() == QEvent::FileOpen) { | ||
| QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event); | ||
| openBackupFile(openEvent->file()); | ||
| return true; | ||
| } | ||
| return QMainWindow::event(event); | ||
| } |
There was a problem hiding this comment.
MainWindow overrides event() to handle QEvent::FileOpen, but main.cpp also installs AppDelegate as an application-wide event filter that consumes the same event type. This duplication makes the flow harder to reason about and can lead to inconsistent behavior across platforms. Prefer a single mechanism (either the app-level filter or the window override) and remove the other.
| if (event->type() == QEvent::FileOpen) { | |
| QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event); | |
| openBackupFile(openEvent->file()); | |
| return true; | |
| } | |
| return QMainWindow::event(event); | |
| } | |
| return QMainWindow::event(event); | |
| } |
| bool AppDelegate::eventFilter(QObject *obj, QEvent *event) | ||
| { | ||
| if (event->type() == QEvent::FileOpen) { | ||
| QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event); | ||
| mainWindow->openBackupFile(openEvent->file()); | ||
| return true; | ||
| } | ||
| return QObject::eventFilter(obj, event); |
There was a problem hiding this comment.
eventFilter doesn’t use the obj parameter, which is likely to trigger an unused-parameter warning under typical warning levels. Consider adding Q_UNUSED(obj); or omitting the parameter name in the signature.
| // Register .wpress file association | ||
| // Command must quote the exe path (handles spaces in Program Files) | ||
| var iconPath = targetDir + "\\file.ico"; | ||
| component.addOperation( | ||
| "RegisterFileType", | ||
| "wpress", | ||
| "\"" + exePath + "\" \"%1\"", | ||
| "WPRESS Backup File", | ||
| "application/x-wpress", | ||
| iconPath | ||
| ); |
There was a problem hiding this comment.
The installer script registers .wpress with an icon path of TargetDir\\file.ico, but this repo only adds icons/file.ico and there’s no package data/ payload here that would copy/rename it into the install directory. This likely results in a missing icon or a failing file-type registration. Ensure the icon is installed at the referenced path (or point the association to an icon that is guaranteed to exist, e.g., an embedded icon in the EXE).
| #include <windows.h> | ||
|
|
||
| 1 VERSIONINFO | ||
| FILEVERSION 1,0,0,0 | ||
| PRODUCTVERSION 1,0,0,0 | ||
| BEGIN | ||
| BLOCK "StringFileInfo" | ||
| BEGIN | ||
| BLOCK "040904E4" | ||
| BEGIN | ||
| VALUE "CompanyName", "ServMask, Inc." | ||
| VALUE "FileDescription", "WPRESS Extractor" | ||
| VALUE "FileVersion", "1.0.0.0" | ||
| VALUE "InternalName", "Traktor" | ||
| VALUE "LegalCopyright", "ServMask, Inc." | ||
| VALUE "OriginalFilename", "Traktor.exe" | ||
| VALUE "ProductName", "Traktor" | ||
| VALUE "ProductVersion", "1.0.0.0" | ||
| END | ||
| END | ||
| BLOCK "VarFileInfo" | ||
| BEGIN | ||
| VALUE "Translation", 0x409, 1252 | ||
| END | ||
| END | ||
|
|
||
| IDI_ICON1 ICON DISCARDABLE "icons/traktor.ico" | ||
|
|
||
| STRINGTABLE | ||
| BEGIN | ||
| 1 "wpress" | ||
| 2 "WPRESS Backup File" | ||
| 3 "Traktor.WPRESS" | ||
| END No newline at end of file |
There was a problem hiding this comment.
win32.rc is added, but it isn’t referenced by the qmake project (Qtraktor.pro) or anywhere else in the repo, so it likely won’t be compiled into the Windows build. Either wire it in (e.g., via RC_FILE / appropriate qmake settings) or remove it to avoid carrying an unused resource definition.
| #include <windows.h> | |
| 1 VERSIONINFO | |
| FILEVERSION 1,0,0,0 | |
| PRODUCTVERSION 1,0,0,0 | |
| BEGIN | |
| BLOCK "StringFileInfo" | |
| BEGIN | |
| BLOCK "040904E4" | |
| BEGIN | |
| VALUE "CompanyName", "ServMask, Inc." | |
| VALUE "FileDescription", "WPRESS Extractor" | |
| VALUE "FileVersion", "1.0.0.0" | |
| VALUE "InternalName", "Traktor" | |
| VALUE "LegalCopyright", "ServMask, Inc." | |
| VALUE "OriginalFilename", "Traktor.exe" | |
| VALUE "ProductName", "Traktor" | |
| VALUE "ProductVersion", "1.0.0.0" | |
| END | |
| END | |
| BLOCK "VarFileInfo" | |
| BEGIN | |
| VALUE "Translation", 0x409, 1252 | |
| END | |
| END | |
| IDI_ICON1 ICON DISCARDABLE "icons/traktor.ico" | |
| STRINGTABLE | |
| BEGIN | |
| 1 "wpress" | |
| 2 "WPRESS Backup File" | |
| 3 "Traktor.WPRESS" | |
| END | |
| // Deprecated: this resource file is intentionally left empty because it is | |
| // not wired into the build (e.g., via qmake's RC_FILE) and would otherwise | |
| // carry unused Windows resource definitions. |
| QDir extractTo(destination + "/" + fileInfo.baseName()); | ||
| if (!QDir().mkdir(extractTo.path())) { | ||
| fprintf(stderr, "Error: cannot create directory: %s\n", | ||
| extractTo.path().toLocal8Bit().constData()); | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
In CLI mode, mkdir(extractTo.path()) will fail if the user passes a destination whose parent directories don’t exist (or if the destination already exists). Consider validating that destination exists and is a directory, and/or using QDir().mkpath(extractTo.path()) so the CLI behaves predictably for common inputs.
This pull request introduces significant improvements to both the user interface and functionality of the application, focusing on enhanced file handling, user experience, and platform integration. The main highlights include the addition of drag-and-drop support for
.wpressfiles, a new CLI mode for headless extraction, and improved metadata for platform compatibility. Below are the most important changes grouped by theme:User Interface Enhancements:
DropOverlaywidget (dropoverlay.h,dropoverlay.cpp) to enable drag-and-drop support for.wpressfiles, including visual feedback and clickable behavior. The UI (mainwindow.ui) was updated to use this widget and add a clear button, replacing the old label-based file selection. [1] [2] [3] [4]File Handling and Application Logic:
AppDelegateclass (appdelegate.h,appdelegate.cpp) to handle file open events, enabling the application to open.wpressfiles directly from the OS (e.g., double-clicking in Finder or Explorer). Integrated this into the Qt event system. [1] [2] [3]main.cpp) to support a new command-line interface (CLI) mode. Users can now extract backups via command-line arguments, with progress and error reporting, and optional password support for encrypted files.Platform Integration and Metadata:
Info.plistfile and updated the project configuration (Qtraktor.pro,Traktor_resource.rc) to register the.wpressfile type with the application, set proper icons, and provide detailed metadata for both macOS and Windows. This improves file association and OS integration. [1] [2] [3] [4]UI Layout and Appearance:
These changes collectively make the application more intuitive and versatile for both end-users and power users.