Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileBrowser: "Open containing folder" automatically selects file in the OS's file manager #7700

Merged
merged 147 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
0fb3d5f
Highlight file (currently not working)
AW1534 Feb 10, 2025
bcc14f7
Final commit
AW1534 Feb 10, 2025
04090c0
Merge branch 'LMMS:master' into filebrowser-changes
AW1534 Feb 10, 2025
68d1f61
Final commit
AW1534 Feb 10, 2025
d808428
fix deprecation warning
AW1534 Feb 10, 2025
61eec0d
address concerns about maintainability
AW1534 Feb 14, 2025
b59f781
Merge branch 'master' into filebrowser-changes
AW1534 Feb 14, 2025
336b859
fix logic error
AW1534 Feb 14, 2025
5ab4514
Update src/gui/FileBrowser.cpp
AW1534 Feb 14, 2025
9d06484
abstract file selection code away from FileBrowser into FileManagerSe…
AW1534 Feb 14, 2025
d7a810e
reformat
AW1534 Feb 14, 2025
02caccc
remove redundant variable
AW1534 Feb 14, 2025
3a6c5fd
make all functions usable on all operating systems
AW1534 Feb 14, 2025
63dfd4c
fix compilation issue
AW1534 Feb 14, 2025
bc2d5f0
remove .desktop extention if present
AW1534 Feb 14, 2025
feba849
remove .desktop extention if present
AW1534 Feb 14, 2025
c19a250
fix linux compilation issue (maybe)
AW1534 Feb 14, 2025
09184b3
minor
AW1534 Feb 14, 2025
1995cdf
Update src/core/FileManagerServices.cpp
AW1534 Feb 15, 2025
a49a631
Update src/core/FileManagerServices.cpp
AW1534 Feb 15, 2025
9e39e33
Update include/FileManagerServices.h
AW1534 Feb 15, 2025
751fc1c
Update src/core/FileManagerServices.cpp
AW1534 Feb 15, 2025
fd41617
Update src/gui/FileBrowser.cpp
AW1534 Feb 15, 2025
4114cde
Update src/gui/FileBrowser.cpp
AW1534 Feb 15, 2025
0f88473
apply code suggestion by tresf
AW1534 Feb 15, 2025
cd291c6
fix issue with fileManagers containing dots (e.g org.kde.dolphin.desk…
AW1534 Feb 15, 2025
4e21f15
fix linux compilation (hopefully)
AW1534 Feb 15, 2025
adbbd21
remove blank whitespace
AW1534 Feb 15, 2025
9d0e1a3
Remove checks to FILE_MANAGER and XDG_FILE_MANAGER env variables
AW1534 Feb 15, 2025
34dd41a
change indents from spaces to tabs
AW1534 Feb 15, 2025
d64c810
cache canSelect
AW1534 Feb 15, 2025
8aa6b98
Update include/FileBrowser.h
AW1534 Feb 16, 2025
ba4faf0
Update include/FileManagerServices.h
AW1534 Feb 16, 2025
3068aac
Update include/FileManagerServices.h
AW1534 Feb 16, 2025
f8bce34
Update src/gui/FileBrowser.cpp
AW1534 Feb 16, 2025
6f556f9
better type checking for file/directories
AW1534 Feb 16, 2025
49bac6d
add email to files
AW1534 Feb 16, 2025
1bfa070
Merge branch 'filebrowser-changes' of https://github.com/AW1534/lmms …
AW1534 Feb 16, 2025
2a66ccb
get rid of openDirectory and open directory without openUrl
AW1534 Feb 16, 2025
de5dc60
get rid of openDirectory and open directory without openUrl
AW1534 Feb 16, 2025
ad5a64d
fix scripted check
AW1534 Feb 16, 2025
9f5fae8
reformatting
AW1534 Feb 16, 2025
d353d80
get rid of `[[maybe_unused]]`
AW1534 Feb 16, 2025
8cde86f
remove preprocessor checks from .h file
AW1534 Feb 16, 2025
3915d72
cache default file manager
AW1534 Feb 16, 2025
d00622a
reformat
AW1534 Feb 16, 2025
04fc8ad
remove useCache option
AW1534 Feb 17, 2025
e275e75
remove unnecessary `Directory` pre-declaration
AW1534 Feb 17, 2025
069fc13
fix caching on windows
AW1534 Feb 17, 2025
6abbece
remove unnecessary isDir
AW1534 Feb 17, 2025
3f84289
Update src/core/FileManagerServices.cpp
AW1534 Feb 17, 2025
f99bbde
Update src/core/FileManagerServices.cpp
AW1534 Feb 17, 2025
33977ec
formatting
AW1534 Feb 17, 2025
ec2ecc2
Merge branch 'filebrowser-changes' of https://github.com/AW1534/lmms …
AW1534 Feb 17, 2025
78ec08c
move call to `QDesktop::openUrl()` into FileManagerServices.cpp & rem…
AW1534 Feb 17, 2025
178b703
rename `select` (and related identifiers) to `reveal`
AW1534 Feb 17, 2025
bf548d4
add show in file manager option to folders
AW1534 Feb 17, 2025
47dab80
reformat
AW1534 Feb 17, 2025
bfaa7c1
rename `cachedCanReveal` and `canReveal`
AW1534 Feb 17, 2025
fdb0072
remove `openContainingFolder`
AW1534 Feb 17, 2025
65e219d
revert whitespace changes
AW1534 Feb 17, 2025
3ce2882
Update src/core/FileManagerServices.cpp
AW1534 Feb 17, 2025
6d2a0a1
cache `supportsSelectOption`
AW1534 Feb 18, 2025
1f68f78
undo unnecessary changes
AW1534 Feb 18, 2025
cf94aa5
undo unnecessary changes
AW1534 Feb 18, 2025
45fcb81
rename fileManagerCache
AW1534 Feb 18, 2025
fe9e6f9
remove weird switch/case statement that was unnecessary and only comp…
AW1534 Feb 18, 2025
41cd4a7
remove supportsSelectOption cache
AW1534 Feb 18, 2025
20b47e1
move FileManagerServices to core and rename to FileRevealer
AW1534 Feb 18, 2025
e188bd3
reorder cmakelists
AW1534 Feb 18, 2025
255ec72
Update src/gui/FileBrowser.cpp
AW1534 Feb 18, 2025
b774511
Update src/gui/FileRevealer.cpp
AW1534 Feb 18, 2025
724b6b7
Update include/FileBrowser.h
AW1534 Feb 18, 2025
1c6234c
Update include/FileBrowser.h
AW1534 Feb 18, 2025
52a4cb8
Merge branch 'filebrowser-changes' of https://github.com/AW1534/lmms …
AW1534 Feb 18, 2025
e4239c8
Update src/gui/FileBrowser.cpp
AW1534 Feb 18, 2025
b9dbe35
Update src/gui/FileBrowser.cpp
AW1534 Feb 18, 2025
be7192b
Merge branch 'filebrowser-changes' of https://github.com/AW1534/lmms …
AW1534 Feb 18, 2025
9266ea7
Update src/gui/FileRevealer.cpp
AW1534 Feb 18, 2025
9cf1558
remove highlight directory
AW1534 Feb 18, 2025
926397b
Merge branch 'filebrowser-changes' of https://github.com/AW1534/lmms …
AW1534 Feb 18, 2025
187633a
Update src/gui/FileRevealer.cpp
AW1534 Feb 18, 2025
9e8ae7f
fix stock folders
AW1534 Feb 18, 2025
1c86f97
Merge branch 'filebrowser-changes' of https://github.com/AW1534/lmms …
AW1534 Feb 18, 2025
bf393c8
fix compilation error
AW1534 Feb 18, 2025
2131e71
Merge branch 'LMMS:master' into filebrowser-changes
AW1534 Feb 18, 2025
693b8d1
Update src/gui/FileBrowser.cpp
AW1534 Feb 18, 2025
7b8015f
Update src/gui/FileBrowser.cpp
AW1534 Feb 18, 2025
81306a0
Update src/gui/FileBrowser.cpp
AW1534 Feb 18, 2025
c1fbc14
fix compilation
AW1534 Feb 18, 2025
4342dcb
remove unused capture of `this`
AW1534 Feb 18, 2025
db5e4ed
Update src/gui/FileRevealer.cpp
AW1534 Feb 19, 2025
6def2ff
Update src/gui/FileRevealer.cpp
AW1534 Feb 19, 2025
14550a4
Update include/FileRevealer.h
AW1534 Feb 19, 2025
9465070
Update include/FileRevealer.h
AW1534 Feb 19, 2025
35b03af
Update src/gui/FileRevealer.cpp
AW1534 Feb 19, 2025
32e15a7
fix `canSelect` caching on MacOS
AW1534 Feb 19, 2025
c3896e4
replace `_WIN32` and `__APPLE__` with `LMMS_BUILD_WIN32` and `LMMS_BU…
AW1534 Feb 19, 2025
3b10722
replace `_WIN32` and `__APPLE__` with `LMMS_BUILD_WIN32` and `LMMS_BU…
AW1534 Feb 19, 2025
e6ae427
add Doxygen documentation
AW1534 Feb 19, 2025
cb52f6e
change #ifdef in hopes of fixing compilation issue
AW1534 Feb 19, 2025
6dcfc4e
Merge branch 'LMMS:master' into filebrowser-changes
AW1534 Feb 19, 2025
0fd6dc5
Update src/gui/FileRevealer.cpp
AW1534 Feb 20, 2025
62377e8
Merge branch 'LMMS:master' into filebrowser-changes
AW1534 Feb 20, 2025
1877ee3
Update src/gui/FileRevealer.cpp
AW1534 Feb 20, 2025
dd739c2
whitelist nemo
AW1534 Feb 20, 2025
0664a30
reorder .cpp to match .h
AW1534 Feb 20, 2025
57ac06e
remove accidental redefinition of `supportsSelectOption`
AW1534 Feb 20, 2025
aa83e23
fix nemo
AW1534 Feb 20, 2025
662b628
fix compile error
AW1534 Feb 20, 2025
0e1d6c3
Refactor the select commands for our little friend nemo
tresf Feb 20, 2025
8751550
fix minor things
AW1534 Feb 20, 2025
a90470a
apply formatting rules
AW1534 Feb 20, 2025
bdeea06
Fix bugs
tresf Feb 20, 2025
a0bd640
Fix windows
tresf Feb 20, 2025
c6e9207
replace missing curly brace
AW1534 Feb 20, 2025
36c0fbd
Fix #endif
tresf Feb 20, 2025
62d13a2
More typos
tresf Feb 20, 2025
fc59a12
Simplify
tresf Feb 20, 2025
6122762
Update src/gui/FileRevealer.cpp
AW1534 Feb 20, 2025
eab1a0a
Update include/FileRevealer.h
AW1534 Feb 20, 2025
a2ac5e6
small changes
AW1534 Feb 20, 2025
42b96be
fix `selectCommandCache`
AW1534 Feb 20, 2025
db1f591
dont use toLatin1
AW1534 Feb 20, 2025
5e98bce
remove unnecessary preprocessor check
AW1534 Feb 20, 2025
0f4b331
rename `canSelect`
AW1534 Feb 20, 2025
69329af
get last fileManager
AW1534 Feb 21, 2025
80ce575
apply formatting rules
AW1534 Feb 21, 2025
b38f99b
Update src/gui/FileRevealer.cpp
AW1534 Feb 22, 2025
b4616e0
Merge branch 'LMMS:master' into filebrowser-changes
AW1534 Feb 25, 2025
aee19b5
Update src/gui/FileRevealer.cpp
AW1534 Feb 26, 2025
1165ac6
fix xfce issues?
AW1534 Feb 26, 2025
bd55659
gnome
AW1534 Feb 26, 2025
2a8ef7d
remove process call
AW1534 Feb 26, 2025
0bff11b
minor change to QString.split call and apply formatting rules
AW1534 Feb 26, 2025
e94049d
only use XDG_CURRENT_DESKTOP
AW1534 Feb 26, 2025
4699059
use QStringList
AW1534 Feb 26, 2025
1871367
Add gnome-->gio support
tresf Feb 26, 2025
c65c2d5
Formatting
tresf Feb 26, 2025
b33a5c9
Update src/gui/FileRevealer.cpp
tresf Feb 26, 2025
aad14a4
Update src/gui/FileRevealer.cpp
AW1534 Feb 28, 2025
a2a7dc4
Update src/gui/FileRevealer.cpp
AW1534 Feb 28, 2025
f9e1cb0
Update src/gui/FileRevealer.cpp
AW1534 Feb 28, 2025
77ab7d7
Update src/gui/FileRevealer.cpp
AW1534 Feb 28, 2025
2f0eb0d
Update src/gui/FileRevealer.cpp
AW1534 Feb 28, 2025
cec8ff5
Update src/gui/FileRevealer.cpp
AW1534 Feb 28, 2025
c004754
Merge branch 'LMMS:master' into filebrowser-changes
AW1534 Feb 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/FileBrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private slots:
} ;



class Directory;

class FileBrowserTreeWidget : public QTreeWidget
{
Expand Down Expand Up @@ -195,8 +195,8 @@ private slots:
bool openInNewSampleTrack( lmms::gui::FileItem* item );
void sendToActiveInstrumentTrack( lmms::gui::FileItem* item );
void updateDirectory( QTreeWidgetItem * item );
void openDirectory( Directory* directory );
void openContainingFolder( lmms::gui::FileItem* item );

} ;


Expand Down
175 changes: 142 additions & 33 deletions src/gui/FileBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <QMdiSubWindow>
#include <QMenu>
#include <QMessageBox>
#include <QProcess>
#include <QPushButton>
#include <QShortcut>
#include <QStringList>
Expand Down Expand Up @@ -68,9 +69,16 @@
#include "ThreadPool.h"
#include "embed.h"

#if !defined(_WIN32) && !defined(__APPLE__)
#include <QHash>
#endif

namespace lmms::gui
{

#if !defined(_WIN32) && !defined(__APPLE__)
QHash<QString, bool> selectOptionCache;
#endif

enum TreeWidgetItemTypes
{
Expand Down Expand Up @@ -629,37 +637,63 @@

void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e )
{
auto file = dynamic_cast<FileItem*>(itemAt(e->pos()));
if( file != nullptr && file->isTrack() )
{
QMenu contextMenu( this );
#ifdef LMMS_BUILD_APPLE
QString fileManager = tr("Finder");
#elif defined(LMMS_BUILD_WIN32)
QString fileManager = tr("File Explorer");
#else
QString fileManager = tr("file manager");
#endif

contextMenu.addAction(
tr( "Send to active instrument-track" ),
[=, this]{ sendToActiveInstrumentTrack(file); }
);
QTreeWidgetItem* item = itemAt(e->pos());

contextMenu.addSeparator();
auto file = dynamic_cast<FileItem*>(item);

contextMenu.addAction(
QIcon(embed::getIconPixmap("folder")),
tr("Open containing folder"),
[=, this]{ openContainingFolder(file); }
);
QMenu contextMenu( this );

auto songEditorHeader = new QAction(tr("Song Editor"), nullptr);
songEditorHeader->setDisabled(true);
contextMenu.addAction( songEditorHeader );
contextMenu.addActions( getContextActions(file, true) );
auto dir = dynamic_cast<Directory*>(item); // TODO: this might not be a great way to check if it's a directory

auto patternEditorHeader = new QAction(tr("Pattern Editor"), nullptr);
patternEditorHeader->setDisabled(true);
contextMenu.addAction(patternEditorHeader);
contextMenu.addActions( getContextActions(file, false) );

// We should only show the menu if it contains items
if (!contextMenu.isEmpty()) { contextMenu.exec( e->globalPos() ); }
}
if( file != nullptr)
{
if (file->isTrack()) {
contextMenu.addAction(
tr( "Send to active instrument-track" ),
[=, this]{ sendToActiveInstrumentTrack(file); }
);

contextMenu.addSeparator();
}

contextMenu.addAction(
QIcon(embed::getIconPixmap("folder")),

tr("Show in") + " " +fileManager,
[=, this]{ openContainingFolder(file); }
);


auto songEditorHeader = new QAction(tr("Song Editor"), nullptr);
songEditorHeader->setDisabled(true);
contextMenu.addAction( songEditorHeader );
contextMenu.addActions( getContextActions(file, true) );

auto patternEditorHeader = new QAction(tr("Pattern Editor"), nullptr);
patternEditorHeader->setDisabled(true);
contextMenu.addAction(patternEditorHeader);
contextMenu.addActions( getContextActions(file, false) );

} else if (dir) {

contextMenu.addAction(
QIcon(embed::getIconPixmap("folder")),
tr("Open in") + " " + fileManager,
[=, this]{ openDirectory(dir); }
);
}

// We should only show the menu if it contains items
if (!contextMenu.isEmpty()) { contextMenu.exec( e->globalPos() ); }
}


Expand Down Expand Up @@ -910,7 +944,7 @@
it->replaceInstrument(dataFile);
break;
}
case FileItem::FileHandling::ImportAsProject:

Check notice on line 947 in src/gui/FileBrowser.cpp

View check run for this annotation

codefactor.io / CodeFactor

src/gui/FileBrowser.cpp#L947

Redundant blank line at the end of a code block should be deleted. (whitespace/blank_line)
ImportFilter::import( f->fullName(),
Engine::getSong() );
break;
Expand Down Expand Up @@ -992,21 +1026,96 @@



void FileBrowserTreeWidget::openDirectory(Directory* directory) {
QDesktopServices::openUrl(QUrl::fromLocalFile(directory->fullName()));
}

#if !defined(_WIN32) && !defined(__APPLE__)

bool supportsSelectOption(const QString &fileManager) {
if (selectOptionCache.contains(fileManager)) {
return selectOptionCache[fileManager];
}

QProcess process;
process.start(fileManager, {"--help"});

// Ensure we don't block forever
if (!process.waitForFinished(1000)) {
selectOptionCache[fileManager] = false;
return false;
}

// Capture both stdout and stderr (some apps print help to stderr)
QString output = QString::fromUtf8(process.readAllStandardOutput() + process.readAllStandardError());

// Some file managers return non-zero exit codes for --help, so we ignore it
bool supportsSelect = output.contains("--select", Qt::CaseInsensitive);

selectOptionCache[fileManager] = supportsSelect; // Cache the result
return supportsSelect;
}


static QString getDefaultFileManager() {
QProcess process;
process.start("xdg-mime", {"query", "default", "inode/directory"});
process.waitForFinished();

QString fileManager = QString::fromUtf8(process.readAllStandardOutput()).trimmed();

if (fileManager.isEmpty()) {
fileManager = qgetenv("FILE_MANAGER");
if (fileManager.isEmpty()) {
fileManager = qgetenv("XDG_FILE_MANAGER");
}
}

return fileManager;
}
#endif

void FileBrowserTreeWidget::openContainingFolder(FileItem* item)
{
// Delegate to QDesktopServices::openUrl with the directory of the selected file. Please note that
// this will only open the directory but not select the file as this is much more complicated due
// to different implementations that are needed for different platforms (Linux/Windows/MacOS).

// Using QDesktopServices::openUrl seems to be the most simple cross platform way which uses
// functionality that's already available in Qt.
QFileInfo fileInfo(item->fullName());
QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.dir().path()));
QFileInfo fileInfo(item->fullName());
QString path = QDir::toNativeSeparators(fileInfo.canonicalFilePath());
QString directory = QDir::toNativeSeparators(fileInfo.canonicalFilePath());

#ifdef _WIN32
// Windows
QStringList param;
if (!fileInfo.isDir())
param += QLatin1String("/select,");
param += path;
QProcess::startDetached("explorer", param);

#elif __APPLE__
// macOS
QProcess::startDetached("open", {"-R", path});
#else
// Linux & BSD
// there are a lot of potential file managers on these systems so we need to figure out what to use.

QString fileManager = getDefaultFileManager();

if (fileManager.isEmpty()) {
QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(path).absolutePath()));
return;
}

// If the file manager supports --select, use it. Otherwise, open the directory.
if (supportsSelectOption(fileManager)) {
QProcess::startDetached(fileManager, {"--select", path});
} else {
QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(path).absolutePath()));
}
#endif
}





void FileBrowserTreeWidget::sendToActiveInstrumentTrack( FileItem* item )
{
// get all windows opened in the workspace
Expand Down
Loading