MythTV  master
lyricsview.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <cstdlib>
3 #include <unistd.h>
4 
5 // qt
6 #include <QKeyEvent>
7 #include <QRegExp>
8 #include <QThread>
9 #include <QDomDocument>
10 
11 // myth
12 #include <mythcontext.h>
13 #include <mythversion.h>
14 #include <mythdbcon.h>
15 #include <mythmainwindow.h>
16 #include <mythuibuttonlist.h>
17 #include <mythuicheckbox.h>
18 #include <mythuitext.h>
19 #include <mythuibutton.h>
20 #include <mythuitextedit.h>
21 #include <mythuiutils.h>
22 #include <mythdialogbox.h>
23 #include <mythuistatetype.h>
24 #include <mythuiprogressbar.h>
25 #include <mythdownloadmanager.h>
26 #include <mythuihelper.h>
27 #include <mythdirs.h>
28 #include <audiooutput.h>
29 
30 
31 // mythmusic
32 #include "musiccommon.h"
33 #include "lyricsview.h"
34 #include "musicplayer.h"
35 
37 // LyricsView
38 
40  : MusicCommon(parent, parentScreen, "lyricsview")
41 {
43 
45 }
46 
48 {
49  if (m_lyricData)
50  {
51  m_lyricData->disconnect();
52  m_lyricData = nullptr;
53  }
54 
56 }
57 
59 {
60  QString windowName = gPlayer->getPlayMode() == MusicPlayer::PLAYMODE_RADIO ? "streamlyricsview" : "trackslyricsview";
61 
62  // Load the theme for this screen
63  bool err = LoadWindowFromXML("music-ui.xml", windowName, this);
64 
65  if (!err)
66  return false;
67 
68  // find common widgets available on any view
69  err = CreateCommon();
70 
71  // find widgets specific to this view
72  UIUtilE::Assign(this, m_lyricsList, "lyrics_list", &err);
73  UIUtilW::Assign(this, m_statusText, "status_text");
74  UIUtilW::Assign(this, m_loadingState, "loading_state");
75 
76  // for streams
77  UIUtilW::Assign(this, m_bufferStatus, "bufferstatus", &err);
78  UIUtilW::Assign(this, m_bufferProgress, "bufferprogress", &err);
79 
80  if (err)
81  {
82  LOG(VB_GENERAL, LOG_ERR, QString("Cannot load screen '%1'").arg(windowName));
83  return false;
84  }
85 
86  connect(m_lyricsList, SIGNAL(itemClicked(MythUIButtonListItem*)), this, SLOT(setLyricTime()));
87 
89 
90  findLyrics();
91 
92  return true;
93 }
94 
95 void LyricsView::customEvent(QEvent *event)
96 {
97  bool handled = false;
98 
99  if ((event->type() == MusicPlayerEvent::TrackChangeEvent) ||
101  {
102  findLyrics();
103  }
104  else if (event->type() == OutputEvent::Info)
105  {
106  if (m_autoScroll)
107  {
108  auto *oe = dynamic_cast<OutputEvent *>(event);
110 
111  if (!oe || !curMeta)
112  return;
113 
114  int rs = 0;
115 
117  {
118  rs = gPlayer->getCurrentTrackTime() * 1000;
119  }
120  else
121  rs = oe->elapsedSeconds() * 1000;
122 
123  int pos = 0;
124  for (int x = 0; x < m_lyricsList->GetCount(); x++)
125  {
127  auto *lyric = item->GetData().value<LyricsLine*>();
128  if (lyric)
129  {
130  if (lyric->m_time > 1000 && rs >= lyric->m_time)
131  pos = x;
132  }
133  }
134 
136  }
137  }
138  else if (event->type() == DialogCompletionEvent::kEventType)
139  {
140  auto dce = dynamic_cast<DialogCompletionEvent*>(event);
141 
142  // make sure the user didn't ESCAPE out of the menu
143  if ((dce == nullptr) || (dce->GetResult() < 0))
144  return;
145 
146  QString resultid = dce->GetId();
147  QString resulttext = dce->GetResultText();
148  if (resultid == "actionmenu")
149  {
150  if (resulttext == tr("Save Lyrics"))
151  {
152  saveLyrics();
153  }
154  else if ((resulttext == tr("Edit Lyrics")) ||
155  (resulttext == tr("Add Lyrics")))
156  {
157  editLyrics();
158  }
159  else if (resulttext == tr("Auto Scroll Lyrics"))
160  {
161  m_autoScroll = true;
162  }
163 
164  handled = true;
165  }
166  else if (resultid == "findlyricsmenu")
167  {
168  if (dce->GetResult() >= 0)
169  {
170  QString grabber = dce->GetData().toString();
171  m_lyricData->clear();
172  findLyrics(grabber);
173  }
174 
175  handled = true;
176  }
177  }
178  else if (event->type() == DecoderHandlerEvent::OperationStart)
179  {
180  auto *dhe = dynamic_cast<DecoderHandlerEvent*>(event);
181  if (!dhe)
182  return;
183  if (dhe->getMessage() && m_bufferStatus)
184  {
185  m_bufferStatus->SetText(*dhe->getMessage());
186  }
187  }
188  else if (event->type() == DecoderHandlerEvent::BufferStatus)
189  {
190  auto *dhe = dynamic_cast<DecoderHandlerEvent*>(event);
191  if (!dhe)
192  return;
193 
194  int available = 0;
195  int maxSize = 0;
196  dhe->getBufferStatus(&available, &maxSize);
197 
198  if (m_bufferStatus)
199  {
200  QString status = QString("%1%").arg((int)(100.0 / ((double)maxSize / (double)available)));
201  m_bufferStatus->SetText(status);
202  }
203 
204  if (m_bufferProgress)
205  {
206  m_bufferProgress->SetTotal(maxSize);
207  m_bufferProgress->SetUsed(available);
208  }
209  }
210  else if (event->type() == DecoderHandlerEvent::OperationStop)
211  {
212  if (m_bufferStatus)
214  }
215 
216  if (!handled)
218 }
219 
221 {
222  QString label = tr("Actions");
223 
224  auto *menu = new MythMenu(label, this, "actionmenu");
225 
226  if (m_lyricData)
227  {
228  menu->AddItem(tr("Find Lyrics"), nullptr, createFindLyricsMenu());
229 
231  {
232  if (m_lyricData->lyrics()->count())
233  menu->AddItem(tr("Edit Lyrics"), nullptr, nullptr);
234  else
235  menu->AddItem(tr("Add Lyrics"), nullptr, nullptr);
236 
237  if (m_lyricData->lyrics()->count() && m_lyricData->changed())
238  menu->AddItem(tr("Save Lyrics"), nullptr, nullptr);
239  }
240 
241  if (!m_autoScroll)
242  menu->AddItem(tr("Auto Scroll Lyrics"), nullptr, nullptr);
243  }
244 
245  menu->AddItem(tr("Other Options"), nullptr, createMainMenu());
246 
247  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
248 
249  auto *menuPopup = new MythDialogBox(menu, popupStack, "actionmenu");
250 
251  if (menuPopup->Create())
252  popupStack->AddScreen(menuPopup);
253  else
254  delete menuPopup;
255 }
256 
258 {
259  QString label = tr("Find Lyrics");
260 
261  auto *menu = new MythMenu(label, this, "findlyricsmenu");
262  menu->AddItem(tr("Search All Grabbers"), qVariantFromValue(QString("ALL")));
263 
264  QStringList strList("MUSIC_LYRICS_GETGRABBERS");
265  if (gCoreContext->SendReceiveStringList(strList))
266  {
267  for (int x = 1; x < strList.count(); x++)
268  menu->AddItem(tr("Search %1").arg(strList.at(x)), qVariantFromValue(strList.at(x)));
269  }
270 
271  return menu;
272 }
273 
274 bool LyricsView::keyPressEvent(QKeyEvent *event)
275 {
276  bool handled = false;
277  QStringList actions;
278 
279  if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
280  {
281  // if the lyrics list widget has focus and the UP/DOWN or PAGEUP/PAGEDOWN keys
282  // are pressed turn off auto scroll
283  if (GetFocusWidget() == m_lyricsList)
284  {
285  GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
286  if (actions.contains("UP") || actions.contains("DOWN") ||
287  actions.contains("PAGEUP") || actions.contains("PAGEDOWN"))
288  m_autoScroll = false;
289  }
290 
291  return true;
292  }
293 
294  handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions);
295 
296  for (int i = 0; i < actions.size() && !handled; i++)
297  {
298  QString action = actions[i];
299  handled = true;
300 
301  if (action == "EDIT")
302  {
303  if (GetFocusWidget() == m_lyricsList)
304  {
306  editLyrics();
307  }
308  else
309  {
310  // pass the EDIT action on for normal tracks if not on the lyrics list
312  handled = false;
313  }
314  }
315  else if (GetFocusWidget() == m_lyricsList && (action == "MARK" || action == "SELECT"))
316  {
317  setLyricTime();
318  }
319  else
320  handled = false;
321  }
322 
323  if (!handled && MusicCommon::keyPressEvent(event))
324  handled = true;
325 
326  return handled;
327 }
328 
330 {
331  // change the time of the next lyric to the playback time
333  {
335 
337  if (item)
338  {
339  auto *lyric = item->GetData().value<LyricsLine*>();
340  if (lyric)
341  {
342  lyric->m_time = gPlayer->getOutput()->GetAudiotime() - 750;
343  m_lyricData->setChanged(true);
345  m_autoScroll = false;
346  }
347  }
348  }
349 }
350 
351 void LyricsView::findLyrics(const QString &grabber)
352 {
353  if (m_lyricData)
354  {
355  if (m_lyricData->changed())
356  m_lyricData->save();
357 
358  m_lyricData->disconnect();
359  m_lyricData = nullptr;
360  }
361 
362  MusicMetadata *mdata = nullptr;
363 
365  {
366  if (gPlayer->getPlayedTracksList().count())
367  mdata = gPlayer->getPlayedTracksList().last();
368  }
369  else
370  mdata = gPlayer->getCurrentMetadata();
371 
372  if (!mdata)
373  return;
374 
375  m_lyricsList->Reset();
376 
377  if (m_loadingState)
379 
380  m_lyricData = mdata->getLyricsData();
381 
382  connect(m_lyricData, SIGNAL(statusChanged(LyricsData::Status, const QString&)),
383  this, SLOT(lyricStatusChanged(LyricsData::Status, const QString&)));
384 
385  m_lyricData->findLyrics(grabber);
386 }
387 
388 void LyricsView::lyricStatusChanged(LyricsData::Status status, const QString &message)
389 {
390  switch (status)
391  {
393  {
394  showMessage(message);
395  break;
396  }
397 
399  {
400  if (m_loadingState)
402 
403  showMessage(message);
404  break;
405  }
406 
408  {
409  showLyrics();
410  break;
411  }
412 
413  default:
414  if (m_loadingState)
416 
417  showMessage("");
418  break;
419  }
420 }
421 
422 void LyricsView::showMessage(const QString &message)
423 {
424  if (m_statusText)
425  {
426  if (message.isEmpty())
427  {
428  m_statusText->Reset();
429  m_statusText->Hide();
430  }
431  else
432  {
433  m_statusText->SetText(message);
434  m_statusText->Show();
435  }
436  }
437 }
438 
440 {
441  if (m_loadingState)
443 
444  showMessage("");
445 
446  m_lyricsList->Reset();
447 
448  QString syncronized = m_lyricData->syncronized() ? tr("Syncronized") : tr("Unsyncronized");
449  new MythUIButtonListItem(m_lyricsList, tr("** Lyrics from %1 (%2) **").arg(m_lyricData->grabber()).arg(syncronized));
450 
451  QMap<int, LyricsLine*>::iterator i = m_lyricData->lyrics()->begin();
452  while (i != m_lyricData->lyrics()->end())
453  {
454  LyricsLine *line = (*i);
455  if (line)
456  new MythUIButtonListItem(m_lyricsList, line->m_lyric, qVariantFromValue(line));
457  ++i;
458  }
459 
460  m_autoScroll = true;
461 }
462 
464 {
465  if (m_lyricData)
466  m_lyricData->save();
467 }
468 
470 {
472 
473  auto *editDialog = new EditLyricsDialog(mainStack, m_lyricData);
474 
475  if (!editDialog->Create())
476  {
477  delete editDialog;
478  return;
479  }
480  connect(editDialog, SIGNAL(haveResult(bool)), this, SLOT(editFinished(bool)));
481  mainStack->AddScreen(editDialog);
482 }
483 
484 void LyricsView::editFinished(bool result)
485 {
486  if (result)
487  showLyrics();
488 }
489 
491 // EditLyricsDialog
492 
494  MythScreenStack *parent, LyricsData *sourceData) :
495  MythScreenType(parent, "EditLyricsDialog"),
496  m_sourceData(sourceData)
497 {
498 }
499 
501 {
502  // Load the theme for this screen
503  bool foundtheme = LoadWindowFromXML("music-ui.xml", "editlyrics", this);
504  if (!foundtheme)
505  return false;
506 
507  bool err = false;
508  UIUtilE::Assign(this, m_grabberEdit, "grabberedit", &err);
509  UIUtilE::Assign(this, m_syncronizedCheck, "syncronizedcheck", &err);
510  UIUtilE::Assign(this, m_titleEdit, "titleedit", &err);
511  UIUtilE::Assign(this, m_artistEdit, "artistedit", &err);
512  UIUtilE::Assign(this, m_albumEdit, "albumedit", &err);
513  UIUtilE::Assign(this, m_lyricsEdit, "lyricsedit", &err);
514  UIUtilE::Assign(this, m_okButton, "okbutton", &err);
515  UIUtilE::Assign(this, m_cancelButton, "cancelbutton", &err);
516 
517  if (err)
518  {
519  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'editlyrics'");
520  return false;
521  }
522 
523  connect(m_okButton, SIGNAL(Clicked()), this, SLOT(okPressed()));
524  connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(cancelPressed()));
525  connect(m_syncronizedCheck, SIGNAL(toggled(bool)), this, SLOT(syncronizedChanged(bool)));
526 
532 
533  loadLyrics();
534 
535  BuildFocusList();
536 
537  return true;
538 }
539 
540 bool EditLyricsDialog::keyPressEvent(QKeyEvent *event)
541 {
542  bool handled = false;
543  QStringList actions;
544 
545  if (GetFocusWidget()->keyPressEvent(event))
546  return true;
547 
548  handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions);
549 
550  for (int i = 0; i < actions.size() && !handled; i++)
551  {
552  QString action = actions[i];
553 
554  if (action == "ESCAPE" && somethingChanged())
555  {
556  cancelPressed();
557  return true;
558  }
559  }
560 
561  return MythScreenType::keyPressEvent(event);
562 }
563 
565 {
566  QString lyrics;
567  QMap<int, LyricsLine*>::iterator i = m_sourceData->lyrics()->begin();
568  while (i != m_sourceData->lyrics()->end())
569  {
570  LyricsLine *line = (*i);
571  ++i;
572 
574 
575  if (i != m_sourceData->lyrics()->end())
576  lyrics += '\n';
577  }
578 
579  m_lyricsEdit->SetText(lyrics);
580 }
581 
583 {
584  (void) syncronized;
585 
586  loadLyrics();
587 }
588 
590 {
591  bool changed = false;
592 
593  changed |= m_sourceData->artist() != m_artistEdit->GetText();
594  changed |= m_sourceData->album() != m_albumEdit->GetText();
595  changed |= m_sourceData->title() != m_titleEdit->GetText();
596  changed |= m_sourceData->grabber() != m_grabberEdit->GetText();
598 
599  QStringList lines = m_lyricsEdit->GetText().split('\n');
600 
601  if (lines.count() != m_sourceData->lyrics()->count())
602  return true;
603 
604  int x = 0;
605  QMap<int, LyricsLine*>::iterator i = m_sourceData->lyrics()->begin();
606  while (i != m_sourceData->lyrics()->end())
607  {
608  LyricsLine *line = (*i);
609  if (line->toString(m_sourceData->syncronized()) != lines.at(x))
610  changed = true;
611 
612  ++i;
613  ++x;
614  }
615 
616  return changed;
617 }
618 
620 {
621  if (!somethingChanged())
622  {
623  emit haveResult(false);
624  Close();
625  return;
626  }
627 
628  QStringList lyrics = m_lyricsEdit->GetText().split('\n');
629 
630  m_sourceData->setChanged(true);
636  m_sourceData->setLyrics(lyrics);
637  m_sourceData->save();
638  m_sourceData->setChanged(false);
639 
640  emit haveResult(true);
641  Close();
642 }
643 
645 {
646  if (!ok)
647  {
648  emit haveResult(false);
649  Close();
650  return;
651  }
652 
653  okPressed();
654 }
655 
657 {
658  if (somethingChanged())
659  {
660  ShowOkPopup(tr("Save changes?"), this, SLOT(saveEdits(bool)), true);
661  return;
662  }
663 
664  emit haveResult(false);
665  Close();
666 }
static Type Info
Definition: output.h:63
void setGrabber(const QString &grabber)
Definition: lyricsdata.h:63
MythUIButtonList * m_lyricsList
Definition: lyricsview.h:47
void Show(void)
void customEvent(QEvent *event) override
Definition: lyricsview.cpp:95
void lyricStatusChanged(LyricsData::Status status, const QString &message)
Definition: lyricsview.cpp:388
MusicPlayer * gPlayer
Definition: musicplayer.cpp:35
QString title(void)
Definition: lyricsdata.h:71
MusicMetadata * getCurrentMetadata(void)
get the metadata for the current track in the playlist
MythUIText * m_statusText
Definition: lyricsview.h:48
MythUIText * m_bufferStatus
Definition: lyricsview.h:50
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
MythConfirmationDialog * ShowOkPopup(const QString &message, QObject *parent, const char *slot, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
void setChanged(bool changed)
Definition: lyricsdata.h:81
LyricsData * m_lyricData
Definition: lyricsview.h:53
MythUIButton * m_cancelButton
Definition: lyricsview.h:92
int getCurrentTrackTime(void)
Definition: musicplayer.h:136
MusicView m_currentView
Definition: musiccommon.h:139
void removeListener(QObject *listener)
Remove a listener to the observable.
Basic menu dialog, message and a list of options.
EditLyricsDialog(MythScreenStack *parent, LyricsData *sourceData)
Definition: lyricsview.cpp:493
bool somethingChanged(void)
Definition: lyricsview.cpp:589
QString artist(void)
Definition: lyricsdata.h:65
MythUITextEdit * m_lyricsEdit
Definition: lyricsview.h:91
void customEvent(QEvent *event) override
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:135
bool isPlaying(void)
Definition: musicplayer.h:102
void setTitle(const QString &title)
Definition: lyricsdata.h:72
MythScreenStack * GetStack(const QString &stackname)
MythUICheckBox * m_syncronizedCheck
Definition: lyricsview.h:87
void haveResult(bool ok)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythScreenStack * GetMainStack()
void addListener(QObject *listener)
Add a listener to the observable.
MythUIButtonListItem * GetItemAt(int pos) const
QString grabber(void)
Definition: lyricsdata.h:62
static MythThemedMenu * menu
LyricsData * m_sourceData
Definition: lyricsview.h:84
void editFinished(bool result)
Definition: lyricsview.cpp:484
QString toString(bool syncronized)
Definition: lyricsdata.h:27
bool keyPressEvent(QKeyEvent *) override
Key event handler.
Definition: lyricsview.cpp:274
void loadLyrics(void)
Definition: lyricsview.cpp:564
MythUITextEdit * m_grabberEdit
Definition: lyricsview.h:86
void BuildFocusList(void)
static Type kEventType
Definition: mythdialogbox.h:50
virtual int64_t GetAudiotime(void)=0
static Type TrackChangeEvent
Definition: musicplayer.h:40
void Hide(void)
virtual void Close()
MythUIStateType * m_loadingState
Definition: lyricsview.h:49
MythUITextEdit * m_artistEdit
Definition: lyricsview.h:89
MythMenu * createFindLyricsMenu(void)
Definition: lyricsview.cpp:257
bool GetBooleanCheckState(void) const
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void findLyrics(const QString &grabber)
Definition: lyricsdata.cpp:50
QString album(void)
Definition: lyricsdata.h:68
PlayMode getPlayMode(void)
Definition: musicplayer.h:70
void showLyrics(void)
Definition: lyricsview.cpp:439
void editLyrics(void)
Definition: lyricsview.cpp:469
int m_time
Definition: lyricsdata.h:24
MythMenu * createMainMenu(void)
QList< MusicMetadata * > & getPlayedTracksList(void)
Definition: musicplayer.h:130
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:83
static Type OperationStart
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
bool Create(void) override
Definition: lyricsview.cpp:500
void saveLyrics(void)
Definition: lyricsview.cpp:463
void saveEdits(bool ok)
Definition: lyricsview.cpp:644
~LyricsView(void)
Definition: lyricsview.cpp:47
bool syncronized(void)
Definition: lyricsdata.h:77
void findLyrics(const QString &grabber="ALL")
Definition: lyricsview.cpp:351
bool Create(void) override
Definition: lyricsview.cpp:58
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
void SetText(const QString &text, bool moveCursor=true)
MythUIType * GetFocusWidget(void) const
void setArtist(const QString &artist)
Definition: lyricsdata.h:66
MythUITextEdit * m_albumEdit
Definition: lyricsview.h:90
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
MythMainWindow * GetMythMainWindow(void)
void setLyricTime(void)
Definition: lyricsview.cpp:329
void setAlbum(const QString &album)
Definition: lyricsdata.h:69
bool keyPressEvent(QKeyEvent *) override
Key event handler.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void clear(void)
Definition: lyricsdata.cpp:27
LyricsView(MythScreenStack *parent, MythScreenType *parentScreen)
Definition: lyricsview.cpp:39
LyricsData * getLyricsData(void)
MythUIProgressBar * m_bufferProgress
Definition: lyricsview.h:51
void showMessage(const QString &message)
Definition: lyricsview.cpp:422
void setLyrics(const QStringList &lyrics)
Definition: lyricsdata.cpp:310
MythUIButton * m_okButton
Definition: lyricsview.h:93
static Type BufferStatus
QMap< int, LyricsLine * > * lyrics(void)
Definition: lyricsdata.h:74
bool DisplayState(const QString &name)
void SetCheckState(MythUIStateType::StateType state)
MythUITextEdit * m_titleEdit
Definition: lyricsview.h:88
void SetItemCurrent(MythUIButtonListItem *item)
void okPressed(void)
Definition: lyricsview.cpp:619
static Type OperationStop
void cancelPressed(void)
Definition: lyricsview.cpp:656
static Type PlayedTracksChangedEvent
Definition: musicplayer.h:51
bool m_autoScroll
Definition: lyricsview.h:55
void save(void)
Definition: lyricsdata.cpp:115
bool changed(void)
Definition: lyricsdata.h:80
void ShowMenu(void) override
Definition: lyricsview.cpp:220
AudioOutput * getOutput(void)
Definition: musicplayer.h:117
Screen in which all other widgets are contained and rendered.
void syncronizedChanged(bool syncronized)
Definition: lyricsview.cpp:582
int GetCurrentPos() const
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
Definition: lyricsview.cpp:540
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
void setSyncronized(bool syncronized)
Definition: lyricsdata.h:78
bool CreateCommon(void)
Definition: musiccommon.cpp:81
QString m_lyric
Definition: lyricsdata.h:25
QString GetText(void) const
MythUIButtonListItem * GetItemCurrent() const