Add option to favorite items in the file browser (#7753)
Added the ability to favorite items. This gets added to its own tab named "My Favorites". --------- Co-authored-by: Sotonye Atemie <sakertooth@gmail.com>
This commit is contained in:
@@ -22,19 +22,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ConfigManager.h"
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <PathUtil.h>
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QDomElement>
|
||||
#include <QMessageBox>
|
||||
#include <QStandardPaths>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ProjectVersion.h"
|
||||
#include "GuiApplication.h"
|
||||
|
||||
#include "lmmsversion.h"
|
||||
|
||||
namespace lmms
|
||||
@@ -299,9 +299,6 @@ void ConfigManager::setBackgroundPicFile(const QString & backgroundPicFile)
|
||||
m_backgroundPicFile = backgroundPicFile;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void ConfigManager::createWorkingDir()
|
||||
{
|
||||
QDir().mkpath(m_workingDir);
|
||||
@@ -335,8 +332,27 @@ void ConfigManager::addRecentlyOpenedProject(const QString & file)
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::addFavoriteItem(const QString& item)
|
||||
{
|
||||
m_favoriteItems.push_back(item);
|
||||
saveConfigFile();
|
||||
emit favoritesChanged();
|
||||
}
|
||||
|
||||
void ConfigManager::removeFavoriteItem(const QString& item)
|
||||
{
|
||||
m_favoriteItems.removeAll(item);
|
||||
saveConfigFile();
|
||||
emit favoritesChanged();
|
||||
}
|
||||
|
||||
bool ConfigManager::isFavoriteItem(const QString& item)
|
||||
{
|
||||
const auto& items = favoriteItems();
|
||||
const auto it = std::find_if(items.begin(), items.end(),
|
||||
[&](const auto& favoriteItem) { return QFileInfo{item} == QFileInfo{favoriteItem}; });
|
||||
return it != items.end();
|
||||
}
|
||||
|
||||
QString ConfigManager::value(const QString& cls, const QString& attribute, const QString& defaultVal) const
|
||||
{
|
||||
@@ -466,8 +482,20 @@ void ConfigManager::loadConfigFile(const QString & configFile)
|
||||
{
|
||||
if(n.isElement() && n.toElement().hasAttributes())
|
||||
{
|
||||
m_recentlyOpenedProjects <<
|
||||
n.toElement().attribute("path");
|
||||
m_recentlyOpenedProjects << n.toElement().attribute("path");
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
}
|
||||
else if (node.nodeName() == "favoriteitems")
|
||||
{
|
||||
m_favoriteItems.clear();
|
||||
QDomNode n = node.firstChild();
|
||||
while (!n.isNull())
|
||||
{
|
||||
if (n.isElement() && n.toElement().hasAttributes())
|
||||
{
|
||||
m_favoriteItems << n.toElement().attribute("path");
|
||||
}
|
||||
n = n.nextSibling();
|
||||
}
|
||||
@@ -571,6 +599,16 @@ void ConfigManager::loadConfigFile(const QString & configFile)
|
||||
{
|
||||
createWorkingDir();
|
||||
}
|
||||
|
||||
for (auto& file : m_recentlyOpenedProjects)
|
||||
{
|
||||
file = PathUtil::toAbsolute(file);
|
||||
}
|
||||
|
||||
for (auto& file : m_favoriteItems)
|
||||
{
|
||||
file = PathUtil::toAbsolute(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -614,11 +652,22 @@ void ConfigManager::saveConfigFile()
|
||||
for (const auto& recentlyOpenedProject : m_recentlyOpenedProjects)
|
||||
{
|
||||
QDomElement n = doc.createElement("file");
|
||||
n.setAttribute("path", recentlyOpenedProject);
|
||||
n.setAttribute("path", PathUtil::toShortestRelative(recentlyOpenedProject));
|
||||
recent_files.appendChild(n);
|
||||
}
|
||||
lmms_config.appendChild(recent_files);
|
||||
|
||||
QDomElement favorite_items = doc.createElement("favoriteitems");
|
||||
|
||||
for (const auto& favoriteItem : m_favoriteItems)
|
||||
{
|
||||
QDomElement n = doc.createElement("item");
|
||||
n.setAttribute("path", PathUtil::toShortestRelative(favoriteItem));
|
||||
favorite_items.appendChild(n);
|
||||
}
|
||||
|
||||
lmms_config.appendChild(favorite_items);
|
||||
|
||||
QString xml = "<?xml version=\"1.0\"?>\n" + doc.toString(2);
|
||||
|
||||
QFile outfile(m_lmmsRcFile);
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
namespace lmms::PathUtil
|
||||
{
|
||||
auto relativeBases = std::array{ Base::ProjectDir, Base::FactorySample, Base::UserSample, Base::UserVST, Base::Preset,
|
||||
Base::UserLADSPA, Base::DefaultLADSPA, Base::UserSoundfont, Base::DefaultSoundfont, Base::UserGIG, Base::DefaultGIG,
|
||||
auto relativeBases = std::array{ Base::ProjectDir, Base::FactoryProjects, Base::FactorySample, Base::UserSample, Base::UserVST, Base::Preset,
|
||||
Base::FactoryPresets, Base::UserLADSPA, Base::DefaultLADSPA, Base::UserSoundfont, Base::DefaultSoundfont, Base::UserGIG, Base::DefaultGIG,
|
||||
Base::LocalDir };
|
||||
|
||||
QString baseLocation(const Base base, bool* error /* = nullptr*/)
|
||||
@@ -22,6 +22,11 @@ namespace lmms::PathUtil
|
||||
switch (base)
|
||||
{
|
||||
case Base::ProjectDir : loc = ConfigManager::inst()->userProjectsDir(); break;
|
||||
case Base::FactoryProjects :
|
||||
{
|
||||
QDir fpd = QDir(ConfigManager::inst()->factoryProjectsDir());
|
||||
loc = fpd.absolutePath(); break;
|
||||
}
|
||||
case Base::FactorySample :
|
||||
{
|
||||
QDir fsd = QDir(ConfigManager::inst()->factorySamplesDir());
|
||||
@@ -30,6 +35,11 @@ namespace lmms::PathUtil
|
||||
case Base::UserSample : loc = ConfigManager::inst()->userSamplesDir(); break;
|
||||
case Base::UserVST : loc = ConfigManager::inst()->userVstDir(); break;
|
||||
case Base::Preset : loc = ConfigManager::inst()->userPresetsDir(); break;
|
||||
case Base::FactoryPresets :
|
||||
{
|
||||
QDir fpd = QDir(ConfigManager::inst()->factoryPresetsDir());
|
||||
loc = fpd.absolutePath(); break;
|
||||
}
|
||||
case Base::UserLADSPA : loc = ConfigManager::inst()->ladspaDir(); break;
|
||||
case Base::DefaultLADSPA : loc = ConfigManager::inst()->userLadspaDir(); break;
|
||||
case Base::UserSoundfont : loc = ConfigManager::inst()->sf2Dir(); break;
|
||||
@@ -70,10 +80,12 @@ namespace lmms::PathUtil
|
||||
switch (base)
|
||||
{
|
||||
case Base::ProjectDir : return QStringLiteral("userprojects:");
|
||||
case Base::FactoryProjects : return QStringLiteral("factoryprojects:");
|
||||
case Base::FactorySample : return QStringLiteral("factorysample:");
|
||||
case Base::UserSample : return QStringLiteral("usersample:");
|
||||
case Base::UserVST : return QStringLiteral("uservst:");
|
||||
case Base::Preset : return QStringLiteral("preset:");
|
||||
case Base::FactoryPresets : return QStringLiteral("factorypreset:");
|
||||
case Base::UserLADSPA : return QStringLiteral("userladspa:");
|
||||
case Base::DefaultLADSPA : return QStringLiteral("defaultladspa:");
|
||||
case Base::UserSoundfont : return QStringLiteral("usersoundfont:");
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "FileBrowser.h"
|
||||
|
||||
#include <PathUtil.h>
|
||||
#include <QApplication>
|
||||
#include <QDirIterator>
|
||||
#include <QHBoxLayout>
|
||||
@@ -77,18 +78,15 @@ enum TreeWidgetItemTypes
|
||||
TypeDirectoryItem
|
||||
} ;
|
||||
|
||||
|
||||
FileBrowser::FileBrowser(const QString & directories, const QString & filter,
|
||||
const QString & title, const QPixmap & pm,
|
||||
QWidget * parent, bool dirs_as_items,
|
||||
const QString& userDir,
|
||||
const QString& factoryDir):
|
||||
SideBarWidget( title, pm, parent ),
|
||||
m_directories( directories ),
|
||||
m_filter( filter ),
|
||||
m_dirsAsItems( dirs_as_items ),
|
||||
m_userDir(userDir),
|
||||
m_factoryDir(factoryDir)
|
||||
FileBrowser::FileBrowser(Type type, const QString& directories, const QString& filter, const QString& title, const QPixmap& pm,
|
||||
QWidget* parent, bool dirs_as_items, const QString& userDir, const QString& factoryDir)
|
||||
: SideBarWidget(title, pm, parent)
|
||||
, m_type(type)
|
||||
, m_directories(directories)
|
||||
, m_filter(filter)
|
||||
, m_dirsAsItems(dirs_as_items)
|
||||
, m_userDir(userDir)
|
||||
, m_factoryDir(factoryDir)
|
||||
{
|
||||
setWindowTitle( tr( "Browser" ) );
|
||||
|
||||
@@ -136,6 +134,14 @@ FileBrowser::FileBrowser(const QString & directories, const QString & filter,
|
||||
|
||||
m_previousFilterValue = "";
|
||||
|
||||
if (m_type == Type::Favorites)
|
||||
{
|
||||
connect(ConfigManager::inst(), &ConfigManager::favoritesChanged, [this] {
|
||||
m_directories = ConfigManager::inst()->favoriteItems().join("*");
|
||||
reloadTree();
|
||||
});
|
||||
}
|
||||
|
||||
reloadTree();
|
||||
show();
|
||||
}
|
||||
@@ -329,7 +335,7 @@ void FileBrowser::reloadTree()
|
||||
|
||||
m_fileBrowserTreeWidget->clear();
|
||||
|
||||
QStringList paths = m_directories.split('*');
|
||||
auto paths = m_directories.isEmpty() ? QStringList{} : m_directories.split('*');
|
||||
|
||||
if (m_showUserContent && !m_showUserContent->isChecked())
|
||||
{
|
||||
@@ -341,12 +347,37 @@ void FileBrowser::reloadTree()
|
||||
paths.removeAll(m_factoryDir);
|
||||
}
|
||||
|
||||
if (!paths.isEmpty())
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::Favorites:
|
||||
for (auto& path : paths)
|
||||
{
|
||||
while (path.endsWith('/') || path.endsWith('\\') || path.endsWith("."))
|
||||
{
|
||||
path.chop(1);
|
||||
}
|
||||
|
||||
auto info = QFileInfo{PathUtil::toAbsolute(path)};
|
||||
|
||||
if (info.isDir())
|
||||
{
|
||||
auto dir = new Directory(info.fileName(), info.absolutePath(), m_filter);
|
||||
dir->update();
|
||||
m_fileBrowserTreeWidget->addTopLevelItem(dir);
|
||||
}
|
||||
else if (info.isFile())
|
||||
{
|
||||
auto file = new FileItem(info.fileName(), info.path());
|
||||
m_fileBrowserTreeWidget->addTopLevelItem(file);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Type::Normal:
|
||||
for (const auto& path : paths)
|
||||
{
|
||||
addItems(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_filterEdit->text().isEmpty())
|
||||
@@ -642,17 +673,29 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent* e)
|
||||
{
|
||||
case TypeFileItem: {
|
||||
auto file = dynamic_cast<FileItem*>(item);
|
||||
|
||||
if (file->isTrack())
|
||||
{
|
||||
contextMenu.addAction(
|
||||
tr("Send to active instrument-track"), [=, this] { sendToActiveInstrumentTrack(file); });
|
||||
contextMenu.addSeparator();
|
||||
}
|
||||
const auto path = QFileInfo{file->fullName()}.absoluteFilePath();
|
||||
|
||||
contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), tr("Show in %1").arg(fileManager),
|
||||
[=] { FileRevealer::reveal(file->fullName()); });
|
||||
|
||||
if (ConfigManager::inst()->isFavoriteItem(file->fullName()))
|
||||
{
|
||||
contextMenu.addAction(
|
||||
QIcon(embed::getIconPixmap("star")), tr("Remove favorite file"), [path] { ConfigManager::inst()->removeFavoriteItem(path); });
|
||||
}
|
||||
else
|
||||
{
|
||||
contextMenu.addAction(
|
||||
QIcon(embed::getIconPixmap("star")), tr("Add favorite file"), [path] { ConfigManager::inst()->addFavoriteItem(path); });
|
||||
}
|
||||
|
||||
if (file->isTrack())
|
||||
{
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(
|
||||
tr("Send to active instrument-track"), [=, this] { sendToActiveInstrumentTrack(file); });
|
||||
}
|
||||
|
||||
auto songEditorHeader = new QAction(tr("Song Editor"), nullptr);
|
||||
songEditorHeader->setDisabled(true);
|
||||
contextMenu.addAction( songEditorHeader );
|
||||
@@ -666,9 +709,20 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent* e)
|
||||
}
|
||||
case TypeDirectoryItem: {
|
||||
auto dir = dynamic_cast<Directory*>(item);
|
||||
const auto path = QFileInfo{dir->fullName()}.absoluteFilePath();
|
||||
|
||||
contextMenu.addAction(QIcon(embed::getIconPixmap("folder")), tr("Open in %1").arg(fileManager), [=] {
|
||||
FileRevealer::openDir(dir->fullName());
|
||||
});
|
||||
|
||||
if (ConfigManager::inst()->isFavoriteItem(dir->fullName()))
|
||||
{
|
||||
contextMenu.addAction(QIcon(embed::getIconPixmap("star")), tr("Remove favorite folder"), [path] { ConfigManager::inst()->removeFavoriteItem(path); });
|
||||
}
|
||||
else
|
||||
{
|
||||
contextMenu.addAction(QIcon(embed::getIconPixmap("star")), tr("Add favorite folder"), [path] { ConfigManager::inst()->addFavoriteItem(path); });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,30 +111,27 @@ MainWindow::MainWindow() :
|
||||
emit initProgress(tr("Preparing plugin browser"));
|
||||
sideBar->appendTab( new PluginBrowser( splitter ) );
|
||||
emit initProgress(tr("Preparing file browsers"));
|
||||
sideBar->appendTab( new FileBrowser(
|
||||
confMgr->userProjectsDir() + "*" +
|
||||
confMgr->factoryProjectsDir(),
|
||||
"*.mmp *.mmpz *.xml *.mid *.mpt",
|
||||
tr( "My Projects" ),
|
||||
embed::getIconPixmap( "project_file" ).transformed( QTransform().rotate( 90 ) ),
|
||||
splitter, false,
|
||||
confMgr->userProjectsDir(),
|
||||
confMgr->factoryProjectsDir()));
|
||||
sideBar->appendTab(
|
||||
new FileBrowser(confMgr->userSamplesDir() + "*" + confMgr->factorySamplesDir(), FileItem::defaultFilters(),
|
||||
tr("My Samples"), embed::getIconPixmap("sample_file").transformed(QTransform().rotate(90)), splitter, false,
|
||||
confMgr->userSamplesDir(), confMgr->factorySamplesDir()));
|
||||
sideBar->appendTab( new FileBrowser(
|
||||
confMgr->userPresetsDir() + "*" +
|
||||
confMgr->factoryPresetsDir(),
|
||||
"*.xpf *.cs.xml *.xiz *.lv2",
|
||||
tr( "My Presets" ),
|
||||
embed::getIconPixmap( "preset_file" ).transformed( QTransform().rotate( 90 ) ),
|
||||
splitter , false,
|
||||
confMgr->userPresetsDir(),
|
||||
confMgr->factoryPresetsDir()));
|
||||
sideBar->appendTab(new FileBrowser(QDir::homePath(), FileItem::defaultFilters(), tr("My Home"),
|
||||
embed::getIconPixmap("home").transformed(QTransform().rotate(90)), splitter, false));
|
||||
|
||||
sideBar->appendTab(new FileBrowser(FileBrowser::Type::Favorites, ConfigManager::inst()->favoriteItems().join("*"), FileItem::defaultFilters(), "My Favorites",
|
||||
embed::getIconPixmap("star").transformed(QTransform().rotate(90)), splitter, false, "", ""));
|
||||
|
||||
sideBar->appendTab(new FileBrowser(FileBrowser::Type::Normal,
|
||||
confMgr->userProjectsDir() + "*" + confMgr->factoryProjectsDir(), "*.mmp *.mmpz *.xml *.mid *.mpt",
|
||||
tr("My Projects"), embed::getIconPixmap("project_file").transformed(QTransform().rotate(90)), splitter, false,
|
||||
confMgr->userProjectsDir(), confMgr->factoryProjectsDir()));
|
||||
|
||||
sideBar->appendTab(new FileBrowser(FileBrowser::Type::Normal,
|
||||
confMgr->userSamplesDir() + "*" + confMgr->factorySamplesDir(), FileItem::defaultFilters(), tr("My Samples"),
|
||||
embed::getIconPixmap("sample_file").transformed(QTransform().rotate(90)), splitter, false,
|
||||
confMgr->userSamplesDir(), confMgr->factorySamplesDir()));
|
||||
|
||||
sideBar->appendTab(new FileBrowser(FileBrowser::Type::Normal,
|
||||
confMgr->userPresetsDir() + "*" + confMgr->factoryPresetsDir(), "*.xpf *.cs.xml *.xiz *.lv2", tr("My Presets"),
|
||||
embed::getIconPixmap("preset_file").transformed(QTransform().rotate(90)), splitter, false,
|
||||
confMgr->userPresetsDir(), confMgr->factoryPresetsDir()));
|
||||
|
||||
sideBar->appendTab(new FileBrowser(FileBrowser::Type::Normal, QDir::homePath(), FileItem::defaultFilters(),
|
||||
tr("My Home"), embed::getIconPixmap("home").transformed(QTransform().rotate(90)), splitter, false));
|
||||
|
||||
QStringList root_paths;
|
||||
QString title = tr("Root Directory");
|
||||
@@ -156,7 +153,7 @@ MainWindow::MainWindow() :
|
||||
}
|
||||
#endif
|
||||
|
||||
sideBar->appendTab(new FileBrowser(root_paths.join("*"), FileItem::defaultFilters(), title,
|
||||
sideBar->appendTab(new FileBrowser(FileBrowser::Type::Normal, root_paths.join("*"), FileItem::defaultFilters(), title,
|
||||
embed::getIconPixmap("computer").transformed(QTransform().rotate(90)), splitter, dirs_as_items));
|
||||
|
||||
m_workspace = new MovableQMdiArea(splitter);
|
||||
|
||||
Reference in New Issue
Block a user