TTKMusicPlayer  4.3.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
musicapplication.cpp
Go to the documentation of this file.
1 #include "musicapplication.h"
2 #include "ui_musicapplication.h"
5 #include "musicconfigmanager.h"
6 #include "musicplayer.h"
7 #include "musicformats.h"
8 #include "musicplaylist.h"
10 #include "musicbottomareawidget.h"
11 #include "musictopareawidget.h"
12 #include "musicrightareawidget.h"
13 #include "musicleftareawidget.h"
14 #include "musicapplicationmodule.h"
15 #include "musichotkeymanager.h"
16 #include "musicfunctionuiobject.h"
17 #include "musictoastlabel.h"
18 #include "musicfileutils.h"
19 #include "musicplaylistmanager.h"
20 #include "musictinyuiobject.h"
21 #include "musicdispatchmanager.h"
22 #include "musictkplconfigmanager.h"
23 #include "musicinputdialog.h"
24 #include "ttkversion.h"
25 
26 #include "qalgorithm/aeswrapper.h"
27 
29 
31  : TTKAbstractMoveResizeWidget(false, parent),
32  m_ui(new Ui::MusicApplication),
33  m_quitWindowMode(false),
34  m_currentPlaylistRow(TTK_NORMAL_LEVEL)
35 {
36  m_instance = this;
37 
43 
44  m_ui->setupUi(this);
45  const QSize &size = G_SETTING_PTR->value(MusicSettingManager::ScreenSize).toSize();
46  setMinimumSize(WINDOW_WIDTH_MIN, WINDOW_HEIGHT_MIN);
47  setMaximumSize(size.width(), size.height());
48 
49  m_player = new MusicPlayer(this);
50  m_playlist = new MusicPlaylist(this);
52  m_ui->songsContainer->addWidget(m_songTreeWidget);
53 
59 
60  m_playlist->setPlaybackMode(TTK::PlayMode::Order); //The default is the order of play
61  m_ui->playedListButton->setPlaylist(m_playlist);
62  m_player->setPlaylist(m_playlist);
63  m_player->setVolume(100); //The default Volume is 100
64 
65  connect(m_player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
66  connect(m_player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
67  connect(m_player, SIGNAL(stateChanged(TTK::PlayState)), SLOT(playerStateChanged(TTK::PlayState)));
68  connect(m_playlist, SIGNAL(currentIndexChanged(int)), SLOT(showCurrentSong()));
69  connect(m_ui->desktopLrcButton, SIGNAL(clicked(bool)), m_rightAreaWidget, SLOT(setDestopLrcVisible(bool)));
70 
71  m_ui->playButton->setFocus();
72  m_ui->lrcDisplayAllButton->hide();
73  m_ui->functionsContainer->setCurrentIndex(MUSIC_SEARCH_PAGE);
74 
75  m_ui->timeSliderWidget->setInputModule(this);
76 
77  G_HOTKEY_PTR->addHotKey(this, SLOT(switchToPlayState()));
78  G_HOTKEY_PTR->addHotKey(this, SLOT(showSettingWidget()));
79  G_HOTKEY_PTR->addHotKey(this, SLOT(playPrevious()));
80  G_HOTKEY_PTR->addHotKey(this, SLOT(playNext()));
81  G_HOTKEY_PTR->addHotKey(this, SLOT(volumeUp()));
82  G_HOTKEY_PTR->addHotKey(this, SLOT(volumeDown()));
83  G_HOTKEY_PTR->addHotKey(this, SLOT(volumeMute()));
84  G_HOTKEY_PTR->addHotKey(this, SLOT(importSongsPopup()));
85  G_HOTKEY_PTR->addHotKey(this, SLOT(addSongToLovestList()));
86  G_HOTKEY_PTR->addHotKey(this, SLOT(currentPlayLocation()));
87  G_HOTKEY_PTR->addHotKey(this, SLOT(importSongsItemList()));
88  G_HOTKEY_PTR->addHotKey(this, SLOT(exportSongsItemList()));
89  G_HOTKEY_PTR->addHotKey(m_applicationModule, SLOT(showSpectrumWidget()));
90  G_HOTKEY_PTR->addHotKey(this, SLOT(windowConciseChanged()));
91  G_HOTKEY_PTR->addHotKey(m_applicationModule, SLOT(showAboutWidget()));
92  G_HOTKEY_PTR->addHotKey(this, SLOT(quitWindow()));
93 
94  // Objects Mouse tracking
95  setObjectsTracking({m_ui->background, m_ui->songsContainer});
96 
98  TTK_SIGNLE_SHOT(m_rightAreaWidget, showSongMainWidget, TTK_SLOT);
99 }
100 
102 {
103  delete m_player;
104  delete m_playlist;
105  delete m_songTreeWidget;
106  delete m_bottomAreaWidget;
107  delete m_topAreaWidget;
108  delete m_rightAreaWidget;
109  delete m_leftAreaWidget;
110  delete m_applicationModule;
111  delete m_ui;
112 }
113 
115 {
116  return m_instance;
117 }
118 
120 {
122  {
123  return {};
124  }
125 
126  const MusicPlayItem &item = m_playlist->currentItem();
127  const MusicSongItemList &items = m_songTreeWidget->items();
128 
129  if(0 <= m_currentPlaylistRow && m_currentPlaylistRow < items.count())
130  {
131  const MusicSongList &songs = items[m_currentPlaylistRow].m_songs;
133  return (index != -1) ? songs[index].name() : QString();
134  }
135  return {};
136 }
137 
139 {
141  {
142  return {};
143  }
144 
145  const MusicPlayItem &item = m_playlist->currentItem();
146  const MusicSongItemList &items = m_songTreeWidget->items();
147 
148  if(0 <= m_currentPlaylistRow && m_currentPlaylistRow < items.count())
149  {
150  const MusicSongList &songs = items[m_currentPlaylistRow].m_songs;
152  return (index != -1) ? songs[index].path() : QString();
153  }
154  return {};
155 }
156 
158 {
160 }
161 
163 {
164  //Loading the current song lrc
166  {
167  return;
168  }
169 
170  const QString &name = currentFileName();
171  const QString &prefixPath = TTK::String::lrcDirPrefix() + name;
172  const QString &nativePath = QFileInfo(currentFilePath()).absolutePath() + TTK_SEPARATOR + name;
173  const QStringList &formats = {LRC_FILE, KRC_FILE, QRC_FILE, TRC_FILE, YRC_FILE};
174 
175  QString path;
176  for(const QString &format : formats)
177  {
178  path = prefixPath + format;
179  if(QFile::exists(path))
180  {
181  break;
182  }
183 
184  // try to load same dir file
185  path = nativePath + format;
186  if(QFile::exists(path))
187  {
188  break;
189  }
190 
191  path.clear();
192  }
193 
195  //reset current song lrc index.
197 }
198 
199 void MusicApplication::importSongsByOutside(const QString &path, bool play)
200 {
201  if(path.isEmpty())
202  {
203  return;
204  }
205 
207 
208  if(play)
209  {
214  }
215 }
216 
217 QString MusicApplication::containsDownloadMedia(bool &contains) const
218 {
219  contains = false;
220  QString path;
222  {
223  const MusicPlayItem &item = m_playlist->currentItem();
224  if(item.isValid())
225  {
227  {
228  path = item.m_path;
229  }
230  else
231  {
232  const MusicSong currentSong(item.m_path);
233  path = QString("%1%2.%3").arg(G_SETTING_PTR->value(MusicSettingManager::DownloadMusicDirPath).toString(), currentFileName(), currentSong.format());
234  }
235 
236  contains = QFile::exists(path);
237  }
238  }
239  return path;
240 }
241 
243 {
245  {
246  const MusicPlayItem &item = m_playlist->currentItem();
247  const MusicSongItemList &items = m_songTreeWidget->items();
248  if(item.isValid() && item.m_playlistRow < items.count())
249  {
250  const MusicSongList &currentSongs = items[item.m_playlistRow].m_songs;
251  const int index = m_songTreeWidget->mapSongIndexByFilePath(item.m_playlistRow, item.m_path);
252  const MusicSongList &loveSongs = items[MUSIC_LOVEST_LIST].m_songs;
253  return index != -1 ? loveSongs.contains(currentSongs[index]) : false;
254  }
255  }
256  return false;
257 }
258 
260 {
262  {
263  const MusicSongItemList &items = m_songTreeWidget->items();
264  if(m_songTreeWidget->currentIndex() < items.count())
265  {
266  const MusicSongList &currentSongs = items[m_songTreeWidget->currentIndex()].m_songs;
267  const MusicSongList &loveSongs = items[MUSIC_LOVEST_LIST].m_songs;
268  return loveSongs.contains(currentSongs[index]);
269  }
270  }
271  return false;
272 }
273 
275 {
277 }
278 
280 {
281  return m_player->isPlaying();
282 }
283 
285 {
286  return m_player->duration();
287 }
288 
290 {
291  return m_playlist->playbackMode();
292 }
293 
295 {
297  //
298  m_quitWindowMode = true;
301  //Write configuration files
303 }
304 
306 {
308  m_ui->timeSliderWidget->setValue(position);
309 
310  if(m_playlist->isEmpty())
311  {
312  m_ui->playCurrentTime->setText(TTK_TIME_INIT);
313  }
314  else
315  {
316  m_ui->playCurrentTime->setText(TTKTime::formatDuration(position));
317  }
318  //Show the current play time
319  m_songTreeWidget->updateDurationLabel(m_ui->playCurrentTime->text(), m_ui->playTotalTime->text());
320 }
321 
323 {
324  //Show the current play total time
325  m_ui->timeSliderWidget->setRange(0, duration);
326  m_ui->playTotalTime->setText(TTK_SEPARATOR + TTKTime::formatDuration(duration));
327  //Loading the current song lrc
329  //Update song quality label
330  m_ui->qualityLabel->updateQuality();
331 }
332 
334 {
335  if(state == TTK::PlayState::Stopped)
336  {
337  const bool concise = G_SETTING_PTR->value(MusicSettingManager::WindowConciseMode).toBool();
338  m_ui->playButton->setStyleSheet(concise ? TTK::UI::TinyBtnPlay : TTK::UI::BtnPlay);
339  }
340 }
341 
343 {
344  QString name;
345  const MusicPlayItem &item = m_playlist->currentItem();
346  const int index = m_songTreeWidget->mapSongIndexByFilePath(item.m_playlistRow, item.m_path);
349 
350  if(index > TTK_NORMAL_LEVEL) //The list to end
351  {
352  name = currentFileName();
354  bool exist = false;
355  containsDownloadMedia(exist);
356  m_ui->downloadButton->setStyleSheet(exist ? TTK::UI::BtnDownload : TTK::UI::BtnUnDownload);
357  //
358  exist = containsLovestMedia();
359  m_ui->bestLoveButton->setStyleSheet(exist ? TTK::UI::BtnLove : TTK::UI::BtnUnLove);
360  //
361  m_songTreeWidget->selectRow(index);
362  }
363  else
364  {
365  const bool concise = G_SETTING_PTR->value(MusicSettingManager::WindowConciseMode).toBool();
366  m_ui->bestLoveButton->setStyleSheet(TTK::UI::BtnUnLove);
367  m_ui->downloadButton->setStyleSheet(TTK::UI::BtnUnDownload);
368  m_ui->playButton->setStyleSheet(concise ? TTK::UI::TinyBtnPlay : TTK::UI::BtnPlay);
369  m_player->stop();
371 
375  m_ui->timeSliderWidget->setCurrentPlayState(isPlaying());
376 
377  durationChanged(0);
378  positionChanged(0);
380  }
381 
382  m_ui->playedListButton->selectCurrentMedia();
385  m_ui->songTitleLabel->setText(name);
386  m_ui->moreFunctionButton->setCurrentSongName(name);
387  //Show the current play song information
390  //display current ArtTheme pic
392  G_BACKGROUND_PTR->setArtistName(currentFileName());
394 }
395 
397 {
398  if(m_playlist->isEmpty())
399  {
400  return; //The playlist is not performing space-time
401  }
402 
403  const bool concise = G_SETTING_PTR->value(MusicSettingManager::WindowConciseMode).toBool();
404  if(isPlaying())
405  {
406  m_ui->playButton->setStyleSheet(concise ? TTK::UI::TinyBtnPlay : TTK::UI::BtnPlay);
407  m_player->pause();
410  }
411  else
412  {
413  m_ui->playButton->setStyleSheet(concise ? TTK::UI::TinyBtnPause : TTK::UI::BtnPause);
414  m_player->play();
417  }
418 
422  m_ui->timeSliderWidget->setCurrentPlayState(isPlaying());
423 }
424 
426 {
427  if(!isPlaying())
428  {
429  return;
430  }
431 
433 }
434 
436 {
437  if(m_playlist->isEmpty())
438  {
439  return; //The playlist is not performing space-time
440  }
441 
442  m_ui->playedListButton->clearQueueState();
444 
445  m_player->stop();
447 }
448 
450 {
451  if(m_playlist->isEmpty())
452  {
453  return; //The playlist is not performing space-time
454  }
455 
457 
458  m_player->stop();
460 }
461 
463 {
465  m_ui->playModeButton->setPlaybackMode(TTK::PlayMode::Order);
466 }
467 
469 {
471  m_ui->playModeButton->setPlaybackMode(TTK::PlayMode::Random);
472 }
473 
475 {
477  m_ui->playModeButton->setPlaybackMode(TTK::PlayMode::ListLoop);
478 }
479 
481 {
483  m_ui->playModeButton->setPlaybackMode(TTK::PlayMode::OneLoop);
484 }
485 
487 {
489  m_ui->playModeButton->setPlaybackMode(TTK::PlayMode::Once);
490 }
491 
493 {
494  int currentVol = m_player->volume();
495  currentVol -= 15;
496  if(currentVol < 0)
497  {
498  currentVol = 0; //reset music volume
499  }
500  volumeChanged(currentVol);
501 }
502 
504 {
505  int currentVol = m_player->volume();
506  currentVol += 15;
507  if(currentVol > 100)
508  {
509  currentVol = 100; //reset music volume
510  }
511  volumeChanged(currentVol);
512 }
513 
515 {
517  const int volume = m_player->volume();
518 
521  m_ui->soundButton->setValue(volume);
522  G_SETTING_PTR->setValue(MusicSettingManager::Volume, volume);
523 }
524 
526 {
529  m_ui->soundButton->setValue(volume);
530  m_player->setVolume(volume);
531  G_SETTING_PTR->setValue(MusicSettingManager::Volume, volume);
532 }
533 
535 {
536  QMenu menu;
537  menu.setStyleSheet(TTK::UI::MenuStyle02);
538  menu.addAction(tr("Open Files"), m_songTreeWidget, SLOT(importSongsByFiles()));
539  menu.addAction(tr("Open Dir"), m_songTreeWidget, SLOT(importSongsByDir()));
540  menu.addAction(tr("Open Url"), this, SLOT(importSongsByUrl()));
541  menu.addSeparator();
542  menu.addAction(tr("Files Drag Drop"))->setEnabled(false);
543 
545  menu.exec(QCursor::pos());
546 }
547 
549 {
550  MusicInputDialog dialog;
551  dialog.setPlaceholderText(tr("Please enter the local or network playback address"));
552  if(!dialog.exec())
553  {
554  return;
555  }
556 
557  const QString &path = dialog.text();
558  if(path.isEmpty())
559  {
560  return;
561  }
562 
564 }
565 
567 {
569  if(files.isEmpty())
570  {
571  return;
572  }
573 
574  MusicPlaylistManager manager;
575  MusicSongItemList items;
576  manager.readSongItems(files, items);
578 }
579 
581 {
583  if(path.isEmpty())
584  {
585  return;
586  }
587 
588  const MusicSongItemList &items = m_songTreeWidget->items();
589  if(index < 0 || index >= items.count())
590  {
591  return;
592  }
593 
594  MusicPlaylistManager manager;
595  manager.writeSongItem(path, {items[index]});
596 
597  MusicToastLabel::popup(tr("Export current file success"));
598 }
599 
601 {
603  if(path.isEmpty())
604  {
605  return;
606  }
607 
608  MusicPlaylistManager manager;
609  manager.writeSongItem(path, m_songTreeWidget->items());
610 
611  MusicToastLabel::popup(tr("Export current file success"));
612 }
613 
615 {
616  const QString &path = m_songTreeWidget->mapFilePathBySongIndex(m_currentPlaylistRow, row);
618 }
619 
621 {
623  m_player->stop();
625 }
626 
628 {
629  m_player->stop();
630 
631  if(row != -1)
632  {
634  m_currentPlaylistRow = row;
636  }
637  else
638  {
639  m_playlist->clear();
640  m_currentPlaylistRow = row;
642  }
643 }
644 
646 {
647  m_player->stop();
648 
650  {
652  const MusicSongItemList &items = m_songTreeWidget->items();
653  const int index = m_songTreeWidget->currentIndex();
654  if(0 <= index && index < items.count())
655  {
656  m_ui->playedListButton->append(items[index].m_songs);
657  }
658  }
659 
663 }
664 
665 void MusicApplication::playIndexClicked(int row, int column)
666 {
668  {
670  const MusicSongItemList &items = m_songTreeWidget->items();
671  const int index = m_songTreeWidget->currentIndex();
672  if(0 <= index && index < items.count())
673  {
674  m_ui->playedListButton->append(items[index].m_songs);
675  }
676  }
677 
678  playIndexBy(row, column);
679 }
680 
682 {
683  //Drag the progress indicator to rewind or fast-forward through the current song
684  m_player->setPosition(time);
685  //Set lrc corrent to show
687 }
688 
690 {
692 }
693 
695 {
696  if(m_playlist->isEmpty())
697  {
698  return;
699  }
700 
701  const MusicPlayItem &item = m_playlist->currentItem();
702  const int index = m_songTreeWidget->mapSongIndexByFilePath(item.m_playlistRow, item.m_path);
704 }
705 
707 {
708  const MusicPlayItem &item = m_playlist->currentItem();
709  const int index = m_songTreeWidget->mapSongIndexByFilePath(item.m_playlistRow, item.m_path);
710  if(m_playlist->isEmpty() || index < 0)
711  {
712  return;
713  }
714 
715  bool contains = true;
716  if(state)
717  {
718  contains = containsLovestMedia();
719  if(contains)
720  {
721  m_songTreeWidget->songToLovestListAt(false, index);
723  }
724  else
725  {
726  m_songTreeWidget->songToLovestListAt(true, index);
728  }
729  }
730  else
731  {
732  m_songTreeWidget->songToLovestListAt(false, index);
734  }
735 
736  MusicToastLabel::popup(!contains ? tr("Add music to lovest list done") : tr("Remove music to lovest list done"));
737 }
738 
740 {
741  const bool v = m_bottomAreaWidget->setWindowConcise();
743 }
744 
746 {
748 }
749 
751 {
752  QMenu menu(this);
753  menu.setStyleSheet(TTK::UI::MenuStyle02);
754 
755  QMenu *addNewFilesMenu = menu.addMenu(tr("Add New Files"));
756  addNewFilesMenu->addAction(tr("Open Files"), m_songTreeWidget, SLOT(importSongsByFiles()));
757  addNewFilesMenu->addAction(tr("Open Dir"), m_songTreeWidget, SLOT(importSongsByDir()));
758  addNewFilesMenu->addAction(tr("Open Url"), this, SLOT(importSongsByUrl()));
759  TTK::Widget::adjustMenuPosition(addNewFilesMenu);
760 
761  QMenu *playbackModeMenu = menu.addMenu(tr("Playback Mode"));
762 
763  QList<QAction*> actions;
764  actions << playbackModeMenu->addAction(tr("Play Once"), this, SLOT(playOnce()));
765  actions << playbackModeMenu->addAction(tr("Single Cycle"), this, SLOT(playOneLoop()));
766  actions << playbackModeMenu->addAction(tr("Order Play"), this, SLOT(playOrder()));
767  actions << playbackModeMenu->addAction(tr("List Cycle"), this, SLOT(playlistLoop()));
768  actions << playbackModeMenu->addAction(tr("Random Play"), this, SLOT(playRandom()));
769 
770  int index = TTK_NORMAL_LEVEL;
771  switch(playMode())
772  {
773  case TTK::PlayMode::Once: index = 0; break;
774  case TTK::PlayMode::OneLoop: index = 1; break;
775  case TTK::PlayMode::Order: index = 2; break;
776  case TTK::PlayMode::ListLoop: index = 3; break;
777  case TTK::PlayMode::Random: index = 4; break;
778  default: break;
779  }
780 
781  if(index > TTK_NORMAL_LEVEL && index < actions.count())
782  {
783  actions[index]->setIcon(QIcon(":/contextMenu/btn_selected"));
784  }
785 
786  menu.addSeparator();
787 
788  QMenu *remoteControlMenu = menu.addMenu(tr("Remote Control"));
789  remoteControlMenu->addAction(tr("Square Remote"), m_topAreaWidget, SLOT(showSquareRemote()));
790  remoteControlMenu->addAction(tr("Rectangle Remote"), m_topAreaWidget, SLOT(showRectangleRemote()));
791  remoteControlMenu->addAction(tr("Simple Style Remote"), m_topAreaWidget, SLOT(showSimpleStyleRemote()));
792  remoteControlMenu->addAction(tr("Complex Style Remote"), m_topAreaWidget, SLOT(showComplexStyleRemote()));
793  remoteControlMenu->addAction(tr("Ripple Remote"), m_topAreaWidget, SLOT(showRippleRemote()));
794  remoteControlMenu->addAction(tr("Delete Remote"), m_topAreaWidget, SLOT(deleteCurrentRemote()));
795  TTK::Widget::adjustMenuPosition(remoteControlMenu);
796 
797  menu.addAction(QIcon(":/contextMenu/btn_equalizer"), tr("Equalizer"), m_applicationModule, SLOT(showEqualizerWidget()));
798  menu.addAction(tr("Sound Effect"), m_applicationModule, SLOT(showSoundEffectWidget()));
799  menu.addAction(tr("Timing Settings"), m_applicationModule, SLOT(showTimerWidget()));
800  menu.addAction(tr("Music Spectrum"), m_applicationModule, SLOT(showSpectrumWidget()));
801  menu.addSeparator();
802 
803  QAction *window = menu.addAction(tr("Window Top"), m_applicationModule, SLOT(setWindowToTop()));
804  window->setIcon(QIcon(m_applicationModule->windowToTop() ? ":/contextMenu/btn_selected" : QString()));
805  menu.addAction(tr("Reset Window"), m_applicationModule, SLOT(resetWindowGeometry()));
806 
807  QMenu *downloadMenu = menu.addMenu(tr("Download"));
809  actions.clear();
810  actions << downloadMenu->addAction(tr("Full Download"), MusicRightAreaWidget::instance(), SLOT(changeDownloadFulllyWidget()));
811  actions << downloadMenu->addAction(tr("Custom"), MusicRightAreaWidget::instance(), SLOT(changeDownloadCustumWidget()));
812 
813  if(index > TTK_NORMAL_LEVEL && index < actions.count())
814  {
815  actions[index]->setIcon(QIcon(":/contextMenu/btn_selected"));
816  }
817 
819  {
820  menu.addAction(QIcon(":/contextMenu/btn_update"), tr("New Version"), m_applicationModule, SLOT(showVersionWidget()));
821  }
822  menu.addAction(QIcon(":/contextMenu/btn_setting"), tr("Settings"), this, SLOT(showSettingWidget()));
823 
824  QMenu *informationMenu = menu.addMenu(QIcon(":/contextMenu/btn_about"), tr("About"));
825  informationMenu->addAction(QIcon(":/contextMenu/btn_bug_reoprt"), tr("Bug Report"), m_applicationModule, SLOT(showBugReportView()));
826  informationMenu->addAction(QIcon(":/contextMenu/btn_about"), tr("Version") + TTK_STR_CAT(TTK_VERSION_STR, TTK_VERSION_TIME_STR), m_applicationModule, SLOT(showAboutWidget()));
827  menu.addSeparator();
828 
829  menu.addAction(QIcon(":/contextMenu/btn_quit"), tr("Quit"), this, SLOT(quitWindow()));
830  menu.exec(QCursor::pos());
831 }
832 
834 {
835  //This attribute is effective immediately.
837  //
841 }
842 
843 void MusicApplication::removeLoveItemAt(const QString &path, bool current)
844 {
845  removeItemAt({path}, false, current, MUSIC_LOVEST_LIST);
846 }
847 
848 void MusicApplication::removeItemAt(const QStringList &path, bool remove, bool current, int playlistRow)
849 {
850  if(path.isEmpty())
851  {
852  return;
853  }
854 
855  if(current)
856  {
857  const MusicPlayItem &item = m_playlist->currentItem();
858  TTKIntList index;
859  for(const QString &p : qAsConst(path))
860  {
861  int idx = -1;
862  do
863  {
864  idx = m_playlist->find(item.m_playlistRow, p, idx + 1);
865  if(idx != -1)
866  {
867  index << idx;
868  }
869  } while(idx != -1);
870  }
871 
872  if(index.isEmpty())
873  {
874  return;
875  }
876  std::sort(index.begin(), index.end());
877 
878  bool contains = false;
879  int oldIndex = m_playlist->currentIndex();
881  if(index.count() == 1 && index.first() == oldIndex)
882  {
883  contains = true;
884  }
886  for(int i = index.count() - 1; i >= 0; --i)
887  {
888  m_ui->playedListButton->remove(index[i]);
889  if(i != 0 && !contains && oldIndex <= index[i] && oldIndex >= index[i - 1])
890  {
891  oldIndex -= i;
892  contains = true;
893  }
894  }
895 
896  if(!contains && m_playlist->currentIndex() > index[0])
897  {
898  oldIndex -= index.count();
899  }
900 
901  if(oldIndex == m_playlist->count())
902  {
903  --oldIndex;
904  }
905  m_playlist->setCurrentIndex(oldIndex);
906 
907  if(contains)
908  {
909  //The corresponding item is deleted from the playlist
910  m_player->stop();
912 
913  if(remove)
914  {
915  if(playlistRow != MUSIC_NETWORK_LIST)
916  {
918  }
919  else
920  {
923  }
924  }
925  }
926  }
927  else
928  {
929  for(const QString &p : qAsConst(path))
930  {
931  m_ui->playedListButton->remove(playlistRow, p);
932  }
933  }
934 }
935 
937 {
938  const QString &fileName = currentFileName();
939  QFile::remove(TTK::String::lrcDirPrefix() + fileName + LRC_FILE);
941 }
942 
944 {
945  const int pos = m_player->position();
946  if(pos != -1)
947  {
949  }
950 }
951 
953 {
954  if(isPlaying())
955  {
956  m_player->setPosition(pos);
957  }
958 }
959 
961 {
962  if(m_playlist->isEmpty() || index < 0 || index >= m_playlist->count())
963  {
964  return;
965  }
966 
968 }
969 
970 void MusicApplication::currentPlaylist(QStringList &list)
971 {
973 }
974 
975 void MusicApplication::resizeEvent(QResizeEvent *event)
976 {
977  if(m_ui->background->isRunning())
978  {
979  event->ignore();
980  return;
981  }
982 
983  if(!m_quitWindowMode)
984  {
989  TTKAbstractMoveResizeWidget::resizeEvent(event);
990  }
991  else
992  {
993  setMinimumSize(0, 0);
994  m_ui->background->stop();
995  event->ignore();
996  }
997 }
998 
999 void MusicApplication::closeEvent(QCloseEvent *event)
1000 {
1001  TTKAbstractMoveResizeWidget::closeEvent(event);
1002  event->ignore();
1003 
1005  {
1006  hide();
1007  m_bottomAreaWidget->showMessage(tr("Prompt"), tr("TTKMusicPlayer will run in the background"));
1008  }
1009  else
1010  {
1011  quitWindow();
1012  }
1013 }
1014 
1015 void MusicApplication::contextMenuEvent(QContextMenuEvent *event)
1016 {
1017  const int h = event->y();
1018  if(h < m_ui->topWidget->height() || h > height() - m_ui->bottomWidget->height())
1019  {
1020  TTKAbstractMoveResizeWidget::contextMenuEvent(event);
1021  createRightMenu();
1022  }
1023  else
1024  {
1025  event->accept();
1026  }
1027 }
1028 
1030 {
1031  TTKAbstractMoveResizeWidget::enterEvent(event);
1033 }
1034 
1035 void MusicApplication::leaveEvent(QEvent *event)
1036 {
1037  TTKAbstractMoveResizeWidget::leaveEvent(event);
1039 }
1040 
1041 void MusicApplication::mouseMoveEvent(QMouseEvent *event)
1042 {
1044 
1045  // ignore if the window mode is concise
1047  {
1048  return;
1049  }
1050 
1051  if(m_ui->background->isRunning())
1052  {
1053  setFixedSize(G_SETTING_PTR->value(MusicSettingManager::WidgetSize).toSize());
1054  }
1055  else
1056  {
1057  const QSize &size = G_SETTING_PTR->value(MusicSettingManager::ScreenSize).toSize();
1058  setMinimumSize(WINDOW_WIDTH_MIN, WINDOW_HEIGHT_MIN);
1059  setMaximumSize(size.width(), size.height());
1060  }
1061 }
1062 
1063 void MusicApplication::mouseReleaseEvent(QMouseEvent *event)
1064 {
1067 }
1068 
1070 {
1071  if(!m_ui->background->isRunning() && QtPositionY(event) <= m_ui->topWidget->height() && !G_SETTING_PTR->value(MusicSettingManager::WindowConciseMode).toBool())
1072  {
1073  TTKAbstractMoveResizeWidget::mouseDoubleClickEvent(event);
1074  if(event->buttons() == Qt::LeftButton)
1075  {
1076  isMaximized() ? showNormal() : showMaximized();
1077  }
1078  }
1079  else
1080  {
1081  event->ignore();
1082  }
1083 }
1084 
1085 bool MusicApplication::eventFilter(QObject *object, QEvent *event)
1086 {
1087  if(object == m_ui->centerWidget && (QEvent::ContextMenu == event->type() || QEvent::MouseButtonPress == event->type()))
1088  {
1089  return true;
1090  }
1091  return TTKAbstractMoveResizeWidget::eventFilter(object, event);
1092 }
1093 
1095 {
1099 }
1100 
1102 {
1103  int value = TTK_NORMAL_LEVEL;
1104  //Path configuration song
1105  MusicSongItemList items;
1106  {
1107  MusicTKPLConfigManager manager;
1108  if(manager.fromFile(PLAYLIST_PATH_FULL))
1109  {
1110  manager.readBuffer(items);
1111  }
1112  }
1113 
1114  MusicConfigManager manager;
1115  if(!manager.fromFile(COFIG_PATH_FULL))
1116  {
1117  TTK_ERROR_STREAM("Load config file error:" << COFIG_PATH_FULL);
1118  return;
1119  }
1120 
1121  manager.readBuffer();
1122 
1124  const bool success = m_songTreeWidget->addSongItemList(items);
1125 
1127  {
1128  case TTK::PlayMode::Order: playOrder();break;
1129  case TTK::PlayMode::Random: playRandom();break;
1130  case TTK::PlayMode::ListLoop: playlistLoop();break;
1131  case TTK::PlayMode::OneLoop: playOneLoop();break;
1132  case TTK::PlayMode::Once: playOnce();break;
1133  default:break;
1134  }
1135 
1136  value = G_SETTING_PTR->value(MusicSettingManager::RemoteWidgetMode).toInt();
1137  if(value != 0)
1138  {
1140  }
1141 
1142  //The size of the volume of the allocation of songs
1144 
1145  //Configure playback mode
1146  m_ui->enhancedButton->setEnhancedSongConfig(G_SETTING_PTR->value(MusicSettingManager::EnhancedMusicIndex).toInt());
1148  if(G_SETTING_PTR->value(MusicSettingManager::EqualizerEnable).toInt() == 1)
1149  {
1151  }
1152 
1153  //global hotkey
1155  {
1156  QStringList hotkeys = G_SETTING_PTR->value(MusicSettingManager::HotkeyValue).toString().split(TTK_SPLITER);
1157  if(hotkeys.count() != G_HOTKEY_PTR->count())
1158  {
1159  hotkeys = G_HOTKEY_PTR->defaultKeys();
1160  }
1161 
1162  for(int i = 0; i < hotkeys.count(); ++i)
1163  {
1164  G_HOTKEY_PTR->setHotKey(i, hotkeys[i]);
1165  }
1166  //
1167  G_HOTKEY_PTR->setEnabled(true);
1168  }
1169 
1170  //musicSetting
1172  //Just always set fade false, because it is not finished yet.
1174 #ifdef Q_OS_UNIX
1175  //Disable window quit mode on unix
1177 #endif
1178  //Set interior lrc mode always on
1180 
1181  //Set the desktop lrc should be shown
1184 
1185  //Set the current background color and alpha value
1187 
1188  //Configuration from next time also stopped at the last record.
1189  const QStringList &lastPlayIndex = G_SETTING_PTR->value(MusicSettingManager::LastPlayIndex).toStringList();
1190  //add new music file to playlist
1191  value = lastPlayIndex[1].toInt();
1192  m_playlist->add(value, m_songTreeWidget->songsFilePath(value));
1193  if(TTK_NORMAL_LEVEL < value && value < items.count())
1194  {
1195  m_ui->playedListButton->append(items[value].m_songs);
1196  }
1197 
1198  applyParameter();
1199 
1200  if(success && lastPlayIndex[0] == "1")
1201  {
1202  TTK_SIGNLE_SHOT(m_songTreeWidget, updateCurrentIndex, TTK_SLOT);
1203  const int index = lastPlayIndex[2].toInt();
1205  m_playlist->blockSignals(true);
1207  m_playlist->blockSignals(false);
1208  m_ui->playedListButton->selectCurrentMedia();
1209  }
1210 
1211  //Configure automatic playback
1212  if(G_SETTING_PTR->value(MusicSettingManager::StartUpPlayMode).toInt() == 1)
1213  {
1215  }
1216 
1220 
1221  //Set the lrc color the user set
1223 
1224  //init or reset the window
1225  value = G_SETTING_PTR->value(MusicSettingManager::ShowDesktopLrc).toInt();
1228 
1229  //Reset geometry
1230  setGeometry(manager.readWindowGeometry());
1231 
1232  //Reset window concise
1234  {
1237  }
1238 
1239  //Update check on
1241  {
1243  }
1244 }
1245 
1247 {
1248  MusicConfigManager manager;
1249  if(!manager.load(COFIG_PATH_FULL))
1250  {
1251  TTK_ERROR_STREAM("Load config file error:" << COFIG_PATH_FULL);
1252  return;
1253  }
1254 
1256 
1260  G_SETTING_PTR->setValue(MusicSettingManager::Volume, m_ui->soundButton->value());
1261 
1262  QStringList lastPlayIndex = G_SETTING_PTR->value(MusicSettingManager::LastPlayIndex).toStringList();
1263  if(lastPlayIndex.isEmpty())
1264  {
1265  lastPlayIndex << "1" << "-1" << "-1";
1266  }
1267  else
1268  {
1269  const MusicPlayItem &item = m_playlist->currentItem();
1270  lastPlayIndex[1] = QString::number(item.m_playlistRow);
1271  lastPlayIndex[2] = QString::number(m_songTreeWidget->mapSongIndexByFilePath(item.m_playlistRow, item.m_path));
1272  }
1273 
1274  G_SETTING_PTR->setValue(MusicSettingManager::LastPlayIndex, lastPlayIndex);
1280  manager.writeBuffer();
1281 
1282  {
1283  MusicTKPLConfigManager manager;
1284  if(!manager.load(PLAYLIST_PATH_FULL))
1285  {
1286  return;
1287  }
1288 
1289  manager.writeBuffer(m_songTreeWidget->items());
1290  }
1291 }
static MusicRightAreaWidget * instance()
void setupUi(Ui::MusicApplication *ui)
MusicBottomAreaWidget * m_bottomAreaWidget
#define QtEnterEvent
Event enter.
Definition: ttkqtcompat.h:178
int backgroundTransparent() const noexcept
#define TTKStaticCast(x, y)
Definition: ttkglobal.h:231
The class of the music play item.
Definition: musicplaylist.h:27
The class of the songs container widget.
bool systemTrayIsVisible() noexcept
The class of the app top area widget.
The class of the app object module.
void setEqualizerConfig()
void updateDurationLabel(const QString &current, const QString &total) const
#define G_DISPATCH_PTR
static MusicApplication * instance()
PlayState
Definition: musicobject.h:183
void setShuffleMode(bool shuffle) noexcept
QRect readWindowGeometry() const
#define MUSIC_SEARCH_PAGE
#define PLAYLIST_PATH_FULL
Definition: musicobject.h:153
#define TTK_LOW_LEVEL
Definition: ttkglobal.h:332
void addSongToLovestList(bool state=true)
static QString supportPlaylistInputFormats() noexcept
MusicApplication(QWidget *parent=nullptr)
#define G_BACKGROUND_PTR
#define G_HOTKEY_PTR
void setPlaySongChanged(int index)
MusicPlayItem currentItem() const noexcept
void songToLovestListAt(bool state, int row)
bool fromFile(const QString &name)
virtual void leaveEvent(QEvent *event) overridefinal
QString m_path
Definition: musicplaylist.h:30
virtual void mouseMoveEvent(QMouseEvent *event) overridefinal
void positionChanged(qint64 position)
bool isEmpty() const noexcept
TTK::PlayMode playbackMode() const noexcept
#define MUSIC_NONE_LIST
void setObjectsTracking(const QWidgetList &objects)
The class of the ttk moving resize widget base.
QStringList songsFilePath(int index) const
#define TTK_SPLITER
Definition: ttkglobal.h:275
voidpf void uLong size
Definition: ioapi.h:136
void playIndexBy(int row)
static constexpr const char * BtnUnDownload
The class of the app main widget.
void setCurrentPlayState(bool state) const
void playSortBy(int row)
QString containsDownloadMedia(bool &contains) const
virtual void mouseReleaseEvent(QMouseEvent *event) overridefinal
QStringList songsFileName(int index) const
MusicPlayer * m_player
void setLabelText(const QString &name) const
bool addSongItemList(const MusicSongItemList &items)
void setPosition(qint64 position)
Definition: musicplayer.cpp:59
virtual void mouseMoveEvent(QMouseEvent *event) override
The class of the playlist manager.
The class of the xml config manager.
void volumeChanged(int volume)
int find(const MusicPlayItem &item) const
static constexpr const char * BtnPlay
The class of the music player.
Definition: musicplayer.h:46
void removeItemAt(const QStringList &path, bool remove, bool current, int playlistRow)
virtual bool eventFilter(QObject *object, QEvent *event) override
Ui::MusicApplication * m_ui
void setInteriorLrcVisible(bool status) const
TTK_MODULE_EXPORT QString generateNetworkSongMetaPath(const QString &path)
int mapSongIndexByFilePath(int playlistRow, const QString &path) const
qint64 duration() const
Definition: musicplayer.cpp:49
void add(int playlistRow, const QString &content)
virtual void mouseDoubleClickEvent(QMouseEvent *event) overridefinal
virtual bool eventFilter(QObject *object, QEvent *event) overridefinal
TTK::PlayMode playMode() const noexcept
qint64 position() const
Definition: musicplayer.cpp:54
MusicTopAreaWidget * m_topAreaWidget
void setVolume(int volume)
Definition: musicplayer.cpp:69
static void popup(const QString &text)
TTK_MODULE_EXPORT void enableBreakPoint(bool enable) noexcept
virtual bool readBuffer(MusicSongItemList &items) overridefinal
void playedIndexBy(int row)
#define TTK_TIME_INIT
Definition: ttkglobal.h:299
bool isMuted() const noexcept
Definition: musicplayer.cpp:75
TTK_MODULE_EXPORT QString getSaveFileName(QWidget *parent, const QString &filter="Image Files (*.png *.bmp *.jpg)")
static constexpr int PLAY_PREVIOUS_LEVEL
Definition: musicplaylist.h:58
static constexpr const char * TinyBtnPause
MusicRightAreaWidget * m_rightAreaWidget
void loadCurrentSongLrc(const QString &name, const QString &path) const
void writeSongItem(const QString &path, const MusicSongItemList &item)
TTK_MODULE_EXPORT QString generateNetworkSongPath(const QString &path)
const MusicSongItemList & items() const noexcept
QList< int > TTKIntList
Definition: ttkqtglobal.h:200
#define qAsConst
Definition: ttkqtglobal.h:57
const char * name
Definition: http_parser.c:458
virtual void enterEvent(QtEnterEvent *event) overridefinal
MusicSongsContainerWidget * m_songTreeWidget
void setLabelText(const QString &name) const
void setDestopLrcVisible(bool status) const
static constexpr const char * BtnDownload
void setPlaceholderText(const QString &text)
#define TTK_SIGNLE_SHOT(...)
Definition: ttkqtglobal.h:189
PlayMode
Definition: musicobject.h:190
#define TRC_FILE
Definition: musicobject.h:79
void setupUi(Ui::MusicApplication *ui)
bool containsLovestMedia() const
MusicPlaylist * m_playlist
void durationChanged(qint64 duration)
void setVolumeValue(int value) const
#define TTK_NORMAL_LEVEL
Definition: ttkglobal.h:333
void currentPlaylist(QStringList &list)
void importSongsByPath(const QStringList &files, int playlistRow)
#define TTK_SEPARATOR
Definition: ttkglobal.h:269
TTK_MODULE_EXPORT QString lrcDirPrefix()
void playIndexClicked(int row, int column)
void updateCurrentTime(qint64 pos)
#define QtPositionY(p)
Definition: ttkqtcompat.h:160
virtual void mouseReleaseEvent(QMouseEvent *event) override
#define KRC_FILE
Definition: musicobject.h:77
static QString supportPlaylistOutputFormats() noexcept
QString currentFilePath() const
#define TTK_VERSION_TIME_STR
Definition: ttkversion.h:180
#define YRC_FILE
Definition: musicobject.h:80
MusicLeftAreaWidget * m_leftAreaWidget
bool isPlaying() const noexcept
Definition: musicplayer.cpp:34
#define TTK_SLOT
Definition: ttkqtglobal.h:177
void importSongsByUrl(const QString &path, int playlistRow)
static constexpr int PLAY_NEXT_LEVEL
Definition: musicplaylist.h:57
#define TTK_VERSION_STR
Definition: ttkversion.h:179
void setDestopLrcVisible(bool visible) const
void setPlaybackMode(TTK::PlayMode mode) noexcept
void importSongsByOutside(const QString &path, bool play)
void setCurrentIndex(int index)
The class of the app left area widget.
QString format() const noexcept
Definition: musicsong.h:97
int count() const noexcept
The class of the app bottom area widget.
#define QRC_FILE
Definition: musicobject.h:78
static const QString MenuStyle02
void setCurrentPlayState(bool state) const
void setCurrentPlayState(bool state) const
static constexpr const char * TinyBtnPlay
#define COFIG_PATH_FULL
Definition: musicobject.h:152
bool backgroundTransparentEnabled() const
bool windowToTop() const noexcept
bool checkMusicListCurrentIndex() const
void setVolumeValue(int value) const
The class of the tkpl config manager.
void exportSongsItem(int index)
Enhance
Definition: musicplayer.h:33
#define MUSIC_NETWORK_LIST
bool load(const QString &name)
#define MUSIC_LOVEST_LIST
virtual void contextMenuEvent(QContextMenuEvent *event) overridefinal
int currentIndex() const noexcept
bool isPlaying() const
virtual void closeEvent(QCloseEvent *event) overridefinal
#define WINDOW_WIDTH_MIN
Definition: musicobject.h:172
static constexpr const char * BtnLove
void readSongItems(const QStringList &paths, MusicSongItemList &items)
void playTimePosition(int time)
#define TTK_STR_CAT(...)
Definition: ttkglobal.h:240
static MusicApplication * m_instance
void setupUi(Ui::MusicApplication *ui)
void enhancedSongChanged(int type)
void checkMetaDataValid(bool mode) const
TTK_MODULE_EXPORT QStringList getOpenFileNames(QWidget *parent, const QString &filter="Image Files (*.png *.bmp *.jpg)")
static constexpr const char * BtnPause
int volume() const
Definition: musicplayer.cpp:64
The class of the music song info.
Definition: musicsong.h:28
bool isValid() const noexcept
Definition: musicplaylist.h:45
void removeLoveItemAt(const QString &path, bool current)
virtual void resizeEvent(QResizeEvent *event) overridefinal
void appendSongItemList(const MusicSongItemList &items)
void setBackgroundAnimation(bool state)
#define const
Definition: zconf.h:233
void playerStateChanged(TTK::PlayState state)
bool systemCloseConfig() noexcept
void showMessage(const QString &title, const QString &text)
The class of the music play list.
Definition: musicplaylist.h:63
QString backgroundPath() const noexcept
The class of the input widget.
#define MUSIC_NORMAL_LIST
#define LRC_FILE
Definition: musicobject.h:76
void setupUi(Ui::MusicApplication *ui)
TTK_MODULE_EXPORT void adjustMenuPosition(QMenu *menu)
void setSongLoveState(bool state)
#define TTK_ERROR_STREAM(msg)
Definition: ttklogger.h:76
qint64 duration() const
The class of the app right area widget.
void setEnhance(TTK::Enhance type)
Definition: musicplayer.cpp:86
QString mapFilePathBySongIndex(int playlistRow, int index) const
void remoteTypeChanged(QAction *type)
void setMuted(bool muted)
Definition: musicplayer.cpp:80
void backgroundAnimationChanged(bool state)
void updateCurrentLrc(qint64 current, qint64 total, bool playState) const
void findTimePosition(qint64 time) const
TTK::Enhance enhance() const noexcept
QPoint readShowDesktopLrcGeometry() const
state
Definition: http_parser.c:279
#define WINDOW_HEIGHT_MIN
Definition: musicobject.h:173
QString text() const
virtual bool writeBuffer(const MusicSongItemList &items) overridefinal
static constexpr const char * BtnUnLove
#define G_SETTING_PTR
static qint64 formatDuration(const QString &time) noexcept
Definition: ttktime.cpp:123
MusicApplicationModule * m_applicationModule
QString currentFileName() const