]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/util/customwidgets.cpp
Qt: respect font sizes
[vlc] / modules / gui / qt4 / util / customwidgets.cpp
index e77171de2e3cc62a94c7779368611703a27da521..26e808f9411ce2a88a5de19f02a21547dbc723d7 100644 (file)
@@ -3,7 +3,7 @@
  ****************************************************************************
  * Copyright (C) 2006 the VideoLAN team
  * Copyright (C) 2004 Daniel Molkentin <molkentin@kde.org>
- * $Id: qvlcframe.hpp 16283 2006-08-17 18:16:09Z zorglub $
+ * $Id$
  *
  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
  * The "ClickLineEdit" control is based on code by  Daniel Molkentin
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #include "customwidgets.hpp"
-#include <QPainter>
-#include <QLineEdit>
+#include "qt4.hpp" /*needed for qtr and CONNECT, but not necessary */
+
 #include <QPainter>
 #include <QColorGroup>
 #include <QRect>
 #include <QKeyEvent>
 #include <QWheelEvent>
-
+#include <QHBoxLayout>
+#include <QStyle>
+#include <QStyleOption>
+#include <vlc_intf_strings.h>
 #include <vlc_keys.h>
+#include <wctype.h> /* twolower() */
 
 ClickLineEdit::ClickLineEdit( const QString &msg, QWidget *parent) : QLineEdit( parent )
 {
@@ -56,9 +65,9 @@ void ClickLineEdit::setText( const QString &txt )
 
 void ClickLineEdit::paintEvent( QPaintEvent *pe )
 {
-    QPainter p( this );
     QLineEdit::paintEvent( pe );
     if ( mDrawClickMsg == true && !hasFocus() ) {
+        QPainter p( this );
         QPen tmp = p.pen();
         p.setPen( palette().color( QPalette::Disabled, QPalette::Text ) );
         QRect cr = contentsRect();
@@ -66,6 +75,7 @@ void ClickLineEdit::paintEvent( QPaintEvent *pe )
         cr.setLeft( cr.left() + 3 );
         p.drawText( cr, Qt::AlignLeft | Qt::AlignVCenter, mClickMessage );
         p.setPen( tmp );
+        p.end();
     }
 }
 
@@ -75,7 +85,6 @@ void ClickLineEdit::dropEvent( QDropEvent *ev )
     QLineEdit::dropEvent( ev );
 }
 
-
 void ClickLineEdit::focusInEvent( QFocusEvent *ev )
 {
     if ( mDrawClickMsg == true ) {
@@ -85,7 +94,6 @@ void ClickLineEdit::focusInEvent( QFocusEvent *ev )
     QLineEdit::focusInEvent( ev );
 }
 
-
 void ClickLineEdit::focusOutEvent( QFocusEvent *ev )
 {
     if ( text().isEmpty() ) {
@@ -95,6 +103,130 @@ void ClickLineEdit::focusOutEvent( QFocusEvent *ev )
     QLineEdit::focusOutEvent( ev );
 }
 
+QVLCFramelessButton::QVLCFramelessButton( QWidget *parent )
+  : QPushButton( parent )
+{
+    setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
+}
+
+void QVLCFramelessButton::paintEvent( QPaintEvent * event )
+{
+    QPainter painter( this );
+    QPixmap pix = icon().pixmap( size() );
+    QPoint pos( (width() - pix.width()) / 2, (height() - pix.height()) / 2 );
+    painter.drawPixmap( QRect( pos.x(), pos.y(), pix.width(), pix.height() ), pix );
+}
+
+QSize QVLCFramelessButton::sizeHint() const
+{
+    return iconSize();
+}
+
+SearchLineEdit::SearchLineEdit( QWidget *parent ) : QLineEdit( parent )
+{
+    clearButton = new QVLCFramelessButton( this );
+    clearButton->setIcon( QIcon( ":/toolbar/clear" ) );
+    clearButton->setIconSize( QSize( 16, 16 ) );
+    clearButton->setCursor( Qt::ArrowCursor );
+    clearButton->setToolTip( qfu(vlc_pgettext("Tooltip|Clear", "Clear")) );
+    clearButton->hide();
+
+    CONNECT( clearButton, clicked(), this, clear() );
+
+    int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth, 0, this );
+
+    QFontMetrics metrics( font() );
+    QString styleSheet = QString( "min-height: %1px; "
+                                  "padding-top: 1px; "
+                                  "padding-bottom: 1px; "
+                                  "padding-right: %2px;" )
+                                  .arg( metrics.height() + ( 2 * frameWidth ) )
+                                  .arg( clearButton->sizeHint().width() + 1 );
+    setStyleSheet( styleSheet );
+
+    setMessageVisible( true );
+
+    CONNECT( this, textEdited( const QString& ),
+             this, updateText( const QString& ) );
+}
+
+void SearchLineEdit::clear()
+{
+    setText( QString() );
+    clearButton->hide();
+    setMessageVisible( true );
+}
+
+void SearchLineEdit::setMessageVisible( bool on )
+{
+    message = on;
+    repaint();
+    return;
+}
+
+void SearchLineEdit::updateText( const QString& text )
+{
+    clearButton->setVisible( !text.isEmpty() );
+}
+
+void SearchLineEdit::resizeEvent ( QResizeEvent * event )
+{
+  QLineEdit::resizeEvent( event );
+  int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this);
+  clearButton->resize( clearButton->sizeHint().width(), height() );
+  clearButton->move( width() - clearButton->width() - frameWidth, 0 );
+}
+
+void SearchLineEdit::focusInEvent( QFocusEvent *event )
+{
+  if( message )
+  {
+      setMessageVisible( false );
+  }
+  QLineEdit::focusInEvent( event );
+}
+
+void SearchLineEdit::focusOutEvent( QFocusEvent *event )
+{
+  if( text().isEmpty() )
+  {
+      setMessageVisible( true );
+  }
+  QLineEdit::focusOutEvent( event );
+}
+
+void SearchLineEdit::paintEvent( QPaintEvent *event )
+{
+  QLineEdit::paintEvent( event );
+  if( !message ) return;
+  QStyleOption option;
+  option.initFrom( this );
+  QRect rect = style()->subElementRect( QStyle::SE_LineEditContents, &option, this )
+                  .adjusted( 3, 0, clearButton->width() + 1, 0 );
+  QPainter painter( this );
+  painter.setPen( palette().color( QPalette::Disabled, QPalette::Text ) );
+  painter.drawText( rect, Qt::AlignLeft | Qt::AlignVCenter, qtr( I_PL_FILTER ) );
+}
+
+
+QVLCElidingLabel::QVLCElidingLabel( const QString &s, Qt::TextElideMode mode, QWidget * parent )
+  : elideMode( mode ), QLabel( s, parent )
+{ }
+
+void QVLCElidingLabel::setElideMode( Qt::TextElideMode mode )
+{
+    elideMode = mode;
+    repaint();
+}
+
+void QVLCElidingLabel::paintEvent( QPaintEvent * event )
+{
+    QPainter p( this );
+    int space = frameWidth() + margin();
+    QRect r = rect().adjusted( space, space, -space, -space );
+    p.drawText( r, fontMetrics().elidedText( text(), elideMode, r.width() ), alignment() );
+}
+
 /***************************************************************************
  * Hotkeys converters
  ***************************************************************************/
@@ -108,59 +240,167 @@ int qtKeyModifiersToVLC( QInputEvent* e )
     return i_keyModifiers;
 }
 
+typedef struct
+{
+    int      qt;
+    uint32_t vlc;
+} vlc_qt_key_t;
+
+static const vlc_qt_key_t keys[] =
+{
+    { Qt::Key_Escape,                KEY_ESC },
+    { Qt::Key_Tab,                   '\t', },
+    // Qt::Key_Backtab
+    { Qt::Key_Backspace,             '\b' },
+    { Qt::Key_Return,                '\r' },
+    { Qt::Key_Enter,                 '\r' }, // numeric pad
+    { Qt::Key_Insert,                KEY_INSERT },
+    { Qt::Key_Delete,                KEY_DELETE },
+    // Qt::Key_Pause
+    // Qt::Key_Print
+    // Qt::Key_SysReq
+    // Qt::Key_Clear
+    { Qt::Key_Home,                  KEY_HOME },
+    { Qt::Key_End,                   KEY_END },
+    { Qt::Key_Left,                  KEY_LEFT },
+    { Qt::Key_Up,                    KEY_UP },
+    { Qt::Key_Right,                 KEY_RIGHT },
+    { Qt::Key_Down,                  KEY_DOWN },
+    { Qt::Key_PageUp,                KEY_PAGEUP },
+    { Qt::Key_PageDown,              KEY_PAGEDOWN },
+    // Qt::Key_Shift
+    // Qt::Key_Control
+    // Qt::Key_Meta
+    // Qt::Key_Alt
+    // Qt::Key_CapsLock
+    // Qt::Key_NumLock
+    // Qt::Key_ScrollLock
+    /* F1 - F35 */
+    // Qt::Key_Super_L
+    // Qt::Key_Super_R
+    { Qt::Key_Menu,                  KEY_MENU },
+    // Qt::Key_Hyper_L
+    // Qt::Key_Hyper_R
+    // Qt::Key_Help
+    // Qt::Key_Direction_L
+    // Qt::Key_Direction_R
+
+    // Qt::Key_Multi_key
+    // Qt::Key_Codeinput
+    // Qt::Key_SingleCandidate
+    // Qt::Key_MultipleCandidate
+    // Qt::Key_PreviousCandidate
+    // Qt::Key_Mode_switch
+    // Qt::Key_Kanji
+    // Qt::Key_Muhenkan
+    // Qt::Key_Henkan
+    // Qt::Key_Romaji
+    // Qt::Key_Hiragana
+    // Qt::Key_Katakana
+    // Qt::Key_Hiragana_Katakana
+    // Qt::Key_Zenkaku
+    // Qt::Key_Hankaku
+    // Qt::Key_Zenkaku_Hankaku
+    // Qt::Key_Touroku
+    // Qt::Key_Massyo
+    // Qt::Key_Kana_Lock
+    // Qt::Key_Kana_Shift
+    // Qt::Key_Eisu_Shift
+    // Qt::Key_Eisu_toggle
+    // Qt::Key_Hangul
+    // Qt::Key_Hangul_Start
+    // Qt::Key_Hangul_End
+    // Qt::Key_Hangul_Hanja
+    // Qt::Key_Hangul_Jamo
+    // Qt::Key_Hangul_Romaja
+    // Qt::Key_Hangul_Jeonja
+    // Qt::Key_Hangul_Banja
+    // Qt::Key_Hangul_PreHanja
+    // Qt::Key_Hangul_PostHanja
+    // Qt::Key_Hangul_Special
+    // Qt::Key_Dead_Grave
+    // Qt::Key_Dead_Acute
+    // Qt::Key_Dead_Circumflex
+    // Qt::Key_Dead_Tilde
+    // Qt::Key_Dead_Macron
+    // Qt::Key_Dead_Breve
+    // Qt::Key_Dead_Abovedot
+    // Qt::Key_Dead_Diaeresis
+    // Qt::Key_Dead_Abovering
+    // Qt::Key_Dead_Doubleacute
+    // Qt::Key_Dead_Caron
+    // Qt::Key_Dead_Cedilla
+    // Qt::Key_Dead_Ogonek
+    // Qt::Key_Dead_Iota
+    // Qt::Key_Dead_Voiced_Sound
+    // Qt::Key_Dead_Semivoiced_Sound
+    // Qt::Key_Dead_Belowdot
+    // Qt::Key_Dead_Hook
+    // Qt::Key_Dead_Horn
+    { Qt::Key_Back,                  KEY_BROWSER_BACK },
+    { Qt::Key_Forward,               KEY_BROWSER_FORWARD },
+    { Qt::Key_Stop,                  KEY_BROWSER_STOP },
+    { Qt::Key_Refresh,               KEY_BROWSER_REFRESH },
+    { Qt::Key_VolumeDown,            KEY_VOLUME_DOWN },
+    { Qt::Key_VolumeMute,            KEY_VOLUME_MUTE },
+    { Qt::Key_VolumeUp,              KEY_VOLUME_UP },
+    // Qt::Key_BassBoost
+    // Qt::Key_BassUp
+    // Qt::Key_BassDown
+    // Qt::Key_TrebleUp
+    // Qt::Key_TrebleDown
+    { Qt::Key_MediaPlay,             KEY_MEDIA_PLAY_PAUSE },
+    { Qt::Key_MediaStop,             KEY_MEDIA_STOP },
+    { Qt::Key_MediaPrevious,         KEY_MEDIA_PREV_TRACK },
+    { Qt::Key_MediaNext,             KEY_MEDIA_NEXT_TRACK },
+    // Qt::Key_MediaRecord
+    { Qt::Key_HomePage,              KEY_BROWSER_HOME },
+    { Qt::Key_Favorites,             KEY_BROWSER_FAVORITES },
+    { Qt::Key_Search,                KEY_BROWSER_SEARCH },
+    // Qt::Key_Standby
+    // Qt::Key_OpenUrl
+    // Qt::Key_LaunchMail
+    // Qt::Key_LaunchMedia
+    /* Qt::Key_Launch0 through Qt::Key_LaunchF */
+    // Qt::Key_MediaLast
+};
+
+static int keycmp( const void *a, const void *b )
+{
+    const int *q = (const int *)a;
+    const vlc_qt_key_t *m = (const vlc_qt_key_t *)b;
+
+    return *q - m->qt;
+}
+
 int qtEventToVLCKey( QKeyEvent *e )
 {
-    int i_vlck = 0;
-    /* Handle modifiers */
-    i_vlck |= qtKeyModifiersToVLC( e );
+    int qtk = e->key();
+    uint32_t i_vlck = 0;
 
-    bool found = false;
-    /* Look for some special keys */
-#define HANDLE( qt, vk ) case Qt::qt : i_vlck |= vk; found = true;break
-    switch( e->key() )
+    if( qtk <= 0xff )
+        /* VLC and X11 use lowercase whereas Qt uses uppercase */
+#if defined( __STDC_ISO_10646__ ) || defined( _WIN32 )
+        i_vlck = towlower( qtk );
+#else
+# error FIXME
+#endif
+    else /* Qt and X11 go to F35, but VLC stops at F12 */
+    if( qtk >= Qt::Key_F1 && qtk <= Qt::Key_F12 )
+        i_vlck = qtk - Qt::Key_F1 + KEY_F1;
+    else
     {
-        HANDLE( Key_Left, KEY_LEFT );
-        HANDLE( Key_Right, KEY_RIGHT );
-        HANDLE( Key_Up, KEY_UP );
-        HANDLE( Key_Down, KEY_DOWN );
-        HANDLE( Key_Space, KEY_SPACE );
-        HANDLE( Key_Escape, KEY_ESC );
-        HANDLE( Key_Enter, KEY_ENTER );
-        HANDLE( Key_F1, KEY_F1 );
-        HANDLE( Key_F2, KEY_F2 );
-        HANDLE( Key_F3, KEY_F3 );
-        HANDLE( Key_F4, KEY_F4 );
-        HANDLE( Key_F5, KEY_F5 );
-        HANDLE( Key_F6, KEY_F6 );
-        HANDLE( Key_F7, KEY_F7 );
-        HANDLE( Key_F8, KEY_F8 );
-        HANDLE( Key_F9, KEY_F9 );
-        HANDLE( Key_F10, KEY_F10 );
-        HANDLE( Key_F11, KEY_F11 );
-        HANDLE( Key_F12, KEY_F12 );
-        HANDLE( Key_PageUp, KEY_PAGEUP );
-        HANDLE( Key_PageDown, KEY_PAGEDOWN );
-        HANDLE( Key_Home, KEY_HOME );
-        HANDLE( Key_End, KEY_END );
-        HANDLE( Key_Insert, KEY_INSERT );
-        HANDLE( Key_Delete, KEY_DELETE );
-        HANDLE( Key_VolumeDown, KEY_VOLUME_DOWN);
-        HANDLE( Key_VolumeUp, KEY_VOLUME_UP );
-        HANDLE( Key_MediaPlay, KEY_MEDIA_PLAY_PAUSE );
-        HANDLE( Key_MediaStop, KEY_MEDIA_STOP );
-        HANDLE( Key_MediaPrevious, KEY_MEDIA_PREV_TRACK );
-        HANDLE( Key_MediaNext, KEY_MEDIA_NEXT_TRACK );
+        const vlc_qt_key_t *map;
 
+        map = (const vlc_qt_key_t *)
+              bsearch( &qtk, (const void *)keys, sizeof(keys)/sizeof(keys[0]),
+                       sizeof(*keys), keycmp );
+        if( map != NULL )
+            i_vlck = map->vlc;
     }
-    if( !found )
-    {
-        /* Force lowercase */
-        if( e->key() >= Qt::Key_A && e->key() <= Qt::Key_Z )
-            i_vlck += e->key() + 32;
-        /* Rest of the ascii range */
-        else if( e->key() >= Qt::Key_Space && e->key() <= Qt::Key_AsciiTilde )
-            i_vlck += e->key();
-    }
+
+    /* Handle modifiers */
+    i_vlck |= qtKeyModifiersToVLC( e );
     return i_vlck;
 }
 
@@ -178,43 +418,23 @@ int qtWheelEventToVLCKey( QWheelEvent *e )
 
 QString VLCKeyToString( int val )
 {
+    char *base = KeyToString (val & ~KEY_MODIFIER);
+
     QString r = "";
     if( val & KEY_MODIFIER_CTRL )
-        r+= "Ctrl+";
+        r+= qfu( "Ctrl+" );
     if( val & KEY_MODIFIER_ALT )
-        r+= "Alt+";
+        r+= qfu( "Alt+" );
     if( val & KEY_MODIFIER_SHIFT )
-        r+= "Shift+";
+        r+= qfu( "Shift+" );
 
-    unsigned int i_keys = sizeof(vlc_keys)/sizeof(key_descriptor_t);
-    for( unsigned int i = 0; i< i_keys; i++ )
+    if (base)
     {
-        if( vlc_keys[i].i_key_code == (val& ~KEY_MODIFIER) )
-        {
-            r+= vlc_keys[i].psz_key_string;
-        }
+        r += qfu( base );
+        free( base );
     }
+    else
+        r += qtr( "Unset" );
     return r;
 }
 
-#include <QComboBox>
-
-void setfillVLCConfigCombo( const char *configname, intf_thread_t *p_intf,
-                        QComboBox *combo, QWidget *parent )
-{
-    module_config_t *p_config =
-                      config_FindConfig( VLC_OBJECT(p_intf), configname );
-    if( p_config )
-    {
-        for ( int i_index = 0; i_index < p_config->i_list; i_index++ )
-        {
-            combo->addItem( qfu( p_config->ppsz_list_text[i_index] ),
-                    QVariant( p_config->pi_list[i_index] ) );
-            if( p_config->value.i == p_config->pi_list[i_index] )
-            {
-                combo->setCurrentIndex( i_index );
-            }
-        }
-        combo->setToolTip( qfu( p_config->psz_longtext ) );
-    }
-}