Commit 2f353e18 authored by Francois Cartegnie's avatar Francois Cartegnie

Qt4: prune SQL media library code

refs c2c113e3
parent 532b001b
...@@ -49,7 +49,6 @@ libqt4_plugin_la_SOURCES = \ ...@@ -49,7 +49,6 @@ libqt4_plugin_la_SOURCES = \
dialogs/bookmarks.cpp dialogs/bookmarks.hpp \ dialogs/bookmarks.cpp dialogs/bookmarks.hpp \
dialogs/preferences.cpp dialogs/preferences.hpp \ dialogs/preferences.cpp dialogs/preferences.hpp \
dialogs/mediainfo.cpp dialogs/mediainfo.hpp \ dialogs/mediainfo.cpp dialogs/mediainfo.hpp \
dialogs/ml_configuration.cpp dialogs/ml_configuration.hpp \
dialogs/epg.cpp dialogs/epg.hpp \ dialogs/epg.cpp dialogs/epg.hpp \
dialogs/extended.cpp dialogs/extended.hpp \ dialogs/extended.cpp dialogs/extended.hpp \
dialogs/messages.cpp dialogs/messages.hpp \ dialogs/messages.cpp dialogs/messages.hpp \
...@@ -85,8 +84,6 @@ libqt4_plugin_la_SOURCES = \ ...@@ -85,8 +84,6 @@ libqt4_plugin_la_SOURCES = \
components/epg/EPGView.cpp components/epg/EPGView.hpp \ components/epg/EPGView.cpp components/epg/EPGView.hpp \
components/epg/EPGWidget.cpp components/epg/EPGWidget.hpp \ components/epg/EPGWidget.cpp components/epg/EPGWidget.hpp \
components/playlist/views.cpp components/playlist/views.hpp \ components/playlist/views.cpp components/playlist/views.hpp \
components/playlist/ml_item.cpp components/playlist/ml_item.hpp \
components/playlist/ml_model.cpp components/playlist/ml_model.hpp \
components/playlist/vlc_model.cpp components/playlist/vlc_model.hpp \ components/playlist/vlc_model.cpp components/playlist/vlc_model.hpp \
components/playlist/playlist_model.cpp \ components/playlist/playlist_model.cpp \
components/playlist/playlist_model.hpp \ components/playlist/playlist_model.hpp \
...@@ -169,7 +166,6 @@ nodist_libqt4_plugin_la_SOURCES = \ ...@@ -169,7 +166,6 @@ nodist_libqt4_plugin_la_SOURCES = \
dialogs/firstrun.moc.cpp \ dialogs/firstrun.moc.cpp \
dialogs/extensions.moc.cpp \ dialogs/extensions.moc.cpp \
dialogs/fingerprintdialog.moc.cpp \ dialogs/fingerprintdialog.moc.cpp \
dialogs/ml_configuration.moc.cpp \
components/extended_panels.moc.cpp \ components/extended_panels.moc.cpp \
components/info_panels.moc.cpp \ components/info_panels.moc.cpp \
components/info_widgets.moc.cpp \ components/info_widgets.moc.cpp \
...@@ -190,7 +186,6 @@ nodist_libqt4_plugin_la_SOURCES = \ ...@@ -190,7 +186,6 @@ nodist_libqt4_plugin_la_SOURCES = \
components/playlist/playlist.moc.cpp \ components/playlist/playlist.moc.cpp \
components/playlist/standardpanel.moc.cpp \ components/playlist/standardpanel.moc.cpp \
components/playlist/selector.moc.cpp \ components/playlist/selector.moc.cpp \
components/playlist/ml_model.moc.cpp \
components/sout/profile_selector.moc.cpp \ components/sout/profile_selector.moc.cpp \
components/sout/sout_widgets.moc.cpp \ components/sout/sout_widgets.moc.cpp \
util/animators.moc.cpp \ util/animators.moc.cpp \
......
/*****************************************************************************
* ml_item.cpp: the SQL media library's result item
*****************************************************************************
* Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
* $Id$
*
* Authors: Antoine Lejeune <phytos@videolan.org>
* Jean-Philippe André <jpeg@videolan.org>
* Rémi Duraffort <ivoire@videolan.org>
* Adrien Maglo <magsoft@videolan.org>
* Srikanth Raju <srikiraju#gmail#com>
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SQL_MEDIA_LIBRARY
#include <QDateTime>
#include <QUrl>
#include <QFileInfo>
#include "ml_item.hpp"
#include <assert.h>
/**
* @brief Compare the attribute 'meta' between medias a and b.
* @param a
* @param b
* @param meta
* @note If a->meta < b->meta, return -1
* If a->meta == b->meta, return 0
* If a->meta > b->meta, return +1
* @note If a->meta == NULL and b->meta != NULL (strings), then b>a
*/
static int compareMeta( ml_media_t *a, ml_media_t *b, ml_select_e meta )
{
bool i_ret = 0;
# define scomp(c) i_ret = ((a->c&&b->c&&*a->c&&*b->c) ?\
strcasecmp(a->c,b->c) : \
(a->c&&*a->c?-1:(b->c&&*b->c?1:0))); break;
# define icomp(c) i_ret = (a->c<b->c?-1:(a->c==b->c?0:1)); break;
if ( a == b ) return 0;
vlc_mutex_lock( &a->lock );
vlc_mutex_lock( &b->lock );
switch( meta )
{
case ML_ALBUM: scomp( psz_album );
case ML_ALBUM_ID: icomp( i_album_id );
//case ML_ARTIST: scomp( psz_artist );
//case ML_ARTIST_ID: icomp( i_artist_id );
case ML_COVER: scomp( psz_cover );
case ML_DURATION: icomp( i_duration );
case ML_EXTRA: scomp( psz_extra );
case ML_GENRE: scomp( psz_genre );
case ML_ID: icomp( i_id );
case ML_LAST_PLAYED: icomp( i_last_played );
case ML_ORIGINAL_TITLE: scomp( psz_orig_title );
case ML_PLAYED_COUNT: icomp( i_played_count );
// case ML_ROLE: 0;
case ML_SCORE: icomp( i_score );
case ML_TITLE: scomp( psz_title );
case ML_TRACK_NUMBER: icomp( i_track_number );
case ML_TYPE: icomp( i_type );
case ML_URI: scomp( psz_uri );
case ML_VOTE: icomp( i_vote );
case ML_YEAR: icomp( i_year );
default:
break;
}
# undef scomp
# undef icomp
vlc_mutex_unlock( &a->lock );
vlc_mutex_unlock( &b->lock );
return i_ret;
}
MLItem::MLItem( intf_thread_t* _p_intf,
ml_media_t *p_media,
MLItem *p_parent )
{
parentItem = p_parent;
if( p_media )
ml_gc_incref( p_media );
media = p_media;
p_ml = ml_Get( _p_intf );
}
MLItem::~MLItem()
{
// Free private data
if( this->media )
ml_gc_decref( this->media );
if( !children.isEmpty() )
clearChildren();
}
AbstractPLItem* MLItem::child( int row ) const
{
if( row < 0 || row >= childCount() ) return NULL;
else return children.at( row );
}
input_item_t* MLItem::inputItem()
{
return ml_CreateInputItem( p_ml, id( MLMEDIA_ID ) );
}
/**
* @brief Get a QVariant representing the data on a column
* @param column
* @return The QVariant may be formed of a int, QString
* Use toString() to print it on the screen, except for pixmaps
*/
QVariant MLItem::data( ml_select_e columntype ) const
{
ml_person_t *p_people = NULL, *p_person = NULL;
QVariant ret;
QString temp;
#define sget(a) if(media->a) ret = qfu(media->a);
#define iget(a) if(media->a) ret = QVariant(media->a);
vlc_mutex_lock( &media->lock );
switch( columntype )
{
case ML_ALBUM:
sget( psz_album );
break;
case ML_ALBUM_ID:
iget( i_album_id );
break;
case ML_ARTIST:
vlc_mutex_unlock( &media->lock );
p_people = ml_GetPersonsFromMedia( p_ml, media, ML_PERSON_ARTIST );
vlc_mutex_lock( &media->lock );
p_person = p_people;
while( p_person )
{
if( !EMPTY_STR( p_person->psz_name ) )
{
temp.isEmpty() ? temp = qfu( p_person->psz_name ) :
temp.append( "," ).append( qfu( p_person->psz_name ) );
}
p_person = p_person->p_next;
}
ml_FreePeople( p_people );
ret = temp;
break;
case ML_COVER:
sget( psz_cover );
break;
case ML_DURATION:
if ( media->i_duration )
ret = QTime().addSecs( media->i_duration/1000000 ).toString( "HH:mm:ss" );
break;
case ML_EXTRA:
sget( psz_extra );
break;
case ML_GENRE:
sget( psz_genre );
break;
case ML_ID:
iget( i_id );
break;
case ML_LAST_PLAYED:
if( media->i_last_played > 0 )
{
QDateTime time( QDate(1970,1,1) );
ret = time.addSecs( qint64( media->i_last_played ) );
}
break;
case ML_ORIGINAL_TITLE:
sget( psz_orig_title );
break;
case ML_PLAYED_COUNT:
iget( i_played_count );
break;
// case ML_ROLE: return qtr( "Role" );
case ML_SCORE:
if ( media->i_score ) iget( i_score );
break;
case ML_TITLE:
temp = qfu( media->psz_title );
/* If no title, return filename */
if( temp.isEmpty() )
{
vlc_mutex_unlock( &media->lock );
QUrl uri = getURI();
vlc_mutex_lock( &media->lock );
if ( uri.scheme() != "file" )
{
ret = QUrl::fromPercentEncoding( uri.toString().toUtf8() );
}
else
{
QFileInfo p_file( uri.toLocalFile() );
ret = p_file.fileName().isEmpty() ? p_file.absoluteFilePath()
: p_file.fileName();
}
} else {
ret = temp;
}
break;
case ML_TRACK_NUMBER:
if ( media->i_track_number ) iget( i_track_number );
break;
case ML_TYPE:
if( media->i_type & ML_AUDIO )
temp = "Audio";
if( media->i_type & ML_VIDEO )
temp = "Video";
if( media->i_type & ML_STREAM )
{
if( temp.isEmpty() ) temp = "Stream";
else temp += " stream";
}
if( media->i_type & ML_REMOVABLE )
{
if( temp.isEmpty() ) temp = "Removable media";
else temp += " (removable media)";
}
if( media->i_type & ML_NODE )
{
if( temp.isEmpty() ) temp = "Playlist";
else temp += " (Playlist)";
}
if( temp.isEmpty() )
temp = qtr( "Unknown" );
ret = temp;
break;
case ML_URI:
sget( psz_uri );
break;
case ML_VOTE:
if ( media->i_vote ) iget( i_vote );
break;
case ML_YEAR:
if ( media->i_year ) iget( i_year );
break;
default:
break;
}
vlc_mutex_unlock( &media->lock );
#undef sget
#undef iget
return ret;
}
bool MLItem::setData( ml_select_e meta, const QVariant &data )
{
# define setmeta(a) ml_LockMedia(media); free(media->a); \
media->a = strdup( qtu(data.toString()) ); ml_UnlockMedia( media ); \
goto update;
switch( meta )
{
/* String values */
case ML_ALBUM: setmeta( psz_album );
case ML_ARTIST: ml_DeletePersonTypeFromMedia( media, ML_PERSON_ARTIST );
ml_CreateAppendPersonAdv( &media->p_people,
ML_PERSON_ARTIST, (char*)qtu(data.toString()), 0 );
return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id( MLMEDIA_ID ),
ML_PEOPLE, ML_PERSON_ARTIST, qtu( data.toString() ) ) == VLC_SUCCESS;
case ML_EXTRA: setmeta( psz_extra );
case ML_GENRE: setmeta( psz_genre );
case ML_ORIGINAL_TITLE: setmeta( psz_orig_title );
case ML_TITLE: setmeta( psz_title );
update:
Q_ASSERT( qtu( data.toString() ) );
return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id( MLMEDIA_ID ),
meta, qtu( data.toString() ) ) == VLC_SUCCESS;
/* Modifiable integers */
case ML_TRACK_NUMBER:
case ML_YEAR:
return ml_UpdateSimple( p_ml, ML_MEDIA, NULL, id( MLMEDIA_ID ),
meta, data.toInt() ) == VLC_SUCCESS;
// TODO case ML_VOTE:
/* Non modifiable meta */
default:
return false;
}
# undef setmeta
}
int MLItem::id( int type )
{
switch( type )
{
case INPUTITEM_ID:
return inputItem()->i_id;
case MLMEDIA_ID:
return media->i_id;
default:
case PLAYLIST_ID:
assert( NULL );
return -1;
}
}
ml_media_t* MLItem::getMedia() const
{
return media;
}
QUrl MLItem::getURI() const
{
QString uri;
vlc_mutex_lock( &media->lock );
uri = qfu( media->psz_uri );
vlc_mutex_unlock( &media->lock );
if ( uri.isEmpty() ) return QUrl(); // This should be rootItem
QUrl url = QUrl::fromEncoded( uri.toUtf8(), QUrl::TolerantMode );
if ( url.scheme().isEmpty() ) url.setScheme( "file" );
return url;
}
QString MLItem::getTitle() const
{
QString title;
vlc_mutex_lock( &media->lock );
title = QString( media->psz_title );
vlc_mutex_unlock( &media->lock );
return title;
}
bool MLItem::operator<( MLItem* item )
{
int ret = compareMeta( getMedia(), item->getMedia(), ML_ALBUM );
if( ret == -1 )
return true;
else return false;
}
#endif
/*****************************************************************************
* ml_item.hpp: the SQL media library's result item
*****************************************************************************
* Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
* $Id$
*
* Authors: Antoine Lejeune <phytos@videolan.org>
* Jean-Philippe André <jpeg@videolan.org>
* Rémi Duraffort <ivoire@videolan.org>
* Adrien Maglo <magsoft@videolan.org>
* Srikanth Raju <srikiraju#gmail#com>
*
* 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 _MEDIA_LIBRARY_MLITEM_H
#define _MEDIA_LIBRARY_MLITEM_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SQL_MEDIA_LIBRARY
#include <vlc_common.h>
#include <vlc_interface.h>
#include <vlc_media_library.h>
#include "playlist_item.hpp"
#include "ml_model.hpp"
#include "qt4.hpp"
class MLModel;
class MLItem : public AbstractPLItem
{
friend class MLModel;
public:
MLItem( intf_thread_t *_p_intf,
ml_media_t *p_media, MLItem *p_parent );
virtual ~MLItem();
bool operator<( MLItem* item );
private:
/* AbstractPLItem */
int id( int type );
input_item_t *inputItem();
AbstractPLItem* child( int row ) const;
virtual QUrl getURI() const;
virtual QString getTitle() const;
/* Local */
QVariant data( ml_select_e meta ) const;
bool setData( ml_select_e meta, const QVariant &data );
// Media structure connections
ml_media_t* getMedia() const;
ml_media_t* media;
media_library_t* p_ml;
};
#endif
#endif
/*****************************************************************************
* ml_model.cpp: the SQL media library's model
*****************************************************************************
* Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
* $Id$
*
* Authors: Antoine Lejeune <phytos@videolan.org>
* Jean-Philippe André <jpeg@videolan.org>
* Rémi Duraffort <ivoire@videolan.org>
* Adrien Maglo <magsoft@videolan.org>
* Srikanth Raju <srikiraju#gmail#com>
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SQL_MEDIA_LIBRARY
#include <QUrl>
#include <QMenu>
#include <QMimeData>
#include <QApplication>
#include "ml_item.hpp"
#include "ml_model.hpp"
#include "dialogs/playlist.hpp"
#include "components/playlist/sorting.h"
#include "dialogs_provider.hpp"
#include "input_manager.hpp" /* THEMIM */
#include "util/qt_dirs.hpp"
#include <assert.h>
#include <vlc_intf_strings.h>
static int mediaAdded( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *data );
static int mediaDeleted( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *data );
static int mediaUpdated( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *data );
/* Register ML Events */
const QEvent::Type MLEvent::MediaAdded_Type =
(QEvent::Type)QEvent::registerEventType();
const QEvent::Type MLEvent::MediaRemoved_Type =
(QEvent::Type)QEvent::registerEventType();
const QEvent::Type MLEvent::MediaUpdated_Type =
(QEvent::Type)QEvent::registerEventType();
/**
* @brief Definition of the result item model for the result tree
* @param parent the parent Qt object
*/
MLModel::MLModel( intf_thread_t* _p_intf, QObject *parent )
:VLCModel( _p_intf, parent )
{
p_ml = ml_Get( p_intf );
if ( !p_ml ) return;
vlc_array_t *p_result_array = vlc_array_new();
if ( p_result_array )
{
ml_Find( p_ml, p_result_array, ML_MEDIA );
insertResultArray( p_result_array );
ml_DestroyResultArray( p_result_array );
vlc_array_destroy( p_result_array );
}
var_AddCallback( p_ml, "media-added", mediaAdded, this );
var_AddCallback( p_ml, "media-deleted", mediaDeleted, this );
var_AddCallback( p_ml, "media-meta-change", mediaUpdated, this );
}
/**
* @brief Simple destructor for the model
*/
MLModel::~MLModel()
{
if ( !p_ml ) return;
var_DelCallback( p_ml, "media-meta-change", mediaUpdated, this );
var_DelCallback( p_ml, "media-deleted", mediaDeleted, this );
var_DelCallback( p_ml, "media-added", mediaAdded, this );
}
void MLModel::removeAll()
{
vlc_array_t* p_where = vlc_array_new();
if ( !p_where ) return;
int rows = rowCount();
if( rows > 0 )
{
beginRemoveRows( createIndex( 0, 0 ), 0, rows-1 );
QList< MLItem* >::iterator it = items.begin();
ml_element_t p_find[ items.count() ];
int i = 0;
while( it != items.end() )
{
p_find[i].criteria = ML_ID;
p_find[i].value.i = (*it)->id( MLMEDIA_ID );
vlc_array_append( p_where, & p_find[i++] );
delete *it;
it++;
}
ml_Delete( p_ml, p_where );
items.clear();
endRemoveRows();
}
vlc_array_destroy( p_where );
reset();
}
QModelIndex MLModel::index( int row, int column,
const QModelIndex &parent ) const
{
if( parent.isValid() || row >= items.count() )
return QModelIndex();
else
{
QModelIndex idx = createIndex( row, column, items.value( row ) );
return idx;
}
}
QModelIndex MLModel::parent(const QModelIndex & ) const
{
return QModelIndex();
}
void MLModel::filter( const QString& search_text, const QModelIndex & root, bool b_recursive )
{
Q_UNUSED( search_text ); Q_UNUSED( root ); Q_UNUSED( b_recursive );
/* FIXME */
}
void MLModel::sort( const int column, Qt::SortOrder order )
{
Q_UNUSED( column ); Q_UNUSED( order );
}
/**
* @brief Return the index of currently playing item
*/
QModelIndex MLModel::currentIndex() const
{
input_thread_t *p_input_thread = THEMIM->getInput();
if( !p_input_thread ) return QModelIndex();
input_item_t* p_iitem = input_GetItem( p_input_thread );
int i = 0;
foreach( MLItem* item, items )
{
if ( item->inputItem() == p_iitem )
return index( i, 0 );
i++;
}
return QModelIndex();
}
QModelIndex MLModel::indexByPLID( const int i_plid, const int c ) const
{
Q_UNUSED( i_plid ); Q_UNUSED( c );
return QModelIndex(); /* FIXME ? */
}
QModelIndex MLModel::indexByInputItemID( const int i_inputitem_id, const int c ) const
{
Q_UNUSED( c );
foreach( MLItem* item, items )
if ( item->id( INPUTITEM_ID ) == i_inputitem_id )
{
return index( items.indexOf( item ), 0 );
}
return QModelIndex();
}
/**
* @brief This returns the type of data shown in the specified column
* @param column must be valid
* @return The type, or ML_END in case of error
*/
ml_select_e MLModel::columnType( int logicalindex ) const
{
if( logicalindex < 0 || logicalindex >= columnCount() ) return ML_END;
return meta_to_mlmeta( columnToMeta( logicalindex ) );
}
Qt::ItemFlags MLModel::flags(const QModelIndex &index) const
{
if( !index.isValid() )
return 0;
if( isEditable( index ) )
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled
| Qt::ItemIsEditable;
else
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
}
bool MLModel::isEditable( const QModelIndex &index ) const
{
if( !index.isValid() )
return false;
ml_select_e type = columnType( index.column() );
switch( type )
{
// Read-only members: not editable
case ML_ALBUM_ID:
case ML_ARTIST_ID:
case ML_DURATION:
case ML_ID:
case ML_LAST_PLAYED:
case ML_PLAYED_COUNT:
case ML_TYPE:
return false;
// Read-write members: editable
case ML_ALBUM:
case ML_ARTIST:
case ML_COVER:
case ML_EXTRA:
case ML_GENRE:
case ML_ORIGINAL_TITLE:
// case ML_ROLE:
case ML_SCORE:
case ML_TITLE:
case ML_TRACK_NUMBER:
case ML_URI:
case ML_VOTE:
case ML_YEAR:
return true;
default:
return false;
}
}
QMimeData* MLModel::mimeData( const QModelIndexList &indexes ) const
{
QList< QUrl > urls;
QList< int > rows;
foreach( QModelIndex idx, indexes )
{
if( rows.contains( idx.row() ) )
continue;
rows.append( idx.row() );
AbstractPLItem* item = static_cast<AbstractPLItem*>( idx.internalPointer() );
urls.append( item->getURI() );
}
QMimeData *data = new QMimeData;
data->setUrls( urls );
return data;
}
int MLModel::rowCount( const QModelIndex & parent ) const
{
if( !parent.isValid() )
return items.count();
return 0;
}
void MLModel::rebuild( playlist_item_t *p )
{
Q_UNUSED( p );
emit layoutChanged();
}
void MLModel::doDelete( QModelIndexList list )
{
for (int i = 0; i < list.count(); ++i)
{
const QModelIndex &index = list.at( i );
if ( !index.isValid() ) break;
int id = itemId( list.at(i), MLMEDIA_ID );
ml_DeleteSimple( p_ml, id );
/* row will be removed by the lib callback */
}
}
bool MLModel::removeRows( int row, int count, const QModelIndex &parent )
{
/* !warn probably not a good idea to expose this as public method */
if ( row < 0 || count < 0 ) return false;
beginRemoveRows( parent, row, row );
MLItem *item = items.takeAt( row );
assert( item );
if ( likely( item ) ) delete item;
endRemoveRows();
return true;
}
QVariant MLModel::data( const QModelIndex &index, const int role ) const
{
if( index.isValid() )
{
if( role == Qt::DisplayRole || role == Qt::EditRole )
{
MLItem *it = static_cast<MLItem*>( index.internalPointer() );
if( !it ) return QVariant();
QVariant tmp = it->data( columnType( index.column() ) );
return tmp;
}
else if( role == Qt::DecorationRole && index.column() == 0 )
{
/*
FIXME: (see ml_type_e)
media->type uses flags for media type information
*/
return QVariant( icons[ getInputItem(index)->i_type ] );
}
else if( role == IsLeafNodeRole )
return isLeaf( index );
else if( role == IsCurrentsParentNodeRole )
return isParent( index, currentIndex() );
else if( role == IsCurrentRole )
{
return QVariant( isCurrent( index ) );
}
}
return QVariant();
}
bool MLModel::setData( const QModelIndex &idx, const QVariant &value,
int role )
{
if( role != Qt::EditRole || !idx.isValid() ) return false;
MLItem *media = static_cast<MLItem*>( idx.internalPointer() );
media->setData( columnType( idx.column() ), value );
emit dataChanged( idx, idx );
return true;
}
/**
* @brief Insert a media to the model in a given row
* @param p_media the media to append
* @param row the future row for this media, -1 to append at the end
* @return a VLC error code
*/
int MLModel::insertMedia( ml_media_t *p_media, int row )
{
// Some checks
if( !p_media || row < -1 || row > rowCount() )
return VLC_EGENERIC;
if( row == -1 )
row = rowCount();
// Create and insert the item
MLItem *item = new MLItem( p_intf, p_media, NULL );
items.append( item );
return VLC_SUCCESS;
}
/**
* @brief Insert all medias from a result array to the model
* @param p_result_array the medias to append
* @return see insertMedia
*/
int MLModel::insertResultArray( vlc_array_t *p_result_array, int row )
{
int i_ok = VLC_SUCCESS;
int count = vlc_array_count( p_result_array );
if( !count )
return i_ok;
emit layoutAboutToBeChanged();
if( row == -1 )
row = rowCount();
// Signal Qt that we will insert rows
beginInsertRows( createIndex( -1, -1 ), row, row + count-1 );
// Loop and insert
for( int i = 0; i < count; ++i )
{
ml_result_t *p_result = (ml_result_t*)
vlc_array_item_at_index( p_result_array, i );
if( !p_result || p_result->type != ML_TYPE_MEDIA )
continue;
i_ok = insertMedia( p_result->value.p_media, row + i );
if( i_ok != VLC_SUCCESS )
break;
}
// Signal we're done
endInsertRows();
emit layoutChanged();
return i_ok;
}
bool MLModel::event( QEvent *event )
{
if ( event->type() == MLEvent::MediaAdded_Type )
{
event->accept();
MLEvent *e = static_cast<MLEvent *>(event);
vlc_array_t* p_result = vlc_array_new();
if ( ml_FindMedia( e->p_ml, p_result, ML_ID, e->ml_media_id ) == VLC_SUCCESS )
{
insertResultArray( p_result );
ml_DestroyResultArray( p_result );
}
vlc_array_destroy( p_result );
return true;
}
else if( event->type() == MLEvent::MediaRemoved_Type )
{
event->accept();
MLEvent *e = static_cast<MLEvent *>(event);
removeRow( getIndexByMLID( e->ml_media_id ).row() );
return true;
}
else if( event->type() == MLEvent::MediaUpdated_Type )
{
event->accept();
/* Never implemented... */
return true;
}
return VLCModel::event( event );
}
/** **************************************************************************
* \brief Add a media to the playlist
*
* \param id the item id
* @todo this code must definitely be done by the ML core
*****************************************************************************/
static void AddItemToPlaylist( int i_media_id, bool bPlay, media_library_t* p_ml,
bool bRenew )
{
input_item_t *p_item = ml_CreateInputItem( p_ml, i_media_id );
if( !p_item )
{
msg_Dbg( p_ml, "unable to create input item for media %d",
i_media_id );
return;
}
playlist_t *p_playlist = THEPL;
playlist_item_t *p_playlist_item = NULL;
playlist_Lock( p_playlist );
if( !bRenew )
{
p_playlist_item = playlist_ItemGetByInput( p_playlist, p_item );
}
if( !p_playlist_item || p_playlist_item->i_id == 1 )
{
playlist_AddInput( p_playlist, p_item,
PLAYLIST_APPEND,
PLAYLIST_END, true, true );
p_playlist_item = playlist_ItemGetByInput( p_playlist, p_item );
}
playlist_Unlock( p_playlist );
if( !p_playlist_item || p_playlist_item->i_id == 1 )
{
msg_Dbg( p_ml, "could not find playlist item %s (%s:%d)",
p_item->psz_name, __FILE__, __LINE__ );
return;
}
/* Auto play item */
if( bPlay ) // || p_playlist->status.i_status == PLAYLIST_STOPPED )
{
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, false,
NULL, p_playlist_item );
}
vlc_gc_decref( p_item );
}
void MLModel::activateItem( const QModelIndex &idx )
{
if( !idx.isValid() ) return;
AddItemToPlaylist( itemId( idx, MLMEDIA_ID ), true, p_ml, true );
}
bool MLModel::action( QAction *action, const QModelIndexList &indexes )
{
actionsContainerType a = action->data().value<actionsContainerType>();
input_item_t *p_input;
switch ( a.action )
{
case ACTION_PLAY:
if ( ! indexes.empty() && indexes.first().isValid() )
{
activateItem( indexes.first() );
return true;
}
break;
case ACTION_ADDTOPLAYLIST:
foreach( const QModelIndex &index, indexes )
{
if( !index.isValid() ) return false;
AddItemToPlaylist( itemId( index, MLMEDIA_ID ), false, p_ml, true );
}
return true;
case ACTION_REMOVE:
doDelete( indexes );
return true;
case ACTION_SORT:
break;
case ACTION_CLEAR:
removeAll();
return true;
case ACTION_ENQUEUEFILE:
foreach( const QString &uri, a.uris )
playlist_Add( THEPL, uri.toAscii().constData(),
NULL, PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, false, pl_Unlocked );
return true;
case ACTION_ENQUEUEDIR:
if( a.uris.isEmpty() ) return false;
p_input = input_item_New( a.uris.first().toAscii().constData(), NULL );
if( unlikely( p_input == NULL ) ) return false;
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND,
PLAYLIST_END, true, pl_Unlocked );
vlc_gc_decref( p_input );
return true;
case ACTION_ENQUEUEGENERIC:
foreach( const QString &uri, a.uris )
{
p_input = input_item_New( qtu( uri ), NULL );
/* Insert options */
foreach( const QString &option, a.options.split( " :" ) )
{
QString temp = colon_unescape( option );
if( !temp.isEmpty() )
input_item_AddOption( p_input, qtu( temp ),
VLC_INPUT_OPTION_TRUSTED );
}
/* FIXME: playlist_AddInput() can fail */
playlist_AddInput( THEPL, p_input,
PLAYLIST_APPEND | PLAYLIST_PREPARSE,
PLAYLIST_END, false, pl_Unlocked );
vlc_gc_decref( p_input );
}
return true;
default:
break;
}
return false;
}
bool MLModel::isSupportedAction( actions action, const QModelIndex &index ) const
{
switch ( action )
{
case ACTION_ADDTOPLAYLIST:
return index.isValid();
case ACTION_SORT:
return false;
case ACTION_PLAY:
case ACTION_STREAM:
case ACTION_SAVE:
case ACTION_INFO:
case ACTION_REMOVE:
return index.isValid();
case ACTION_EXPLORE:
if( index.isValid() )
return getURI( index ).startsWith( "file://" );
case ACTION_CREATENODE:
return false;
case ACTION_CLEAR:
return rowCount() && canEdit();
case ACTION_ENQUEUEFILE:
case ACTION_ENQUEUEDIR:
case ACTION_ENQUEUEGENERIC:
return canEdit();
default:
return false;
}
return false;
}
QModelIndex MLModel::rootIndex() const
{
// FIXME
return QModelIndex();
}
bool MLModel::isTree() const
{
// FIXME ?
return false;
}
bool MLModel::canEdit() const
{
/* can always insert */
return true;
}
QModelIndex MLModel::getIndexByMLID( int id ) const
{
for( int i = 0; i < rowCount( ); i++ )
{
QModelIndex idx = index( i, 0 );
MLItem *item = static_cast< MLItem* >( idx.internalPointer() );
if( item->id( MLMEDIA_ID ) == id ) return idx;
}
return QModelIndex();
}
bool MLModel::isParent( const QModelIndex &index, const QModelIndex &current) const
{
Q_UNUSED( index ); Q_UNUSED( current );
return false;
}
bool MLModel::isLeaf( const QModelIndex &index ) const
{
Q_UNUSED( index );
return true;
}
/* ML Callbacks handling */
inline void postMLEvent( vlc_object_t *p_this, QEvent::Type type, void *data, int32_t i )
{
MLModel* p_model = static_cast<MLModel*>(data);
media_library_t *p_ml = (media_library_t *) p_this;
QApplication::postEvent( p_model, new MLEvent( type, p_ml, i ) );
}
static int mediaAdded( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *data )
{
VLC_UNUSED( psz_var ); VLC_UNUSED( oldval );
postMLEvent( p_this, MLEvent::MediaAdded_Type, data, newval.i_int );
return VLC_SUCCESS;
}
static int mediaDeleted( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *data )
{
VLC_UNUSED( psz_var ); VLC_UNUSED( oldval );
postMLEvent( p_this, MLEvent::MediaRemoved_Type, data, newval.i_int );
return VLC_SUCCESS;
}
static int mediaUpdated( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval,
void *data )
{
VLC_UNUSED( psz_var ); VLC_UNUSED( oldval );
postMLEvent( p_this, MLEvent::MediaUpdated_Type, data, newval.i_int );
return VLC_SUCCESS;
}
#endif
/*****************************************************************************
* ml_model.hpp SQL ML model
*****************************************************************************
* Copyright (C) 2008-2011 the VideoLAN Team and AUTHORS
* $Id$
*
* Authors: Antoine Lejeune <phytos@videolan.org>
* Jean-Philippe André <jpeg@videolan.org>
* Rémi Duraffort <ivoire@videolan.org>
* Adrien Maglo <magsoft@videolan.org>
* Srikanth Raju <srikiraju#gmail#com>
*
* 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 _MEDIA_LIBRARY_MLMODEL_H
#define _MEDIA_LIBRARY_MLMODEL_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SQL_MEDIA_LIBRARY
#include <vlc_common.h>
#include <vlc_interface.h>
#include <vlc_media_library.h>
#include "components/playlist/vlc_model.hpp"
#include "ml_item.hpp"
#include "qt4.hpp"
#include <QMutex>
#include <QEvent>
class MLItem;
/** *************************************************************************
* \brief ML Events class because we don't want direct callbacks
****************************************************************************/
class MLEvent : public QEvent
{
public:
static const QEvent::Type MediaAdded_Type;
static const QEvent::Type MediaRemoved_Type;
static const QEvent::Type MediaUpdated_Type;
MLEvent( QEvent::Type type, media_library_t *_p_ml, int32_t _ml_media_id ) :
QEvent( type ), ml_media_id( _ml_media_id ), p_ml( _p_ml ) {};
int32_t ml_media_id;
media_library_t * p_ml; /* store instance */
};
/** *************************************************************************
* \brief Tree model for the result list
****************************************************************************/
class MLModel : public VLCModel
{
Q_OBJECT;
public:
// Basic QAbstractItemModel implementation
MLModel( intf_thread_t *_p_intf, QObject *parent = NULL );
virtual ~MLModel();
QVariant data( const QModelIndex &idx, const int role = Qt::DisplayRole ) const;
bool setData( const QModelIndex &idx, const QVariant &value,
int role = Qt::EditRole );
QModelIndex index( int row, int column,
const QModelIndex & parent = QModelIndex() ) const;
int rowCount( const QModelIndex & parent = QModelIndex() ) const;
QModelIndex parent( const QModelIndex& ) const;
Qt::ItemFlags flags( const QModelIndex& ) const;
QMimeData* mimeData( const QModelIndexList & indexes ) const;
virtual bool removeRows( int row, int count, const QModelIndex & parent = QModelIndex() );
virtual void sort( const int column, Qt::SortOrder order = Qt::AscendingOrder );
// Custom functions
bool isEditable( const QModelIndex& ) const;
ml_select_e columnType( int column ) const;
virtual bool event( QEvent * e );
QModelIndex getIndexByMLID( int id ) const;
/* VLCModelSubInterface */
virtual void rebuild( playlist_item_t * p = NULL );
virtual void doDelete( QModelIndexList selected );
virtual void createNode( QModelIndex, QString ) {};
virtual void removeAll();
virtual QModelIndex rootIndex() const;
virtual void filter( const QString& search_text, const QModelIndex & root, bool b_recursive );
virtual QModelIndex currentIndex() const;
virtual QModelIndex indexByPLID( const int i_plid, const int c ) const;
virtual QModelIndex indexByInputItemID( const int i_inputitem_id, const int c ) const;
virtual bool isTree() const;
virtual bool canEdit() const;
virtual bool action( QAction *action, const QModelIndexList &indexes );
virtual bool isSupportedAction( actions action, const QModelIndex & ) const;
/* VLCModelSubInterface virtual slots */
virtual void activateItem( const QModelIndex &index );
protected:
/* VLCModel subclassing */
bool isParent( const QModelIndex &index, const QModelIndex &current) const;
bool isLeaf( const QModelIndex &index ) const;
private:
/* custom */
int insertMedia( ml_media_t *p_media, int row = -1 );
int insertResultArray( vlc_array_t *p_result_array, int row = -1 );
QList< MLItem* > items;
media_library_t* p_ml;
};
#endif
#endif
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "components/playlist/standardpanel.hpp" /* MainView */ #include "components/playlist/standardpanel.hpp" /* MainView */
#include "components/playlist/selector.hpp" /* PLSelector */ #include "components/playlist/selector.hpp" /* PLSelector */
#include "components/playlist/playlist_model.hpp" /* PLModel */ #include "components/playlist/playlist_model.hpp" /* PLModel */
#include "components/playlist/ml_model.hpp" /* MLModel */
#include "components/interface_widgets.hpp" /* CoverArtLabel */ #include "components/interface_widgets.hpp" /* CoverArtLabel */
#include "util/searchlineedit.hpp" #include "util/searchlineedit.hpp"
...@@ -100,11 +99,6 @@ PlaylistWidget::PlaylistWidget( intf_thread_t *_p_i, QWidget *_par ) ...@@ -100,11 +99,6 @@ PlaylistWidget::PlaylistWidget( intf_thread_t *_p_i, QWidget *_par )
model->setModel( VLCProxyModel::PL_MODEL, plmodel ); model->setModel( VLCProxyModel::PL_MODEL, plmodel );
model->switchToModel( VLCProxyModel::PL_MODEL ); model->switchToModel( VLCProxyModel::PL_MODEL );
#ifdef SQL_MEDIA_LIBRARY
MLModel *mlmodel = new MLModel( p_intf, model );
model->setModel( VLCProxyModel::SQLML_MODEL, mlmodel );
#endif
mainView = new StandardPLPanel( this, p_intf, p_root, selector, model ); mainView = new StandardPLPanel( this, p_intf, p_root, selector, model );
/* Location Bar */ /* Location Bar */
......
...@@ -240,12 +240,6 @@ void PLSelector::createItems() ...@@ -240,12 +240,6 @@ void PLSelector::createItems()
ml->treeItem()->setData( 0, SPECIAL_ROLE, QVariant( IS_ML ) ); ml->treeItem()->setData( 0, SPECIAL_ROLE, QVariant( IS_ML ) );
ml->treeItem()->setData( 0, Qt::DecorationRole, QIcon( ":/sidebar/library" ) ); ml->treeItem()->setData( 0, Qt::DecorationRole, QIcon( ":/sidebar/library" ) );
#ifdef SQL_MEDIA_LIBRARY
/* SQL ML */
ml = addItem( SQL_ML_TYPE, "SQL Media Library" )->treeItem();
ml->treeItem()->setData( 0, Qt::DecorationRole, QIcon( ":/sidebar/library" ) );
#endif
/* SD nodes */ /* SD nodes */
QTreeWidgetItem *mycomp = addItem( CATEGORY_TYPE, N_("My Computer"), false, true )->treeItem(); QTreeWidgetItem *mycomp = addItem( CATEGORY_TYPE, N_("My Computer"), false, true )->treeItem();
QTreeWidgetItem *devices = addItem( CATEGORY_TYPE, N_("Devices"), false, true )->treeItem(); QTreeWidgetItem *devices = addItem( CATEGORY_TYPE, N_("Devices"), false, true )->treeItem();
...@@ -377,14 +371,6 @@ void PLSelector::setSource( QTreeWidgetItem *item ) ...@@ -377,14 +371,6 @@ void PLSelector::setSource( QTreeWidgetItem *item )
item->setData( 0, CAP_SEARCH_ROLE, true ); item->setData( 0, CAP_SEARCH_ROLE, true );
} }
} }
#ifdef SQL_MEDIA_LIBRARY
else if( i_type == SQL_ML_TYPE )
{
emit categoryActivated( NULL, true );
curItem = item;
return;
}
#endif
curItem = item; curItem = item;
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "components/playlist/vlc_model.hpp" /* VLCModel */ #include "components/playlist/vlc_model.hpp" /* VLCModel */
#include "components/playlist/playlist_model.hpp" /* PLModel */ #include "components/playlist/playlist_model.hpp" /* PLModel */
#include "components/playlist/ml_model.hpp" /* MLModel */
#include "components/playlist/views.hpp" /* 3 views */ #include "components/playlist/views.hpp" /* 3 views */
#include "components/playlist/selector.hpp" /* PLSelector */ #include "components/playlist/selector.hpp" /* PLSelector */
#include "util/animators.hpp" /* PixmapAnimator */ #include "util/animators.hpp" /* PixmapAnimator */
...@@ -478,21 +477,9 @@ void StandardPLPanel::searchDelayed( const QString& searchText ) ...@@ -478,21 +477,9 @@ void StandardPLPanel::searchDelayed( const QString& searchText )
/* This activated by the selector selection */ /* This activated by the selector selection */
void StandardPLPanel::setRootItem( playlist_item_t *p_item, bool b ) void StandardPLPanel::setRootItem( playlist_item_t *p_item, bool b )
{ {
#ifdef SQL_MEDIA_LIBRARY
if( b )
{
msg_Dbg( p_intf, "Setting the SQL ML" );
if ( model->switchToModel( VLCProxyModel::SQLML_MODEL ) )
currentView->setModel( model );
}
else
#else
Q_UNUSED( b ); Q_UNUSED( b );
#endif
{
if ( model->switchToModel( VLCProxyModel::PL_MODEL ) ) if ( model->switchToModel( VLCProxyModel::PL_MODEL ) )
model->rebuild( p_item ); model->rebuild( p_item );
}
} }
void StandardPLPanel::browseInto( const QModelIndex &index ) void StandardPLPanel::browseInto( const QModelIndex &index )
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include "components/simple_preferences.hpp" #include "components/simple_preferences.hpp"
#include "components/preferences_widgets.hpp" #include "components/preferences_widgets.hpp"
#include "dialogs/ml_configuration.hpp"
#include <vlc_config_cat.h> #include <vlc_config_cat.h>
#include <vlc_configuration.h> #include <vlc_configuration.h>
...@@ -749,11 +748,6 @@ SPrefsPanel::SPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent, ...@@ -749,11 +748,6 @@ SPrefsPanel::SPrefsPanel( intf_thread_t *_p_intf, QWidget *_parent,
#else #else
ui.osGroupBox->hide(); ui.osGroupBox->hide();
#endif #endif
#ifdef SQL_MEDIA_LIBRARY
BUTTONACT( ui.sqlMLbtn, configML() );
#else
ui.sqlMLbtn->hide();
#endif
/* interface */ /* interface */
char *psz_intf = config_GetPsz( p_intf, "intf" ); char *psz_intf = config_GetPsz( p_intf, "intf" );
......
/*****************************************************************************
* ml_configuration.cpp: SQL ML's configuration dialog (folder view)
*****************************************************************************
* Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
* $Id$
*
* Authors: Antoine Lejeune <phytos@videolan.org>
* Jean-Philippe André <jpeg@videolan.org>
* Rémi Duraffort <ivoire@videolan.org>
* Adrien Maglo <magsoft@videolan.org>
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SQL_MEDIA_LIBRARY
#include "ml_configuration.hpp"
#include <QTreeView>
#include <QPushButton>
#include <QDialogButtonBox>
MLConfDialog *MLConfDialog::instance = NULL;
/** **************************************************************************
* MODEL FOR THE FILESYSTEM
*****************************************************************************/
Qt::ItemFlags MLDirModel::flags( const QModelIndex &index ) const
{
Qt::ItemFlags flags = QDirModel::flags( index );
flags |= Qt::ItemIsUserCheckable;
if( b_recursive )
{
for( int i = 0; i < monitoredDirs.count(); i++ )
{
if( filePath( index ).startsWith( monitoredDirs.at( i ) ) )
{
if( monitoredDirs.at( i ) != filePath( index ) )
flags ^= Qt::ItemIsEnabled;
break;
}
}
}
return flags;
}
QVariant MLDirModel::data( const QModelIndex &index, int role ) const
{
if( index.column() == 0 && role == Qt::CheckStateRole )
{
if( itemCheckState.contains( filePath( index ) ) )
return itemCheckState.value( filePath( index ) );
else if( b_recursive )
{
for( int i = 0; i < monitoredDirs.count(); i++ )
{
if( filePath( index ).startsWith( monitoredDirs.at( i ) ) )
return Qt::Checked;
}
return Qt::Unchecked;
}
else
return Qt::Unchecked;
}
return QDirModel::data( index, role );
}
bool MLDirModel::setData( const QModelIndex &index, const QVariant &value,
int role )
{
QModelIndex idx;
QModelIndex topLeft, bottomRight; // index to signal they have changed
if( role == Qt::CheckStateRole )
{
if( value == Qt::Checked )
{
monitoredDirs << filePath( index );
itemCheckState[filePath( index )] = Qt::Checked;
/* We have to make his parents Qt::PartiallyChecked */
idx = index.parent();
while( idx != QModelIndex() )
{
if( !( !b_recursive && monitoredDirs.contains( filePath(idx) ) ) )
itemCheckState[filePath(idx)] = Qt::PartiallyChecked;
topLeft = idx;
idx = idx.parent();
}
/* We have to remove his children that are monitored if we are
in recursive mode */
if( b_recursive )
{
for( int i = 0; i < monitoredDirs.count()-1; i++ )
{
if( monitoredDirs.at( i ).startsWith( filePath( index ) ) )
{
itemCheckState.take( monitoredDirs.at( i ) );
monitoredDirs.removeAt( i );
i--;
}
}
}
}
else if( monitoredDirs.removeOne( filePath( index ) ) )
{
itemCheckState.take( filePath( index ) );
/* We have to make his parent Qt::Unchecked
if index is his only child */
for( idx = index.parent(); idx != QModelIndex(); idx = idx.parent() )
{
if( monitoredDirs.count() == 0 )
{
itemCheckState.take( filePath(idx) );
topLeft = idx;
continue;
}
for( int i = 0; i < monitoredDirs.count(); i++ )
{
if( monitoredDirs.at( i ).startsWith( filePath( idx ) ) )
break;
itemCheckState.take( filePath(idx) );
topLeft = idx;
}
}
}
emit dataChanged( topLeft, index );
return true;
}
return QDirModel::setData( index, value, role );
}
int MLDirModel::columnCount( const QModelIndex & ) const
{
return 1;
}
void MLDirModel::reset( bool _b_recursive, vlc_array_t *p_array )
{
b_recursive = _b_recursive;
itemCheckState.clear();
monitoredDirs.clear();
for( int i = 0; i < vlc_array_count( p_array ); i++ )
{
setData( index( qfu((char*)vlc_array_item_at_index(p_array, i)) ),
Qt::Checked, Qt::CheckStateRole );
}
emit layoutChanged();
}
void MLDirModel::setRecursivity( bool _b_recursive )
{
/* If the selection becomes recursive, we may have to delete from
monitoredDirs some directories */
if( !b_recursive && _b_recursive )
{
for( int i = 0; i < monitoredDirs.count(); i++ )
{
for( int j = i+1; j < monitoredDirs.count(); j++ )
{
if( monitoredDirs.at( i ).startsWith( monitoredDirs.at( j ) ) )
{
setData( index( monitoredDirs.at( i ) ),
Qt::Unchecked, Qt::CheckStateRole );
i--;
}
else if( monitoredDirs.at( j ).startsWith( monitoredDirs.at( i ) ) )
setData( index( monitoredDirs.at( j ) ),
Qt::Unchecked, Qt::CheckStateRole );
}
}
}
b_recursive = _b_recursive;
emit layoutChanged();
}
/** **************************************************************************
* PREFERENCES DIALOG FOR THE MEDIA LIBRARY
*****************************************************************************/
MLConfDialog::MLConfDialog( QWidget *parent, intf_thread_t *_p_intf )
: QVLCDialog( parent, _p_intf ), p_intf( _p_intf )
{
p_monitored_dirs = NULL;
setWindowTitle( qtr( "Media library Preferences" ) );
setMinimumSize( 400, 300 );
setParent( parent, Qt::Window );
setWindowModality( Qt::NonModal );
resize( 550, 450 );
QGridLayout *main_layout = new QGridLayout( this );
/* Directories selection */
QStringList nameFilters;
model = new MLDirModel( nameFilters,
QDir::Dirs | QDir::NoDotAndDotDot,
QDir::Name, this );
QTreeView *tree = new QTreeView( this );
tree->setModel( model );
/* recursivity */
recursivity = new QCheckBox( qtr( "Subdirectory recursive scanning" ) );
synchronous = new QCheckBox( qtr( "Use safe transactions" ) );
/* Buttons */
QDialogButtonBox *buttonsBox = new QDialogButtonBox();
QPushButton *save = new QPushButton( qtr( "&Save" ) );
QPushButton *cancel = new QPushButton( qtr( "&Cancel" ) );
QPushButton *reset = new QPushButton( qtr( "&Reset" ) );
buttonsBox->addButton( save, QDialogButtonBox::AcceptRole );
buttonsBox->addButton( cancel, QDialogButtonBox::RejectRole );
buttonsBox->addButton( reset, QDialogButtonBox::ResetRole );
main_layout->addWidget( tree, 0, 0 );
main_layout->addWidget( recursivity, 1, 0 );
main_layout->addWidget( synchronous, 2, 0 );
main_layout->addWidget( buttonsBox, 3, 0 );
p_ml = ml_Get( p_intf );
init();
BUTTONACT( save, save() );
BUTTONACT( cancel, cancel() );
BUTTONACT( reset, reset() );
CONNECT( recursivity, toggled( bool ), model, setRecursivity( bool ) );
}
void MLConfDialog::init()
{
bool b_recursive = var_CreateGetBool( p_ml, "ml-recursive-scan" );
recursivity->setChecked( b_recursive );
bool b_sync = var_CreateGetBool( p_ml, "ml-synchronous" );
synchronous->setChecked( b_sync );
if( p_monitored_dirs )
vlc_array_destroy( p_monitored_dirs );
p_monitored_dirs = vlc_array_new();
ml_Control( p_ml, ML_GET_MONITORED, p_monitored_dirs );
model->reset( b_recursive, p_monitored_dirs );
}
void MLConfDialog::save()
{
QStringList newDirs = model->monitoredDirs;
QStringList toDelete;
for( int i = 0; i < vlc_array_count( p_monitored_dirs ); i++ )
{
if( newDirs.removeAll(
qfu((char*)vlc_array_item_at_index(p_monitored_dirs, i)) ) == 0 )
{
toDelete << qfu((char*)vlc_array_item_at_index(p_monitored_dirs, i));
}
}
for( int i = 0; i < toDelete.count(); i++ )
{
ml_Control( p_ml, ML_DEL_MONITORED, qtu( toDelete.at( i ) ) );
}
for( int i = 0; i < newDirs.count(); i++ )
{
ml_Control( p_ml, ML_ADD_MONITORED, qtu( newDirs.at( i ) ) );
}
var_SetBool( p_ml, "ml-recursive-scan", recursivity->isChecked() );
var_SetBool( p_ml, "ml-synchronous", synchronous->isChecked() );
init();
hide();
}
void MLConfDialog::cancel()
{
init();
hide();
}
void MLConfDialog::reset()
{
init();
}
#endif
/*****************************************************************************
* ml_configuration.hpp: SQL ML's configuration dialog (folder view)
*****************************************************************************
* Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
* $Id$
*
* Authors: Antoine Lejeune <phytos@videolan.org>
* Jean-Philippe André <jpeg@videolan.org>
* Rémi Duraffort <ivoire@videolan.org>
* Adrien Maglo <magsoft@videolan.org>
*
* 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 _MEDIA_LIBRARY_CONFIG_H
#define _MEDIA_LIBRARY_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef SQL_MEDIA_LIBRARY
#include <vlc_common.h>
#include <vlc_media_library.h>
#include "util/qvlcframe.hpp"
#include <QDirModel>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QPushButton>
/** Classes in this header */
class MLDirModel;
class MLConfDialog;
/** *************************************************************************
* \brief Model representing the filesystem and whose items are checkable
****************************************************************************/
class MLDirModel : public QDirModel
{
Q_OBJECT;
public:
MLDirModel( const QStringList &nameFilters, QDir::Filters filters,
QDir::SortFlags sort, QObject *parent = 0 )
: QDirModel( nameFilters, filters, sort, parent ) {};
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
virtual QVariant data( const QModelIndex &index, int role ) const;
virtual bool setData( const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole );
int columnCount( const QModelIndex &parent = QModelIndex() ) const;
void reset( bool, vlc_array_t *);
QStringList monitoredDirs;
private:
bool b_recursive;
QMap<QString, Qt::CheckState> itemCheckState;
intf_thread_t *p_intf;
media_library_t* p_ml;
public slots:
void setRecursivity( bool );
};
/** *************************************************************************
* \brief Configuration dialog for the media library
****************************************************************************/
class MLConfDialog : public QVLCDialog
{
Q_OBJECT;
public:
MLConfDialog( QWidget *, intf_thread_t * );
private:
void init();
vlc_array_t *p_monitored_dirs;
media_library_t *p_ml;
intf_thread_t *p_intf;
MLDirModel *model;
QCheckBox *recursivity;
QCheckBox *synchronous;
static MLConfDialog *instance;
private slots:
void save();
void cancel();
void reset();
void close() { save(); };
};
#endif
#endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>686</width> <width>686</width>
<height>656</height> <height>667</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
...@@ -318,16 +318,7 @@ ...@@ -318,16 +318,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QGridLayout" name="gridLayout_7"> <layout class="QGridLayout" name="gridLayout_7">
<property name="leftMargin"> <property name="margin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="1" column="1"> <item row="1" column="1">
...@@ -432,48 +423,41 @@ ...@@ -432,48 +423,41 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="treePlaylist"> <widget class="QCheckBox" name="OneInterfaceMode">
<property name="text"> <property name="text">
<string>Display playlist tree</string> <string>Allow only one instance</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="EnqueueOneInterfaceMode"> <widget class="QCheckBox" name="oneInstanceFromFile">
<property name="text"> <property name="text">
<string>Enqueue items into playlist in one instance mode</string> <string>Use only one instance when started from file manager</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="0">
<widget class="QCheckBox" name="playPauseBox"> <widget class="QCheckBox" name="treePlaylist">
<property name="text"> <property name="text">
<string>Pause on the last frame of a video</string> <string>Display playlist tree</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="2" column="1">
<widget class="QCheckBox" name="OneInterfaceMode"> <widget class="QCheckBox" name="playPauseBox">
<property name="text"> <property name="text">
<string>Allow only one instance</string> <string>Pause on the last frame of a video</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="4" column="1">
<widget class="QComboBox" name="artFetcher"/> <widget class="QComboBox" name="artFetcher"/>
</item> </item>
<item row="5" column="0"> <item row="0" column="1">
<widget class="QPushButton" name="sqlMLbtn"> <widget class="QCheckBox" name="EnqueueOneInterfaceMode">
<property name="text">
<string>Configure Media Library</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="oneInstanceFromFile">
<property name="text"> <property name="text">
<string>Use only one instance when started from file manager</string> <string>Enqueue items into playlist in one instance mode</string>
</property> </property>
</widget> </widget>
</item> </item>
...@@ -678,7 +662,6 @@ ...@@ -678,7 +662,6 @@
<tabstop>treePlaylist</tabstop> <tabstop>treePlaylist</tabstop>
<tabstop>playPauseBox</tabstop> <tabstop>playPauseBox</tabstop>
<tabstop>artFetcher</tabstop> <tabstop>artFetcher</tabstop>
<tabstop>sqlMLbtn</tabstop>
<tabstop>updatesBox</tabstop> <tabstop>updatesBox</tabstop>
<tabstop>updatesDays</tabstop> <tabstop>updatesDays</tabstop>
<tabstop>saveRecentlyPlayed</tabstop> <tabstop>saveRecentlyPlayed</tabstop>
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
*/ */
#include "pictureflow.hpp" #include "pictureflow.hpp"
#include "components/playlist/ml_model.hpp"
#include <QApplication> #include <QApplication>
#include <QImage> #include <QImage>
......
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