1 /*****************************************************************************
2 * customwidgets.cpp: Custom widgets
3 ****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
5 * Copyright (C) 2004 Daniel Molkentin <molkentin@kde.org>
8 * Authors: Clément Stenac <zorglub@videolan.org>
9 * The "ClickLineEdit" control is based on code by Daniel Molkentin
10 * <molkentin@kde.org> for libkdepim
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
31 #include "customwidgets.hpp"
32 #include "qt4.hpp" /*needed for qtr and CONNECT, but not necessary */
35 #include <QColorGroup>
38 #include <QWheelEvent>
39 #include <QHBoxLayout>
41 #include <QStyleOption>
42 #include <vlc_intf_strings.h>
44 #include <wctype.h> /* twolower() */
46 ClickLineEdit::ClickLineEdit( const QString
&msg
, QWidget
*parent
) : QLineEdit( parent
)
49 setClickMessage( msg
);
52 void ClickLineEdit::setClickMessage( const QString
&msg
)
59 void ClickLineEdit::setText( const QString
&txt
)
61 mDrawClickMsg
= txt
.isEmpty();
63 QLineEdit::setText( txt
);
66 void ClickLineEdit::paintEvent( QPaintEvent
*pe
)
68 QLineEdit::paintEvent( pe
);
69 if ( mDrawClickMsg
== true && !hasFocus() ) {
72 p
.setPen( palette().color( QPalette::Disabled
, QPalette::Text
) );
73 QRect cr
= contentsRect();
74 // Add two pixel margin on the left side
75 cr
.setLeft( cr
.left() + 3 );
76 p
.drawText( cr
, Qt::AlignLeft
| Qt::AlignVCenter
, mClickMessage
);
82 void ClickLineEdit::dropEvent( QDropEvent
*ev
)
84 mDrawClickMsg
= false;
85 QLineEdit::dropEvent( ev
);
88 void ClickLineEdit::focusInEvent( QFocusEvent
*ev
)
90 if ( mDrawClickMsg
== true ) {
91 mDrawClickMsg
= false;
94 QLineEdit::focusInEvent( ev
);
97 void ClickLineEdit::focusOutEvent( QFocusEvent
*ev
)
99 if ( text().isEmpty() ) {
100 mDrawClickMsg
= true;
103 QLineEdit::focusOutEvent( ev
);
106 QVLCFramelessButton::QVLCFramelessButton( QWidget
*parent
)
107 : QPushButton( parent
)
109 setSizePolicy( QSizePolicy::Preferred
, QSizePolicy::Preferred
);
112 void QVLCFramelessButton::paintEvent( QPaintEvent
* event
)
114 QPainter
painter( this );
115 QPixmap pix
= icon().pixmap( size() );
116 QPoint
pos( (width() - pix
.width()) / 2, (height() - pix
.height()) / 2 );
117 painter
.drawPixmap( QRect( pos
.x(), pos
.y(), pix
.width(), pix
.height() ), pix
);
120 QSize
QVLCFramelessButton::sizeHint() const
125 SearchLineEdit::SearchLineEdit( QWidget
*parent
) : QLineEdit( parent
)
127 clearButton
= new QVLCFramelessButton( this );
128 clearButton
->setIcon( QIcon( ":/toolbar/clear" ) );
129 clearButton
->setIconSize( QSize( 16, 16 ) );
130 clearButton
->setCursor( Qt::ArrowCursor
);
131 clearButton
->setToolTip( qfu(vlc_pgettext("Tooltip|Clear", "Clear")) );
134 CONNECT( clearButton
, clicked(), this, clear() );
136 int frameWidth
= style()->pixelMetric( QStyle::PM_DefaultFrameWidth
, 0, this );
138 QFontMetrics
metrics( font() );
139 QString styleSheet
= QString( "min-height: %1px; "
141 "padding-bottom: 1px; "
142 "padding-right: %2px;" )
143 .arg( metrics
.height() + ( 2 * frameWidth
) )
144 .arg( clearButton
->sizeHint().width() + 1 );
145 setStyleSheet( styleSheet
);
147 setMessageVisible( true );
149 CONNECT( this, textEdited( const QString
& ),
150 this, updateText( const QString
& ) );
153 void SearchLineEdit::clear()
155 setText( QString() );
157 setMessageVisible( true );
160 void SearchLineEdit::setMessageVisible( bool on
)
167 void SearchLineEdit::updateText( const QString
& text
)
169 clearButton
->setVisible( !text
.isEmpty() );
172 void SearchLineEdit::resizeEvent ( QResizeEvent
* event
)
174 QLineEdit::resizeEvent( event
);
175 int frameWidth
= style()->pixelMetric(QStyle::PM_DefaultFrameWidth
,0,this);
176 clearButton
->resize( clearButton
->sizeHint().width(), height() );
177 clearButton
->move( width() - clearButton
->width() - frameWidth
, 0 );
180 void SearchLineEdit::focusInEvent( QFocusEvent
*event
)
184 setMessageVisible( false );
186 QLineEdit::focusInEvent( event
);
189 void SearchLineEdit::focusOutEvent( QFocusEvent
*event
)
191 if( text().isEmpty() )
193 setMessageVisible( true );
195 QLineEdit::focusOutEvent( event
);
198 void SearchLineEdit::paintEvent( QPaintEvent
*event
)
200 QLineEdit::paintEvent( event
);
201 if( !message
) return;
203 option
.initFrom( this );
204 QRect rect
= style()->subElementRect( QStyle::SE_LineEditContents
, &option
, this )
205 .adjusted( 3, 0, clearButton
->width() + 1, 0 );
206 QPainter
painter( this );
207 painter
.setPen( palette().color( QPalette::Disabled
, QPalette::Text
) );
208 painter
.drawText( rect
, Qt::AlignLeft
| Qt::AlignVCenter
, qtr( I_PL_FILTER
) );
212 QVLCElidingLabel::QVLCElidingLabel( const QString
&s
, Qt::TextElideMode mode
, QWidget
* parent
)
213 : elideMode( mode
), QLabel( s
, parent
)
216 void QVLCElidingLabel::setElideMode( Qt::TextElideMode mode
)
222 void QVLCElidingLabel::paintEvent( QPaintEvent
* event
)
225 int space
= frameWidth() + margin();
226 QRect r
= rect().adjusted( space
, space
, -space
, -space
);
227 p
.drawText( r
, fontMetrics().elidedText( text(), elideMode
, r
.width() ), alignment() );
230 /***************************************************************************
232 ***************************************************************************/
233 int qtKeyModifiersToVLC( QInputEvent
* e
)
235 int i_keyModifiers
= 0;
236 if( e
->modifiers() & Qt::ShiftModifier
) i_keyModifiers
|= KEY_MODIFIER_SHIFT
;
237 if( e
->modifiers() & Qt::AltModifier
) i_keyModifiers
|= KEY_MODIFIER_ALT
;
238 if( e
->modifiers() & Qt::ControlModifier
) i_keyModifiers
|= KEY_MODIFIER_CTRL
;
239 if( e
->modifiers() & Qt::MetaModifier
) i_keyModifiers
|= KEY_MODIFIER_META
;
240 return i_keyModifiers
;
249 static const vlc_qt_key_t keys
[] =
251 { Qt::Key_Escape
, KEY_ESC
},
252 { Qt::Key_Tab
, '\t', },
254 { Qt::Key_Backspace
, '\b' },
255 { Qt::Key_Return
, '\r' },
256 { Qt::Key_Enter
, '\r' }, // numeric pad
257 { Qt::Key_Insert
, KEY_INSERT
},
258 { Qt::Key_Delete
, KEY_DELETE
},
263 { Qt::Key_Home
, KEY_HOME
},
264 { Qt::Key_End
, KEY_END
},
265 { Qt::Key_Left
, KEY_LEFT
},
266 { Qt::Key_Up
, KEY_UP
},
267 { Qt::Key_Right
, KEY_RIGHT
},
268 { Qt::Key_Down
, KEY_DOWN
},
269 { Qt::Key_PageUp
, KEY_PAGEUP
},
270 { Qt::Key_PageDown
, KEY_PAGEDOWN
},
277 // Qt::Key_ScrollLock
281 { Qt::Key_Menu
, KEY_MENU
},
285 // Qt::Key_Direction_L
286 // Qt::Key_Direction_R
290 // Qt::Key_SingleCandidate
291 // Qt::Key_MultipleCandidate
292 // Qt::Key_PreviousCandidate
293 // Qt::Key_Mode_switch
300 // Qt::Key_Hiragana_Katakana
303 // Qt::Key_Zenkaku_Hankaku
307 // Qt::Key_Kana_Shift
308 // Qt::Key_Eisu_Shift
309 // Qt::Key_Eisu_toggle
311 // Qt::Key_Hangul_Start
312 // Qt::Key_Hangul_End
313 // Qt::Key_Hangul_Hanja
314 // Qt::Key_Hangul_Jamo
315 // Qt::Key_Hangul_Romaja
316 // Qt::Key_Hangul_Jeonja
317 // Qt::Key_Hangul_Banja
318 // Qt::Key_Hangul_PreHanja
319 // Qt::Key_Hangul_PostHanja
320 // Qt::Key_Hangul_Special
321 // Qt::Key_Dead_Grave
322 // Qt::Key_Dead_Acute
323 // Qt::Key_Dead_Circumflex
324 // Qt::Key_Dead_Tilde
325 // Qt::Key_Dead_Macron
326 // Qt::Key_Dead_Breve
327 // Qt::Key_Dead_Abovedot
328 // Qt::Key_Dead_Diaeresis
329 // Qt::Key_Dead_Abovering
330 // Qt::Key_Dead_Doubleacute
331 // Qt::Key_Dead_Caron
332 // Qt::Key_Dead_Cedilla
333 // Qt::Key_Dead_Ogonek
335 // Qt::Key_Dead_Voiced_Sound
336 // Qt::Key_Dead_Semivoiced_Sound
337 // Qt::Key_Dead_Belowdot
340 { Qt::Key_Back
, KEY_BROWSER_BACK
},
341 { Qt::Key_Forward
, KEY_BROWSER_FORWARD
},
342 { Qt::Key_Stop
, KEY_BROWSER_STOP
},
343 { Qt::Key_Refresh
, KEY_BROWSER_REFRESH
},
344 { Qt::Key_VolumeDown
, KEY_VOLUME_DOWN
},
345 { Qt::Key_VolumeMute
, KEY_VOLUME_MUTE
},
346 { Qt::Key_VolumeUp
, KEY_VOLUME_UP
},
351 // Qt::Key_TrebleDown
352 { Qt::Key_MediaPlay
, KEY_MEDIA_PLAY_PAUSE
},
353 { Qt::Key_MediaStop
, KEY_MEDIA_STOP
},
354 { Qt::Key_MediaPrevious
, KEY_MEDIA_PREV_TRACK
},
355 { Qt::Key_MediaNext
, KEY_MEDIA_NEXT_TRACK
},
356 // Qt::Key_MediaRecord
357 { Qt::Key_HomePage
, KEY_BROWSER_HOME
},
358 { Qt::Key_Favorites
, KEY_BROWSER_FAVORITES
},
359 { Qt::Key_Search
, KEY_BROWSER_SEARCH
},
362 // Qt::Key_LaunchMail
363 // Qt::Key_LaunchMedia
364 /* Qt::Key_Launch0 through Qt::Key_LaunchF */
368 static int keycmp( const void *a
, const void *b
)
370 const int *q
= (const int *)a
;
371 const vlc_qt_key_t
*m
= (const vlc_qt_key_t
*)b
;
376 int qtEventToVLCKey( QKeyEvent
*e
)
382 /* VLC and X11 use lowercase whereas Qt uses uppercase */
383 #if defined( __STDC_ISO_10646__ ) || defined( _WIN32 )
384 i_vlck
= towlower( qtk
);
388 else /* Qt and X11 go to F35, but VLC stops at F12 */
389 if( qtk
>= Qt::Key_F1
&& qtk
<= Qt::Key_F12
)
390 i_vlck
= qtk
- Qt::Key_F1
+ KEY_F1
;
393 const vlc_qt_key_t
*map
;
395 map
= (const vlc_qt_key_t
*)
396 bsearch( &qtk
, (const void *)keys
, sizeof(keys
)/sizeof(keys
[0]),
397 sizeof(*keys
), keycmp
);
402 /* Handle modifiers */
403 i_vlck
|= qtKeyModifiersToVLC( e
);
407 int qtWheelEventToVLCKey( QWheelEvent
*e
)
410 /* Handle modifiers */
411 i_vlck
|= qtKeyModifiersToVLC( e
);
412 if ( e
->delta() > 0 )
413 i_vlck
|= KEY_MOUSEWHEELUP
;
415 i_vlck
|= KEY_MOUSEWHEELDOWN
;
419 QString
VLCKeyToString( int val
)
421 char *base
= KeyToString (val
& ~KEY_MODIFIER
);
424 if( val
& KEY_MODIFIER_CTRL
)
426 if( val
& KEY_MODIFIER_ALT
)
428 if( val
& KEY_MODIFIER_SHIFT
)