1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
3 
4 #include <cmath>
5 #include <QLibraryInfo>
6 #include <QMimeData>
7 #include <QDesktopWidget>
8 
9 #include "bakaengine.h"
10 #include "mpvhandler.h"
11 #include "gesturehandler.h"
12 #include "overlayhandler.h"
13 #include "util.h"
14 #include "widgets/dimdialog.h"
15 #include "inputdialog.h"
16 #include "screenshotdialog.h"
17 
MainWindow(QWidget * parent)18 MainWindow::MainWindow(QWidget *parent):
19     QMainWindow(parent),
20     ui(new Ui::MainWindow)
21 {
22     ui->setupUi(this);
23 #if defined(Q_OS_UNIX) || defined(Q_OS_LINUX)
24     // update streaming support disabled on unix platforms
25     ui->actionUpdate_Streaming_Support->setEnabled(false);
26 #endif
27     ShowPlaylist(false);
28     addActions(ui->menubar->actions()); // makes menubar shortcuts work even when menubar is hidden
29 
30     // initialize managers/handlers
31     baka = new BakaEngine(this);
32     mpv = baka->mpv;
33 
34     ui->playlistWidget->AttachEngine(baka);
35     ui->mpvFrame->installEventFilter(this); // capture events on mpvFrame in the eventFilter function
36     ui->mpvFrame->setMouseTracking(true);
37     autohide = new QTimer(this);
38 
39     // command action mappings (action (right) performs command (left))
40     commandActionMap = {
41         {"mpv add chapter +1", ui->action_Next_Chapter},
42         {"mpv add chapter -1", ui->action_Previous_Chapter},
43         {"mpv set sub-scale 1", ui->action_Reset_Size},
44         {"mpv add sub-scale +0.1", ui->action_Size},
45         {"mpv add sub-scale -0.1", ui->actionS_ize},
46         {"mpv set video-aspect -1", ui->action_Auto_Detect}, // todo: make these baka-commands so we can output messages when they change
47         {"mpv set video-aspect 16:9", ui->actionForce_16_9},
48         {"mpv set video-aspect 2.35:1", ui->actionForce_2_35_1},
49         {"mpv set video-aspect 4:3", ui->actionForce_4_3},
50         {"mpv cycle sub-visibility", ui->actionShow_Subtitles},
51         {"mpv set time-pos 0", ui->action_Restart},
52         {"mpv frame_step", ui->action_Frame_Step},
53         {"mpv frame_back_step", ui->actionFrame_Back_Step},
54         {"deinterlace", ui->action_Deinterlace},
55         {"interpolate", ui->action_Motion_Interpolation},
56         {"mute", ui->action_Mute},
57         {"screenshot subtitles", ui->actionWith_Subtitles},
58         {"screenshot", ui->actionWithout_Subtitles},
59         {"add_subtitles", ui->action_Add_Subtitle_File},
60         {"add_audio", ui->action_Add_Audio_File},
61         {"fitwindow", ui->action_To_Current_Size},
62         {"fitwindow 50", ui->action50},
63         {"fitwindow 75", ui->action75},
64         {"fitwindow 100", ui->action100},
65         {"fitwindow 150", ui->action150},
66         {"fitwindow 200", ui->action200},
67         {"fullscreen", ui->action_Full_Screen},
68         {"hide_all_controls", ui->actionHide_All_Controls},
69         {"jump", ui->action_Jump_to_Time},
70         {"media_info", ui->actionMedia_Info},
71         {"new", ui->action_New_Player},
72         {"open", ui->action_Open_File},
73         {"open_clipboard", ui->actionOpen_Path_from_Clipboard},
74         {"open_location", ui->actionOpen_URL},
75         {"playlist play +1", ui->actionPlay_Next_File},
76         {"playlist play -1", ui->actionPlay_Previous_File},
77         {"playlist repeat off", ui->action_Off},
78         {"playlist repeat playlist", ui->action_Playlist},
79         {"playlist repeat this", ui->action_This_File},
80         {"playlist shuffle", ui->actionSh_uffle},
81         {"playlist toggle", ui->action_Show_Playlist},
82         {"playlist full", ui->action_Hide_Album_Art},
83         {"dim", ui->action_Dim_Lights},
84         {"play_pause", ui->action_Play},
85         {"quit", ui->actionE_xit},
86         {"show_in_folder", ui->actionShow_in_Folder},
87         {"stop", ui->action_Stop},
88         {"volume +5", ui->action_Increase_Volume},
89         {"volume -5", ui->action_Decrease_Volume},
90         {"speed +0.1", ui->action_Increase},
91         {"speed -0.1", ui->action_Decrease},
92         {"speed 1.0", ui->action_Reset},
93         {"output", ui->actionShow_D_ebug_Output},
94         {"preferences", ui->action_Preferences},
95         {"online_help", ui->actionOnline_Help},
96         {"update", ui->action_Check_for_Updates},
97         {"update youtube-dl", ui->actionUpdate_Streaming_Support},
98         {"about qt", ui->actionAbout_Qt},
99         {"about", ui->actionAbout_Baka_MPlayer}
100     };
101 
102     // map actions to commands
103     for(auto action = commandActionMap.begin(); action != commandActionMap.end(); ++action)
104     {
105         const QString cmd = action.key();
106         connect(*action, &QAction::triggered,
107                 [=] { baka->Command(cmd); });
108     }
109 
110     // setup signals & slots
111 
112     // mainwindow
113     connect(this, &MainWindow::langChanged,
114             [=](QString lang)
115             {
116                 if(lang == "auto") // fetch lang from locale
117                     lang = QLocale::system().name();
118 
119                 if(lang != "en")
120                 {
121                     QTranslator *tmp;
122 
123                     // load the system translations provided by Qt
124                     tmp = baka->qtTranslator;
125                     baka->qtTranslator = new QTranslator();
126                     baka->qtTranslator->load(QString("qt_%0").arg(lang), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
127                     qApp->installTranslator(baka->qtTranslator);
128                     if(tmp != nullptr)
129                         delete tmp;
130 
131                     // load the application translations
132                     tmp = baka->translator;
133                     baka->translator = new QTranslator();
134                     baka->translator->load(QString("baka-mplayer_%0").arg(lang), BAKA_MPLAYER_LANG_PATH);
135                     qApp->installTranslator(baka->translator);
136                     if(tmp != nullptr)
137                         delete tmp;
138                 }
139                 else
140                 {
141                     if(baka->qtTranslator != nullptr)
142                         qApp->removeTranslator(baka->qtTranslator);
143                     if(baka->translator != nullptr)
144                         qApp->removeTranslator(baka->translator);
145                 }
146 
147                 // save strings we want to keep
148                 QString title = windowTitle(),
149                         duration = ui->durationLabel->text(),
150                         remaining = ui->remainingLabel->text(),
151                         index = ui->indexLabel->text();
152 
153                 ui->retranslateUi(this);
154 
155                 // reload strings we kept
156                 setWindowTitle(title);
157                 ui->durationLabel->setText(duration);
158                 ui->remainingLabel->setText(remaining);
159                 ui->indexLabel->setText(index);
160             });
161 
162     connect(this, &MainWindow::onTopChanged,
163             [=](QString onTop)
164             {
165                 if(onTop == "never")
166                     Util::SetAlwaysOnTop(winId(), false);
167                 else if(onTop == "always")
168                     Util::SetAlwaysOnTop(winId(), true);
169                 else if(onTop == "playing" && mpv->getPlayState() > 0)
170                     Util::SetAlwaysOnTop(winId(), true);
171             });
172 
173     connect(this, &MainWindow::remainingChanged,
174             [=]
175             {
176                 SetRemainingLabels(mpv->getTime());
177             });
178 
179     connect(this, &MainWindow::debugChanged,
180             [=](bool b)
181             {
182                 ui->actionShow_D_ebug_Output->setChecked(b);
183                 ui->verticalWidget->setVisible(b);
184                 mouseMoveEvent(new QMouseEvent(QMouseEvent::MouseMove,
185                                                QCursor::pos(),
186                                                Qt::NoButton,Qt::NoButton,Qt::NoModifier));
187                 if(b)
188                     ui->inputLineEdit->setFocus();
189             });
190 
191     connect(this, &MainWindow::hideAllControlsChanged,
192             [=](bool b)
193             {
194                 HideAllControls(b);
195                 blockSignals(true);
196                 ui->actionHide_All_Controls->setChecked(b);
197                 blockSignals(false);
198             });
199 
200     connect(baka->sysTrayIcon, &QSystemTrayIcon::activated,
201             [=](QSystemTrayIcon::ActivationReason reason)
202             {
203                 if(reason == QSystemTrayIcon::Trigger)
204                 {
205                     if(!hidePopup)
206                     {
207                         if(mpv->getPlayState() == Mpv::Playing)
208                             baka->sysTrayIcon->showMessage("Baka MPlayer", tr("Playing"), QSystemTrayIcon::NoIcon, 4000);
209                         else if(mpv->getPlayState() == Mpv::Paused)
210                             baka->sysTrayIcon->showMessage("Baka MPlayer", tr("Paused"), QSystemTrayIcon::NoIcon, 4000);
211                     }
212                     baka->PlayPause();
213                 }
214 
215             });
216 
217     //    connect(this, &MainWindow::hidePopupChanged,
218     //            [=](bool b)
219     //    {
220     //    });
221 
222     connect(autohide, &QTimer::timeout, // cursor autohide
223             [=]
224             {
225                 if(ui->mpvFrame->geometry().contains(ui->mpvFrame->mapFromGlobal(cursor().pos())))
226                     setCursor(QCursor(Qt::BlankCursor));
227                 if(autohide)
228                     autohide->stop();
229             });
230 
231     // dimDialog
232     connect(baka->dimDialog, &DimDialog::visbilityChanged,
233             [=](bool dim)
234             {
235                 ui->action_Dim_Lights->setChecked(dim);
236                 if(dim)
237                     Util::SetAlwaysOnTop(winId(), true);
238                 else if(onTop == "never" || (onTop == "playing" && mpv->getPlayState() > 0))
239                     Util::SetAlwaysOnTop(winId(), false);
240             });
241 
242     // mpv
243 
244     connect(mpv, &MpvHandler::playlistChanged,
245             [=](const QStringList &list)
246             {
247                 if(list.length() > 1)
248                 {
249                     ui->actionSh_uffle->setEnabled(true);
250                     ui->actionStop_after_Current->setEnabled(true);
251                     ShowPlaylist(true);
252                 }
253                 else
254                 {
255                     ui->actionSh_uffle->setEnabled(false);
256                     ui->actionStop_after_Current->setEnabled(false);
257                 }
258 
259                 if(list.length() > 0)
260                     ui->menuR_epeat->setEnabled(true);
261                 else
262                     ui->menuR_epeat->setEnabled(false);
263             });
264 
265     connect(mpv, &MpvHandler::fileInfoChanged,
266             [=](const Mpv::FileInfo &fileInfo)
267             {
268                 if(mpv->getPlayState() > 0)
269                 {
270                     if(fileInfo.media_title == "")
271                         setWindowTitle("Baka MPlayer");
272                     else if(fileInfo.media_title == "-")
273                         setWindowTitle("Baka MPlayer: stdin"); // todo: disable playlist?
274                     else
275                         setWindowTitle(fileInfo.media_title);
276 
277                     QString f = mpv->getFile(), file = mpv->getPath()+f;
278                     if(f != QString() && maxRecent > 0)
279                     {
280                         int i = recent.indexOf(file);
281                         if(i >= 0)
282                         {
283                             int t = recent.at(i).time;
284                             if(t > 0 && resume)
285                                 mpv->Seek(t);
286                             recent.removeAt(i);
287                         }
288                         if(recent.isEmpty() || recent.front() != file)
289                         {
290                             UpdateRecentFiles(); // update after initialization and only if the current file is different from the first recent
291                             while(recent.length() > maxRecent-1)
292                                 recent.removeLast();
293                             recent.push_front(
294                                 Recent(file,
295                                        (mpv->getPath() == QString() || !Util::IsValidFile(file)) ?
296                                            fileInfo.media_title : QString()));
297                             current = &recent.front();
298                         }
299                     }
300 
301                     // reset speed if length isn't known and we have a streaming video
302                     // todo: don't save this reset, put their speed back when a normal video comes on
303                     // todo: disable speed alteration during streaming media
304                     if(fileInfo.length == 0)
305                         if(mpv->getSpeed() != 1)
306                             mpv->Speed(1);
307 
308                     ui->seekBar->setTracking(fileInfo.length);
309 
310                     if(ui->actionMedia_Info->isChecked())
311                         baka->MediaInfo(true);
312 
313                     SetRemainingLabels(fileInfo.length);
314                 }
315             });
316 
317     connect(mpv, &MpvHandler::trackListChanged,
318             [=](const QList<Mpv::Track> &trackList)
319             {
320                 if(mpv->getPlayState() > 0)
321                 {
322                     QAction *action;
323                     bool video = false,
324                          albumArt = false;
325 
326                     ui->menuSubtitle_Track->clear();
327                     ui->menuSubtitle_Track->addAction(ui->action_Add_Subtitle_File);
328                     ui->menuAudio_Tracks->clear();
329                     ui->menuAudio_Tracks->addAction(ui->action_Add_Audio_File);
330                     for(auto &track : trackList)
331                     {
332                         if(track.type == "sub")
333                         {
334                             action = ui->menuSubtitle_Track->addAction(QString("%0: %1 (%2)").arg(QString::number(track.id), track.title, track.external ? "external" : track.lang).replace("&", "&&"));
335                             connect(action, &QAction::triggered,
336                                     [=]
337                                     {
338                                         // basically, if you uncheck the selected subtitle id, we hide subtitles
339                                         // when you check a subtitle id, we make sure subtitles are showing and set it
340                                         if(mpv->getSid() == track.id)
341                                         {
342                                             if(mpv->getSubtitleVisibility())
343                                             {
344                                                 mpv->ShowSubtitles(false);
345                                                 return;
346                                             }
347                                             else
348                                                 mpv->ShowSubtitles(true);
349                                         }
350                                         else if(!mpv->getSubtitleVisibility())
351                                             mpv->ShowSubtitles(true);
352                                         mpv->Sid(track.id);
353                                         mpv->ShowText(QString("%0 %1: %2 (%3)").arg(tr("Sub"), QString::number(track.id), track.title, track.external ? "external" : track.lang));
354                                     });
355                         }
356                         else if(track.type == "audio")
357                         {
358                             action = ui->menuAudio_Tracks->addAction(QString("%0: %1 (%2)").arg(QString::number(track.id), track.title, track.lang).replace("&", "&&"));
359                             connect(action, &QAction::triggered,
360                                     [=]
361                                     {
362                                         if(mpv->getAid() != track.id) // don't allow selection of the same track
363                                         {
364                                             mpv->Aid(track.id);
365                                             mpv->ShowText(QString("%0 %1: %2 (%3)").arg(tr("Audio"), QString::number(track.id), track.title, track.lang));
366                                         }
367                                         else
368                                             action->setChecked(true); // recheck the track
369                                     });
370                         }
371                         else if(track.type == "video") // video track
372                         {
373                             if(!track.albumart) // isn't album art
374                                 video = true;
375                             else
376                                 albumArt = true;
377                         }
378                     }
379                     if(video)
380                     {
381                         // if we were hiding album art, show it--we've gone to a video
382                         if(ui->mpvFrame->styleSheet() != QString()) // remove filler album art
383                             ui->mpvFrame->setStyleSheet("");
384                         if(ui->action_Hide_Album_Art->isChecked())
385                             HideAlbumArt(false);
386                         ui->action_Hide_Album_Art->setEnabled(false);
387                         ui->menuSubtitle_Track->setEnabled(true);
388                         if(ui->menuSubtitle_Track->actions().count() > 1)
389                         {
390                             ui->menuFont_Si_ze->setEnabled(true);
391                             ui->actionShow_Subtitles->setEnabled(true);
392                             ui->actionShow_Subtitles->setChecked(mpv->getSubtitleVisibility());
393                         }
394                         else
395                         {
396                             ui->menuFont_Si_ze->setEnabled(false);
397                             ui->actionShow_Subtitles->setEnabled(false);
398                             ui->actionShow_Subtitles->setChecked(false);
399                         }
400                         ui->menuTake_Screenshot->setEnabled(true);
401                         ui->menuFit_Window->setEnabled(true);
402                         ui->menuAspect_Ratio->setEnabled(true);
403                         ui->action_Frame_Step->setEnabled(true);
404                         ui->actionFrame_Back_Step->setEnabled(true);
405                         ui->action_Deinterlace->setEnabled(true);
406                         ui->action_Motion_Interpolation->setEnabled(true);
407                     }
408                     else
409                     {
410                         if(!albumArt)
411                         {
412                             // put in filler albumArt
413                             if(ui->mpvFrame->styleSheet() == QString())
414                                 ui->mpvFrame->setStyleSheet("background-image:url(:/img/album-art.png);background-repeat:no-repeat;background-position:center;");
415                         }
416                         ui->action_Hide_Album_Art->setEnabled(true);
417                         ui->menuSubtitle_Track->setEnabled(false);
418                         ui->menuFont_Si_ze->setEnabled(false);
419                         ui->actionShow_Subtitles->setEnabled(false);
420                         ui->actionShow_Subtitles->setChecked(false);
421                         ui->menuTake_Screenshot->setEnabled(false);
422                         ui->menuFit_Window->setEnabled(false);
423                         ui->menuAspect_Ratio->setEnabled(false);
424                         ui->action_Frame_Step->setEnabled(false);
425                         ui->actionFrame_Back_Step->setEnabled(false);
426                         ui->action_Deinterlace->setEnabled(false);
427                         ui->action_Motion_Interpolation->setEnabled(false);
428 
429                         if(baka->sysTrayIcon->isVisible() && !hidePopup)
430                         {
431                             // todo: use {artist} - {title}
432                             baka->sysTrayIcon->showMessage("Baka MPlayer", mpv->getFileInfo().media_title, QSystemTrayIcon::NoIcon, 4000);
433                         }
434                     }
435 
436                     if(ui->menuAudio_Tracks->actions().count() == 1)
437                         ui->menuAudio_Tracks->actions().first()->setEnabled(false);
438 
439                     if(pathChanged && autoFit)
440                     {
441                         baka->FitWindow(autoFit, false);
442                         pathChanged = false;
443                     }
444                 }
445             });
446 
447     connect(mpv, &MpvHandler::chaptersChanged,
448             [=](const QList<Mpv::Chapter> &chapters)
449             {
450                 if(mpv->getPlayState() > 0)
451                 {
452                     QAction *action;
453                     QList<int> ticks;
454                     int n = 1,
455                         N = chapters.length();
456                     ui->menu_Chapters->clear();
457                     for(auto &ch : chapters)
458                     {
459                         action = ui->menu_Chapters->addAction(QString("%0: %1").arg(Util::FormatNumberWithAmpersand(n, N), ch.title));
460                         if(n <= 9)
461                             action->setShortcut(QKeySequence("Ctrl+"+QString::number(n)));
462                         connect(action, &QAction::triggered,
463                                 [=]
464                                 {
465                                     mpv->Seek(ch.time);
466                                 });
467                         ticks.push_back(ch.time);
468                         n++;
469                     }
470                     if(ui->menu_Chapters->actions().count() == 0)
471                     {
472                         ui->menu_Chapters->setEnabled(false);
473                         ui->action_Next_Chapter->setEnabled(false);
474                         ui->action_Previous_Chapter->setEnabled(false);
475                     }
476                     else
477                     {
478                         ui->menu_Chapters->setEnabled(true);
479                         ui->action_Next_Chapter->setEnabled(true);
480                         ui->action_Previous_Chapter->setEnabled(true);
481                     }
482 
483                     ui->seekBar->setTicks(ticks);
484                 }
485             });
486 
487     connect(mpv, &MpvHandler::playStateChanged,
488             [=](Mpv::PlayState playState)
489             {
490                 switch(playState)
491                 {
492                 case Mpv::Loaded:
493                     baka->mpv->ShowText("Loading...", 0);
494                     break;
495 
496                 case Mpv::Started:
497                     if(!init) // will only happen the first time a file is loaded.
498                     {
499                         ui->action_Play->setEnabled(true);
500                         ui->playButton->setEnabled(true);
501 #if defined(Q_OS_WIN)
502                         playpause_toolbutton->setEnabled(true);
503 #endif
504                         ui->playlistButton->setEnabled(true);
505                         ui->action_Show_Playlist->setEnabled(true);
506                         ui->menuAudio_Tracks->setEnabled(true);
507                         init = true;
508                     }
509                     SetPlaybackControls(true);
510                     mpv->Play();
511                     baka->overlay->showStatusText(QString(), 0);
512                 case Mpv::Playing:
513                     SetPlayButtonIcon(false);
514                     if(onTop == "playing")
515                         Util::SetAlwaysOnTop(winId(), true);
516                     break;
517 
518                 case Mpv::Paused:
519                 case Mpv::Stopped:
520                     SetPlayButtonIcon(true);
521                     if(onTop == "playing")
522                         Util::SetAlwaysOnTop(winId(), false);
523                     break;
524 
525                 case Mpv::Idle:
526                     if(init)
527                     {
528                         if(ui->action_This_File->isChecked()) // repeat this file
529                             ui->playlistWidget->PlayIndex(0, true); // restart file
530                         else if(ui->actionStop_after_Current->isChecked() ||  // stop after playing this file
531                                 ui->playlistWidget->CurrentIndex() >= ui->playlistWidget->count()-1) // end of the playlist
532                         {
533                             if(!ui->actionStop_after_Current->isChecked() && // not supposed to stop after current
534                                 ui->action_Playlist->isChecked() && // we're supposed to restart the playlist
535                                 ui->playlistWidget->count() > 0) // playlist isn't empty
536                             {
537                                 ui->playlistWidget->PlayIndex(0); // restart playlist
538                             }
539                             else // stop
540                             {
541                                 setWindowTitle("Baka MPlayer");
542                                 SetPlaybackControls(false);
543                                 ui->seekBar->setTracking(0);
544                                 ui->actionStop_after_Current->setChecked(false);
545                                 if(ui->mpvFrame->styleSheet() != QString()) // remove filler album art
546                                     ui->mpvFrame->setStyleSheet("");
547                             }
548                         }
549                         else
550                             ui->playlistWidget->PlayIndex(1, true);
551                     }
552                     break;
553                 }
554             });
555 
556     connect(mpv, &MpvHandler::pathChanged,
557             [=]()
558             {
559                 pathChanged = true;
560             });
561 
562       connect(mpv, &MpvHandler::fileChanging,
563               [=](int t, int l)
564               {
565                   if(current != nullptr)
566                   {
567                       if(t > 0.05*l && t < 0.95*l) // only save if within the middle 90%
568                           current->time = t;
569                       else
570                           current->time = 0;
571                   }
572               });
573 
574 //    connect(mpv, &MpvHandler::fileChanged,
575 //            [=](QString f)
576 //            {
577 //            });
578 
579     connect(mpv, &MpvHandler::timeChanged,
580             [=](int i)
581             {
582                 const Mpv::FileInfo &fi = mpv->getFileInfo();
583                 // set the seekBar's location with NoSignal function so that it doesn't trigger a seek
584                 // the formula is a simple ratio seekBar's max * time/totalTime
585                 ui->seekBar->setValueNoSignal(ui->seekBar->maximum()*((double)i/fi.length));
586 
587                 SetRemainingLabels(i);
588 
589                 // set next/previous chapter's enabled state
590                 if(fi.chapters.length() > 0)
591                 {
592                     ui->action_Next_Chapter->setEnabled(i < fi.chapters.last().time);
593                     ui->action_Previous_Chapter->setEnabled(i > fi.chapters.first().time);
594                 }
595             });
596 
597     connect(mpv, &MpvHandler::volumeChanged,
598             [=](int volume)
599             {
600                 ui->volumeSlider->setValueNoSignal(volume);
601             });
602 
603     connect(mpv, &MpvHandler::speedChanged,
604             [=](double speed)
605             {
606                 static double last = 1;
607                 if(last != speed)
608                 {
609                     if(init)
610                         mpv->ShowText(tr("Speed: %0x").arg(QString::number(speed)));
611                     if(speed <= 0.25)
612                         ui->action_Decrease->setEnabled(false);
613                     else
614                         ui->action_Decrease->setEnabled(true);
615                     last = speed;
616                 }
617             });
618 
619     connect(mpv, &MpvHandler::sidChanged,
620             [=](int sid)
621             {
622                 QList<QAction*> actions = ui->menuSubtitle_Track->actions();
623                 for(auto &action : actions)
624                 {
625                     if(action->text().startsWith(QString::number(sid)))
626                     {
627                         action->setCheckable(true);
628                         action->setChecked(true);
629                     }
630                     else
631                         action->setChecked(false);
632                 }
633             });
634 
635     connect(mpv, &MpvHandler::aidChanged,
636             [=](int aid)
637             {
638                 QList<QAction*> actions = ui->menuAudio_Tracks->actions();
639                 for(auto &action : actions)
640                 {
641                     if(action->text().startsWith(QString::number(aid)))
642                     {
643                         action->setCheckable(true);
644                         action->setChecked(true);
645                     }
646                     else
647                         action->setChecked(false);
648                 }
649             });
650 
651     connect(mpv, &MpvHandler::subtitleVisibilityChanged,
652             [=](bool b)
653             {
654                 if(ui->actionShow_Subtitles->isEnabled())
655                     ui->actionShow_Subtitles->setChecked(b);
656                 if(init)
657                     mpv->ShowText(b ? tr("Subtitles visible") : tr("Subtitles hidden"));
658             });
659 
660     connect(mpv, &MpvHandler::muteChanged,
661             [=](bool b)
662             {
663                 if(b)
664                     ui->muteButton->setIcon(QIcon(":/img/default_mute.svg"));
665                 else
666                     ui->muteButton->setIcon(QIcon(":/img/default_unmute.svg"));
667                 mpv->ShowText(b ? tr("Muted") : tr("Unmuted"));
668             });
669 
670     connect(mpv, &MpvHandler::voChanged,
671             [=](QString vo)
672             {
673                 ui->action_Motion_Interpolation->setChecked(vo.contains("interpolation"));
674             });
675     // ui
676 
677     connect(ui->seekBar, &SeekBar::valueChanged,                        // Playback: Seekbar clicked
678             [=](int i)
679             {
680                 mpv->Seek(mpv->Relative(((double)i/ui->seekBar->maximum())*mpv->getFileInfo().length), true);
681             });
682 
683     connect(ui->openButton, &OpenButton::LeftClick,                     // Playback: Open button (left click)
684             [=]
685             {
686                 baka->Open();
687             });
688 
689     connect(ui->openButton, &OpenButton::MiddleClick,                   // Playback: Open button (middle click)
690             [=]
691             {
692                 baka->Jump();
693             });
694 
695     connect(ui->openButton, &OpenButton::RightClick,                    // Playback: Open button (right click)
696             [=]
697             {
698                 baka->OpenLocation();
699             });
700 
701     connect(ui->rewindButton, &QPushButton::clicked,                    // Playback: Rewind button
702             [=]
703             {
704                 mpv->Rewind();
705             });
706 
707     connect(ui->previousButton, &IndexButton::clicked,                  // Playback: Previous button
708             [=]
709             {
710                 ui->playlistWidget->PlayIndex(-1, true);
711             });
712 
713     connect(ui->playButton, &QPushButton::clicked,                      // Playback: Play/pause button
714             [=]
715             {
716                 baka->PlayPause();
717             });
718 
719     connect(ui->nextButton, &IndexButton::clicked,                      // Playback: Next button
720             [=]
721             {
722                 ui->playlistWidget->PlayIndex(1, true);
723             });
724 
725     connect(ui->muteButton, &QPushButton::clicked,
726             [=]
727             {
728                 mpv->Mute(!mpv->getMute());
729             });
730 
731     connect(ui->volumeSlider, &CustomSlider::valueChanged,              // Playback: Volume slider adjusted
732             [=](int i)
733             {
734                 mpv->Volume(i, true);
735             });
736 
737     connect(ui->playlistButton, &QPushButton::clicked,                  // Playback: Clicked the playlist button
738             [=]
739             {
740                 TogglePlaylist();
741             });
742 
743     connect(ui->splitter, &CustomSplitter::positionChanged,             // Splitter position changed
744             [=](int i)
745             {
746                 blockSignals(true);
747                 if(i == 0) // right-most, playlist is hidden
748                 {
749                     ui->action_Show_Playlist->setChecked(false);
750                     ui->action_Hide_Album_Art->setChecked(false);
751                     ui->playlistLayoutWidget->setVisible(false);
752                 }
753                 else if(i == ui->splitter->max()) // left-most, album art is hidden, playlist is visible
754                 {
755                     ui->action_Show_Playlist->setChecked(true);
756                     ui->action_Hide_Album_Art->setChecked(true);
757                 }
758                 else // in the middle, album art is visible, playlist is visible
759                 {
760                     ui->action_Show_Playlist->setChecked(true);
761                     ui->action_Hide_Album_Art->setChecked(false);
762                 }
763                 ui->playlistLayoutWidget->setVisible(ui->action_Show_Playlist->isChecked());
764                 blockSignals(false);
765                 if(ui->actionMedia_Info->isChecked())
766                     baka->overlay->showInfoText();
767             });
768 
769     connect(ui->searchBox, &QLineEdit::textChanged,                     // Playlist: Search box
770             [=](QString s)
771             {
772                 ui->playlistWidget->Search(s);
773             });
774 
775     connect(ui->indexLabel, &CustomLabel::clicked,                      // Playlist: Clicked the indexLabel
776             [=]
777             {
778                 QString res = InputDialog::getInput(tr("Enter the file number you want to play:\nNote: Value must be from %0 - %1").arg("1", QString::number(ui->playlistWidget->count())),
779                                                     tr("Enter File Number"),
780                                                     [this](QString input)
781                                                     {
782                                                         int in = input.toInt();
783                                                         if(in >= 1 && in <= ui->playlistWidget->count())
784                                                             return true;
785                                                         return false;
786                                                     },
787                                                     this);
788                 if(res != "")
789                     ui->playlistWidget->PlayIndex(res.toInt()-1); // user index will be 1 greater than actual
790             });
791 
792     connect(ui->playlistWidget, &PlaylistWidget::currentRowChanged,     // Playlist: Playlist selection changed
793             [=](int)
794             {
795                 SetIndexLabels(true);
796             });
797 
798     connect(ui->currentFileButton, &QPushButton::clicked,               // Playlist: Select current file button
799             [=]
800             {
801                 ui->playlistWidget->SelectIndex(ui->playlistWidget->CurrentIndex());
802             });
803 
804     connect(ui->hideFilesButton, &QPushButton::clicked,                 // Playlist: Hide files button
805             [=](bool b)
806             {
807                 ui->playlistWidget->ShowAll(!b);
808             });
809 
810     connect(ui->refreshButton, &QPushButton::clicked,                   // Playlist: Refresh playlist button
811             [=]
812             {
813                 ui->playlistWidget->RefreshPlaylist();
814             });
815 
816     connect(ui->inputLineEdit, &CustomLineEdit::submitted,
817             [=](QString s)
818             {
819                 baka->Command(s);
820                 ui->inputLineEdit->setText("");
821             });
822 
823     // add multimedia shortcuts
824     ui->action_Play->setShortcuts({ui->action_Play->shortcut(), QKeySequence(Qt::Key_MediaPlay)});
825     ui->action_Stop->setShortcuts({ui->action_Stop->shortcut(), QKeySequence(Qt::Key_MediaStop)});
826     ui->actionPlay_Next_File->setShortcuts({ui->actionPlay_Next_File->shortcut(), QKeySequence(Qt::Key_MediaNext)});
827     ui->actionPlay_Previous_File->setShortcuts({ui->actionPlay_Previous_File->shortcut(), QKeySequence(Qt::Key_MediaPrevious)});
828 }
829 
~MainWindow()830 MainWindow::~MainWindow()
831 {
832     if(current != nullptr)
833     {
834         int t = mpv->getTime(),
835             l = mpv->getFileInfo().length;
836         if(t > 0.05*l && t < 0.95*l) // only save if within the middle 90%
837             current->time = t;
838         else
839             current->time = 0;
840     }
841     baka->SaveSettings();
842 
843     // Note: child objects _should_ not need to be deleted because
844     // all children should get deleted when mainwindow is deleted
845     // see: http://qt-project.org/doc/qt-4.8/objecttrees.html
846 
847     // but apparently they don't (https://github.com/u8sand/Baka-MPlayer/issues/47)
848 #if defined(Q_OS_WIN)
849     delete prev_toolbutton;
850     delete playpause_toolbutton;
851     delete next_toolbutton;
852     delete thumbnail_toolbar;
853 #endif
854     delete baka;
855     delete ui;
856 }
857 
Load(QString file)858 void MainWindow::Load(QString file)
859 {
860     // load the settings here--the constructor has already been called
861     // this solves some issues with setting things before the constructor has ended
862     menuVisible = ui->menubar->isVisible(); // does the OS use a menubar? (appmenu doesn't)
863 #if defined(Q_OS_WIN)
864     // add windows 7+ thubnail toolbar buttons
865     thumbnail_toolbar = new QWinThumbnailToolBar(this);
866     thumbnail_toolbar->setWindow(this->windowHandle());
867 
868     prev_toolbutton = new QWinThumbnailToolButton(thumbnail_toolbar);
869     prev_toolbutton->setEnabled(false);
870     prev_toolbutton->setToolTip(tr("Previous"));
871     prev_toolbutton->setIcon(QIcon(":/img/tool-previous.ico"));
872     connect(prev_toolbutton, &QWinThumbnailToolButton::clicked,
873             [=]
874             {
875                 ui->playlistWidget->PlayIndex(-1, true);
876             });
877 
878     playpause_toolbutton = new QWinThumbnailToolButton(thumbnail_toolbar);
879     playpause_toolbutton->setEnabled(false);
880     playpause_toolbutton->setToolTip(tr("Play"));
881     playpause_toolbutton->setIcon(QIcon(":/img/tool-play.ico"));
882     connect(playpause_toolbutton, &QWinThumbnailToolButton::clicked,
883             [=]
884             {
885                 baka->PlayPause();
886             });
887 
888     next_toolbutton = new QWinThumbnailToolButton(thumbnail_toolbar);
889     next_toolbutton->setEnabled(false);
890     next_toolbutton->setToolTip(tr("Next"));
891     next_toolbutton->setIcon(QIcon(":/img/tool-next.ico"));
892     connect(next_toolbutton, &QWinThumbnailToolButton::clicked,
893             [=]
894             {
895                 ui->playlistWidget->PlayIndex(1, true);
896             });
897 
898     thumbnail_toolbar->addButton(prev_toolbutton);
899     thumbnail_toolbar->addButton(playpause_toolbutton);
900     thumbnail_toolbar->addButton(next_toolbutton);
901 #endif
902     baka->LoadSettings();
903     mpv->Initialize();
904     mpv->LoadFile(file);
905 }
906 
MapShortcuts()907 void MainWindow::MapShortcuts()
908 {
909     auto tmp = commandActionMap;
910     // map shortcuts to actions
911     for(auto input_iter = baka->input.begin(); input_iter != baka->input.end(); ++input_iter)
912     {
913         auto commandAction = tmp.find(input_iter->first);
914         if(commandAction != tmp.end())
915         {
916             (*commandAction)->setShortcut(QKeySequence(input_iter.key()));
917             tmp.erase(commandAction);
918         }
919     }
920     // clear the rest
921     for(auto iter = tmp.begin(); iter != tmp.end(); ++iter)
922         (*iter)->setShortcut(QKeySequence());
923 }
924 
dragEnterEvent(QDragEnterEvent * event)925 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
926 {
927     if(event->mimeData()->hasUrls() || event->mimeData()->hasText()) // url / text
928         event->acceptProposedAction();
929 }
930 
dropEvent(QDropEvent * event)931 void MainWindow::dropEvent(QDropEvent *event)
932 {
933     const QMimeData *mimeData = event->mimeData();
934     if(mimeData->hasUrls()) // urls
935     {
936         for(QUrl &url : mimeData->urls())
937         {
938             if(url.isLocalFile())
939                 mpv->LoadFile(url.toLocalFile());
940             else
941                 mpv->LoadFile(url.url());
942         }
943     }
944     else if(mimeData->hasText()) // text
945         mpv->LoadFile(mimeData->text());
946 }
947 
mousePressEvent(QMouseEvent * event)948 void MainWindow::mousePressEvent(QMouseEvent *event)
949 {
950     if(event->button() == Qt::LeftButton)
951     {
952         if(gestures)
953         {
954             if(ui->mpvFrame->geometry().contains(event->pos())) // mouse is in the mpvFrame
955                 baka->gesture->Begin(GestureHandler::HSEEK_VVOLUME, event->globalPos(), pos());
956             else if(!isFullScreen()) // not fullscreen
957                 baka->gesture->Begin(GestureHandler::MOVE, event->globalPos(), pos());
958         }
959         else if(!isFullScreen()) // not fullscreen
960             baka->gesture->Begin(GestureHandler::MOVE, event->globalPos(), pos());
961 
962         if(ui->remainingLabel->rect().contains(ui->remainingLabel->mapFrom(this, event->pos()))) // clicked timeLayoutWidget
963             setRemaining(!remaining); // todo: use a bakacommand
964     }
965     else if(event->button() == Qt::RightButton &&
966             !isFullScreenMode() &&  // not fullscreen mode
967             mpv->getPlayState() > 0 &&  // playing
968             ui->mpvFrame->geometry().contains(event->pos())) // mouse is in the mpvFrame
969     {
970         mpv->PlayPause(ui->playlistWidget->CurrentItem());
971     }
972     QMainWindow::mousePressEvent(event);
973 }
974 
mouseReleaseEvent(QMouseEvent * event)975 void MainWindow::mouseReleaseEvent(QMouseEvent *event)
976 {
977     baka->gesture->End();
978     QMainWindow::mouseReleaseEvent(event);
979 }
980 
mouseMoveEvent(QMouseEvent * event)981 void MainWindow::mouseMoveEvent(QMouseEvent *event)
982 {
983     if(baka->gesture->Process(event->globalPos()))
984         event->accept();
985     else if(isFullScreenMode())
986     {
987         setCursor(QCursor(Qt::ArrowCursor)); // show the cursor
988         autohide->stop();
989 
990         QRect playbackRect = geometry();
991         playbackRect.setTop(playbackRect.bottom() - 60);
992         bool showPlayback = playbackRect.contains(event->globalPos());
993         ui->playbackLayoutWidget->setVisible(showPlayback || ui->outputTextEdit->isVisible());
994         ui->seekBar->setVisible(showPlayback || ui->outputTextEdit->isVisible());
995 
996         QRect playlistRect = geometry();
997         playlistRect.setLeft(playlistRect.right() - std::ceil(playlistRect.width()/7.0));
998         bool showPlaylist = playlistRect.contains(event->globalPos());
999         ShowPlaylist(showPlaylist);
1000 
1001         if(!(showPlayback || showPlaylist) && autohide)
1002             autohide->start(500);
1003     }
1004     QMainWindow::mouseMoveEvent(event);
1005 }
1006 
leaveEvent(QEvent * event)1007 void MainWindow::leaveEvent(QEvent *event)
1008 {
1009     mouseMoveEvent(new QMouseEvent(QMouseEvent::MouseMove,
1010                                    QCursor::pos(),
1011                                    Qt::NoButton,Qt::NoButton,Qt::NoModifier));
1012     QMainWindow::leaveEvent(event);
1013 }
1014 
eventFilter(QObject * obj,QEvent * event)1015 bool MainWindow::eventFilter(QObject *obj, QEvent *event)
1016 {
1017     if(obj == ui->mpvFrame && isFullScreenMode() && event->type() == QEvent::MouseMove)
1018     {
1019         QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
1020         mouseMoveEvent(mouseEvent);
1021     }
1022     else if(event->type() == 6) // QEvent::KeyPress = 6  (but using QEvent::KeyPress causes compile errors, not sure why)
1023     {
1024         QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
1025         keyPressEvent(keyEvent);
1026     }
1027     return false;
1028 }
1029 
wheelEvent(QWheelEvent * event)1030 void MainWindow::wheelEvent(QWheelEvent *event)
1031 {
1032     if(event->delta() > 0)
1033         mpv->Volume(mpv->getVolume()+5, true);
1034     else
1035         mpv->Volume(mpv->getVolume()-5, true);
1036     QMainWindow::wheelEvent(event);
1037 }
1038 
keyPressEvent(QKeyEvent * event)1039 void MainWindow::keyPressEvent(QKeyEvent *event)
1040 {
1041     // keyboard shortcuts
1042     if(!baka->input.empty())
1043     {
1044         QString key = QKeySequence(event->modifiers()|event->key()).toString();
1045 
1046         // TODO: Add more protection/find a better way to protect edit boxes from executing commands
1047         if(focusWidget() == ui->inputLineEdit &&
1048            key == "Return")
1049             return;
1050 
1051         // Escape exits fullscreen
1052         if(isFullScreen() &&
1053            key == "Esc") {
1054             FullScreen(false);
1055             return;
1056         }
1057 
1058         // find shortcut in input hash table
1059         auto iter = baka->input.find(key);
1060         if(iter != baka->input.end())
1061             baka->Command(iter->first); // execute command
1062     }
1063 }
1064 
resizeEvent(QResizeEvent * event)1065 void MainWindow::resizeEvent(QResizeEvent *event)
1066 {
1067     if(ui->actionMedia_Info->isChecked())
1068         baka->overlay->showInfoText();
1069     QMainWindow::resizeEvent(event);
1070 }
1071 
mouseDoubleClickEvent(QMouseEvent * event)1072 void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
1073 {
1074     if(event->button() == Qt::LeftButton && ui->mpvFrame->geometry().contains(event->pos())) // if mouse is in the mpvFrame
1075     {
1076         if(!isFullScreen() && ui->action_Full_Screen->isEnabled()) // don't allow people to go full screen if they shouldn't be able to
1077             FullScreen(true);
1078         else // they can leave fullscreen even if it's disabled (eg. video ends while in full screen)
1079             FullScreen(false);
1080         event->accept();
1081     }
1082     QMainWindow::mouseDoubleClickEvent(event);
1083 }
1084 
SetIndexLabels(bool enable)1085 void MainWindow::SetIndexLabels(bool enable)
1086 {
1087     int i = ui->playlistWidget->currentRow(),
1088         index = ui->playlistWidget->CurrentIndex();
1089 
1090     // next file
1091     if(enable && index+1 < ui->playlistWidget->count()) // not the last entry
1092     {
1093         SetNextButtonEnabled(true);
1094         ui->nextButton->setIndex(index+2); // starting at 1 instead of at 0 like actual index
1095 
1096     }
1097     else
1098         SetNextButtonEnabled(false);
1099 
1100     // previous file
1101     if(enable && index-1 >= 0) // not the first entry
1102     {
1103         SetPreviousButtonEnabled(true);
1104         ui->previousButton->setIndex(-index); // we use a negative index value for the left button
1105     }
1106     else
1107         SetPreviousButtonEnabled(false);
1108 
1109     if(i == -1) // no selection
1110     {
1111         ui->indexLabel->setText(tr("No selection"));
1112         ui->indexLabel->setEnabled(false);
1113     }
1114     else
1115     {
1116         ui->indexLabel->setEnabled(true);
1117         ui->indexLabel->setText(tr("File %0 of %1").arg(QString::number(i+1), QString::number(ui->playlistWidget->count())));
1118     }
1119 }
1120 
SetPlaybackControls(bool enable)1121 void MainWindow::SetPlaybackControls(bool enable)
1122 {
1123     // playback controls
1124     ui->seekBar->setEnabled(enable);
1125     ui->rewindButton->setEnabled(enable);
1126 
1127     SetIndexLabels(enable);
1128 
1129     // menubar
1130     ui->action_Stop->setEnabled(enable);
1131     ui->action_Restart->setEnabled(enable);
1132     ui->menuS_peed->setEnabled(enable);
1133     ui->action_Jump_to_Time->setEnabled(enable);
1134     ui->actionMedia_Info->setEnabled(enable);
1135     ui->actionShow_in_Folder->setEnabled(enable && baka->mpv->getPath() != QString());
1136     ui->action_Full_Screen->setEnabled(enable);
1137     if(!enable)
1138     {
1139         ui->action_Hide_Album_Art->setEnabled(false);
1140         ui->menuSubtitle_Track->setEnabled(false);
1141         ui->menuFont_Si_ze->setEnabled(false);
1142     }
1143 }
1144 
HideAllControls(bool w,bool s)1145 void MainWindow::HideAllControls(bool w, bool s)
1146 {
1147     if(s)
1148     {
1149         hideAllControls = w;
1150         if(isFullScreen())
1151             return;
1152     }
1153     if(w)
1154     {
1155         if(s || !hideAllControls)
1156             playlistState = ui->playlistLayoutWidget->isVisible();
1157         ui->menubar->setVisible(false);
1158         setContextMenuPolicy(Qt::ActionsContextMenu);
1159         mouseMoveEvent(new QMouseEvent(QMouseEvent::MouseMove,
1160                                        QCursor::pos(),
1161                                        Qt::NoButton,Qt::NoButton,Qt::NoModifier));
1162     }
1163     else
1164     {
1165         if(menuVisible)
1166             ui->menubar->setVisible(true);
1167         ui->seekBar->setVisible(true);
1168         ui->playbackLayoutWidget->setVisible(true);
1169         setContextMenuPolicy(Qt::NoContextMenu);
1170         setCursor(QCursor(Qt::ArrowCursor)); // show cursor
1171         autohide->stop();
1172         ShowPlaylist(playlistState);
1173     }
1174 }
1175 
FullScreen(bool fs)1176 void MainWindow::FullScreen(bool fs)
1177 {
1178     if(fs)
1179     {
1180         if(baka->dimDialog && baka->dimDialog->isVisible())
1181             baka->Dim(false);
1182         setWindowState(windowState() | Qt::WindowFullScreen);
1183         if(!hideAllControls)
1184             HideAllControls(true, false);
1185     }
1186     else
1187     {
1188         setWindowState(windowState() & ~Qt::WindowFullScreen);
1189         if(!hideAllControls)
1190             HideAllControls(false, false);
1191     }
1192 }
1193 
isPlaylistVisible()1194 bool MainWindow::isPlaylistVisible()
1195 {
1196     // if the position is 0, playlist is hidden
1197     return (ui->splitter->position() != 0);
1198 }
1199 
TogglePlaylist()1200 void MainWindow::TogglePlaylist()
1201 {
1202     ShowPlaylist(!isPlaylistVisible());
1203 }
1204 
ShowPlaylist(bool visible)1205 void MainWindow::ShowPlaylist(bool visible)
1206 {
1207     if(ui->splitter->position() != 0 && visible) // ignore showing if it's already visible as it resets original position
1208         return;
1209 
1210     if(visible)
1211         ui->splitter->setPosition(ui->splitter->normalPosition()); // bring splitter position to normal
1212     else
1213     {
1214         if(ui->splitter->position() != ui->splitter->max() && ui->splitter->position() != 0)
1215             ui->splitter->setNormalPosition(ui->splitter->position()); // save current splitter position as the normal position
1216         ui->splitter->setPosition(0); // set splitter position to right-most
1217         setFocus();
1218     }
1219 }
1220 
HideAlbumArt(bool hide)1221 void MainWindow::HideAlbumArt(bool hide)
1222 {
1223     if(hide)
1224     {
1225         if(ui->splitter->position() != ui->splitter->max() && ui->splitter->position() != 0)
1226             ui->splitter->setNormalPosition(ui->splitter->position()); // save splitter position as the normal position
1227         ui->splitter->setPosition(ui->splitter->max()); // bring the splitter position to the left-most
1228     }
1229     else
1230         ui->splitter->setPosition(ui->splitter->normalPosition()); // bring the splitter to normal position
1231 }
1232 
UpdateRecentFiles()1233 void MainWindow::UpdateRecentFiles()
1234 {
1235     ui->menu_Recently_Opened->clear();
1236     QAction *action;
1237     int n = 1,
1238         N = recent.length();
1239     for(auto &f : recent)
1240     {
1241         action = ui->menu_Recently_Opened->addAction(QString("%0. %1").arg(Util::FormatNumberWithAmpersand(n, N), Util::ShortenPathToParent(f).replace("&","&&")));
1242         if(n++ == 1)
1243             action->setShortcut(QKeySequence("Ctrl+Z"));
1244         connect(action, &QAction::triggered,
1245                 [=]
1246                 {
1247                     mpv->LoadFile(f);
1248                 });
1249     }
1250 }
1251 
SetNextButtonEnabled(bool enable)1252 void MainWindow::SetNextButtonEnabled(bool enable)
1253 {
1254     ui->nextButton->setEnabled(enable);
1255     ui->actionPlay_Next_File->setEnabled(enable);
1256 #if defined(Q_OS_WIN)
1257     next_toolbutton->setEnabled(enable);
1258 #endif
1259 }
1260 
SetPreviousButtonEnabled(bool enable)1261 void MainWindow::SetPreviousButtonEnabled(bool enable)
1262 {
1263     ui->previousButton->setEnabled(enable);
1264     ui->actionPlay_Previous_File->setEnabled(enable);
1265 #if defined(Q_OS_WIN)
1266     prev_toolbutton->setEnabled(enable);
1267 #endif
1268 }
1269 
SetPlayButtonIcon(bool play)1270 void MainWindow::SetPlayButtonIcon(bool play)
1271 {
1272     if(play)
1273     {
1274         ui->playButton->setIcon(QIcon(":/img/default_play.svg"));
1275         ui->action_Play->setText(tr("&Play"));
1276 #if defined(Q_OS_WIN)
1277         playpause_toolbutton->setToolTip(tr("Play"));
1278         playpause_toolbutton->setIcon(QIcon(":/img/tool-play.ico"));
1279 #endif
1280     }
1281     else // pause icon
1282     {
1283         ui->playButton->setIcon(QIcon(":/img/default_pause.svg"));
1284         ui->action_Play->setText(tr("&Pause"));
1285 #if defined(Q_OS_WIN)
1286         playpause_toolbutton->setToolTip(tr("Pause"));
1287         playpause_toolbutton->setIcon(QIcon(":/img/tool-pause.ico"));
1288 #endif
1289     }
1290 }
1291 
SetRemainingLabels(int time)1292 void MainWindow::SetRemainingLabels(int time)
1293 {
1294     // todo: move setVisible functions outside of this function which gets called every second and somewhere at the start of a video
1295     const Mpv::FileInfo &fi = mpv->getFileInfo();
1296     if(fi.length == 0)
1297     {
1298         ui->durationLabel->setText(Util::FormatTime(time, time));
1299         ui->remainingLabel->setVisible(false);
1300         ui->seperatorLabel->setVisible(false);
1301     }
1302     else
1303     {
1304         ui->remainingLabel->setVisible(true);
1305         ui->seperatorLabel->setVisible(true);
1306 
1307         ui->durationLabel->setText(Util::FormatTime(time, fi.length));
1308         if(remaining)
1309         {
1310             int remainingTime = fi.length - time;
1311             QString text = "-" + Util::FormatTime(remainingTime, fi.length);
1312             if(mpv->getSpeed() != 1)
1313             {
1314                 double speed = mpv->getSpeed();
1315                 text += QString("  (-%0)").arg(Util::FormatTime(int(remainingTime/speed), int(fi.length/speed)));
1316             }
1317             ui->remainingLabel->setText(text);
1318         }
1319         else
1320         {
1321             QString text = Util::FormatTime(fi.length, fi.length);
1322             if(mpv->getSpeed() != 1)
1323             {
1324                 double speed = mpv->getSpeed();
1325                 text += QString("  (%0)").arg(Util::FormatTime(int(fi.length/speed), int(fi.length/speed)));
1326             }
1327             ui->remainingLabel->setText(text);
1328         }
1329     }
1330 }
1331