File indexing completed on 2024-04-21 04:54:05

0001 /*
0002     SPDX-FileCopyrightText: 2005 Koos Vriezen <koos ! vriezen ? gmail ! com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include <QIcon>
0008 #include <QLayout>
0009 #include <QPixmap>
0010 #include <QSlider>
0011 #include <QLabel>
0012 #include <QPainter>
0013 #include <QStringList>
0014 #include <QCursor>
0015 #include <QPalette>
0016 #include <QSlider>
0017 #include <QLabel>
0018 #include <QWheelEvent>
0019 #include <QWidgetAction>
0020 
0021 #include <KIconLoader>
0022 #include <KLocalizedString>
0023 
0024 #include "kmplayercommon_log.h"
0025 #include "kmplayerview.h"
0026 #include "kmplayercontrolpanel.h"
0027 
0028 static const int button_height_with_slider = 16;
0029 static const int button_height_only_buttons = 16;
0030 static float dpi_scale = 1.0;
0031 #include "kmplayerview.h"
0032 #include "kmplayercontrolpanel.h"
0033 
0034 using namespace KMPlayer;
0035 
0036 static char xpm_fg_color [32] = ".      c #000000";
0037 
0038 static const char * stop_xpm[] = {
0039     "5 7 2 1",
0040     "       c None",
0041     xpm_fg_color,
0042     "     ",
0043     ".....",
0044     ".....",
0045     ".....",
0046     ".....",
0047     ".....",
0048     "     "};
0049 
0050 static const char * play_xpm[] = {
0051     "5 9 2 1",
0052     "       c None",
0053     xpm_fg_color,
0054     ".    ",
0055     "..   ",
0056     "...  ",
0057     ".... ",
0058     ".....",
0059     ".... ",
0060     "...  ",
0061     "..   ",
0062     ".    "};
0063 
0064 static const char * pause_xpm[] = {
0065     "7 9 2 1",
0066     "       c None",
0067     xpm_fg_color,
0068     "       ",
0069     "..   ..",
0070     "..   ..",
0071     "..   ..",
0072     "..   ..",
0073     "..   ..",
0074     "..   ..",
0075     "..   ..",
0076     "       "};
0077 
0078 static const char * forward_xpm[] = {
0079     "11 9 2 1",
0080     "       c None",
0081     xpm_fg_color,
0082     ".     .    ",
0083     "..    ..   ",
0084     "...   ...  ",
0085     "....  .... ",
0086     "..... .....",
0087     "....  .... ",
0088     "...   ...  ",
0089     "..    ..   ",
0090     ".     .    "};
0091 
0092 static const char * back_xpm[] = {
0093     "11 9 2 1",
0094     "       c None",
0095     xpm_fg_color,
0096     "    .     .",
0097     "   ..    ..",
0098     "  ...   ...",
0099     " ....  ....",
0100     "..... .....",
0101     " ....  ....",
0102     "  ...   ...",
0103     "   ..    ..",
0104     "    .     ."};
0105 
0106 static const char * config_xpm[] = {
0107     "11 8 2 1",
0108     "       c None",
0109     xpm_fg_color,
0110     "           ",
0111     "           ",
0112     "...........",
0113     " ......... ",
0114     "  .......  ",
0115     "   .....   ",
0116     "    ...    ",
0117     "     .     "};
0118 
0119 static const char *playlist_xpm[] = {
0120     "8 9 2 1",
0121     "       c None",
0122     xpm_fg_color,
0123     "        ",
0124     "        ",
0125     "........",
0126     "........",
0127     "        ",
0128     "        ",
0129     "........",
0130     "........",
0131     "        "};
0132 
0133 static const char *normal_window_xpm[] = {
0134     "7 9 2 1",
0135     "       c None",
0136     xpm_fg_color,
0137     "       ",
0138     ".......",
0139     ".......",
0140     ".     .",
0141     ".     .",
0142     ".     .",
0143     ".     .",
0144     ".......",
0145     "       "};
0146 
0147 static const char * record_xpm[] = {
0148     "7 7 3 1",
0149     "       c None",
0150     xpm_fg_color,
0151     "+      c #FF0000",
0152     "       ",
0153     ".......",
0154     ".+++++.",
0155     ".+++++.",
0156     ".+++++.",
0157     ".......",
0158     "       "};
0159 
0160 static const char * broadcast_xpm[] = {
0161 "21 9 2 1",
0162 "       c None",
0163 xpm_fg_color,
0164 "                     ",
0165 " ..  ..       ..  .. ",
0166 "..  ..   ...   ..  ..",
0167 "..  ..  .....  ..  ..",
0168 "..  ..  .....  ..  ..",
0169 "..  ..  .....  ..  ..",
0170 "..  ..   ...   ..  ..",
0171 " ..  ..       ..  .. ",
0172 "                     "};
0173 
0174 static const char * language_xpm [] = {
0175     "12 9 2 1",
0176     "       c None",
0177     xpm_fg_color,
0178     "            ",
0179     "            ",
0180     "            ",
0181     "            ",
0182     "            ",
0183     "....  ......",
0184     "....  ......",
0185     "....  ......",
0186     "            "};
0187 
0188 static const char * red_xpm[] = {
0189     "7 9 3 1",
0190     "       c None",
0191     xpm_fg_color,
0192     "+      c #FF0000",
0193     "       ",
0194     ".......",
0195     ".+++++.",
0196     ".+++++.",
0197     ".+++++.",
0198     ".+++++.",
0199     ".+++++.",
0200     ".......",
0201     "       "};
0202 
0203 static const char * green_xpm[] = {
0204     "7 9 3 1",
0205     "       c None",
0206     xpm_fg_color,
0207     "+      c #00FF00",
0208     "       ",
0209     ".......",
0210     ".+++++.",
0211     ".+++++.",
0212     ".+++++.",
0213     ".+++++.",
0214     ".+++++.",
0215     ".......",
0216     "       "};
0217 
0218 static const char * yellow_xpm[] = {
0219     "7 9 3 1",
0220     "       c None",
0221     xpm_fg_color,
0222     "+      c #FFFF00",
0223     "       ",
0224     ".......",
0225     ".+++++.",
0226     ".+++++.",
0227     ".+++++.",
0228     ".+++++.",
0229     ".+++++.",
0230     ".......",
0231     "       "};
0232 
0233 static const char * blue_xpm[] = {
0234     "7 9 3 1",
0235     "       c None",
0236     xpm_fg_color,
0237     "+      c #0080FF00",
0238     "       ",
0239     ".......",
0240     ".+++++.",
0241     ".+++++.",
0242     ".+++++.",
0243     ".+++++.",
0244     ".+++++.",
0245     ".......",
0246     "       "};
0247 
0248 //-----------------------------------------------------------------------------
0249 
0250 static QIcon makeIcon(const char** xpm) {
0251     QPixmap pix(xpm);
0252     if (dpi_scale > 1.01)
0253         pix = pix.scaledToHeight(pix.height() * dpi_scale, Qt::SmoothTransformation);
0254     return QIcon(pix);
0255 }
0256 
0257 static QPushButton *ctrlButton(QBoxLayout* l, const char **p, int key = 0) {
0258     QPushButton* b = new QPushButton(makeIcon(p), QString());
0259     b->setFocusPolicy (Qt::NoFocus);
0260     b->setFlat (true);
0261     b->setAutoFillBackground (true);
0262     if (key)
0263         b->setShortcut (QKeySequence (key));
0264     l->addWidget (b);
0265     return b;
0266 }
0267 
0268 KMPlayerMenuButton::KMPlayerMenuButton(QWidget*, QBoxLayout * l, const char ** p, int key)
0269  : QPushButton(makeIcon(p), QString()) {
0270     setFocusPolicy (Qt::NoFocus);
0271     setFlat (true);
0272     setAutoFillBackground (true);
0273     if (key)
0274         setShortcut (QKeySequence (key));
0275     l->addWidget (this);
0276 }
0277 
0278 void KMPlayerMenuButton::enterEvent (QEvent *) {
0279     Q_EMIT mouseEntered ();
0280 }
0281 
0282 //-----------------------------------------------------------------------------
0283 
0284 KMPlayerPopupMenu::KMPlayerPopupMenu (QWidget *parent, const QString &title)
0285  : QMenu(title, parent) {}
0286 
0287 void KMPlayerPopupMenu::leaveEvent (QEvent *) {
0288     Q_EMIT mouseLeft ();
0289 }
0290 
0291 //-----------------------------------------------------------------------------
0292 
0293 VolumeBar::VolumeBar(QWidget*, View * view)
0294  : m_view(view), m_value(100) {
0295     setSizePolicy( QSizePolicy (QSizePolicy::Minimum, QSizePolicy::Fixed));
0296     setMinimumSize (QSize (51, button_height_only_buttons + 2));
0297     setToolTip (i18n ("Volume is ") + QString::number (m_value));
0298     setAutoFillBackground (true);
0299     QPalette palette;
0300     palette.setColor (backgroundRole (), m_view->palette ().color (QPalette::Background));
0301     setPalette (palette);
0302 }
0303 
0304 VolumeBar::~VolumeBar () {
0305 }
0306 
0307 void VolumeBar::setValue (int v) {
0308     m_value = v;
0309     if (m_value < 0) m_value = 0;
0310     if (m_value > 100) m_value = 100;
0311     setToolTip (i18n ("Volume is ") + QString::number (m_value));
0312     repaint ();
0313     Q_EMIT volumeChanged (m_value);
0314 }
0315 
0316 void VolumeBar::wheelEvent (QWheelEvent * e) {
0317     setValue (m_value + (e->delta () > 0 ? 2 : -2));
0318     e->accept ();
0319 }
0320 
0321 void VolumeBar::paintEvent (QPaintEvent * e) {
0322     QWidget::paintEvent (e);
0323     QPainter p;
0324     p.begin (this);
0325     QColor color = palette ().color (foregroundRole ());
0326     p.setPen (color);
0327     int w = width () - 6 * dpi_scale;
0328     int vx = m_value * w / 100;
0329     p.fillRect (3 * dpi_scale, 3 * dpi_scale, vx, 7 * dpi_scale, color);
0330     p.drawRect (vx + 3 * dpi_scale, 3 * dpi_scale, w - vx, 7 * dpi_scale);
0331     p.end ();
0332     //qCDebug(LOG_KMPLAYER_COMMON) << "w=" << w << " vx=" << vx;
0333 }
0334 
0335 void VolumeBar::mousePressEvent (QMouseEvent * e) {
0336     setValue (100 * (e->x () - 3 * dpi_scale) / (width () - 6 * dpi_scale));
0337     e->accept ();
0338 }
0339 
0340 void VolumeBar::mouseMoveEvent (QMouseEvent * e) {
0341     setValue (100 * (e->x () - 3 * dpi_scale) / (width () - 6 * dpi_scale));
0342     e->accept ();
0343 }
0344 
0345 //-----------------------------------------------------------------------------
0346 
0347 ControlPanel::ControlPanel(QWidget * parent, View * view)
0348  : QWidget (parent),
0349    m_progress_mode (progress_playing),
0350    m_progress_length (0),
0351    m_popup_timer (0),
0352    m_popdown_timer (0),
0353    m_view (view),
0354    m_auto_controls (true),
0355    m_popup_clicked (false) {
0356     setAttribute (Qt::WA_NativeWindow);
0357     setAttribute(Qt::WA_DontCreateNativeAncestors);
0358     dpi_scale = qMax(1.0, logicalDpiX() / 120.0);
0359     m_buttonbox = new QHBoxLayout (this);
0360     m_buttonbox->setSpacing (4 * dpi_scale);
0361     m_buttonbox->setContentsMargins (5 * dpi_scale, 5 * dpi_scale, 5 * dpi_scale, 5 * dpi_scale);
0362     setAutoFillBackground (true);
0363     QColor c = palette ().color (foregroundRole ());
0364     strncpy (xpm_fg_color, QString::asprintf(".      c #%02x%02x%02x", c.red(), c.green(),c.blue()).toLatin1().constData(), 31);
0365     xpm_fg_color[31] = 0;
0366     m_buttons[button_config] = new KMPlayerMenuButton (this, m_buttonbox, config_xpm);
0367     m_buttons[button_playlist] = ctrlButton(m_buttonbox, playlist_xpm);
0368     m_buttons[button_back] = ctrlButton(m_buttonbox, back_xpm);
0369     m_buttons[button_play] = ctrlButton(m_buttonbox, play_xpm, Qt::Key_R);
0370     m_buttons[button_forward] = ctrlButton(m_buttonbox, forward_xpm);
0371     m_buttons[button_stop] = ctrlButton(m_buttonbox, stop_xpm, Qt::Key_S);
0372     m_buttons[button_pause]=ctrlButton(m_buttonbox, pause_xpm, Qt::Key_P);
0373     m_buttons[button_record] = ctrlButton(m_buttonbox, record_xpm);
0374     m_buttons[button_broadcast] = ctrlButton(m_buttonbox, broadcast_xpm);
0375     m_buttons[button_language] = new KMPlayerMenuButton (this, m_buttonbox, language_xpm);
0376     m_buttons[button_red] = ctrlButton(m_buttonbox, red_xpm);
0377     m_buttons[button_green] = ctrlButton(m_buttonbox, green_xpm);
0378     m_buttons[button_yellow] = ctrlButton(m_buttonbox, yellow_xpm);
0379     m_buttons[button_blue] = ctrlButton(m_buttonbox, blue_xpm);
0380     m_buttons[button_play]->setCheckable (true);
0381     m_buttons[button_stop]->setCheckable (true);
0382     m_buttons[button_record]->setCheckable (true);
0383     m_buttons[button_broadcast]->setCheckable (true);
0384     m_posSlider = new QSlider;
0385     m_posSlider->setOrientation (Qt::Horizontal);
0386     m_posSlider->setMaximum (100);
0387     m_posSlider->setPageStep (1);
0388     m_posSlider->setEnabled (false);
0389     m_buttonbox->addWidget (m_posSlider);
0390     setupPositionSlider (true);
0391     m_volume = new VolumeBar (this, m_view);
0392     m_buttonbox->addWidget (m_volume);
0393 
0394     popupMenu = new KMPlayerPopupMenu (this, QString ());
0395 
0396     playerMenu = new KMPlayerPopupMenu (this, i18n ("&Play with"));
0397     playersAction = popupMenu->addMenu (playerMenu);
0398 
0399     videoConsoleAction = popupMenu->addAction(QIcon::fromTheme("utilities-terminal"), i18n("Con&sole"));
0400 
0401     playlistAction = popupMenu->addAction(QIcon::fromTheme("view-media-playlist"), i18n("Play&list"));
0402 
0403     zoomMenu = new KMPlayerPopupMenu (this, i18n ("&Zoom"));
0404     zoomAction = popupMenu->addMenu (zoomMenu);
0405     zoomAction->setIcon(QIcon::fromTheme("zoom-fit-best"));
0406     zoom50Action = zoomMenu->addAction (i18n ("50%"));
0407     zoom100Action = zoomMenu->addAction (i18n ("100%"));
0408     zoom150Action = zoomMenu->addAction (i18n ("150%"));
0409 
0410     fullscreenAction = popupMenu->addAction(QIcon::fromTheme("view-fullscreen"), i18n("&Full Screen"));
0411     fullscreenAction->setShortcut (QKeySequence (Qt::Key_F));
0412 
0413     popupMenu->addSeparator ();
0414 
0415     colorMenu = new KMPlayerPopupMenu (this, i18n ("Co&lors"));
0416     colorAction = popupMenu->addMenu (colorMenu);
0417     colorAction->setIcon(QIcon::fromTheme("format-fill-color"));
0418     /*QLabel * label = new QLabel (i18n ("Contrast:"), colorMenu);
0419     colorMenu->insertItem (label);
0420     m_contrastSlider = new QSlider (-100, 100, 10, 0, Qt::Horizontal, colorMenu);
0421     colorMenu->insertItem (m_contrastSlider);
0422     label = new QLabel (i18n ("Brightness:"), colorMenu);
0423     colorMenu->insertItem (label);
0424     m_brightnessSlider = new QSlider (-100, 100, 10, 0, Qt::Horizontal, colorMenu);
0425     colorMenu->insertItem (m_brightnessSlider);
0426     label = new QLabel (i18n ("Hue:"), colorMenu);
0427     colorMenu->insertItem (label);
0428     m_hueSlider = new QSlider (-100, 100, 10, 0, Qt::Horizontal, colorMenu);
0429     colorMenu->insertItem (m_hueSlider);
0430     label = new QLabel (i18n ("Saturation:"), colorMenu);
0431     colorMenu->insertItem (label);
0432     m_saturationSlider = new QSlider (-100, 100, 10, 0, Qt::Horizontal, colorMenu);
0433     colorMenu->insertItem (m_saturationSlider);*/
0434     colorAction->setVisible (false);
0435 
0436     bookmarkMenu = new KMPlayerPopupMenu (this, i18n("&Bookmarks"));
0437     bookmarkAction = popupMenu->addMenu (bookmarkMenu);
0438     bookmarkAction->setVisible (false);
0439 
0440     languageMenu = new KMPlayerPopupMenu (this, i18n ("&Audio languages"));
0441     languageAction = popupMenu->addMenu (languageMenu);
0442     audioMenu = new KMPlayerPopupMenu (this, i18n ("&Audio languages"));
0443     subtitleMenu = new KMPlayerPopupMenu (this, i18n ("&Subtitles"));
0444     QAction *audioAction = languageMenu->addMenu (audioMenu);
0445     QAction *subtitleAction = languageMenu->addMenu (subtitleMenu);
0446     audioAction->setIcon(QIcon::fromTheme("audio-x-generic"));
0447     subtitleAction->setIcon(QIcon::fromTheme("view-list-text"));
0448     languageAction->setVisible (false);
0449 
0450     scaleLabelAction = new QWidgetAction (popupMenu);
0451     scaleLabelAction->setDefaultWidget (new QLabel (i18n ("Scale:")));
0452     popupMenu->addAction (scaleLabelAction);
0453     scaleAction = new QWidgetAction (popupMenu);
0454     scale_slider = new QSlider;
0455     scale_slider->setOrientation (Qt::Horizontal);
0456     scale_slider->setMinimum (50);
0457     scale_slider->setMaximum (150);
0458     scale_slider->setPageStep (10);
0459     scale_slider->setSliderPosition (100);
0460     scaleAction->setDefaultWidget (scale_slider);
0461     popupMenu->addAction (scaleAction);
0462 
0463     configureAction = popupMenu->addAction(QIcon::fromTheme("configure"), i18n("&Configure KMPlayer..."));
0464 
0465     QPalette pal = palette ();
0466     pal.setColor(backgroundRole(), view->palette().color(QPalette::Background));
0467     setPalette (pal);
0468     setAutoControls (true);
0469     connect (m_buttons [button_config], &QPushButton::clicked,
0470             this, &ControlPanel::buttonClicked);
0471     connect (m_buttons [button_language], &QPushButton::clicked,
0472             this, &ControlPanel::buttonClicked);
0473     connect (qobject_cast<KMPlayerMenuButton*>(m_buttons [button_config]), &KMPlayerMenuButton::mouseEntered,
0474              this, &ControlPanel::buttonMouseEntered);
0475     connect (qobject_cast<KMPlayerMenuButton*>(m_buttons [button_language]), &KMPlayerMenuButton::mouseEntered,
0476              this, &ControlPanel::buttonMouseEntered);
0477     connect (popupMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0478     connect (playerMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0479     connect (zoomMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0480     connect (colorMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0481     connect (languageMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0482     connect (subtitleMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0483     connect (audioMenu, &KMPlayerPopupMenu::mouseLeft, this, &ControlPanel::menuMouseLeft);
0484 }
0485 
0486 void ControlPanel::setPalette (const QPalette & pal) {
0487     QWidget::setPalette (pal);
0488     QColor c = palette ().color (foregroundRole ());
0489     if (c == Qt::black)
0490         return;
0491     strncpy (xpm_fg_color, QString::asprintf(".      c #%02x%02x%02x", c.red(), c.green(),c.blue()).toLatin1().constData(), 31);
0492     xpm_fg_color[31] = 0;
0493     m_buttons[button_config]->setIcon(makeIcon(config_xpm));
0494     m_buttons[button_playlist]->setIcon(makeIcon(playlist_xpm));
0495     m_buttons[button_back]->setIcon(makeIcon(back_xpm));
0496     m_buttons[button_play]->setIcon(makeIcon(play_xpm));
0497     m_buttons[button_forward]->setIcon(makeIcon(forward_xpm));
0498     m_buttons[button_stop]->setIcon(makeIcon(stop_xpm));
0499     m_buttons[button_pause]->setIcon(makeIcon(pause_xpm));
0500     m_buttons[button_record]->setIcon(makeIcon(record_xpm));
0501     m_buttons[button_broadcast]->setIcon(makeIcon(broadcast_xpm));
0502     m_buttons[button_language]->setIcon(makeIcon(language_xpm));
0503     m_buttons[button_red]->setIcon(makeIcon(red_xpm));
0504     m_buttons[button_green]->setIcon(makeIcon(green_xpm));
0505     m_buttons[button_yellow]->setIcon(makeIcon(yellow_xpm));
0506     m_buttons[button_blue]->setIcon(makeIcon(blue_xpm));
0507 }
0508 
0509 void ControlPanel::timerEvent (QTimerEvent * e) {
0510     if (e->timerId () == m_popup_timer) {
0511         m_popup_timer = 0;
0512         if (m_button_monitored == button_config) {
0513             if (m_buttons [button_config]->testAttribute(Qt::WA_UnderMouse) &&
0514                     !popupMenu->isVisible ())
0515                 showPopupMenu ();
0516         } else if (m_buttons [button_language]->testAttribute(Qt::WA_UnderMouse) &&
0517                     !languageMenu->isVisible ()) {
0518             showLanguageMenu ();
0519         }
0520     } else if (e->timerId () == m_popdown_timer) {
0521         m_popdown_timer = 0;
0522         QPoint mpos = QCursor::pos();
0523 #define HAS_MOUSE(menu) ((menu)->isVisible() && (menu)->rect().contains((menu)->mapFromGlobal(mpos)))
0524         if (popupMenu->isVisible () &&
0525                 !popupMenu->underMouse() &&
0526                 !HAS_MOUSE(playerMenu) &&
0527                 !HAS_MOUSE(zoomMenu) &&
0528                 !HAS_MOUSE(colorMenu) &&
0529                 !HAS_MOUSE(bookmarkMenu)) {
0530             if (!(bookmarkMenu->isVisible () &&
0531                         static_cast <QWidget *> (bookmarkMenu) != QWidget::keyboardGrabber ())) {
0532                 // not if user entered the bookmark sub menu or if I forgot one
0533                 popupMenu->hide ();
0534                 if (m_buttons [button_config]->isChecked ())
0535                     m_buttons [button_config]->toggle ();
0536             }
0537         } else if (languageMenu->isVisible () &&
0538                 !HAS_MOUSE(languageMenu) &&
0539                 !HAS_MOUSE(audioMenu) &&
0540                 !HAS_MOUSE(subtitleMenu)) {
0541             languageMenu->hide ();
0542             if (m_buttons [button_language]->isChecked ())
0543                 m_buttons [button_language]->toggle ();
0544         }
0545 #undef HAS_MOUSE
0546     }
0547     killTimer (e->timerId ());
0548 }
0549 
0550 void ControlPanel::setAutoControls (bool b) {
0551     m_auto_controls = b;
0552     if (m_auto_controls) {
0553         for (int i = 0; i < (int) button_broadcast; i++)
0554             m_buttons [i]->show ();
0555         for (int i = button_broadcast; i < (int) button_last; i++)
0556             m_buttons [i]->hide ();
0557         showPositionSlider (false);
0558         m_volume->show ();
0559         if (m_buttons [button_broadcast]->isChecked ()) // still broadcasting
0560             m_buttons [button_broadcast]->show ();
0561     } else { // hide everything
0562         for (int i = 0; i < (int) button_last; i++)
0563             m_buttons [i]->hide ();
0564         m_posSlider->hide ();
0565         m_volume->hide ();
0566     }
0567     m_view->updateLayout ();
0568 }
0569 
0570 void ControlPanel::showPopupMenu () {
0571     popupMenu->exec (m_buttons [button_config]->mapToGlobal (QPoint (0, maximumSize ().height ())));
0572 }
0573 
0574 void ControlPanel::showLanguageMenu () {
0575     languageMenu->exec (m_buttons [button_language]->mapToGlobal (QPoint (0, maximumSize ().height ())));
0576 }
0577 
0578 void ControlPanel::showPositionSlider (bool show) {
0579     if (!m_auto_controls || show == m_posSlider->isVisible ())
0580         return;
0581     setupPositionSlider (show);
0582     if (isVisible ())
0583         m_view->updateLayout ();
0584 }
0585 
0586 void ControlPanel::setupPositionSlider (bool show) {
0587     int h = show ? button_height_with_slider : button_height_only_buttons;
0588     m_posSlider->setEnabled (false);
0589     m_posSlider->setValue (0);
0590     m_posSlider->setVisible (show);
0591     for (int i = 0; i < (int) button_last; i++) {
0592         m_buttons[i]->setMinimumSize (15 * dpi_scale, (h-1) * dpi_scale);
0593         m_buttons[i]->setMaximumHeight(h * dpi_scale);
0594     }
0595     setMaximumHeight((h + 6) * dpi_scale);
0596 }
0597 
0598 int ControlPanel::preferredHeight () {
0599     return dpi_scale * (m_posSlider->isVisible () ?
0600             button_height_with_slider + 8 : button_height_only_buttons + 2);
0601 }
0602 
0603 void ControlPanel::enableSeekButtons (bool enable) {
0604     if (!m_auto_controls) return;
0605     if (enable) {
0606         m_buttons[button_back]->show ();
0607         m_buttons[button_forward]->show ();
0608     } else {
0609         m_buttons[button_back]->hide ();
0610         m_buttons[button_forward]->hide ();
0611     }
0612 }
0613 
0614 void ControlPanel::enableRecordButtons (bool enable) {
0615     if (!m_auto_controls) return;
0616     if (enable)
0617         m_buttons[button_record]->show ();
0618     else
0619         m_buttons[button_record]->hide ();
0620 }
0621 
0622 void ControlPanel::enableFullscreenButton(bool enable) {
0623     m_buttons[button_playlist]->setIcon(makeIcon(enable ? normal_window_xpm : playlist_xpm));
0624 }
0625 
0626 void ControlPanel::setPlaying (bool play) {
0627     if (play != m_buttons[button_play]->isChecked ())
0628         m_buttons[button_play]->toggle ();
0629     m_posSlider->setEnabled (false);
0630     m_posSlider->setValue (0);
0631     if (!play) {
0632         showPositionSlider (false);
0633         enableSeekButtons (true);
0634     }
0635 }
0636 
0637 void ControlPanel::setRecording (bool record) {
0638     if (record != m_buttons[button_record]->isChecked ())
0639         m_buttons[button_record]->toggle ();
0640 }
0641 
0642 void ControlPanel::setPlayingProgress (int pos, int len) {
0643     m_posSlider->setEnabled (false);
0644     m_progress_length = len;
0645     showPositionSlider (len > 0);
0646     if (m_progress_mode != progress_playing) {
0647         m_posSlider->setMaximum (m_progress_length);
0648         m_progress_mode = progress_playing;
0649     }
0650     if (pos < len && len > 0 && len != m_posSlider->maximum ())
0651         m_posSlider->setMaximum (m_progress_length);
0652     else if (m_progress_length <= 0 && pos > 7 * m_posSlider->maximum ()/8)
0653         m_posSlider->setMaximum (m_posSlider->maximum() * 2);
0654     else if (m_posSlider->maximum() < pos)
0655         m_posSlider->setMaximum (int (1.4 * m_posSlider->maximum()));
0656     m_posSlider->setValue (pos);
0657     m_posSlider->setEnabled (true);
0658 }
0659 
0660 void ControlPanel::setLoadingProgress (int pos) {
0661     if (pos > 0 && pos < 100 && !m_posSlider->isVisible ())
0662         showPositionSlider (true);
0663     else if (pos >= 100 && m_posSlider->isVisible ())
0664         showPositionSlider (false);
0665     m_posSlider->setEnabled (false);
0666     if (m_progress_mode != progress_loading) {
0667         m_posSlider->setMaximum (100);
0668         m_progress_mode = progress_loading;
0669     }
0670     m_posSlider->setValue (pos);
0671 }
0672 
0673 void ControlPanel::buttonClicked () {
0674     if (m_popup_timer) {
0675         killTimer (m_popup_timer);
0676         m_popup_timer = 0;
0677     }
0678     m_popup_clicked = true;
0679     if (sender () == m_buttons [button_language])
0680         showLanguageMenu ();
0681     else
0682         showPopupMenu ();
0683 }
0684 
0685 void ControlPanel::buttonMouseEntered () {
0686     if (!m_popup_timer) {
0687         if (sender () == m_buttons [button_config]) {
0688             if (!popupMenu->isVisible ()) {
0689                 m_button_monitored = button_config;
0690                 m_popup_clicked = false;
0691                 m_popup_timer = startTimer (400);
0692             }
0693         } else if (!languageMenu->isVisible ()) {
0694             m_button_monitored = button_language;
0695             m_popup_clicked = false;
0696             m_popup_timer = startTimer (400);
0697         }
0698     }
0699 }
0700 
0701 void ControlPanel::menuMouseLeft () {
0702     if (!m_popdown_timer && !m_popup_clicked)
0703         m_popdown_timer = startTimer (400);
0704 }
0705 
0706 void ControlPanel::setLanguages (const QStringList & alang, const QStringList & slang) {
0707     int sz = (int) alang.size ();
0708     bool showbutton = (sz > 0);
0709     audioMenu->clear ();
0710     for (int i = 0; i < sz; i++)
0711         audioMenu->addAction (alang [i])->setCheckable(true);
0712     sz = (int) slang.size ();
0713     showbutton |= (sz > 0);
0714     subtitleMenu->clear ();
0715     for (int i = 0; i < sz; i++)
0716         subtitleMenu->addAction (slang [i])->setCheckable(true);
0717     if (showbutton)
0718         m_buttons [button_language]->show ();
0719     else
0720         m_buttons [button_language]->hide ();
0721 }
0722 
0723 void ControlPanel::actionToggled (QAction* act) {
0724     if (act->isChecked ())
0725         return;
0726     int size = act->parentWidget()->actions().count();
0727     for (int i = 0; i < size; i++)
0728         if (act->parentWidget()->actions().at(i)->isChecked ()) {
0729             act->parentWidget()->actions().at(i)->setChecked (false);
0730             break;
0731         }
0732     act->setChecked (true);
0733 }
0734 
0735 //-----------------------------------------------------------------------------
0736 
0737 #include "moc_kmplayercontrolpanel.cpp"