Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (6)
Showing
with 472 additions and 157 deletions
......@@ -422,6 +422,7 @@ nodist_libqt_plugin_la_SOURCES = \
gui/qt/medialibrary/mlalbumtrackmodel.moc.cpp \
gui/qt/medialibrary/mlartist.moc.cpp \
gui/qt/medialibrary/mlartistmodel.moc.cpp \
gui/qt/medialibrary/mlbookmarkmodel.moc.cpp \
gui/qt/medialibrary/mlbasemodel.moc.cpp \
gui/qt/medialibrary/mlfoldersmodel.moc.cpp \
gui/qt/medialibrary/mlgenremodel.moc.cpp \
......@@ -860,6 +861,7 @@ libqt_plugin_la_QML = \
gui/qt/network/qml/NetworkThumbnailItem.qml \
gui/qt/network/qml/ServicesHomeDisplay.qml \
gui/qt/player/qml/qmldir \
gui/qt/player/qml/Bookmarks.qml \
gui/qt/player/qml/ControlBar.qml \
gui/qt/player/qml/ControlbarControls.qml \
gui/qt/player/qml/PlaybackSpeed.qml \
......
......@@ -44,7 +44,7 @@ BookmarksDialog::BookmarksDialog( qt_intf_t *_p_intf ):QVLCFrame( _p_intf )
QHBoxLayout *layout = new QHBoxLayout( this );
QDialogButtonBox *buttonsBox = new QDialogButtonBox( Qt::Vertical );
QPushButton *addButton = new QPushButton( qtr( "Create" ) );
addButton = new QPushButton( qtr( "Create" ) );
addButton->setToolTip( qtr( "Create a new bookmark" ) );
buttonsBox->addButton( addButton, QDialogButtonBox::ActionRole );
delButton = new QPushButton( qtr( "Delete" ) );
......@@ -63,9 +63,9 @@ BookmarksDialog::BookmarksDialog( qt_intf_t *_p_intf ):QVLCFrame( _p_intf )
QDialogButtonBox::RejectRole);
bookmarksList = new QTreeView( this );
m_model = new MLBookmarkModel( _p_intf->p_mi->getMediaLibrary(),
_p_intf->p_player,
bookmarksList );
m_model = new MLBookmarkModel( bookmarksList );
m_model->setPlayer(_p_intf->p_player);
m_model->setMl(_p_intf->p_mi->getMediaLibrary());
bookmarksList->setModel( m_model );
bookmarksList->setRootIsDecorated( false );
bookmarksList->setAlternatingRowColors( true );
......@@ -106,6 +106,11 @@ BookmarksDialog::~BookmarksDialog()
void BookmarksDialog::updateButtons()
{
vlc_player_locker lock{ m_model->player() };
vlc_player_state currentState = vlc_player_GetState( m_model->player() );
addButton->setEnabled(currentState != VLC_PLAYER_STATE_STOPPING &&
currentState != VLC_PLAYER_STATE_STOPPED);
clearButton->setEnabled( bookmarksList->model()->rowCount() > 0 );
delButton->setEnabled( bookmarksList->selectionModel()->hasSelection() );
}
......
......@@ -43,6 +43,7 @@ private:
QTreeView *bookmarksList;
QPushButton *clearButton;
QPushButton *delButton;
QPushButton *addButton;
MLBookmarkModel* m_model;
private slots:
......
......@@ -19,6 +19,7 @@
#include "medialibrary/mlplaylistlistmodel.hpp"
#include "medialibrary/mlplaylistmodel.hpp"
#include "medialibrary/mlplaylist.hpp"
#include "medialibrary/mlbookmarkmodel.hpp"
#include "player/player_controller.hpp"
#include "player/player_controlbar_model.hpp"
......@@ -254,7 +255,7 @@ void MainUI::registerQMLTypes()
qmlRegisterUncreatableType<TrackListModel>(uri, versionMajor, versionMinor, "TrackListModel", "available tracks of a media (audio/video/sub)" );
qmlRegisterUncreatableType<TitleListModel>(uri, versionMajor, versionMinor, "TitleListModel", "available titles of a media" );
qmlRegisterUncreatableType<ChapterListModel>(uri, versionMajor, versionMinor, "ChapterListModel", "available titles of a media" );
qmlRegisterUncreatableType<ChapterListModel>(uri, versionMajor, versionMinor, "ChapterListModel", "available chapters of a media" );
qmlRegisterUncreatableType<ProgramListModel>(uri, versionMajor, versionMinor, "ProgramListModel", "available programs of a media" );
qmlRegisterUncreatableType<VLCVarChoiceModel>(uri, versionMajor, versionMinor, "VLCVarChoiceModel", "generic variable with choice model" );
......@@ -356,6 +357,7 @@ void MainUI::registerQMLTypes()
qmlRegisterType<MLVideoFoldersModel>( uri, versionMajor, versionMinor, "MLVideoFoldersModel" );
qmlRegisterType<MLPlaylistListModel>( uri, versionMajor, versionMinor, "MLPlaylistListModel" );
qmlRegisterType<MLPlaylistModel>( uri, versionMajor, versionMinor, "MLPlaylistModel" );
qmlRegisterType<MLBookmarkModel>( uri, versionMajor, versionMinor, "MLBookmarkModel" );
qRegisterMetaType<NetworkTreeItem>();
qmlRegisterType<NetworkMediaModel>( uri, versionMajor, versionMinor, "NetworkMediaModel");
......
......@@ -27,100 +27,55 @@
#include "medialib.hpp"
#include "mlhelper.hpp"
#include "util/vlctick.hpp"
#include "player/player_controller.hpp"
MLBookmarkModel::MLBookmarkModel( MediaLib* medialib, vlc_player_t *player,
QObject *parent )
MLBookmarkModel::MLBookmarkModel( QObject *parent )
: QAbstractListModel( parent )
, m_mediaLib( medialib )
, m_player( player )
, m_currentItem( nullptr, &input_item_Release )
{
static const vlc_player_cbs cbs {
&onCurrentMediaChanged,
&onPlaybackStateChanged,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
};
QString uri;
{
vlc_player_locker lock{ m_player };
vlc::threads::mutex_locker selflock{ m_mutex };
m_listener = vlc_player_AddListener( m_player, &cbs, this );
if ( m_listener == nullptr )
throw std::bad_alloc{};
auto currentItem = vlc_player_GetCurrentMedia( m_player );
m_currentItem = vlc::wrap_cptr( currentItem ? input_item_Hold( currentItem ) : nullptr,
&input_item_Release );
if (m_currentItem)
{
uri = m_currentItem->psz_uri;
}
}
updateMediaId(0, uri);
}
, m_ml_event_handle( nullptr, [this](vlc_ml_event_callback_t* cb ) {
if (!cb)
return;
if ( m_mediaLib )
m_mediaLib->unregisterEventListener(cb);
})
{}
MLBookmarkModel::~MLBookmarkModel()
{
vlc_player_locker lock{ m_player };
vlc_player_RemoveListener( m_player, m_listener );
if(m_player && m_listener){
vlc_player_locker lock{ m_player };
vlc_player_RemoveListener( m_player, m_listener );
}
}
QVariant MLBookmarkModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() || index.row() < 0 ||
!m_bookmarks ||
(uint32_t)index.row() >= m_bookmarks->i_nb_items )
{
if ( !index.isValid() || index.row() < 0 || m_player == nullptr ||
!m_bookmarks || (uint32_t)index.row() >= m_bookmarks->i_nb_items )
return QVariant{};
}
const auto& bookmark = m_bookmarks->p_items[index.row()];
// NOTE: We want to keep the current value when editing.
if ( role != Qt::DisplayRole && role != Qt::EditRole )
return QVariant{};
if (role == Qt::DisplayRole || role == Qt::EditRole)
role = columnToRole(index.column());
switch ( index.column() )
{
case 0:
return QVariant::fromValue( QString::fromUtf8( bookmark.psz_name ) );
case 1:
return QVariant::fromValue( VLCTick::fromMS( bookmark.i_time ).formatHMS() );
case 2:
return QVariant::fromValue( QString::fromUtf8( bookmark.psz_description ) );
default:
return QVariant{};
switch(role){
case BookmarkRoles::NameRole:
return QVariant::fromValue( qfu( bookmark.psz_name ) );
case BookmarkRoles::TimeRole:
return QVariant::fromValue( VLCTick::fromMS( bookmark.i_time ).formatHMS() );
case BookmarkRoles::PositionRole:
{
vlc_player_locker lock{ m_player };
return !vlc_player_GetLength( m_player ) ? QVariant{} :
QVariant::fromValue<float> ((float) VLC_TICK_FROM_MS(bookmark.i_time) / vlc_player_GetLength( m_player ));
}
case BookmarkRoles::DescriptionRole:
return QVariant::fromValue( qfu( bookmark.psz_description ) );
default:
return QVariant{};
}
}
......@@ -128,17 +83,16 @@ bool MLBookmarkModel::setData(const QModelIndex &index, const QVariant &value, i
{
if ( index.isValid() == false )
return false;
if ( role != Qt::EditRole )
return false;
if ( index.column() == 1 )
/* Disable editing the Time value through the listing */
if ( role == Qt::EditRole )
role = columnToRole(index.column());
if ( role != BookmarkRoles::NameRole && role != BookmarkRoles::DescriptionRole )
return false;
if ( value.canConvert<QString>() == false )
return false;
size_t row = index.row();
bool updateName = (index.column() == 0);
assert( index.column() == 0 || index.column() == 2 );
if ( ! m_bookmarks || row >= m_bookmarks->i_nb_items )
return false;
......@@ -175,22 +129,44 @@ bool MLBookmarkModel::setData(const QModelIndex &index, const QVariant &value, i
{
free( b.psz_name );
b.psz_name = strdup( qtu( str ) );
emit dataChanged(this->index(row, 0), this->index(row, 0),
{Qt::DisplayRole, BookmarkRoles::NameRole});
}
else
{
free( b.psz_description );
b.psz_description = strdup( qtu( str ) );
emit dataChanged(this->index(row, 2), this->index(row, 2),
{Qt::DisplayRole, BookmarkRoles::DescriptionRole});
}
if (updateName)
emit dataChanged(this->index(row, 0), this->index(row, 0), {Qt::DisplayRole});
else
emit dataChanged(this->index(row, 2), this->index(row, 2), {Qt::DisplayRole});
});
return true;
}
QHash<int, QByteArray> MLBookmarkModel::roleNames() const{
return QHash<int, QByteArray>{
{BookmarkRoles::NameRole, "name"},
{BookmarkRoles::TimeRole, "time"},
{BookmarkRoles::PositionRole, "position"},
{BookmarkRoles::DescriptionRole, "description"}
};
}
int MLBookmarkModel::columnToRole(int column) const{
switch (column)
{
case 0:
return BookmarkRoles::NameRole;
case 1:
return BookmarkRoles::TimeRole;
case 2:
return BookmarkRoles::DescriptionRole;
default:
return -1;
}
}
Qt::ItemFlags MLBookmarkModel::flags( const QModelIndex& index ) const
{
auto f = QAbstractItemModel::flags( index );
......@@ -224,10 +200,9 @@ QModelIndex MLBookmarkModel::parent(const QModelIndex &) const
QVariant MLBookmarkModel::headerData( int section, Qt::Orientation orientation,
int role ) const
{
if ( role != Qt::DisplayRole )
return QVariant{};
if ( orientation == Qt::Vertical )
if (role != Qt::DisplayRole || orientation == Qt::Vertical)
return QVariant{};
switch ( section )
{
case 0:
......@@ -266,7 +241,6 @@ void MLBookmarkModel::sort( int column, Qt::SortOrder order )
void MLBookmarkModel::add()
{
vlc_tick_t currentTime;
{
vlc_player_locker lock{ m_player };
......@@ -288,7 +262,7 @@ void MLBookmarkModel::add()
if (media)
{
QString name = QString("%1 #%2").arg(media->psz_title).arg(count);
QString name = qtr("Bookmark at %1").arg(VLCTick::fromMS( time ).formatHMS());
vlc_ml_media_update_bookmark(ml, mediaId, time, qtu(name), nullptr);
}
......@@ -297,7 +271,6 @@ void MLBookmarkModel::add()
[this](){
refresh( MLBOOKMARKMODEL_REFRESH );
});
}
void MLBookmarkModel::remove( const QModelIndexList &indexes )
......@@ -395,6 +368,9 @@ void MLBookmarkModel::onPlaybackStateChanged( vlc_player_t *, vlc_player_state s
{
auto self = static_cast<MLBookmarkModel*>( data );
if(self->m_currentMediaId == 0)
return;
QMetaObject::invokeMethod(self, [self, state](){
if ( state == VLC_PLAYER_STATE_STARTED )
self->refresh( MLBOOKMARKMODEL_REFRESH );
......@@ -445,13 +421,12 @@ void MLBookmarkModel::updateMediaId(uint64_t revision, const QString mediaUri)
beginResetModel();
m_bookmarks = std::move(ctx.newBookmarks);
m_currentMediaId = ctx.newMLid;
refresh(MLBOOKMARKMODEL_REFRESH);
endResetModel();
}
});
}
void MLBookmarkModel::refresh(MLBookmarkModel::RefreshOperation forceClear )
{
if (m_currentMediaId == 0 || forceClear == MLBOOKMARKMODEL_CLEAR)
......@@ -488,3 +463,147 @@ void MLBookmarkModel::refresh(MLBookmarkModel::RefreshOperation forceClear )
});
}
}
vlc_player_t * MLBookmarkModel::player() const
{
return m_player;
}
void MLBookmarkModel::setPlayer(vlc_player_t * player)
{
if (m_player == player) return;
if(m_player && m_listener){
vlc_player_locker lock{ m_player };
vlc_player_RemoveListener( m_player, m_listener );
}
m_player = player;
if (m_player && m_mediaLib)
initModel();
}
PlayerController * MLBookmarkModel::playerController() const
{
return m_player_controller;
}
void MLBookmarkModel::setPlayer(PlayerController * player)
{
if (m_player_controller == player) return;
if (m_player_controller)
disconnect(m_player_controller, nullptr, this, nullptr);
m_player_controller = player;
connect(m_player_controller, &PlayerController::lengthChanged, this, &MLBookmarkModel::playerLengthChanged);
setPlayer(player->getPlayer());
}
MediaLib* MLBookmarkModel::ml() const
{
return m_mediaLib;
}
void MLBookmarkModel::playerLengthChanged()
{
refresh(MLBOOKMARKMODEL_REFRESH);
}
void MLBookmarkModel::setMl(MediaLib* medialib)
{
if(m_mediaLib == medialib) return;
if(m_mediaLib)
m_ml_event_handle.reset(nullptr);
m_mediaLib = medialib;
if (m_player && m_mediaLib)
initModel();
}
void MLBookmarkModel::initModel()
{
static const vlc_player_cbs cbs {
&onCurrentMediaChanged,
&onPlaybackStateChanged,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
};
QString uri;
{
vlc_player_locker lock{ m_player };
vlc::threads::mutex_locker selflock{ m_mutex };
m_listener = vlc_player_AddListener( m_player, &cbs, this );
if ( m_listener == nullptr )
throw std::bad_alloc{};
auto currentItem = vlc_player_GetCurrentMedia( m_player );
m_currentItem = vlc::wrap_cptr( currentItem ? input_item_Hold( currentItem ) : nullptr,
&input_item_Release );
if (m_currentItem)
{
uri = m_currentItem->psz_uri;
}
}
updateMediaId(0, uri);
if (m_ml_event_handle == nullptr)
m_ml_event_handle.reset(m_mediaLib->registerEventListener(onVlcMlEvent, this));
}
void MLBookmarkModel::onVlcMlEvent(void* data, const vlc_ml_event_t* event)
{
auto self = static_cast<MLBookmarkModel*>(data);
auto mlEvent = std::make_shared<MLEvent>(event);
QMetaObject::invokeMethod(self, [self, mlEvent] () mutable {
self->onVlcMlEvent(*mlEvent);
});
}
void MLBookmarkModel::onVlcMlEvent(const MLEvent &event){
switch (event.i_type)
{
case VLC_ML_EVENT_BOOKMARKS_ADDED:
case VLC_ML_EVENT_BOOKMARKS_DELETED:
case VLC_ML_EVENT_BOOKMARKS_UPDATED:
refresh(MLBOOKMARKMODEL_REFRESH);
break;
default:
break;
}
}
......@@ -22,6 +22,10 @@
#include <QAbstractListModel>
#include <memory>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_media_library.h>
#include <vlc_player.h>
......@@ -29,15 +33,31 @@
#include <vlc_cxx_helpers.hpp>
#include "mlhelper.hpp"
#include "mlevent.hpp"
class PlayerController;
class MediaLib;
class MLBookmarkModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(PlayerController * player READ playerController WRITE setPlayer FINAL)
Q_PROPERTY(MediaLib * ml READ ml WRITE setMl FINAL)
public:
MLBookmarkModel( MediaLib* medialib, vlc_player_t* player, QObject* parent );
explicit MLBookmarkModel( QObject* parent = nullptr );
virtual ~MLBookmarkModel();
enum BookmarkRoles {
NameRole = Qt::UserRole,
TimeRole = Qt::UserRole + 1,
PositionRole = Qt::UserRole + 2,
DescriptionRole = Qt::UserRole + 3
};
virtual QHash<int, QByteArray> roleNames() const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole ) const override;
bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole ) override;
Qt::ItemFlags flags( const QModelIndex & ) const override;
......@@ -49,18 +69,30 @@ public:
QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
void sort( int column, Qt::SortOrder order ) override;
vlc_player_t* player() const;
void setPlayer(vlc_player_t* player);
PlayerController * playerController() const;
void setPlayer(PlayerController* playerController);
MediaLib* ml() const;
void setMl(MediaLib* ml);
void add();
void remove( const QModelIndexList& indexes );
void clear();
void select( const QModelIndex& index );
Q_INVOKABLE void select( const QModelIndex& index );
private:
static void onCurrentMediaChanged( vlc_player_t* player, input_item_t* media,
void* data );
static void onPlaybackStateChanged( vlc_player_t* player, vlc_player_state state,
void* data );
void playerLengthChanged();
void updateMediaId(uint64_t revision, const QString mediaUri);
static void onVlcMlEvent( void* data, const vlc_ml_event_t* event );
int columnToRole(int column) const;
void initModel();
enum RefreshOperation {
MLBOOKMARKMODEL_REFRESH,
......@@ -74,6 +106,7 @@ private:
MediaLib* m_mediaLib = nullptr;
vlc_player_t* m_player = nullptr;
vlc_player_listener_id* m_listener = nullptr;
PlayerController* m_player_controller = nullptr;
// Assume to be only used from the GUI thread
BookmarkListPtr m_bookmarks;
......@@ -87,6 +120,11 @@ private:
vlc_ml_sorting_criteria_t m_sort = VLC_ML_SORTING_INSERTIONDATE;
bool m_desc = false;
protected:
std::unique_ptr<vlc_ml_event_callback_t,
std::function<void(vlc_ml_event_callback_t*)>> m_ml_event_handle;
virtual void onVlcMlEvent( const MLEvent &event );
};
#endif // MLBOOKMARKMODEL_HPP
......@@ -554,7 +554,9 @@ BookmarkMenu::BookmarkMenu(MediaLib * mediaLib, vlc_player_t * player, QWidget *
addSeparator();
MLBookmarkModel * model = new MLBookmarkModel(mediaLib, player, this);
MLBookmarkModel * model = new MLBookmarkModel(this);
model->setPlayer(player);
model->setMl(mediaLib);
ListMenuHelper * helper = new ListMenuHelper(this, model, nullptr, this);
......
......@@ -479,8 +479,9 @@ bool QmlMenuPositioner::eventFilter(QObject * object, QEvent * event)
m_menu->addSeparator();
MLBookmarkModel * bookmarks = new MLBookmarkModel(m_ctx->getMediaLibrary(),
m_player->getPlayer(), m_menu.get());
MLBookmarkModel * bookmarks = new MLBookmarkModel(m_menu.get());
bookmarks->setPlayer(m_player->getPlayer());
bookmarks->setMl(m_ctx->getMediaLibrary());
helper = new ListMenuHelper(m_menu.get(), bookmarks, nullptr, m_menu.get());
......
/*****************************************************************************
* Copyright (C) 2022 VLC authors and VideoLAN
*
* 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.
*****************************************************************************/
import QtQuick 2.11
import QtQuick.Controls 2.4
import org.videolan.vlc 0.1
import org.videolan.medialib 0.1
import "qrc:///widgets/" as Widgets
import "qrc:///style/"
Item {
id: control
property real barHeight
property int yShift
property VLCColors colors
property bool controlBarHovered
property bool bookmarkHovered
property string bookmarkText
property real bookmarkPosition
implicitHeight: control.barHeight
height: implicitHeight
visible: false
opacity: 0
Widgets.PointingTooltip {
id: timeTooltip
visible: control.bookmarkHovered
text: control.bookmarkText
pos: Qt.point(control.bookmarkPosition, - yShift)
colors: control.colors
}
transitions: [
Transition {
to: "hidden"
SequentialAnimation {
NumberAnimation{
target: control
properties: "opacity"
to: 0
duration: VLCStyle.duration_short; easing.type: Easing.OutSine
}
PropertyAction { target: control; property: "visible"; value: false; }
}
},
Transition {
to: "visible"
SequentialAnimation {
PropertyAction { target: control; property: "visible"; value: true; }
NumberAnimation{
target: control
properties: "opacity"
to: 1
duration: VLCStyle.duration_short; easing.type: Easing.InSine
}
}
}
]
state: controlBarHovered && bookmarksRptr.count > 0 ? "visible" : "hidden"
Repeater {
id: bookmarksRptr
model: MLBookmarkModel {
id: modelBookmark
player: Player
ml: MediaLib
}
Widgets.IconToolButton {
id: bookmarkButton
size: control.barHeight
x: control.width * model.position - width/2
focusPolicy: Qt.NoFocus
onClicked: modelBookmark.select(modelBookmark.index(index, 0))
onHoveredChanged: {
if(bookmarkButton.hovered){
control.bookmarkText = model.name
control.bookmarkPosition = x + width/2
}
control.bookmarkHovered = bookmarkButton.hovered
}
background: Rectangle {
radius: parent.width * 0.5
color: colors.playerFg
}
}
}
}
......@@ -44,7 +44,7 @@ Control {
property alias identifier: playerControlLayout.identifier
property alias sliderHeight: trackPositionSlider.barHeight
property alias sliderBackgroundColor: trackPositionSlider.backgroundColor
property bool showRightTimeText: true
property real bookmarksHeight: VLCStyle.icon_xsmall * 0.9
signal requestLockUnlockAutoHide(bool lock)
......@@ -67,45 +67,48 @@ Control {
onTextPositionChanged: _layout()
function _layout() {
trackPositionSlider.visible = true
mediaTime.visible = true
mediaRemainingTime.visible = Qt.binding(function() { return root.showRightTimeText && textPosition !== ControlBar.TimeTextPosition.Hide; })
mediaTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_normal })
mediaRemainingTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_normal })
row2.Layout.leftMargin = 0
row2.Layout.rightMargin = 0
switch (textPosition) {
case ControlBar.TimeTextPosition.Hide:
row1.children = []
row2.children = [trackPositionSlider]
mediaTime.visible = false
break;
case ControlBar.TimeTextPosition.AboveSlider:
var spacer = Qt.createQmlObject("import QtQuick 2.11; Item {}", row1, "ControlBar")
row1.children = [mediaTime, spacer, mediaRemainingTime]
spacer.Layout.fillWidth = true
row2.children = [trackPositionSlider]
break;
case ControlBar.TimeTextPosition.LeftRightSlider:
row1.children = []
row2.children = [mediaTime, trackPositionSlider, mediaRemainingTime]
row2.Layout.leftMargin = Qt.binding(function() { return VLCStyle.margin_xsmall })
row2.Layout.rightMargin = Qt.binding(function() { return VLCStyle.margin_xsmall })
mediaTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_small })
mediaRemainingTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_small })
trackPositionSlider.Layout.alignment = Qt.AlignVCenter
break;
default:
console.assert(false, "invalid text position")
case ControlBar.TimeTextPosition.Hide:
row1.children = []
row2.children = [trackPositionSlider]
mediaTime.visible = false
mediaRemainingTime.visible = false
spacer.visible = false
row2.Layout.leftMargin = 0
row2.Layout.rightMargin = 0
mediaTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_normal })
mediaRemainingTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_normal })
break;
case ControlBar.TimeTextPosition.AboveSlider:
row1.children = [mediaTime, spacer, mediaRemainingTime]
row2.children = [trackPositionSlider]
mediaTime.visible = true
mediaRemainingTime.visible = Qt.binding(function() { return !playlistVisibility.isPlaylistVisible })
spacer.visible = true
row2.Layout.leftMargin = 0
row2.Layout.rightMargin = 0
mediaTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_normal })
mediaRemainingTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_normal })
break;
case ControlBar.TimeTextPosition.LeftRightSlider:
row1.children = []
row2.children = [mediaTime, trackPositionSlider, mediaRemainingTime]
mediaTime.visible = true
mediaRemainingTime.visible = true
spacer.visible = false
row2.Layout.leftMargin = VLCStyle.margin_xsmall
row2.Layout.rightMargin = VLCStyle.margin_xsmall
mediaTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_small })
mediaRemainingTime.font.pixelSize = Qt.binding(function() { return VLCStyle.fontSize_small })
trackPositionSlider.Layout.alignment = Qt.AlignVCenter
break;
default:
console.assert(false, "invalid text position")
}
trackPositionSlider.Layout.fillWidth = true
row1.visible = row1.children.length > 0
row2.visible = row2.children.length > 0
}
......@@ -114,6 +117,7 @@ Control {
id: columnLayout
spacing: VLCStyle.margin_xsmall
z: 1
RowLayout {
id: row1
......@@ -147,26 +151,20 @@ Control {
}
}
//FIXME use the right xxxLabel class
T.Label {
id: mediaTime
visible: false
text: Player.time.formatHMS()
color: root.colors.playerFg
font.pixelSize: VLCStyle.fontSize_normal
}
//FIXME use the right xxxLabel class
T.Label {
id: mediaRemainingTime
visible: false
text: (MainCtx.showRemainingTime && Player.remainingTime.valid())
? "-" + Player.remainingTime.formatHMS()
: Player.length.formatHMS()
color: root.colors.playerFg
font.pixelSize: VLCStyle.fontSize_normal
MouseArea {
anchors.fill: parent
......@@ -174,12 +172,18 @@ Control {
}
}
Item {
id: spacer
Layout.fillWidth: true
}
SliderBar {
id: trackPositionSlider
visible: false
backgroundColor: colors.playerSeekBar
barHeight: VLCStyle.heightBar_xxsmall
Layout.fillWidth: true
enabled: Player.playingState === Player.PLAYING_STATE_PLAYING || Player.playingState === Player.PLAYING_STATE_PAUSED
colors: root.colors
......@@ -190,4 +194,22 @@ Control {
Navigation.defaultKeyAction(event)
}
}
Loader {
id: bookmarksLoader
active: MainCtx.mediaLibraryAvailable
source: "qrc:/player/Bookmarks.qml"
x: root.leftPadding + trackPositionSlider.x + row2.Layout.leftMargin
y: row2.y + row2.height + VLCStyle.margin_xxsmall
width: trackPositionSlider.width
onLoaded: {
item.colors = Qt.binding(function() { return root.colors })
item.barHeight = Qt.binding(function() { return bookmarksHeight })
item.controlBarHovered = Qt.binding(function() { return root.hovered })
item.yShift = Qt.binding(function() { return row2.height + VLCStyle.margin_xxsmall })
}
}
}
......@@ -89,6 +89,7 @@ FocusScope {
textPosition: ControlBar.TimeTextPosition.Hide
sliderHeight: VLCStyle.dp(3, VLCStyle.scale)
sliderBackgroundColor: colors.sliderBarMiniplayerBgColor
bookmarksHeight: VLCStyle.icon_xsmall * 0.7
identifier: PlayerControlbarModel.Miniplayer
Navigation.parentItem: root
......
......@@ -608,7 +608,6 @@ FocusScope {
colors: rootPlayer.colors
textPosition: rootPlayer.pinVideoControls ? ControlBar.TimeTextPosition.LeftRightSlider : ControlBar.TimeTextPosition.AboveSlider
showRightTimeText: (textPosition !== ControlBar.TimeTextPosition.AboveSlider) || !playlistVisibility.isPlaylistVisible
Navigation.parentItem: rootPlayer
Navigation.upItem: playlistpopup.showPlaylist ? playlistpopup : (audioControls.visible ? audioControls : topcontrolView)
......
......@@ -29,7 +29,7 @@ import "qrc:///util/Helpers.js" as Helpers
Slider {
id: control
readonly property real _hoveredScalingFactor: 2
readonly property real _hoveredScalingFactor: 1.8
property int barHeight: VLCStyle.dp(5, VLCStyle.scale)
readonly property real _scaledBarHeight: control.barHeight * _hoveredScalingFactor
readonly property real _scaledY: (-control.barHeight / 2) * (control._hoveredScalingFactor - 1)
......@@ -145,8 +145,8 @@ Slider {
fsm.playerUpdatePosition(Player.position)
}
height: control.barHeight
implicitHeight: control.barHeight
height: implicitHeight
padding: 0
......@@ -230,6 +230,7 @@ Slider {
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
radius: parent.radius
width: sliderRect.width * control.visualPosition - parent.x - control._seekPointsDistance
visible: parent._currentChapter === 0
......@@ -376,11 +377,13 @@ Slider {
handle: Rectangle {
id: sliderHandle
property int _size: control.barHeight * 3
x: (control.visualPosition * control.availableWidth) - width / 2
y: (control.barHeight - height) / 2
implicitWidth: VLCStyle.margin_small
implicitHeight: VLCStyle.margin_small
implicitWidth: sliderHandle._size
implicitHeight: sliderHandle._size
radius: VLCStyle.margin_small
color: control.colors.accent
......@@ -402,7 +405,7 @@ Slider {
PropertyAction { target: sliderHandle; property: "visible"; value: true; }
NumberAnimation {
target: sliderHandle; properties: "implicitWidth,implicitHeight"
to: VLCStyle.margin_small
to: sliderHandle._size
duration: VLCStyle.duration_short; easing.type: Easing.InSine
}
}
......@@ -413,7 +416,7 @@ Slider {
PropertyAction { target: sliderHandle; property: "visible"; value: true; }
NumberAnimation {
target: sliderHandle; properties: "implicitWidth,implicitHeight"
to: VLCStyle.margin_small * (0.75 * control._hoveredScalingFactor)
to: sliderHandle._size * (0.8 * control._hoveredScalingFactor)
duration: VLCStyle.duration_short; easing.type: Easing.InSine
}
}
......
......@@ -311,6 +311,7 @@
<file alias="PlayerPlaylistVisibilityFSM.qml">player/qml/PlayerPlaylistVisibilityFSM.qml</file>
<file alias="PlayerBlurredBackground.qml">player/qml/PlayerBlurredBackground.qml</file>
<file alias="PlayerBlurredBackground.frag">player/qml/PlayerBlurredBackground.frag</file>
<file alias="Bookmarks.qml">player/qml/Bookmarks.qml</file>
</qresource>
<qresource prefix="/player/controlbarcontrols">
<file alias="HighResolutionTimeWidget.qml">player/qml/controlbarcontrols/HighResolutionTimeWidget.qml</file>
......