Compare commits
3 Commits
74094447b9
...
0da199e00e
Author | SHA1 | Date |
---|---|---|
Skulking Scavenger | 0da199e00e | |
Clementine Buildbot | f76dbffa6b | |
Klaus von Nachtstein | 933d7da3ee |
|
@ -1241,6 +1241,7 @@ void Playlist::UpdateItems(const SongList& songs) {
|
|||
}
|
||||
}
|
||||
}
|
||||
connect(backend_,SIGNAL(PlaylistSaved(int)),SIGNAL(PlaylistSongsLoaded(int)));
|
||||
Save();
|
||||
}
|
||||
|
||||
|
|
|
@ -373,6 +373,9 @@ class Playlist : public QAbstractListModel {
|
|||
// Signals that the queue has changed, meaning that the remaining queued
|
||||
// items should update their position.
|
||||
void QueueChanged();
|
||||
// Signals that the playlist has finished asynchronously loading songs
|
||||
// the playlist can now be safely processed or closed
|
||||
void PlaylistSongsLoaded(int id);
|
||||
|
||||
private:
|
||||
void SetCurrentIsPaused(bool paused);
|
||||
|
|
|
@ -343,6 +343,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
|
|||
if (db_->CheckErrors(update)) return;
|
||||
|
||||
transaction.Commit();
|
||||
emit PlaylistSaved(playlist);
|
||||
}
|
||||
|
||||
int PlaylistBackend::CreatePlaylist(const QString& name,
|
||||
|
|
|
@ -79,7 +79,9 @@ class PlaylistBackend : public QObject {
|
|||
public slots:
|
||||
void SavePlaylist(int playlist, const PlaylistItemList& items,
|
||||
int last_played, smart_playlists::GeneratorPtr dynamic);
|
||||
|
||||
signals:
|
||||
void PlaylistSaved(int id);
|
||||
|
||||
private:
|
||||
struct NewSongFromQueryState {
|
||||
QHash<QString, SongList> cached_cues_;
|
||||
|
|
|
@ -24,16 +24,22 @@
|
|||
#include <QPainter>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStandardItemModel>
|
||||
#include <QFileDialog>
|
||||
#include <QDirIterator>
|
||||
#include <iostream>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/player.h"
|
||||
#include "core/utilities.h"
|
||||
#include "playlist.h"
|
||||
#include "playlistlistmodel.h"
|
||||
#include "playlistmanager.h"
|
||||
#include "ui/iconloader.h"
|
||||
#include "ui_playlistlistcontainer.h"
|
||||
#include "playlistparsers/playlistparser.h"
|
||||
|
||||
const char* PlaylistListContainer::kSettingsGroup = "PlaylistList";
|
||||
|
||||
/* This filter proxy will:
|
||||
- Accept all ancestors if at least a single child matches
|
||||
|
@ -146,6 +152,7 @@ PlaylistListContainer::PlaylistListContainer(QWidget* parent)
|
|||
action_new_folder_(new QAction(this)),
|
||||
action_remove_(new QAction(this)),
|
||||
action_save_playlist_(new QAction(this)),
|
||||
action_bulk_import_playlists_(new QAction(this)),
|
||||
model_(new PlaylistListModel(this)),
|
||||
proxy_(new PlaylistListFilterProxyModel(this)),
|
||||
loaded_icons_(false),
|
||||
|
@ -158,16 +165,20 @@ PlaylistListContainer::PlaylistListContainer(QWidget* parent)
|
|||
action_remove_->setText(tr("Delete"));
|
||||
action_save_playlist_->setText(
|
||||
tr("Save playlist", "Save playlist menu action."));
|
||||
action_bulk_import_playlists_->setText(tr("Bulk Import Playlists"));
|
||||
|
||||
ui_->new_folder->setDefaultAction(action_new_folder_);
|
||||
ui_->remove->setDefaultAction(action_remove_);
|
||||
ui_->save_playlist->setDefaultAction(action_save_playlist_);
|
||||
ui_->bulk_import_playlists->setDefaultAction(action_bulk_import_playlists_);
|
||||
|
||||
|
||||
connect(action_new_folder_, SIGNAL(triggered()), SLOT(NewFolderClicked()));
|
||||
connect(action_remove_, SIGNAL(triggered()), SLOT(DeleteClicked()));
|
||||
connect(action_save_playlist_, SIGNAL(triggered()), SLOT(SavePlaylist()));
|
||||
connect(model_, SIGNAL(PlaylistPathChanged(int, QString)),
|
||||
SLOT(PlaylistPathChanged(int, QString)));
|
||||
connect(action_bulk_import_playlists_, SIGNAL(triggered()), SLOT(BulkImportPlaylists()));
|
||||
|
||||
proxy_->setSourceModel(model_);
|
||||
proxy_->setDynamicSortFilter(true);
|
||||
|
@ -182,6 +193,9 @@ PlaylistListContainer::PlaylistListContainer(QWidget* parent)
|
|||
|
||||
connect(ui_->search, SIGNAL(textChanged(QString)),
|
||||
SLOT(SearchTextEdited(QString)));
|
||||
|
||||
//access to global settings using the QSettings object. Use this to get data about last opened folder etc.
|
||||
settings_.beginGroup(kSettingsGroup);
|
||||
}
|
||||
|
||||
PlaylistListContainer::~PlaylistListContainer() { delete ui_; }
|
||||
|
@ -198,6 +212,8 @@ void PlaylistListContainer::showEvent(QShowEvent* e) {
|
|||
action_remove_->setIcon(IconLoader::Load("edit-delete", IconLoader::Base));
|
||||
action_save_playlist_->setIcon(
|
||||
IconLoader::Load("document-save", IconLoader::Base));
|
||||
action_bulk_import_playlists_->setIcon(
|
||||
IconLoader::Load("document-open-folder", IconLoader::Base));
|
||||
|
||||
model_->SetIcons(IconLoader::Load("view-media-playlist", IconLoader::Base),
|
||||
IconLoader::Load("folder", IconLoader::Base));
|
||||
|
@ -330,6 +346,86 @@ void PlaylistListContainer::SavePlaylist() {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Open filepicker and Use QDirIterator to recursively find subdirectories
|
||||
within the chosen directory. create an empty
|
||||
*/
|
||||
void PlaylistListContainer::BulkImportPlaylists() {
|
||||
QString base_path(settings_.value("last_path", Utilities::GetConfigPath(
|
||||
Utilities::Path_DefaultMusicLibrary)).toString());
|
||||
base_path = QFileDialog::getExistingDirectory(this, tr("Add directory..."), base_path);
|
||||
|
||||
if (base_path.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Create Root Folder
|
||||
QFileInfo child_info(base_path);
|
||||
QStandardItem* root_folder = model_->NewFolder(child_info.fileName());
|
||||
model_->invisibleRootItem()->appendRow(root_folder);
|
||||
|
||||
bulk_imported_id_list_ = new QList<int>();
|
||||
bulk_imported_count_ = 0;
|
||||
|
||||
RecursivelyCreateSubfolders(root_folder, base_path, child_info.baseName());
|
||||
|
||||
settings_.setValue("last_path", base_path);
|
||||
}
|
||||
|
||||
void PlaylistListContainer::RecursivelyCreateSubfolders(QStandardItem* parent_folder, QString path, QString ui_path){
|
||||
QStringList filters;
|
||||
filters = app_->playlist_manager()->parser()->file_extensions();
|
||||
for(int i=0; i<filters.count(); i++){
|
||||
filters[i] = "*." + filters[i];
|
||||
}
|
||||
|
||||
QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot);
|
||||
while(it.hasNext()) {
|
||||
QString child(it.next());
|
||||
QFileInfo child_info(child);
|
||||
if (child_info.isDir()) {
|
||||
QStandardItem* folder = model_->NewFolder(child_info.fileName());
|
||||
parent_folder->appendRow(folder);
|
||||
RecursivelyCreateSubfolders(folder, child_info.absoluteFilePath(), ui_path + "/" + child_info.baseName());
|
||||
}else if(child_info.isFile()){
|
||||
if(QDir::match(filters, child_info.fileName())){
|
||||
bulk_imported_count_++;
|
||||
int id = app_->playlist_manager()->LoadBulkPlaylists(child, ui_path);
|
||||
Playlist* playlist = app_->playlist_manager()->playlist(id);
|
||||
connect(playlist, SIGNAL(PlaylistSongsLoaded(int)), SLOT(BulkImportPlaylistsCallback(int)));
|
||||
PlaylistPathChanged(id, ui_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* After the bulk imported playlist has asynchronously had its songs
|
||||
* loaded, add it to the list of finished playlists
|
||||
* once the quota has been filled, close the temporary tabs
|
||||
*/
|
||||
void PlaylistListContainer::BulkImportPlaylistsCallback (int id){
|
||||
if(bulk_imported_count_ == 0){
|
||||
return;
|
||||
}
|
||||
if(bulk_imported_id_list_->contains(id)){
|
||||
return;
|
||||
}
|
||||
app_->playlist_manager()->BulkImportPlaylistsCallback(id);
|
||||
const QString& name = app_->playlist_manager()->GetPlaylistName(id);
|
||||
AddPlaylist(id, name, true);
|
||||
bulk_imported_id_list_->append(id);
|
||||
if(bulk_imported_id_list_->count() == bulk_imported_count_){
|
||||
//clean up tabs
|
||||
for(qsizetype i =0; i < bulk_imported_id_list_->count(); i++){
|
||||
app_->playlist_manager()->Close(bulk_imported_id_list_->at(i));
|
||||
}
|
||||
app_->playlist_manager()->ChangePlaylistOrder(app_->playlist_manager()->GetAllPlaylistIds());
|
||||
bulk_imported_count_ = 0;
|
||||
bulk_imported_id_list_ = new QList<int>();
|
||||
}
|
||||
}
|
||||
|
||||
void PlaylistListContainer::PlaylistFavoriteStateChanged(int id,
|
||||
bool favorite) {
|
||||
if (favorite) {
|
||||
|
@ -473,6 +569,7 @@ void PlaylistListContainer::contextMenuEvent(QContextMenuEvent* e) {
|
|||
menu_->addAction(action_remove_);
|
||||
menu_->addSeparator();
|
||||
menu_->addAction(action_save_playlist_);
|
||||
menu_->addAction(action_bulk_import_playlists_);
|
||||
}
|
||||
menu_->popup(e->globalPos());
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef PLAYLISTLISTCONTAINER_H
|
||||
#define PLAYLISTLISTCONTAINER_H
|
||||
|
||||
#include <QSettings>
|
||||
#include <QWidget>
|
||||
|
||||
#include "playlistbackend.h"
|
||||
|
@ -42,6 +43,8 @@ class PlaylistListContainer : public QWidget {
|
|||
|
||||
void SetApplication(Application* app);
|
||||
|
||||
static const char* kSettingsGroup;
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* e);
|
||||
void contextMenuEvent(QContextMenuEvent* e);
|
||||
|
@ -63,6 +66,9 @@ class PlaylistListContainer : public QWidget {
|
|||
const QString* ui_path = nullptr);
|
||||
void RemovePlaylist(int id);
|
||||
void SavePlaylist();
|
||||
void BulkImportPlaylists();
|
||||
void RecursivelyCreateSubfolders(QStandardItem* parent_folder, QString path, QString ui_path);
|
||||
void BulkImportPlaylistsCallback (int id);
|
||||
void PlaylistFavoriteStateChanged(int id, bool favorite);
|
||||
void CurrentChanged(Playlist* new_playlist);
|
||||
void ActiveChanged(Playlist* new_playlist);
|
||||
|
@ -89,6 +95,7 @@ class PlaylistListContainer : public QWidget {
|
|||
QAction* action_new_folder_;
|
||||
QAction* action_remove_;
|
||||
QAction* action_save_playlist_;
|
||||
QAction* action_bulk_import_playlists_;
|
||||
|
||||
PlaylistListModel* model_;
|
||||
PlaylistListFilterProxyModel* proxy_;
|
||||
|
@ -97,6 +104,12 @@ class PlaylistListContainer : public QWidget {
|
|||
QIcon padded_play_icon_;
|
||||
|
||||
int active_playlist_id_;
|
||||
|
||||
QSettings settings_;
|
||||
|
||||
QList<int>* bulk_imported_id_list_;
|
||||
int bulk_imported_count_;
|
||||
int debug_count_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTLISTCONTAINER_H
|
||||
|
|
|
@ -72,6 +72,13 @@
|
|||
<item>
|
||||
<widget class="QToolButton" name="save_playlist"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="bulk_import_playlists">
|
||||
<property name="toolTip">
|
||||
<string>Bulk Import Playlists</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
|
|
|
@ -101,6 +101,16 @@ QList<Playlist*> PlaylistManager::GetAllPlaylists() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
QList<int> PlaylistManager::GetAllPlaylistIds() const {
|
||||
QList<int> result;
|
||||
|
||||
for (const int data : playlists_.keys()) {
|
||||
result.append(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QItemSelection PlaylistManager::selection(int id) const {
|
||||
QMap<int, Data>::const_iterator it = playlists_.find(id);
|
||||
return it->selection;
|
||||
|
@ -196,6 +206,35 @@ void PlaylistManager::Save(int id, const QString& filename,
|
|||
}
|
||||
}
|
||||
|
||||
int PlaylistManager::LoadBulkPlaylists(const QString& filename, const QString& ui_path){
|
||||
QFileInfo info(filename);
|
||||
|
||||
int id = playlist_backend_->CreatePlaylist(info.baseName(), QString());
|
||||
|
||||
if (id == -1) {
|
||||
emit Error(tr("Couldn't create playlist"));
|
||||
return id;
|
||||
}
|
||||
|
||||
Playlist* playlist =
|
||||
AddPlaylist(id, info.baseName(), QString(), ui_path, false);
|
||||
|
||||
QList<QUrl> urls;
|
||||
playlist->InsertUrls(urls << QUrl::fromLocalFile(filename));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void PlaylistManager::BulkImportPlaylistsCallback(int id){
|
||||
if (playlists_.contains(id)) {
|
||||
// If playlists_ contains this playlist, its means it's opened: star or
|
||||
// unstar it.
|
||||
bool favorite = true;
|
||||
playlist_backend_->FavoritePlaylist(id, favorite);
|
||||
playlists_[id].p->set_favorite(favorite);
|
||||
}
|
||||
}
|
||||
|
||||
void PlaylistManager::ItemsLoadedForSavePlaylist(QFuture<SongList> future,
|
||||
const QString& filename,
|
||||
Playlist::Path path_type) {
|
||||
|
|
|
@ -55,6 +55,7 @@ class PlaylistManagerInterface : public QObject {
|
|||
|
||||
// Returns the collection of playlists managed by this PlaylistManager.
|
||||
virtual QList<Playlist*> GetAllPlaylists() const = 0;
|
||||
virtual QList<int> GetAllPlaylistIds() const = 0;
|
||||
// Grays out and reloads all deleted songs in all playlists.
|
||||
virtual void InvalidateDeletedSongs() = 0;
|
||||
// Removes all deleted songs from all playlists.
|
||||
|
@ -151,6 +152,7 @@ class PlaylistManager : public PlaylistManagerInterface {
|
|||
|
||||
// Returns the collection of playlists managed by this PlaylistManager.
|
||||
QList<Playlist*> GetAllPlaylists() const;
|
||||
QList<int> GetAllPlaylistIds() const;
|
||||
// Grays out and reloads all deleted songs in all playlists.
|
||||
void InvalidateDeletedSongs();
|
||||
// Removes all deleted songs from all playlists.
|
||||
|
@ -185,6 +187,8 @@ class PlaylistManager : public PlaylistManagerInterface {
|
|||
const QString& special_type = QString());
|
||||
void Load(const QString& filename);
|
||||
void Save(int id, const QString& filename, Playlist::Path path_type);
|
||||
int LoadBulkPlaylists(const QString& filename, const QString& ui_path);
|
||||
void BulkImportPlaylistsCallback(int id);
|
||||
// Display a file dialog to let user choose a file before saving the file
|
||||
void SaveWithUI(int id, const QString& playlist_name);
|
||||
void Rename(int id, const QString& new_name);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
# Martin Brodbeck <martin@brodbeck-online.de>, 2013
|
||||
# Martin Herkt <lachs0r@hong-mailing.de>, 2011
|
||||
# Martin Herkt <luck3r@phicode.de>, 2010
|
||||
# Michael Kohler, 2024
|
||||
# MCMicS, 2020
|
||||
# Mohamed Sakhri, 2013
|
||||
# Mohamed Sakhri, 2013
|
||||
|
@ -70,7 +71,7 @@ msgstr ""
|
|||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-04-09 10:24+0000\n"
|
||||
"PO-Revision-Date: 2011-10-27 18:53+0000\n"
|
||||
"Last-Translator: 6543 <6543@obermui.de>, 2020\n"
|
||||
"Last-Translator: Michael Kohler, 2024\n"
|
||||
"Language-Team: German (http://app.transifex.com/davidsansome/clementine/language/de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
@ -219,7 +220,7 @@ msgid "1 track"
|
|||
msgstr "1 Titel"
|
||||
|
||||
msgid "128K MP3"
|
||||
msgstr ""
|
||||
msgstr "128K MP3"
|
||||
|
||||
msgid "128k MP3"
|
||||
msgstr "128k MP3"
|
||||
|
@ -240,7 +241,7 @@ msgid "A Grooveshark Anywhere account is required."
|
|||
msgstr ""
|
||||
|
||||
msgid "A Spotify Premium account is required."
|
||||
msgstr ""
|
||||
msgstr "Spotify Premium Zugang wird benötigt."
|
||||
|
||||
msgid ""
|
||||
"A smart playlist is a dynamic list of songs that come from your library. "
|
||||
|
@ -293,7 +294,7 @@ msgid "Action"
|
|||
msgstr "Aktion"
|
||||
|
||||
msgid "Active/deactive Wiiremote"
|
||||
msgstr ""
|
||||
msgstr "Aktivieren/deaktivieren Wiiremote"
|
||||
|
||||
msgid "Add Stream"
|
||||
msgstr "Datenstrom hinzufügen"
|
||||
|
@ -326,7 +327,7 @@ msgid "Add folder..."
|
|||
msgstr "Ordner hinzufügen …"
|
||||
|
||||
msgid "Add media"
|
||||
msgstr ""
|
||||
msgstr "Medien hinzufügen ..."
|
||||
|
||||
msgid "Add new folder..."
|
||||
msgstr "Neuen Ordner hinzufügen …"
|
||||
|
@ -386,7 +387,7 @@ msgid "Add wiimotedev action"
|
|||
msgstr "Aktion für Wii-Fernbedienung hinzufügen"
|
||||
|
||||
msgid "Add..."
|
||||
msgstr ""
|
||||
msgstr "Hinzufügen …"
|
||||
|
||||
msgid "Added this month"
|
||||
msgstr "Diesen Monat hinzugefügt"
|
||||
|
@ -422,7 +423,7 @@ msgid "Album info on jamendo.com..."
|
|||
msgstr "Albuminformationen auf jamendo.com …"
|
||||
|
||||
msgid "Albumartist"
|
||||
msgstr ""
|
||||
msgstr "Albumkünstler"
|
||||
|
||||
msgid "Albums with covers"
|
||||
msgstr "Alben mit Titelbildern"
|
||||
|
@ -633,7 +634,7 @@ msgid "CUE sheet support"
|
|||
msgstr "Unterstützung von Cuesheets"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Abbrechen"
|
||||
|
||||
msgid "Change cover art"
|
||||
msgstr "Titelbilder ändern"
|
||||
|
|
Loading…
Reference in New Issue