NowPlayingWidget::NowPlayingWidget(QWidget* parent) : QWidget(parent), app_(nullptr), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), mode_(SmallSongDetails), menu_(new QMenu(this)), above_statusbar_action_(nullptr), fit_cover_width_action_(nullptr), visible_(false), small_ideal_height_(0), fit_width_(false), show_hide_animation_(new QTimeLine(500, this)), fade_animation_(new QTimeLine(1000, this)), details_(new QTextDocument(this)), previous_track_opacity_(0.0), bask_in_his_glory_action_(nullptr), downloading_covers_(false), aww_(false), kittens_(nullptr), pending_kitten_(0) { // Load settings QSettings s; s.beginGroup(kSettingsGroup); mode_ = Mode(s.value("mode", SmallSongDetails).toInt()); album_cover_choice_controller_->search_cover_auto_action()->setChecked( s.value("search_for_cover_auto", false).toBool()); fit_width_ = s.value("fit_cover_width", false).toBool(); // Accept drops for setting album art setAcceptDrops(true); // Context menu QActionGroup* mode_group = new QActionGroup(this); QSignalMapper* mode_mapper = new QSignalMapper(this); connect(mode_mapper, SIGNAL(mapped(int)), SLOT(SetMode(int))); CreateModeAction(SmallSongDetails, tr("Small album cover"), mode_group, mode_mapper); CreateModeAction(LargeSongDetails, tr("Large album cover"), mode_group, mode_mapper); CreateModeAction(LargeSongDetailsBelow, tr("Large album cover (details below)"), mode_group, mode_mapper); menu_->addActions(mode_group->actions()); fit_cover_width_action_ = menu_->addAction(tr("Fit cover to width")); fit_cover_width_action_->setCheckable(true); fit_cover_width_action_->setEnabled((mode_ != SmallSongDetails) ? true : false); connect(fit_cover_width_action_, SIGNAL(toggled(bool)), SLOT(FitCoverWidth(bool))); fit_cover_width_action_->setChecked(fit_width_); menu_->addSeparator(); QList<QAction*> actions = album_cover_choice_controller_->GetAllActions(); // Here we add the search automatically action, too! actions.append(album_cover_choice_controller_->search_cover_auto_action()); connect(album_cover_choice_controller_->cover_from_file_action(), SIGNAL(triggered()), this, SLOT(LoadCoverFromFile())); connect(album_cover_choice_controller_->cover_to_file_action(), SIGNAL(triggered()), this, SLOT(SaveCoverToFile())); connect(album_cover_choice_controller_->cover_from_url_action(), SIGNAL(triggered()), this, SLOT(LoadCoverFromURL())); connect(album_cover_choice_controller_->search_for_cover_action(), SIGNAL(triggered()), this, SLOT(SearchForCover())); connect(album_cover_choice_controller_->unset_cover_action(), SIGNAL(triggered()), this, SLOT(UnsetCover())); connect(album_cover_choice_controller_->show_cover_action(), SIGNAL(triggered()), this, SLOT(ShowCover())); connect(album_cover_choice_controller_->search_cover_auto_action(), SIGNAL(triggered()), this, SLOT(SearchCoverAutomatically())); menu_->addActions(actions); menu_->addSeparator(); above_statusbar_action_ = menu_->addAction(tr("Show above status bar")); above_statusbar_action_->setCheckable(true); connect(above_statusbar_action_, SIGNAL(toggled(bool)), SLOT(ShowAboveStatusBar(bool))); above_statusbar_action_->setChecked( s.value("above_status_bar", false).toBool()); bask_in_his_glory_action_ = menu_->addAction(tr("ALL GLORY TO THE HYPNOTOAD")); bask_in_his_glory_action_->setVisible(false); connect(bask_in_his_glory_action_, SIGNAL(triggered()), SLOT(Bask())); // Animations connect(show_hide_animation_, SIGNAL(frameChanged(int)), SLOT(SetHeight(int))); setMaximumHeight(0); connect(fade_animation_, SIGNAL(valueChanged(qreal)), SLOT(FadePreviousTrack(qreal))); fade_animation_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0 // add placeholder text to get the correct height if (mode_ == LargeSongDetailsBelow) { details_->setDefaultStyleSheet( "p {" " font-size: small;" " color: white;" "}"); details_->setHtml(QString("<p align=center><i></i><br/><br/></p>")); } UpdateHeight(); connect(album_cover_choice_controller_, SIGNAL(AutomaticCoverSearchDone()), this, SLOT(AutomaticCoverSearchDone())); }
void AlbumCoverManager::Init() { // View menu QActionGroup* filter_group = new QActionGroup(this); filter_all_ = filter_group->addAction(tr("All albums")); filter_with_covers_ = filter_group->addAction(tr("Albums with covers")); filter_without_covers_ = filter_group->addAction(tr("Albums without covers")); filter_all_->setCheckable(true); filter_with_covers_->setCheckable(true); filter_without_covers_->setCheckable(true); filter_group->setExclusive(true); filter_all_->setChecked(true); QMenu* view_menu = new QMenu(this); view_menu->addActions(filter_group->actions()); ui_->view->setMenu(view_menu); // Context menu QList<QAction*> actions = album_cover_choice_controller_->GetAllActions(); connect(album_cover_choice_controller_->cover_from_file_action(), SIGNAL(triggered()), this, SLOT(LoadCoverFromFile())); connect(album_cover_choice_controller_->cover_to_file_action(), SIGNAL(triggered()), this, SLOT(SaveCoverToFile())); connect(album_cover_choice_controller_->cover_from_url_action(), SIGNAL(triggered()), this, SLOT(LoadCoverFromURL())); connect(album_cover_choice_controller_->search_for_cover_action(), SIGNAL(triggered()), this, SLOT(SearchForCover())); connect(album_cover_choice_controller_->unset_cover_action(), SIGNAL(triggered()), this, SLOT(UnsetCover())); connect(album_cover_choice_controller_->show_cover_action(), SIGNAL(triggered()), this, SLOT(ShowCover())); context_menu_->addActions(actions); context_menu_->addSeparator(); context_menu_->addAction(ui_->action_load); context_menu_->addAction(ui_->action_add_to_playlist); ui_->albums->installEventFilter(this); // Connections connect(ui_->artists, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SLOT(ArtistChanged(QListWidgetItem*))); connect(ui_->filter, SIGNAL(textChanged(QString)), SLOT(UpdateFilter())); connect(filter_group, SIGNAL(triggered(QAction*)), SLOT(UpdateFilter())); connect(ui_->view, SIGNAL(clicked()), ui_->view, SLOT(showMenu())); connect(ui_->fetch, SIGNAL(clicked()), SLOT(FetchAlbumCovers())); connect(cover_fetcher_, SIGNAL(AlbumCoverFetched(quint64,QImage,CoverSearchStatistics)), SLOT(AlbumCoverFetched(quint64,QImage,CoverSearchStatistics))); connect(ui_->action_fetch, SIGNAL(triggered()), SLOT(FetchSingleCover())); connect(ui_->albums, SIGNAL(doubleClicked(QModelIndex)), SLOT(AlbumDoubleClicked(QModelIndex))); connect(ui_->action_add_to_playlist, SIGNAL(triggered()), SLOT(AddSelectedToPlaylist())); connect(ui_->action_load, SIGNAL(triggered()), SLOT(LoadSelectedToPlaylist())); #ifdef Q_OS_DARWIN MacLineEdit* lineedit = new MacLineEdit(ui_->filter->parentWidget()); lineedit->set_hint(ui_->filter->hint()); delete ui_->filter; ui_->horizontalLayout->insertWidget(0, lineedit); filter_ = lineedit; connect(lineedit, SIGNAL(textChanged(QString)), SLOT(UpdateFilter())); lineedit->show(); #else filter_ = ui_->filter; #endif // Restore settings QSettings s; s.beginGroup(kSettingsGroup); restoreGeometry(s.value("geometry").toByteArray()); if (!ui_->splitter->restoreState(s.value("splitter_state").toByteArray())) { // Sensible default size for the artists view ui_->splitter->setSizes(QList<int>() << 200 << width() - 200); } cover_loader_->Start(true); CoverLoaderInitialised(); cover_searcher_->Init(cover_fetcher_); new ForceScrollPerPixel(ui_->albums, this); }
EditTagDialog::EditTagDialog(Application* app, QWidget* parent) : QDialog(parent), ui_(new Ui_EditTagDialog), app_(app), album_cover_choice_controller_(new AlbumCoverChoiceController(this)), loading_(false), ignore_edits_(false), tag_fetcher_(new TagFetcher(this)), cover_art_id_(0), cover_art_is_set_(false), results_dialog_(new TrackSelectionDialog(this)) { cover_options_.default_output_image_ = AlbumCoverLoader::ScaleAndPad(cover_options_, QImage(":nocover.png")); connect(app_->album_cover_loader(), SIGNAL(ImageLoaded(quint64, QImage, QImage)), SLOT(ArtLoaded(quint64, QImage, QImage))); connect(tag_fetcher_, SIGNAL(ResultAvailable(Song, SongList)), results_dialog_, SLOT(FetchTagFinished(Song, SongList)), Qt::QueuedConnection); connect(tag_fetcher_, SIGNAL(Progress(Song, QString)), results_dialog_, SLOT(FetchTagProgress(Song, QString))); connect(results_dialog_, SIGNAL(SongChosen(Song, Song)), SLOT(FetchTagSongChosen(Song, Song))); connect(results_dialog_, SIGNAL(finished(int)), tag_fetcher_, SLOT(Cancel())); album_cover_choice_controller_->SetApplication(app_); ui_->setupUi(this); ui_->splitter->setSizes(QList<int>() << 200 << width() - 200); ui_->loading_label->hide(); // An editable field is one that has a label as a buddy. The label is // important because it gets turned bold when the field is changed. for (QLabel* label : findChildren<QLabel*>()) { QWidget* widget = label->buddy(); if (widget) { // Store information about the field fields_ << FieldData(label, widget, widget->objectName()); // Connect the Reset signal if (dynamic_cast<ExtendedEditor*>(widget)) { connect(widget, SIGNAL(Reset()), SLOT(ResetField())); } // Connect the edited signal if (qobject_cast<QLineEdit*>(widget)) { connect(widget, SIGNAL(textChanged(QString)), SLOT(FieldValueEdited())); } else if (qobject_cast<QPlainTextEdit*>(widget)) { connect(widget, SIGNAL(textChanged()), SLOT(FieldValueEdited())); } else if (qobject_cast<QSpinBox*>(widget)) { connect(widget, SIGNAL(valueChanged(int)), SLOT(FieldValueEdited())); } } } // Set the colour of all the labels on the summary page const bool light = palette().color(QPalette::Base).value() > 128; const QColor color = palette().color(QPalette::Dark); QPalette summary_label_palette(palette()); summary_label_palette.setColor( QPalette::WindowText, light ? color.darker(150) : color.lighter(125)); for (QLabel* label : ui_->summary_tab->findChildren<QLabel*>()) { if (label->property("field_label").toBool()) { label->setPalette(summary_label_palette); } } // Pretend the summary text is just a label ui_->summary->setMaximumHeight(ui_->art->height() - ui_->summary_art_button->height() - 4); connect(ui_->song_list->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(SelectionChanged())); connect(ui_->button_box, SIGNAL(clicked(QAbstractButton*)), SLOT(ButtonClicked(QAbstractButton*))); connect(ui_->rating, SIGNAL(RatingChanged(float)), SLOT(SongRated(float))); connect(ui_->playcount_reset, SIGNAL(clicked()), SLOT(ResetPlayCounts())); connect(ui_->fetch_tag, SIGNAL(clicked()), SLOT(FetchTag())); // Set up the album cover menu cover_menu_ = new QMenu(this); QList<QAction*> actions = album_cover_choice_controller_->GetAllActions(); connect(album_cover_choice_controller_->cover_from_file_action(), SIGNAL(triggered()), this, SLOT(LoadCoverFromFile())); connect(album_cover_choice_controller_->cover_to_file_action(), SIGNAL(triggered()), this, SLOT(SaveCoverToFile())); connect(album_cover_choice_controller_->cover_from_url_action(), SIGNAL(triggered()), this, SLOT(LoadCoverFromURL())); connect(album_cover_choice_controller_->search_for_cover_action(), SIGNAL(triggered()), this, SLOT(SearchForCover())); connect(album_cover_choice_controller_->unset_cover_action(), SIGNAL(triggered()), this, SLOT(UnsetCover())); connect(album_cover_choice_controller_->show_cover_action(), SIGNAL(triggered()), this, SLOT(ShowCover())); cover_menu_->addActions(actions); ui_->summary_art_button->setMenu(cover_menu_); ui_->art->installEventFilter(this); ui_->art->setAcceptDrops(true); // Add the next/previous buttons previous_button_ = new QPushButton(IconLoader::Load("go-previous"), tr("Previous"), this); next_button_ = new QPushButton(IconLoader::Load("go-next"), tr("Next"), this); ui_->button_box->addButton(previous_button_, QDialogButtonBox::ResetRole); ui_->button_box->addButton(next_button_, QDialogButtonBox::ResetRole); connect(previous_button_, SIGNAL(clicked()), SLOT(PreviousSong())); connect(next_button_, SIGNAL(clicked()), SLOT(NextSong())); // Set some shortcuts for the buttons new QShortcut(QKeySequence::Back, previous_button_, SLOT(click())); new QShortcut(QKeySequence::Forward, next_button_, SLOT(click())); new QShortcut(QKeySequence::MoveToPreviousPage, previous_button_, SLOT(click())); new QShortcut(QKeySequence::MoveToNextPage, next_button_, SLOT(click())); // Show the shortcuts as tooltips previous_button_->setToolTip(QString("%1 (%2 / %3)").arg( previous_button_->text(), QKeySequence(QKeySequence::Back).toString(QKeySequence::NativeText), QKeySequence(QKeySequence::MoveToPreviousPage) .toString(QKeySequence::NativeText))); next_button_->setToolTip(QString("%1 (%2 / %3)").arg( next_button_->text(), QKeySequence(QKeySequence::Forward).toString(QKeySequence::NativeText), QKeySequence(QKeySequence::MoveToNextPage) .toString(QKeySequence::NativeText))); new TagCompleter(app_->library_backend(), Playlist::Column_Artist, ui_->artist); new TagCompleter(app_->library_backend(), Playlist::Column_Album, ui_->album); new TagCompleter(app_->library_backend(), Playlist::Column_AlbumArtist, ui_->albumartist); new TagCompleter(app_->library_backend(), Playlist::Column_Genre, ui_->genre); new TagCompleter(app_->library_backend(), Playlist::Column_Composer, ui_->composer); new TagCompleter(app_->library_backend(), Playlist::Column_Performer, ui_->performer); new TagCompleter(app_->library_backend(), Playlist::Column_Grouping, ui_->grouping); }