1 /* This file is part of Clementine.
2    Copyright 2010, David Sansome <me@davidsansome.com>
3 
4    Clementine is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8 
9    Clementine is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with Clementine.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #ifndef MAINWINDOW_H
19 #define MAINWINDOW_H
20 
21 #include <memory>
22 
23 #include <QMainWindow>
24 #include <QSettings>
25 #include <QSystemTrayIcon>
26 
27 #include "config.h"
28 #include "core/lazy.h"
29 #include "core/mac_startup.h"
30 #include "core/tagreaderclient.h"
31 #include "engines/engine_fwd.h"
32 #include "library/librarymodel.h"
33 #include "playlist/playlistitem.h"
34 #include "songinfo/streamdiscoverer.h"
35 #include "ui/organisedialog.h"
36 #include "ui/settingsdialog.h"
37 #include "ui/streamdetailsdialog.h"
38 
39 class About;
40 class AddStreamDialog;
41 class AlbumCoverManager;
42 class Appearance;
43 class Application;
44 class ArtistInfoView;
45 class BackgroundStreams;
46 class CommandlineOptions;
47 class CoverProviders;
48 class Database;
49 class DeviceManager;
50 class DeviceView;
51 class DeviceViewContainer;
52 class EditTagDialog;
53 class Equalizer;
54 class ErrorDialog;
55 class FileView;
56 class GlobalSearch;
57 class GlobalSearchView;
58 class GlobalShortcuts;
59 class GroupByDialog;
60 class Library;
61 class LibraryViewContainer;
62 class MimeData;
63 class MultiLoadingIndicator;
64 class OSD;
65 class Player;
66 class PlaylistBackend;
67 class PlaylistListContainer;
68 class PlaylistManager;
69 class QueueManager;
70 class InternetItem;
71 class InternetModel;
72 class InternetViewContainer;
73 class RipCDDialog;
74 class Song;
75 class SongInfoBase;
76 class SongInfoView;
77 class StreamDetailsDialog;
78 class SystemTrayIcon;
79 class TagFetcher;
80 class TaskManager;
81 class TrackSelectionDialog;
82 class TranscodeDialog;
83 class VisualisationContainer;
84 class WiimotedevShortcuts;
85 class Windows7ThumbBar;
86 class Ui_MainWindow;
87 
88 class QSortFilterProxyModel;
89 
90 class MainWindow : public QMainWindow, public PlatformInterface {
91   Q_OBJECT
92 
93  public:
94   MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
95              const CommandlineOptions& options, QWidget* parent = nullptr);
96   ~MainWindow();
97 
98   static const char* kSettingsGroup;
99   static const char* kAllFilesFilterSpec;
100 
101   // Don't change the values
102   enum StartupBehaviour {
103     Startup_Remember = 1,
104     Startup_AlwaysShow = 2,
105     Startup_AlwaysHide = 3,
106   };
107 
108   // Don't change the values
109   enum AddBehaviour {
110     AddBehaviour_Append = 1,
111     AddBehaviour_Enqueue = 2,
112     AddBehaviour_Load = 3,
113     AddBehaviour_OpenInNew = 4
114   };
115 
116   // Don't change the values
117   enum PlayBehaviour {
118     PlayBehaviour_Never = 1,
119     PlayBehaviour_IfStopped = 2,
120     PlayBehaviour_Always = 3,
121   };
122 
123   // Don't change the values
124   enum PlaylistAddBehaviour {
125     PlaylistAddBehaviour_Play = 1,
126     PlaylistAddBehaviour_Enqueue = 2,
127   };
128 
129   void SetHiddenInTray(bool hidden);
130   void CommandlineOptionsReceived(const CommandlineOptions& options);
131 
132  protected:
133   void keyPressEvent(QKeyEvent* event);
134   void changeEvent(QEvent*);
135   void resizeEvent(QResizeEvent*);
136   void closeEvent(QCloseEvent* event);
137 
138 #ifdef Q_OS_WIN32
139   bool winEvent(MSG* message, long* result);
140 #endif
141 
142   // PlatformInterface
143   void Activate();
144   bool LoadUrl(const QString& url);
145 
146 signals:
147   // Signals that stop playing after track was toggled.
148   void StopAfterToggled(bool stop);
149 
150   void IntroPointReached();
151  private slots:
152   void FilePathChanged(const QString& path);
153 
154   void SaveSettings(QSettings* settings);
155   void MediaStopped();
156   void MediaPaused();
157   void MediaPlaying();
158   void TrackSkipped(PlaylistItemPtr item);
159   void ForceShowOSD(const Song& song, const bool toggle);
160 
161   void PlaylistRightClick(const QPoint& global_pos, const QModelIndex& index);
162   void PlaylistCurrentChanged(const QModelIndex& current);
163   void PlaylistViewSelectionModelChanged();
164   void PlaylistPlay();
165   void PlaylistStopAfter();
166   void PlaylistQueue();
167   void PlaylistQueuePlayNext();
168   void PlaylistSkip();
169   void PlaylistRemoveCurrent();
170   void PlaylistEditFinished(const QModelIndex& index);
171   void EditTracks();
172   void EditTagDialogAccepted();
173   void DiscoverStreamDetails();
174   void ShowStreamDetails(const StreamDetails& details);
175   void RenumberTracks();
176   void SelectionSetValue();
177   void EditValue();
178   void AutoCompleteTags();
179   void AutoCompleteTagsAccepted();
180   void PlaylistUndoRedoChanged(QAction* undo, QAction* redo);
181   void AddFilesToTranscoder();
182 
183   void SearchForArtist();
184   void SearchForAlbum();
185 
186   void PlaylistCopyToLibrary();
187   void PlaylistMoveToLibrary();
188   void PlaylistCopyToDevice();
189   void PlaylistOrganiseSelected(bool copy);
190   void PlaylistDelete();
191   void PlaylistOpenInBrowser();
192   void ShowInLibrary();
193 
194   void ChangeLibraryQueryMode(QAction* action);
195 
196   void PlayIndex(const QModelIndex& index);
197   void PlaylistDoubleClick(const QModelIndex& index);
198   void StopAfterCurrent();
199 
200   void SongChanged(const Song& song);
201   void VolumeChanged(int volume);
202 
203   void CopyFilesToLibrary(const QList<QUrl>& urls);
204   void MoveFilesToLibrary(const QList<QUrl>& urls);
205   void CopyFilesToDevice(const QList<QUrl>& urls);
206   void EditFileTags(const QList<QUrl>& urls);
207 
208   void AddToPlaylist(QMimeData* data);
209   void AddToPlaylist(QAction* action);
210 
211   void VolumeWheelEvent(int delta);
212   void ToggleShowHide();
213 
214   void Seeked(qlonglong microseconds);
215   void UpdateTrackPosition();
216   void UpdateTrackSliderPosition();
217 
218   // Handle visibility of LastFM icons
219   void LastFMButtonVisibilityChanged(bool value);
220   void ScrobbleButtonVisibilityChanged(bool value);
221   void SetToggleScrobblingIcon(bool value);
222 #ifdef HAVE_LIBLASTFM
223   void ScrobblingEnabledChanged(bool value);
224   void Love();
225   void ScrobbledRadioStream();
226 #endif
227 
228   void TaskCountChanged(int count);
229 
230   void ShowLibraryConfig();
231   void ReloadSettings();
232   void ReloadAllSettings();
233   void RefreshStyleSheet();
SetHiddenInTray()234   void SetHiddenInTray() { SetHiddenInTray(true); }
235 
236   void AddFile();
237   void AddFolder();
238   void AddStream();
239   void AddStreamAccepted();
240   void OpenRipCDDialog();
241   void AddCDTracks();
242   void AddPodcast();
243 
244   void CommandlineOptionsReceived(const QString& string_options);
245 
246   void CheckForUpdates();
247 
248   void NowPlayingWidgetPositionChanged(bool above_status_bar);
249 
250   void SongSaveComplete(TagReaderReply* reply,
251                         const QPersistentModelIndex& index);
252 
253   void ShowCoverManager();
254 #ifdef HAVE_LIBLASTFM
255   void ScrobbleSubmitted();
256   void ScrobbleError(int value);
257 #endif
258   void ShowAboutDialog();
259   void ShowTranscodeDialog();
260   void ShowErrorDialog(const QString& message);
261   void ShowQueueManager();
262   void ShowVisualisations();
263   SettingsDialog* CreateSettingsDialog();
264   EditTagDialog* CreateEditTagDialog();
265   StreamDiscoverer* CreateStreamDiscoverer();
266   void OpenSettingsDialog();
267   void OpenSettingsDialogAtPage(SettingsDialog::Page page);
268   void ShowSongInfoConfig();
269 
270   void SaveGeometry(QSettings* settings);
271   void SavePlaybackStatus(QSettings* settings);
272   void LoadPlaybackStatus();
273   void ResumePlayback();
274   void ResumePlaybackPosition();
275 
276   void AddSongInfoGenerator(smart_playlists::GeneratorPtr gen);
277 
278   void DeleteFinished(const SongList& songs_with_errors);
279 
280   void Raise();
281 
282   void Exit();
283 
284   void HandleNotificationPreview(OSD::Behaviour type, QString line1,
285                                  QString line2);
286 
287   void ScrollToInternetIndex(const QModelIndex& index);
288   void FocusLibraryTab();
289   void FocusGlobalSearchField();
290   void DoGlobalSearch(const QString& query);
291 
292   void ShowConsole();
293 
294  private:
295   void ConnectInfoView(SongInfoBase* view);
296 
297   void ApplyAddBehaviour(AddBehaviour b, MimeData* data) const;
298   void ApplyPlayBehaviour(PlayBehaviour b, MimeData* data) const;
299 
300   void CheckFullRescanRevisions();
301 
302   // creates the icon by painting the full one depending on the current position
303   QPixmap CreateOverlayedIcon(int position, int scrobble_point);
304 
305  private:
306   Ui_MainWindow* ui_;
307   Windows7ThumbBar* thumbbar_;
308 
309   Application* app_;
310   SystemTrayIcon* tray_icon_;
311   OSD* osd_;
312   Lazy<EditTagDialog> edit_tag_dialog_;
313   Lazy<About> about_dialog_;
314   Lazy<StreamDiscoverer> stream_discoverer_;
315 
316   GlobalShortcuts* global_shortcuts_;
317 
318   GlobalSearchView* global_search_view_;
319   LibraryViewContainer* library_view_;
320   FileView* file_view_;
321 #ifdef HAVE_AUDIOCD
322   std::unique_ptr<RipCDDialog> rip_cd_dialog_;
323 #endif
324   PlaylistListContainer* playlist_list_;
325   InternetViewContainer* internet_view_;
326   DeviceViewContainer* device_view_container_;
327   DeviceView* device_view_;
328   SongInfoView* song_info_view_;
329   ArtistInfoView* artist_info_view_;
330 
331   Lazy<SettingsDialog> settings_dialog_;
332   Lazy<AddStreamDialog> add_stream_dialog_;
333   Lazy<AlbumCoverManager> cover_manager_;
334   std::unique_ptr<Equalizer> equalizer_;
335   Lazy<TranscodeDialog> transcode_dialog_;
336   Lazy<ErrorDialog> error_dialog_;
337   Lazy<OrganiseDialog> organise_dialog_;
338   Lazy<QueueManager> queue_manager_;
339 
340   std::unique_ptr<TagFetcher> tag_fetcher_;
341   std::unique_ptr<TrackSelectionDialog> track_selection_dialog_;
342   PlaylistItemList autocomplete_tag_items_;
343 
344 #ifdef HAVE_VISUALISATIONS
345   std::unique_ptr<VisualisationContainer> visualisation_;
346 #endif
347 
348 #ifdef HAVE_WIIMOTEDEV
349   std::unique_ptr<WiimotedevShortcuts> wiimotedev_shortcuts_;
350 #endif
351 
352   QAction* library_show_all_;
353   QAction* library_show_duplicates_;
354   QAction* library_show_untagged_;
355 
356   QMenu* playlist_menu_;
357   QAction* playlist_play_pause_;
358   QAction* playlist_stop_after_;
359   QAction* playlist_undoredo_;
360   QAction* playlist_organise_;
361   QAction* playlist_show_in_library_;
362   QAction* playlist_copy_to_library_;
363   QAction* playlist_move_to_library_;
364   QAction* playlist_copy_to_device_;
365   QAction* playlist_delete_;
366   QAction* playlist_open_in_browser_;
367   QAction* playlist_queue_;
368   QAction* playlist_queue_play_next_;
369   QAction* playlist_skip_;
370   QAction* playlist_add_to_another_;
371   QList<QAction*> playlistitem_actions_;
372   QAction* playlistitem_actions_separator_;
373   QModelIndex playlist_menu_index_;
374 
375   QAction* search_for_artist_;
376   QAction* search_for_album_;
377 
378   QSortFilterProxyModel* library_sort_model_;
379 
380   QTimer* track_position_timer_;
381   QTimer* track_slider_timer_;
382   QSettings settings_;
383 
384   bool initialized_;
385 
386   bool dirty_geometry_;
387   bool dirty_playback_;
388 
389   bool was_maximized_;
390   int saved_playback_position_;
391   Engine::State saved_playback_state_;
392   AddBehaviour doubleclick_addmode_;
393   PlayBehaviour doubleclick_playmode_;
394   PlaylistAddBehaviour doubleclick_playlist_addmode_;
395   PlayBehaviour menu_playmode_;
396 
397   BackgroundStreams* background_streams_;
398 };
399 
400 #endif  // MAINWINDOW_H
401