Commit 9f13f726 authored by Clément Stenac's avatar Clément Stenac

Find as you type

parent 6e670ff2
...@@ -33,7 +33,8 @@ TOMOC = main_interface \ ...@@ -33,7 +33,8 @@ TOMOC = main_interface \
components/playlist/panels \ components/playlist/panels \
components/playlist/selector \ components/playlist/selector \
util/input_slider \ util/input_slider \
util/views util/views \
util/customwidgets
MOCCPP = $(TOMOC:%=%.moc.cpp) MOCCPP = $(TOMOC:%=%.moc.cpp)
nodist_SOURCES_qt4 = \ nodist_SOURCES_qt4 = \
...@@ -56,6 +57,7 @@ nodist_SOURCES_qt4 = \ ...@@ -56,6 +57,7 @@ nodist_SOURCES_qt4 = \
components/playlist/selector.moc.cpp \ components/playlist/selector.moc.cpp \
util/input_slider.moc.cpp \ util/input_slider.moc.cpp \
util/views.moc.cpp \ util/views.moc.cpp \
util/customwidgets.moc.cpp \
resources.cpp resources.cpp
if ENABLE_QT4 if ENABLE_QT4
...@@ -97,6 +99,7 @@ SOURCES_qt4 = qt4.cpp \ ...@@ -97,6 +99,7 @@ SOURCES_qt4 = qt4.cpp \
components/playlist/standardpanel.cpp \ components/playlist/standardpanel.cpp \
components/playlist/selector.cpp \ components/playlist/selector.cpp \
util/input_slider.cpp \ util/input_slider.cpp \
util/customwidgets.cpp \
$(NULL) $(NULL)
EXTRA_DIST += \ EXTRA_DIST += \
...@@ -122,6 +125,7 @@ EXTRA_DIST += \ ...@@ -122,6 +125,7 @@ EXTRA_DIST += \
util/input_slider.hpp \ util/input_slider.hpp \
util/directslider.hpp \ util/directslider.hpp \
util/views.hpp \ util/views.hpp \
util/customwidgets.hpp \
util/qvlcframe.hpp \ util/qvlcframe.hpp \
ui/input_stats.ui \ ui/input_stats.ui \
ui/file_open.ui \ ui/file_open.ui \
......
...@@ -33,6 +33,7 @@ class QTreeView; ...@@ -33,6 +33,7 @@ class QTreeView;
class PLModel; class PLModel;
class QPushButton; class QPushButton;
class QKeyEvent; class QKeyEvent;
class ClickLineEdit;
class PLPanel: public QWidget class PLPanel: public QWidget
{ {
...@@ -63,6 +64,7 @@ private: ...@@ -63,6 +64,7 @@ private:
PLModel *model; PLModel *model;
QTreeView *view; QTreeView *view;
QPushButton *repeatButton , *randomButton; QPushButton *repeatButton , *randomButton;
ClickLineEdit *searchLine;
public slots: public slots:
virtual void setRoot( int ); virtual void setRoot( int );
private slots: private slots:
...@@ -71,6 +73,8 @@ private slots: ...@@ -71,6 +73,8 @@ private slots:
void toggleRandom(); void toggleRandom();
void toggleRepeat(); void toggleRepeat();
void doPopup( QModelIndex index, QPoint point ); void doPopup( QModelIndex index, QPoint point );
void search( QString search );
void clearFilter();
}; };
#endif #endif
...@@ -32,8 +32,11 @@ ...@@ -32,8 +32,11 @@
#include "qt4.hpp" #include "qt4.hpp"
#include <assert.h> #include <assert.h>
#include <QModelIndexList> #include <QModelIndexList>
#include <QToolBar>
#include <QLabel>
#include <QSpacerItem>
#include "util/views.hpp" #include "util/views.hpp"
#include "util/customwidgets.hpp"
StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf, StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf,
playlist_t *p_playlist, playlist_t *p_playlist,
...@@ -50,8 +53,6 @@ StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf, ...@@ -50,8 +53,6 @@ StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf,
view->header()->setClickable( true ); view->header()->setClickable( true );
view->setSelectionMode( QAbstractItemView::ExtendedSelection ); view->setSelectionMode( QAbstractItemView::ExtendedSelection );
// connect( view->header(), SIGNAL( sectionClicked( int)), view, SLOT( sortByColumn(int)));
connect( view, SIGNAL( activated( const QModelIndex& ) ), model, connect( view, SIGNAL( activated( const QModelIndex& ) ), model,
SLOT( activateItem( const QModelIndex& ) ) ); SLOT( activateItem( const QModelIndex& ) ) );
...@@ -66,23 +67,34 @@ StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf, ...@@ -66,23 +67,34 @@ StandardPLPanel::StandardPLPanel( QWidget *_parent, intf_thread_t *_p_intf,
layout->setSpacing( 0 ); layout->setMargin( 0 ); layout->setSpacing( 0 ); layout->setMargin( 0 );
QHBoxLayout *buttons = new QHBoxLayout(); QHBoxLayout *buttons = new QHBoxLayout();
repeatButton = new QPushButton( this );
buttons->addWidget( repeatButton );
randomButton = new QPushButton( this );
buttons->addWidget( randomButton );
if( model->hasRandom() ) randomButton->setText( qtr( "Random" ) );
else randomButton->setText( qtr( "No random" ) );
repeatButton = new QPushButton( 0 ); buttons->addWidget( repeatButton );
if( model->hasRepeat() ) repeatButton->setText( qtr( "Repeat One" ) ); if( model->hasRepeat() ) repeatButton->setText( qtr( "Repeat One" ) );
else if( model->hasLoop() ) repeatButton->setText( qtr( "Repeat All" ) ); else if( model->hasLoop() ) repeatButton->setText( qtr( "Repeat All" ) );
else repeatButton->setText( qtr( "No Repeat" ) ); else repeatButton->setText( qtr( "No Repeat" ) );
connect( repeatButton, SIGNAL( clicked() ), this, SLOT( toggleRepeat() )); connect( repeatButton, SIGNAL( clicked() ), this, SLOT( toggleRepeat() ));
randomButton = new QPushButton( 0 ); buttons->addWidget( randomButton );
if( model->hasRandom() ) randomButton->setText( qtr( "Random" ) );
else randomButton->setText( qtr( "No random" ) );
connect( randomButton, SIGNAL( clicked() ), this, SLOT( toggleRandom() )); connect( randomButton, SIGNAL( clicked() ), this, SLOT( toggleRandom() ));
QSpacerItem *spacer = new QSpacerItem( 10, 20 );buttons->addItem( spacer );
QLabel *filter = new QLabel( qfu( "&Search:" ) + " " );
buttons->addWidget( filter );
searchLine = new ClickLineEdit( qfu( "Playlist filter" ), 0 );
connect( searchLine, SIGNAL( textChanged(QString) ),
this, SLOT( search(QString)) );
buttons->addWidget( searchLine ); filter->setBuddy( searchLine );
QPushButton *clear = new QPushButton( qfu( "CL") );
buttons->addWidget( clear );
connect( clear, SIGNAL( clicked() ), this, SLOT( clearFilter() ) );
layout->addWidget( view ); layout->addWidget( view );
layout->addLayout( buttons ); layout->addLayout( buttons );
// layout->addWidget( bar );
setLayout( layout ); setLayout( layout );
} }
...@@ -126,6 +138,16 @@ void StandardPLPanel::handleExpansion( const QModelIndex &index ) ...@@ -126,6 +138,16 @@ void StandardPLPanel::handleExpansion( const QModelIndex &index )
} }
} }
void StandardPLPanel::clearFilter()
{
searchLine->setText( "" );
}
void StandardPLPanel::search( QString searchText )
{
model->search( searchText );
}
void StandardPLPanel::doPopup( QModelIndex index, QPoint point ) void StandardPLPanel::doPopup( QModelIndex index, QPoint point )
{ {
assert( index.isValid() ); assert( index.isValid() );
......
...@@ -163,8 +163,8 @@ PLModel::PLModel( playlist_t *_p_playlist, ...@@ -163,8 +163,8 @@ PLModel::PLModel( playlist_t *_p_playlist,
ADD_ICON( NODE, node ); ADD_ICON( NODE, node );
rootItem = NULL; rootItem = NULL;
rebuild( p_root );
addCallbacks(); addCallbacks();
rebuild( p_root );
} }
...@@ -176,6 +176,7 @@ PLModel::~PLModel() ...@@ -176,6 +176,7 @@ PLModel::~PLModel()
void PLModel::addCallbacks() void PLModel::addCallbacks()
{ {
fprintf( stderr, "[%i] Adding callbacks\n", i_depth );
/* Some global changes happened -> Rebuild all */ /* Some global changes happened -> Rebuild all */
var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this ); var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
/* We went to the next item */ /* We went to the next item */
...@@ -188,6 +189,7 @@ void PLModel::addCallbacks() ...@@ -188,6 +189,7 @@ void PLModel::addCallbacks()
void PLModel::delCallbacks() void PLModel::delCallbacks()
{ {
fprintf( stderr, "[%i] Rming callbacks\n", i_depth );
var_DelCallback( p_playlist, "item-change", ItemChanged, this ); var_DelCallback( p_playlist, "item-change", ItemChanged, this );
var_DelCallback( p_playlist, "playlist-current", PlaylistNext, this ); var_DelCallback( p_playlist, "playlist-current", PlaylistNext, this );
var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this ); var_DelCallback( p_playlist, "intf-change", PlaylistChanged, this );
...@@ -526,6 +528,7 @@ void PLModel::rebuild( playlist_item_t *p_root ) ...@@ -526,6 +528,7 @@ void PLModel::rebuild( playlist_item_t *p_root )
rootItem = new PLItem( p_root, NULL, this ); rootItem = new PLItem( p_root, NULL, this );
rootItem->strings[0] = qtr("Name"); rootItem->strings[0] = qtr("Name");
rootItem->strings[1] = qtr("Artist"); rootItem->strings[1] = qtr("Artist");
rootItem->strings[2] = qtr("Duration");
} }
assert( rootItem ); assert( rootItem );
/* Recreate from root */ /* Recreate from root */
...@@ -559,6 +562,7 @@ void PLModel::UpdateNodeChildren( playlist_item_t *p_node, PLItem *root ) ...@@ -559,6 +562,7 @@ void PLModel::UpdateNodeChildren( playlist_item_t *p_node, PLItem *root )
{ {
for( int i = 0; i < p_node->i_children ; i++ ) for( int i = 0; i < p_node->i_children ; i++ )
{ {
if( p_node->pp_children[i]->i_flags & PLAYLIST_DBL_FLAG ) continue;
PLItem *newItem = new PLItem( p_node->pp_children[i], root, this ); PLItem *newItem = new PLItem( p_node->pp_children[i], root, this );
root->appendChild( newItem, false ); root->appendChild( newItem, false );
UpdateTreeItem( newItem, false, true ); UpdateTreeItem( newItem, false, true );
...@@ -661,6 +665,20 @@ void PLModel::sort( int column, Qt::SortOrder order ) ...@@ -661,6 +665,20 @@ void PLModel::sort( int column, Qt::SortOrder order )
rebuild(); rebuild();
} }
void PLModel::search( QString search_text )
{
/** \todo Fire the search with a small delay ? */
fprintf( stderr, "Searching\n" );
PL_LOCK;
playlist_item_t *p_root = playlist_ItemGetById( p_playlist,rootItem->i_id );
assert( p_root );
char *psz_name = search_text.toUtf8().data();
fprintf( stderr, "Searching %s\n", psz_name );
playlist_LiveSearchUpdate( p_playlist , p_root, psz_name );
PL_UNLOCK;
rebuild();
}
/*********** Popup *********/ /*********** Popup *********/
void PLModel::popup( QModelIndex & index, QPoint &point, QModelIndexList list ) void PLModel::popup( QModelIndex & index, QPoint &point, QModelIndexList list )
{ {
......
...@@ -118,6 +118,7 @@ public: ...@@ -118,6 +118,7 @@ public:
/* Actions made by the views */ /* Actions made by the views */
void popup( QModelIndex & index, QPoint &point, QModelIndexList list ); void popup( QModelIndex & index, QPoint &point, QModelIndexList list );
void doDelete( QModelIndexList selected ); void doDelete( QModelIndexList selected );
void search( QString search );
void sort( int column, Qt::SortOrder order ); void sort( int column, Qt::SortOrder order );
private: private:
void addCallbacks(); void addCallbacks();
......
/*****************************************************************************
* customwidgets.cpp: Custom widgets
****************************************************************************
* 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 $
*
* Authors: Clément Stenac <zorglub@videolan.org>
* The "ClickLineEdit" control is based on code by Daniel Molkentin
* <molkentin@kde.org> for libkdepim
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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. *****************************************************************************/
#include "customwidgets.hpp"
#include <QPainter>
#include <QLineEdit>
#include <QPainter>
#include <QColorGroup>
#include <QRect>
ClickLineEdit::ClickLineEdit( const QString &msg, QWidget *parent) : QLineEdit( parent )
{
mDrawClickMsg = true;
setClickMessage( msg );
}
void ClickLineEdit::setClickMessage( const QString &msg )
{
mClickMessage = msg;
repaint();
}
void ClickLineEdit::setText( const QString &txt )
{
mDrawClickMsg = txt.isEmpty();
repaint();
QLineEdit::setText( txt );
}
void ClickLineEdit::paintEvent( QPaintEvent *pe )
{
QPainter p( this );
QLineEdit::paintEvent( pe );
if ( mDrawClickMsg == true && !hasFocus() ) {
QPen tmp = p.pen();
p.setPen( palette().color( QPalette::Disabled, QPalette::Text ) );
QRect cr = contentsRect();
// Add two pixel margin on the left side
cr.setLeft( cr.left() + 3 );
p.drawText( cr, Qt::AlignLeft | Qt::AlignVCenter, mClickMessage );
p.setPen( tmp );
}
}
void ClickLineEdit::dropEvent( QDropEvent *ev )
{
mDrawClickMsg = false;
QLineEdit::dropEvent( ev );
}
void ClickLineEdit::focusInEvent( QFocusEvent *ev )
{
if ( mDrawClickMsg == true ) {
mDrawClickMsg = false;
repaint();
}
QLineEdit::focusInEvent( ev );
}
void ClickLineEdit::focusOutEvent( QFocusEvent *ev )
{
if ( text().isEmpty() ) {
mDrawClickMsg = true;
repaint();
}
QLineEdit::focusOutEvent( ev );
}
/*****************************************************************************
* customwidgets.h: Custom widgets
****************************************************************************
* 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 $
*
* Authors: Clément Stenac <zorglub@videolan.org>
* The "ClickLineEdit" control is based on code by Daniel Molkentin
* <molkentin@kde.org> for libkdepim
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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. *****************************************************************************/
#ifndef _CUSTOMWIDGETS_H_
#define _CUSTOMWIDGETS_H_
#include <QLineEdit>
/**
This class provides a QLineEdit which contains a greyed-out hinting
text as long as the user didn't enter any text
@short LineEdit with customizable "Click here" text
@author Daniel Molkentin
*/
class ClickLineEdit : public QLineEdit
{
Q_OBJECT
Q_PROPERTY( QString clickMessage READ clickMessage WRITE setClickMessage )
public:
ClickLineEdit( const QString &msg, QWidget *parent );
virtual ~ClickLineEdit() {};
void setClickMessage( const QString &msg );
QString clickMessage() const { return mClickMessage; }
virtual void setText( const QString& txt );
protected:
virtual void paintEvent( QPaintEvent *e );
virtual void dropEvent( QDropEvent *ev );
virtual void focusInEvent( QFocusEvent *ev );
virtual void focusOutEvent( QFocusEvent *ev );
private:
QString mClickMessage;
bool mDrawClickMsg;
};
#endif // CLICKLINEEDIT_H
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment