2010-03-24 00:11:46 +01:00
|
|
|
/* This file is part of Clementine.
|
2010-11-20 14:27:10 +01:00
|
|
|
Copyright 2010, David Sansome <me@davidsansome.com>
|
2010-03-24 00:11:46 +01:00
|
|
|
|
|
|
|
Clementine is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Clementine is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
#include "mainwindow.h"
|
2014-02-06 14:48:00 +01:00
|
|
|
|
|
|
|
#include <QCloseEvent>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QFileSystemModel>
|
|
|
|
#include <QLinearGradient>
|
2021-05-30 14:23:37 +02:00
|
|
|
#include <QList>
|
2014-02-06 14:48:00 +01:00
|
|
|
#include <QMenu>
|
|
|
|
#include <QMessageBox>
|
2018-11-29 22:32:12 +01:00
|
|
|
#include <QPainter>
|
2014-02-06 14:48:00 +01:00
|
|
|
#include <QSettings>
|
|
|
|
#include <QShortcut>
|
|
|
|
#include <QSortFilterProxyModel>
|
|
|
|
#include <QStatusBar>
|
2018-10-01 10:40:31 +02:00
|
|
|
#include <QSystemTrayIcon>
|
2014-02-06 14:48:00 +01:00
|
|
|
#include <QTimer>
|
|
|
|
#include <QUndoStack>
|
2017-01-11 19:08:43 +01:00
|
|
|
#include <QtDebug>
|
2020-09-18 16:15:19 +02:00
|
|
|
#include <cmath>
|
|
|
|
#include <memory>
|
2014-02-06 14:48:00 +01:00
|
|
|
|
2012-01-09 20:08:09 +01:00
|
|
|
#include "core/appearance.h"
|
2012-02-12 14:41:50 +01:00
|
|
|
#include "core/application.h"
|
2010-12-03 14:53:43 +01:00
|
|
|
#include "core/backgroundstreams.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "core/commandlineoptions.h"
|
|
|
|
#include "core/database.h"
|
2010-12-11 11:54:42 +01:00
|
|
|
#include "core/deletefiles.h"
|
2012-11-10 08:24:59 +01:00
|
|
|
#include "core/filesystemmusicstorage.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "core/globalshortcuts.h"
|
2011-04-22 18:50:29 +02:00
|
|
|
#include "core/logging.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "core/mac_startup.h"
|
|
|
|
#include "core/mergedproxymodel.h"
|
2011-01-10 23:26:13 +01:00
|
|
|
#include "core/mimedata.h"
|
2010-12-06 00:41:41 +01:00
|
|
|
#include "core/mpris_common.h"
|
2010-12-30 17:20:33 +01:00
|
|
|
#include "core/network.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "core/player.h"
|
2010-06-15 20:24:08 +02:00
|
|
|
#include "core/songloader.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "core/stylesheetloader.h"
|
2010-06-23 15:21:30 +02:00
|
|
|
#include "core/taskmanager.h"
|
2013-02-17 19:28:11 +01:00
|
|
|
#include "core/timeconstants.h"
|
2011-03-17 20:52:21 +01:00
|
|
|
#include "core/utilities.h"
|
2010-06-26 14:41:18 +02:00
|
|
|
#include "devices/devicemanager.h"
|
2010-08-08 15:06:52 +02:00
|
|
|
#include "devices/devicestatefiltermodel.h"
|
2010-10-01 21:27:01 +02:00
|
|
|
#include "devices/deviceview.h"
|
2014-01-05 01:32:07 +01:00
|
|
|
#include "devices/deviceviewcontainer.h"
|
2010-04-04 19:50:11 +02:00
|
|
|
#include "engines/enginebase.h"
|
2010-12-26 14:01:35 +01:00
|
|
|
#include "engines/gstengine.h"
|
2011-09-24 15:44:23 +02:00
|
|
|
#include "globalsearch/globalsearch.h"
|
2012-06-04 19:18:37 +02:00
|
|
|
#include "globalsearch/globalsearchview.h"
|
2011-09-24 15:44:23 +02:00
|
|
|
#include "globalsearch/librarysearchprovider.h"
|
2014-12-18 23:35:21 +01:00
|
|
|
#include "internet/core/internetmodel.h"
|
|
|
|
#include "internet/core/internetview.h"
|
|
|
|
#include "internet/core/internetviewcontainer.h"
|
|
|
|
#include "internet/internetradio/savedradio.h"
|
2017-01-11 19:08:43 +01:00
|
|
|
#include "internet/magnatune/magnatuneservice.h"
|
|
|
|
#include "internet/podcasts/podcastservice.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "library/groupbydialog.h"
|
2010-10-01 21:27:01 +02:00
|
|
|
#include "library/library.h"
|
2010-08-31 23:24:57 +02:00
|
|
|
#include "library/librarybackend.h"
|
2010-06-24 19:34:23 +02:00
|
|
|
#include "library/librarydirectorymodel.h"
|
2010-10-01 21:27:01 +02:00
|
|
|
#include "library/libraryfilterwidget.h"
|
|
|
|
#include "library/libraryviewcontainer.h"
|
2011-03-12 22:19:41 +01:00
|
|
|
#include "musicbrainz/tagfetcher.h"
|
2013-12-22 15:16:42 +01:00
|
|
|
#include "networkremote/networkremote.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "playlist/playlist.h"
|
2017-01-11 19:08:43 +01:00
|
|
|
#include "playlist/playlistbackend.h"
|
2012-10-31 07:04:22 +01:00
|
|
|
#include "playlist/playlistlistcontainer.h"
|
2010-05-20 23:21:55 +02:00
|
|
|
#include "playlist/playlistmanager.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "playlist/playlistsequence.h"
|
2010-05-20 16:12:15 +02:00
|
|
|
#include "playlist/playlistview.h"
|
2010-07-11 17:37:40 +02:00
|
|
|
#include "playlist/queue.h"
|
|
|
|
#include "playlist/queuemanager.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "playlist/songplaylistitem.h"
|
2010-05-22 22:06:19 +02:00
|
|
|
#include "playlistparsers/playlistparser.h"
|
2020-09-18 16:15:19 +02:00
|
|
|
#include "ui_mainwindow.h"
|
2015-02-18 20:05:35 +01:00
|
|
|
#ifdef HAVE_AUDIOCD
|
|
|
|
#include "ripper/ripcddialog.h"
|
|
|
|
#endif
|
2010-12-04 17:19:30 +01:00
|
|
|
#include "smartplaylists/generator.h"
|
2011-01-10 23:26:13 +01:00
|
|
|
#include "smartplaylists/generatormimedata.h"
|
2010-10-02 18:23:33 +02:00
|
|
|
#include "songinfo/artistinfoview.h"
|
2010-10-10 18:09:20 +02:00
|
|
|
#include "songinfo/songinfoview.h"
|
2016-12-21 17:57:04 +01:00
|
|
|
#include "songinfo/streamdiscoverer.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "transcoder/transcodedialog.h"
|
|
|
|
#include "ui/about.h"
|
|
|
|
#include "ui/addstreamdialog.h"
|
2011-04-27 21:10:37 +02:00
|
|
|
#include "ui/albumcovermanager.h"
|
2012-09-26 18:36:47 +02:00
|
|
|
#include "ui/console.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "ui/edittagdialog.h"
|
|
|
|
#include "ui/equalizer.h"
|
2010-05-19 17:45:29 +02:00
|
|
|
#include "ui/iconloader.h"
|
2020-09-18 16:15:19 +02:00
|
|
|
#include "ui/lovedialog.h"
|
2010-06-24 18:26:49 +02:00
|
|
|
#include "ui/organisedialog.h"
|
2010-12-11 11:54:42 +01:00
|
|
|
#include "ui/organiseerrordialog.h"
|
2010-06-24 18:26:49 +02:00
|
|
|
#include "ui/qtsystemtrayicon.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "ui/settingsdialog.h"
|
2016-12-21 17:57:04 +01:00
|
|
|
#include "ui/streamdetailsdialog.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "ui/systemtrayicon.h"
|
2011-03-06 15:07:41 +01:00
|
|
|
#include "ui/trackselectiondialog.h"
|
2011-01-16 01:39:51 +01:00
|
|
|
#include "ui/windows7thumbbar.h"
|
2011-01-24 21:45:15 +01:00
|
|
|
#include "version.h"
|
2010-05-31 22:49:44 +02:00
|
|
|
#include "widgets/errordialog.h"
|
2010-10-01 21:27:01 +02:00
|
|
|
#include "widgets/fileview.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "widgets/multiloadingindicator.h"
|
|
|
|
#include "widgets/osd.h"
|
2010-10-10 16:04:05 +02:00
|
|
|
#include "widgets/stylehelper.h"
|
2010-05-10 23:50:31 +02:00
|
|
|
#include "widgets/trackslider.h"
|
|
|
|
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef Q_OS_DARWIN
|
2014-02-07 16:34:20 +01:00
|
|
|
#include "ui/macsystemtrayicon.h"
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBLASTFM
|
2014-12-18 23:35:21 +01:00
|
|
|
#include "internet/lastfm/lastfmservice.h"
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
|
|
|
|
2011-03-12 22:19:32 +01:00
|
|
|
#ifdef HAVE_WIIMOTEDEV
|
2014-02-07 16:34:20 +01:00
|
|
|
#include "wiimotedev/shortcuts.h"
|
2010-08-23 19:42:51 +02:00
|
|
|
#endif
|
|
|
|
|
2018-11-29 22:32:12 +01:00
|
|
|
#ifdef HAVE_VISUALISATIONS
|
2014-02-07 16:34:20 +01:00
|
|
|
#include "visualisations/visualisationcontainer.h"
|
2010-06-11 00:48:23 +02:00
|
|
|
#endif
|
|
|
|
|
2012-05-27 22:15:58 +02:00
|
|
|
#ifdef HAVE_MOODBAR
|
2014-02-07 16:34:20 +01:00
|
|
|
#include "moodbar/moodbarcontroller.h"
|
|
|
|
#include "moodbar/moodbarproxystyle.h"
|
2012-05-27 22:15:58 +02:00
|
|
|
#endif
|
|
|
|
|
2018-10-05 17:19:05 +02:00
|
|
|
#include <algorithm>
|
2009-12-29 20:57:33 +01:00
|
|
|
#include <cmath>
|
|
|
|
|
2014-09-21 11:35:43 +02:00
|
|
|
#ifdef Q_OS_DARWIN
|
2010-04-14 21:38:09 +02:00
|
|
|
// Non exported mac-specific function.
|
|
|
|
void qt_mac_set_dock_menu(QMenu*);
|
|
|
|
#endif
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
const char* MainWindow::kSettingsGroup = "MainWindow";
|
2014-02-07 16:34:20 +01:00
|
|
|
const char* MainWindow::kAllFilesFilterSpec = QT_TR_NOOP("All Files (*)");
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2014-05-20 13:44:30 +02:00
|
|
|
namespace {
|
2016-10-11 00:10:56 +02:00
|
|
|
const int kTrackSliderUpdateTimeMs = 500;
|
2014-08-18 17:56:01 +02:00
|
|
|
const int kTrackPositionUpdateTimeMs = 1000;
|
2020-09-18 16:15:19 +02:00
|
|
|
} // namespace
|
2014-05-20 13:44:30 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
2016-04-12 16:53:43 +02:00
|
|
|
const CommandlineOptions& options, QWidget* parent)
|
2014-02-07 16:34:20 +01:00
|
|
|
: QMainWindow(parent),
|
|
|
|
ui_(new Ui_MainWindow),
|
|
|
|
thumbbar_(new Windows7ThumbBar(this)),
|
|
|
|
app_(app),
|
|
|
|
tray_icon_(tray_icon),
|
|
|
|
osd_(osd),
|
2016-02-12 14:15:45 +01:00
|
|
|
edit_tag_dialog_(std::bind(&MainWindow::CreateEditTagDialog, this)),
|
2020-07-26 20:38:14 +02:00
|
|
|
love_dialog_(std::bind(&MainWindow::CreateLoveDialog, this)),
|
2016-12-21 17:57:04 +01:00
|
|
|
stream_discoverer_(std::bind(&MainWindow::CreateStreamDiscoverer, this)),
|
2020-12-29 10:05:10 +01:00
|
|
|
debug_console_(std::bind(&MainWindow::CreateDebugConsole, this)),
|
2014-02-07 16:34:20 +01:00
|
|
|
global_shortcuts_(new GlobalShortcuts(this)),
|
|
|
|
global_search_view_(new GlobalSearchView(app_, this)),
|
|
|
|
library_view_(new LibraryViewContainer(this)),
|
|
|
|
file_view_(new FileView(this)),
|
|
|
|
playlist_list_(new PlaylistListContainer(this)),
|
|
|
|
internet_view_(new InternetViewContainer(this)),
|
|
|
|
device_view_container_(new DeviceViewContainer(this)),
|
|
|
|
device_view_(device_view_container_->view()),
|
|
|
|
song_info_view_(new SongInfoView(this)),
|
|
|
|
artist_info_view_(new ArtistInfoView(this)),
|
2016-02-12 14:15:45 +01:00
|
|
|
settings_dialog_(std::bind(&MainWindow::CreateSettingsDialog, this)),
|
2016-02-12 17:10:24 +01:00
|
|
|
add_stream_dialog_([=]() {
|
|
|
|
AddStreamDialog* add_stream_dialog = new AddStreamDialog;
|
|
|
|
connect(add_stream_dialog, SIGNAL(accepted()), this,
|
|
|
|
SLOT(AddStreamAccepted()));
|
|
|
|
add_stream_dialog->set_add_on_accept(
|
|
|
|
InternetModel::Service<SavedRadio>());
|
|
|
|
return add_stream_dialog;
|
|
|
|
}),
|
|
|
|
cover_manager_([=]() {
|
|
|
|
AlbumCoverManager* cover_manager =
|
|
|
|
new AlbumCoverManager(app, app->library_backend());
|
|
|
|
cover_manager->Init();
|
|
|
|
|
|
|
|
// Cover manager connections
|
|
|
|
connect(cover_manager, SIGNAL(AddToPlaylist(QMimeData*)), this,
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
|
|
|
return cover_manager;
|
|
|
|
}),
|
2014-02-07 16:34:20 +01:00
|
|
|
equalizer_(new Equalizer),
|
2016-02-12 13:25:35 +01:00
|
|
|
organise_dialog_([=]() {
|
2020-09-18 16:15:19 +02:00
|
|
|
OrganiseDialog* dialog =
|
|
|
|
new OrganiseDialog(app->task_manager(), app->library_backend());
|
2020-02-11 00:38:57 +01:00
|
|
|
dialog->SetDestinationModel(app->directory_model());
|
2016-02-12 13:25:35 +01:00
|
|
|
return dialog;
|
|
|
|
}),
|
2016-02-12 17:10:24 +01:00
|
|
|
queue_manager_([=]() {
|
|
|
|
QueueManager* manager = new QueueManager;
|
|
|
|
manager->SetPlaylistManager(app->playlist_manager());
|
|
|
|
return manager;
|
|
|
|
}),
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_menu_(new QMenu(this)),
|
|
|
|
playlist_add_to_another_(nullptr),
|
|
|
|
playlistitem_actions_separator_(nullptr),
|
|
|
|
library_sort_model_(new QSortFilterProxyModel(this)),
|
|
|
|
track_position_timer_(new QTimer(this)),
|
2014-05-19 17:51:40 +02:00
|
|
|
track_slider_timer_(new QTimer(this)),
|
2018-11-28 21:08:23 +01:00
|
|
|
initialized_(false),
|
2019-09-07 06:02:48 +02:00
|
|
|
dirty_geometry_(false),
|
|
|
|
dirty_playback_(false),
|
2014-02-07 16:34:20 +01:00
|
|
|
saved_playback_position_(0),
|
|
|
|
saved_playback_state_(Engine::Empty),
|
|
|
|
doubleclick_addmode_(AddBehaviour_Append),
|
|
|
|
doubleclick_playmode_(PlayBehaviour_IfStopped),
|
|
|
|
menu_playmode_(PlayBehaviour_IfStopped) {
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Starting";
|
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(app, SIGNAL(ErrorAdded(QString)), SLOT(ShowErrorDialog(QString)));
|
2012-03-10 23:39:24 +01:00
|
|
|
connect(app, SIGNAL(SettingsDialogRequested(SettingsDialog::Page)),
|
|
|
|
SLOT(OpenSettingsDialogAtPage(SettingsDialog::Page)));
|
2011-01-19 16:36:40 +01:00
|
|
|
|
2010-06-02 17:58:07 +02:00
|
|
|
// Initialise the UI
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->setupUi(this);
|
2012-02-06 18:00:17 +01:00
|
|
|
#ifdef Q_OS_DARWIN
|
|
|
|
ui_->menu_help->menuAction()->setVisible(false);
|
|
|
|
#endif
|
2012-02-06 17:32:13 +01:00
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
ui_->multi_loading_indicator->SetTaskManager(app_->task_manager());
|
|
|
|
ui_->now_playing->SetApplication(app_);
|
2010-11-21 22:36:27 +01:00
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
int volume = app_->player()->GetVolume();
|
2010-11-21 22:36:27 +01:00
|
|
|
ui_->volume->setValue(volume);
|
|
|
|
VolumeChanged(volume);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2011-08-28 22:33:59 +02:00
|
|
|
// Initialise the global search widget
|
|
|
|
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
|
2011-08-29 03:37:55 +02:00
|
|
|
|
2011-09-24 15:44:23 +02:00
|
|
|
// Add global search providers
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->global_search()->AddProvider(new LibrarySearchProvider(
|
|
|
|
app_->library_backend(), tr("Library"), "library",
|
2015-10-14 03:01:08 +02:00
|
|
|
IconLoader::Load("folder-sound", IconLoader::Base), true, app_, this));
|
2011-09-24 15:44:23 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_search_view_, SIGNAL(AddToPlaylist(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
2011-08-28 22:33:59 +02:00
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
// Set up the settings group early
|
|
|
|
settings_.beginGroup(kSettingsGroup);
|
|
|
|
|
2010-10-01 21:27:01 +02:00
|
|
|
// Add tabs to the fancy tab widget
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(global_search_view_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("search", IconLoader::Base),
|
2014-02-08 15:11:06 +01:00
|
|
|
tr("Search", "Global search settings dialog title."));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(library_view_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("folder-sound", IconLoader::Base),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("Library"));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(file_view_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("document-open", IconLoader::Base),
|
2015-10-14 03:01:08 +02:00
|
|
|
tr("Files"));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(playlist_list_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("view-media-playlist", IconLoader::Base),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("Playlists"));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(internet_view_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("applications-internet", IconLoader::Base),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("Internet"));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(
|
2015-12-20 18:25:45 +01:00
|
|
|
device_view_container_,
|
|
|
|
IconLoader::Load("multimedia-player-ipod-mini-blue", IconLoader::Base),
|
|
|
|
tr("Devices"));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addSpacer();
|
|
|
|
ui_->tabs->addTab(song_info_view_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("view-media-lyrics", IconLoader::Base),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("Song info"));
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addTab(artist_info_view_,
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("x-clementine-artist", IconLoader::Base),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("Artist info"));
|
2010-10-01 21:27:01 +02:00
|
|
|
|
2010-10-06 20:16:49 +02:00
|
|
|
// Add the now playing widget to the fancy tab widget
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->addBottomWidget(ui_->now_playing);
|
2010-10-06 20:16:49 +02:00
|
|
|
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->setBackgroundPixmap(QPixmap(":/sidebar_background.png"));
|
|
|
|
|
|
|
|
// Do this only after all default tabs have been added
|
2019-09-11 01:29:48 +02:00
|
|
|
ui_->tabs->loadSettings(settings_);
|
2010-10-01 21:27:01 +02:00
|
|
|
|
2014-05-20 13:44:30 +02:00
|
|
|
track_position_timer_->setInterval(kTrackPositionUpdateTimeMs);
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(track_position_timer_, SIGNAL(timeout()),
|
|
|
|
SLOT(UpdateTrackPosition()));
|
2014-05-20 13:44:30 +02:00
|
|
|
track_slider_timer_->setInterval(kTrackSliderUpdateTimeMs);
|
2014-05-19 17:51:40 +02:00
|
|
|
connect(track_slider_timer_, SIGNAL(timeout()),
|
|
|
|
SLOT(UpdateTrackSliderPosition()));
|
2009-12-29 20:57:33 +01:00
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
connect(app_, SIGNAL(SaveSettings(QSettings*)),
|
|
|
|
SLOT(SaveSettings(QSettings*)));
|
|
|
|
|
2010-02-04 00:12:21 +01:00
|
|
|
// Start initialising the player
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Initialising player";
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->Init();
|
|
|
|
background_streams_ = new BackgroundStreams(app_->player()->engine(), this);
|
2010-12-03 14:53:43 +01:00
|
|
|
background_streams_->LoadStreams();
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Models
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Creating models";
|
2012-02-12 14:41:50 +01:00
|
|
|
library_sort_model_->setSourceModel(app_->library()->model());
|
2010-05-09 02:10:26 +02:00
|
|
|
library_sort_model_->setSortRole(LibraryModel::Role_SortText);
|
2009-12-24 20:16:07 +01:00
|
|
|
library_sort_model_->setDynamicSortFilter(true);
|
2013-02-05 12:17:09 +01:00
|
|
|
library_sort_model_->setSortLocaleAware(true);
|
2009-12-24 20:16:07 +01:00
|
|
|
library_sort_model_->sort(0);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->playlist, SIGNAL(ViewSelectionModelChanged()),
|
|
|
|
SLOT(PlaylistViewSelectionModelChanged()));
|
2019-09-07 04:29:19 +02:00
|
|
|
ui_->playlist->SetApplication(app_);
|
2010-03-10 01:04:04 +01:00
|
|
|
|
2010-10-01 21:27:01 +02:00
|
|
|
library_view_->view()->setModel(library_sort_model_);
|
2012-02-12 14:41:50 +01:00
|
|
|
library_view_->view()->SetApplication(app_);
|
|
|
|
internet_view_->SetApplication(app_);
|
|
|
|
device_view_->SetApplication(app_);
|
2012-10-31 07:04:22 +01:00
|
|
|
playlist_list_->SetApplication(app_);
|
2009-12-26 16:13:38 +01:00
|
|
|
|
2010-05-19 17:45:29 +02:00
|
|
|
// Icons
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Creating UI";
|
2015-10-14 03:01:08 +02:00
|
|
|
ui_->action_about->setIcon(IconLoader::Load("help-about", IconLoader::Base));
|
|
|
|
ui_->action_about_qt->setIcon(IconLoader::Load("qtlogo", IconLoader::Base));
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_add_file->setIcon(
|
|
|
|
IconLoader::Load("document-open", IconLoader::Base));
|
|
|
|
ui_->action_add_folder->setIcon(
|
|
|
|
IconLoader::Load("document-open-folder", IconLoader::Base));
|
|
|
|
ui_->action_add_stream->setIcon(
|
|
|
|
IconLoader::Load("document-open-remote", IconLoader::Base));
|
|
|
|
ui_->action_add_podcast->setIcon(
|
|
|
|
IconLoader::Load("podcast", IconLoader::Provider));
|
|
|
|
ui_->action_clear_playlist->setIcon(
|
|
|
|
IconLoader::Load("edit-clear-list", IconLoader::Base));
|
|
|
|
ui_->action_configure->setIcon(
|
|
|
|
IconLoader::Load("configure", IconLoader::Base));
|
|
|
|
ui_->action_cover_manager->setIcon(
|
|
|
|
IconLoader::Load("download", IconLoader::Base));
|
|
|
|
ui_->action_edit_track->setIcon(
|
|
|
|
IconLoader::Load("edit-rename", IconLoader::Base));
|
|
|
|
ui_->action_equalizer->setIcon(
|
|
|
|
IconLoader::Load("view-media-equalizer", IconLoader::Base));
|
2015-10-14 03:01:08 +02:00
|
|
|
ui_->action_jump->setIcon(IconLoader::Load("go-jump", IconLoader::Base));
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_next_track->setIcon(
|
|
|
|
IconLoader::Load("media-skip-forward", IconLoader::Base));
|
2021-01-10 06:53:40 +01:00
|
|
|
ui_->action_next_album->setIcon(
|
|
|
|
IconLoader::Load("media-skip-forward", IconLoader::Base));
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_open_media->setIcon(
|
|
|
|
IconLoader::Load("document-open", IconLoader::Base));
|
|
|
|
ui_->action_open_cd->setIcon(
|
|
|
|
IconLoader::Load("media-optical", IconLoader::Base));
|
|
|
|
ui_->action_play_pause->setIcon(
|
|
|
|
IconLoader::Load("media-playback-start", IconLoader::Base));
|
|
|
|
ui_->action_previous_track->setIcon(
|
|
|
|
IconLoader::Load("media-skip-backward", IconLoader::Base));
|
|
|
|
ui_->action_mute->setIcon(
|
|
|
|
IconLoader::Load("audio-volume-muted", IconLoader::Base));
|
|
|
|
ui_->action_quit->setIcon(
|
|
|
|
IconLoader::Load("application-exit", IconLoader::Base));
|
|
|
|
ui_->action_remove_from_playlist->setIcon(
|
|
|
|
IconLoader::Load("list-remove", IconLoader::Base));
|
|
|
|
ui_->action_repeat_mode->setIcon(
|
|
|
|
IconLoader::Load("media-playlist-repeat", IconLoader::Base));
|
|
|
|
ui_->action_rip_audio_cd->setIcon(
|
|
|
|
IconLoader::Load("media-optical", IconLoader::Base));
|
|
|
|
ui_->action_shuffle->setIcon(
|
|
|
|
IconLoader::Load("x-clementine-shuffle", IconLoader::Base));
|
|
|
|
ui_->action_shuffle_mode->setIcon(
|
|
|
|
IconLoader::Load("media-playlist-shuffle", IconLoader::Base));
|
|
|
|
ui_->action_stop->setIcon(
|
|
|
|
IconLoader::Load("media-playback-stop", IconLoader::Base));
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->action_stop_after_this_track->setIcon(
|
2015-10-14 03:01:08 +02:00
|
|
|
IconLoader::Load("media-playback-stop", IconLoader::Base));
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_new_playlist->setIcon(
|
|
|
|
IconLoader::Load("document-new", IconLoader::Base));
|
|
|
|
ui_->action_load_playlist->setIcon(
|
|
|
|
IconLoader::Load("document-open", IconLoader::Base));
|
|
|
|
ui_->action_save_playlist->setIcon(
|
|
|
|
IconLoader::Load("document-save", IconLoader::Base));
|
|
|
|
ui_->action_full_library_scan->setIcon(
|
|
|
|
IconLoader::Load("view-refresh", IconLoader::Base));
|
|
|
|
ui_->action_rain->setIcon(
|
|
|
|
IconLoader::Load("weather-showers-scattered", IconLoader::Base));
|
|
|
|
ui_->action_hypnotoad->setIcon(
|
|
|
|
IconLoader::Load("hypnotoad", IconLoader::Base));
|
2015-10-14 03:01:08 +02:00
|
|
|
ui_->action_kittens->setIcon(IconLoader::Load("kittens", IconLoader::Base));
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_enterprise->setIcon(
|
|
|
|
IconLoader::Load("enterprise", IconLoader::Base));
|
2015-12-01 06:43:26 +01:00
|
|
|
ui_->action_love->setIcon(IconLoader::Load("love", IconLoader::Lastfm));
|
2010-05-19 17:45:29 +02:00
|
|
|
|
2009-12-24 21:27:32 +01:00
|
|
|
// File view connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(file_view_, SIGNAL(AddToPlaylist(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
|
|
|
connect(file_view_, SIGNAL(PathChanged(QString)),
|
|
|
|
SLOT(FilePathChanged(QString)));
|
|
|
|
connect(file_view_, SIGNAL(CopyToLibrary(QList<QUrl>)),
|
|
|
|
SLOT(CopyFilesToLibrary(QList<QUrl>)));
|
|
|
|
connect(file_view_, SIGNAL(MoveToLibrary(QList<QUrl>)),
|
|
|
|
SLOT(MoveFilesToLibrary(QList<QUrl>)));
|
|
|
|
connect(file_view_, SIGNAL(EditTags(QList<QUrl>)),
|
|
|
|
SLOT(EditFileTags(QList<QUrl>)));
|
|
|
|
connect(file_view_, SIGNAL(CopyToDevice(QList<QUrl>)),
|
|
|
|
SLOT(CopyFilesToDevice(QList<QUrl>)));
|
2012-02-12 14:41:50 +01:00
|
|
|
file_view_->SetTaskManager(app_->task_manager());
|
2009-12-24 20:16:07 +01:00
|
|
|
|
|
|
|
// Action connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_next_track, SIGNAL(triggered()), app_->player(),
|
|
|
|
SLOT(Next()));
|
2021-01-10 06:53:40 +01:00
|
|
|
connect(ui_->action_next_album, SIGNAL(triggered()), app_->player(),
|
|
|
|
SLOT(NextAlbum()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_previous_track, SIGNAL(triggered()), app_->player(),
|
|
|
|
SLOT(Previous()));
|
|
|
|
connect(ui_->action_play_pause, SIGNAL(triggered()), app_->player(),
|
|
|
|
SLOT(PlayPause()));
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(ui_->action_stop, SIGNAL(triggered()), app_->player(), SLOT(Stop()));
|
2011-02-16 23:43:05 +01:00
|
|
|
connect(ui_->action_quit, SIGNAL(triggered()), SLOT(Exit()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_stop_after_this_track, SIGNAL(triggered()),
|
|
|
|
SLOT(StopAfterCurrent()));
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(ui_->action_mute, SIGNAL(triggered()), app_->player(), SLOT(Mute()));
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2010-05-10 23:50:31 +02:00
|
|
|
connect(ui_->action_love, SIGNAL(triggered()), SLOT(Love()));
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(ui_->action_toggle_scrobbling, SIGNAL(triggered()), app_->scrobbler(),
|
|
|
|
SLOT(ToggleScrobbling()));
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
2014-03-07 18:58:50 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_clear_playlist, SIGNAL(triggered()),
|
|
|
|
app_->playlist_manager(), SLOT(ClearCurrent()));
|
|
|
|
connect(ui_->action_remove_duplicates, SIGNAL(triggered()),
|
|
|
|
app_->playlist_manager(), SLOT(RemoveDuplicatesCurrent()));
|
2014-08-24 10:44:27 +02:00
|
|
|
connect(ui_->action_remove_unavailable, SIGNAL(triggered()),
|
|
|
|
app_->playlist_manager(), SLOT(RemoveUnavailableCurrent()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_remove_from_playlist, SIGNAL(triggered()),
|
|
|
|
SLOT(PlaylistRemoveCurrent()));
|
2016-09-06 14:28:25 +02:00
|
|
|
connect(ui_->action_toggle_show_sidebar, SIGNAL(toggled(bool)),
|
2016-10-07 13:29:50 +02:00
|
|
|
ui_->sidebar_layout, SLOT(setVisible(bool)));
|
2010-05-10 23:50:31 +02:00
|
|
|
connect(ui_->action_edit_track, SIGNAL(triggered()), SLOT(EditTracks()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_renumber_tracks, SIGNAL(triggered()),
|
|
|
|
SLOT(RenumberTracks()));
|
|
|
|
connect(ui_->action_selection_set_value, SIGNAL(triggered()),
|
|
|
|
SLOT(SelectionSetValue()));
|
2010-05-10 23:50:31 +02:00
|
|
|
connect(ui_->action_edit_value, SIGNAL(triggered()), SLOT(EditValue()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_auto_complete_tags, SIGNAL(triggered()),
|
|
|
|
SLOT(AutoCompleteTags()));
|
|
|
|
connect(ui_->action_configure, SIGNAL(triggered()),
|
|
|
|
SLOT(OpenSettingsDialog()));
|
2010-08-27 17:42:58 +02:00
|
|
|
connect(ui_->action_about, SIGNAL(triggered()), SLOT(ShowAboutDialog()));
|
2010-09-30 23:25:31 +02:00
|
|
|
connect(ui_->action_about_qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_shuffle, SIGNAL(triggered()), app_->playlist_manager(),
|
|
|
|
SLOT(ShuffleCurrent()));
|
2010-05-11 22:02:19 +02:00
|
|
|
connect(ui_->action_open_media, SIGNAL(triggered()), SLOT(AddFile()));
|
2011-06-10 01:08:43 +02:00
|
|
|
connect(ui_->action_open_cd, SIGNAL(triggered()), SLOT(AddCDTracks()));
|
2014-02-07 16:34:20 +01:00
|
|
|
#ifdef HAVE_AUDIOCD
|
2015-02-18 20:05:35 +01:00
|
|
|
connect(ui_->action_rip_audio_cd, SIGNAL(triggered()),
|
|
|
|
SLOT(OpenRipCDDialog()));
|
2014-02-07 16:34:20 +01:00
|
|
|
#else
|
|
|
|
ui_->action_rip_audio_cd->setVisible(false);
|
|
|
|
#endif
|
2010-05-11 22:02:19 +02:00
|
|
|
connect(ui_->action_add_file, SIGNAL(triggered()), SLOT(AddFile()));
|
|
|
|
connect(ui_->action_add_folder, SIGNAL(triggered()), SLOT(AddFolder()));
|
2010-05-10 23:50:31 +02:00
|
|
|
connect(ui_->action_add_stream, SIGNAL(triggered()), SLOT(AddStream()));
|
2012-03-12 15:11:24 +01:00
|
|
|
connect(ui_->action_add_podcast, SIGNAL(triggered()), SLOT(AddPodcast()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_cover_manager, SIGNAL(triggered()),
|
|
|
|
SLOT(ShowCoverManager()));
|
|
|
|
connect(ui_->action_equalizer, SIGNAL(triggered()), equalizer_.get(),
|
|
|
|
SLOT(show()));
|
|
|
|
connect(ui_->action_transcode, SIGNAL(triggered()),
|
|
|
|
SLOT(ShowTranscodeDialog()));
|
|
|
|
connect(ui_->action_jump, SIGNAL(triggered()), ui_->playlist->view(),
|
|
|
|
SLOT(JumpToCurrentlyPlayingTrack()));
|
|
|
|
connect(ui_->action_update_library, SIGNAL(triggered()), app_->library(),
|
|
|
|
SLOT(IncrementalScan()));
|
|
|
|
connect(ui_->action_full_library_scan, SIGNAL(triggered()), app_->library(),
|
|
|
|
SLOT(FullScan()));
|
|
|
|
connect(ui_->action_queue_manager, SIGNAL(triggered()),
|
|
|
|
SLOT(ShowQueueManager()));
|
|
|
|
connect(ui_->action_add_files_to_transcoder, SIGNAL(triggered()),
|
|
|
|
SLOT(AddFilesToTranscoder()));
|
2016-12-21 17:57:04 +01:00
|
|
|
connect(ui_->action_view_stream_details, SIGNAL(triggered()),
|
|
|
|
SLOT(DiscoverStreamDetails()));
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2020-12-31 22:30:59 +01:00
|
|
|
// Relay this signal to the Application
|
|
|
|
connect(this, SIGNAL(NewDebugConsole(Console*)), app_,
|
|
|
|
SIGNAL(NewDebugConsole(Console*)));
|
|
|
|
|
2011-06-19 16:42:00 +02:00
|
|
|
background_streams_->AddAction("Rain", ui_->action_rain);
|
|
|
|
background_streams_->AddAction("Hypnotoad", ui_->action_hypnotoad);
|
2012-01-10 17:00:17 +01:00
|
|
|
background_streams_->AddAction("Make it so!", ui_->action_enterprise);
|
2011-06-19 16:42:00 +02:00
|
|
|
|
2011-04-19 22:11:24 +02:00
|
|
|
// Playlist view actions
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->action_next_playlist->setShortcuts(
|
2015-06-02 18:11:58 +02:00
|
|
|
QList<QKeySequence>()
|
|
|
|
<< QKeySequence::fromString("Ctrl+Tab")
|
2015-03-28 17:18:22 +01:00
|
|
|
#ifdef Q_OS_DARWIN
|
2015-06-02 18:11:58 +02:00
|
|
|
// On OS X "Ctrl+Tab" == Cmd + Tab but this shorcut
|
|
|
|
// is already used by default for switching between
|
|
|
|
// applications.
|
|
|
|
// I would have preferred to use Meta+Tab (which
|
|
|
|
// means Ctrl+Tab on OS X), like in Firefox or
|
|
|
|
// Chrome, but this doesn't work (probably at Qt bug)
|
|
|
|
// and some applications (e.g. Qt creator) uses
|
|
|
|
// Alt+Tab too so I believe it's a good shorcut anyway
|
|
|
|
<< QKeySequence::fromString("Alt+Tab")
|
|
|
|
#endif // Q_OS_DARWIN
|
|
|
|
<< QKeySequence::fromString("Ctrl+PgDown"));
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->action_previous_playlist->setShortcuts(
|
|
|
|
QList<QKeySequence>() << QKeySequence::fromString("Ctrl+Shift+Tab")
|
2015-03-28 17:18:22 +01:00
|
|
|
#ifdef Q_OS_DARWIN
|
|
|
|
<< QKeySequence::fromString("Alt+Shift+Tab")
|
2015-06-02 18:11:58 +02:00
|
|
|
#endif // Q_OS_DARWIN
|
2014-02-07 16:34:20 +01:00
|
|
|
<< QKeySequence::fromString("Ctrl+PgUp"));
|
|
|
|
// Actions for switching tabs will be global to the entire window, so adding
|
|
|
|
// them here
|
2011-04-19 22:11:24 +02:00
|
|
|
addAction(ui_->action_next_playlist);
|
|
|
|
addAction(ui_->action_previous_playlist);
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Give actions to buttons
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->forward_button->setDefaultAction(ui_->action_next_track);
|
|
|
|
ui_->back_button->setDefaultAction(ui_->action_previous_track);
|
|
|
|
ui_->pause_play_button->setDefaultAction(ui_->action_play_pause);
|
|
|
|
ui_->stop_button->setDefaultAction(ui_->action_stop);
|
|
|
|
ui_->love_button->setDefaultAction(ui_->action_love);
|
2011-04-07 18:25:52 +02:00
|
|
|
ui_->scrobbling_button->setDefaultAction(ui_->action_toggle_scrobbling);
|
2010-06-18 17:07:21 +02:00
|
|
|
ui_->clear_playlist_button->setDefaultAction(ui_->action_clear_playlist);
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->playlist->SetActions(
|
|
|
|
ui_->action_new_playlist, ui_->action_load_playlist,
|
|
|
|
ui_->action_save_playlist,
|
|
|
|
ui_->action_next_playlist, /* These two actions aren't associated */
|
|
|
|
ui_->action_previous_playlist /* to a button but to the main window */);
|
2011-04-07 18:25:52 +02:00
|
|
|
|
2018-11-29 22:32:12 +01:00
|
|
|
#ifdef HAVE_VISUALISATIONS
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_visualisations, SIGNAL(triggered()),
|
|
|
|
SLOT(ShowVisualisations()));
|
2010-06-11 00:48:23 +02:00
|
|
|
#else
|
|
|
|
ui_->action_visualisations->setEnabled(false);
|
|
|
|
#endif
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-03-12 02:03:43 +01:00
|
|
|
// Add the shuffle and repeat action groups to the menu
|
2010-06-16 21:21:15 +02:00
|
|
|
ui_->action_shuffle_mode->setMenu(ui_->playlist_sequence->shuffle_menu());
|
|
|
|
ui_->action_repeat_mode->setMenu(ui_->playlist_sequence->repeat_menu());
|
2010-03-12 02:03:43 +01:00
|
|
|
|
2021-01-10 06:53:40 +01:00
|
|
|
// Next Actions
|
|
|
|
QMenu* next_menu = new QMenu(this);
|
|
|
|
next_menu->addAction(ui_->action_next_track);
|
|
|
|
next_menu->addAction(ui_->action_next_album);
|
|
|
|
ui_->forward_button->setMenu(next_menu);
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Stop actions
|
|
|
|
QMenu* stop_menu = new QMenu(this);
|
2010-05-10 23:50:31 +02:00
|
|
|
stop_menu->addAction(ui_->action_stop);
|
|
|
|
stop_menu->addAction(ui_->action_stop_after_this_track);
|
|
|
|
ui_->stop_button->setMenu(stop_menu);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
|
|
|
// Player connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->volume, SIGNAL(valueChanged(int)), app_->player(),
|
|
|
|
SLOT(SetVolume(int)));
|
2012-02-12 14:41:50 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->player(), SIGNAL(Error(QString)),
|
|
|
|
SLOT(ShowErrorDialog(QString)));
|
|
|
|
connect(app_->player(), SIGNAL(SongChangeRequestProcessed(QUrl, bool)),
|
|
|
|
app_->playlist_manager(),
|
|
|
|
SLOT(SongChangeRequestProcessed(QUrl, bool)));
|
2012-02-12 14:41:50 +01:00
|
|
|
|
|
|
|
connect(app_->player(), SIGNAL(Paused()), SLOT(MediaPaused()));
|
|
|
|
connect(app_->player(), SIGNAL(Playing()), SLOT(MediaPlaying()));
|
|
|
|
connect(app_->player(), SIGNAL(Stopped()), SLOT(MediaStopped()));
|
|
|
|
connect(app_->player(), SIGNAL(Seeked(qlonglong)), SLOT(Seeked(qlonglong)));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->player(), SIGNAL(TrackSkipped(PlaylistItemPtr)),
|
|
|
|
SLOT(TrackSkipped(PlaylistItemPtr)));
|
2015-06-15 22:27:40 +02:00
|
|
|
connect(this, SIGNAL(IntroPointReached()), app_->player(),
|
|
|
|
SLOT(IntroPointReached()));
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(app_->player(), SIGNAL(VolumeChanged(int)), SLOT(VolumeChanged(int)));
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->player(), SIGNAL(Paused()), ui_->playlist,
|
|
|
|
SLOT(ActivePaused()));
|
|
|
|
connect(app_->player(), SIGNAL(Playing()), ui_->playlist,
|
|
|
|
SLOT(ActivePlaying()));
|
|
|
|
connect(app_->player(), SIGNAL(Stopped()), ui_->playlist,
|
|
|
|
SLOT(ActiveStopped()));
|
2012-02-12 14:41:50 +01:00
|
|
|
|
|
|
|
connect(app_->player(), SIGNAL(Paused()), osd_, SLOT(Paused()));
|
|
|
|
connect(app_->player(), SIGNAL(Stopped()), osd_, SLOT(Stopped()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->player(), SIGNAL(PlaylistFinished()), osd_,
|
|
|
|
SLOT(PlaylistFinished()));
|
|
|
|
connect(app_->player(), SIGNAL(VolumeChanged(int)), osd_,
|
|
|
|
SLOT(VolumeChanged(int)));
|
|
|
|
connect(app_->player(), SIGNAL(VolumeChanged(int)), ui_->volume,
|
|
|
|
SLOT(setValue(int)));
|
|
|
|
connect(app_->player(), SIGNAL(ForceShowOSD(Song, bool)),
|
|
|
|
SLOT(ForceShowOSD(Song, bool)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)),
|
|
|
|
SLOT(SongChanged(Song)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)),
|
|
|
|
app_->player(), SLOT(CurrentMetadataChanged(Song)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(EditingFinished(QModelIndex)),
|
|
|
|
SLOT(PlaylistEditFinished(QModelIndex)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(Error(QString)),
|
|
|
|
SLOT(ShowErrorDialog(QString)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(SummaryTextChanged(QString)),
|
|
|
|
ui_->playlist_summary, SLOT(setText(QString)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(PlayRequested(QModelIndex)),
|
|
|
|
SLOT(PlayIndex(QModelIndex)));
|
|
|
|
|
|
|
|
connect(ui_->playlist->view(), SIGNAL(doubleClicked(QModelIndex)),
|
2015-08-10 05:25:56 +02:00
|
|
|
SLOT(PlaylistDoubleClick(QModelIndex)));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->playlist->view(), SIGNAL(PlayItem(QModelIndex)),
|
|
|
|
SLOT(PlayIndex(QModelIndex)));
|
|
|
|
connect(ui_->playlist->view(), SIGNAL(PlayPause()), app_->player(),
|
|
|
|
SLOT(PlayPause()));
|
|
|
|
connect(ui_->playlist->view(), SIGNAL(RightClicked(QPoint, QModelIndex)),
|
|
|
|
SLOT(PlaylistRightClick(QPoint, QModelIndex)));
|
2015-07-02 14:59:30 +02:00
|
|
|
connect(ui_->playlist->view(), SIGNAL(SeekForward()), app_->player(),
|
|
|
|
SLOT(SeekForward()));
|
|
|
|
connect(ui_->playlist->view(), SIGNAL(SeekBackward()), app_->player(),
|
|
|
|
SLOT(SeekBackward()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->playlist->view(), SIGNAL(BackgroundPropertyChanged()),
|
|
|
|
SLOT(RefreshStyleSheet()));
|
|
|
|
|
2014-05-19 17:51:40 +02:00
|
|
|
connect(ui_->track_slider, SIGNAL(ValueChangedSeconds(int)), app_->player(),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(SeekTo(int)));
|
2015-07-02 14:59:30 +02:00
|
|
|
connect(ui_->track_slider, SIGNAL(SeekForward()), app_->player(),
|
|
|
|
SLOT(SeekForward()));
|
|
|
|
connect(ui_->track_slider, SIGNAL(SeekBackward()), app_->player(),
|
|
|
|
SLOT(SeekBackward()));
|
2010-03-06 16:33:57 +01:00
|
|
|
|
2018-08-12 17:54:07 +02:00
|
|
|
connect(ui_->track_slider, SIGNAL(Previous()), app_->player(),
|
|
|
|
SLOT(Previous()));
|
|
|
|
connect(ui_->track_slider, SIGNAL(Next()), app_->player(), SLOT(Next()));
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Library connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(library_view_->view(), SIGNAL(AddToPlaylistSignal(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
|
|
|
connect(library_view_->view(), SIGNAL(ShowConfigDialog()),
|
|
|
|
SLOT(ShowLibraryConfig()));
|
|
|
|
connect(app_->library_model(), SIGNAL(TotalSongCountUpdated(int)),
|
|
|
|
library_view_->view(), SLOT(TotalSongCountUpdated(int)));
|
|
|
|
connect(app_->library_model(), SIGNAL(modelAboutToBeReset()),
|
|
|
|
library_view_->view(), SLOT(SaveFocus()));
|
|
|
|
connect(app_->library_model(), SIGNAL(modelReset()), library_view_->view(),
|
|
|
|
SLOT(RestoreFocus()));
|
|
|
|
|
|
|
|
connect(app_->task_manager(), SIGNAL(PauseLibraryWatchers()), app_->library(),
|
|
|
|
SLOT(PauseWatcher()));
|
|
|
|
connect(app_->task_manager(), SIGNAL(ResumeLibraryWatchers()),
|
|
|
|
app_->library(), SLOT(ResumeWatcher()));
|
2010-06-24 23:46:18 +02:00
|
|
|
|
2010-07-04 22:52:45 +02:00
|
|
|
// Devices connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(device_view_, SIGNAL(AddToPlaylistSignal(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
2010-07-04 22:52:45 +02:00
|
|
|
|
2010-05-09 22:18:05 +02:00
|
|
|
// Library filter widget
|
2011-02-06 14:18:18 +01:00
|
|
|
QActionGroup* library_view_group = new QActionGroup(this);
|
|
|
|
|
|
|
|
library_show_all_ = library_view_group->addAction(tr("Show all songs"));
|
2014-02-07 16:34:20 +01:00
|
|
|
library_show_duplicates_ =
|
|
|
|
library_view_group->addAction(tr("Show only duplicates"));
|
|
|
|
library_show_untagged_ =
|
|
|
|
library_view_group->addAction(tr("Show only untagged"));
|
2011-02-06 14:18:18 +01:00
|
|
|
|
|
|
|
library_show_all_->setCheckable(true);
|
|
|
|
library_show_duplicates_->setCheckable(true);
|
|
|
|
library_show_untagged_->setCheckable(true);
|
|
|
|
library_show_all_->setChecked(true);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(library_view_group, SIGNAL(triggered(QAction*)),
|
|
|
|
SLOT(ChangeLibraryQueryMode(QAction*)));
|
2011-01-30 22:00:49 +01:00
|
|
|
|
2015-12-20 18:25:45 +01:00
|
|
|
QAction* library_config_action =
|
|
|
|
new QAction(IconLoader::Load("configure", IconLoader::Base),
|
|
|
|
tr("Configure library..."), this);
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(library_config_action, SIGNAL(triggered()),
|
|
|
|
SLOT(ShowLibraryConfig()));
|
2010-10-01 21:27:01 +02:00
|
|
|
library_view_->filter()->SetSettingsGroup(kSettingsGroup);
|
2012-02-12 14:41:50 +01:00
|
|
|
library_view_->filter()->SetLibraryModel(app_->library()->model());
|
2011-01-30 22:00:49 +01:00
|
|
|
|
2011-02-02 17:22:04 +01:00
|
|
|
QAction* separator = new QAction(this);
|
|
|
|
separator->setSeparator(true);
|
|
|
|
|
2011-02-06 14:18:18 +01:00
|
|
|
library_view_->filter()->AddMenuAction(library_show_all_);
|
|
|
|
library_view_->filter()->AddMenuAction(library_show_duplicates_);
|
|
|
|
library_view_->filter()->AddMenuAction(library_show_untagged_);
|
2011-02-02 17:22:04 +01:00
|
|
|
library_view_->filter()->AddMenuAction(separator);
|
2010-10-01 21:27:01 +02:00
|
|
|
library_view_->filter()->AddMenuAction(library_config_action);
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-01-15 17:22:19 +01:00
|
|
|
// Playlist menu
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_play_pause_ =
|
|
|
|
playlist_menu_->addAction(tr("Play"), this, SLOT(PlaylistPlay()));
|
2010-05-10 23:50:31 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_stop);
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_stop_after_ = playlist_menu_->addAction(
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("media-playback-stop", IconLoader::Base),
|
2015-10-14 03:01:08 +02:00
|
|
|
tr("Stop after this track"), this, SLOT(PlaylistStopAfter()));
|
2010-07-11 23:52:00 +02:00
|
|
|
playlist_queue_ = playlist_menu_->addAction("", this, SLOT(PlaylistQueue()));
|
2010-07-26 17:21:56 +02:00
|
|
|
playlist_queue_->setShortcut(QKeySequence("Ctrl+D"));
|
|
|
|
ui_->playlist->addAction(playlist_queue_);
|
2018-04-14 22:57:06 +02:00
|
|
|
playlist_queue_play_next_ =
|
|
|
|
playlist_menu_->addAction("", this, SLOT(PlaylistQueuePlayNext()));
|
2018-03-18 19:43:44 +01:00
|
|
|
playlist_queue_play_next_->setShortcut(QKeySequence("Ctrl+Shift+D"));
|
|
|
|
ui_->playlist->addAction(playlist_queue_play_next_);
|
2014-01-18 16:30:12 +01:00
|
|
|
playlist_skip_ = playlist_menu_->addAction("", this, SLOT(PlaylistSkip()));
|
2014-01-14 06:29:23 +01:00
|
|
|
ui_->playlist->addAction(playlist_skip_);
|
2017-08-09 15:12:36 +02:00
|
|
|
playlist_menu_->addSeparator();
|
|
|
|
search_for_artist_ = playlist_menu_->addAction(
|
|
|
|
IconLoader::Load("system-search", IconLoader::Base),
|
|
|
|
tr("Search for artist"), this, SLOT(SearchForArtist()));
|
|
|
|
search_for_album_ = playlist_menu_->addAction(
|
|
|
|
IconLoader::Load("system-search", IconLoader::Base),
|
|
|
|
tr("Search for album"), this, SLOT(SearchForAlbum()));
|
2010-03-24 01:12:52 +01:00
|
|
|
playlist_menu_->addSeparator();
|
2010-05-10 23:50:31 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_remove_from_playlist);
|
2010-05-20 23:21:55 +02:00
|
|
|
playlist_undoredo_ = playlist_menu_->addSeparator();
|
2010-05-10 23:50:31 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_edit_track);
|
2016-12-21 17:57:04 +01:00
|
|
|
playlist_menu_->addAction(ui_->action_view_stream_details);
|
2010-05-10 23:50:31 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_edit_value);
|
|
|
|
playlist_menu_->addAction(ui_->action_renumber_tracks);
|
|
|
|
playlist_menu_->addAction(ui_->action_selection_set_value);
|
2011-03-06 15:07:41 +01:00
|
|
|
playlist_menu_->addAction(ui_->action_auto_complete_tags);
|
2013-06-30 16:54:13 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_add_files_to_transcoder);
|
2010-01-15 17:22:19 +01:00
|
|
|
playlist_menu_->addSeparator();
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_copy_to_library_ = playlist_menu_->addAction(
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("edit-copy", IconLoader::Base), tr("Copy to library..."),
|
|
|
|
this, SLOT(PlaylistCopyToLibrary()));
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_move_to_library_ = playlist_menu_->addAction(
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("go-jump", IconLoader::Base), tr("Move to library..."),
|
|
|
|
this, SLOT(PlaylistMoveToLibrary()));
|
|
|
|
playlist_organise_ = playlist_menu_->addAction(
|
|
|
|
IconLoader::Load("edit-copy", IconLoader::Base), tr("Organise files..."),
|
|
|
|
this, SLOT(PlaylistMoveToLibrary()));
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_copy_to_device_ = playlist_menu_->addAction(
|
2015-10-14 03:01:08 +02:00
|
|
|
IconLoader::Load("multimedia-player-ipod-mini-blue", IconLoader::Base),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("Copy to device..."), this, SLOT(PlaylistCopyToDevice()));
|
2015-12-20 18:25:45 +01:00
|
|
|
playlist_delete_ = playlist_menu_->addAction(
|
|
|
|
IconLoader::Load("edit-delete", IconLoader::Base),
|
|
|
|
tr("Delete from disk..."), this, SLOT(PlaylistDelete()));
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_open_in_browser_ = playlist_menu_->addAction(
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("document-open-folder", IconLoader::Base),
|
|
|
|
tr("Show in file browser..."), this, SLOT(PlaylistOpenInBrowser()));
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_show_in_library_ = playlist_menu_->addAction(
|
2015-12-20 18:25:45 +01:00
|
|
|
IconLoader::Load("edit-find", IconLoader::Base), tr("Show in library..."),
|
|
|
|
this, SLOT(ShowInLibrary()));
|
2010-06-25 01:36:39 +02:00
|
|
|
playlist_menu_->addSeparator();
|
2012-07-29 03:11:00 +02:00
|
|
|
playlistitem_actions_separator_ = playlist_menu_->addSeparator();
|
2010-05-10 23:50:31 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_clear_playlist);
|
|
|
|
playlist_menu_->addAction(ui_->action_shuffle);
|
2012-07-29 02:38:24 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_remove_duplicates);
|
2014-08-24 10:44:27 +02:00
|
|
|
playlist_menu_->addAction(ui_->action_remove_unavailable);
|
2010-01-15 17:22:19 +01:00
|
|
|
|
2010-07-26 14:05:50 +02:00
|
|
|
#ifdef Q_OS_DARWIN
|
|
|
|
ui_->action_shuffle->setShortcut(QKeySequence());
|
|
|
|
#endif
|
|
|
|
|
2011-03-06 19:26:06 +01:00
|
|
|
// We have to add the actions on the playlist menu to this QWidget otherwise
|
|
|
|
// their shortcut keys don't work
|
|
|
|
addActions(playlist_menu_->actions());
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->playlist, SIGNAL(UndoRedoActionsChanged(QAction*, QAction*)),
|
|
|
|
SLOT(PlaylistUndoRedoChanged(QAction*, QAction*)));
|
2010-05-20 23:21:55 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_copy_to_device_->setDisabled(
|
|
|
|
app_->device_manager()->connected_devices_model()->rowCount() == 0);
|
|
|
|
connect(app_->device_manager()->connected_devices_model(),
|
|
|
|
SIGNAL(IsEmptyChanged(bool)), playlist_copy_to_device_,
|
|
|
|
SLOT(setDisabled(bool)));
|
2010-08-08 15:06:52 +02:00
|
|
|
|
2012-06-16 22:17:13 +02:00
|
|
|
// Global search shortcut
|
|
|
|
QAction* global_search_action = new QAction(this);
|
|
|
|
global_search_action->setShortcuts(QList<QKeySequence>()
|
|
|
|
<< QKeySequence("Ctrl+F")
|
|
|
|
<< QKeySequence("Ctrl+L"));
|
|
|
|
addAction(global_search_action);
|
|
|
|
connect(global_search_action, SIGNAL(triggered()),
|
|
|
|
SLOT(FocusGlobalSearchField()));
|
|
|
|
|
2011-07-15 15:27:50 +02:00
|
|
|
// Internet connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->internet_model(), SIGNAL(StreamError(QString)),
|
|
|
|
SLOT(ShowErrorDialog(QString)));
|
|
|
|
connect(app_->internet_model(), SIGNAL(StreamMetadataFound(QUrl, Song)),
|
|
|
|
app_->playlist_manager(), SLOT(SetActiveStreamMetadata(QUrl, Song)));
|
|
|
|
connect(app_->internet_model(), SIGNAL(AddToPlaylist(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
|
|
|
connect(app_->internet_model(), SIGNAL(ScrollToIndex(QModelIndex)),
|
|
|
|
SLOT(ScrollToInternetIndex(QModelIndex)));
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(app_->scrobbler(), SIGNAL(ButtonVisibilityChanged(bool)),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(LastFMButtonVisibilityChanged(bool)));
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(app_->scrobbler(), SIGNAL(ScrobbleButtonVisibilityChanged(bool)),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(ScrobbleButtonVisibilityChanged(bool)));
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(app_->scrobbler(), SIGNAL(ScrobblingEnabledChanged(bool)),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(ScrobblingEnabledChanged(bool)));
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(app_->scrobbler(), SIGNAL(ScrobbledRadioStream()),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(ScrobbledRadioStream()));
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->internet_model()->Service<MagnatuneService>(),
|
|
|
|
SIGNAL(DownloadFinished(QStringList)), osd_,
|
|
|
|
SLOT(MagnatuneDownloadFinished(QStringList)));
|
|
|
|
connect(internet_view_->tree(), SIGNAL(AddToPlaylistSignal(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
2009-12-26 22:35:45 +01:00
|
|
|
|
2010-05-28 00:53:07 +02:00
|
|
|
// Connections to the saved streams service
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(InternetModel::Service<SavedRadio>(), SIGNAL(ShowAddStreamDialog()),
|
|
|
|
SLOT(AddStream()));
|
2010-05-28 00:53:07 +02:00
|
|
|
|
2020-11-27 13:05:53 +01:00
|
|
|
// Network Remote
|
|
|
|
connect(app->network_remote(), SIGNAL(AddToPlaylistSignal(QMimeData*)),
|
|
|
|
SLOT(AddToPlaylist(QMimeData*)));
|
|
|
|
connect(app->network_remote(), SIGNAL(SetCurrentPlaylist(int)),
|
|
|
|
app_->playlist_manager(), SLOT(SetCurrentPlaylist(int)));
|
|
|
|
|
2010-06-22 16:09:13 +02:00
|
|
|
#ifdef Q_OS_DARWIN
|
|
|
|
mac::SetApplicationHandler(this);
|
|
|
|
#endif
|
2009-12-24 20:16:07 +01:00
|
|
|
// Tray icon
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) {
|
|
|
|
tray_icon_->SetupMenu(ui_->action_previous_track, ui_->action_play_pause,
|
|
|
|
ui_->action_stop, ui_->action_stop_after_this_track,
|
|
|
|
ui_->action_next_track, ui_->action_mute,
|
|
|
|
ui_->action_love, ui_->action_quit);
|
|
|
|
connect(tray_icon_, SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause()));
|
|
|
|
connect(tray_icon_, SIGNAL(SeekForward()), app_->player(),
|
|
|
|
SLOT(SeekForward()));
|
|
|
|
connect(tray_icon_, SIGNAL(SeekBackward()), app_->player(),
|
|
|
|
SLOT(SeekBackward()));
|
|
|
|
connect(tray_icon_, SIGNAL(NextTrack()), app_->player(), SLOT(Next()));
|
|
|
|
connect(tray_icon_, SIGNAL(PreviousTrack()), app_->player(),
|
|
|
|
SLOT(Previous()));
|
|
|
|
connect(tray_icon_, SIGNAL(ShowHide()), SLOT(ToggleShowHide()));
|
|
|
|
connect(tray_icon_, SIGNAL(ChangeVolume(int)), SLOT(VolumeWheelEvent(int)));
|
|
|
|
}
|
2010-12-03 14:53:43 +01:00
|
|
|
|
2011-01-16 01:39:51 +01:00
|
|
|
// Windows 7 thumbbar buttons
|
|
|
|
thumbbar_->SetActions(QList<QAction*>()
|
2014-02-07 16:34:20 +01:00
|
|
|
<< ui_->action_previous_track << ui_->action_play_pause
|
|
|
|
<< ui_->action_stop << ui_->action_next_track
|
|
|
|
<< nullptr // spacer
|
2014-03-27 18:55:58 +01:00
|
|
|
<< ui_->action_love);
|
2011-01-16 01:39:51 +01:00
|
|
|
|
2010-12-30 17:20:33 +01:00
|
|
|
#if (defined(Q_OS_DARWIN) && defined(HAVE_SPARKLE)) || defined(Q_OS_WIN32)
|
|
|
|
// Add check for updates item to application menu.
|
2014-02-07 16:34:20 +01:00
|
|
|
QAction* check_updates =
|
|
|
|
ui_->menu_tools->addAction(tr("Check for updates..."));
|
2010-12-30 17:20:33 +01:00
|
|
|
check_updates->setMenuRole(QAction::ApplicationSpecificRole);
|
|
|
|
connect(check_updates, SIGNAL(triggered(bool)), SLOT(CheckForUpdates()));
|
|
|
|
#endif
|
2010-05-25 15:19:28 +02:00
|
|
|
|
2009-12-30 17:24:55 +01:00
|
|
|
// Global shortcuts
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(Play()), app_->player(), SLOT(Play()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(Pause()), app_->player(), SLOT(Pause()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(PlayPause()), ui_->action_play_pause,
|
|
|
|
SLOT(trigger()));
|
2010-05-10 23:50:31 +02:00
|
|
|
connect(global_shortcuts_, SIGNAL(Stop()), ui_->action_stop, SLOT(trigger()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(StopAfter()),
|
|
|
|
ui_->action_stop_after_this_track, SLOT(trigger()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(Next()), ui_->action_next_track,
|
|
|
|
SLOT(trigger()));
|
2021-06-03 05:36:24 +02:00
|
|
|
connect(global_shortcuts_, SIGNAL(NextAlbum()), ui_->action_next_album,
|
|
|
|
SLOT(trigger()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(Previous()), ui_->action_previous_track,
|
|
|
|
SLOT(trigger()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(IncVolume()), app_->player(),
|
|
|
|
SLOT(VolumeUp()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(DecVolume()), app_->player(),
|
|
|
|
SLOT(VolumeDown()));
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(Mute()), app_->player(), SLOT(Mute()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(SeekForward()), app_->player(),
|
|
|
|
SLOT(SeekForward()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(SeekBackward()), app_->player(),
|
|
|
|
SLOT(SeekBackward()));
|
2010-07-24 14:39:09 +02:00
|
|
|
connect(global_shortcuts_, SIGNAL(ShowHide()), SLOT(ToggleShowHide()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(ShowOSD()), app_->player(),
|
|
|
|
SLOT(ShowOSD()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(TogglePrettyOSD()), app_->player(),
|
|
|
|
SLOT(TogglePrettyOSD()));
|
2011-04-07 18:25:52 +02:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(ToggleScrobbling()), app_->scrobbler(),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(ToggleScrobbling()));
|
2015-06-17 14:21:24 +02:00
|
|
|
connect(global_shortcuts_, SIGNAL(Love()), app_->scrobbler(), SLOT(Love()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(Ban()), app_->scrobbler(), SLOT(Ban()));
|
2011-04-07 18:25:52 +02:00
|
|
|
#endif
|
2010-02-24 23:26:01 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(global_shortcuts_, SIGNAL(RateCurrentSong(int)),
|
|
|
|
app_->playlist_manager(), SLOT(RateCurrentSong(int)));
|
2017-05-31 18:59:36 +02:00
|
|
|
connect(global_shortcuts_, SIGNAL(RemoveCurrentSong()),
|
|
|
|
app_->playlist_manager(), SLOT(RemoveCurrentSong()));
|
2010-12-17 01:21:20 +01:00
|
|
|
|
2010-09-26 18:00:28 +02:00
|
|
|
// Lyrics
|
2010-10-10 18:09:20 +02:00
|
|
|
ConnectInfoView(song_info_view_);
|
2010-10-02 18:23:33 +02:00
|
|
|
ConnectInfoView(artist_info_view_);
|
2010-09-26 18:00:28 +02:00
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Analyzer
|
2012-02-12 14:41:50 +01:00
|
|
|
ui_->analyzer->SetEngine(app_->player()->engine());
|
2010-06-23 17:52:56 +02:00
|
|
|
ui_->analyzer->SetActions(ui_->action_visualisations);
|
2013-07-27 08:12:41 +02:00
|
|
|
connect(ui_->analyzer, SIGNAL(WheelEvent(int)), SLOT(VolumeWheelEvent(int)));
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-04-07 18:26:04 +02:00
|
|
|
// Equalizer
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Creating equalizer";
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(equalizer_.get(), SIGNAL(ParametersChanged(int, QList<int>)),
|
|
|
|
app_->player()->engine(),
|
|
|
|
SLOT(SetEqualizerParameters(int, QList<int>)));
|
2010-04-14 23:58:51 +02:00
|
|
|
connect(equalizer_.get(), SIGNAL(EnabledChanged(bool)),
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->engine(), SLOT(SetEqualizerEnabled(bool)));
|
2013-04-27 05:05:42 +02:00
|
|
|
connect(equalizer_.get(), SIGNAL(StereoBalanceChanged(float)),
|
|
|
|
app_->player()->engine(), SLOT(SetStereoBalance(float)));
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->engine()->SetEqualizerEnabled(equalizer_->is_enabled());
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->player()->engine()->SetEqualizerParameters(equalizer_->preamp_value(),
|
|
|
|
equalizer_->gain_values());
|
2013-04-27 05:05:42 +02:00
|
|
|
app_->player()->engine()->SetStereoBalance(equalizer_->stereo_balance());
|
2010-04-07 18:26:04 +02:00
|
|
|
|
2010-01-15 18:12:47 +01:00
|
|
|
// Statusbar widgets
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->playlist_summary->setMinimumWidth(
|
|
|
|
QFontMetrics(font()).width("WW selected of WW tracks - [ WW:WW ]"));
|
2010-06-16 21:21:15 +02:00
|
|
|
ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page);
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->multi_loading_indicator, SIGNAL(TaskCountChange(int)),
|
|
|
|
SLOT(TaskCountChanged(int)));
|
2010-01-15 18:12:47 +01:00
|
|
|
|
2012-05-28 00:44:49 +02:00
|
|
|
ui_->track_slider->SetApplication(app);
|
2012-05-27 22:15:58 +02:00
|
|
|
#ifdef HAVE_MOODBAR
|
2012-05-25 23:02:10 +02:00
|
|
|
// Moodbar connections
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->moodbar_controller(),
|
|
|
|
SIGNAL(CurrentMoodbarDataChanged(QByteArray)),
|
2012-05-25 23:02:10 +02:00
|
|
|
ui_->track_slider->moodbar_style(), SLOT(SetMoodbarData(QByteArray)));
|
2012-05-27 22:15:58 +02:00
|
|
|
#endif
|
2012-05-25 23:02:10 +02:00
|
|
|
|
2010-06-17 00:00:39 +02:00
|
|
|
// Now playing widget
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Creating now playing widget";
|
2010-06-17 00:00:39 +02:00
|
|
|
ui_->now_playing->set_ideal_height(ui_->status_bar->sizeHint().height() +
|
2011-03-07 21:21:34 +01:00
|
|
|
ui_->player_controls->sizeHint().height());
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(app_->player(), SIGNAL(Stopped()), ui_->now_playing, SLOT(Stopped()));
|
2010-06-18 02:06:59 +02:00
|
|
|
connect(ui_->now_playing, SIGNAL(ShowAboveStatusBarChanged(bool)),
|
|
|
|
SLOT(NowPlayingWidgetPositionChanged(bool)));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(ui_->action_hypnotoad, SIGNAL(toggled(bool)), ui_->now_playing,
|
|
|
|
SLOT(AllHail(bool)));
|
|
|
|
connect(ui_->action_kittens, SIGNAL(toggled(bool)), ui_->now_playing,
|
|
|
|
SLOT(EnableKittens(bool)));
|
|
|
|
connect(ui_->action_kittens, SIGNAL(toggled(bool)), app_->network_remote(),
|
|
|
|
SLOT(EnableKittens(bool)));
|
2021-01-26 20:33:24 +01:00
|
|
|
if (app->DebugFeaturesEnabled())
|
2020-05-26 00:53:22 +02:00
|
|
|
connect(ui_->action_console, SIGNAL(triggered()), SLOT(ShowConsole()));
|
|
|
|
else
|
|
|
|
ui_->action_console->setVisible(false);
|
2010-06-18 02:06:59 +02:00
|
|
|
NowPlayingWidgetPositionChanged(ui_->now_playing->show_above_status_bar());
|
2010-06-17 00:00:39 +02:00
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
// Load theme
|
2012-01-14 16:27:49 +01:00
|
|
|
// This is tricky: we need to save the default/system palette now, before
|
2020-09-18 16:15:19 +02:00
|
|
|
// loading user preferred theme (which will override it), to be able to
|
|
|
|
// restore it later
|
2012-01-14 16:27:49 +01:00
|
|
|
const_cast<QPalette&>(Appearance::kDefaultPalette) = QApplication::palette();
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->appearance()->LoadUserTheme();
|
2010-02-27 17:36:25 +01:00
|
|
|
StyleSheetLoader* css_loader = new StyleSheetLoader(this);
|
|
|
|
css_loader->SetStyleSheet(this, ":mainwindow.css");
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-05-20 23:21:55 +02:00
|
|
|
// Load playlists
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->Init(app_->library_backend(),
|
|
|
|
app_->playlist_backend(),
|
2012-02-12 14:41:50 +01:00
|
|
|
ui_->playlist_sequence, ui_->playlist);
|
2010-05-20 23:21:55 +02:00
|
|
|
|
2014-01-07 11:46:39 +01:00
|
|
|
// This connection must be done after the playlists have been initialized.
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(this, SIGNAL(StopAfterToggled(bool)), osd_,
|
|
|
|
SLOT(StopAfterToggle(bool)));
|
|
|
|
|
|
|
|
// We need to connect these global shortcuts here after the playlist have been
|
|
|
|
// initialized
|
|
|
|
connect(global_shortcuts_, SIGNAL(CycleShuffleMode()),
|
|
|
|
app_->playlist_manager()->sequence(), SLOT(CycleShuffleMode()));
|
|
|
|
connect(global_shortcuts_, SIGNAL(CycleRepeatMode()),
|
|
|
|
app_->playlist_manager()->sequence(), SLOT(CycleRepeatMode()));
|
|
|
|
connect(app_->playlist_manager()->sequence(),
|
|
|
|
SIGNAL(RepeatModeChanged(PlaylistSequence::RepeatMode)), osd_,
|
|
|
|
SLOT(RepeatModeChanged(PlaylistSequence::RepeatMode)));
|
|
|
|
connect(app_->playlist_manager()->sequence(),
|
|
|
|
SIGNAL(ShuffleModeChanged(PlaylistSequence::ShuffleMode)), osd_,
|
|
|
|
SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode)));
|
2011-03-17 09:21:05 +01:00
|
|
|
|
2021-01-10 06:53:40 +01:00
|
|
|
// Connect the RepeatModeChanged signal such that it will dis/enable the
|
|
|
|
// action_next_album on the UI
|
|
|
|
connect(app_->playlist_manager()->sequence(),
|
|
|
|
SIGNAL(RepeatModeChanged(PlaylistSequence::RepeatMode)),
|
|
|
|
SLOT(SetNextAlbumEnabled(PlaylistSequence::RepeatMode)));
|
|
|
|
|
2011-04-07 18:25:52 +02:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2014-01-18 23:13:23 +01:00
|
|
|
connect(app_->scrobbler(), SIGNAL(CachedToScrobble()),
|
|
|
|
SLOT(CachedToScrobble()));
|
2014-03-27 18:55:58 +01:00
|
|
|
connect(app_->scrobbler(), SIGNAL(ScrobbleError(int)),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(ScrobbleError(int)));
|
|
|
|
|
2014-03-27 18:55:58 +01:00
|
|
|
LastFMButtonVisibilityChanged(app_->scrobbler()->AreButtonsVisible());
|
|
|
|
ScrobbleButtonVisibilityChanged(app_->scrobbler()->IsScrobbleButtonVisible());
|
|
|
|
ScrobblingEnabledChanged(app_->scrobbler()->IsScrobblingEnabled());
|
2011-04-07 18:25:52 +02:00
|
|
|
#else
|
|
|
|
LastFMButtonVisibilityChanged(false);
|
|
|
|
ScrobbleButtonVisibilityChanged(false);
|
|
|
|
#endif
|
|
|
|
|
2009-12-24 21:27:32 +01:00
|
|
|
// Load settings
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Loading settings";
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2015-11-22 06:35:27 +01:00
|
|
|
// Set last used geometry to position window on the correct monitor
|
|
|
|
// Set window state only if the window was last maximized
|
2015-10-20 11:44:42 +02:00
|
|
|
was_maximized_ = settings_.value("maximized", false).toBool();
|
2010-02-27 17:52:18 +01:00
|
|
|
restoreGeometry(settings_.value("geometry").toByteArray());
|
2015-11-22 06:35:27 +01:00
|
|
|
if (was_maximized_) {
|
2015-10-20 11:44:42 +02:00
|
|
|
setWindowState(windowState() | Qt::WindowMaximized);
|
2015-11-22 06:35:27 +01:00
|
|
|
}
|
2015-10-20 11:44:42 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!ui_->splitter->restoreState(
|
2014-03-27 18:55:58 +01:00
|
|
|
settings_.value("splitter_state").toByteArray())) {
|
2010-12-19 15:29:25 +01:00
|
|
|
ui_->splitter->setSizes(QList<int>() << 300 << width() - 300);
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->setCurrentIndex(
|
2014-02-07 16:34:20 +01:00
|
|
|
settings_.value("current_tab", 1 /* Library tab */).toInt());
|
2011-03-18 16:09:30 +01:00
|
|
|
FancyTabWidget::Mode default_mode = FancyTabWidget::Mode_LargeSidebar;
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->tabs->SetMode(
|
|
|
|
FancyTabWidget::Mode(settings_.value("tab_mode", default_mode).toInt()));
|
|
|
|
file_view_->SetPath(
|
|
|
|
settings_.value("file_path", QDir::homePath()).toString());
|
2009-12-24 21:27:32 +01:00
|
|
|
|
2014-05-29 12:43:43 +02:00
|
|
|
// Users often collapse one side of the splitter by mistake and don't know
|
|
|
|
// how to restore it. This must be set after the state is restored above.
|
|
|
|
ui_->splitter->setChildrenCollapsible(false);
|
2009-12-24 21:27:32 +01:00
|
|
|
|
2010-05-15 19:45:04 +02:00
|
|
|
ReloadSettings();
|
|
|
|
|
2016-03-26 01:12:59 +01:00
|
|
|
// The "GlobalSearchView" requires that "InternetModel" has already been
|
|
|
|
// initialised before reload settings.
|
|
|
|
app_->global_search()->ReloadSettings();
|
|
|
|
global_search_view_->ReloadSettings();
|
|
|
|
|
2011-05-28 10:50:29 +02:00
|
|
|
// Reload pretty OSD to avoid issues with fonts
|
|
|
|
osd_->ReloadPrettyOSDSettings();
|
|
|
|
|
2011-06-08 16:48:43 +02:00
|
|
|
// Reload playlist settings, for BG and glowing
|
|
|
|
ui_->playlist->view()->ReloadSettings();
|
|
|
|
|
2018-10-01 10:40:31 +02:00
|
|
|
#ifdef Q_OS_DARWIN
|
|
|
|
// Always show mainwindow on startup on OS X.
|
|
|
|
show();
|
|
|
|
#else
|
2014-02-07 16:34:20 +01:00
|
|
|
StartupBehaviour behaviour = StartupBehaviour(
|
|
|
|
settings_.value("startupbehaviour", Startup_Remember).toInt());
|
2010-03-31 05:07:11 +02:00
|
|
|
bool hidden = settings_.value("hidden", false).toBool();
|
2010-04-07 01:46:34 +02:00
|
|
|
|
|
|
|
switch (behaviour) {
|
2014-02-07 16:34:20 +01:00
|
|
|
case Startup_AlwaysHide:
|
|
|
|
hide();
|
|
|
|
break;
|
|
|
|
case Startup_AlwaysShow:
|
|
|
|
show();
|
|
|
|
break;
|
|
|
|
case Startup_Remember:
|
|
|
|
setVisible(!hidden);
|
|
|
|
break;
|
2010-04-07 01:46:34 +02:00
|
|
|
}
|
2010-02-26 19:22:44 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// Force the window to show in case somehow the config has tray and window set
|
|
|
|
// to hide
|
2018-10-01 10:40:31 +02:00
|
|
|
if (hidden && (!QSystemTrayIcon::isSystemTrayAvailable() || !tray_icon_ ||
|
2020-11-01 20:55:45 +01:00
|
|
|
!tray_icon_->IsVisible()))
|
2010-02-26 19:22:44 +01:00
|
|
|
show();
|
2010-04-14 21:38:09 +02:00
|
|
|
#endif
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-04-14 23:27:27 +02:00
|
|
|
QShortcut* close_window_shortcut = new QShortcut(this);
|
|
|
|
close_window_shortcut->setKey(Qt::CTRL + Qt::Key_W);
|
2010-06-17 19:08:56 +02:00
|
|
|
connect(close_window_shortcut, SIGNAL(activated()), SLOT(SetHiddenInTray()));
|
2010-04-14 23:27:27 +02:00
|
|
|
|
2011-03-12 22:19:32 +01:00
|
|
|
#ifdef HAVE_WIIMOTEDEV
|
2014-02-07 16:34:20 +01:00
|
|
|
// http://code.google.com/p/clementine-player/issues/detail?id=670
|
|
|
|
// Switched position, mayby something is not ready ?
|
2010-09-01 17:37:09 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
wiimotedev_shortcuts_.reset(
|
|
|
|
new WiimotedevShortcuts(osd_, this, app_->player()));
|
2010-09-01 17:37:09 +02:00
|
|
|
#endif
|
|
|
|
|
2011-02-25 21:10:41 +01:00
|
|
|
CheckFullRescanRevisions();
|
2011-04-24 20:07:09 +02:00
|
|
|
|
2016-04-12 16:53:43 +02:00
|
|
|
CommandlineOptionsReceived(options);
|
|
|
|
|
2016-07-01 11:37:04 +02:00
|
|
|
if (!options.contains_play_options()) LoadPlaybackStatus();
|
2013-03-03 22:29:27 +01:00
|
|
|
|
2021-01-10 06:53:40 +01:00
|
|
|
// Set the state of action_next_album based on the repeat mode.
|
|
|
|
if (app_->playlist_manager()->current()->sequence()->repeat_mode() ==
|
|
|
|
PlaylistSequence::Repeat_Track ||
|
|
|
|
app_->playlist_manager()->current()->sequence()->repeat_mode() ==
|
|
|
|
PlaylistSequence::Repeat_Album)
|
|
|
|
ui_->action_next_album->setDisabled(true);
|
|
|
|
|
2018-11-28 21:08:23 +01:00
|
|
|
initialized_ = true;
|
|
|
|
|
2011-04-24 20:07:09 +02:00
|
|
|
qLog(Debug) << "Started";
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2020-09-18 16:15:19 +02:00
|
|
|
MainWindow::~MainWindow() { delete ui_; }
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-04-07 01:46:34 +02:00
|
|
|
void MainWindow::ReloadSettings() {
|
2010-04-14 21:38:09 +02:00
|
|
|
#ifndef Q_OS_DARWIN
|
2018-10-01 10:40:31 +02:00
|
|
|
bool show_tray =
|
|
|
|
settings_.value("showtray", QSystemTrayIcon::isSystemTrayAvailable())
|
|
|
|
.toBool();
|
2010-02-26 19:22:44 +01:00
|
|
|
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetVisible(show_tray);
|
|
|
|
if ((!show_tray || !QSystemTrayIcon::isSystemTrayAvailable()) && !isVisible())
|
|
|
|
show();
|
2010-04-14 21:38:09 +02:00
|
|
|
#endif
|
2010-05-15 19:45:04 +02:00
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
doubleclick_addmode_ = AddBehaviour(
|
|
|
|
settings_.value("doubleclick_addmode", AddBehaviour_Append).toInt());
|
2011-01-24 22:16:26 +01:00
|
|
|
doubleclick_playmode_ = PlayBehaviour(
|
2019-09-07 06:02:48 +02:00
|
|
|
settings_.value("doubleclick_playmode", PlayBehaviour_IfStopped).toInt());
|
|
|
|
doubleclick_playlist_addmode_ = PlaylistAddBehaviour(
|
|
|
|
settings_.value("doubleclick_playlist_addmode", PlaylistAddBehaviour_Play)
|
|
|
|
.toInt());
|
|
|
|
menu_playmode_ = PlayBehaviour(
|
|
|
|
settings_.value("menu_playmode", PlayBehaviour_IfStopped).toInt());
|
2016-09-06 14:28:25 +02:00
|
|
|
|
|
|
|
bool show_sidebar = settings_.value("show_sidebar", true).toBool();
|
2016-10-07 13:29:50 +02:00
|
|
|
ui_->sidebar_layout->setVisible(show_sidebar);
|
2016-09-06 14:28:25 +02:00
|
|
|
ui_->action_toggle_show_sidebar->setChecked(show_sidebar);
|
2010-05-15 19:45:04 +02:00
|
|
|
}
|
|
|
|
|
2011-01-02 15:50:17 +01:00
|
|
|
void MainWindow::ReloadAllSettings() {
|
|
|
|
ReloadSettings();
|
|
|
|
|
|
|
|
// Other settings
|
2012-03-09 13:15:24 +01:00
|
|
|
app_->ReloadSettings();
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->global_search()->ReloadSettings();
|
|
|
|
app_->library()->ReloadSettings();
|
|
|
|
app_->player()->ReloadSettings();
|
2011-01-02 15:50:17 +01:00
|
|
|
osd_->ReloadSettings();
|
2011-11-05 20:09:02 +01:00
|
|
|
library_view_->ReloadSettings();
|
2011-01-02 15:50:17 +01:00
|
|
|
song_info_view_->ReloadSettings();
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->engine()->ReloadSettings();
|
2018-01-03 16:24:56 +01:00
|
|
|
ui_->playlist->ReloadSettings();
|
2011-01-02 15:50:17 +01:00
|
|
|
ui_->playlist->view()->ReloadSettings();
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->internet_model()->ReloadSettings();
|
2011-03-12 22:19:32 +01:00
|
|
|
#ifdef HAVE_WIIMOTEDEV
|
2011-01-02 15:50:17 +01:00
|
|
|
wiimotedev_shortcuts_->ReloadSettings();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::RefreshStyleSheet() { setStyleSheet(styleSheet()); }
|
2009-12-24 20:16:07 +01:00
|
|
|
void MainWindow::MediaStopped() {
|
2010-11-23 20:38:15 +01:00
|
|
|
setWindowTitle(QCoreApplication::applicationName());
|
|
|
|
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_stop->setEnabled(false);
|
|
|
|
ui_->action_stop_after_this_track->setEnabled(false);
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_play_pause->setIcon(
|
|
|
|
IconLoader::Load("media-playback-start", IconLoader::Base));
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_play_pause->setText(tr("Play"));
|
2009-12-29 17:15:21 +01:00
|
|
|
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_play_pause->setEnabled(true);
|
2009-12-29 20:22:02 +01:00
|
|
|
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_love->setEnabled(false);
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->LastFMButtonLoveStateChanged(false);
|
2009-12-29 20:57:33 +01:00
|
|
|
|
|
|
|
track_position_timer_->stop();
|
2014-05-19 17:51:40 +02:00
|
|
|
track_slider_timer_->stop();
|
2010-06-16 21:21:15 +02:00
|
|
|
ui_->track_slider->SetStopped();
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) {
|
|
|
|
tray_icon_->SetProgress(0);
|
|
|
|
tray_icon_->SetStopped();
|
|
|
|
}
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::MediaPaused() {
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_stop->setEnabled(true);
|
|
|
|
ui_->action_stop_after_this_track->setEnabled(true);
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_play_pause->setIcon(
|
|
|
|
IconLoader::Load("media-playback-start", IconLoader::Base));
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_play_pause->setText(tr("Play"));
|
2009-12-29 17:15:21 +01:00
|
|
|
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_play_pause->setEnabled(true);
|
2009-12-29 20:57:33 +01:00
|
|
|
|
|
|
|
track_position_timer_->stop();
|
2014-05-19 17:51:40 +02:00
|
|
|
track_slider_timer_->stop();
|
2010-04-19 15:53:26 +02:00
|
|
|
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetPaused();
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::MediaPlaying() {
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_stop->setEnabled(true);
|
|
|
|
ui_->action_stop_after_this_track->setEnabled(true);
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_play_pause->setIcon(
|
|
|
|
IconLoader::Load("media-playback-pause", IconLoader::Base));
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_play_pause->setText(tr("Pause"));
|
2009-12-29 17:15:21 +01:00
|
|
|
|
2020-08-05 18:46:07 +02:00
|
|
|
const PlaylistItemPtr item = app_->player()->GetCurrentItem();
|
2020-08-06 15:41:00 +02:00
|
|
|
if (!item) {
|
|
|
|
qLog(Debug) << "MediaPlaying: no current item -- not enabling buttons etc";
|
|
|
|
return;
|
|
|
|
}
|
2020-08-05 18:46:07 +02:00
|
|
|
|
2020-09-18 16:15:19 +02:00
|
|
|
const bool enable_play_pause =
|
|
|
|
!(item->options() & PlaylistItem::PauseDisabled);
|
2011-03-07 22:33:01 +01:00
|
|
|
ui_->action_play_pause->setEnabled(enable_play_pause);
|
2009-12-29 20:22:02 +01:00
|
|
|
|
2020-09-18 16:15:19 +02:00
|
|
|
const bool can_seek = !(item->options() & PlaylistItem::SeekDisabled);
|
2011-11-28 19:19:11 +01:00
|
|
|
ui_->track_slider->SetCanSeek(can_seek);
|
|
|
|
|
2020-08-05 18:46:07 +02:00
|
|
|
// Set the rate/love icon
|
2020-08-26 17:06:13 +02:00
|
|
|
if (IsLastFmEnabled()) {
|
|
|
|
ui_->action_love->setIcon(IconLoader::Load("love", IconLoader::Lastfm));
|
|
|
|
ui_->action_love->setEnabled(true);
|
2020-09-18 16:15:19 +02:00
|
|
|
} else if (item->IsLocalLibraryItem()) {
|
|
|
|
ui_->action_love->setIcon(
|
|
|
|
IconLoader::Load("rate-enabled", IconLoader::Base));
|
2020-08-26 17:06:13 +02:00
|
|
|
ui_->action_love->setEnabled(true);
|
2020-09-18 16:15:19 +02:00
|
|
|
} else {
|
2020-08-26 17:06:13 +02:00
|
|
|
ui_->action_love->setEnabled(false);
|
2020-08-05 18:46:07 +02:00
|
|
|
}
|
|
|
|
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) {
|
2020-08-26 17:06:13 +02:00
|
|
|
const bool enable_love = app_->scrobbler()->IsScrobblingEnabled();
|
2018-10-01 10:40:31 +02:00
|
|
|
tray_icon_->LastFMButtonLoveStateChanged(enable_love);
|
|
|
|
tray_icon_->SetPlaying(enable_play_pause, enable_love);
|
|
|
|
}
|
2010-12-18 18:28:02 +01:00
|
|
|
#else
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetPlaying(enable_play_pause);
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
2010-01-15 18:12:47 +01:00
|
|
|
|
2009-12-29 20:57:33 +01:00
|
|
|
track_position_timer_->start();
|
2014-05-19 17:51:40 +02:00
|
|
|
track_slider_timer_->start();
|
2009-12-29 20:57:33 +01:00
|
|
|
UpdateTrackPosition();
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2010-11-21 22:36:27 +01:00
|
|
|
void MainWindow::VolumeChanged(int volume) {
|
|
|
|
ui_->action_mute->setChecked(!volume);
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->MuteButtonStateChanged(!volume);
|
2010-11-21 22:36:27 +01:00
|
|
|
}
|
|
|
|
|
2010-11-23 20:38:15 +01:00
|
|
|
void MainWindow::SongChanged(const Song& song) {
|
|
|
|
setWindowTitle(song.PrettyTitleWithArtist());
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetProgress(0);
|
2011-04-07 18:25:52 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBLASTFM
|
|
|
|
if (ui_->action_toggle_scrobbling->isVisible())
|
2014-03-27 18:55:58 +01:00
|
|
|
SetToggleScrobblingIcon(app_->scrobbler()->IsScrobblingEnabled());
|
2011-04-07 18:25:52 +02:00
|
|
|
#endif
|
2010-11-23 20:38:15 +01:00
|
|
|
}
|
|
|
|
|
2010-10-17 21:27:31 +02:00
|
|
|
void MainWindow::TrackSkipped(PlaylistItemPtr item) {
|
|
|
|
// If it was a library item then we have to increment its skipped count in
|
|
|
|
// the database.
|
2011-04-28 12:32:56 +02:00
|
|
|
if (item && item->IsLocalLibraryItem() && item->Metadata().id() != -1 &&
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->active()->get_lastfm_status() !=
|
|
|
|
Playlist::LastFM_Scrobbled &&
|
|
|
|
app_->playlist_manager()->active()->get_lastfm_status() !=
|
|
|
|
Playlist::LastFM_Queued) {
|
2010-11-01 22:15:52 +01:00
|
|
|
Song song = item->Metadata();
|
2012-02-12 14:41:50 +01:00
|
|
|
const qint64 position = app_->player()->engine()->position_nanosec();
|
|
|
|
const qint64 length = app_->player()->engine()->length_nanosec();
|
2010-11-01 22:15:52 +01:00
|
|
|
const float percentage = (length == 0 ? 1 : float(position) / length);
|
|
|
|
|
2013-02-17 19:28:11 +01:00
|
|
|
const qint64 seconds_left = (length - position) / kNsecPerSec;
|
|
|
|
const qint64 seconds_total = length / kNsecPerSec;
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (((0.05 * seconds_total > 60 && percentage < 0.98) ||
|
|
|
|
percentage < 0.95) &&
|
|
|
|
seconds_left > 5) { // Never count the skip if under 5 seconds left
|
2013-02-17 19:28:11 +01:00
|
|
|
app_->library_backend()->IncrementSkipCountAsync(song.id(), percentage);
|
|
|
|
}
|
2010-10-17 21:27:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2009-12-29 21:48:50 +01:00
|
|
|
void MainWindow::ScrobblingEnabledChanged(bool value) {
|
2011-04-07 18:25:52 +02:00
|
|
|
if (ui_->action_toggle_scrobbling->isVisible())
|
|
|
|
SetToggleScrobblingIcon(value);
|
|
|
|
|
2014-02-14 15:51:08 +01:00
|
|
|
if (app_->player()->GetState() != Engine::Idle) {
|
2009-12-30 05:14:29 +01:00
|
|
|
return;
|
2014-02-07 16:34:20 +01:00
|
|
|
} else {
|
|
|
|
// invalidate current song, we will scrobble the next one
|
|
|
|
if (app_->playlist_manager()->active()->get_lastfm_status() ==
|
2014-02-14 14:36:47 +01:00
|
|
|
Playlist::LastFM_New) {
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->active()->set_lastfm_status(
|
|
|
|
Playlist::LastFM_Seeked);
|
2014-02-14 14:36:47 +01:00
|
|
|
}
|
2011-04-07 18:25:52 +02:00
|
|
|
}
|
2009-12-30 05:14:29 +01:00
|
|
|
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_love->setEnabled(value);
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->LastFMButtonLoveStateChanged(value);
|
2009-12-29 21:48:50 +01:00
|
|
|
}
|
2010-12-18 18:28:02 +01:00
|
|
|
#endif
|
2009-12-29 21:48:50 +01:00
|
|
|
|
2010-04-07 21:26:49 +02:00
|
|
|
void MainWindow::LastFMButtonVisibilityChanged(bool value) {
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_love->setVisible(value);
|
|
|
|
ui_->last_fm_controls->setVisible(value);
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->LastFMButtonVisibilityChanged(value);
|
2010-04-07 21:26:49 +02:00
|
|
|
}
|
|
|
|
|
2011-04-07 18:25:52 +02:00
|
|
|
void MainWindow::ScrobbleButtonVisibilityChanged(bool value) {
|
|
|
|
ui_->action_toggle_scrobbling->setVisible(value);
|
|
|
|
ui_->scrobbling_button->setVisible(value);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// when you reshow the buttons
|
2011-04-07 18:25:52 +02:00
|
|
|
if (value) {
|
2014-02-07 16:34:20 +01:00
|
|
|
// check if the song was scrobbled
|
|
|
|
if (app_->playlist_manager()->active()->get_lastfm_status() ==
|
|
|
|
Playlist::LastFM_Scrobbled) {
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_toggle_scrobbling->setIcon(
|
|
|
|
IconLoader::Load("as", IconLoader::Lastfm));
|
2011-04-07 18:25:52 +02:00
|
|
|
} else {
|
|
|
|
#ifdef HAVE_LIBLASTFM
|
2014-03-27 18:55:58 +01:00
|
|
|
SetToggleScrobblingIcon(app_->scrobbler()->IsScrobblingEnabled());
|
2011-04-07 18:25:52 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
void MainWindow::SaveSettings(QSettings* settings) {
|
2018-11-28 21:08:23 +01:00
|
|
|
if (!initialized_) return;
|
2019-09-07 06:02:48 +02:00
|
|
|
settings->beginGroup(kSettingsGroup);
|
|
|
|
if (dirty_geometry_) SaveGeometry(settings);
|
|
|
|
if (dirty_playback_) SavePlaybackStatus(settings);
|
|
|
|
settings->endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::changeEvent(QEvent*) {
|
|
|
|
dirty_geometry_ = true;
|
|
|
|
app_->DirtySettings();
|
2018-11-28 21:08:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::resizeEvent(QResizeEvent*) {
|
2019-09-07 06:02:48 +02:00
|
|
|
dirty_geometry_ = true;
|
|
|
|
app_->DirtySettings();
|
2018-11-28 21:08:23 +01:00
|
|
|
}
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
void MainWindow::SaveGeometry(QSettings* settings) {
|
2018-11-28 21:08:23 +01:00
|
|
|
if (!initialized_) return;
|
2019-09-07 06:02:48 +02:00
|
|
|
dirty_geometry_ = false;
|
2018-11-28 21:08:23 +01:00
|
|
|
|
2015-10-20 11:44:42 +02:00
|
|
|
was_maximized_ = isMaximized();
|
2019-09-07 06:02:48 +02:00
|
|
|
settings->setValue("maximized", was_maximized_);
|
2015-10-20 11:44:42 +02:00
|
|
|
// Save the geometry only when mainwindow is not in maximized state
|
|
|
|
if (!was_maximized_) {
|
2019-09-07 06:02:48 +02:00
|
|
|
settings->setValue("geometry", saveGeometry());
|
2015-10-20 11:44:42 +02:00
|
|
|
}
|
2019-09-07 06:02:48 +02:00
|
|
|
settings->setValue("splitter_state", ui_->splitter->saveState());
|
|
|
|
settings->setValue("current_tab", ui_->tabs->currentIndex());
|
|
|
|
settings->setValue("tab_mode", ui_->tabs->mode());
|
2018-01-10 10:22:05 +01:00
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
// Leaving this here for now
|
|
|
|
ui_->tabs->saveSettings(settings);
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2019-09-07 06:02:48 +02:00
|
|
|
void MainWindow::SavePlaybackStatus(QSettings* settings) {
|
|
|
|
dirty_playback_ = false;
|
|
|
|
settings->setValue("playback_state", app_->player()->GetState());
|
2013-03-03 22:29:27 +01:00
|
|
|
if (app_->player()->GetState() == Engine::Playing ||
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->player()->GetState() == Engine::Paused) {
|
2019-09-07 06:02:48 +02:00
|
|
|
settings->setValue(
|
2014-02-07 16:34:20 +01:00
|
|
|
"playback_position",
|
|
|
|
app_->player()->engine()->position_nanosec() / kNsecPerSec);
|
2013-03-03 22:29:27 +01:00
|
|
|
} else {
|
2019-09-07 06:02:48 +02:00
|
|
|
settings->setValue("playback_position", 0);
|
2013-03-03 22:29:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::LoadPlaybackStatus() {
|
2014-02-07 16:34:20 +01:00
|
|
|
bool resume_playback =
|
2019-09-07 06:02:48 +02:00
|
|
|
settings_.value("resume_playback_after_start", false).toBool();
|
2014-02-07 16:34:20 +01:00
|
|
|
saved_playback_state_ = static_cast<Engine::State>(
|
2019-09-07 06:02:48 +02:00
|
|
|
settings_.value("playback_state", Engine::Empty).toInt());
|
|
|
|
saved_playback_position_ = settings_.value("playback_position", 0).toDouble();
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!resume_playback || saved_playback_state_ == Engine::Empty ||
|
|
|
|
saved_playback_state_ == Engine::Idle) {
|
2013-03-03 22:29:27 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-12-22 06:55:37 +01:00
|
|
|
connect(app_->playlist_manager()->active(), SIGNAL(RestoreFinished()),
|
|
|
|
SLOT(ResumePlayback()));
|
2013-03-03 22:29:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::ResumePlayback() {
|
|
|
|
qLog(Debug) << "Resuming playback";
|
|
|
|
|
2016-12-22 06:55:37 +01:00
|
|
|
disconnect(app_->playlist_manager()->active(), SIGNAL(RestoreFinished()),
|
|
|
|
this, SLOT(ResumePlayback()));
|
|
|
|
|
2013-03-03 22:29:27 +01:00
|
|
|
if (saved_playback_state_ == Engine::Paused) {
|
2015-06-02 18:11:58 +02:00
|
|
|
NewClosure(app_->player(), SIGNAL(Playing()), app_->player(),
|
|
|
|
SLOT(PlayPause()));
|
2013-03-03 22:29:27 +01:00
|
|
|
}
|
2015-06-02 18:11:58 +02:00
|
|
|
|
|
|
|
app_->player()->Play();
|
|
|
|
|
2019-12-14 17:05:08 +01:00
|
|
|
connect(track_position_timer_, SIGNAL(timeout()),
|
|
|
|
SLOT(ResumePlaybackPosition()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::ResumePlaybackPosition() {
|
|
|
|
// We must wait until the song has a length because
|
|
|
|
// seeking a song without length does not work
|
|
|
|
if (app_->player()->engine()->length_nanosec() > 0) {
|
|
|
|
disconnect(track_position_timer_, SIGNAL(timeout()), this,
|
|
|
|
SLOT(ResumePlaybackPosition()));
|
|
|
|
|
|
|
|
app_->player()->SeekTo(saved_playback_position_);
|
|
|
|
}
|
2013-03-03 22:29:27 +01:00
|
|
|
}
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
void MainWindow::PlayIndex(const QModelIndex& index) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!index.isValid()) return;
|
2009-12-24 20:16:07 +01:00
|
|
|
|
2010-05-25 21:39:04 +02:00
|
|
|
int row = index.row();
|
2012-02-12 14:41:50 +01:00
|
|
|
if (index.model() == app_->playlist_manager()->current()->proxy()) {
|
2010-05-25 21:39:04 +02:00
|
|
|
// The index was in the proxy model (might've been filtered), so we need
|
|
|
|
// to get the actual row in the source model.
|
2014-02-07 16:34:20 +01:00
|
|
|
row =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
2010-05-25 21:39:04 +02:00
|
|
|
}
|
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->SetActiveToCurrent();
|
|
|
|
app_->player()->PlayAt(row, Engine::Manual, true);
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2015-08-10 05:25:56 +02:00
|
|
|
void MainWindow::PlaylistDoubleClick(const QModelIndex& index) {
|
|
|
|
if (!index.isValid()) return;
|
|
|
|
|
|
|
|
int row = index.row();
|
|
|
|
if (index.model() == app_->playlist_manager()->current()->proxy()) {
|
|
|
|
// The index was in the proxy model (might've been filtered), so we need
|
|
|
|
// to get the actual row in the source model.
|
|
|
|
row =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndexList dummyIndexList;
|
|
|
|
|
|
|
|
switch (doubleclick_playlist_addmode_) {
|
|
|
|
case PlaylistAddBehaviour_Play:
|
2015-09-26 05:34:09 +02:00
|
|
|
app_->playlist_manager()->SetActiveToCurrent();
|
|
|
|
app_->player()->PlayAt(row, Engine::Manual, true);
|
2015-08-10 05:25:56 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PlaylistAddBehaviour_Enqueue:
|
|
|
|
dummyIndexList.append(index);
|
2015-08-14 22:48:01 +02:00
|
|
|
app_->playlist_manager()->current()->queue()->ToggleTracks(
|
|
|
|
dummyIndexList);
|
2015-09-26 05:34:09 +02:00
|
|
|
if (app_->player()->GetState() != Engine::Playing) {
|
2017-12-14 22:48:03 +01:00
|
|
|
app_->playlist_manager()->SetActiveToCurrent();
|
2015-09-26 05:34:09 +02:00
|
|
|
app_->player()->PlayAt(
|
|
|
|
app_->playlist_manager()->current()->queue()->TakeNext(),
|
|
|
|
Engine::Manual, true);
|
2015-08-10 05:25:56 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-24 20:16:07 +01:00
|
|
|
void MainWindow::VolumeWheelEvent(int delta) {
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->volume->setValue(ui_->volume->value() + delta / 30);
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2010-06-22 13:52:55 +02:00
|
|
|
void MainWindow::ToggleShowHide() {
|
|
|
|
if (settings_.value("hidden").toBool()) {
|
|
|
|
show();
|
2020-11-01 20:55:45 +01:00
|
|
|
activateWindow();
|
2010-06-22 13:52:55 +02:00
|
|
|
SetHiddenInTray(false);
|
|
|
|
} else if (isActiveWindow()) {
|
|
|
|
hide();
|
|
|
|
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
|
|
|
SetHiddenInTray(true);
|
|
|
|
} else if (isMinimized()) {
|
|
|
|
hide();
|
|
|
|
setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
|
|
|
|
SetHiddenInTray(false);
|
2014-02-07 16:34:20 +01:00
|
|
|
} else if (!isVisible()) {
|
2010-09-02 15:41:25 +02:00
|
|
|
show();
|
|
|
|
activateWindow();
|
2010-06-22 13:52:55 +02:00
|
|
|
} else {
|
|
|
|
// Window is not hidden but does not have focus; bring it to front.
|
|
|
|
activateWindow();
|
|
|
|
raise();
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::StopAfterCurrent() {
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->active()->StopAfter(
|
|
|
|
app_->playlist_manager()->active()->current_row());
|
|
|
|
emit StopAfterToggled(
|
|
|
|
app_->playlist_manager()->active()->stop_after_current());
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent* event) {
|
2020-09-23 11:39:59 +02:00
|
|
|
if (!tray_icon_ ||
|
|
|
|
!settings_.value("keeprunning", tray_icon_->IsVisible()).toBool())
|
2018-03-10 00:11:04 +01:00
|
|
|
Exit();
|
2020-09-23 11:39:59 +02:00
|
|
|
|
|
|
|
QMainWindow::closeEvent(event);
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2020-11-01 20:55:45 +01:00
|
|
|
void MainWindow::hideEvent(QHideEvent* event) {
|
|
|
|
settings_.setValue("hidden", true);
|
|
|
|
QMainWindow::hideEvent(event);
|
|
|
|
}
|
2010-04-19 16:10:31 +02:00
|
|
|
|
2020-11-01 20:55:45 +01:00
|
|
|
void MainWindow::showEvent(QShowEvent* event) {
|
|
|
|
settings_.setValue("hidden", false);
|
|
|
|
QMainWindow::showEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::SetHiddenInTray(bool hidden) {
|
2010-04-19 16:23:57 +02:00
|
|
|
// Some window managers don't remember maximized state between calls to
|
|
|
|
// hide() and show(), so we have to remember it ourself.
|
2010-04-19 16:10:31 +02:00
|
|
|
if (hidden) {
|
2019-07-13 13:57:27 +02:00
|
|
|
QTimer::singleShot(0, this, &QWidget::hide);
|
2010-04-19 16:10:31 +02:00
|
|
|
} else {
|
|
|
|
if (was_maximized_)
|
|
|
|
showMaximized();
|
|
|
|
else
|
|
|
|
show();
|
|
|
|
}
|
2009-12-24 20:16:07 +01:00
|
|
|
}
|
|
|
|
|
2009-12-24 21:27:32 +01:00
|
|
|
void MainWindow::FilePathChanged(const QString& path) {
|
2010-02-27 17:52:18 +01:00
|
|
|
settings_.setValue("file_path", path);
|
2009-12-24 21:27:32 +01:00
|
|
|
}
|
2009-12-29 20:57:33 +01:00
|
|
|
|
2011-03-21 16:15:17 +01:00
|
|
|
void MainWindow::Seeked(qlonglong microseconds) {
|
|
|
|
const int position = microseconds / kUsecPerSec;
|
2014-02-07 16:34:20 +01:00
|
|
|
const int length =
|
|
|
|
app_->player()->GetCurrentItem()->Metadata().length_nanosec() /
|
|
|
|
kNsecPerSec;
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetProgress(double(position) / length * 100);
|
2011-04-07 18:25:52 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// if we seeked, scrobbling is canceled, update the icon
|
|
|
|
if (ui_->action_toggle_scrobbling->isVisible()) SetToggleScrobblingIcon(true);
|
2011-03-21 16:15:17 +01:00
|
|
|
}
|
|
|
|
|
2018-10-20 13:57:49 +02:00
|
|
|
/**
|
|
|
|
* Update track position, tray icon, playcount
|
|
|
|
*/
|
2009-12-29 20:57:33 +01:00
|
|
|
void MainWindow::UpdateTrackPosition() {
|
2010-01-17 22:11:03 +01:00
|
|
|
// Track position in seconds
|
2012-02-12 14:41:50 +01:00
|
|
|
Playlist* playlist = app_->playlist_manager()->active();
|
2011-04-17 16:11:37 +02:00
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
PlaylistItemPtr item(app_->player()->GetCurrentItem());
|
2011-02-13 19:29:27 +01:00
|
|
|
const int position = std::floor(
|
2012-02-12 14:41:50 +01:00
|
|
|
float(app_->player()->engine()->position_nanosec()) / kNsecPerSec + 0.5);
|
2014-05-29 13:33:53 +02:00
|
|
|
const int length = app_->player()->engine()->length_nanosec() / kNsecPerSec;
|
2011-04-17 16:11:37 +02:00
|
|
|
const int scrobble_point = playlist->scrobble_point_nanosec() / kNsecPerSec;
|
2018-10-20 13:57:49 +02:00
|
|
|
const int play_count_point =
|
|
|
|
playlist->play_count_point_nanosec() / kNsecPerSec;
|
2009-12-29 20:57:33 +01:00
|
|
|
|
2010-01-18 03:49:07 +01:00
|
|
|
if (length <= 0) {
|
|
|
|
// Probably a stream that we don't know the length of
|
|
|
|
return;
|
|
|
|
}
|
2018-10-20 13:57:49 +02:00
|
|
|
|
2011-04-07 18:25:52 +02:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2018-10-20 13:57:49 +02:00
|
|
|
// Time to scrobble?
|
2011-04-17 16:11:37 +02:00
|
|
|
const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() &&
|
2014-03-27 18:55:58 +01:00
|
|
|
app_->scrobbler()->IsScrobblingEnabled() &&
|
|
|
|
app_->scrobbler()->IsAuthenticated();
|
2010-01-18 03:49:07 +01:00
|
|
|
|
2011-04-17 16:11:37 +02:00
|
|
|
if (position >= scrobble_point) {
|
|
|
|
if (playlist->get_lastfm_status() == Playlist::LastFM_New) {
|
2014-03-27 18:55:58 +01:00
|
|
|
if (app_->scrobbler()->IsScrobblingEnabled() &&
|
|
|
|
app_->scrobbler()->IsAuthenticated()) {
|
2014-01-18 23:13:23 +01:00
|
|
|
app_->scrobbler()->CacheSong(scrobble_point);
|
2014-02-07 16:34:20 +01:00
|
|
|
}
|
2011-04-17 16:11:37 +02:00
|
|
|
}
|
2018-10-20 13:57:49 +02:00
|
|
|
}
|
|
|
|
#endif
|
2011-04-17 01:17:48 +02:00
|
|
|
|
2018-10-20 13:57:49 +02:00
|
|
|
if (position >= play_count_point) {
|
2010-10-17 21:27:31 +02:00
|
|
|
// Update the play count for the song if it's from the library
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!playlist->have_incremented_playcount() && item->IsLocalLibraryItem() &&
|
|
|
|
item->Metadata().id() != -1 &&
|
2011-04-17 16:11:37 +02:00
|
|
|
playlist->get_lastfm_status() != Playlist::LastFM_Seeked) {
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->library_backend()->IncrementPlayCountAsync(item->Metadata().id());
|
2011-04-17 16:11:37 +02:00
|
|
|
playlist->set_have_incremented_playcount();
|
2010-10-17 21:27:31 +02:00
|
|
|
}
|
2009-12-29 20:57:33 +01:00
|
|
|
}
|
2010-01-15 18:12:47 +01:00
|
|
|
|
2015-07-02 14:59:30 +02:00
|
|
|
// (just after) the scrobble point is a good point to change tracks in intro
|
|
|
|
// mode
|
2015-06-15 22:27:40 +02:00
|
|
|
if (position >= scrobble_point + 5) {
|
|
|
|
if (playlist->sequence()->repeat_mode() == PlaylistSequence::Repeat_Intro) {
|
|
|
|
emit IntroPointReached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-17 22:11:03 +01:00
|
|
|
// Update the tray icon every 10 seconds
|
2010-10-17 20:26:25 +02:00
|
|
|
if (position % 10 == 0) {
|
2018-10-20 13:57:49 +02:00
|
|
|
qLog(Debug) << "position:" << position
|
|
|
|
<< ", scrobble point:" << scrobble_point
|
|
|
|
<< ", lastfm status:" << playlist->get_lastfm_status()
|
|
|
|
<< ", play count point:" << play_count_point
|
2019-08-22 05:43:16 +02:00
|
|
|
<< ", is local library item:" << item->IsLocalLibraryItem()
|
2018-10-20 13:57:49 +02:00
|
|
|
<< ", playlist have incremented playcount: "
|
|
|
|
<< playlist->have_incremented_playcount();
|
|
|
|
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetProgress(double(position) / length * 100);
|
2011-04-07 18:25:52 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// if we're waiting for the scrobble point, update the icon
|
2011-04-07 18:25:52 +02:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2011-04-17 16:11:37 +02:00
|
|
|
if (position < scrobble_point &&
|
|
|
|
playlist->get_lastfm_status() == Playlist::LastFM_New &&
|
|
|
|
last_fm_enabled) {
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->action_toggle_scrobbling->setIcon(
|
|
|
|
CreateOverlayedIcon(position, scrobble_point));
|
2011-04-07 18:25:52 +02:00
|
|
|
}
|
|
|
|
#endif
|
2010-01-17 22:11:03 +01:00
|
|
|
}
|
2009-12-29 20:57:33 +01:00
|
|
|
}
|
2009-12-29 21:48:50 +01:00
|
|
|
|
2014-05-19 17:51:40 +02:00
|
|
|
void MainWindow::UpdateTrackSliderPosition() {
|
|
|
|
PlaylistItemPtr item(app_->player()->GetCurrentItem());
|
|
|
|
|
|
|
|
const int slider_position = std::floor(
|
|
|
|
float(app_->player()->engine()->position_nanosec()) / kNsecPerMsec);
|
2014-05-29 13:33:53 +02:00
|
|
|
const int slider_length =
|
|
|
|
app_->player()->engine()->length_nanosec() / kNsecPerMsec;
|
2014-05-19 17:51:40 +02:00
|
|
|
|
|
|
|
// Update the slider
|
|
|
|
ui_->track_slider->SetValue(slider_position, slider_length);
|
|
|
|
}
|
|
|
|
|
2010-12-18 18:28:02 +01:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2011-04-16 17:27:34 +02:00
|
|
|
void MainWindow::ScrobbledRadioStream() {
|
|
|
|
ui_->action_love->setEnabled(true);
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->LastFMButtonLoveStateChanged(true);
|
2011-04-16 17:27:34 +02:00
|
|
|
}
|
2020-07-26 20:38:14 +02:00
|
|
|
#endif
|
2011-04-16 17:27:34 +02:00
|
|
|
|
2009-12-29 21:48:50 +01:00
|
|
|
void MainWindow::Love() {
|
2020-07-27 16:13:42 +02:00
|
|
|
Playlist* active_playlist = app_->playlist_manager()->active();
|
2020-08-26 17:06:13 +02:00
|
|
|
const PlaylistItemPtr item = active_playlist->current_item();
|
2020-07-26 20:38:14 +02:00
|
|
|
if (!item) {
|
|
|
|
// Don't make a big deal about it
|
|
|
|
qLog(Warning) << "Love: nothing playing so can't love it";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-26 17:06:13 +02:00
|
|
|
if (IsLastFmEnabled()) {
|
|
|
|
#ifdef HAVE_LIBLASTFM
|
|
|
|
app_->scrobbler()->Love();
|
|
|
|
ui_->action_love->setEnabled(false);
|
|
|
|
if (tray_icon_) tray_icon_->LastFMButtonLoveStateChanged(false);
|
|
|
|
#endif
|
2020-09-18 16:15:19 +02:00
|
|
|
} else if (item->IsLocalLibraryItem()) {
|
2020-07-27 16:13:42 +02:00
|
|
|
const Song& song = item->Metadata();
|
|
|
|
if (!song.is_valid() || song.id() == -1) return;
|
2020-07-26 20:38:14 +02:00
|
|
|
love_dialog_->SetSong(song);
|
|
|
|
love_dialog_->show();
|
2020-09-18 16:15:19 +02:00
|
|
|
} else {
|
2020-08-26 17:06:13 +02:00
|
|
|
qLog(Warning) << "Love: unable to love or rate";
|
2020-07-26 20:38:14 +02:00
|
|
|
}
|
2009-12-29 21:48:50 +01:00
|
|
|
}
|
2009-12-30 00:17:54 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::ApplyAddBehaviour(MainWindow::AddBehaviour b,
|
|
|
|
MimeData* data) const {
|
2011-01-24 22:16:26 +01:00
|
|
|
switch (b) {
|
2014-02-07 16:34:20 +01:00
|
|
|
case AddBehaviour_Append:
|
|
|
|
data->clear_first_ = false;
|
|
|
|
data->enqueue_now_ = false;
|
|
|
|
break;
|
2011-01-24 22:16:26 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
case AddBehaviour_Enqueue:
|
|
|
|
data->clear_first_ = false;
|
|
|
|
data->enqueue_now_ = true;
|
|
|
|
break;
|
2011-01-24 22:16:26 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
case AddBehaviour_Load:
|
|
|
|
data->clear_first_ = true;
|
|
|
|
data->enqueue_now_ = false;
|
|
|
|
break;
|
2011-02-09 18:51:59 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
case AddBehaviour_OpenInNew:
|
|
|
|
data->open_in_new_playlist_ = true;
|
|
|
|
break;
|
2011-01-24 22:16:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::ApplyPlayBehaviour(MainWindow::PlayBehaviour b,
|
|
|
|
MimeData* data) const {
|
2011-01-24 22:16:26 +01:00
|
|
|
switch (b) {
|
2014-02-07 16:34:20 +01:00
|
|
|
case PlayBehaviour_Always:
|
|
|
|
data->play_now_ = true;
|
|
|
|
break;
|
2011-01-24 22:16:26 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
case PlayBehaviour_Never:
|
|
|
|
data->play_now_ = false;
|
|
|
|
break;
|
2011-01-24 22:16:26 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
case PlayBehaviour_IfStopped:
|
|
|
|
data->play_now_ = !(app_->player()->GetState() == Engine::Playing);
|
|
|
|
break;
|
2011-01-24 22:16:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-10 23:26:13 +01:00
|
|
|
void MainWindow::AddToPlaylist(QMimeData* data) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!data) return;
|
2010-05-15 19:45:04 +02:00
|
|
|
|
2020-11-27 13:05:53 +01:00
|
|
|
Playlist* playlist = nullptr;
|
2011-01-10 23:26:13 +01:00
|
|
|
if (MimeData* mime_data = qobject_cast<MimeData*>(data)) {
|
|
|
|
// Should we replace the flags with the user's preference?
|
2011-09-19 00:26:21 +02:00
|
|
|
if (mime_data->override_user_settings_) {
|
|
|
|
// Do nothing
|
|
|
|
} else if (mime_data->from_doubleclick_) {
|
2011-01-24 22:16:26 +01:00
|
|
|
ApplyAddBehaviour(doubleclick_addmode_, mime_data);
|
|
|
|
ApplyPlayBehaviour(doubleclick_playmode_, mime_data);
|
|
|
|
} else {
|
|
|
|
ApplyPlayBehaviour(menu_playmode_, mime_data);
|
2011-01-10 23:26:13 +01:00
|
|
|
}
|
2011-02-09 18:51:59 +01:00
|
|
|
|
|
|
|
// Should we create a new playlist for the songs?
|
2014-02-07 16:34:20 +01:00
|
|
|
if (mime_data->open_in_new_playlist_) {
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->New(mime_data->get_name_for_new_playlist());
|
2011-02-09 18:51:59 +01:00
|
|
|
}
|
2020-11-27 13:05:53 +01:00
|
|
|
// or shall we drop the songs in another playlist?
|
|
|
|
else if (mime_data->playlist_id != -1)
|
|
|
|
playlist = app_->playlist_manager()->playlist(mime_data->playlist_id);
|
2010-05-25 21:39:04 +02:00
|
|
|
}
|
|
|
|
|
2020-11-27 13:05:53 +01:00
|
|
|
if (!playlist) playlist = app_->playlist_manager()->current();
|
|
|
|
|
|
|
|
playlist->dropMimeData(data, Qt::CopyAction, -1, 0, QModelIndex());
|
2011-01-10 23:26:13 +01:00
|
|
|
delete data;
|
2010-05-09 20:36:10 +02:00
|
|
|
}
|
|
|
|
|
2011-03-20 18:38:15 +01:00
|
|
|
void MainWindow::AddToPlaylist(QAction* action) {
|
|
|
|
int destination = action->data().toInt();
|
|
|
|
PlaylistItemList items;
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// get the selected playlist items
|
2014-03-27 18:55:58 +01:00
|
|
|
for (const QModelIndex& index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index.column() != 0) continue;
|
|
|
|
int row =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
2012-02-12 14:41:50 +01:00
|
|
|
items << app_->playlist_manager()->current()->item_at(row);
|
2011-03-20 18:38:15 +01:00
|
|
|
}
|
|
|
|
|
2011-03-25 20:16:12 +01:00
|
|
|
SongList songs;
|
2014-02-10 14:29:07 +01:00
|
|
|
for (PlaylistItemPtr item : items) {
|
2011-03-25 20:16:12 +01:00
|
|
|
songs << item->Metadata();
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// we're creating a new playlist
|
2011-03-20 18:38:15 +01:00
|
|
|
if (destination == -1) {
|
2014-02-07 16:34:20 +01:00
|
|
|
// save the current playlist to reactivate it
|
2012-02-12 14:41:50 +01:00
|
|
|
int current_id = app_->playlist_manager()->current_id();
|
2014-02-07 16:34:20 +01:00
|
|
|
// get the name from selection
|
|
|
|
app_->playlist_manager()->New(
|
|
|
|
app_->playlist_manager()->GetNameForNewPlaylist(songs));
|
2012-02-12 14:41:50 +01:00
|
|
|
if (app_->playlist_manager()->current()->id() != current_id) {
|
2014-02-07 16:34:20 +01:00
|
|
|
// I'm sure the new playlist was created and is selected, so I can just
|
|
|
|
// insert items
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->current()->InsertItems(items);
|
2014-02-07 16:34:20 +01:00
|
|
|
// set back the current playlist
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->SetCurrentPlaylist(current_id);
|
2011-03-20 18:38:15 +01:00
|
|
|
}
|
2014-02-07 16:34:20 +01:00
|
|
|
} else {
|
|
|
|
// we're inserting in a existing playlist
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->playlist(destination)->InsertItems(items);
|
2011-03-20 18:38:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::PlaylistRightClick(const QPoint& global_pos,
|
|
|
|
const QModelIndex& index) {
|
|
|
|
QModelIndex source_index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index);
|
2010-11-28 15:47:35 +01:00
|
|
|
playlist_menu_index_ = source_index;
|
|
|
|
|
2010-06-25 01:36:39 +02:00
|
|
|
// Is this song currently playing?
|
2014-02-07 16:34:20 +01:00
|
|
|
if (app_->playlist_manager()->current()->current_row() ==
|
|
|
|
source_index.row() &&
|
|
|
|
app_->player()->GetState() == Engine::Playing) {
|
2010-02-23 19:33:09 +01:00
|
|
|
playlist_play_pause_->setText(tr("Pause"));
|
2015-12-20 18:25:45 +01:00
|
|
|
playlist_play_pause_->setIcon(
|
|
|
|
IconLoader::Load("media-playback-pause", IconLoader::Base));
|
2010-01-15 17:22:19 +01:00
|
|
|
} else {
|
2010-02-23 19:33:09 +01:00
|
|
|
playlist_play_pause_->setText(tr("Play"));
|
2015-12-20 18:25:45 +01:00
|
|
|
playlist_play_pause_->setIcon(
|
|
|
|
IconLoader::Load("media-playback-start", IconLoader::Base));
|
2010-01-15 17:22:19 +01:00
|
|
|
}
|
|
|
|
|
2010-06-25 01:36:39 +02:00
|
|
|
// Are we allowed to pause?
|
2010-01-17 16:48:31 +01:00
|
|
|
if (index.isValid()) {
|
|
|
|
playlist_play_pause_->setEnabled(
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->current()->current_row() !=
|
|
|
|
source_index.row() ||
|
|
|
|
!(app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(source_index.row())
|
|
|
|
->options() &
|
|
|
|
PlaylistItem::PauseDisabled));
|
2010-01-17 16:48:31 +01:00
|
|
|
} else {
|
|
|
|
playlist_play_pause_->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
2010-01-15 17:22:19 +01:00
|
|
|
playlist_stop_after_->setEnabled(index.isValid());
|
|
|
|
|
2010-07-11 23:52:00 +02:00
|
|
|
// Are any of the selected songs editable or queued?
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndexList selection =
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes();
|
2011-02-21 19:18:16 +01:00
|
|
|
bool cue_selected = false;
|
2010-03-24 01:12:52 +01:00
|
|
|
int editable = 0;
|
2011-03-20 13:43:10 +01:00
|
|
|
int streams = 0;
|
2010-07-11 23:52:00 +02:00
|
|
|
int in_queue = 0;
|
|
|
|
int not_in_queue = 0;
|
2014-01-17 07:01:31 +01:00
|
|
|
int in_skipped = 0;
|
|
|
|
int not_in_skipped = 0;
|
2020-02-28 23:43:38 +01:00
|
|
|
for (const QModelIndex& idx : selection) {
|
|
|
|
if (idx.column() != 0) continue;
|
|
|
|
|
|
|
|
const QModelIndex src_idx =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(idx);
|
|
|
|
if (!src_idx.isValid()) continue;
|
2011-02-21 19:18:16 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
PlaylistItemPtr item =
|
2020-02-28 23:43:38 +01:00
|
|
|
app_->playlist_manager()->current()->item_at(src_idx.row());
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (item->Metadata().has_cue()) {
|
2011-02-21 19:18:16 +01:00
|
|
|
cue_selected = true;
|
2011-03-20 13:43:10 +01:00
|
|
|
} else if (item->Metadata().IsEditable()) {
|
2010-03-24 01:12:52 +01:00
|
|
|
editable++;
|
2010-01-16 17:12:47 +01:00
|
|
|
}
|
2010-07-11 23:52:00 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (item->Metadata().is_stream()) {
|
2011-03-20 13:43:10 +01:00
|
|
|
streams++;
|
|
|
|
}
|
|
|
|
|
2020-02-28 23:43:38 +01:00
|
|
|
if (src_idx.data(Playlist::Role_QueuePosition).toInt() == -1)
|
2014-02-07 16:34:20 +01:00
|
|
|
not_in_queue++;
|
2010-07-11 23:52:00 +02:00
|
|
|
else
|
2014-02-07 16:34:20 +01:00
|
|
|
in_queue++;
|
2014-01-17 07:01:31 +01:00
|
|
|
|
2014-02-08 02:47:35 +01:00
|
|
|
if (item->GetShouldSkip()) {
|
2014-01-17 07:01:31 +01:00
|
|
|
in_skipped++;
|
|
|
|
} else {
|
|
|
|
not_in_skipped++;
|
|
|
|
}
|
2010-01-16 17:12:47 +01:00
|
|
|
}
|
2011-02-21 19:18:16 +01:00
|
|
|
|
2011-03-20 13:43:10 +01:00
|
|
|
int all = not_in_queue + in_queue;
|
|
|
|
|
2011-02-21 19:18:16 +01:00
|
|
|
// this is available when we have one or many files and at least one of
|
|
|
|
// those is not CUE related
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_edit_track->setEnabled(editable);
|
2011-02-21 19:18:16 +01:00
|
|
|
ui_->action_edit_track->setVisible(editable);
|
2011-03-06 15:07:41 +01:00
|
|
|
ui_->action_auto_complete_tags->setEnabled(editable);
|
|
|
|
ui_->action_auto_complete_tags->setVisible(editable);
|
2011-02-21 19:18:16 +01:00
|
|
|
// the rest of the read / write actions work only when there are no CUEs
|
|
|
|
// involved
|
2014-02-07 16:34:20 +01:00
|
|
|
if (cue_selected) editable = 0;
|
2010-03-31 21:09:35 +02:00
|
|
|
|
2011-03-20 13:43:10 +01:00
|
|
|
// no 'show in browser' action if only streams are selected
|
|
|
|
playlist_open_in_browser_->setVisible(streams != all);
|
|
|
|
|
2016-12-21 17:57:04 +01:00
|
|
|
// If exactly one stream is selected, enable the 'show details' action.
|
|
|
|
ui_->action_view_stream_details->setEnabled(all == 1 && streams == 1);
|
|
|
|
ui_->action_view_stream_details->setVisible(all == 1 && streams == 1);
|
|
|
|
|
2010-03-31 21:09:35 +02:00
|
|
|
bool track_column = (index.column() == Playlist::Column_Track);
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_renumber_tracks->setVisible(editable >= 2 && track_column);
|
|
|
|
ui_->action_selection_set_value->setVisible(editable >= 2 && !track_column);
|
|
|
|
ui_->action_edit_value->setVisible(editable);
|
|
|
|
ui_->action_remove_from_playlist->setEnabled(!selection.isEmpty());
|
2010-03-24 01:12:52 +01:00
|
|
|
|
2014-01-11 21:03:32 +01:00
|
|
|
playlist_show_in_library_->setVisible(false);
|
2010-06-25 01:36:39 +02:00
|
|
|
playlist_copy_to_library_->setVisible(false);
|
|
|
|
playlist_move_to_library_->setVisible(false);
|
|
|
|
playlist_organise_->setVisible(false);
|
|
|
|
playlist_delete_->setVisible(false);
|
2010-12-11 11:54:42 +01:00
|
|
|
playlist_copy_to_device_->setVisible(false);
|
2010-06-25 01:36:39 +02:00
|
|
|
|
2017-08-09 15:12:36 +02:00
|
|
|
search_for_artist_->setVisible(all == 1);
|
|
|
|
search_for_album_->setVisible(all == 1);
|
|
|
|
|
2010-07-11 23:52:00 +02:00
|
|
|
if (in_queue == 1 && not_in_queue == 0)
|
|
|
|
playlist_queue_->setText(tr("Dequeue track"));
|
|
|
|
else if (in_queue > 1 && not_in_queue == 0)
|
|
|
|
playlist_queue_->setText(tr("Dequeue selected tracks"));
|
|
|
|
else if (in_queue == 0 && not_in_queue == 1)
|
|
|
|
playlist_queue_->setText(tr("Queue track"));
|
|
|
|
else if (in_queue == 0 && not_in_queue > 1)
|
|
|
|
playlist_queue_->setText(tr("Queue selected tracks"));
|
|
|
|
else
|
|
|
|
playlist_queue_->setText(tr("Toggle queue status"));
|
|
|
|
|
2018-04-14 22:57:06 +02:00
|
|
|
if (all > 1)
|
|
|
|
playlist_queue_play_next_->setText(tr("Play selected tracks next"));
|
|
|
|
else
|
|
|
|
playlist_queue_play_next_->setText(tr("Play next"));
|
2018-03-18 19:43:44 +01:00
|
|
|
|
2014-01-18 16:30:12 +01:00
|
|
|
if (in_skipped == 1 && not_in_skipped == 0)
|
|
|
|
playlist_skip_->setText(tr("Unskip track"));
|
|
|
|
else if (in_skipped > 1 && not_in_skipped == 0)
|
|
|
|
playlist_skip_->setText(tr("Unskip selected tracks"));
|
|
|
|
else if (in_skipped == 0 && not_in_skipped == 1)
|
2014-01-21 00:42:00 +01:00
|
|
|
playlist_skip_->setText(tr("Skip track"));
|
|
|
|
else if (in_skipped == 0 && not_in_skipped > 1)
|
|
|
|
playlist_skip_->setText(tr("Skip selected tracks"));
|
2014-01-18 16:30:12 +01:00
|
|
|
|
2010-07-11 23:52:00 +02:00
|
|
|
if (not_in_queue == 0)
|
2015-10-14 03:01:08 +02:00
|
|
|
playlist_queue_->setIcon(IconLoader::Load("go-previous", IconLoader::Base));
|
2010-07-11 23:52:00 +02:00
|
|
|
else
|
2015-10-14 03:01:08 +02:00
|
|
|
playlist_queue_->setIcon(IconLoader::Load("go-next", IconLoader::Base));
|
2010-07-11 23:52:00 +02:00
|
|
|
|
2018-04-14 22:57:06 +02:00
|
|
|
playlist_queue_play_next_->setIcon(
|
|
|
|
IconLoader::Load("go-next", IconLoader::Base));
|
2018-03-19 03:44:00 +01:00
|
|
|
|
2010-03-24 17:13:05 +01:00
|
|
|
if (!index.isValid()) {
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_selection_set_value->setVisible(false);
|
|
|
|
ui_->action_edit_value->setVisible(false);
|
2010-03-24 17:13:05 +01:00
|
|
|
} else {
|
|
|
|
Playlist::Column column = (Playlist::Column)index.column();
|
2014-02-07 16:34:20 +01:00
|
|
|
bool column_is_editable = Playlist::column_is_editable(column) && editable;
|
2010-03-26 00:48:58 +01:00
|
|
|
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_selection_set_value->setVisible(
|
2010-06-25 01:36:39 +02:00
|
|
|
ui_->action_selection_set_value->isVisible() && column_is_editable);
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->action_edit_value->setVisible(ui_->action_edit_value->isVisible() &&
|
|
|
|
column_is_editable);
|
2010-03-24 17:13:05 +01:00
|
|
|
|
|
|
|
QString column_name = Playlist::column_name(column);
|
2014-02-07 16:34:20 +01:00
|
|
|
QString column_value =
|
|
|
|
app_->playlist_manager()->current()->data(source_index).toString();
|
2010-03-24 17:13:05 +01:00
|
|
|
if (column_value.length() > 25)
|
|
|
|
column_value = column_value.left(25) + "...";
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
ui_->action_selection_set_value->setText(
|
|
|
|
tr("Set %1 to \"%2\"...").arg(column_name.toLower()).arg(column_value));
|
2010-05-10 23:50:31 +02:00
|
|
|
ui_->action_edit_value->setText(tr("Edit tag \"%1\"...").arg(column_name));
|
2010-06-25 01:36:39 +02:00
|
|
|
|
|
|
|
// Is it a library item?
|
2014-02-07 16:34:20 +01:00
|
|
|
PlaylistItemPtr item =
|
|
|
|
app_->playlist_manager()->current()->item_at(source_index.row());
|
2011-03-20 17:07:24 +01:00
|
|
|
if (item->IsLocalLibraryItem() && item->Metadata().id() != -1) {
|
2010-06-25 01:36:39 +02:00
|
|
|
playlist_organise_->setVisible(editable);
|
2014-01-11 21:03:32 +01:00
|
|
|
playlist_show_in_library_->setVisible(editable);
|
2010-06-25 01:36:39 +02:00
|
|
|
} else {
|
|
|
|
playlist_copy_to_library_->setVisible(editable);
|
|
|
|
playlist_move_to_library_->setVisible(editable);
|
|
|
|
}
|
2010-12-11 11:54:42 +01:00
|
|
|
|
|
|
|
playlist_delete_->setVisible(editable);
|
|
|
|
playlist_copy_to_device_->setVisible(editable);
|
2011-11-06 16:12:44 +01:00
|
|
|
|
|
|
|
// Remove old item actions, if any.
|
2014-02-10 14:29:07 +01:00
|
|
|
for (QAction* action : playlistitem_actions_) {
|
2011-11-06 16:12:44 +01:00
|
|
|
playlist_menu_->removeAction(action);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the new item actions, and add them
|
2012-07-29 03:11:00 +02:00
|
|
|
playlistitem_actions_ = item->actions();
|
2014-02-07 16:34:20 +01:00
|
|
|
playlistitem_actions_separator_->setVisible(
|
|
|
|
!playlistitem_actions_.isEmpty());
|
|
|
|
playlist_menu_->insertActions(playlistitem_actions_separator_,
|
|
|
|
playlistitem_actions_);
|
2010-03-24 17:13:05 +01:00
|
|
|
}
|
2010-01-16 17:12:47 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// if it isn't the first time we right click, we need to remove the menu
|
|
|
|
// previously created
|
2014-02-06 16:49:49 +01:00
|
|
|
if (playlist_add_to_another_ != nullptr) {
|
2011-03-20 18:38:15 +01:00
|
|
|
playlist_menu_->removeAction(playlist_add_to_another_);
|
|
|
|
delete playlist_add_to_another_;
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// create the playlist submenu
|
2011-03-20 18:38:15 +01:00
|
|
|
QMenu* add_to_another_menu = new QMenu(tr("Add to another playlist"), this);
|
2015-10-14 03:01:08 +02:00
|
|
|
add_to_another_menu->setIcon(IconLoader::Load("list-add", IconLoader::Base));
|
2011-03-20 19:31:15 +01:00
|
|
|
|
2014-02-12 22:11:28 +01:00
|
|
|
for (const PlaylistBackend::Playlist& playlist :
|
2014-02-10 14:29:07 +01:00
|
|
|
app_->playlist_backend()->GetAllOpenPlaylists()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
// don't add the current playlist
|
2012-02-12 14:41:50 +01:00
|
|
|
if (playlist.id != app_->playlist_manager()->current()->id()) {
|
2011-03-20 18:38:15 +01:00
|
|
|
QAction* existing_playlist = new QAction(this);
|
|
|
|
existing_playlist->setText(playlist.name);
|
|
|
|
existing_playlist->setData(playlist.id);
|
|
|
|
add_to_another_menu->addAction(existing_playlist);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
add_to_another_menu->addSeparator();
|
2014-02-07 16:34:20 +01:00
|
|
|
// add to a new playlist
|
2011-03-20 18:38:15 +01:00
|
|
|
QAction* new_playlist = new QAction(this);
|
|
|
|
new_playlist->setText(tr("New playlist"));
|
2014-02-07 16:34:20 +01:00
|
|
|
new_playlist->setData(-1); // fake id
|
2011-03-20 18:38:15 +01:00
|
|
|
add_to_another_menu->addAction(new_playlist);
|
2014-02-07 16:34:20 +01:00
|
|
|
playlist_add_to_another_ = playlist_menu_->insertMenu(
|
|
|
|
ui_->action_remove_from_playlist, add_to_another_menu);
|
2011-03-20 18:38:15 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(add_to_another_menu, SIGNAL(triggered(QAction*)),
|
|
|
|
SLOT(AddToPlaylist(QAction*)));
|
2011-03-20 18:38:15 +01:00
|
|
|
|
2010-01-15 17:22:19 +01:00
|
|
|
playlist_menu_->popup(global_pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::PlaylistPlay() {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (app_->playlist_manager()->current()->current_row() ==
|
|
|
|
playlist_menu_index_.row()) {
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->PlayPause();
|
2010-01-15 17:22:19 +01:00
|
|
|
} else {
|
2010-05-25 21:39:04 +02:00
|
|
|
PlayIndex(playlist_menu_index_);
|
2010-01-15 17:22:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::PlaylistStopAfter() {
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->current()->StopAfter(playlist_menu_index_.row());
|
2010-01-15 17:22:19 +01:00
|
|
|
}
|
2010-01-16 17:12:47 +01:00
|
|
|
|
|
|
|
void MainWindow::EditTracks() {
|
|
|
|
SongList songs;
|
2010-12-21 14:42:06 +01:00
|
|
|
PlaylistItemList items;
|
2010-01-16 17:12:47 +01:00
|
|
|
|
2014-03-27 18:55:58 +01:00
|
|
|
for (const QModelIndex& index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index.column() != 0) continue;
|
|
|
|
int row =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
2012-02-12 14:41:50 +01:00
|
|
|
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(row));
|
2010-12-21 14:42:06 +01:00
|
|
|
Song song = item->Metadata();
|
2010-01-16 17:12:47 +01:00
|
|
|
|
|
|
|
if (song.IsEditable()) {
|
|
|
|
songs << song;
|
2010-12-21 14:42:06 +01:00
|
|
|
items << item;
|
2010-01-16 17:12:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-21 14:42:06 +01:00
|
|
|
edit_tag_dialog_->SetSongs(songs, items);
|
|
|
|
edit_tag_dialog_->show();
|
|
|
|
}
|
2010-03-29 18:59:01 +02:00
|
|
|
|
2010-12-21 14:42:06 +01:00
|
|
|
void MainWindow::EditTagDialogAccepted() {
|
2014-02-10 14:29:07 +01:00
|
|
|
for (PlaylistItemPtr item : edit_tag_dialog_->playlist_items()) {
|
2010-12-21 14:42:06 +01:00
|
|
|
item->Reload();
|
|
|
|
}
|
2010-01-16 17:12:47 +01:00
|
|
|
|
2010-12-21 14:42:06 +01:00
|
|
|
// This is really lame but we don't know what rows have changed
|
|
|
|
ui_->playlist->view()->update();
|
2011-08-28 00:09:42 +02:00
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->current()->Save();
|
2010-01-16 17:12:47 +01:00
|
|
|
}
|
2010-01-16 18:52:51 +01:00
|
|
|
|
2016-12-21 17:57:04 +01:00
|
|
|
void MainWindow::DiscoverStreamDetails() {
|
|
|
|
int row = playlist_menu_index_.row();
|
|
|
|
Song song = app_->playlist_manager()->current()->item_at(row)->Metadata();
|
|
|
|
|
|
|
|
QString url = song.url().toString();
|
|
|
|
stream_discoverer_->Discover(url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::ShowStreamDetails(const StreamDetails& details) {
|
|
|
|
StreamDetailsDialog stream_details_dialog(this);
|
|
|
|
|
|
|
|
stream_details_dialog.setUrl(details.url);
|
|
|
|
stream_details_dialog.setFormat(details.format);
|
|
|
|
stream_details_dialog.setBitrate(details.bitrate);
|
|
|
|
stream_details_dialog.setChannels(details.channels);
|
|
|
|
stream_details_dialog.setDepth(details.depth);
|
|
|
|
stream_details_dialog.setSampleRate(details.sample_rate);
|
|
|
|
|
|
|
|
stream_details_dialog.exec();
|
|
|
|
}
|
|
|
|
|
2010-03-22 23:46:53 +01:00
|
|
|
void MainWindow::RenumberTracks() {
|
2011-08-28 00:16:57 +02:00
|
|
|
QModelIndexList indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes();
|
|
|
|
int track = 1;
|
2010-03-22 23:46:53 +01:00
|
|
|
|
2010-04-27 19:15:11 +02:00
|
|
|
// Get the index list in order
|
2018-10-05 17:19:05 +02:00
|
|
|
std::stable_sort(indexes.begin(), indexes.end());
|
2010-04-27 19:15:11 +02:00
|
|
|
|
2010-03-22 23:46:53 +01:00
|
|
|
// if first selected song has a track number set, start from that offset
|
2011-08-27 23:43:02 +02:00
|
|
|
if (!indexes.isEmpty()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
const Song first_song = app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(indexes[0].row())
|
|
|
|
->Metadata();
|
2011-08-27 23:43:02 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (first_song.track() > 0) track = first_song.track();
|
2010-03-22 23:46:53 +01:00
|
|
|
}
|
|
|
|
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& index : indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index.column() != 0) continue;
|
2010-03-22 23:46:53 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
const QModelIndex source_index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index);
|
2011-08-28 00:16:57 +02:00
|
|
|
int row = source_index.row();
|
2012-02-12 14:41:50 +01:00
|
|
|
Song song = app_->playlist_manager()->current()->item_at(row)->Metadata();
|
2010-03-22 23:46:53 +01:00
|
|
|
|
|
|
|
if (song.IsEditable()) {
|
|
|
|
song.set_track(track);
|
2012-01-06 22:27:02 +01:00
|
|
|
|
|
|
|
TagReaderReply* reply =
|
|
|
|
TagReaderClient::Instance()->SaveFile(song.url().toLocalFile(), song);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
NewClosure(reply, SIGNAL(Finished(bool)), this,
|
|
|
|
SLOT(SongSaveComplete(TagReaderReply*, QPersistentModelIndex)),
|
2012-01-06 22:27:02 +01:00
|
|
|
reply, QPersistentModelIndex(source_index));
|
2010-03-22 23:46:53 +01:00
|
|
|
}
|
|
|
|
track++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-06 22:27:02 +01:00
|
|
|
void MainWindow::SongSaveComplete(TagReaderReply* reply,
|
|
|
|
const QPersistentModelIndex& index) {
|
|
|
|
if (reply->is_successful() && index.isValid()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->current()->ReloadItems(QList<int>()
|
|
|
|
<< index.row());
|
2010-08-02 16:22:05 +02:00
|
|
|
}
|
2012-01-06 22:27:02 +01:00
|
|
|
reply->deleteLater();
|
2010-08-02 16:22:05 +02:00
|
|
|
}
|
|
|
|
|
2010-03-24 01:12:52 +01:00
|
|
|
void MainWindow::SelectionSetValue() {
|
|
|
|
Playlist::Column column = (Playlist::Column)playlist_menu_index_.column();
|
2014-02-07 16:34:20 +01:00
|
|
|
QVariant column_value =
|
|
|
|
app_->playlist_manager()->current()->data(playlist_menu_index_);
|
2010-03-24 01:12:52 +01:00
|
|
|
|
2010-11-28 15:47:35 +01:00
|
|
|
QModelIndexList indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes();
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& index : indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index.column() != 0) continue;
|
2010-03-24 01:12:52 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
const QModelIndex source_index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index);
|
2011-08-28 00:16:57 +02:00
|
|
|
int row = source_index.row();
|
2012-02-12 14:41:50 +01:00
|
|
|
Song song = app_->playlist_manager()->current()->item_at(row)->Metadata();
|
2010-03-24 01:12:52 +01:00
|
|
|
|
2010-11-28 15:47:35 +01:00
|
|
|
if (Playlist::set_column_value(song, column, column_value)) {
|
2012-01-06 22:27:02 +01:00
|
|
|
TagReaderReply* reply =
|
|
|
|
TagReaderClient::Instance()->SaveFile(song.url().toLocalFile(), song);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
NewClosure(reply, SIGNAL(Finished(bool)), this,
|
|
|
|
SLOT(SongSaveComplete(TagReaderReply*, QPersistentModelIndex)),
|
2012-01-06 22:27:02 +01:00
|
|
|
reply, QPersistentModelIndex(source_index));
|
2010-03-24 01:12:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-26 00:48:58 +01:00
|
|
|
void MainWindow::EditValue() {
|
2010-08-30 18:49:10 +02:00
|
|
|
QModelIndex current = ui_->playlist->view()->currentIndex();
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!current.isValid()) return;
|
2010-08-30 18:49:10 +02:00
|
|
|
|
|
|
|
// Edit the last column that was right-clicked on. If nothing's ever been
|
|
|
|
// right clicked then look for the first editable column.
|
|
|
|
int column = playlist_menu_index_.column();
|
|
|
|
if (column == -1) {
|
2014-02-07 16:34:20 +01:00
|
|
|
for (int i = 0; i < ui_->playlist->view()->model()->columnCount(); ++i) {
|
|
|
|
if (ui_->playlist->view()->isColumnHidden(i)) continue;
|
|
|
|
if (!Playlist::column_is_editable(Playlist::Column(i))) continue;
|
2010-08-30 18:49:10 +02:00
|
|
|
column = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ui_->playlist->view()->edit(current.sibling(current.row(), column));
|
2010-03-26 00:48:58 +01:00
|
|
|
}
|
|
|
|
|
2010-05-11 22:02:19 +02:00
|
|
|
void MainWindow::AddFile() {
|
2010-02-24 23:26:01 +01:00
|
|
|
// Last used directory
|
2014-02-07 16:34:20 +01:00
|
|
|
QString directory =
|
|
|
|
settings_.value("add_media_path", QDir::currentPath()).toString();
|
2010-02-24 23:26:01 +01:00
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
PlaylistParser parser(app_->library_backend());
|
2010-06-15 20:24:08 +02:00
|
|
|
|
2010-02-24 23:26:01 +01:00
|
|
|
// Show dialog
|
2010-03-07 15:42:51 +01:00
|
|
|
QStringList file_names = QFileDialog::getOpenFileNames(
|
2011-11-04 14:14:07 +01:00
|
|
|
this, tr("Add file"), directory,
|
2020-09-18 16:15:19 +02:00
|
|
|
QString("%1 (%2);;%3;;%4")
|
|
|
|
.arg(tr("Music"), FileView::kFileFilter, parser.filters(),
|
|
|
|
tr(kAllFilesFilterSpec)));
|
2014-02-07 16:34:20 +01:00
|
|
|
if (file_names.isEmpty()) return;
|
2010-02-24 23:26:01 +01:00
|
|
|
|
|
|
|
// Save last used directory
|
2010-02-27 17:52:18 +01:00
|
|
|
settings_.setValue("add_media_path", file_names[0]);
|
2010-02-24 23:26:01 +01:00
|
|
|
|
2010-06-15 20:24:08 +02:00
|
|
|
// Convert to URLs
|
|
|
|
QList<QUrl> urls;
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QString& path : file_names) {
|
2011-03-13 15:43:03 +01:00
|
|
|
urls << QUrl::fromLocalFile(QFileInfo(path).canonicalFilePath());
|
2010-02-24 23:26:01 +01:00
|
|
|
}
|
2011-01-10 23:26:13 +01:00
|
|
|
|
|
|
|
MimeData* data = new MimeData;
|
|
|
|
data->setUrls(urls);
|
|
|
|
AddToPlaylist(data);
|
2010-02-24 23:26:01 +01:00
|
|
|
}
|
|
|
|
|
2010-05-11 22:02:19 +02:00
|
|
|
void MainWindow::AddFolder() {
|
|
|
|
// Last used directory
|
2014-02-07 16:34:20 +01:00
|
|
|
QString directory =
|
|
|
|
settings_.value("add_folder_path", QDir::currentPath()).toString();
|
2010-05-11 22:02:19 +02:00
|
|
|
|
|
|
|
// Show dialog
|
2014-02-07 16:34:20 +01:00
|
|
|
directory =
|
|
|
|
QFileDialog::getExistingDirectory(this, tr("Add folder"), directory);
|
|
|
|
if (directory.isEmpty()) return;
|
2010-05-11 22:02:19 +02:00
|
|
|
|
|
|
|
// Save last used directory
|
|
|
|
settings_.setValue("add_folder_path", directory);
|
|
|
|
|
|
|
|
// Add media
|
2011-01-10 23:26:13 +01:00
|
|
|
MimeData* data = new MimeData;
|
2014-02-07 16:34:20 +01:00
|
|
|
data->setUrls(QList<QUrl>() << QUrl::fromLocalFile(
|
2014-05-19 17:51:40 +02:00
|
|
|
QFileInfo(directory).canonicalFilePath()));
|
2011-01-10 23:26:13 +01:00
|
|
|
AddToPlaylist(data);
|
2010-05-11 22:02:19 +02:00
|
|
|
}
|
|
|
|
|
2016-02-12 17:10:24 +01:00
|
|
|
void MainWindow::AddStream() { add_stream_dialog_->show(); }
|
2010-02-24 23:26:01 +01:00
|
|
|
|
|
|
|
void MainWindow::AddStreamAccepted() {
|
2011-01-10 23:26:13 +01:00
|
|
|
MimeData* data = new MimeData;
|
|
|
|
data->setUrls(QList<QUrl>() << add_stream_dialog_->url());
|
|
|
|
AddToPlaylist(data);
|
2010-03-07 21:19:35 +01:00
|
|
|
}
|
2010-03-24 17:36:44 +01:00
|
|
|
|
2015-02-18 20:05:35 +01:00
|
|
|
void MainWindow::OpenRipCDDialog() {
|
2014-02-07 16:34:20 +01:00
|
|
|
#ifdef HAVE_AUDIOCD
|
2015-02-18 20:05:35 +01:00
|
|
|
if (!rip_cd_dialog_) {
|
2021-06-01 17:51:00 +02:00
|
|
|
Q_ASSERT(app_->device_manager());
|
2021-06-01 19:36:54 +02:00
|
|
|
rip_cd_dialog_.reset(new RipCDDialog(*(app_->device_manager())));
|
2014-02-07 16:34:20 +01:00
|
|
|
}
|
2021-05-30 14:23:37 +02:00
|
|
|
rip_cd_dialog_->show();
|
2014-02-07 16:34:20 +01:00
|
|
|
#endif
|
2014-01-23 16:18:35 +01:00
|
|
|
}
|
|
|
|
|
2011-06-10 01:08:43 +02:00
|
|
|
void MainWindow::AddCDTracks() {
|
|
|
|
MimeData* data = new MimeData;
|
|
|
|
// We are putting empty data, but we specify cdda mimetype to indicate that
|
|
|
|
// we want to load audio cd tracks
|
|
|
|
data->open_in_new_playlist_ = true;
|
|
|
|
data->setData(Playlist::kCddaMimeType, QByteArray());
|
|
|
|
AddToPlaylist(data);
|
|
|
|
}
|
|
|
|
|
2014-01-11 21:03:32 +01:00
|
|
|
void MainWindow::ShowInLibrary() {
|
|
|
|
// Show the first valid selected track artist/album in LibraryView
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndexList proxy_indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows();
|
2014-01-11 21:03:32 +01:00
|
|
|
SongList songs;
|
|
|
|
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& proxy_index : proxy_indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndex index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(proxy_index);
|
|
|
|
if (app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(index.row())
|
|
|
|
->IsLocalLibraryItem()) {
|
|
|
|
songs << app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(index.row())
|
|
|
|
->Metadata();
|
2014-01-11 21:03:32 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-01-12 21:25:53 +01:00
|
|
|
QString search;
|
|
|
|
if (!songs.isEmpty()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
search =
|
|
|
|
"artist:" + songs.first().artist() + " album:" + songs.first().album();
|
2014-01-12 21:25:53 +01:00
|
|
|
}
|
2014-01-11 21:03:32 +01:00
|
|
|
library_view_->filter()->ShowInLibrary(search);
|
2016-07-01 11:37:04 +02:00
|
|
|
FocusLibraryTab();
|
2014-01-11 21:03:32 +01:00
|
|
|
}
|
|
|
|
|
2010-03-24 17:36:44 +01:00
|
|
|
void MainWindow::PlaylistRemoveCurrent() {
|
2017-04-18 15:29:25 +02:00
|
|
|
ui_->playlist->view()->RemoveSelected(false);
|
2010-03-24 17:36:44 +01:00
|
|
|
}
|
2010-03-31 02:30:57 +02:00
|
|
|
|
2010-04-11 19:58:58 +02:00
|
|
|
void MainWindow::PlaylistEditFinished(const QModelIndex& index) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index == playlist_menu_index_) SelectionSetValue();
|
2010-04-11 19:58:58 +02:00
|
|
|
}
|
2010-04-13 00:44:29 +02:00
|
|
|
|
2015-10-05 12:16:52 +02:00
|
|
|
void MainWindow::CommandlineOptionsReceived(const QString& string_options) {
|
2010-04-13 00:44:29 +02:00
|
|
|
CommandlineOptions options;
|
2015-10-05 12:16:52 +02:00
|
|
|
options.Load(string_options.toLatin1());
|
2010-04-13 00:44:29 +02:00
|
|
|
|
2010-04-13 01:35:47 +02:00
|
|
|
if (options.is_empty()) {
|
|
|
|
show();
|
|
|
|
activateWindow();
|
2020-10-03 18:59:31 +02:00
|
|
|
} else {
|
2010-04-13 01:35:47 +02:00
|
|
|
CommandlineOptionsReceived(options);
|
2020-10-03 18:59:31 +02:00
|
|
|
}
|
2010-04-13 00:44:29 +02:00
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::CommandlineOptionsReceived(const CommandlineOptions& options) {
|
2017-11-21 11:02:36 +01:00
|
|
|
qLog(Debug) << "command line options received";
|
2018-10-05 17:19:05 +02:00
|
|
|
|
2010-04-13 00:44:29 +02:00
|
|
|
switch (options.player_action()) {
|
|
|
|
case CommandlineOptions::Player_Play:
|
2014-02-07 20:28:37 +01:00
|
|
|
if (options.urls().empty()) {
|
|
|
|
app_->player()->Play();
|
|
|
|
}
|
2010-04-13 00:44:29 +02:00
|
|
|
break;
|
|
|
|
case CommandlineOptions::Player_PlayPause:
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->PlayPause();
|
2010-04-13 00:44:29 +02:00
|
|
|
break;
|
|
|
|
case CommandlineOptions::Player_Pause:
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->Pause();
|
2010-04-13 00:44:29 +02:00
|
|
|
break;
|
|
|
|
case CommandlineOptions::Player_Stop:
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->Stop();
|
2010-04-13 00:44:29 +02:00
|
|
|
break;
|
2016-03-18 20:21:34 +01:00
|
|
|
case CommandlineOptions::Player_StopAfterCurrent:
|
|
|
|
app_->player()->StopAfterCurrent();
|
|
|
|
break;
|
2010-04-13 00:44:29 +02:00
|
|
|
case CommandlineOptions::Player_Previous:
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->Previous();
|
2010-04-13 00:44:29 +02:00
|
|
|
break;
|
|
|
|
case CommandlineOptions::Player_Next:
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->Next();
|
2010-04-13 00:44:29 +02:00
|
|
|
break;
|
2020-10-03 18:59:31 +02:00
|
|
|
case CommandlineOptions::Player_PlayPlaylist:
|
2020-11-28 19:59:19 +01:00
|
|
|
if (options.playlist_name().isEmpty()) {
|
2020-10-03 18:59:31 +02:00
|
|
|
qLog(Error) << "ERROR: playlist name missing";
|
|
|
|
} else {
|
|
|
|
app_->player()->PlayPlaylist(options.playlist_name());
|
|
|
|
}
|
|
|
|
break;
|
2013-05-29 21:27:07 +02:00
|
|
|
case CommandlineOptions::Player_RestartOrPrevious:
|
|
|
|
app_->player()->RestartOrPrevious();
|
|
|
|
break;
|
2010-04-13 00:44:29 +02:00
|
|
|
|
|
|
|
case CommandlineOptions::Player_None:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-02-07 20:28:37 +01:00
|
|
|
if (!options.urls().empty()) {
|
|
|
|
MimeData* data = new MimeData;
|
|
|
|
data->setUrls(options.urls());
|
|
|
|
// Behaviour depends on command line options, so set it here
|
|
|
|
data->override_user_settings_ = true;
|
2010-04-13 00:44:29 +02:00
|
|
|
|
2014-02-07 20:28:37 +01:00
|
|
|
if (options.player_action() == CommandlineOptions::Player_Play)
|
|
|
|
data->play_now_ = true;
|
|
|
|
else
|
|
|
|
ApplyPlayBehaviour(doubleclick_playmode_, data);
|
|
|
|
|
|
|
|
switch (options.url_list_action()) {
|
|
|
|
case CommandlineOptions::UrlList_Load:
|
|
|
|
data->clear_first_ = true;
|
|
|
|
break;
|
|
|
|
case CommandlineOptions::UrlList_Append:
|
|
|
|
// Nothing to do
|
|
|
|
break;
|
|
|
|
case CommandlineOptions::UrlList_None:
|
|
|
|
ApplyAddBehaviour(doubleclick_addmode_, data);
|
|
|
|
break;
|
2016-08-26 15:59:11 +02:00
|
|
|
case CommandlineOptions::UrlList_CreateNew:
|
|
|
|
data->name_for_new_playlist_ = options.playlist_name();
|
|
|
|
ApplyAddBehaviour(AddBehaviour_OpenInNew, data);
|
|
|
|
break;
|
2011-01-10 23:26:13 +01:00
|
|
|
}
|
2014-02-07 20:28:37 +01:00
|
|
|
|
|
|
|
AddToPlaylist(data);
|
2010-04-13 00:44:29 +02:00
|
|
|
}
|
2010-04-13 01:35:47 +02:00
|
|
|
|
|
|
|
if (options.set_volume() != -1)
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->SetVolume(options.set_volume());
|
2010-04-13 01:35:47 +02:00
|
|
|
|
|
|
|
if (options.volume_modifier() != 0)
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->player()->SetVolume(app_->player()->GetVolume() +
|
|
|
|
options.volume_modifier());
|
2010-04-13 01:35:47 +02:00
|
|
|
|
|
|
|
if (options.seek_to() != -1)
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->SeekTo(options.seek_to());
|
2010-04-13 22:22:29 +02:00
|
|
|
else if (options.seek_by() != 0)
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->player()->SeekTo(app_->player()->engine()->position_nanosec() /
|
|
|
|
kNsecPerSec +
|
|
|
|
options.seek_by());
|
2010-04-13 01:35:47 +02:00
|
|
|
|
|
|
|
if (options.play_track_at() != -1)
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->PlayAt(options.play_track_at(), Engine::Manual, true);
|
2010-04-13 01:35:47 +02:00
|
|
|
|
2018-10-05 17:19:05 +02:00
|
|
|
// Just pass the url of the currently playing
|
2017-11-21 11:02:36 +01:00
|
|
|
if (options.delete_current_track()) {
|
|
|
|
qLog(Debug) << "deleting current track";
|
2018-10-05 17:19:05 +02:00
|
|
|
|
2017-11-21 11:02:36 +01:00
|
|
|
Playlist* activePlaylist = app_->playlist_manager()->active();
|
|
|
|
PlaylistItemPtr playlistItemPtr = activePlaylist->current_item();
|
|
|
|
|
|
|
|
if (playlistItemPtr) {
|
|
|
|
const QUrl& url = playlistItemPtr->Url();
|
|
|
|
qLog(Debug) << url;
|
2018-10-05 17:19:05 +02:00
|
|
|
|
|
|
|
std::shared_ptr<MusicStorage> storage(new FilesystemMusicStorage("/"));
|
|
|
|
|
2017-11-21 11:02:36 +01:00
|
|
|
app_->player()->Next();
|
2018-10-05 17:19:05 +02:00
|
|
|
|
2020-09-18 16:15:19 +02:00
|
|
|
DeleteFiles* delete_files =
|
|
|
|
new DeleteFiles(app_->task_manager(), storage);
|
2017-11-21 11:02:36 +01:00
|
|
|
connect(delete_files, SIGNAL(Finished(SongList)),
|
|
|
|
SLOT(DeleteFinished(SongList)));
|
|
|
|
delete_files->Start(url);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
qLog(Debug) << "no currently playing track to delete";
|
|
|
|
}
|
|
|
|
}
|
2018-10-05 17:19:05 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (options.show_osd()) app_->player()->ShowOSD();
|
2011-06-05 10:21:17 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (options.toggle_pretty_osd()) app_->player()->TogglePrettyOSD();
|
2010-04-13 00:44:29 +02:00
|
|
|
}
|
2010-04-13 22:45:40 +02:00
|
|
|
|
2012-02-13 21:44:04 +01:00
|
|
|
void MainWindow::ForceShowOSD(const Song& song, const bool toggle) {
|
2011-06-05 15:34:12 +02:00
|
|
|
if (toggle) {
|
2011-06-05 10:21:17 +02:00
|
|
|
osd_->SetPrettyOSDToggleMode(toggle);
|
2011-06-05 15:34:12 +02:00
|
|
|
}
|
2012-02-13 21:44:04 +01:00
|
|
|
osd_->ReshowCurrentSong();
|
2010-04-13 22:45:40 +02:00
|
|
|
}
|
2010-04-14 23:27:27 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::Activate() { show(); }
|
2010-06-14 15:22:45 +02:00
|
|
|
|
2010-06-15 23:56:33 +02:00
|
|
|
bool MainWindow::LoadUrl(const QString& url) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!QFile::exists(url)) return false;
|
2010-06-15 23:56:33 +02:00
|
|
|
|
2011-01-10 23:26:13 +01:00
|
|
|
MimeData* data = new MimeData;
|
|
|
|
data->setUrls(QList<QUrl>() << QUrl::fromLocalFile(url));
|
|
|
|
AddToPlaylist(data);
|
|
|
|
|
2010-06-15 23:56:33 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-04-15 17:23:12 +02:00
|
|
|
void MainWindow::CheckForUpdates() {
|
2010-12-30 17:20:33 +01:00
|
|
|
#if defined(Q_OS_DARWIN)
|
2010-04-15 17:23:12 +02:00
|
|
|
mac::CheckForUpdates();
|
|
|
|
#endif
|
|
|
|
}
|
2010-05-20 23:21:55 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::PlaylistUndoRedoChanged(QAction* undo, QAction* redo) {
|
2010-05-20 23:21:55 +02:00
|
|
|
playlist_menu_->insertAction(playlist_undoredo_, undo);
|
|
|
|
playlist_menu_->insertAction(playlist_undoredo_, redo);
|
|
|
|
}
|
2010-06-09 17:38:00 +02:00
|
|
|
|
2013-06-30 16:54:13 +02:00
|
|
|
void MainWindow::AddFilesToTranscoder() {
|
|
|
|
QStringList filenames;
|
|
|
|
|
2014-03-27 18:55:58 +01:00
|
|
|
for (const QModelIndex& index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index.column() != 0) continue;
|
|
|
|
int row =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
2013-06-30 16:54:13 +02:00
|
|
|
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(row));
|
|
|
|
Song song = item->Metadata();
|
|
|
|
filenames << song.url().toLocalFile();
|
|
|
|
}
|
|
|
|
|
|
|
|
transcode_dialog_->SetFilenames(filenames);
|
|
|
|
|
|
|
|
ShowTranscodeDialog();
|
|
|
|
}
|
|
|
|
|
2010-06-09 17:38:00 +02:00
|
|
|
void MainWindow::ShowLibraryConfig() {
|
2012-12-05 10:36:22 +01:00
|
|
|
settings_dialog_->OpenAtPage(SettingsDialog::Page_Library);
|
2010-06-09 17:38:00 +02:00
|
|
|
}
|
2010-06-16 21:21:15 +02:00
|
|
|
|
|
|
|
void MainWindow::TaskCountChanged(int count) {
|
|
|
|
if (count == 0) {
|
|
|
|
ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page);
|
|
|
|
} else {
|
|
|
|
ui_->status_bar_stack->setCurrentWidget(ui_->multi_loading_indicator);
|
|
|
|
}
|
|
|
|
}
|
2010-06-18 02:06:59 +02:00
|
|
|
|
|
|
|
void MainWindow::NowPlayingWidgetPositionChanged(bool above_status_bar) {
|
|
|
|
if (above_status_bar) {
|
|
|
|
ui_->status_bar->setParent(ui_->centralWidget);
|
|
|
|
} else {
|
|
|
|
ui_->status_bar->setParent(ui_->player_controls_container);
|
|
|
|
}
|
|
|
|
|
|
|
|
ui_->status_bar->parentWidget()->layout()->addWidget(ui_->status_bar);
|
|
|
|
ui_->status_bar->show();
|
|
|
|
}
|
2010-06-24 18:26:49 +02:00
|
|
|
|
2012-01-29 19:44:00 +01:00
|
|
|
void MainWindow::CopyFilesToLibrary(const QList<QUrl>& urls) {
|
2020-02-11 00:38:57 +01:00
|
|
|
organise_dialog_->SetDestinationModel(app_->directory_model());
|
2010-06-24 18:26:49 +02:00
|
|
|
organise_dialog_->SetUrls(urls);
|
2010-06-24 22:26:17 +02:00
|
|
|
organise_dialog_->SetCopy(true);
|
2010-06-24 18:26:49 +02:00
|
|
|
organise_dialog_->show();
|
|
|
|
}
|
|
|
|
|
2012-01-29 19:44:00 +01:00
|
|
|
void MainWindow::MoveFilesToLibrary(const QList<QUrl>& urls) {
|
2020-02-11 00:38:57 +01:00
|
|
|
organise_dialog_->SetDestinationModel(app_->directory_model());
|
2010-06-24 18:26:49 +02:00
|
|
|
organise_dialog_->SetUrls(urls);
|
2010-06-24 22:26:17 +02:00
|
|
|
organise_dialog_->SetCopy(false);
|
2010-06-24 18:26:49 +02:00
|
|
|
organise_dialog_->show();
|
|
|
|
}
|
2010-06-25 01:36:39 +02:00
|
|
|
|
2012-01-29 19:44:00 +01:00
|
|
|
void MainWindow::CopyFilesToDevice(const QList<QUrl>& urls) {
|
2014-02-07 16:34:20 +01:00
|
|
|
organise_dialog_->SetDestinationModel(
|
|
|
|
app_->device_manager()->connected_devices_model(), true);
|
2010-09-18 11:54:33 +02:00
|
|
|
organise_dialog_->SetCopy(true);
|
|
|
|
if (organise_dialog_->SetUrls(urls))
|
|
|
|
organise_dialog_->show();
|
|
|
|
else {
|
2014-02-07 16:34:20 +01:00
|
|
|
QMessageBox::warning(
|
|
|
|
this, tr("Error"),
|
2010-09-18 11:54:33 +02:00
|
|
|
tr("None of the selected songs were suitable for copying to a device"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-29 19:44:00 +01:00
|
|
|
void MainWindow::EditFileTags(const QList<QUrl>& urls) {
|
|
|
|
SongList songs;
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QUrl& url : urls) {
|
2012-01-29 19:44:00 +01:00
|
|
|
Song song;
|
|
|
|
song.set_url(url);
|
|
|
|
song.set_valid(true);
|
|
|
|
song.set_filetype(Song::Type_Mpeg);
|
|
|
|
songs << song;
|
|
|
|
}
|
|
|
|
|
|
|
|
edit_tag_dialog_->SetSongs(songs);
|
|
|
|
edit_tag_dialog_->show();
|
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::PlaylistCopyToLibrary() { PlaylistOrganiseSelected(true); }
|
2010-06-25 01:36:39 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::PlaylistMoveToLibrary() { PlaylistOrganiseSelected(false); }
|
2010-06-25 01:36:39 +02:00
|
|
|
|
|
|
|
void MainWindow::PlaylistOrganiseSelected(bool copy) {
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndexList proxy_indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows();
|
2010-08-08 15:06:52 +02:00
|
|
|
SongList songs;
|
2010-06-25 01:36:39 +02:00
|
|
|
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& proxy_index : proxy_indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndex index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(proxy_index);
|
2010-06-25 01:36:39 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
songs << app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(index.row())
|
|
|
|
->Metadata();
|
2010-06-25 01:36:39 +02:00
|
|
|
}
|
|
|
|
|
2020-02-11 00:38:57 +01:00
|
|
|
organise_dialog_->SetDestinationModel(app_->directory_model());
|
2010-08-08 15:06:52 +02:00
|
|
|
organise_dialog_->SetSongs(songs);
|
2010-06-25 01:36:39 +02:00
|
|
|
organise_dialog_->SetCopy(copy);
|
|
|
|
organise_dialog_->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::PlaylistDelete() {
|
2010-12-11 11:54:42 +01:00
|
|
|
// Note: copied from LibraryView::Delete
|
|
|
|
|
2013-02-23 22:02:51 +01:00
|
|
|
if (QMessageBox::warning(this, tr("Delete files"),
|
2014-02-07 16:34:20 +01:00
|
|
|
tr("These files will be permanently deleted from "
|
|
|
|
"disk, are you sure you want to continue?"),
|
|
|
|
QMessageBox::Yes,
|
|
|
|
QMessageBox::Cancel) != QMessageBox::Yes)
|
2010-12-11 11:54:42 +01:00
|
|
|
return;
|
|
|
|
|
2014-02-06 14:48:00 +01:00
|
|
|
std::shared_ptr<MusicStorage> storage(new FilesystemMusicStorage("/"));
|
2010-12-11 11:54:42 +01:00
|
|
|
|
|
|
|
// Get selected songs
|
|
|
|
SongList selected_songs;
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndexList proxy_indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows();
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& proxy_index : proxy_indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndex index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(proxy_index);
|
|
|
|
selected_songs << app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(index.row())
|
|
|
|
->Metadata();
|
2010-12-11 11:54:42 +01:00
|
|
|
}
|
|
|
|
|
2017-04-18 15:29:25 +02:00
|
|
|
if (app_->player()->GetState() == Engine::Playing) {
|
|
|
|
if (app_->playlist_manager()->current()->rowCount() ==
|
|
|
|
selected_songs.length()) {
|
|
|
|
app_->player()->Stop();
|
|
|
|
} else {
|
|
|
|
for (Song x : selected_songs) {
|
|
|
|
if (x == app_->player()->GetCurrentItem()->Metadata()) {
|
|
|
|
app_->player()->Next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ui_->playlist->view()->RemoveSelected(true);
|
2010-12-11 11:54:42 +01:00
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
DeleteFiles* delete_files = new DeleteFiles(app_->task_manager(), storage);
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(delete_files, SIGNAL(Finished(SongList)),
|
|
|
|
SLOT(DeleteFinished(SongList)));
|
2010-12-11 11:54:42 +01:00
|
|
|
delete_files->Start(selected_songs);
|
|
|
|
}
|
|
|
|
|
2011-03-17 20:52:21 +01:00
|
|
|
void MainWindow::PlaylistOpenInBrowser() {
|
2011-10-26 14:54:24 +02:00
|
|
|
QList<QUrl> urls;
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndexList proxy_indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows();
|
2011-03-17 20:52:21 +01:00
|
|
|
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& proxy_index : proxy_indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
const QModelIndex index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(proxy_index);
|
|
|
|
urls << QUrl(index.sibling(index.row(), Playlist::Column_Filename)
|
|
|
|
.data()
|
|
|
|
.toString());
|
2011-03-06 14:10:14 +01:00
|
|
|
}
|
2011-03-17 20:52:21 +01:00
|
|
|
|
2011-10-26 14:54:24 +02:00
|
|
|
Utilities::OpenInFileBrowser(urls);
|
2011-03-06 14:10:14 +01:00
|
|
|
}
|
|
|
|
|
2010-12-11 11:54:42 +01:00
|
|
|
void MainWindow::DeleteFinished(const SongList& songs_with_errors) {
|
2017-11-21 11:02:36 +01:00
|
|
|
if (songs_with_errors.isEmpty()) {
|
|
|
|
qLog(Debug) << "Finished deleting songs";
|
|
|
|
Playlist* activePlaylist = app_->playlist_manager()->active();
|
|
|
|
if (activePlaylist->id() != -1) {
|
|
|
|
activePlaylist->RemoveUnavailableSongs();
|
|
|
|
qLog(Debug) << "Found active playlist and removed unavailable songs";
|
|
|
|
}
|
2018-10-05 17:19:05 +02:00
|
|
|
|
2017-11-21 11:02:36 +01:00
|
|
|
return;
|
2018-10-05 17:19:05 +02:00
|
|
|
}
|
2010-12-11 11:54:42 +01:00
|
|
|
|
|
|
|
OrganiseErrorDialog* dialog = new OrganiseErrorDialog(this);
|
|
|
|
dialog->Show(OrganiseErrorDialog::Type_Delete, songs_with_errors);
|
|
|
|
// It deletes itself when the user closes it
|
2010-07-11 17:37:40 +02:00
|
|
|
}
|
2010-06-25 01:36:39 +02:00
|
|
|
|
2010-07-11 17:37:40 +02:00
|
|
|
void MainWindow::PlaylistQueue() {
|
2010-07-11 18:58:22 +02:00
|
|
|
QModelIndexList indexes;
|
2014-03-27 18:55:58 +01:00
|
|
|
for (const QModelIndex& proxy_index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
2014-05-19 17:51:40 +02:00
|
|
|
proxy_index);
|
2010-07-11 18:58:22 +02:00
|
|
|
}
|
|
|
|
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->current()->queue()->ToggleTracks(indexes);
|
2010-06-25 01:36:39 +02:00
|
|
|
}
|
2010-08-08 15:06:52 +02:00
|
|
|
|
2018-03-18 19:43:44 +01:00
|
|
|
void MainWindow::PlaylistQueuePlayNext() {
|
2018-04-14 22:57:06 +02:00
|
|
|
QModelIndexList indexes;
|
|
|
|
for (const QModelIndex& proxy_index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows()) {
|
|
|
|
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
|
|
|
proxy_index);
|
|
|
|
}
|
2018-03-18 19:43:44 +01:00
|
|
|
|
2018-04-14 22:57:06 +02:00
|
|
|
app_->playlist_manager()->current()->queue()->InsertFirst(indexes);
|
2018-03-18 19:43:44 +01:00
|
|
|
}
|
|
|
|
|
2014-01-14 06:29:23 +01:00
|
|
|
void MainWindow::PlaylistSkip() {
|
|
|
|
QModelIndexList indexes;
|
2014-03-27 18:55:58 +01:00
|
|
|
for (const QModelIndex& proxy_index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows()) {
|
2014-02-08 02:47:35 +01:00
|
|
|
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
2014-05-19 17:51:40 +02:00
|
|
|
proxy_index);
|
2014-01-14 06:29:23 +01:00
|
|
|
}
|
|
|
|
|
2014-01-17 07:01:31 +01:00
|
|
|
app_->playlist_manager()->current()->SkipTracks(indexes);
|
2014-01-14 06:29:23 +01:00
|
|
|
}
|
|
|
|
|
2010-08-08 15:06:52 +02:00
|
|
|
void MainWindow::PlaylistCopyToDevice() {
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndexList proxy_indexes =
|
|
|
|
ui_->playlist->view()->selectionModel()->selectedRows();
|
2010-08-08 15:06:52 +02:00
|
|
|
SongList songs;
|
|
|
|
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QModelIndex& proxy_index : proxy_indexes) {
|
2014-02-07 16:34:20 +01:00
|
|
|
QModelIndex index =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(proxy_index);
|
2010-08-08 15:06:52 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
songs << app_->playlist_manager()
|
|
|
|
->current()
|
|
|
|
->item_at(index.row())
|
|
|
|
->Metadata();
|
2010-08-08 15:06:52 +02:00
|
|
|
}
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
organise_dialog_->SetDestinationModel(
|
|
|
|
app_->device_manager()->connected_devices_model(), true);
|
2010-08-08 15:06:52 +02:00
|
|
|
organise_dialog_->SetCopy(true);
|
2010-09-15 22:00:17 +02:00
|
|
|
if (organise_dialog_->SetSongs(songs))
|
|
|
|
organise_dialog_->show();
|
|
|
|
else {
|
2014-02-07 16:34:20 +01:00
|
|
|
QMessageBox::warning(
|
|
|
|
this, tr("Error"),
|
2010-09-15 22:00:17 +02:00
|
|
|
tr("None of the selected songs were suitable for copying to a device"));
|
|
|
|
}
|
2010-08-08 15:06:52 +02:00
|
|
|
}
|
2010-08-27 17:42:58 +02:00
|
|
|
|
2017-08-09 15:12:36 +02:00
|
|
|
void MainWindow::SearchForArtist() {
|
|
|
|
PlaylistItemPtr item(
|
|
|
|
app_->playlist_manager()->current()->item_at(playlist_menu_index_.row()));
|
|
|
|
Song song = item->Metadata();
|
|
|
|
if (!song.albumartist().isEmpty()) {
|
|
|
|
DoGlobalSearch(song.albumartist().simplified());
|
|
|
|
} else if (!song.artist().isEmpty()) {
|
|
|
|
DoGlobalSearch(song.artist().simplified());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::SearchForAlbum() {
|
|
|
|
PlaylistItemPtr item(
|
|
|
|
app_->playlist_manager()->current()->item_at(playlist_menu_index_.row()));
|
|
|
|
Song song = item->Metadata();
|
|
|
|
if (!song.album().isEmpty()) {
|
|
|
|
DoGlobalSearch(song.album().simplified());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 14:18:18 +01:00
|
|
|
void MainWindow::ChangeLibraryQueryMode(QAction* action) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (action == library_show_duplicates_) {
|
2011-02-06 14:18:18 +01:00
|
|
|
library_view_->filter()->SetQueryMode(QueryOptions::QueryMode_Duplicates);
|
|
|
|
} else if (action == library_show_untagged_) {
|
|
|
|
library_view_->filter()->SetQueryMode(QueryOptions::QueryMode_Untagged);
|
|
|
|
} else {
|
|
|
|
library_view_->filter()->SetQueryMode(QueryOptions::QueryMode_All);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-12 17:10:24 +01:00
|
|
|
void MainWindow::ShowCoverManager() { cover_manager_->show(); }
|
2010-08-27 17:42:58 +02:00
|
|
|
|
2016-02-12 14:15:45 +01:00
|
|
|
SettingsDialog* MainWindow::CreateSettingsDialog() {
|
|
|
|
SettingsDialog* settings_dialog =
|
|
|
|
new SettingsDialog(app_, background_streams_);
|
|
|
|
settings_dialog->SetGlobalShortcutManager(global_shortcuts_);
|
|
|
|
settings_dialog->SetSongInfoView(song_info_view_);
|
2010-08-27 17:42:58 +02:00
|
|
|
|
|
|
|
// Settings
|
2016-02-12 14:15:45 +01:00
|
|
|
connect(settings_dialog, SIGNAL(accepted()), SLOT(ReloadAllSettings()));
|
2011-01-02 15:50:17 +01:00
|
|
|
|
2011-03-12 22:19:32 +01:00
|
|
|
#ifdef HAVE_WIIMOTEDEV
|
2016-02-12 14:15:45 +01:00
|
|
|
connect(settings_dialog, SIGNAL(SetWiimotedevInterfaceActived(bool)),
|
2014-02-07 16:34:20 +01:00
|
|
|
wiimotedev_shortcuts_.get(),
|
|
|
|
SLOT(SetWiimotedevInterfaceActived(bool)));
|
2010-08-31 22:35:11 +02:00
|
|
|
#endif
|
2011-05-22 23:15:11 +02:00
|
|
|
|
|
|
|
// Allows custom notification preview
|
2016-02-12 14:15:45 +01:00
|
|
|
connect(settings_dialog,
|
2014-02-07 16:34:20 +01:00
|
|
|
SIGNAL(NotificationPreview(OSD::Behaviour, QString, QString)),
|
|
|
|
SLOT(HandleNotificationPreview(OSD::Behaviour, QString, QString)));
|
2016-02-12 14:15:45 +01:00
|
|
|
return settings_dialog;
|
2010-08-27 17:42:58 +02:00
|
|
|
}
|
|
|
|
|
2016-02-12 14:15:45 +01:00
|
|
|
void MainWindow::OpenSettingsDialog() { settings_dialog_->show(); }
|
2010-08-27 17:42:58 +02:00
|
|
|
|
|
|
|
void MainWindow::OpenSettingsDialogAtPage(SettingsDialog::Page page) {
|
|
|
|
settings_dialog_->OpenAtPage(page);
|
|
|
|
}
|
|
|
|
|
2016-02-12 14:15:45 +01:00
|
|
|
EditTagDialog* MainWindow::CreateEditTagDialog() {
|
|
|
|
EditTagDialog* edit_tag_dialog = new EditTagDialog(app_);
|
|
|
|
connect(edit_tag_dialog, SIGNAL(accepted()), SLOT(EditTagDialogAccepted()));
|
|
|
|
connect(edit_tag_dialog, SIGNAL(Error(QString)),
|
2014-02-07 16:34:20 +01:00
|
|
|
SLOT(ShowErrorDialog(QString)));
|
2016-02-12 14:15:45 +01:00
|
|
|
return edit_tag_dialog;
|
2010-08-27 17:42:58 +02:00
|
|
|
}
|
|
|
|
|
2020-07-26 20:38:14 +02:00
|
|
|
LoveDialog* MainWindow::CreateLoveDialog() {
|
|
|
|
LoveDialog* dialog = new LoveDialog(app_);
|
2020-09-18 16:15:19 +02:00
|
|
|
connect(dialog, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
2020-07-26 20:38:14 +02:00
|
|
|
return dialog;
|
|
|
|
}
|
|
|
|
|
2016-12-21 17:57:04 +01:00
|
|
|
StreamDiscoverer* MainWindow::CreateStreamDiscoverer() {
|
|
|
|
StreamDiscoverer* discoverer = new StreamDiscoverer();
|
|
|
|
connect(discoverer, SIGNAL(DataReady(StreamDetails)),
|
|
|
|
SLOT(ShowStreamDetails(StreamDetails)));
|
|
|
|
connect(discoverer, SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
|
|
|
|
return discoverer;
|
|
|
|
}
|
|
|
|
|
2020-12-31 22:30:59 +01:00
|
|
|
Console* MainWindow::CreateDebugConsole() {
|
|
|
|
Console* console = new Console(app_, this);
|
|
|
|
emit NewDebugConsole(console);
|
|
|
|
return console;
|
|
|
|
}
|
2020-12-29 10:05:10 +01:00
|
|
|
|
2016-02-12 17:10:24 +01:00
|
|
|
void MainWindow::ShowAboutDialog() { about_dialog_->show(); }
|
2010-08-27 17:42:58 +02:00
|
|
|
|
2016-02-12 17:10:24 +01:00
|
|
|
void MainWindow::ShowTranscodeDialog() { transcode_dialog_->show(); }
|
2010-08-27 21:09:03 +02:00
|
|
|
|
|
|
|
void MainWindow::ShowErrorDialog(const QString& message) {
|
|
|
|
error_dialog_->ShowMessage(message);
|
|
|
|
}
|
|
|
|
|
2011-02-25 21:10:41 +01:00
|
|
|
void MainWindow::CheckFullRescanRevisions() {
|
2012-02-12 14:41:50 +01:00
|
|
|
int from = app_->database()->startup_schema_version();
|
|
|
|
int to = app_->database()->current_schema_version();
|
2011-02-25 21:10:41 +01:00
|
|
|
|
|
|
|
// if we're restoring DB from scratch or nothing has
|
|
|
|
// changed, do nothing
|
2014-02-07 16:34:20 +01:00
|
|
|
if (from == 0 || from == to) {
|
2011-02-25 21:10:41 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// collect all reasons
|
|
|
|
QSet<QString> reasons;
|
2014-02-07 16:34:20 +01:00
|
|
|
for (int i = from; i <= to; i++) {
|
2012-02-12 14:41:50 +01:00
|
|
|
QString reason = app_->library()->full_rescan_reason(i);
|
2011-02-25 21:10:41 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!reason.isEmpty()) {
|
2011-02-25 21:10:41 +01:00
|
|
|
reasons.insert(reason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if we have any...
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!reasons.isEmpty()) {
|
|
|
|
QString message = tr("The version of Clementine you've just updated to "
|
|
|
|
"requires a full library rescan "
|
|
|
|
"because of the new features listed below:") +
|
|
|
|
"<ul>";
|
2014-02-10 14:29:07 +01:00
|
|
|
for (const QString& reason : reasons) {
|
2011-02-25 21:10:41 +01:00
|
|
|
message += ("<li>" + reason + "</li>");
|
|
|
|
}
|
2011-03-22 15:53:48 +01:00
|
|
|
message += "</ul>" + tr("Would you like to run a full rescan right now?");
|
2011-02-25 21:10:41 +01:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (QMessageBox::question(this, tr("Library rescan notice"), message,
|
|
|
|
QMessageBox::Yes,
|
|
|
|
QMessageBox::No) == QMessageBox::Yes) {
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->library()->FullScan();
|
2011-02-25 21:10:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-12 17:10:24 +01:00
|
|
|
void MainWindow::ShowQueueManager() { queue_manager_->show(); }
|
2010-08-27 21:09:03 +02:00
|
|
|
|
|
|
|
void MainWindow::ShowVisualisations() {
|
2018-11-29 22:32:12 +01:00
|
|
|
#ifdef HAVE_VISUALISATIONS
|
2010-08-27 21:09:03 +02:00
|
|
|
if (!visualisation_) {
|
|
|
|
visualisation_.reset(new VisualisationContainer);
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
visualisation_->SetActions(ui_->action_previous_track,
|
|
|
|
ui_->action_play_pause, ui_->action_stop,
|
|
|
|
ui_->action_next_track);
|
|
|
|
connect(app_->player(), SIGNAL(Stopped()), visualisation_.get(),
|
|
|
|
SLOT(Stopped()));
|
|
|
|
connect(app_->player(), SIGNAL(ForceShowOSD(Song, bool)),
|
|
|
|
visualisation_.get(), SLOT(SongMetadataChanged(Song)));
|
|
|
|
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)),
|
|
|
|
visualisation_.get(), SLOT(SongMetadataChanged(Song)));
|
2010-08-27 21:09:03 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
visualisation_->SetEngine(
|
|
|
|
qobject_cast<GstEngine*>(app_->player()->engine()));
|
2010-08-27 21:09:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
visualisation_->show();
|
2018-11-29 22:32:12 +01:00
|
|
|
#endif // HAVE_VISUALISATIONS
|
2010-08-27 21:09:03 +02:00
|
|
|
}
|
2010-10-01 21:27:01 +02:00
|
|
|
|
2010-10-02 15:37:10 +02:00
|
|
|
void MainWindow::ConnectInfoView(SongInfoBase* view) {
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), view,
|
|
|
|
SLOT(SongChanged(Song)));
|
|
|
|
connect(app_->player(), SIGNAL(PlaylistFinished()), view,
|
|
|
|
SLOT(SongFinished()));
|
2012-02-12 14:41:50 +01:00
|
|
|
connect(app_->player(), SIGNAL(Stopped()), view, SLOT(SongFinished()));
|
2010-10-16 16:45:23 +02:00
|
|
|
|
|
|
|
connect(view, SIGNAL(ShowSettingsDialog()), SLOT(ShowSongInfoConfig()));
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(view, SIGNAL(DoGlobalSearch(QString)), SLOT(DoGlobalSearch(QString)));
|
2010-12-04 17:19:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::AddSongInfoGenerator(smart_playlists::GeneratorPtr gen) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (!gen) return;
|
2012-02-12 14:41:50 +01:00
|
|
|
gen->set_library(app_->library_backend());
|
2010-12-04 17:19:30 +01:00
|
|
|
|
2011-01-10 23:26:13 +01:00
|
|
|
AddToPlaylist(new smart_playlists::GeneratorMimeData(gen));
|
2010-10-16 16:45:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::ShowSongInfoConfig() {
|
2012-12-05 10:36:22 +01:00
|
|
|
OpenSettingsDialogAtPage(SettingsDialog::Page_SongInformation);
|
2010-10-02 15:37:10 +02:00
|
|
|
}
|
2010-11-28 16:14:48 +01:00
|
|
|
|
|
|
|
void MainWindow::PlaylistViewSelectionModelChanged() {
|
|
|
|
connect(ui_->playlist->view()->selectionModel(),
|
2014-02-07 16:34:20 +01:00
|
|
|
SIGNAL(currentChanged(QModelIndex, QModelIndex)),
|
2010-11-28 16:14:48 +01:00
|
|
|
SLOT(PlaylistCurrentChanged(QModelIndex)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::PlaylistCurrentChanged(const QModelIndex& proxy_current) {
|
|
|
|
const QModelIndex source_current =
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(proxy_current);
|
2010-11-28 16:14:48 +01:00
|
|
|
|
|
|
|
// If the user moves the current index using the keyboard and then presses
|
|
|
|
// F2, we don't want that editing the last column that was right clicked on.
|
|
|
|
if (source_current != playlist_menu_index_)
|
|
|
|
playlist_menu_index_ = QModelIndex();
|
|
|
|
}
|
2010-12-31 19:13:28 +01:00
|
|
|
|
2011-01-04 12:33:22 +01:00
|
|
|
void MainWindow::Raise() {
|
|
|
|
show();
|
|
|
|
activateWindow();
|
|
|
|
}
|
|
|
|
|
2011-01-15 21:51:48 +01:00
|
|
|
#ifdef Q_OS_WIN32
|
2011-01-16 01:39:51 +01:00
|
|
|
bool MainWindow::winEvent(MSG* msg, long*) {
|
|
|
|
thumbbar_->HandleWinEvent(msg);
|
2011-01-15 21:51:48 +01:00
|
|
|
return false;
|
|
|
|
}
|
2014-02-07 16:34:20 +01:00
|
|
|
#endif // Q_OS_WIN32
|
2011-02-16 23:43:05 +01:00
|
|
|
|
|
|
|
void MainWindow::Exit() {
|
2019-09-07 06:02:48 +02:00
|
|
|
// FIXME: This may add an extra write.
|
|
|
|
dirty_playback_ = true;
|
2016-09-06 14:28:25 +02:00
|
|
|
settings_.setValue("show_sidebar",
|
|
|
|
ui_->action_toggle_show_sidebar->isChecked());
|
2019-09-07 06:02:48 +02:00
|
|
|
settings_.endGroup();
|
|
|
|
SaveSettings(&settings_);
|
|
|
|
settings_.sync();
|
2016-09-06 14:28:25 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
if (app_->player()->engine()->is_fadeout_enabled()) {
|
2011-02-17 00:44:03 +01:00
|
|
|
// To shut down the application when fadeout will be finished
|
2014-02-07 16:34:20 +01:00
|
|
|
connect(app_->player()->engine(), SIGNAL(FadeoutFinishedSignal()), qApp,
|
|
|
|
SLOT(quit()));
|
|
|
|
if (app_->player()->GetState() == Engine::Playing) {
|
2012-02-12 14:41:50 +01:00
|
|
|
app_->player()->Stop();
|
2011-02-17 00:44:03 +01:00
|
|
|
hide();
|
2018-10-01 10:40:31 +02:00
|
|
|
if (tray_icon_) tray_icon_->SetVisible(false);
|
2014-02-07 16:34:20 +01:00
|
|
|
return; // Don't quit the application now: wait for the fadeout finished
|
|
|
|
// signal
|
2011-02-17 00:44:03 +01:00
|
|
|
}
|
2011-02-17 00:03:00 +01:00
|
|
|
}
|
2011-02-17 00:44:03 +01:00
|
|
|
qApp->quit();
|
2011-02-16 23:43:05 +01:00
|
|
|
}
|
2011-03-06 15:07:41 +01:00
|
|
|
|
|
|
|
void MainWindow::AutoCompleteTags() {
|
|
|
|
// Create the tag fetching stuff if it hasn't been already
|
|
|
|
if (!tag_fetcher_) {
|
|
|
|
tag_fetcher_.reset(new TagFetcher);
|
|
|
|
track_selection_dialog_.reset(new TrackSelectionDialog);
|
|
|
|
track_selection_dialog_->set_save_on_close(true);
|
|
|
|
|
2011-03-12 22:19:41 +01:00
|
|
|
connect(tag_fetcher_.get(), SIGNAL(ResultAvailable(Song, SongList)),
|
2014-02-07 16:34:20 +01:00
|
|
|
track_selection_dialog_.get(),
|
|
|
|
SLOT(FetchTagFinished(Song, SongList)), Qt::QueuedConnection);
|
|
|
|
connect(tag_fetcher_.get(), SIGNAL(Progress(Song, QString)),
|
|
|
|
track_selection_dialog_.get(),
|
|
|
|
SLOT(FetchTagProgress(Song, QString)));
|
2011-03-06 15:07:41 +01:00
|
|
|
connect(track_selection_dialog_.get(), SIGNAL(accepted()),
|
|
|
|
SLOT(AutoCompleteTagsAccepted()));
|
2011-03-13 13:52:08 +01:00
|
|
|
connect(track_selection_dialog_.get(), SIGNAL(finished(int)),
|
|
|
|
tag_fetcher_.get(), SLOT(Cancel()));
|
2015-12-20 18:25:45 +01:00
|
|
|
connect(track_selection_dialog_.get(), SIGNAL(Error(QString)),
|
|
|
|
SLOT(ShowErrorDialog(QString)));
|
2011-03-06 15:07:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get the selected songs and start fetching tags for them
|
|
|
|
SongList songs;
|
|
|
|
autocomplete_tag_items_.clear();
|
2014-03-27 18:55:58 +01:00
|
|
|
for (const QModelIndex& index :
|
|
|
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (index.column() != 0) continue;
|
|
|
|
int row =
|
|
|
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
2012-02-12 14:41:50 +01:00
|
|
|
PlaylistItemPtr item(app_->playlist_manager()->current()->item_at(row));
|
2011-03-06 15:07:41 +01:00
|
|
|
Song song = item->Metadata();
|
|
|
|
|
|
|
|
if (song.IsEditable()) {
|
|
|
|
songs << song;
|
|
|
|
autocomplete_tag_items_ << item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
track_selection_dialog_->Init(songs);
|
2011-03-12 22:19:41 +01:00
|
|
|
tag_fetcher_->StartFetch(songs);
|
|
|
|
|
2011-03-06 15:07:41 +01:00
|
|
|
track_selection_dialog_->show();
|
|
|
|
}
|
2011-03-06 16:11:52 +01:00
|
|
|
|
2011-03-06 15:07:41 +01:00
|
|
|
void MainWindow::AutoCompleteTagsAccepted() {
|
2014-02-10 14:29:07 +01:00
|
|
|
for (PlaylistItemPtr item : autocomplete_tag_items_) {
|
2011-03-06 15:07:41 +01:00
|
|
|
item->Reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is really lame but we don't know what rows have changed
|
|
|
|
ui_->playlist->view()->update();
|
|
|
|
}
|
2011-04-07 18:25:52 +02:00
|
|
|
|
|
|
|
QPixmap MainWindow::CreateOverlayedIcon(int position, int scrobble_point) {
|
2015-12-20 18:25:45 +01:00
|
|
|
QPixmap normal_icon =
|
|
|
|
IconLoader::Load("as_light", IconLoader::Lastfm).pixmap(16);
|
2015-10-14 03:01:08 +02:00
|
|
|
QPixmap light_icon = IconLoader::Load("as", IconLoader::Lastfm).pixmap(16);
|
2011-04-07 18:25:52 +02:00
|
|
|
QRect rect(normal_icon.rect());
|
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
// calculates the progress
|
|
|
|
double perc = 1.0 - ((double)position / (double)scrobble_point);
|
2011-04-07 18:25:52 +02:00
|
|
|
|
|
|
|
QPolygon mask;
|
|
|
|
mask << rect.topRight();
|
|
|
|
mask << rect.topLeft();
|
2014-02-07 16:34:20 +01:00
|
|
|
mask << QPoint(rect.left(), rect.height() * perc);
|
|
|
|
mask << QPoint(rect.right(), (rect.height()) * perc);
|
2011-04-07 18:25:52 +02:00
|
|
|
|
|
|
|
QPixmap ret(light_icon);
|
|
|
|
QPainter p(&ret);
|
|
|
|
|
|
|
|
// Draw the red icon over the light red one
|
|
|
|
p.setClipRegion(mask);
|
|
|
|
p.drawPixmap(0, 0, normal_icon);
|
|
|
|
p.setClipping(false);
|
|
|
|
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::SetToggleScrobblingIcon(bool value) {
|
|
|
|
if (!value) {
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_toggle_scrobbling->setIcon(
|
|
|
|
IconLoader::Load("as_disabled", IconLoader::Lastfm));
|
2011-04-07 18:25:52 +02:00
|
|
|
} else {
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_toggle_scrobbling->setIcon(
|
|
|
|
IconLoader::Load("as_light", IconLoader::Lastfm));
|
2011-04-07 18:25:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-26 17:06:13 +02:00
|
|
|
bool MainWindow::IsLastFmEnabled() {
|
|
|
|
#ifdef HAVE_LIBLASTFM
|
|
|
|
return ui_->action_toggle_scrobbling->isVisible() &&
|
2020-09-18 16:15:19 +02:00
|
|
|
app_->scrobbler()->IsScrobblingEnabled() &&
|
|
|
|
app_->scrobbler()->IsAuthenticated();
|
2020-08-26 17:06:13 +02:00
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-04-07 18:25:52 +02:00
|
|
|
#ifdef HAVE_LIBLASTFM
|
2014-01-18 23:13:23 +01:00
|
|
|
void MainWindow::CachedToScrobble() {
|
2020-08-26 17:06:13 +02:00
|
|
|
const bool last_fm_enabled = IsLastFmEnabled();
|
2011-04-17 01:17:48 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->active()->set_lastfm_status(
|
|
|
|
Playlist::LastFM_Scrobbled);
|
2012-06-25 12:30:53 +02:00
|
|
|
|
|
|
|
// update the button icon
|
|
|
|
if (last_fm_enabled)
|
2015-12-20 18:25:45 +01:00
|
|
|
ui_->action_toggle_scrobbling->setIcon(
|
|
|
|
IconLoader::Load("as", IconLoader::Lastfm));
|
2012-06-25 12:30:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::ScrobbleError(int value) {
|
2011-04-17 01:17:48 +02:00
|
|
|
switch (value) {
|
|
|
|
case -1:
|
|
|
|
// custom error value got from initial validity check
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->active()->set_lastfm_status(
|
|
|
|
Playlist::LastFM_Invalid);
|
2011-04-17 01:17:48 +02:00
|
|
|
break;
|
2011-04-07 18:25:52 +02:00
|
|
|
|
2011-04-28 12:32:56 +02:00
|
|
|
case 30:
|
|
|
|
// Hack: when offline, liblastfm doesn't inform us, so set the status
|
2014-02-07 16:34:20 +01:00
|
|
|
// as queued; in this way we won't try to scrobble again, it will be done
|
|
|
|
// automatically
|
|
|
|
app_->playlist_manager()->active()->set_lastfm_status(
|
|
|
|
Playlist::LastFM_Queued);
|
2011-04-28 12:32:56 +02:00
|
|
|
break;
|
|
|
|
|
2011-04-17 01:17:48 +02:00
|
|
|
default:
|
|
|
|
if (value > 3) {
|
|
|
|
// we're for sure in an error state
|
2014-02-07 16:34:20 +01:00
|
|
|
app_->playlist_manager()->active()->set_lastfm_status(
|
|
|
|
Playlist::LastFM_Error);
|
2011-04-22 18:50:29 +02:00
|
|
|
qLog(Warning) << "Last.fm scrobbling error: " << value;
|
2011-04-17 01:17:48 +02:00
|
|
|
}
|
|
|
|
break;
|
2011-04-07 18:25:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2011-05-22 23:15:11 +02:00
|
|
|
|
2014-02-07 16:34:20 +01:00
|
|
|
void MainWindow::HandleNotificationPreview(OSD::Behaviour type, QString line1,
|
|
|
|
QString line2) {
|
2021-03-23 00:16:48 +01:00
|
|
|
qLog(Debug) << "Handling notification preview";
|
2012-02-12 14:41:50 +01:00
|
|
|
if (!app_->playlist_manager()->current()->GetAllSongs().isEmpty()) {
|
2011-05-22 23:15:11 +02:00
|
|
|
// Show a preview notification for the first song in the current playlist
|
2014-02-07 16:34:20 +01:00
|
|
|
osd_->ShowPreview(
|
|
|
|
type, line1, line2,
|
|
|
|
app_->playlist_manager()->current()->GetAllSongs().first());
|
2011-05-22 23:15:11 +02:00
|
|
|
} else {
|
|
|
|
qLog(Debug) << "The current playlist is empty, showing a fake song";
|
|
|
|
// Create a fake song
|
|
|
|
Song fake;
|
|
|
|
fake.Init("Title", "Artist", "Album", 123);
|
|
|
|
fake.set_genre("Classical");
|
|
|
|
fake.set_composer("Anonymous");
|
2013-03-03 13:00:24 +01:00
|
|
|
fake.set_performer("Anonymous");
|
2015-04-10 21:05:07 +02:00
|
|
|
fake.set_lyrics("None");
|
2011-05-22 23:15:11 +02:00
|
|
|
fake.set_track(1);
|
|
|
|
fake.set_disc(1);
|
|
|
|
fake.set_year(2011);
|
|
|
|
|
|
|
|
osd_->ShowPreview(type, line1, line2, fake);
|
|
|
|
}
|
|
|
|
}
|
2012-03-11 18:57:15 +01:00
|
|
|
|
|
|
|
void MainWindow::ScrollToInternetIndex(const QModelIndex& index) {
|
|
|
|
internet_view_->ScrollToIndex(index);
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->setCurrentWidget(internet_view_);
|
2012-03-11 18:57:15 +01:00
|
|
|
}
|
2012-03-12 15:11:24 +01:00
|
|
|
|
|
|
|
void MainWindow::AddPodcast() {
|
|
|
|
app_->internet_model()->Service<PodcastService>()->AddPodcast();
|
|
|
|
}
|
2012-06-16 22:17:13 +02:00
|
|
|
|
2016-07-01 11:37:04 +02:00
|
|
|
void MainWindow::FocusLibraryTab() {
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->setCurrentWidget(library_view_);
|
2016-07-01 11:37:04 +02:00
|
|
|
}
|
|
|
|
|
2012-06-16 22:17:13 +02:00
|
|
|
void MainWindow::FocusGlobalSearchField() {
|
2018-01-10 10:22:05 +01:00
|
|
|
ui_->tabs->setCurrentWidget(global_search_view_);
|
2012-06-16 22:17:13 +02:00
|
|
|
global_search_view_->FocusSearchField();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::DoGlobalSearch(const QString& query) {
|
|
|
|
FocusGlobalSearchField();
|
|
|
|
global_search_view_->StartSearch(query);
|
|
|
|
}
|
2012-09-26 18:36:47 +02:00
|
|
|
|
2020-12-29 10:05:10 +01:00
|
|
|
void MainWindow::ShowConsole() { debug_console_->show(); }
|
2013-05-13 17:40:00 +02:00
|
|
|
|
|
|
|
void MainWindow::keyPressEvent(QKeyEvent* event) {
|
2014-02-07 16:34:20 +01:00
|
|
|
if (event->key() == Qt::Key_Space) {
|
2013-05-13 17:40:00 +02:00
|
|
|
app_->player()->PlayPause();
|
|
|
|
event->accept();
|
|
|
|
} else {
|
|
|
|
QMainWindow::keyPressEvent(event);
|
|
|
|
}
|
|
|
|
}
|
2021-01-10 06:53:40 +01:00
|
|
|
|
|
|
|
// Change the state of action_next_album based when the repeat mode is
|
|
|
|
// changed.
|
|
|
|
void MainWindow::SetNextAlbumEnabled(PlaylistSequence::RepeatMode mode) {
|
|
|
|
if (mode == PlaylistSequence::Repeat_Track ||
|
|
|
|
mode == PlaylistSequence::Repeat_Album) {
|
|
|
|
if (ui_->action_next_album->isEnabled())
|
|
|
|
ui_->action_next_album->setDisabled(true);
|
|
|
|
} else {
|
|
|
|
if (!ui_->action_next_album->isEnabled())
|
|
|
|
ui_->action_next_album->setEnabled(true);
|
|
|
|
}
|
|
|
|
}
|