2000-02-19 13:36:48 +01:00
/*
* menu . c : The actual menu implementations
*
2000-04-24 09:46:05 +02:00
* See the main source file ' vdr . c ' for copyright information and
2000-02-19 13:36:48 +01:00
* how to reach the author .
*
2021-05-21 10:41:46 +02:00
* $ Id : menu . c 5.6 2021 / 05 / 21 10 : 41 : 31 kls Exp $
2000-02-19 13:36:48 +01:00
*/
# include "menu.h"
2002-04-13 10:52:01 +02:00
# include <ctype.h>
2000-02-19 13:36:48 +01:00
# include <limits.h>
2009-01-24 11:42:24 +01:00
# include <math.h>
2000-02-19 13:36:48 +01:00
# include <stdio.h>
2000-10-29 13:17:22 +01:00
# include <stdlib.h>
2000-02-19 13:36:48 +01:00
# include <string.h>
2002-10-06 10:25:42 +02:00
# include "channels.h"
2000-02-19 13:36:48 +01:00
# include "config.h"
2013-10-21 08:23:19 +02:00
# include "cutter.h"
2004-01-17 15:38:11 +01:00
# include "eitscan.h"
2000-11-11 10:39:27 +01:00
# include "i18n.h"
2004-05-16 10:35:36 +02:00
# include "interface.h"
2002-05-09 16:26:56 +02:00
# include "plugin.h"
2002-06-16 12:57:31 +02:00
# include "recording.h"
2002-09-29 13:40:45 +02:00
# include "remote.h"
2007-02-25 10:56:29 +01:00
# include "shutdown.h"
2010-02-28 12:19:50 +01:00
# include "sourceparams.h"
2002-10-06 10:25:42 +02:00
# include "sources.h"
2002-05-19 15:50:11 +02:00
# include "status.h"
2015-09-08 11:08:06 +02:00
# include "svdrp.h"
2004-05-16 10:35:36 +02:00
# include "themes.h"
2002-10-20 12:28:55 +02:00
# include "timers.h"
2003-08-24 14:47:34 +02:00
# include "transfer.h"
2002-01-27 13:11:23 +01:00
# include "videodir.h"
2000-02-19 13:36:48 +01:00
2003-04-27 12:51:01 +02:00
# define MAXWAIT4EPGINFO 3 // seconds
2001-09-14 14:06:43 +02:00
# define MODETIMEOUT 3 // seconds
2006-04-16 10:29:48 +02:00
# define NEWTIMERLIMIT 120 // seconds until the start time of a new timer created from the Schedule menu,
// within which it will go directly into the "Edit timer" menu to allow
// further parameter settings
2011-08-06 13:20:07 +02:00
# define DEFERTIMER 60 // seconds by which a timer is deferred in case of problems
2000-05-01 16:29:46 +02:00
2002-06-16 12:57:31 +02:00
# define MAXRECORDCONTROLS (MAXDEVICES * MAXRECEIVERS)
2002-04-26 13:43:46 +02:00
# define MAXINSTANTRECTIME (24 * 60 - 1) // 23:59 hours
2007-01-07 14:46:14 +01:00
# define MAXWAITFORCAMMENU 10 // seconds to wait for the CAM menu to open
2017-06-10 11:52:47 +02:00
# define CAMMENURETRYTIMEOUT 3 // seconds after which opening the CAM menu is retried
2007-01-07 14:46:14 +01:00
# define CAMRESPONSETIMEOUT 5 // seconds to wait for a response from a CAM
2018-04-14 10:24:41 +02:00
# define PROGRESSTIMEOUT 100 // milliseconds to wait before updating the replay progress display
2006-06-24 10:22:57 +02:00
# define MINFREEDISK 300 // minimum free disk space (in MB) required to start recording
2006-01-20 16:34:56 +01:00
# define NODISKSPACEDELTA 300 // seconds between "Not enough disk space to start recording!" messages
2012-04-06 12:35:39 +02:00
# define MAXCHNAMWIDTH 16 // maximum number of characters of channels' short names shown in schedules menus
2002-04-26 13:43:46 +02:00
2015-09-01 11:14:27 +02:00
# define CHNUMWIDTH (numdigits(cChannels::MaxNumber()) + 1)
# define CHNAMWIDTH (min(MAXCHNAMWIDTH, cChannels::MaxShortChannelNameLength() + 1))
2002-03-29 10:50:20 +01:00
2002-03-03 16:12:29 +01:00
// --- cMenuEditCaItem -------------------------------------------------------
class cMenuEditCaItem : public cMenuEditIntItem {
protected :
virtual void Set ( void ) ;
public :
2006-01-07 14:10:17 +01:00
cMenuEditCaItem ( const char * Name , int * Value ) ;
2002-03-03 16:12:29 +01:00
eOSState ProcessKey ( eKeys Key ) ;
} ;
2006-01-07 14:10:17 +01:00
cMenuEditCaItem : : cMenuEditCaItem ( const char * Name , int * Value )
2002-03-03 16:12:29 +01:00
: cMenuEditIntItem ( Name , Value , 0 )
{
Set ( ) ;
}
void cMenuEditCaItem : : Set ( void )
{
2006-01-07 14:10:17 +01:00
if ( * value = = CA_FTA )
SetValue ( tr ( " Free To Air " ) ) ;
else if ( * value > = CA_ENCRYPTED_MIN )
SetValue ( tr ( " encrypted " ) ) ;
2002-03-03 16:12:29 +01:00
else
cMenuEditIntItem : : Set ( ) ;
}
eOSState cMenuEditCaItem : : ProcessKey ( eKeys Key )
{
eOSState state = cMenuEditItem : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2006-01-07 14:10:17 +01:00
if ( NORMALKEY ( Key ) = = kLeft & & * value > = CA_ENCRYPTED_MIN )
* value = CA_FTA ;
2002-03-03 16:12:29 +01:00
else
return cMenuEditIntItem : : ProcessKey ( Key ) ;
Set ( ) ;
state = osContinue ;
}
return state ;
}
2002-10-06 10:25:42 +02:00
// --- cMenuEditSrcItem ------------------------------------------------------
class cMenuEditSrcItem : public cMenuEditIntItem {
private :
const cSource * source ;
protected :
virtual void Set ( void ) ;
public :
cMenuEditSrcItem ( const char * Name , int * Value ) ;
eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuEditSrcItem : : cMenuEditSrcItem ( const char * Name , int * Value )
: cMenuEditIntItem ( Name , Value , 0 )
{
source = Sources . Get ( * Value ) ;
Set ( ) ;
}
void cMenuEditSrcItem : : Set ( void )
{
2008-02-15 14:57:48 +01:00
if ( source )
SetValue ( cString : : sprintf ( " %s - %s " , * cSource : : ToString ( source - > Code ( ) ) , source - > Description ( ) ) ) ;
2002-10-06 10:25:42 +02:00
else
cMenuEditIntItem : : Set ( ) ;
}
eOSState cMenuEditSrcItem : : ProcessKey ( eKeys Key )
{
eOSState state = cMenuEditItem : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2010-03-06 12:47:47 +01:00
bool IsRepeat = Key & k_Repeat ;
Key = NORMALKEY ( Key ) ;
if ( Key = = kLeft ) { // TODO might want to increase the delta if repeated quickly?
if ( source ) {
if ( source - > Prev ( ) )
source = ( cSource * ) source - > Prev ( ) ;
else if ( ! IsRepeat )
source = Sources . Last ( ) ;
2002-10-06 10:25:42 +02:00
* value = source - > Code ( ) ;
}
}
2010-03-06 12:47:47 +01:00
else if ( Key = = kRight ) {
2003-12-22 13:29:24 +01:00
if ( source ) {
2002-10-06 10:25:42 +02:00
if ( source - > Next ( ) )
source = ( cSource * ) source - > Next ( ) ;
2010-03-06 12:47:47 +01:00
else if ( ! IsRepeat )
source = Sources . First ( ) ;
2002-10-06 10:25:42 +02:00
}
else
source = Sources . First ( ) ;
if ( source )
* value = source - > Code ( ) ;
}
else
return state ; // we don't call cMenuEditIntItem::ProcessKey(Key) here since we don't accept numerical input
Set ( ) ;
state = osContinue ;
}
return state ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuEditChannel ------------------------------------------------------
class cMenuEditChannel : public cOsdMenu {
private :
2015-09-01 11:14:27 +02:00
cStateKey * channelsStateKey ;
2000-02-19 13:36:48 +01:00
cChannel * channel ;
cChannel data ;
2010-02-28 12:19:50 +01:00
cSourceParam * sourceParam ;
2004-10-31 12:53:00 +01:00
char name [ 256 ] ;
2002-10-06 10:25:42 +02:00
void Setup ( void ) ;
2000-02-19 13:36:48 +01:00
public :
2015-09-01 11:14:27 +02:00
cMenuEditChannel ( cStateKey * ChannelsStateKey , cChannel * Channel , bool New = false ) ;
cChannel * Channel ( void ) { return channel ; }
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
2015-09-01 11:14:27 +02:00
cMenuEditChannel : : cMenuEditChannel ( cStateKey * ChannelsStateKey , cChannel * Channel , bool New )
2005-10-09 11:23:18 +02:00
: cOsdMenu ( tr ( " Edit channel " ) , 16 )
2000-02-19 13:36:48 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcChannelEdit ) ;
2015-09-01 11:14:27 +02:00
channelsStateKey = ChannelsStateKey ;
2002-11-10 15:50:21 +01:00
channel = Channel ;
2010-02-28 12:19:50 +01:00
sourceParam = NULL ;
2010-05-13 13:32:01 +02:00
* name = 0 ;
2000-02-19 13:36:48 +01:00
if ( channel ) {
data = * channel ;
2010-05-02 15:09:59 +02:00
strn0cpy ( name , data . name , sizeof ( name ) ) ;
2004-02-13 13:36:52 +01:00
if ( New ) {
2002-11-10 15:50:21 +01:00
channel = NULL ;
2014-01-30 09:10:39 +01:00
// clear non-editable members:
2004-02-13 13:36:52 +01:00
data . nid = 0 ;
data . tid = 0 ;
data . rid = 0 ;
2014-01-30 09:10:39 +01:00
* data . shortName = 0 ;
* data . provider = 0 ;
* data . portalName = 0 ;
2004-02-13 13:36:52 +01:00
}
2000-02-19 13:36:48 +01:00
}
2010-05-02 15:09:59 +02:00
Setup ( ) ;
2000-02-19 13:36:48 +01:00
}
2002-10-06 10:25:42 +02:00
void cMenuEditChannel : : Setup ( void )
{
int current = Current ( ) ;
Clear ( ) ;
// Parameters for all types of sources:
2007-11-03 15:06:00 +01:00
Add ( new cMenuEditStrItem ( tr ( " Name " ) , name , sizeof ( name ) ) ) ;
2002-10-06 10:25:42 +02:00
Add ( new cMenuEditSrcItem ( tr ( " Source " ) , & data . source ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Frequency " ) , & data . frequency ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Vpid " ) , & data . vpid , 0 , 0x1FFF ) ) ;
2003-04-26 11:58:54 +02:00
Add ( new cMenuEditIntItem ( tr ( " Ppid " ) , & data . ppid , 0 , 0x1FFF ) ) ;
2004-01-25 15:32:08 +01:00
Add ( new cMenuEditIntItem ( tr ( " Apid1 " ) , & data . apids [ 0 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Apid2 " ) , & data . apids [ 1 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Dpid1 " ) , & data . dpids [ 0 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Dpid2 " ) , & data . dpids [ 1 ] , 0 , 0x1FFF ) ) ;
2007-10-12 14:52:30 +02:00
Add ( new cMenuEditIntItem ( tr ( " Spid1 " ) , & data . spids [ 0 ] , 0 , 0x1FFF ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Spid2 " ) , & data . spids [ 1 ] , 0 , 0x1FFF ) ) ;
2002-10-06 10:25:42 +02:00
Add ( new cMenuEditIntItem ( tr ( " Tpid " ) , & data . tpid , 0 , 0x1FFF ) ) ;
2006-01-07 14:10:17 +01:00
Add ( new cMenuEditCaItem ( tr ( " CA " ) , & data . caids [ 0 ] ) ) ;
2004-02-13 13:36:52 +01:00
Add ( new cMenuEditIntItem ( tr ( " Sid " ) , & data . sid , 1 , 0xFFFF ) ) ;
2002-11-24 14:48:38 +01:00
Add ( new cMenuEditIntItem ( tr ( " Nid " ) , & data . nid , 0 ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Tid " ) , & data . tid , 0 ) ) ;
2014-03-16 10:48:30 +01:00
/* XXX not yet used
2002-11-24 14:48:38 +01:00
Add ( new cMenuEditIntItem ( tr ( " Rid " ) , & data . rid , 0 ) ) ;
XXX */
2002-10-06 10:25:42 +02:00
// Parameters for specific types of sources:
2010-02-28 12:19:50 +01:00
sourceParam = SourceParams . Get ( * * cSource : : ToString ( data . source ) ) ;
if ( sourceParam ) {
sourceParam - > SetData ( & data ) ;
cOsdItem * Item ;
while ( ( Item = sourceParam - > GetOsdItem ( ) ) ! = NULL )
Add ( Item ) ;
}
2002-10-06 10:25:42 +02:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditChannel : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
2002-10-06 10:25:42 +02:00
int oldSource = data . source ;
2000-03-11 11:22:37 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2000-02-19 13:36:48 +01:00
2000-03-11 11:22:37 +01:00
if ( state = = osUnknown ) {
2000-02-19 13:36:48 +01:00
if ( Key = = kOk ) {
2015-09-01 11:14:27 +02:00
cChannels * Channels = cChannels : : GetChannelsWrite ( * channelsStateKey ) ;
bool Modified = false ;
2010-02-28 12:19:50 +01:00
if ( sourceParam )
sourceParam - > GetData ( & data ) ;
2015-09-01 11:14:27 +02:00
if ( Channels - > HasUniqueChannelID ( & data , channel ) ) {
2004-10-31 12:53:00 +01:00
data . name = strcpyrealloc ( data . name , name ) ;
2002-11-10 15:50:21 +01:00
if ( channel ) {
* channel = data ;
2015-09-01 11:14:27 +02:00
isyslog ( " edited channel %d %s " , channel - > Number ( ) , * channel - > ToText ( ) ) ;
2002-11-10 15:50:21 +01:00
state = osBack ;
}
else {
channel = new cChannel ;
* channel = data ;
2015-09-01 11:14:27 +02:00
Channels - > Add ( channel ) ;
Channels - > ReNumber ( ) ;
isyslog ( " added channel %d %s " , channel - > Number ( ) , * channel - > ToText ( ) ) ;
2002-11-10 15:50:21 +01:00
state = osUser1 ;
}
2015-09-01 11:14:27 +02:00
Channels - > SetModifiedByUser ( ) ;
Modified = true ;
2002-11-10 15:50:21 +01:00
}
else {
2004-05-16 10:35:36 +02:00
Skins . Message ( mtError , tr ( " Channel settings are not unique! " ) ) ;
2002-11-10 15:50:21 +01:00
state = osContinue ;
}
2015-09-01 11:14:27 +02:00
channelsStateKey - > Remove ( Modified ) ;
2000-02-19 13:36:48 +01:00
}
}
2010-02-28 12:19:50 +01:00
if ( Key ! = kNone & & ( data . source & cSource : : st_Mask ) ! = ( oldSource & cSource : : st_Mask ) ) {
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_WRITE ;
2010-02-28 12:19:50 +01:00
if ( sourceParam )
sourceParam - > GetData ( & data ) ;
2002-10-06 10:25:42 +02:00
Setup ( ) ;
2010-02-28 12:19:50 +01:00
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
// --- cMenuChannelItem ------------------------------------------------------
class cMenuChannelItem : public cOsdItem {
2004-11-01 13:59:58 +01:00
public :
enum eChannelSortMode { csmNumber , csmName , csmProvider } ;
2000-02-19 13:36:48 +01:00
private :
2004-11-01 13:59:58 +01:00
static eChannelSortMode sortMode ;
2015-09-01 11:14:27 +02:00
const cChannel * channel ;
2000-02-19 13:36:48 +01:00
public :
2015-09-01 11:14:27 +02:00
cMenuChannelItem ( const cChannel * Channel ) ;
2004-11-01 13:59:58 +01:00
static void SetSortMode ( eChannelSortMode SortMode ) { sortMode = SortMode ; }
static void IncSortMode ( void ) { sortMode = eChannelSortMode ( ( sortMode = = csmProvider ) ? csmNumber : sortMode + 1 ) ; }
2006-01-15 13:09:16 +01:00
static eChannelSortMode SortMode ( void ) { return sortMode ; }
2004-11-01 13:59:58 +01:00
virtual int Compare ( const cListObject & ListObject ) const ;
2000-02-19 13:36:48 +01:00
virtual void Set ( void ) ;
2015-09-01 11:14:27 +02:00
const cChannel * Channel ( void ) { return channel ; }
2012-12-08 11:05:39 +01:00
virtual void SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable ) ;
2000-02-19 13:36:48 +01:00
} ;
2004-11-01 13:59:58 +01:00
cMenuChannelItem : : eChannelSortMode cMenuChannelItem : : sortMode = csmNumber ;
2015-09-01 11:14:27 +02:00
cMenuChannelItem : : cMenuChannelItem ( const cChannel * Channel )
2000-02-19 13:36:48 +01:00
{
channel = Channel ;
2002-10-06 10:25:42 +02:00
if ( channel - > GroupSep ( ) )
2004-05-16 10:35:36 +02:00
SetSelectable ( false ) ;
2000-02-19 13:36:48 +01:00
Set ( ) ;
}
2004-11-01 13:59:58 +01:00
int cMenuChannelItem : : Compare ( const cListObject & ListObject ) const
{
cMenuChannelItem * p = ( cMenuChannelItem * ) & ListObject ;
int r = - 1 ;
if ( sortMode = = csmProvider )
r = strcoll ( channel - > Provider ( ) , p - > channel - > Provider ( ) ) ;
if ( sortMode = = csmName | | r = = 0 )
r = strcoll ( channel - > Name ( ) , p - > channel - > Name ( ) ) ;
if ( sortMode = = csmNumber | | r = = 0 )
r = channel - > Number ( ) - p - > channel - > Number ( ) ;
return r ;
}
2000-02-19 13:36:48 +01:00
void cMenuChannelItem : : Set ( void )
{
2008-02-15 14:57:48 +01:00
cString buffer ;
2004-11-01 13:59:58 +01:00
if ( ! channel - > GroupSep ( ) ) {
2017-06-10 15:57:33 +02:00
const char * X = * channel - > Caids ( ) > = CA_ENCRYPTED_MIN ? " X " : " " ;
const char * R = ! channel - > Vpid ( ) & & ( * channel - > Apids ( ) | | * channel - > Dpids ( ) ) ? " R " : " " ;
2004-11-01 13:59:58 +01:00
if ( sortMode = = csmProvider )
2017-06-10 15:57:33 +02:00
buffer = cString : : sprintf ( " %d \t %s%s \t %s - %s " , channel - > Number ( ) , X , R , channel - > Provider ( ) , channel - > Name ( ) ) ;
2004-11-01 13:59:58 +01:00
else
2017-06-10 15:57:33 +02:00
buffer = cString : : sprintf ( " %d \t %s%s \t %s " , channel - > Number ( ) , X , R , channel - > Name ( ) ) ;
2004-11-01 13:59:58 +01:00
}
2000-09-09 14:57:43 +02:00
else
2017-06-10 19:19:51 +02:00
buffer = cString : : sprintf ( " \t \t %s " , channel - > Name ( ) ) ;
2008-02-15 14:57:48 +01:00
SetText ( buffer ) ;
2000-02-19 13:36:48 +01:00
}
2012-12-08 11:05:39 +01:00
void cMenuChannelItem : : SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable )
{
if ( ! DisplayMenu - > SetItemChannel ( channel , Index , Current , Selectable , sortMode = = csmProvider ) )
DisplayMenu - > SetItem ( Text ( ) , Index , Current , Selectable ) ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuChannels ---------------------------------------------------------
2006-01-05 13:43:07 +01:00
# define CHANNELNUMBERTIMEOUT 1000 //ms
2000-02-19 13:36:48 +01:00
class cMenuChannels : public cOsdMenu {
2002-10-20 12:28:55 +02:00
private :
2015-09-01 11:14:27 +02:00
cStateKey channelsStateKey ;
2006-01-05 13:43:07 +01:00
int number ;
cTimeMs numberTimer ;
2015-09-01 11:14:27 +02:00
void Set ( bool Force = false ) ;
2002-12-22 12:49:10 +01:00
cChannel * GetChannel ( int Index ) ;
2015-09-01 11:14:27 +02:00
void Propagate ( cChannels * Channels ) ;
2000-03-11 11:22:37 +01:00
protected :
2006-01-05 13:43:07 +01:00
eOSState Number ( eKeys Key ) ;
2000-03-11 11:22:37 +01:00
eOSState Switch ( void ) ;
eOSState Edit ( void ) ;
eOSState New ( void ) ;
2002-11-10 16:07:58 +01:00
eOSState Delete ( void ) ;
2000-03-11 11:22:37 +01:00
virtual void Move ( int From , int To ) ;
2000-02-19 13:36:48 +01:00
public :
cMenuChannels ( void ) ;
2004-01-04 12:30:00 +01:00
~ cMenuChannels ( ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuChannels : : cMenuChannels ( void )
2017-06-10 15:57:33 +02:00
: cOsdMenu ( tr ( " Channels " ) , CHNUMWIDTH , 3 )
2000-02-19 13:36:48 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcChannel ) ;
2006-01-05 13:43:07 +01:00
number = 0 ;
2015-09-01 11:14:27 +02:00
Set ( ) ;
2004-01-04 12:30:00 +01:00
}
cMenuChannels : : ~ cMenuChannels ( )
{
2000-03-11 11:22:37 +01:00
}
2015-09-01 11:14:27 +02:00
void cMenuChannels : : Set ( bool Force )
2004-11-01 13:59:58 +01:00
{
2015-09-01 11:14:27 +02:00
if ( Force )
channelsStateKey . Reset ( ) ;
if ( const cChannels * Channels = cChannels : : GetChannelsRead ( channelsStateKey ) ) {
const cChannel * CurrentChannel = GetChannel ( Current ( ) ) ;
if ( ! CurrentChannel )
CurrentChannel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) ;
cMenuChannelItem * CurrentItem = NULL ;
Clear ( ) ;
for ( const cChannel * Channel = Channels - > First ( ) ; Channel ; Channel = Channels - > Next ( Channel ) ) {
if ( ! Channel - > GroupSep ( ) | | cMenuChannelItem : : SortMode ( ) = = cMenuChannelItem : : csmNumber & & * Channel - > Name ( ) ) {
cMenuChannelItem * Item = new cMenuChannelItem ( Channel ) ;
Add ( Item ) ;
if ( Channel = = CurrentChannel )
CurrentItem = Item ;
}
2004-11-01 13:59:58 +01:00
}
2015-09-01 11:14:27 +02:00
SetMenuSortMode ( cMenuChannelItem : : SortMode ( ) = = cMenuChannelItem : : csmName ? msmName :
cMenuChannelItem : : SortMode ( ) = = cMenuChannelItem : : csmProvider ? msmProvider :
msmNumber ) ;
if ( cMenuChannelItem : : SortMode ( ) ! = cMenuChannelItem : : csmNumber )
Sort ( ) ;
SetCurrent ( CurrentItem ) ;
SetHelp ( tr ( " Button$Edit " ) , tr ( " Button$New " ) , tr ( " Button$Delete " ) , tr ( " Button$Mark " ) ) ;
Display ( ) ;
channelsStateKey . Remove ( ) ;
}
2004-11-01 13:59:58 +01:00
}
2002-12-22 12:49:10 +01:00
cChannel * cMenuChannels : : GetChannel ( int Index )
{
cMenuChannelItem * p = ( cMenuChannelItem * ) Get ( Index ) ;
return p ? ( cChannel * ) p - > Channel ( ) : NULL ;
}
2015-09-01 11:14:27 +02:00
void cMenuChannels : : Propagate ( cChannels * Channels )
2002-10-20 12:28:55 +02:00
{
2015-09-01 11:14:27 +02:00
Channels - > ReNumber ( ) ;
2002-10-20 12:28:55 +02:00
for ( cMenuChannelItem * ci = ( cMenuChannelItem * ) First ( ) ; ci ; ci = ( cMenuChannelItem * ) ci - > Next ( ) )
ci - > Set ( ) ;
Display ( ) ;
2015-09-01 11:14:27 +02:00
Channels - > SetModifiedByUser ( ) ;
2002-10-20 12:28:55 +02:00
}
2006-01-05 13:43:07 +01:00
eOSState cMenuChannels : : Number ( eKeys Key )
{
if ( HasSubMenu ( ) )
return osContinue ;
if ( numberTimer . TimedOut ( ) )
number = 0 ;
if ( ! number & & Key = = k0 ) {
cMenuChannelItem : : IncSortMode ( ) ;
2015-09-01 11:14:27 +02:00
Set ( true ) ;
2006-01-05 13:43:07 +01:00
}
else {
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
2006-01-05 13:43:07 +01:00
number = number * 10 + Key - k0 ;
for ( cMenuChannelItem * ci = ( cMenuChannelItem * ) First ( ) ; ci ; ci = ( cMenuChannelItem * ) ci - > Next ( ) ) {
if ( ! ci - > Channel ( ) - > GroupSep ( ) & & ci - > Channel ( ) - > Number ( ) = = number ) {
SetCurrent ( ci ) ;
Display ( ) ;
break ;
}
}
numberTimer . Set ( CHANNELNUMBERTIMEOUT ) ;
}
return osContinue ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuChannels : : Switch ( void )
{
2003-07-26 10:09:38 +02:00
if ( HasSubMenu ( ) )
return osContinue ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
2002-12-22 12:49:10 +01:00
cChannel * ch = GetChannel ( Current ( ) ) ;
2000-03-11 11:22:37 +01:00
if ( ch )
2004-02-08 14:15:01 +01:00
return cDevice : : PrimaryDevice ( ) - > SwitchChannel ( ch , true ) ? osEnd : osContinue ;
2000-03-11 11:22:37 +01:00
return osEnd ;
}
eOSState cMenuChannels : : Edit ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
2002-12-22 12:49:10 +01:00
cChannel * ch = GetChannel ( Current ( ) ) ;
2002-11-10 15:50:21 +01:00
if ( ch )
2015-09-01 11:14:27 +02:00
return AddSubMenu ( new cMenuEditChannel ( & channelsStateKey , ch ) ) ;
2002-10-20 14:22:09 +02:00
return osContinue ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuChannels : : New ( void )
{
if ( HasSubMenu ( ) )
return osContinue ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
return AddSubMenu ( new cMenuEditChannel ( & channelsStateKey , GetChannel ( Current ( ) ) , true ) ) ;
2000-02-19 13:36:48 +01:00
}
2002-11-10 16:07:58 +01:00
eOSState cMenuChannels : : Delete ( void )
2000-02-19 13:36:48 +01:00
{
2003-07-26 10:09:38 +02:00
if ( ! HasSubMenu ( ) & & Count ( ) > 0 ) {
2015-09-01 11:14:27 +02:00
LOCK_TIMERS_READ ; // must lock timers before channels!
cChannels * Channels = cChannels : : GetChannelsWrite ( channelsStateKey ) ;
2000-03-11 11:22:37 +01:00
int Index = Current ( ) ;
2015-09-01 11:14:27 +02:00
cChannel * Channel = GetChannel ( Current ( ) ) ;
if ( ! Channels - > Contains ( Channel ) ) {
channelsStateKey . Remove ( false ) ;
channelsStateKey . Reset ( ) ; // makes sure the menu is refreshed
return osContinue ;
}
bool Deleted = false ;
int CurrentChannelNr = cDevice : : CurrentChannel ( ) ;
cChannel * CurrentChannel = Channels - > GetByNumber ( CurrentChannelNr ) ;
int DeletedChannel = Channel - > Number ( ) ;
2000-03-11 11:22:37 +01:00
// Check if there is a timer using this channel:
2015-09-01 11:14:27 +02:00
if ( Timers - > UsesChannel ( Channel ) ) {
2016-12-08 10:43:58 +01:00
channelsStateKey . Remove ( false ) ;
2006-02-28 14:00:28 +01:00
Skins . Message ( mtError , tr ( " Channel is being used by a timer! " ) ) ;
return osContinue ;
}
2000-12-28 12:57:16 +01:00
if ( Interface - > Confirm ( tr ( " Delete channel? " ) ) ) {
2015-09-01 11:14:27 +02:00
if ( CurrentChannel & & Channel = = CurrentChannel ) {
int n = Channels - > GetNextNormal ( CurrentChannel - > Index ( ) ) ;
2006-05-28 10:48:50 +02:00
if ( n < 0 )
2015-09-01 11:14:27 +02:00
n = Channels - > GetPrevNormal ( CurrentChannel - > Index ( ) ) ;
CurrentChannel = Channels - > Get ( n ) ;
2006-05-28 10:48:50 +02:00
CurrentChannelNr = 0 ; // triggers channel switch below
}
2015-09-01 11:14:27 +02:00
Channels - > Del ( Channel ) ;
2000-03-11 11:22:37 +01:00
cOsdMenu : : Del ( Index ) ;
2015-09-01 11:14:27 +02:00
Propagate ( Channels ) ;
2002-05-13 16:35:49 +02:00
isyslog ( " channel %d deleted " , DeletedChannel ) ;
2015-09-01 11:14:27 +02:00
Deleted = true ;
2006-05-28 10:48:50 +02:00
if ( CurrentChannel & & CurrentChannel - > Number ( ) ! = CurrentChannelNr ) {
if ( ! cDevice : : PrimaryDevice ( ) - > Replaying ( ) | | cDevice : : PrimaryDevice ( ) - > Transferring ( ) )
2015-09-01 11:14:27 +02:00
Channels - > SwitchTo ( CurrentChannel - > Number ( ) ) ;
2006-05-28 10:48:50 +02:00
else
2016-12-08 10:48:53 +01:00
cDevice : : SetCurrentChannel ( CurrentChannel - > Number ( ) ) ;
2006-05-28 10:48:50 +02:00
}
2000-03-11 11:22:37 +01:00
}
2015-09-01 11:14:27 +02:00
channelsStateKey . Remove ( Deleted ) ;
2000-03-11 11:22:37 +01:00
}
return osContinue ;
}
2000-02-19 13:36:48 +01:00
2000-03-11 11:22:37 +01:00
void cMenuChannels : : Move ( int From , int To )
{
2015-09-01 11:14:27 +02:00
if ( cChannels * Channels = cChannels : : GetChannelsWrite ( channelsStateKey ) ) {
int CurrentChannelNr = cDevice : : CurrentChannel ( ) ;
cChannel * CurrentChannel = Channels - > GetByNumber ( CurrentChannelNr ) ;
cChannel * FromChannel = GetChannel ( From ) ;
cChannel * ToChannel = GetChannel ( To ) ;
if ( FromChannel & & ToChannel ) {
int FromNumber = FromChannel - > Number ( ) ;
int ToNumber = ToChannel - > Number ( ) ;
2020-04-11 09:22:05 +02:00
if ( Channels - > MoveNeedsDecrement ( FromChannel , ToChannel ) ) {
ToChannel = Channels - > Prev ( ToChannel ) ; // cListBase::Move() doesn't know about the channel list's numbered groups!
To - - ;
}
2015-09-01 11:14:27 +02:00
Channels - > Move ( FromChannel , ToChannel ) ;
cOsdMenu : : Move ( From , To ) ;
2020-04-11 09:22:05 +02:00
SetCurrent ( Get ( To ) ) ;
2015-09-01 11:14:27 +02:00
Propagate ( Channels ) ;
isyslog ( " channel %d moved to %d " , FromNumber , ToNumber ) ;
if ( CurrentChannel & & CurrentChannel - > Number ( ) ! = CurrentChannelNr ) {
if ( ! cDevice : : PrimaryDevice ( ) - > Replaying ( ) | | cDevice : : PrimaryDevice ( ) - > Transferring ( ) )
Channels - > SwitchTo ( CurrentChannel - > Number ( ) ) ;
else
2016-12-08 10:48:53 +01:00
cDevice : : SetCurrentChannel ( CurrentChannel - > Number ( ) ) ;
2015-09-01 11:14:27 +02:00
}
2006-05-28 09:19:30 +02:00
}
2015-09-01 11:14:27 +02:00
channelsStateKey . Remove ( ) ;
2002-12-22 12:49:10 +01:00
}
2000-03-11 11:22:37 +01:00
}
eOSState cMenuChannels : : ProcessKey ( eKeys Key )
{
2015-09-01 11:14:27 +02:00
if ( ! HasSubMenu ( ) )
Set ( ) ; // react on any changes to the channels list
2000-03-11 11:22:37 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2002-11-10 15:50:21 +01:00
switch ( state ) {
case osUser1 : {
2015-09-01 11:14:27 +02:00
if ( cMenuEditChannel * MenuEditChannel = dynamic_cast < cMenuEditChannel * > ( SubMenu ( ) ) ) {
if ( cChannel * Channel = MenuEditChannel - > Channel ( ) ) {
LOCK_CHANNELS_READ ;
Add ( new cMenuChannelItem ( Channel ) , true ) ;
return CloseSubMenu ( ) ;
}
2002-11-10 15:50:21 +01:00
}
}
break ;
default :
if ( state = = osUnknown ) {
2019-03-18 16:20:17 +01:00
switch ( int ( Key ) ) {
2006-01-05 13:43:07 +01:00
case k0 . . . k9 :
return Number ( Key ) ;
2002-11-10 15:50:21 +01:00
case kOk : return Switch ( ) ;
case kRed : return Edit ( ) ;
case kGreen : return New ( ) ;
2002-11-10 16:07:58 +01:00
case kYellow : return Delete ( ) ;
2006-01-05 15:11:04 +01:00
case kBlue : if ( ! HasSubMenu ( ) )
2003-07-26 10:09:38 +02:00
Mark ( ) ;
break ;
2019-03-18 16:20:17 +01:00
case kChanUp | k_Repeat :
case kChanUp :
case kChanDn | k_Repeat :
case kChanDn : {
LOCK_CHANNELS_READ ;
int CurrentChannelNr = cDevice : : CurrentChannel ( ) ;
for ( cMenuChannelItem * ci = ( cMenuChannelItem * ) First ( ) ; ci ; ci = ( cMenuChannelItem * ) ci - > Next ( ) ) {
if ( ! ci - > Channel ( ) - > GroupSep ( ) & & ci - > Channel ( ) - > Number ( ) = = CurrentChannelNr ) {
SetCurrent ( ci ) ;
Display ( ) ;
break ;
}
}
}
2002-11-10 15:50:21 +01:00
default : break ;
}
}
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
2000-11-11 16:38:41 +01:00
// --- cMenuText -------------------------------------------------------------
2000-07-24 16:43:04 +02:00
2000-11-18 15:46:00 +01:00
cMenuText : : cMenuText ( const char * Title , const char * Text , eDvbFont Font )
2000-11-11 16:38:41 +01:00
: cOsdMenu ( Title )
2000-07-24 16:43:04 +02:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcText ) ;
2004-05-23 09:54:06 +02:00
text = NULL ;
2006-02-17 15:45:25 +01:00
font = Font ;
2004-05-23 09:54:06 +02:00
SetText ( Text ) ;
}
cMenuText : : ~ cMenuText ( )
{
free ( text ) ;
}
void cMenuText : : SetText ( const char * Text )
{
free ( text ) ;
2004-08-08 14:21:17 +02:00
text = Text ? strdup ( Text ) : NULL ;
2004-05-16 10:35:36 +02:00
}
void cMenuText : : Display ( void )
{
cOsdMenu : : Display ( ) ;
2006-02-17 15:45:25 +01:00
DisplayMenu ( ) - > SetText ( text , font = = fontFix ) ; //XXX define control character in text to choose the font???
2006-04-09 14:31:33 +02:00
if ( text )
cStatus : : MsgOsdTextItem ( text ) ;
2000-07-24 16:43:04 +02:00
}
2000-11-11 16:38:41 +01:00
eOSState cMenuText : : ProcessKey ( eKeys Key )
2000-07-24 16:43:04 +02:00
{
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2004-05-16 10:35:36 +02:00
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
case kLeft | k_Repeat :
case kLeft :
case kRight | k_Repeat :
case kRight :
DisplayMenu ( ) - > Scroll ( NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft , NORMALKEY ( Key ) = = kLeft | | NORMALKEY ( Key ) = = kRight ) ;
2007-08-12 10:45:43 +02:00
cStatus : : MsgOsdTextItem ( NULL , NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft ) ;
2004-05-16 10:35:36 +02:00
return osContinue ;
default : break ;
}
2000-07-24 16:43:04 +02:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2000-11-11 16:38:41 +01:00
if ( state = = osUnknown ) {
switch ( Key ) {
case kOk : return osBack ;
default : state = osContinue ;
}
}
2000-07-24 16:43:04 +02:00
return state ;
}
2010-01-17 12:08:03 +01:00
// --- cMenuFolderItem -------------------------------------------------------
class cMenuFolderItem : public cOsdItem {
private :
cNestedItem * folder ;
public :
2017-12-15 13:43:00 +01:00
virtual void Set ( void ) ;
2010-01-17 12:08:03 +01:00
cMenuFolderItem ( cNestedItem * Folder ) ;
cNestedItem * Folder ( void ) { return folder ; }
} ;
cMenuFolderItem : : cMenuFolderItem ( cNestedItem * Folder )
: cOsdItem ( Folder - > Text ( ) )
{
folder = Folder ;
2017-12-15 13:43:00 +01:00
Set ( ) ;
}
void cMenuFolderItem : : Set ( void )
{
if ( folder - > SubItems ( ) & & folder - > SubItems ( ) - > Count ( ) )
2010-01-17 12:08:03 +01:00
SetText ( cString : : sprintf ( " %s... " , folder - > Text ( ) ) ) ;
2017-12-15 13:43:00 +01:00
else
SetText ( folder - > Text ( ) ) ;
2010-01-17 12:08:03 +01:00
}
// --- cMenuEditFolder -------------------------------------------------------
class cMenuEditFolder : public cOsdMenu {
private :
cList < cNestedItem > * list ;
cNestedItem * folder ;
char name [ PATH_MAX ] ;
eOSState Confirm ( void ) ;
public :
cMenuEditFolder ( const char * Dir , cList < cNestedItem > * List , cNestedItem * Folder = NULL ) ;
cString GetFolder ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuEditFolder : : cMenuEditFolder ( const char * Dir , cList < cNestedItem > * List , cNestedItem * Folder )
: cOsdMenu ( Folder ? tr ( " Edit folder " ) : tr ( " New folder " ) , 12 )
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcFolder ) ;
2010-01-17 12:08:03 +01:00
list = List ;
folder = Folder ;
2017-12-15 13:43:00 +01:00
if ( folder )
2010-01-17 12:08:03 +01:00
strn0cpy ( name , folder - > Text ( ) , sizeof ( name ) ) ;
else {
* name = 0 ;
cRemote : : Put ( kRight , true ) ; // go right into string editing mode
}
if ( ! isempty ( Dir ) ) {
cOsdItem * DirItem = new cOsdItem ( Dir ) ;
DirItem - > SetSelectable ( false ) ;
Add ( DirItem ) ;
}
Add ( new cMenuEditStrItem ( tr ( " Name " ) , name , sizeof ( name ) ) ) ;
}
cString cMenuEditFolder : : GetFolder ( void )
{
return folder ? folder - > Text ( ) : " " ;
}
eOSState cMenuEditFolder : : Confirm ( void )
{
if ( ! folder | | strcmp ( folder - > Text ( ) , name ) ! = 0 ) {
// each name may occur only once in a folder list
for ( cNestedItem * Folder = list - > First ( ) ; Folder ; Folder = list - > Next ( Folder ) ) {
if ( strcmp ( Folder - > Text ( ) , name ) = = 0 ) {
Skins . Message ( mtError , tr ( " Folder name already exists! " ) ) ;
return osContinue ;
}
}
char * p = strpbrk ( name , " \\ {}#~ " ) ; // FOLDERDELIMCHAR
if ( p ) {
Skins . Message ( mtError , cString : : sprintf ( tr ( " Folder name must not contain '%c'! " ) , * p ) ) ;
return osContinue ;
}
}
2017-12-15 13:43:00 +01:00
if ( folder )
2010-01-17 12:08:03 +01:00
folder - > SetText ( name ) ;
else
2017-12-15 13:43:00 +01:00
list - > Add ( folder = new cNestedItem ( name ) ) ;
2010-01-17 12:08:03 +01:00
return osEnd ;
}
eOSState cMenuEditFolder : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
case kOk : return Confirm ( ) ;
case kRed :
case kGreen :
case kYellow :
case kBlue : return osContinue ;
default : break ;
}
}
return state ;
}
// --- cMenuFolder -----------------------------------------------------------
cMenuFolder : : cMenuFolder ( const char * Title , cNestedItemList * NestedItemList , const char * Path )
: cOsdMenu ( Title )
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcFolder ) ;
2010-01-17 12:08:03 +01:00
list = nestedItemList = NestedItemList ;
firstFolder = NULL ;
editing = false ;
2013-11-03 13:43:01 +01:00
helpKeys = - 1 ;
2010-01-17 12:08:03 +01:00
Set ( ) ;
DescendPath ( Path ) ;
2013-11-03 13:43:01 +01:00
Display ( ) ;
SetHelpKeys ( ) ;
2010-01-17 12:08:03 +01:00
}
cMenuFolder : : cMenuFolder ( const char * Title , cList < cNestedItem > * List , cNestedItemList * NestedItemList , const char * Dir , const char * Path )
: cOsdMenu ( Title )
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcFolder ) ;
2010-01-17 12:08:03 +01:00
list = List ;
nestedItemList = NestedItemList ;
dir = Dir ;
firstFolder = NULL ;
editing = false ;
2013-11-03 13:43:01 +01:00
helpKeys = - 1 ;
2010-01-17 12:08:03 +01:00
Set ( ) ;
DescendPath ( Path ) ;
2013-11-03 13:43:01 +01:00
Display ( ) ;
SetHelpKeys ( ) ;
2010-01-17 12:08:03 +01:00
}
void cMenuFolder : : SetHelpKeys ( void )
{
2013-11-03 13:43:01 +01:00
if ( HasSubMenu ( ) )
return ;
int NewHelpKeys = 0 ;
2017-12-15 13:43:00 +01:00
if ( firstFolder )
NewHelpKeys = 1 ;
2013-11-03 13:43:01 +01:00
if ( NewHelpKeys ! = helpKeys ) {
helpKeys = NewHelpKeys ;
SetHelp ( NewHelpKeys > 0 ? tr ( " Button$Open " ) : NULL , tr ( " Button$New " ) , firstFolder ? tr ( " Button$Delete " ) : NULL , firstFolder ? tr ( " Button$Edit " ) : NULL ) ;
}
2010-01-17 12:08:03 +01:00
}
2015-02-04 13:20:37 +01:00
# define FOLDERDELIMCHARSUBST 0x01
2015-09-01 11:14:27 +02:00
static void AddRecordingFolders ( const cRecordings * Recordings , cList < cNestedItem > * List , char * Path )
2015-02-04 13:20:37 +01:00
{
if ( Path ) {
char * p = strchr ( Path , FOLDERDELIMCHARSUBST ) ;
if ( p )
* p + + = 0 ;
cNestedItem * Folder ;
for ( Folder = List - > First ( ) ; Folder ; Folder = List - > Next ( Folder ) ) {
if ( strcmp ( Path , Folder - > Text ( ) ) = = 0 )
break ;
}
if ( ! Folder )
List - > Add ( Folder = new cNestedItem ( Path ) ) ;
if ( p ) {
Folder - > SetSubItems ( true ) ;
2015-09-01 11:14:27 +02:00
AddRecordingFolders ( Recordings , Folder - > SubItems ( ) , p ) ;
2015-02-04 13:20:37 +01:00
}
}
else {
cStringList Dirs ;
2015-09-01 11:14:27 +02:00
for ( const cRecording * Recording = Recordings - > First ( ) ; Recording ; Recording = Recordings - > Next ( Recording ) ) {
2015-02-04 13:20:37 +01:00
cString Folder = Recording - > Folder ( ) ;
strreplace ( ( char * ) * Folder , FOLDERDELIMCHAR , FOLDERDELIMCHARSUBST ) ; // makes sure parent folders come before subfolders
if ( Dirs . Find ( Folder ) < 0 )
Dirs . Append ( strdup ( Folder ) ) ;
}
Dirs . Sort ( ) ;
for ( int i = 0 ; i < Dirs . Size ( ) ; i + + ) {
2015-09-01 11:14:27 +02:00
if ( char * s = Dirs [ i ] )
AddRecordingFolders ( Recordings , & Folders , s ) ;
2015-02-04 13:20:37 +01:00
}
}
}
2010-01-17 12:08:03 +01:00
void cMenuFolder : : Set ( const char * CurrentFolder )
{
2015-09-01 11:14:27 +02:00
static cStateKey RecordingsStateKey ;
if ( list = = & Folders ) {
if ( const cRecordings * Recordings = cRecordings : : GetRecordingsRead ( RecordingsStateKey ) ) {
AddRecordingFolders ( Recordings , & Folders , NULL ) ;
RecordingsStateKey . Remove ( ) ;
}
}
2010-01-17 12:08:03 +01:00
firstFolder = NULL ;
Clear ( ) ;
if ( ! isempty ( dir ) ) {
cOsdItem * DirItem = new cOsdItem ( dir ) ;
DirItem - > SetSelectable ( false ) ;
Add ( DirItem ) ;
}
list - > Sort ( ) ;
for ( cNestedItem * Folder = list - > First ( ) ; Folder ; Folder = list - > Next ( Folder ) ) {
cOsdItem * FolderItem = new cMenuFolderItem ( Folder ) ;
Add ( FolderItem , CurrentFolder ? strcmp ( Folder - > Text ( ) , CurrentFolder ) = = 0 : false ) ;
if ( ! firstFolder )
firstFolder = FolderItem ;
}
}
void cMenuFolder : : DescendPath ( const char * Path )
{
if ( Path ) {
const char * p = strchr ( Path , FOLDERDELIMCHAR ) ;
if ( p ) {
for ( cMenuFolderItem * Folder = ( cMenuFolderItem * ) firstFolder ; Folder ; Folder = ( cMenuFolderItem * ) Next ( Folder ) ) {
if ( strncmp ( Folder - > Folder ( ) - > Text ( ) , Path , p - Path ) = = 0 ) {
SetCurrent ( Folder ) ;
2013-11-03 13:43:01 +01:00
if ( Folder - > Folder ( ) - > SubItems ( ) & & strchr ( p + 1 , FOLDERDELIMCHAR ) )
2010-01-17 12:08:03 +01:00
AddSubMenu ( new cMenuFolder ( Title ( ) , Folder - > Folder ( ) - > SubItems ( ) , nestedItemList , ! isempty ( dir ) ? * cString : : sprintf ( " %s%c%s " , * dir , FOLDERDELIMCHAR , Folder - > Folder ( ) - > Text ( ) ) : Folder - > Folder ( ) - > Text ( ) , p + 1 ) ) ;
break ;
}
}
}
}
}
2013-11-03 13:43:01 +01:00
eOSState cMenuFolder : : Select ( bool Open )
2010-01-17 12:08:03 +01:00
{
if ( firstFolder ) {
cMenuFolderItem * Folder = ( cMenuFolderItem * ) Get ( Current ( ) ) ;
if ( Folder ) {
2017-12-15 13:43:00 +01:00
if ( Open ) {
Folder - > Folder ( ) - > SetSubItems ( true ) ;
2010-01-17 12:08:03 +01:00
return AddSubMenu ( new cMenuFolder ( Title ( ) , Folder - > Folder ( ) - > SubItems ( ) , nestedItemList , ! isempty ( dir ) ? * cString : : sprintf ( " %s%c%s " , * dir , FOLDERDELIMCHAR , Folder - > Folder ( ) - > Text ( ) ) : Folder - > Folder ( ) - > Text ( ) ) ) ;
2017-12-15 13:43:00 +01:00
}
2010-01-17 12:08:03 +01:00
else
return osEnd ;
}
}
return osContinue ;
}
eOSState cMenuFolder : : New ( void )
{
editing = true ;
return AddSubMenu ( new cMenuEditFolder ( dir , list ) ) ;
}
eOSState cMenuFolder : : Delete ( void )
{
if ( ! HasSubMenu ( ) & & firstFolder ) {
cMenuFolderItem * Folder = ( cMenuFolderItem * ) Get ( Current ( ) ) ;
if ( Folder & & Interface - > Confirm ( Folder - > Folder ( ) - > SubItems ( ) ? tr ( " Delete folder and all sub folders? " ) : tr ( " Delete folder? " ) ) ) {
list - > Del ( Folder - > Folder ( ) ) ;
Del ( Folder - > Index ( ) ) ;
firstFolder = Get ( isempty ( dir ) ? 0 : 1 ) ;
Display ( ) ;
SetHelpKeys ( ) ;
nestedItemList - > Save ( ) ;
}
}
return osContinue ;
}
eOSState cMenuFolder : : Edit ( void )
{
if ( ! HasSubMenu ( ) & & firstFolder ) {
cMenuFolderItem * Folder = ( cMenuFolderItem * ) Get ( Current ( ) ) ;
if ( Folder ) {
editing = true ;
return AddSubMenu ( new cMenuEditFolder ( dir , list , Folder - > Folder ( ) ) ) ;
}
}
return osContinue ;
}
eOSState cMenuFolder : : SetFolder ( void )
{
2013-10-10 13:13:30 +02:00
if ( cMenuEditFolder * mef = dynamic_cast < cMenuEditFolder * > ( SubMenu ( ) ) ) {
2010-01-17 12:08:03 +01:00
Set ( mef - > GetFolder ( ) ) ;
SetHelpKeys ( ) ;
Display ( ) ;
nestedItemList - > Save ( ) ;
}
return CloseSubMenu ( ) ;
}
cString cMenuFolder : : GetFolder ( void )
{
if ( firstFolder ) {
cMenuFolderItem * Folder = ( cMenuFolderItem * ) Get ( Current ( ) ) ;
if ( Folder ) {
2013-10-10 13:13:30 +02:00
if ( cMenuFolder * mf = dynamic_cast < cMenuFolder * > ( SubMenu ( ) ) )
2010-01-17 12:08:03 +01:00
return cString : : sprintf ( " %s%c%s " , Folder - > Folder ( ) - > Text ( ) , FOLDERDELIMCHAR , * mf - > GetFolder ( ) ) ;
return Folder - > Folder ( ) - > Text ( ) ;
}
}
return " " ;
}
eOSState cMenuFolder : : ProcessKey ( eKeys Key )
{
if ( ! HasSubMenu ( ) )
editing = false ;
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
2013-11-03 13:43:01 +01:00
case kOk : return Select ( false ) ;
case kRed : return Select ( true ) ;
2010-01-17 12:08:03 +01:00
case kGreen : return New ( ) ;
case kYellow : return Delete ( ) ;
case kBlue : return Edit ( ) ;
default : state = osContinue ;
}
}
else if ( state = = osEnd & & HasSubMenu ( ) & & editing )
state = SetFolder ( ) ;
2013-11-03 13:43:01 +01:00
SetHelpKeys ( ) ;
2010-01-17 12:08:03 +01:00
return state ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuEditTimer --------------------------------------------------------
2020-12-26 15:49:01 +01:00
static const char * TimerFileMacrosForPattern [ ] = {
TIMERMACRO_TITLE ,
TIMERMACRO_EPISODE ,
TIMERMACRO_BEFORE ,
TIMERMACRO_MATCH ,
TIMERMACRO_AFTER ,
" " ,
NULL
} ;
static const char * TimerFileMacros [ ] = {
TIMERMACRO_TITLE ,
TIMERMACRO_EPISODE ,
" " ,
NULL
} ;
2015-09-01 11:14:27 +02:00
const cTimer * cMenuEditTimer : : addedTimer = NULL ;
2003-06-06 15:02:37 +02:00
cMenuEditTimer : : cMenuEditTimer ( cTimer * Timer , bool New )
2002-04-06 09:51:08 +02:00
: cOsdMenu ( tr ( " Edit timer " ) , 12 )
2000-02-19 13:36:48 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcTimerEdit ) ;
2015-09-01 11:14:27 +02:00
addedTimer = NULL ;
2020-12-26 15:49:01 +01:00
pattern = NULL ;
2010-01-17 12:08:03 +01:00
file = NULL ;
2012-03-08 13:51:00 +01:00
day = firstday = NULL ;
2003-06-06 15:02:37 +02:00
timer = Timer ;
addIfConfirmed = New ;
2000-02-19 13:36:48 +01:00
if ( timer ) {
data = * timer ;
2000-04-15 17:38:11 +02:00
if ( New )
2004-02-29 14:21:22 +01:00
data . SetFlags ( tfActive ) ;
2002-10-20 12:28:55 +02:00
channel = data . Channel ( ) - > Number ( ) ;
2004-02-29 14:21:22 +01:00
Add ( new cMenuEditBitItem ( tr ( " Active " ) , & data . flags , tfActive ) ) ;
2002-10-20 12:28:55 +02:00
Add ( new cMenuEditChanItem ( tr ( " Channel " ) , & channel ) ) ;
2012-03-08 13:51:00 +01:00
Add ( day = new cMenuEditDateItem ( tr ( " Day " ) , & data . day , & data . weekdays ) ) ;
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditTimeItem ( tr ( " Start " ) , & data . start ) ) ;
Add ( new cMenuEditTimeItem ( tr ( " Stop " ) , & data . stop ) ) ;
2004-02-29 14:21:22 +01:00
Add ( new cMenuEditBitItem ( tr ( " VPS " ) , & data . flags , tfVps ) ) ;
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditIntItem ( tr ( " Priority " ) , & data . priority , 0 , MAXPRIORITY ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Lifetime " ) , & data . lifetime , 0 , MAXLIFETIME ) ) ;
2010-01-17 12:08:03 +01:00
Add ( file = new cMenuEditStrItem ( tr ( " File " ) , data . file , sizeof ( data . file ) ) ) ;
2002-02-17 13:05:05 +01:00
SetFirstDayItem ( ) ;
2020-12-26 15:49:01 +01:00
SetPatternItem ( true ) ;
2015-09-10 10:39:45 +02:00
if ( data . remote )
strn0cpy ( remote , data . remote , sizeof ( remote ) ) ;
else
* remote = 0 ;
if ( GetSVDRPServerNames ( & svdrpServerNames ) ) {
svdrpServerNames . Sort ( true ) ;
svdrpServerNames . Insert ( strdup ( " " ) ) ;
Add ( new cMenuEditStrlItem ( tr ( " Record on " ) , remote , sizeof ( remote ) , & svdrpServerNames ) ) ;
}
2002-02-17 13:05:05 +01:00
}
2010-01-17 12:08:03 +01:00
SetHelpKeys ( ) ;
2003-02-09 13:14:44 +01:00
}
cMenuEditTimer : : ~ cMenuEditTimer ( )
{
2003-06-06 15:02:37 +02:00
if ( timer & & addIfConfirmed )
delete timer ; // apparently it wasn't confirmed
2015-09-01 11:14:27 +02:00
}
const cTimer * cMenuEditTimer : : AddedTimer ( void )
{
const cTimer * Timer = addedTimer ;
addedTimer = NULL ;
return Timer ;
2002-02-17 13:05:05 +01:00
}
2010-01-17 12:08:03 +01:00
void cMenuEditTimer : : SetHelpKeys ( void )
{
2020-12-26 15:49:01 +01:00
SetHelp ( tr ( " Button$Folder " ) , data . weekdays ? tr ( " Button$Single " ) : tr ( " Button$Repeating " ) , * data . pattern ? tr ( " Button$Regular " ) : tr ( " Button$Pattern " ) ) ;
2010-01-17 12:08:03 +01:00
}
2002-02-17 13:05:05 +01:00
void cMenuEditTimer : : SetFirstDayItem ( void )
{
if ( ! firstday & & ! data . IsSingleEvent ( ) ) {
2005-03-19 15:38:43 +01:00
Add ( firstday = new cMenuEditDateItem ( tr ( " First day " ) , & data . day ) ) ;
2002-02-17 13:05:05 +01:00
Display ( ) ;
}
else if ( firstday & & data . IsSingleEvent ( ) ) {
Del ( firstday - > Index ( ) ) ;
firstday = NULL ;
Display ( ) ;
2000-02-19 13:36:48 +01:00
}
}
2020-12-26 15:49:01 +01:00
void cMenuEditTimer : : SetPatternItem ( bool Initial )
{
if ( Initial & & ! * data . pattern ) {
file - > SetMacros ( TimerFileMacros ) ;
return ;
}
if ( ! pattern ) {
if ( data . HasFlags ( tfRecording ) ) {
Skins . Message ( mtWarning , tr ( " Timer is recording! " ) ) ;
return ;
}
if ( ! * data . pattern ) {
2021-01-01 15:26:27 +01:00
char * p = strgetlast ( data . file , FOLDERDELIMCHAR ) ;
2020-12-26 15:49:01 +01:00
strn0cpy ( data . pattern , p , sizeof ( data . pattern ) ) ;
}
Ins ( pattern = new cMenuEditStrItem ( tr ( " Pattern " ) , data . pattern , sizeof ( data . pattern ) ) , true , file ) ;
pattern - > SetKeepSpace ( ) ;
file - > SetMacros ( TimerFileMacrosForPattern ) ;
Display ( ) ;
}
else {
Del ( pattern - > Index ( ) ) ;
pattern = NULL ;
* data . pattern = 0 ;
file - > SetMacros ( TimerFileMacros ) ;
Display ( ) ;
}
SetHelpKeys ( ) ;
}
2010-01-17 12:08:03 +01:00
eOSState cMenuEditTimer : : SetFolder ( void )
{
2013-10-10 13:13:30 +02:00
if ( cMenuFolder * mf = dynamic_cast < cMenuFolder * > ( SubMenu ( ) ) ) {
2010-01-17 12:08:03 +01:00
cString Folder = mf - > GetFolder ( ) ;
2021-01-01 15:26:27 +01:00
char * p = strgetlast ( data . file , FOLDERDELIMCHAR ) ;
2010-01-17 12:08:03 +01:00
if ( ! isempty ( * Folder ) )
strn0cpy ( data . file , cString : : sprintf ( " %s%c%s " , * Folder , FOLDERDELIMCHAR , p ) , sizeof ( data . file ) ) ;
else if ( p ! = data . file )
memmove ( data . file , p , strlen ( p ) + 1 ) ;
SetCurrent ( file ) ;
Display ( ) ;
}
return CloseSubMenu ( ) ;
}
2015-09-10 10:39:45 +02:00
static bool RemoteTimerError ( const cTimer * Timer )
{
2015-09-11 08:38:11 +02:00
Skins . Message ( mtError , cString : : sprintf ( " %s %d@%s! " , tr ( " Error while accessing remote timer " ) , Timer - > Id ( ) , Timer - > Remote ( ) ) ) ;
2015-09-10 10:39:45 +02:00
return false ; // convenience return code
}
2015-09-14 13:23:06 +02:00
static bool HandleRemoteModifications ( cTimer * NewTimer , cTimer * OldTimer = NULL )
2015-09-10 10:39:45 +02:00
{
2017-03-30 15:25:20 +02:00
cString ErrorMessage ;
if ( ! HandleRemoteTimerModifications ( NewTimer , OldTimer , & ErrorMessage ) ) {
2018-04-28 12:17:22 +02:00
Skins . QueueMessage ( mtError , ErrorMessage ) ;
2017-03-30 15:25:20 +02:00
return false ;
2015-09-10 10:39:45 +02:00
}
return true ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditTimer : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
2000-03-11 11:22:37 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2000-02-19 13:36:48 +01:00
2000-03-11 11:22:37 +01:00
if ( state = = osUnknown ) {
2000-11-11 12:55:10 +01:00
switch ( Key ) {
2015-09-01 11:14:27 +02:00
case kOk : if ( timer ) {
LOCK_TIMERS_WRITE ;
if ( ! addIfConfirmed & & ! Timers - > Contains ( timer ) ) {
2017-04-20 10:08:04 +02:00
if ( cTimer * t = Timers - > GetById ( timer - > Id ( ) , timer - > Remote ( ) ) )
timer = t ;
else {
Skins . Message ( mtWarning , tr ( " Timer has been deleted! " ) ) ;
break ;
}
2015-09-01 11:14:27 +02:00
}
LOCK_CHANNELS_READ ;
if ( const cChannel * Channel = Channels - > GetByNumber ( channel ) )
data . channel = Channel ;
else {
Skins . Message ( mtError , tr ( " *** Invalid Channel *** " ) ) ;
break ;
}
if ( ! * data . file )
strcpy ( data . file , data . Channel ( ) - > ShortName ( true ) ) ;
2015-09-10 10:39:45 +02:00
data . SetRemote ( * remote ? remote : NULL ) ;
2015-09-01 11:14:27 +02:00
if ( addIfConfirmed ) {
2015-09-14 13:23:06 +02:00
* timer = data ;
2015-09-01 11:14:27 +02:00
Timers - > Add ( timer ) ;
addedTimer = timer ;
2015-09-14 13:23:06 +02:00
if ( ! HandleRemoteModifications ( timer ) ) {
// must add the timer before HandleRemoteModifications to get proper log messages with timer ids
2020-11-06 13:13:05 +01:00
Timers - > Del ( timer , false ) ;
2015-09-14 13:23:06 +02:00
addedTimer = NULL ;
return osContinue ;
}
}
else {
if ( ! HandleRemoteModifications ( & data , timer ) )
return osContinue ;
2017-03-30 15:25:20 +02:00
if ( timer - > Local ( ) & & timer - > Recording ( ) & & data . Remote ( ) )
cRecordControls : : Stop ( timer ) ;
2018-03-05 15:49:20 +01:00
if ( timer - > Remote ( ) & & data . Remote ( ) )
Timers - > SetSyncStateKey ( StateKeySVDRPRemoteTimersPoll ) ;
2020-12-26 15:49:01 +01:00
if ( data . Local ( ) & & ! timer - > IsPatternTimer ( ) & & data . IsPatternTimer ( ) )
data . SetEvent ( NULL ) ;
2015-09-14 13:23:06 +02:00
* timer = data ;
2015-09-01 11:14:27 +02:00
}
2021-01-14 10:29:05 +01:00
timer - > TriggerRespawn ( ) ;
2015-09-01 11:14:27 +02:00
LOCK_SCHEDULES_READ ;
timer - > SetEventFromSchedule ( Schedules ) ;
timer - > Matches ( ) ;
addIfConfirmed = false ;
}
2000-11-11 12:55:10 +01:00
return osBack ;
2010-01-17 12:08:03 +01:00
case kRed : return AddSubMenu ( new cMenuFolder ( tr ( " Select folder " ) , & Folders , data . file ) ) ;
2012-03-08 13:51:00 +01:00
case kGreen : if ( day ) {
day - > ToggleRepeating ( ) ;
SetCurrent ( day ) ;
SetFirstDayItem ( ) ;
SetHelpKeys ( ) ;
Display ( ) ;
}
return osContinue ;
2020-12-26 15:49:01 +01:00
case kYellow : SetPatternItem ( ) ;
return osContinue ;
2000-11-11 12:55:10 +01:00
case kBlue : return osContinue ;
default : break ;
}
2000-02-19 13:36:48 +01:00
}
2010-01-17 12:08:03 +01:00
else if ( state = = osEnd & & HasSubMenu ( ) )
state = SetFolder ( ) ;
2002-02-17 13:05:05 +01:00
if ( Key ! = kNone )
SetFirstDayItem ( ) ;
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
// --- cMenuTimerItem --------------------------------------------------------
class cMenuTimerItem : public cOsdItem {
private :
2015-09-01 11:14:27 +02:00
const cTimer * timer ;
2000-02-19 13:36:48 +01:00
public :
2015-09-01 11:14:27 +02:00
cMenuTimerItem ( const cTimer * Timer ) ;
2004-11-01 10:40:38 +01:00
virtual int Compare ( const cListObject & ListObject ) const ;
2000-02-19 13:36:48 +01:00
virtual void Set ( void ) ;
2015-09-01 11:14:27 +02:00
const cTimer * Timer ( void ) { return timer ; }
2012-12-08 11:05:39 +01:00
virtual void SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable ) ;
2000-02-19 13:36:48 +01:00
} ;
2015-09-01 11:14:27 +02:00
cMenuTimerItem : : cMenuTimerItem ( const cTimer * Timer )
2000-02-19 13:36:48 +01:00
{
timer = Timer ;
Set ( ) ;
}
2004-11-01 10:40:38 +01:00
int cMenuTimerItem : : Compare ( const cListObject & ListObject ) const
2001-08-26 14:17:20 +02:00
{
2004-11-01 10:40:38 +01:00
return timer - > Compare ( * ( ( cMenuTimerItem * ) & ListObject ) - > timer ) ;
2001-08-26 14:17:20 +02:00
}
2000-02-19 13:36:48 +01:00
void cMenuTimerItem : : Set ( void )
{
2005-03-19 15:45:19 +01:00
cString day , name ( " " ) ;
if ( timer - > WeekDays ( ) )
2007-06-10 13:02:43 +02:00
day = timer - > PrintDay ( 0 , timer - > WeekDays ( ) , false ) ;
2005-03-19 15:45:19 +01:00
else if ( timer - > Day ( ) - time ( NULL ) < 28 * SECSINDAY ) {
day = itoa ( timer - > GetMDay ( timer - > Day ( ) ) ) ;
name = WeekDayName ( timer - > Day ( ) ) ;
}
else {
struct tm tm_r ;
time_t Day = timer - > Day ( ) ;
localtime_r ( & Day , & tm_r ) ;
char buffer [ 16 ] ;
strftime ( buffer , sizeof ( buffer ) , " %Y%m%d " , & tm_r ) ;
day = buffer ;
}
2020-12-26 15:49:01 +01:00
const char * File = timer - > Pattern ( ) ;
if ( ! * File ) {
if ( timer - > HasFlags ( tfSpawned ) & & timer - > Event ( ) & & timer - > Event ( ) - > Title ( ) )
File = timer - > Event ( ) - > Title ( ) ;
else {
File = Setup . FoldersInTimerMenu ? NULL : strrchr ( timer - > File ( ) , FOLDERDELIMCHAR ) ;
if ( File & & strcmp ( File + 1 , TIMERMACRO_TITLE ) & & strcmp ( File + 1 , TIMERMACRO_EPISODE ) )
File + + ;
else
File = timer - > File ( ) ;
}
}
SetText ( cString : : sprintf ( " %c \t %d \t %s%s%s \t %02d:%02d \t %02d:%02d \t %s%s%s%s " ,
2004-02-29 14:21:22 +01:00
! ( timer - > HasFlags ( tfActive ) ) ? ' ' : timer - > FirstDay ( ) ? ' ! ' : timer - > Recording ( ) ? ' # ' : ' > ' ,
2002-10-20 12:28:55 +02:00
timer - > Channel ( ) - > Number ( ) ,
2005-03-19 15:45:19 +01:00
* name ,
* name & & * * name ? " " : " " ,
* day ,
2002-10-20 12:28:55 +02:00
timer - > Start ( ) / 100 ,
timer - > Start ( ) % 100 ,
timer - > Stop ( ) / 100 ,
timer - > Stop ( ) % 100 ,
2015-09-06 09:32:00 +02:00
timer - > Remote ( ) ? * cString : : sprintf ( " @%s: " , timer - > Remote ( ) ) : " " ,
2020-12-26 15:49:01 +01:00
timer - > IsPatternTimer ( ) ? " { " : " " ,
File ,
timer - > IsPatternTimer ( ) ? " } " : " " ) ) ;
2000-02-19 13:36:48 +01:00
}
2012-12-08 11:05:39 +01:00
void cMenuTimerItem : : SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable )
{
if ( ! DisplayMenu - > SetItemTimer ( timer , Index , Current , Selectable ) )
DisplayMenu - > SetItem ( Text ( ) , Index , Current , Selectable ) ;
}
2000-03-11 11:22:37 +01:00
// --- cMenuTimers -----------------------------------------------------------
2000-02-19 13:36:48 +01:00
2000-03-11 11:22:37 +01:00
class cMenuTimers : public cOsdMenu {
private :
2015-09-01 11:14:27 +02:00
cStateKey timersStateKey ;
2006-02-25 14:39:29 +01:00
int helpKeys ;
2015-09-01 11:14:27 +02:00
void Set ( void ) ;
2000-03-11 11:22:37 +01:00
eOSState Edit ( void ) ;
eOSState New ( void ) ;
2002-11-10 16:07:58 +01:00
eOSState Delete ( void ) ;
2002-02-17 13:05:05 +01:00
eOSState OnOff ( void ) ;
2006-02-25 14:39:29 +01:00
eOSState Info ( void ) ;
2015-09-01 11:14:27 +02:00
cTimer * GetTimer ( void ) ;
2006-02-25 14:39:29 +01:00
void SetHelpKeys ( void ) ;
2000-02-19 13:36:48 +01:00
public :
2000-03-11 11:22:37 +01:00
cMenuTimers ( void ) ;
2003-02-09 13:14:44 +01:00
virtual ~ cMenuTimers ( ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
2000-03-11 11:22:37 +01:00
cMenuTimers : : cMenuTimers ( void )
2002-03-29 10:50:20 +01:00
: cOsdMenu ( tr ( " Timers " ) , 2 , CHNUMWIDTH , 10 , 6 , 6 )
2000-02-19 13:36:48 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcTimer ) ;
2006-02-25 14:39:29 +01:00
helpKeys = - 1 ;
2015-09-01 11:14:27 +02:00
cMenuEditTimer : : AddedTimer ( ) ; // to clear any leftovers
Set ( ) ;
2003-02-09 13:14:44 +01:00
}
cMenuTimers : : ~ cMenuTimers ( )
{
2001-08-26 14:17:20 +02:00
}
2015-09-01 11:14:27 +02:00
void cMenuTimers : : Set ( void )
{
if ( const cTimers * Timers = cTimers : : GetTimersRead ( timersStateKey ) ) {
const cTimer * CurrentTimer = GetTimer ( ) ;
cMenuTimerItem * CurrentItem = NULL ;
Clear ( ) ;
for ( const cTimer * Timer = Timers - > First ( ) ; Timer ; Timer = Timers - > Next ( Timer ) ) {
cMenuTimerItem * Item = new cMenuTimerItem ( Timer ) ;
Add ( Item ) ;
2015-09-10 10:39:45 +02:00
if ( CurrentTimer & & Timer - > Id ( ) = = CurrentTimer - > Id ( ) & & ( ! Timer - > Remote ( ) & & ! CurrentTimer - > Remote ( ) | | Timer - > Remote ( ) & & CurrentTimer - > Remote ( ) & & strcmp ( Timer - > Remote ( ) , CurrentTimer - > Remote ( ) ) = = 0 ) )
2015-09-01 11:14:27 +02:00
CurrentItem = Item ;
}
Sort ( ) ;
SetCurrent ( CurrentItem ? CurrentItem : First ( ) ) ;
SetHelpKeys ( ) ;
Display ( ) ;
timersStateKey . Remove ( ) ;
}
}
cTimer * cMenuTimers : : GetTimer ( void )
2001-08-26 14:17:20 +02:00
{
cMenuTimerItem * item = ( cMenuTimerItem * ) Get ( Current ( ) ) ;
2015-09-01 11:14:27 +02:00
return item ? ( cTimer * ) item - > Timer ( ) : NULL ;
2000-03-11 11:22:37 +01:00
}
2006-02-25 14:39:29 +01:00
void cMenuTimers : : SetHelpKeys ( void )
{
int NewHelpKeys = 0 ;
2015-09-01 11:14:27 +02:00
if ( const cTimer * Timer = GetTimer ( ) ) {
if ( Timer - > Event ( ) )
2006-02-25 14:39:29 +01:00
NewHelpKeys = 2 ;
else
NewHelpKeys = 1 ;
}
if ( NewHelpKeys ! = helpKeys ) {
helpKeys = NewHelpKeys ;
SetHelp ( helpKeys > 0 ? tr ( " Button$On/Off " ) : NULL , tr ( " Button$New " ) , helpKeys > 0 ? tr ( " Button$Delete " ) : NULL , helpKeys = = 2 ? tr ( " Button$Info " ) : NULL ) ;
}
}
2002-02-17 13:05:05 +01:00
eOSState cMenuTimers : : OnOff ( void )
2000-03-11 11:22:37 +01:00
{
2006-02-25 14:39:29 +01:00
if ( HasSubMenu ( ) )
return osContinue ;
2018-02-10 10:54:33 +01:00
cStateKey StateKey ;
2018-03-05 15:49:20 +01:00
cTimers * Timers = cTimers : : GetTimersWrite ( StateKey ) ;
2015-09-01 11:14:27 +02:00
cTimer * Timer = GetTimer ( ) ;
if ( Timer ) {
Timer - > OnOff ( ) ;
2015-09-10 10:39:45 +02:00
if ( Timer - > Remote ( ) ) {
2018-03-05 15:49:20 +01:00
Timers - > SetSyncStateKey ( StateKeySVDRPRemoteTimersPoll ) ;
2015-09-10 10:39:45 +02:00
cStringList Response ;
if ( ! ExecSVDRPCommand ( Timer - > Remote ( ) , cString : : sprintf ( " MODT %d %s " , Timer - > Id ( ) , * Timer - > ToText ( true ) ) , & Response ) | | SVDRPCode ( Response [ 0 ] ) ! = 250 )
2015-09-11 08:38:11 +02:00
RemoteTimerError ( Timer ) ;
2015-09-10 10:39:45 +02:00
}
2020-09-16 13:35:30 +02:00
{
LOCK_SCHEDULES_READ ;
Timer - > SetEventFromSchedule ( Schedules ) ;
}
2000-03-11 11:22:37 +01:00
RefreshCurrent ( ) ;
DisplayCurrent ( true ) ;
2015-09-01 11:14:27 +02:00
if ( Timer - > FirstDay ( ) )
2015-09-14 13:23:06 +02:00
isyslog ( " set first day of timer %s to %s " , * Timer - > ToDescr ( ) , * Timer - > PrintFirstDay ( ) ) ;
2002-02-17 13:05:05 +01:00
else
2015-09-14 13:23:06 +02:00
isyslog ( " %sactivated timer %s " , Timer - > HasFlags ( tfActive ) ? " " : " de " , * Timer - > ToDescr ( ) ) ;
2000-03-11 11:22:37 +01:00
}
2018-02-10 10:54:33 +01:00
StateKey . Remove ( Timer ! = NULL ) ;
2000-03-11 11:22:37 +01:00
return osContinue ;
}
eOSState cMenuTimers : : Edit ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
2015-09-01 11:14:27 +02:00
return AddSubMenu ( new cMenuEditTimer ( GetTimer ( ) ) ) ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuTimers : : New ( void )
{
if ( HasSubMenu ( ) )
return osContinue ;
2015-09-14 13:23:06 +02:00
cTimer * Timer = new cTimer ;
2017-05-20 13:01:34 +02:00
if ( Setup . SVDRPPeering & & * Setup . SVDRPDefaultHost )
2015-09-14 13:23:06 +02:00
Timer - > SetRemote ( Setup . SVDRPDefaultHost ) ;
return AddSubMenu ( new cMenuEditTimer ( Timer , true ) ) ;
2000-03-11 11:22:37 +01:00
}
2002-11-10 16:07:58 +01:00
eOSState cMenuTimers : : Delete ( void )
2000-03-11 11:22:37 +01:00
{
2015-09-01 11:14:27 +02:00
cTimers * Timers = cTimers : : GetTimersWrite ( timersStateKey ) ;
2000-03-11 11:22:37 +01:00
// Check if this timer is active:
2015-09-01 11:14:27 +02:00
cTimer * Timer = GetTimer ( ) ;
if ( Timer ) {
2018-03-18 12:03:46 +01:00
bool TimerRecording = Timer - > Recording ( ) ;
timersStateKey . Remove ( false ) ; // must release lock while prompting!
if ( Interface - > Confirm ( tr ( " Delete timer? " ) ) & & ( ! TimerRecording | | Interface - > Confirm ( tr ( " Timer still recording - really delete? " ) ) ) ) {
Timers = cTimers : : GetTimersWrite ( timersStateKey ) ;
Timer = GetTimer ( ) ;
2015-09-01 11:14:27 +02:00
if ( Timer ) {
2018-03-18 12:03:46 +01:00
if ( ! Timer - > Remote ( ) ) {
Timer - > Skip ( ) ;
cRecordControls : : Process ( Timers , time ( NULL ) ) ;
}
if ( HandleRemoteModifications ( NULL , Timer ) ) {
if ( Timer - > Remote ( ) )
Timers - > SetSyncStateKey ( StateKeySVDRPRemoteTimersPoll ) ;
Timers - > Del ( Timer ) ;
cOsdMenu : : Del ( Current ( ) ) ;
Display ( ) ;
2015-09-10 10:39:45 +02:00
}
2000-03-11 11:22:37 +01:00
}
}
2018-03-18 12:03:46 +01:00
else
return osContinue ;
2000-03-11 11:22:37 +01:00
}
2015-09-01 11:14:27 +02:00
timersStateKey . Remove ( Timer ! = NULL ) ;
2000-03-11 11:22:37 +01:00
return osContinue ;
2000-02-19 13:36:48 +01:00
}
2006-02-25 14:39:29 +01:00
eOSState cMenuTimers : : Info ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
2015-09-01 11:14:27 +02:00
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
cTimer * Timer = GetTimer ( ) ;
if ( Timer & & Timer - > Event ( ) )
return AddSubMenu ( new cMenuEvent ( Timers , Channels , Timer - > Event ( ) ) ) ;
2006-02-25 14:39:29 +01:00
return osContinue ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuTimers : : ProcessKey ( eKeys Key )
{
2015-09-01 11:14:27 +02:00
if ( ! HasSubMenu ( ) )
Set ( ) ;
2000-03-11 11:22:37 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2000-02-19 13:36:48 +01:00
switch ( Key ) {
2006-02-25 12:09:22 +01:00
case kOk : return Edit ( ) ;
2006-02-25 15:57:56 +01:00
case kRed : state = OnOff ( ) ; break ; // must go through SetHelpKeys()!
2000-03-11 11:22:37 +01:00
case kGreen : return New ( ) ;
2006-02-28 12:36:52 +01:00
case kYellow : state = Delete ( ) ; break ;
2007-11-25 15:27:10 +01:00
case kInfo :
2006-02-25 14:39:29 +01:00
case kBlue : return Info ( ) ;
break ;
2000-02-19 13:36:48 +01:00
default : break ;
}
}
2015-09-01 11:14:27 +02:00
if ( const cTimer * Timer = cMenuEditTimer : : AddedTimer ( ) ) {
// a newly created timer was confirmed with Ok and the proper item needs to be added:
LOCK_TIMERS_READ ;
2018-02-10 12:51:19 +01:00
cMenuTimerItem * CurrentItem = new cMenuTimerItem ( Timer ) ;
Add ( CurrentItem , true ) ;
Sort ( ) ;
SetCurrent ( CurrentItem ) ;
SetHelpKeys ( ) ;
2003-05-25 13:58:21 +02:00
Display ( ) ;
}
2006-02-25 14:39:29 +01:00
if ( Key ! = kNone )
SetHelpKeys ( ) ;
2000-03-11 11:22:37 +01:00
return state ;
}
2000-10-29 13:17:22 +01:00
// --- cMenuEvent ------------------------------------------------------------
2015-09-01 11:14:27 +02:00
cMenuEvent : : cMenuEvent ( const cTimers * Timers , const cChannels * Channels , const cEvent * Event , bool CanSwitch , bool Buttons )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Event " ) )
2000-10-29 13:17:22 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcEvent ) ;
2003-12-22 13:29:24 +01:00
event = Event ;
if ( event ) {
2015-09-01 11:14:27 +02:00
if ( const cChannel * Channel = Channels - > GetByChannelID ( event - > ChannelID ( ) , true ) ) {
SetTitle ( Channel - > Name ( ) ) ;
if ( Buttons ) {
eTimerMatch TimerMatch = tmNone ;
Timers - > GetMatch ( event , & TimerMatch ) ;
2006-02-25 14:39:29 +01:00
SetHelp ( TimerMatch = = tmFull ? tr ( " Button$Timer " ) : tr ( " Button$Record " ) , NULL , NULL , CanSwitch ? tr ( " Button$Switch " ) : NULL ) ;
2015-09-01 11:14:27 +02:00
}
2000-11-01 11:45:05 +01:00
}
2000-10-29 13:17:22 +01:00
}
}
2004-05-16 10:35:36 +02:00
void cMenuEvent : : Display ( void )
{
cOsdMenu : : Display ( ) ;
DisplayMenu ( ) - > SetEvent ( event ) ;
2006-04-09 14:31:33 +02:00
if ( event - > Description ( ) )
cStatus : : MsgOsdTextItem ( event - > Description ( ) ) ;
2004-05-16 10:35:36 +02:00
}
2000-11-01 11:45:05 +01:00
eOSState cMenuEvent : : ProcessKey ( eKeys Key )
2000-10-29 13:17:22 +01:00
{
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2004-05-16 10:35:36 +02:00
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
case kLeft | k_Repeat :
case kLeft :
case kRight | k_Repeat :
case kRight :
DisplayMenu ( ) - > Scroll ( NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft , NORMALKEY ( Key ) = = kLeft | | NORMALKEY ( Key ) = = kRight ) ;
2007-08-12 10:45:43 +02:00
cStatus : : MsgOsdTextItem ( NULL , NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft ) ;
2004-05-16 10:35:36 +02:00
return osContinue ;
2007-11-25 15:27:10 +01:00
case kInfo : return osBack ;
2004-05-16 10:35:36 +02:00
default : break ;
}
2000-11-01 11:45:05 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2000-10-29 13:17:22 +01:00
2000-11-01 11:45:05 +01:00
if ( state = = osUnknown ) {
switch ( Key ) {
2000-11-18 16:31:48 +01:00
case kGreen :
case kYellow : return osContinue ;
2000-11-01 11:45:05 +01:00
case kOk : return osBack ;
default : break ;
}
2000-10-29 13:17:22 +01:00
}
2000-11-01 11:45:05 +01:00
return state ;
2000-10-29 13:17:22 +01:00
}
2005-12-27 11:27:38 +01:00
// --- cMenuScheduleItem -----------------------------------------------------
2000-10-29 13:17:22 +01:00
2005-12-27 11:27:38 +01:00
class cMenuScheduleItem : public cOsdItem {
2006-01-15 13:09:16 +01:00
public :
enum eScheduleSortMode { ssmAllThis , ssmThisThis , ssmThisAll , ssmAllAll } ; // "which event(s) on which channel(s)"
private :
static eScheduleSortMode sortMode ;
2000-10-29 13:17:22 +01:00
public :
2003-12-22 13:29:24 +01:00
const cEvent * event ;
2004-02-21 13:56:20 +01:00
const cChannel * channel ;
2006-01-15 13:09:16 +01:00
bool withDate ;
2012-12-08 11:05:39 +01:00
eTimerMatch timerMatch ;
2017-06-25 10:03:19 +02:00
bool timerActive ;
2015-09-01 11:14:27 +02:00
cMenuScheduleItem ( const cTimers * Timers , const cEvent * Event , const cChannel * Channel = NULL , bool WithDate = false ) ;
2006-01-15 13:09:16 +01:00
static void SetSortMode ( eScheduleSortMode SortMode ) { sortMode = SortMode ; }
static void IncSortMode ( void ) { sortMode = eScheduleSortMode ( ( sortMode = = ssmAllAll ) ? ssmAllThis : sortMode + 1 ) ; }
static eScheduleSortMode SortMode ( void ) { return sortMode ; }
virtual int Compare ( const cListObject & ListObject ) const ;
2015-09-01 11:14:27 +02:00
bool Update ( const cTimers * Timers , bool Force = false ) ;
2012-12-08 11:05:39 +01:00
virtual void SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable ) ;
2006-01-15 13:09:16 +01:00
} ;
cMenuScheduleItem : : eScheduleSortMode cMenuScheduleItem : : sortMode = ssmAllThis ;
2000-10-29 13:17:22 +01:00
2015-09-01 11:14:27 +02:00
cMenuScheduleItem : : cMenuScheduleItem ( const cTimers * Timers , const cEvent * Event , const cChannel * Channel , bool WithDate )
2000-10-29 13:17:22 +01:00
{
2003-12-22 13:29:24 +01:00
event = Event ;
2004-02-21 13:56:20 +01:00
channel = Channel ;
2006-01-15 13:09:16 +01:00
withDate = WithDate ;
2005-12-27 11:27:38 +01:00
timerMatch = tmNone ;
2017-06-25 10:03:19 +02:00
timerActive = false ;
2015-09-01 11:14:27 +02:00
Update ( Timers , true ) ;
2005-12-27 11:27:38 +01:00
}
2006-01-15 13:09:16 +01:00
int cMenuScheduleItem : : Compare ( const cListObject & ListObject ) const
{
cMenuScheduleItem * p = ( cMenuScheduleItem * ) & ListObject ;
int r = - 1 ;
if ( sortMode ! = ssmAllThis )
r = strcoll ( event - > Title ( ) , p - > event - > Title ( ) ) ;
if ( sortMode = = ssmAllThis | | r = = 0 )
r = event - > StartTime ( ) - p - > event - > StartTime ( ) ;
return r ;
}
2017-06-25 10:03:19 +02:00
static const char * TimerMatchChars = " tT iI " ;
2005-12-27 11:27:38 +01:00
2015-09-01 11:14:27 +02:00
bool cMenuScheduleItem : : Update ( const cTimers * Timers , bool Force )
2005-12-27 11:27:38 +01:00
{
2012-12-08 11:05:39 +01:00
eTimerMatch OldTimerMatch = timerMatch ;
2017-06-25 10:03:19 +02:00
bool OldTimerActive = timerActive ;
const cTimer * Timer = Timers - > GetMatch ( event , & timerMatch ) ;
2021-04-17 09:44:01 +02:00
if ( event - > EndTime ( ) < time ( NULL ) & & ! event - > IsRunning ( ) & & ( ! Timer | | ! Timer - > Recording ( ) ) )
2020-12-26 15:49:01 +01:00
timerMatch = tmNone ;
2017-06-25 10:03:19 +02:00
timerActive = Timer & & Timer - > HasFlags ( tfActive ) ;
if ( Force | | timerMatch ! = OldTimerMatch | | timerActive ! = OldTimerActive ) {
2008-02-15 14:57:48 +01:00
cString buffer ;
2017-06-25 10:03:19 +02:00
char t = TimerMatchChars [ timerMatch + ( timerActive ? 0 : 3 ) ] ;
2005-12-27 11:27:38 +01:00
char v = event - > Vps ( ) & & ( event - > Vps ( ) - event - > StartTime ( ) ) ? ' V ' : ' ' ;
2006-06-03 09:42:12 +02:00
char r = event - > SeenWithin ( 30 ) & & event - > IsRunning ( ) ? ' * ' : ' ' ;
2007-06-10 13:02:43 +02:00
const char * csn = channel ? channel - > ShortName ( true ) : NULL ;
2008-01-13 14:05:26 +01:00
cString eds = event - > GetDateString ( ) ;
2006-01-15 13:09:16 +01:00
if ( channel & & withDate )
2012-03-11 13:29:06 +01:00
buffer = cString : : sprintf ( " %d \t %.*s \t %.*s \t %s \t %c%c%c \t %s " , channel - > Number ( ) , Utf8SymChars ( csn , 999 ) , csn , Utf8SymChars ( eds , 6 ) , * eds , * event - > GetTimeString ( ) , t , v , r , event - > Title ( ) ) ;
2006-01-15 13:09:16 +01:00
else if ( channel )
2012-03-11 13:29:06 +01:00
buffer = cString : : sprintf ( " %d \t %.*s \t %s \t %c%c%c \t %s " , channel - > Number ( ) , Utf8SymChars ( csn , 999 ) , csn , * event - > GetTimeString ( ) , t , v , r , event - > Title ( ) ) ;
2005-12-27 11:27:38 +01:00
else
2008-02-15 14:57:48 +01:00
buffer = cString : : sprintf ( " %.*s \t %s \t %c%c%c \t %s " , Utf8SymChars ( eds , 6 ) , * eds , * event - > GetTimeString ( ) , t , v , r , event - > Title ( ) ) ;
SetText ( buffer ) ;
2015-09-01 11:14:27 +02:00
return true ;
2005-12-27 11:27:38 +01:00
}
2015-09-01 11:14:27 +02:00
return false ;
2000-10-29 13:17:22 +01:00
}
2012-12-08 11:05:39 +01:00
void cMenuScheduleItem : : SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable )
{
2017-06-25 10:03:19 +02:00
if ( ! DisplayMenu - > SetItemEvent ( event , Index , Current , Selectable , channel , withDate , timerMatch , timerActive ) )
2012-12-08 11:05:39 +01:00
DisplayMenu - > SetItem ( Text ( ) , Index , Current , Selectable ) ;
}
2000-10-29 13:17:22 +01:00
// --- cMenuWhatsOn ----------------------------------------------------------
class cMenuWhatsOn : public cOsdMenu {
private :
2005-12-27 15:06:26 +01:00
bool now ;
2015-02-03 11:56:51 +01:00
bool canSwitch ;
2005-12-27 15:06:26 +01:00
int helpKeys ;
2015-09-01 11:14:27 +02:00
cStateKey timersStateKey ;
2000-10-29 13:17:22 +01:00
eOSState Record ( void ) ;
eOSState Switch ( void ) ;
2001-02-10 15:37:21 +01:00
static int currentChannel ;
2003-12-22 13:29:24 +01:00
static const cEvent * scheduleEvent ;
2005-12-27 11:27:38 +01:00
bool Update ( void ) ;
2017-06-04 09:35:18 +02:00
void SetHelpKeys ( const cChannels * Channels ) ;
2000-10-29 13:17:22 +01:00
public :
2015-09-01 11:14:27 +02:00
cMenuWhatsOn ( const cTimers * Timers , const cChannels * Channels , const cSchedules * Schedules , bool Now , int CurrentChannelNr ) ;
2001-02-10 15:37:21 +01:00
static int CurrentChannel ( void ) { return currentChannel ; }
static void SetCurrentChannel ( int ChannelNr ) { currentChannel = ChannelNr ; }
2003-12-22 13:29:24 +01:00
static const cEvent * ScheduleEvent ( void ) ;
2000-10-29 13:17:22 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
2001-02-10 15:37:21 +01:00
int cMenuWhatsOn : : currentChannel = 0 ;
2003-12-22 13:29:24 +01:00
const cEvent * cMenuWhatsOn : : scheduleEvent = NULL ;
2000-11-12 16:48:50 +01:00
2015-09-01 11:14:27 +02:00
cMenuWhatsOn : : cMenuWhatsOn ( const cTimers * Timers , const cChannels * Channels , const cSchedules * Schedules , bool Now , int CurrentChannelNr )
2012-03-11 13:29:06 +01:00
: cOsdMenu ( Now ? tr ( " What's on now? " ) : tr ( " What's on next? " ) , CHNUMWIDTH , CHNAMWIDTH , 6 , 4 )
2000-10-29 13:17:22 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( Now ? mcScheduleNow : mcScheduleNext ) ;
2005-12-27 15:06:26 +01:00
now = Now ;
2015-02-03 11:56:51 +01:00
canSwitch = false ;
helpKeys = 0 ;
2015-09-01 11:14:27 +02:00
for ( const cChannel * Channel = Channels - > First ( ) ; Channel ; Channel = Channels - > Next ( Channel ) ) {
2004-02-22 13:43:55 +01:00
if ( ! Channel - > GroupSep ( ) ) {
2015-09-01 11:14:27 +02:00
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( Channel ) ) {
if ( const cEvent * Event = Now ? Schedule - > GetPresentEvent ( ) : Schedule - > GetFollowingEvent ( ) )
Add ( new cMenuScheduleItem ( Timers , Event , Channel ) , Channel - > Number ( ) = = CurrentChannelNr ) ;
2004-02-22 13:43:55 +01:00
}
2004-02-21 13:56:20 +01:00
}
}
2001-02-10 15:37:21 +01:00
currentChannel = CurrentChannelNr ;
2006-04-09 12:03:31 +02:00
Display ( ) ;
2017-06-04 09:35:18 +02:00
SetHelpKeys ( Channels ) ;
2000-10-29 13:17:22 +01:00
}
2005-12-27 11:27:38 +01:00
bool cMenuWhatsOn : : Update ( void )
{
bool result = false ;
2015-09-01 11:14:27 +02:00
if ( const cTimers * Timers = cTimers : : GetTimersRead ( timersStateKey ) ) {
2006-01-15 13:44:55 +01:00
for ( cOsdItem * item = First ( ) ; item ; item = Next ( item ) ) {
2015-09-01 11:14:27 +02:00
if ( ( ( cMenuScheduleItem * ) item ) - > Update ( Timers ) )
2006-01-15 13:44:55 +01:00
result = true ;
}
2015-09-01 11:14:27 +02:00
timersStateKey . Remove ( ) ;
2006-01-15 13:44:55 +01:00
}
2005-12-27 11:27:38 +01:00
return result ;
}
2017-06-04 09:35:18 +02:00
void cMenuWhatsOn : : SetHelpKeys ( const cChannels * Channels )
2005-12-27 15:06:26 +01:00
{
cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
2015-02-03 11:56:51 +01:00
canSwitch = false ;
2005-12-27 15:06:26 +01:00
int NewHelpKeys = 0 ;
if ( item ) {
if ( item - > timerMatch = = tmFull )
2015-02-03 11:56:51 +01:00
NewHelpKeys | = 0x02 ; // "Timer"
2005-12-27 15:06:26 +01:00
else
2015-02-03 11:56:51 +01:00
NewHelpKeys | = 0x01 ; // "Record"
if ( now )
NewHelpKeys | = 0x04 ; // "Next"
else
NewHelpKeys | = 0x08 ; // "Now"
2015-09-01 11:14:27 +02:00
if ( const cChannel * Channel = Channels - > GetByChannelID ( item - > event - > ChannelID ( ) , true ) ) {
2015-02-03 11:56:51 +01:00
if ( Channel - > Number ( ) ! = cDevice : : CurrentChannel ( ) ) {
NewHelpKeys | = 0x10 ; // "Switch"
canSwitch = true ;
}
}
2005-12-27 15:06:26 +01:00
}
if ( NewHelpKeys ! = helpKeys ) {
2006-03-31 13:00:05 +02:00
const char * Red [ ] = { NULL , tr ( " Button$Record " ) , tr ( " Button$Timer " ) } ;
2015-02-03 11:56:51 +01:00
SetHelp ( Red [ NewHelpKeys & 0x03 ] , now ? tr ( " Button$Next " ) : tr ( " Button$Now " ) , tr ( " Button$Schedule " ) , canSwitch ? tr ( " Button$Switch " ) : NULL ) ;
2005-12-27 15:06:26 +01:00
helpKeys = NewHelpKeys ;
}
}
2003-12-22 13:29:24 +01:00
const cEvent * cMenuWhatsOn : : ScheduleEvent ( void )
2000-11-12 16:48:50 +01:00
{
2003-12-22 13:29:24 +01:00
const cEvent * ei = scheduleEvent ;
scheduleEvent = NULL ;
2000-11-12 16:48:50 +01:00
return ei ;
}
2000-10-29 13:17:22 +01:00
eOSState cMenuWhatsOn : : Switch ( void )
{
2005-12-27 11:27:38 +01:00
cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
2000-10-29 13:17:22 +01:00
if ( item ) {
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
const cChannel * Channel = Channels - > GetByChannelID ( item - > event - > ChannelID ( ) , true ) ;
if ( Channel ) {
if ( ! cDevice : : PrimaryDevice ( ) - > SwitchChannel ( Channel , true ) )
Channel = NULL ;
}
if ( Channel )
2000-10-29 13:17:22 +01:00
return osEnd ;
}
2004-05-16 10:35:36 +02:00
Skins . Message ( mtError , tr ( " Can't switch channel! " ) ) ;
2000-10-29 13:17:22 +01:00
return osContinue ;
}
eOSState cMenuWhatsOn : : Record ( void )
{
2015-09-01 11:14:27 +02:00
if ( cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ) {
2017-06-20 15:02:39 +02:00
LOCK_TIMERS_WRITE ;
LOCK_CHANNELS_READ ;
LOCK_SCHEDULES_READ ;
Timers - > SetExplicitModify ( ) ;
if ( item - > timerMatch = = tmFull ) {
if ( cTimer * Timer = Timers - > GetMatch ( item - > event ) )
return AddSubMenu ( new cMenuEditTimer ( Timer ) ) ;
}
cTimer * Timer = new cTimer ( item - > event ) ;
if ( Setup . SVDRPPeering & & * Setup . SVDRPDefaultHost )
Timer - > SetRemote ( Setup . SVDRPDefaultHost ) ;
if ( cTimer * t = Timers - > GetTimer ( Timer ) ) {
delete Timer ;
Timer = t ;
return AddSubMenu ( new cMenuEditTimer ( Timer ) ) ;
}
if ( Timer - > Matches ( 0 , false , NEWTIMERLIMIT ) )
return AddSubMenu ( new cMenuEditTimer ( Timer , true ) ) ;
Timers - > Add ( Timer ) ;
Timers - > SetModified ( ) ;
if ( ! HandleRemoteModifications ( Timer ) ) {
// must add the timer before HandleRemoteModifications to get proper log messages with timer ids
Timers - > Del ( Timer ) ;
}
2018-03-05 15:49:20 +01:00
else if ( Timer - > Remote ( ) )
Timers - > SetSyncStateKey ( StateKeySVDRPRemoteTimersPoll ) ;
2015-09-01 11:14:27 +02:00
if ( HasSubMenu ( ) )
CloseSubMenu ( ) ;
2000-10-29 13:17:22 +01:00
}
2018-04-05 14:18:55 +02:00
if ( Update ( ) ) {
LOCK_SCHEDULES_READ ;
Display ( ) ;
}
LOCK_CHANNELS_READ ;
SetHelpKeys ( Channels ) ;
2000-10-29 13:17:22 +01:00
return osContinue ;
}
eOSState cMenuWhatsOn : : ProcessKey ( eKeys Key )
{
2005-12-27 11:27:38 +01:00
bool HadSubMenu = HasSubMenu ( ) ;
2000-10-29 13:17:22 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2017-05-21 13:18:26 +02:00
switch ( int ( Key ) ) {
2002-10-27 14:32:06 +01:00
case kRecord :
2000-10-29 13:17:22 +01:00
case kRed : return Record ( ) ;
2001-02-10 15:37:21 +01:00
case kYellow : state = osBack ;
// continue with kGreen
case kGreen : {
2005-12-27 11:27:38 +01:00
cMenuScheduleItem * mi = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
2001-02-10 15:37:21 +01:00
if ( mi ) {
2003-12-22 13:29:24 +01:00
scheduleEvent = mi - > event ;
2004-02-21 13:56:20 +01:00
currentChannel = mi - > channel - > Number ( ) ;
2001-02-10 15:37:21 +01:00
}
2000-11-12 16:48:50 +01:00
}
2001-02-10 15:37:21 +01:00
break ;
2015-02-03 11:56:51 +01:00
case kBlue : if ( canSwitch )
return Switch ( ) ;
break ;
2017-05-21 13:18:26 +02:00
case kChanUp | k_Repeat :
case kChanUp :
case kChanDn | k_Repeat :
case kChanDn : if ( ! HasSubMenu ( ) ) {
for ( cOsdItem * item = First ( ) ; item ; item = Next ( item ) ) {
if ( ( ( cMenuScheduleItem * ) item ) - > channel - > Number ( ) = = cDevice : : CurrentChannel ( ) ) {
SetCurrent ( item ) ;
2017-06-21 09:40:39 +02:00
{
LOCK_SCHEDULES_READ ;
Display ( ) ;
}
2017-06-04 09:35:18 +02:00
LOCK_CHANNELS_READ ;
SetHelpKeys ( Channels ) ;
2017-05-21 13:18:26 +02:00
break ;
}
}
}
break ;
2007-11-25 15:27:10 +01:00
case kInfo :
2015-09-01 11:14:27 +02:00
case kOk : if ( Count ( ) ) {
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
return AddSubMenu ( new cMenuEvent ( Timers , Channels , ( ( cMenuScheduleItem * ) Get ( Current ( ) ) ) - > event , canSwitch , true ) ) ;
}
2000-11-01 15:50:00 +01:00
break ;
2000-10-29 13:17:22 +01:00
default : break ;
}
}
2005-12-27 15:06:26 +01:00
else if ( ! HasSubMenu ( ) ) {
2017-06-21 09:40:39 +02:00
if ( HadSubMenu & & Update ( ) ) {
LOCK_SCHEDULES_READ ;
2005-12-27 15:06:26 +01:00
Display ( ) ;
2017-06-21 09:40:39 +02:00
}
2017-06-04 09:35:18 +02:00
if ( Key ! = kNone ) {
LOCK_CHANNELS_READ ;
SetHelpKeys ( Channels ) ;
}
2005-12-27 15:06:26 +01:00
}
2000-10-29 13:17:22 +01:00
return state ;
}
// --- cMenuSchedule ---------------------------------------------------------
class cMenuSchedule : public cOsdMenu {
private :
2015-09-01 11:14:27 +02:00
cStateKey timersStateKey ;
cStateKey schedulesStateKey ;
int scheduleState ;
2000-10-29 13:17:22 +01:00
bool now , next ;
2015-02-03 11:56:51 +01:00
bool canSwitch ;
2005-12-27 15:06:26 +01:00
int helpKeys ;
2017-06-04 09:35:18 +02:00
void Set ( const cTimers * Timers , const cChannels * Channels , const cChannel * Channel = NULL , bool Force = false ) ;
2006-01-15 13:09:16 +01:00
eOSState Number ( void ) ;
2000-10-29 13:17:22 +01:00
eOSState Record ( void ) ;
2000-11-26 16:18:52 +01:00
eOSState Switch ( void ) ;
2015-09-01 11:14:27 +02:00
bool PrepareScheduleAllThis ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel ) ;
bool PrepareScheduleThisThis ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel ) ;
bool PrepareScheduleThisAll ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel ) ;
bool PrepareScheduleAllAll ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel ) ;
2005-12-27 11:27:38 +01:00
bool Update ( void ) ;
2005-12-27 15:06:26 +01:00
void SetHelpKeys ( void ) ;
2000-10-29 13:17:22 +01:00
public :
cMenuSchedule ( void ) ;
2002-04-02 20:59:05 +02:00
virtual ~ cMenuSchedule ( ) ;
2000-10-29 13:17:22 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuSchedule : : cMenuSchedule ( void )
2018-03-09 15:08:45 +01:00
: cOsdMenu ( tr ( " Schedule " ) )
2000-10-29 13:17:22 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcSchedule ) ;
2015-09-01 11:14:27 +02:00
scheduleState = - 1 ;
2000-10-29 13:17:22 +01:00
now = next = false ;
2015-02-03 11:56:51 +01:00
canSwitch = false ;
helpKeys = 0 ;
2006-01-15 13:09:16 +01:00
cMenuScheduleItem : : SetSortMode ( cMenuScheduleItem : : ssmAllThis ) ;
2015-09-01 11:14:27 +02:00
cMenuWhatsOn : : SetCurrentChannel ( cDevice : : CurrentChannel ( ) ) ;
2017-06-04 09:35:18 +02:00
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
Set ( Timers , Channels , NULL , true ) ;
2000-10-29 13:17:22 +01:00
}
2002-04-02 20:59:05 +02:00
cMenuSchedule : : ~ cMenuSchedule ( )
{
2003-12-22 13:29:24 +01:00
cMenuWhatsOn : : ScheduleEvent ( ) ; // makes sure any posted data is cleared
2002-04-02 20:59:05 +02:00
}
2017-06-04 09:35:18 +02:00
void cMenuSchedule : : Set ( const cTimers * Timers , const cChannels * Channels , const cChannel * Channel , bool Force )
2000-10-29 13:17:22 +01:00
{
2015-09-01 11:14:27 +02:00
if ( Force ) {
schedulesStateKey . Reset ( ) ;
scheduleState = - 1 ;
}
if ( const cSchedules * Schedules = cSchedules : : GetSchedulesRead ( schedulesStateKey ) ) {
cMenuScheduleItem * CurrentItem = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
const cEvent * Event = NULL ;
if ( ! Channel ) {
if ( CurrentItem ) {
Event = CurrentItem - > event ;
Channel = Channels - > GetByChannelID ( Event - > ChannelID ( ) , true ) ;
}
else
Channel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) ;
}
bool Refresh = false ;
switch ( cMenuScheduleItem : : SortMode ( ) ) {
case cMenuScheduleItem : : ssmAllThis : Refresh = PrepareScheduleAllThis ( Timers , Schedules , Event , Channel ) ; break ;
case cMenuScheduleItem : : ssmThisThis : Refresh = PrepareScheduleThisThis ( Timers , Schedules , Event , Channel ) ; break ;
case cMenuScheduleItem : : ssmThisAll : Refresh = Force & & PrepareScheduleThisAll ( Timers , Schedules , Event , Channel ) ; break ;
case cMenuScheduleItem : : ssmAllAll : Refresh = Force & & PrepareScheduleAllAll ( Timers , Schedules , Event , Channel ) ; break ;
default : esyslog ( " ERROR: unknown SortMode %d (%s %d) " , cMenuScheduleItem : : SortMode ( ) , __FUNCTION__ , __LINE__ ) ;
}
if ( Refresh ) {
CurrentItem = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
Sort ( ) ;
SetCurrent ( CurrentItem ) ;
SetHelpKeys ( ) ;
Display ( ) ;
}
schedulesStateKey . Remove ( ) ;
}
}
bool cMenuSchedule : : PrepareScheduleAllThis ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel )
{
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( Channel ) ) {
if ( Schedule - > Modified ( scheduleState ) ) {
Clear ( ) ;
SetCols ( 7 , 6 , 4 ) ;
SetTitle ( cString : : sprintf ( tr ( " Schedule - %s " ) , Channel - > Name ( ) ) ) ;
2006-01-29 14:04:37 +01:00
const cEvent * PresentEvent = Event ? Event : Schedule - > GetPresentEvent ( ) ;
2006-01-15 13:09:16 +01:00
time_t now = time ( NULL ) - Setup . EPGLinger * 60 ;
for ( const cEvent * ev = Schedule - > Events ( ) - > First ( ) ; ev ; ev = Schedule - > Events ( ) - > Next ( ev ) ) {
if ( ev - > EndTime ( ) > now | | ev = = PresentEvent )
2015-09-01 11:14:27 +02:00
Add ( new cMenuScheduleItem ( Timers , ev ) , ev = = PresentEvent ) ;
2006-01-15 13:09:16 +01:00
}
2015-09-01 11:14:27 +02:00
return true ;
2006-01-15 13:09:16 +01:00
}
}
2015-09-01 11:14:27 +02:00
return false ;
2006-01-15 13:09:16 +01:00
}
2015-09-01 11:14:27 +02:00
bool cMenuSchedule : : PrepareScheduleThisThis ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel )
2006-01-15 13:09:16 +01:00
{
2015-09-01 11:14:27 +02:00
if ( Event ) {
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( Channel ) ) {
if ( Schedule - > Modified ( scheduleState ) ) {
Clear ( ) ;
SetCols ( 7 , 6 , 4 ) ;
SetTitle ( cString : : sprintf ( tr ( " This event - %s " ) , Channel - > Name ( ) ) ) ;
time_t now = time ( NULL ) - Setup . EPGLinger * 60 ;
for ( const cEvent * ev = Schedule - > Events ( ) - > First ( ) ; ev ; ev = Schedule - > Events ( ) - > Next ( ev ) ) {
if ( ( ev - > EndTime ( ) > now | | ev = = Event ) & & ! strcmp ( ev - > Title ( ) , Event - > Title ( ) ) )
Add ( new cMenuScheduleItem ( Timers , ev ) , ev = = Event ) ;
}
return true ;
}
2000-10-29 13:17:22 +01:00
}
}
2015-09-01 11:14:27 +02:00
return false ;
2000-10-29 13:17:22 +01:00
}
2015-09-01 11:14:27 +02:00
bool cMenuSchedule : : PrepareScheduleThisAll ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel )
2006-01-15 13:09:16 +01:00
{
Clear ( ) ;
2012-03-11 13:29:06 +01:00
SetCols ( CHNUMWIDTH , CHNAMWIDTH , 7 , 6 , 4 ) ;
2006-01-15 13:09:16 +01:00
SetTitle ( tr ( " This event - all channels " ) ) ;
2015-09-01 11:14:27 +02:00
if ( Event ) {
LOCK_CHANNELS_READ ;
for ( const cChannel * ch = Channels - > First ( ) ; ch ; ch = Channels - > Next ( ch ) ) {
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( ch ) ) {
2006-01-15 13:09:16 +01:00
time_t now = time ( NULL ) - Setup . EPGLinger * 60 ;
for ( const cEvent * ev = Schedule - > Events ( ) - > First ( ) ; ev ; ev = Schedule - > Events ( ) - > Next ( ev ) ) {
if ( ( ev - > EndTime ( ) > now | | ev = = Event ) & & ! strcmp ( ev - > Title ( ) , Event - > Title ( ) ) )
2015-09-01 11:14:27 +02:00
Add ( new cMenuScheduleItem ( Timers , ev , ch , true ) , ev = = Event & & ch = = Channel ) ;
2006-01-15 13:09:16 +01:00
}
}
}
}
2015-09-01 11:14:27 +02:00
return true ;
2006-01-15 13:09:16 +01:00
}
2015-09-01 11:14:27 +02:00
bool cMenuSchedule : : PrepareScheduleAllAll ( const cTimers * Timers , const cSchedules * Schedules , const cEvent * Event , const cChannel * Channel )
2006-01-15 13:09:16 +01:00
{
Clear ( ) ;
2012-03-11 13:29:06 +01:00
SetCols ( CHNUMWIDTH , CHNAMWIDTH , 7 , 6 , 4 ) ;
2006-01-15 13:09:16 +01:00
SetTitle ( tr ( " All events - all channels " ) ) ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
cStateKey StateKey ;
for ( const cChannel * ch = Channels - > First ( ) ; ch ; ch = Channels - > Next ( ch ) ) {
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( ch ) ) {
time_t now = time ( NULL ) - Setup . EPGLinger * 60 ;
for ( const cEvent * ev = Schedule - > Events ( ) - > First ( ) ; ev ; ev = Schedule - > Events ( ) - > Next ( ev ) ) {
if ( ev - > EndTime ( ) > now | | ev = = Event )
Add ( new cMenuScheduleItem ( Timers , ev , ch , true ) , ev = = Event & & ch = = Channel ) ;
}
2006-01-15 13:09:16 +01:00
}
2015-09-01 11:14:27 +02:00
}
return true ;
2006-01-15 13:09:16 +01:00
}
2005-12-27 11:27:38 +01:00
bool cMenuSchedule : : Update ( void )
{
bool result = false ;
2015-09-01 11:14:27 +02:00
if ( const cTimers * Timers = cTimers : : GetTimersRead ( timersStateKey ) ) {
2006-01-15 13:44:55 +01:00
for ( cOsdItem * item = First ( ) ; item ; item = Next ( item ) ) {
2015-09-01 11:14:27 +02:00
if ( ( ( cMenuScheduleItem * ) item ) - > Update ( Timers ) )
2006-01-15 13:44:55 +01:00
result = true ;
}
2015-09-01 11:14:27 +02:00
timersStateKey . Remove ( ) ;
2006-01-15 13:44:55 +01:00
}
2005-12-27 11:27:38 +01:00
return result ;
}
2005-12-27 15:06:26 +01:00
void cMenuSchedule : : SetHelpKeys ( void )
{
cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
2015-02-03 11:56:51 +01:00
canSwitch = false ;
2005-12-27 15:06:26 +01:00
int NewHelpKeys = 0 ;
if ( item ) {
if ( item - > timerMatch = = tmFull )
2015-02-03 11:56:51 +01:00
NewHelpKeys | = 0x02 ; // "Timer"
2005-12-27 15:06:26 +01:00
else
2015-02-03 11:56:51 +01:00
NewHelpKeys | = 0x01 ; // "Record"
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
if ( const cChannel * Channel = Channels - > GetByChannelID ( item - > event - > ChannelID ( ) , true ) ) {
2015-02-03 11:56:51 +01:00
if ( Channel - > Number ( ) ! = cDevice : : CurrentChannel ( ) ) {
NewHelpKeys | = 0x10 ; // "Switch"
canSwitch = true ;
}
}
2005-12-27 15:06:26 +01:00
}
if ( NewHelpKeys ! = helpKeys ) {
2006-03-31 13:00:05 +02:00
const char * Red [ ] = { NULL , tr ( " Button$Record " ) , tr ( " Button$Timer " ) } ;
2015-02-03 11:56:51 +01:00
SetHelp ( Red [ NewHelpKeys & 0x03 ] , tr ( " Button$Now " ) , tr ( " Button$Next " ) , canSwitch ? tr ( " Button$Switch " ) : NULL ) ;
2005-12-27 15:06:26 +01:00
helpKeys = NewHelpKeys ;
}
}
2006-01-15 13:09:16 +01:00
eOSState cMenuSchedule : : Number ( void )
{
cMenuScheduleItem : : IncSortMode ( ) ;
2017-06-04 09:35:18 +02:00
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
Set ( Timers , Channels , NULL , true ) ;
2006-01-15 13:09:16 +01:00
return osContinue ;
}
2000-10-29 13:17:22 +01:00
eOSState cMenuSchedule : : Record ( void )
{
2015-09-01 11:14:27 +02:00
if ( cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ) {
2017-06-21 09:40:39 +02:00
LOCK_TIMERS_WRITE ;
LOCK_CHANNELS_READ ;
LOCK_SCHEDULES_READ ;
Timers - > SetExplicitModify ( ) ;
if ( item - > timerMatch = = tmFull ) {
if ( cTimer * Timer = Timers - > GetMatch ( item - > event ) )
return AddSubMenu ( new cMenuEditTimer ( Timer ) ) ;
}
cTimer * Timer = new cTimer ( item - > event ) ;
if ( Setup . SVDRPPeering & & * Setup . SVDRPDefaultHost )
Timer - > SetRemote ( Setup . SVDRPDefaultHost ) ;
if ( cTimer * t = Timers - > GetTimer ( Timer ) ) {
delete Timer ;
Timer = t ;
return AddSubMenu ( new cMenuEditTimer ( Timer ) ) ;
}
if ( Timer - > Matches ( 0 , false , NEWTIMERLIMIT ) )
return AddSubMenu ( new cMenuEditTimer ( Timer , true ) ) ;
Timers - > Add ( Timer ) ;
Timers - > SetModified ( ) ;
if ( ! HandleRemoteModifications ( Timer ) ) {
// must add the timer before HandleRemoteModifications to get proper log messages with timer ids
Timers - > Del ( Timer ) ;
}
2018-03-05 15:49:20 +01:00
else if ( Timer - > Remote ( ) )
Timers - > SetSyncStateKey ( StateKeySVDRPRemoteTimersPoll ) ;
2015-09-01 11:14:27 +02:00
if ( HasSubMenu ( ) )
CloseSubMenu ( ) ;
2000-10-29 13:17:22 +01:00
}
2018-04-05 14:18:55 +02:00
if ( Update ( ) ) {
LOCK_SCHEDULES_READ ;
Display ( ) ;
}
SetHelpKeys ( ) ;
2000-10-29 13:17:22 +01:00
return osContinue ;
}
2000-11-26 16:18:52 +01:00
eOSState cMenuSchedule : : Switch ( void )
{
2015-02-03 10:52:33 +01:00
cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
if ( item ) {
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
const cChannel * Channel = NULL ;
if ( Channel = Channels - > GetByChannelID ( item - > event - > ChannelID ( ) , true ) ) {
if ( ! Channels - > SwitchTo ( Channel - > Number ( ) ) )
Channel = NULL ;
2015-02-03 10:52:33 +01:00
}
2015-09-01 11:14:27 +02:00
if ( Channel )
return osEnd ;
2000-11-26 16:18:52 +01:00
}
2004-05-16 10:35:36 +02:00
Skins . Message ( mtError , tr ( " Can't switch channel! " ) ) ;
2000-11-26 16:18:52 +01:00
return osContinue ;
}
2000-10-29 13:17:22 +01:00
eOSState cMenuSchedule : : ProcessKey ( eKeys Key )
{
2017-06-04 09:35:18 +02:00
if ( ! HasSubMenu ( ) ) {
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
Set ( Timers , Channels ) ; // react on any changes to the schedules list
}
2005-12-27 11:27:38 +01:00
bool HadSubMenu = HasSubMenu ( ) ;
2000-10-29 13:17:22 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2017-05-21 13:18:26 +02:00
switch ( int ( Key ) ) {
2006-01-15 13:09:16 +01:00
case k0 : return Number ( ) ;
2002-10-27 14:32:06 +01:00
case kRecord :
2000-10-29 13:17:22 +01:00
case kRed : return Record ( ) ;
2015-09-01 11:14:27 +02:00
case kGreen : {
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
LOCK_SCHEDULES_READ ;
if ( ! now & & ! next ) {
int ChannelNr = 0 ;
if ( Count ( ) ) {
if ( const cChannel * Channel = Channels - > GetByChannelID ( ( ( cMenuScheduleItem * ) Get ( Current ( ) ) ) - > event - > ChannelID ( ) , true ) )
ChannelNr = Channel - > Number ( ) ;
}
now = true ;
return AddSubMenu ( new cMenuWhatsOn ( Timers , Channels , Schedules , now , ChannelNr ) ) ;
}
now = ! now ;
next = ! next ;
return AddSubMenu ( new cMenuWhatsOn ( Timers , Channels , Schedules , now , cMenuWhatsOn : : CurrentChannel ( ) ) ) ;
}
case kYellow : {
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
LOCK_SCHEDULES_READ ;
return AddSubMenu ( new cMenuWhatsOn ( Timers , Channels , Schedules , false , cMenuWhatsOn : : CurrentChannel ( ) ) ) ;
}
2015-02-03 11:56:51 +01:00
case kBlue : if ( canSwitch )
2001-03-18 10:16:56 +01:00
return Switch ( ) ;
break ;
2017-05-21 13:18:26 +02:00
case kChanUp | k_Repeat :
case kChanUp :
case kChanDn | k_Repeat :
case kChanDn : if ( ! HasSubMenu ( ) ) {
2017-06-04 09:35:18 +02:00
LOCK_TIMERS_READ ;
2017-05-21 13:18:26 +02:00
LOCK_CHANNELS_READ ;
if ( const cChannel * Channel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) )
2017-06-04 09:35:18 +02:00
Set ( Timers , Channels , Channel , true ) ;
2017-05-21 13:18:26 +02:00
}
break ;
2007-11-25 15:27:10 +01:00
case kInfo :
2015-09-01 11:14:27 +02:00
case kOk : if ( Count ( ) ) {
LOCK_TIMERS_READ ;
LOCK_CHANNELS_READ ;
LOCK_SCHEDULES_READ ;
return AddSubMenu ( new cMenuEvent ( Timers , Channels , ( ( cMenuScheduleItem * ) Get ( Current ( ) ) ) - > event , canSwitch , true ) ) ;
}
2000-11-01 15:50:00 +01:00
break ;
2000-10-29 13:17:22 +01:00
default : break ;
}
}
2000-11-12 16:48:50 +01:00
else if ( ! HasSubMenu ( ) ) {
2000-11-01 11:45:05 +01:00
now = next = false ;
2015-09-01 11:14:27 +02:00
if ( const cEvent * ei = cMenuWhatsOn : : ScheduleEvent ( ) ) {
2017-06-04 09:35:18 +02:00
LOCK_TIMERS_READ ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
if ( const cChannel * Channel = Channels - > GetByChannelID ( ei - > ChannelID ( ) , true ) ) {
2006-01-15 13:09:16 +01:00
cMenuScheduleItem : : SetSortMode ( cMenuScheduleItem : : ssmAllThis ) ;
2017-06-04 09:35:18 +02:00
Set ( Timers , Channels , Channel , true ) ;
2000-11-12 16:48:50 +01:00
}
}
2017-06-21 09:40:39 +02:00
else if ( HadSubMenu & & Update ( ) ) {
LOCK_SCHEDULES_READ ;
2005-12-27 11:27:38 +01:00
Display ( ) ;
2017-06-21 09:40:39 +02:00
}
2005-12-27 15:06:26 +01:00
if ( Key ! = kNone )
SetHelpKeys ( ) ;
2000-11-12 16:48:50 +01:00
}
2000-10-29 13:17:22 +01:00
return state ;
}
2002-10-13 12:14:49 +02:00
// --- cMenuCommands ---------------------------------------------------------
2010-01-31 12:59:50 +01:00
cMenuCommands : : cMenuCommands ( const char * Title , cList < cNestedItem > * Commands , const char * Parameters )
2002-10-13 12:14:49 +02:00
: cOsdMenu ( Title )
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcCommand ) ;
2010-01-31 12:59:50 +01:00
result = NULL ;
2002-10-13 12:14:49 +02:00
SetHasHotkeys ( ) ;
commands = Commands ;
2010-01-31 12:59:50 +01:00
parameters = Parameters ;
for ( cNestedItem * Command = commands - > First ( ) ; Command ; Command = commands - > Next ( Command ) ) {
const char * s = Command - > Text ( ) ;
if ( Command - > SubItems ( ) )
Add ( new cOsdItem ( hk ( cString : : sprintf ( " %s... " , s ) ) ) ) ;
else if ( Parse ( s ) )
Add ( new cOsdItem ( hk ( title ) ) ) ;
}
2002-10-13 12:14:49 +02:00
}
cMenuCommands : : ~ cMenuCommands ( )
{
2010-01-31 12:59:50 +01:00
free ( result ) ;
}
bool cMenuCommands : : Parse ( const char * s )
{
const char * p = strchr ( s , ' : ' ) ;
if ( p ) {
int l = p - s ;
if ( l > 0 ) {
char t [ l + 1 ] ;
stripspace ( strn0cpy ( t , s , l + 1 ) ) ;
l = strlen ( t ) ;
if ( l > 1 & & t [ l - 1 ] = = ' ? ' ) {
t [ l - 1 ] = 0 ;
confirm = true ;
}
else
confirm = false ;
title = t ;
command = skipspace ( p + 1 ) ;
return true ;
}
}
return false ;
2002-10-13 12:14:49 +02:00
}
eOSState cMenuCommands : : Execute ( void )
{
2010-01-31 12:59:50 +01:00
cNestedItem * Command = commands - > Get ( Current ( ) ) ;
if ( Command ) {
if ( Command - > SubItems ( ) )
return AddSubMenu ( new cMenuCommands ( Title ( ) , Command - > SubItems ( ) , parameters ) ) ;
if ( Parse ( Command - > Text ( ) ) ) {
if ( ! confirm | | Interface - > Confirm ( cString : : sprintf ( " %s? " , * title ) ) ) {
Skins . Message ( mtStatus , cString : : sprintf ( " %s... " , * title ) ) ;
free ( result ) ;
result = NULL ;
cString cmdbuf ;
if ( ! isempty ( parameters ) )
cmdbuf = cString : : sprintf ( " %s %s " , * command , * parameters ) ;
const char * cmd = * cmdbuf ? * cmdbuf : * command ;
dsyslog ( " executing command '%s' " , cmd ) ;
cPipe p ;
if ( p . Open ( cmd , " r " ) ) {
int l = 0 ;
int c ;
while ( ( c = fgetc ( p ) ) ! = EOF ) {
2011-02-25 15:25:42 +01:00
if ( l % 20 = = 0 ) {
if ( char * NewBuffer = ( char * ) realloc ( result , l + 21 ) )
result = NewBuffer ;
else {
esyslog ( " ERROR: out of memory " ) ;
break ;
}
}
2010-01-31 12:59:50 +01:00
result [ l + + ] = char ( c ) ;
}
if ( result )
result [ l ] = 0 ;
p . Close ( ) ;
}
else
esyslog ( " ERROR: can't open pipe for command '%s' " , cmd ) ;
Skins . Message ( mtStatus , NULL ) ;
if ( result )
return AddSubMenu ( new cMenuText ( title , result , fontFix ) ) ;
return osEnd ;
}
2002-10-13 12:14:49 +02:00
}
}
return osContinue ;
}
eOSState cMenuCommands : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
2005-05-16 14:45:11 +02:00
case kRed :
case kGreen :
case kYellow :
case kBlue : return osContinue ;
case kOk : return Execute ( ) ;
default : break ;
2002-10-13 12:14:49 +02:00
}
}
return state ;
}
2003-01-06 14:44:27 +01:00
// --- cMenuCam --------------------------------------------------------------
2012-06-13 11:35:16 +02:00
static bool CamMenuIsOpen = false ;
2007-01-07 14:46:14 +01:00
class cMenuCam : public cOsdMenu {
private :
cCamSlot * camSlot ;
cCiMenu * ciMenu ;
cCiEnquiry * ciEnquiry ;
char * input ;
int offset ;
time_t lastCamExchange ;
void GenerateTitle ( const char * s = NULL ) ;
void QueryCam ( void ) ;
void AddMultiLineItem ( const char * s ) ;
void Set ( void ) ;
eOSState Select ( void ) ;
public :
cMenuCam ( cCamSlot * CamSlot ) ;
virtual ~ cMenuCam ( ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuCam : : cMenuCam ( cCamSlot * CamSlot )
: cOsdMenu ( " " , 1 ) // tab necessary for enquiry!
2003-01-06 14:44:27 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcCam ) ;
2007-01-07 14:46:14 +01:00
camSlot = CamSlot ;
ciMenu = NULL ;
ciEnquiry = NULL ;
input = NULL ;
2005-10-02 09:59:30 +02:00
offset = 0 ;
2007-01-07 14:46:14 +01:00
lastCamExchange = time ( NULL ) ;
SetNeedsFastResponse ( true ) ;
QueryCam ( ) ;
2012-06-13 11:35:16 +02:00
CamMenuIsOpen = true ;
2003-01-06 14:44:27 +01:00
}
cMenuCam : : ~ cMenuCam ( )
{
2007-01-07 14:46:14 +01:00
if ( ciMenu )
2005-10-02 13:54:34 +02:00
ciMenu - > Abort ( ) ;
2003-01-06 14:44:27 +01:00
delete ciMenu ;
2007-01-07 14:46:14 +01:00
if ( ciEnquiry )
ciEnquiry - > Abort ( ) ;
delete ciEnquiry ;
free ( input ) ;
2012-06-13 11:35:16 +02:00
CamMenuIsOpen = false ;
2007-01-07 14:46:14 +01:00
}
void cMenuCam : : GenerateTitle ( const char * s )
{
SetTitle ( cString : : sprintf ( " CAM %d - %s " , camSlot - > SlotNumber ( ) , ( s & & * s ) ? s : camSlot - > GetCamName ( ) ) ) ;
}
void cMenuCam : : QueryCam ( void )
{
delete ciMenu ;
ciMenu = NULL ;
delete ciEnquiry ;
ciEnquiry = NULL ;
if ( camSlot - > HasUserIO ( ) ) {
ciMenu = camSlot - > GetMenu ( ) ;
ciEnquiry = camSlot - > GetEnquiry ( ) ;
}
Set ( ) ;
}
void cMenuCam : : Set ( void )
{
if ( ciMenu ) {
Clear ( ) ;
free ( input ) ;
input = NULL ;
dsyslog ( " CAM %d: Menu ------------------ " , camSlot - > SlotNumber ( ) ) ;
offset = 0 ;
SetHasHotkeys ( ciMenu - > Selectable ( ) ) ;
GenerateTitle ( ciMenu - > TitleText ( ) ) ;
dsyslog ( " CAM %d: '%s' " , camSlot - > SlotNumber ( ) , ciMenu - > TitleText ( ) ) ;
2017-05-17 09:17:44 +02:00
if ( ! isempty ( ciMenu - > SubTitleText ( ) ) ) {
2007-01-07 14:46:14 +01:00
dsyslog ( " CAM %d: '%s' " , camSlot - > SlotNumber ( ) , ciMenu - > SubTitleText ( ) ) ;
AddMultiLineItem ( ciMenu - > SubTitleText ( ) ) ;
offset = Count ( ) ;
}
for ( int i = 0 ; i < ciMenu - > NumEntries ( ) ; i + + ) {
Add ( new cOsdItem ( hk ( ciMenu - > Entry ( i ) ) , osUnknown , ciMenu - > Selectable ( ) ) ) ;
dsyslog ( " CAM %d: '%s' " , camSlot - > SlotNumber ( ) , ciMenu - > Entry ( i ) ) ;
}
2017-05-17 09:17:44 +02:00
if ( ! isempty ( ciMenu - > BottomText ( ) ) ) {
2007-01-07 14:46:14 +01:00
AddMultiLineItem ( ciMenu - > BottomText ( ) ) ;
dsyslog ( " CAM %d: '%s' " , camSlot - > SlotNumber ( ) , ciMenu - > BottomText ( ) ) ;
}
2008-02-23 14:40:58 +01:00
cRemote : : TriggerLastActivity ( ) ;
2007-01-07 14:46:14 +01:00
}
else if ( ciEnquiry ) {
Clear ( ) ;
int Length = ciEnquiry - > ExpectedLength ( ) ;
free ( input ) ;
input = MALLOC ( char , Length + 1 ) ;
* input = 0 ;
2017-06-10 11:52:47 +02:00
dsyslog ( " CAM %d: Enquiry ------------------ " , camSlot - > SlotNumber ( ) ) ;
2007-01-07 14:46:14 +01:00
GenerateTitle ( ) ;
Add ( new cOsdItem ( ciEnquiry - > Text ( ) , osUnknown , false ) ) ;
2017-06-10 11:52:47 +02:00
dsyslog ( " CAM %d: '%s' " , camSlot - > SlotNumber ( ) , ciEnquiry - > Text ( ) ) ;
2007-01-07 14:46:14 +01:00
Add ( new cOsdItem ( " " , osUnknown , false ) ) ;
Add ( new cMenuEditNumItem ( " " , input , Length , ciEnquiry - > Blind ( ) ) ) ;
}
Display ( ) ;
2003-01-06 14:44:27 +01:00
}
2005-10-03 11:26:07 +02:00
void cMenuCam : : AddMultiLineItem ( const char * s )
{
while ( s & & * s ) {
const char * p = strchr ( s , ' \n ' ) ;
int l = p ? p - s : strlen ( s ) ;
cOsdItem * item = new cOsdItem ;
item - > SetSelectable ( false ) ;
item - > SetText ( strndup ( s , l ) , false ) ;
Add ( item ) ;
s = p ? p + 1 : p ;
}
}
2003-01-06 14:44:27 +01:00
eOSState cMenuCam : : Select ( void )
{
2007-01-07 14:46:14 +01:00
if ( ciMenu ) {
if ( ciMenu - > Selectable ( ) ) {
ciMenu - > Select ( Current ( ) - offset ) ;
dsyslog ( " CAM %d: select %d " , camSlot - > SlotNumber ( ) , Current ( ) - offset ) ;
}
else
ciMenu - > Cancel ( ) ;
2005-10-02 13:54:34 +02:00
}
2007-01-07 14:46:14 +01:00
else if ( ciEnquiry ) {
if ( ciEnquiry - > ExpectedLength ( ) < 0xFF & & int ( strlen ( input ) ) ! = ciEnquiry - > ExpectedLength ( ) ) {
char buffer [ 64 ] ;
snprintf ( buffer , sizeof ( buffer ) , tr ( " Please enter %d digits! " ) , ciEnquiry - > ExpectedLength ( ) ) ;
Skins . Message ( mtError , buffer ) ;
return osContinue ;
}
ciEnquiry - > Reply ( input ) ;
dsyslog ( " CAM %d: entered '%s' " , camSlot - > SlotNumber ( ) , ciEnquiry - > Blind ( ) ? " **** " : input ) ;
2005-10-02 12:59:53 +02:00
}
2007-01-07 14:46:14 +01:00
QueryCam ( ) ;
return osContinue ;
2003-01-06 14:44:27 +01:00
}
2007-01-07 14:46:14 +01:00
eOSState cMenuCam : : ProcessKey ( eKeys Key )
2003-01-06 14:44:27 +01:00
{
2007-01-07 14:46:14 +01:00
if ( ! camSlot - > HasMMI ( ) )
return osBack ;
2003-01-06 14:44:27 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2007-01-07 14:46:14 +01:00
if ( ciMenu | | ciEnquiry ) {
lastCamExchange = time ( NULL ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
case kOk : return Select ( ) ;
default : break ;
}
}
else if ( state = = osBack ) {
if ( ciMenu )
ciMenu - > Cancel ( ) ;
if ( ciEnquiry )
ciEnquiry - > Cancel ( ) ;
QueryCam ( ) ;
return osContinue ;
}
if ( ciMenu & & ciMenu - > HasUpdate ( ) ) {
QueryCam ( ) ;
return osContinue ;
}
2003-01-06 14:44:27 +01:00
}
2007-01-07 14:46:14 +01:00
else if ( time ( NULL ) - lastCamExchange < CAMRESPONSETIMEOUT )
QueryCam ( ) ;
else {
Skins . Message ( mtError , tr ( " CAM not responding! " ) ) ;
return osBack ;
2005-10-03 12:58:22 +02:00
}
2003-01-06 14:44:27 +01:00
return state ;
}
// --- CamControl ------------------------------------------------------------
cOsdObject * CamControl ( void )
{
2007-01-07 14:46:14 +01:00
for ( cCamSlot * CamSlot = CamSlots . First ( ) ; CamSlot ; CamSlot = CamSlots . Next ( CamSlot ) ) {
if ( CamSlot - > HasUserIO ( ) )
return new cMenuCam ( CamSlot ) ;
2003-01-06 14:44:27 +01:00
}
return NULL ;
}
2012-06-13 11:35:16 +02:00
bool CamMenuActive ( void )
{
return CamMenuIsOpen ;
}
2013-10-10 13:13:30 +02:00
// --- cMenuPathEdit ---------------------------------------------------------
2017-12-14 10:45:02 +01:00
# define osUserRecRenamed osUser1
# define osUserRecMoved osUser2
# define osUserRecRemoved osUser3
# define osUserRecEmpty osUser4
2013-10-10 13:13:30 +02:00
class cMenuPathEdit : public cOsdMenu {
private :
cString path ;
2017-12-14 10:45:02 +01:00
cString oldFolder ;
2013-10-10 13:13:30 +02:00
char folder [ PATH_MAX ] ;
char name [ NAME_MAX ] ;
cMenuEditStrItem * folderItem ;
int pathIsInUse ;
eOSState SetFolder ( void ) ;
eOSState Folder ( void ) ;
eOSState ApplyChanges ( void ) ;
public :
cMenuPathEdit ( const char * Path ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuPathEdit : : cMenuPathEdit ( const char * Path )
: cOsdMenu ( tr ( " Edit path " ) , 12 )
{
2013-11-03 14:10:59 +01:00
SetMenuCategory ( mcRecordingEdit ) ;
2013-10-10 13:13:30 +02:00
path = Path ;
* folder = 0 ;
* name = 0 ;
const char * s = strrchr ( path , FOLDERDELIMCHAR ) ;
if ( s ) {
strn0cpy ( folder , cString ( path , s ) , sizeof ( folder ) ) ;
s + + ;
}
else
s = path ;
strn0cpy ( name , s , sizeof ( name ) ) ;
2015-09-01 11:14:27 +02:00
{
LOCK_RECORDINGS_READ ;
pathIsInUse = Recordings - > PathIsInUse ( path ) ;
}
2017-12-14 10:45:02 +01:00
oldFolder = folder ;
2013-10-10 13:13:30 +02:00
cOsdItem * p ;
Add ( p = folderItem = new cMenuEditStrItem ( tr ( " Folder " ) , folder , sizeof ( folder ) ) ) ;
p - > SetSelectable ( ! pathIsInUse ) ;
Add ( p = new cMenuEditStrItem ( tr ( " Name " ) , name , sizeof ( name ) ) ) ;
p - > SetSelectable ( ! pathIsInUse ) ;
2021-05-21 10:41:46 +02:00
if ( * path ) {
int DirSize = 0 ;
{
LOCK_RECORDINGS_READ ;
for ( const cRecording * Recording = Recordings - > First ( ) ; Recording ; Recording = Recordings - > Next ( Recording ) ) {
if ( Recording - > IsInPath ( path ) ) {
int FileSizeMB = Recording - > FileSizeMB ( ) ;
if ( FileSizeMB > 0 )
DirSize + = FileSizeMB ;
}
}
}
if ( DirSize > 1023 )
Add ( new cOsdItem ( cString : : sprintf ( " %s: \t %.2f GB " , tr ( " Size " ) , DirSize / 1024. ) , osUnknown , false ) ) ;
else
Add ( new cOsdItem ( cString : : sprintf ( " %s: \t %d MB " , tr ( " Size " ) , DirSize ) , osUnknown , false ) ) ;
}
2013-10-14 09:59:04 +02:00
if ( pathIsInUse ) {
Add ( new cOsdItem ( " " , osUnknown , false ) ) ;
Add ( new cOsdItem ( tr ( " This folder is currently in use - no changes are possible! " ) , osUnknown , false ) ) ;
}
2013-10-10 13:13:30 +02:00
Display ( ) ;
if ( ! pathIsInUse )
SetHelp ( tr ( " Button$Folder " ) ) ;
}
eOSState cMenuPathEdit : : SetFolder ( void )
{
if ( cMenuFolder * mf = dynamic_cast < cMenuFolder * > ( SubMenu ( ) ) ) {
strn0cpy ( folder , mf - > GetFolder ( ) , sizeof ( folder ) ) ;
SetCurrent ( folderItem ) ;
Display ( ) ;
}
return CloseSubMenu ( ) ;
}
eOSState cMenuPathEdit : : Folder ( void )
{
return AddSubMenu ( new cMenuFolder ( tr ( " Select folder " ) , & Folders , path ) ) ;
}
eOSState cMenuPathEdit : : ApplyChanges ( void )
{
2015-02-07 15:53:30 +01:00
if ( ! * name ) {
2013-10-10 13:13:30 +02:00
* name = ' ' ; // name must not be empty!
2015-02-07 15:53:30 +01:00
name [ 1 ] = 0 ;
}
2013-10-10 13:13:30 +02:00
cString NewPath = * folder ? cString : : sprintf ( " %s%c%s " , folder , FOLDERDELIMCHAR , name ) : name ;
NewPath . CompactChars ( FOLDERDELIMCHAR ) ;
if ( strcmp ( NewPath , path ) ) {
2017-12-05 16:44:21 +01:00
int NumRecordings = 0 ;
{
LOCK_RECORDINGS_READ ;
NumRecordings = Recordings - > GetNumRecordingsInPath ( path ) ;
}
2013-10-10 13:13:30 +02:00
if ( NumRecordings > 1 & & ! Interface - > Confirm ( cString : : sprintf ( tr ( " Move entire folder containing %d recordings? " ) , NumRecordings ) ) )
return osContinue ;
2018-01-17 10:27:37 +01:00
bool Error = false ;
{
LOCK_RECORDINGS_WRITE ;
Recordings - > SetExplicitModify ( ) ;
Error = ! Recordings - > MoveRecordings ( path , NewPath ) ;
if ( ! Error )
Recordings - > SetModified ( ) ;
}
if ( Error ) {
2013-10-10 13:13:30 +02:00
Skins . Message ( mtError , tr ( " Error while moving folder! " ) ) ;
return osContinue ;
}
2017-12-14 10:45:02 +01:00
if ( strcmp ( folder , oldFolder ) )
return osUserRecMoved ;
return osUserRecRenamed ;
2013-10-10 13:13:30 +02:00
}
return osBack ;
}
eOSState cMenuPathEdit : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
if ( ! pathIsInUse ) {
switch ( Key ) {
case kRed : return Folder ( ) ;
case kOk : return ApplyChanges ( ) ;
default : break ;
}
}
else if ( Key = = kOk )
return osBack ;
}
else if ( state = = osEnd & & HasSubMenu ( ) )
state = SetFolder ( ) ;
return state ;
}
// --- cMenuRecordingEdit ----------------------------------------------------
class cMenuRecordingEdit : public cOsdMenu {
private :
2015-09-01 11:14:27 +02:00
const cRecording * recording ;
2013-10-14 09:59:04 +02:00
cString originalFileName ;
2015-09-01 11:14:27 +02:00
cStateKey recordingsStateKey ;
2013-10-10 13:13:30 +02:00
char folder [ PATH_MAX ] ;
char name [ NAME_MAX ] ;
int priority ;
int lifetime ;
cMenuEditStrItem * folderItem ;
2015-02-04 09:38:55 +01:00
cMenuEditStrItem * nameItem ;
2013-10-10 13:13:30 +02:00
const char * buttonFolder ;
const char * buttonAction ;
const char * buttonDeleteMarks ;
const char * actionCancel ;
const char * doCut ;
int recordingIsInUse ;
void Set ( void ) ;
void SetHelpKeys ( void ) ;
2013-10-14 09:59:04 +02:00
bool RefreshRecording ( void ) ;
2013-10-10 13:13:30 +02:00
eOSState SetFolder ( void ) ;
eOSState Folder ( void ) ;
eOSState Action ( void ) ;
2015-02-04 09:38:55 +01:00
eOSState RemoveName ( void ) ;
2013-10-10 13:13:30 +02:00
eOSState DeleteMarks ( void ) ;
eOSState ApplyChanges ( void ) ;
public :
2015-09-01 11:14:27 +02:00
cMenuRecordingEdit ( const cRecording * Recording ) ;
2013-10-10 13:13:30 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
2015-09-01 11:14:27 +02:00
cMenuRecordingEdit : : cMenuRecordingEdit ( const cRecording * Recording )
2013-10-10 13:13:30 +02:00
: cOsdMenu ( tr ( " Edit recording " ) , 12 )
{
2013-11-03 14:10:59 +01:00
SetMenuCategory ( mcRecordingEdit ) ;
2013-10-10 13:13:30 +02:00
recording = Recording ;
2013-10-14 09:59:04 +02:00
originalFileName = recording - > FileName ( ) ;
2013-10-10 13:13:30 +02:00
strn0cpy ( folder , recording - > Folder ( ) , sizeof ( folder ) ) ;
strn0cpy ( name , recording - > BaseName ( ) , sizeof ( name ) ) ;
priority = recording - > Priority ( ) ;
lifetime = recording - > Lifetime ( ) ;
folderItem = NULL ;
2015-02-04 09:38:55 +01:00
nameItem = NULL ;
2013-10-10 13:13:30 +02:00
buttonFolder = NULL ;
buttonAction = NULL ;
buttonDeleteMarks = NULL ;
actionCancel = NULL ;
doCut = NULL ;
2013-10-14 09:59:04 +02:00
recordingIsInUse = ruNone ;
2013-10-10 13:13:30 +02:00
Set ( ) ;
}
void cMenuRecordingEdit : : Set ( void )
{
2013-10-14 09:59:04 +02:00
int current = Current ( ) ;
2013-10-10 13:13:30 +02:00
Clear ( ) ;
2013-10-14 09:59:04 +02:00
recordingIsInUse = recording - > IsInUse ( ) ;
2013-10-10 13:13:30 +02:00
cOsdItem * p ;
Add ( p = folderItem = new cMenuEditStrItem ( tr ( " Folder " ) , folder , sizeof ( folder ) ) ) ;
p - > SetSelectable ( ! recordingIsInUse ) ;
2015-02-04 09:38:55 +01:00
Add ( p = nameItem = new cMenuEditStrItem ( tr ( " Name " ) , name , sizeof ( name ) ) ) ;
2013-10-10 13:13:30 +02:00
p - > SetSelectable ( ! recordingIsInUse ) ;
Add ( p = new cMenuEditIntItem ( tr ( " Priority " ) , & priority , 0 , MAXPRIORITY ) ) ;
p - > SetSelectable ( ! recordingIsInUse ) ;
Add ( p = new cMenuEditIntItem ( tr ( " Lifetime " ) , & lifetime , 0 , MAXLIFETIME ) ) ;
p - > SetSelectable ( ! recordingIsInUse ) ;
2013-10-14 09:59:04 +02:00
if ( recordingIsInUse ) {
Add ( new cOsdItem ( " " , osUnknown , false ) ) ;
Add ( new cOsdItem ( tr ( " This recording is currently in use - no changes are possible! " ) , osUnknown , false ) ) ;
}
SetCurrent ( Get ( current ) ) ;
2013-10-10 13:13:30 +02:00
Display ( ) ;
SetHelpKeys ( ) ;
}
void cMenuRecordingEdit : : SetHelpKeys ( void )
{
buttonFolder = ! recordingIsInUse ? tr ( " Button$Folder " ) : NULL ;
buttonAction = NULL ;
buttonDeleteMarks = NULL ;
actionCancel = NULL ;
doCut = NULL ;
if ( ( recordingIsInUse & ruCut ) ! = 0 )
2013-10-14 09:59:04 +02:00
buttonAction = actionCancel = ( ( recordingIsInUse & ruPending ) ! = 0 ) ? tr ( " Button$Cancel cutting " ) : tr ( " Button$Stop cutting " ) ;
2013-10-10 13:13:30 +02:00
else if ( ( recordingIsInUse & ruMove ) ! = 0 )
2013-10-14 09:59:04 +02:00
buttonAction = actionCancel = ( ( recordingIsInUse & ruPending ) ! = 0 ) ? tr ( " Button$Cancel moving " ) : tr ( " Button$Stop moving " ) ;
2013-10-10 13:13:30 +02:00
else if ( ( recordingIsInUse & ruCopy ) ! = 0 )
2013-10-14 09:59:04 +02:00
buttonAction = actionCancel = ( ( recordingIsInUse & ruPending ) ! = 0 ) ? tr ( " Button$Cancel copying " ) : tr ( " Button$Stop copying " ) ;
2013-10-10 13:13:30 +02:00
else if ( recording - > HasMarks ( ) ) {
buttonAction = doCut = tr ( " Button$Cut " ) ;
buttonDeleteMarks = tr ( " Button$Delete marks " ) ;
}
SetHelp ( buttonFolder , buttonAction , buttonDeleteMarks ) ;
}
2013-10-14 09:59:04 +02:00
bool cMenuRecordingEdit : : RefreshRecording ( void )
{
2015-09-01 11:14:27 +02:00
if ( const cRecordings * Recordings = cRecordings : : GetRecordingsRead ( recordingsStateKey ) ) {
if ( ( recording = Recordings - > GetByName ( originalFileName ) ) ! = NULL )
2013-10-14 09:59:04 +02:00
Set ( ) ;
else {
2015-09-01 11:14:27 +02:00
recordingsStateKey . Remove ( ) ;
2013-10-14 09:59:04 +02:00
Skins . Message ( mtWarning , tr ( " Recording vanished! " ) ) ;
return false ;
}
2015-09-01 11:14:27 +02:00
recordingsStateKey . Remove ( ) ;
2013-10-14 09:59:04 +02:00
}
return true ;
}
2013-10-10 13:13:30 +02:00
eOSState cMenuRecordingEdit : : SetFolder ( void )
{
if ( cMenuFolder * mf = dynamic_cast < cMenuFolder * > ( SubMenu ( ) ) ) {
strn0cpy ( folder , mf - > GetFolder ( ) , sizeof ( folder ) ) ;
SetCurrent ( folderItem ) ;
Display ( ) ;
}
return CloseSubMenu ( ) ;
}
eOSState cMenuRecordingEdit : : Folder ( void )
{
return AddSubMenu ( new cMenuFolder ( tr ( " Select folder " ) , & Folders , recording - > Name ( ) ) ) ;
}
eOSState cMenuRecordingEdit : : Action ( void )
{
if ( actionCancel )
RecordingsHandler . Del ( recording - > FileName ( ) ) ;
else if ( doCut ) {
2013-10-21 08:23:19 +02:00
if ( access ( cCutter : : EditedFileName ( recording - > FileName ( ) ) , F_OK ) ! = 0 | | Interface - > Confirm ( tr ( " Edited version already exists - overwrite? " ) ) ) {
if ( ! RecordingsHandler . Add ( ruCut , recording - > FileName ( ) ) )
Skins . Message ( mtError , tr ( " Error while queueing recording for cutting! " ) ) ;
}
2013-10-10 13:13:30 +02:00
}
recordingIsInUse = recording - > IsInUse ( ) ;
2013-10-14 09:59:04 +02:00
RefreshRecording ( ) ;
2013-10-10 13:13:30 +02:00
SetHelpKeys ( ) ;
return osContinue ;
}
2015-02-04 09:38:55 +01:00
eOSState cMenuRecordingEdit : : RemoveName ( void )
{
if ( Get ( Current ( ) ) = = nameItem ) {
2015-02-07 16:01:13 +01:00
if ( Interface - > Confirm ( tr ( " Rename recording to folder name? " ) ) ) {
char * s = strrchr ( folder , FOLDERDELIMCHAR ) ;
if ( s )
* s + + = 0 ;
else
s = folder ;
strn0cpy ( name , s , sizeof ( name ) ) ;
if ( s = = folder )
* s = 0 ;
Set ( ) ;
}
2015-02-04 09:38:55 +01:00
}
return osContinue ;
}
2013-10-10 13:13:30 +02:00
eOSState cMenuRecordingEdit : : DeleteMarks ( void )
{
if ( buttonDeleteMarks & & Interface - > Confirm ( tr ( " Delete editing marks for this recording? " ) ) ) {
2018-01-29 14:09:59 +01:00
if ( cMarks : : DeleteMarksFile ( recording ) ) {
2013-10-10 13:13:30 +02:00
SetHelpKeys ( ) ;
2020-05-18 16:47:29 +02:00
cMutexLock ControlMutexLock ;
if ( cControl * Control = cControl : : Control ( ControlMutexLock , true ) ) {
2018-01-29 14:09:59 +01:00
if ( const cRecording * Recording = Control - > GetRecording ( ) ) {
if ( strcmp ( recording - > FileName ( ) , Recording - > FileName ( ) ) = = 0 )
2018-02-01 16:08:15 +01:00
Control - > ClearEditingMarks ( ) ;
2018-01-29 14:09:59 +01:00
}
}
}
2013-10-10 13:13:30 +02:00
else
Skins . Message ( mtError , tr ( " Error while deleting editing marks! " ) ) ;
}
return osContinue ;
}
eOSState cMenuRecordingEdit : : ApplyChanges ( void )
{
2015-09-01 11:14:27 +02:00
cStateKey StateKey ;
cRecordings * Recordings = cRecordings : : GetRecordingsWrite ( StateKey ) ;
cRecording * Recording = Recordings - > GetByName ( recording - > FileName ( ) ) ;
if ( ! Recording ) {
2016-12-13 13:54:00 +01:00
StateKey . Remove ( false ) ;
2015-09-01 11:14:27 +02:00
Skins . Message ( mtWarning , tr ( " Recording vanished! " ) ) ;
return osBack ;
}
2013-10-10 13:13:30 +02:00
bool Modified = false ;
if ( priority ! = recording - > Priority ( ) | | lifetime ! = recording - > Lifetime ( ) ) {
2015-09-01 11:14:27 +02:00
if ( ! Recording - > ChangePriorityLifetime ( priority , lifetime ) ) {
StateKey . Remove ( Modified ) ;
2016-12-13 13:54:00 +01:00
Skins . Message ( mtError , tr ( " Error while changing priority/lifetime! " ) ) ;
2013-10-10 13:13:30 +02:00
return osContinue ;
}
Modified = true ;
}
2015-02-07 15:53:30 +01:00
if ( ! * name ) {
2013-10-10 13:13:30 +02:00
* name = ' ' ; // name must not be empty!
2015-02-07 15:53:30 +01:00
name [ 1 ] = 0 ;
}
2017-12-14 10:45:02 +01:00
cString OldFolder = Recording - > Folder ( ) ;
2013-10-10 13:13:30 +02:00
cString NewName = * folder ? cString : : sprintf ( " %s%c%s " , folder , FOLDERDELIMCHAR , name ) : name ;
NewName . CompactChars ( FOLDERDELIMCHAR ) ;
2015-09-01 11:14:27 +02:00
if ( strcmp ( NewName , Recording - > Name ( ) ) ) {
if ( ! Recording - > ChangeName ( NewName ) ) {
StateKey . Remove ( Modified ) ;
2016-12-13 13:54:00 +01:00
Skins . Message ( mtError , tr ( " Error while changing folder/name! " ) ) ;
2013-10-10 13:13:30 +02:00
return osContinue ;
}
Modified = true ;
}
if ( Modified ) {
2017-12-14 10:45:02 +01:00
eOSState state = osUserRecRenamed ;
if ( strcmp ( Recording - > Folder ( ) , OldFolder ) )
state = osUserRecMoved ;
2015-09-01 11:14:27 +02:00
Recordings - > TouchUpdate ( ) ;
StateKey . Remove ( Modified ) ;
2017-12-14 10:45:02 +01:00
return state ;
2013-10-10 13:13:30 +02:00
}
2015-09-01 11:14:27 +02:00
StateKey . Remove ( Modified ) ;
2013-10-10 13:13:30 +02:00
return osBack ;
}
eOSState cMenuRecordingEdit : : ProcessKey ( eKeys Key )
{
2013-10-14 09:59:04 +02:00
if ( ! HasSubMenu ( ) ) {
if ( ! RefreshRecording ( ) )
return osBack ; // the recording has vanished, so close this menu
}
2013-10-10 13:13:30 +02:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2013-10-14 10:28:10 +02:00
switch ( Key ) {
2015-02-04 09:38:55 +01:00
case k0 : return RemoveName ( ) ;
2013-10-14 10:28:10 +02:00
case kRed : return buttonFolder ? Folder ( ) : osContinue ;
case kGreen : return buttonAction ? Action ( ) : osContinue ;
case kYellow : return buttonDeleteMarks ? DeleteMarks ( ) : osContinue ;
case kOk : return ! recordingIsInUse ? ApplyChanges ( ) : osBack ;
default : break ;
}
2013-10-10 13:13:30 +02:00
}
else if ( state = = osEnd & & HasSubMenu ( ) )
state = SetFolder ( ) ;
return state ;
}
2005-05-16 14:45:11 +02:00
// --- cMenuRecording --------------------------------------------------------
class cMenuRecording : public cOsdMenu {
private :
2015-09-01 11:14:27 +02:00
const cRecording * recording ;
2013-10-14 09:59:04 +02:00
cString originalFileName ;
2015-09-01 11:14:27 +02:00
cStateKey recordingsStateKey ;
2006-01-15 15:06:19 +01:00
bool withButtons ;
2013-10-14 09:59:04 +02:00
bool RefreshRecording ( void ) ;
2005-05-16 14:45:11 +02:00
public :
2015-09-01 11:14:27 +02:00
cMenuRecording ( const cRecording * Recording , bool WithButtons = false ) ;
2005-05-16 14:45:11 +02:00
virtual void Display ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
2015-09-01 11:14:27 +02:00
cMenuRecording : : cMenuRecording ( const cRecording * Recording , bool WithButtons )
2005-08-14 12:06:40 +02:00
: cOsdMenu ( tr ( " Recording info " ) )
2005-05-16 14:45:11 +02:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcRecordingInfo ) ;
2020-11-03 22:12:38 +01:00
if ( cRecordings : : GetRecordingsRead ( recordingsStateKey ) ) // initializes recordingsStateKey, so we don't call Display() unnecessarily
recordingsStateKey . Remove ( ) ;
2005-05-16 14:45:11 +02:00
recording = Recording ;
2013-10-14 09:59:04 +02:00
originalFileName = recording - > FileName ( ) ;
2006-01-15 15:06:19 +01:00
withButtons = WithButtons ;
if ( withButtons )
2013-10-10 13:13:30 +02:00
SetHelp ( tr ( " Button$Play " ) , tr ( " Button$Rewind " ) , NULL , tr ( " Button$Edit " ) ) ;
2005-05-16 14:45:11 +02:00
}
2013-10-14 09:59:04 +02:00
bool cMenuRecording : : RefreshRecording ( void )
{
2015-09-01 11:14:27 +02:00
if ( const cRecordings * Recordings = cRecordings : : GetRecordingsRead ( recordingsStateKey ) ) {
if ( ( recording = Recordings - > GetByName ( originalFileName ) ) ! = NULL )
2013-10-14 09:59:04 +02:00
Display ( ) ;
else {
2015-09-01 11:14:27 +02:00
recordingsStateKey . Remove ( ) ;
2013-10-14 09:59:04 +02:00
Skins . Message ( mtWarning , tr ( " Recording vanished! " ) ) ;
return false ;
}
2015-09-01 11:14:27 +02:00
recordingsStateKey . Remove ( ) ;
2013-10-14 09:59:04 +02:00
}
return true ;
}
2005-05-16 14:45:11 +02:00
void cMenuRecording : : Display ( void )
{
2013-10-14 09:59:04 +02:00
if ( HasSubMenu ( ) ) {
SubMenu ( ) - > Display ( ) ;
return ;
}
2005-05-16 14:45:11 +02:00
cOsdMenu : : Display ( ) ;
DisplayMenu ( ) - > SetRecording ( recording ) ;
2006-04-09 14:31:33 +02:00
if ( recording - > Info ( ) - > Description ( ) )
cStatus : : MsgOsdTextItem ( recording - > Info ( ) - > Description ( ) ) ;
2005-05-16 14:45:11 +02:00
}
eOSState cMenuRecording : : ProcessKey ( eKeys Key )
{
2014-01-25 12:44:32 +01:00
if ( HasSubMenu ( ) )
return cOsdMenu : : ProcessKey ( Key ) ;
2013-10-14 09:59:04 +02:00
else if ( ! RefreshRecording ( ) )
return osBack ; // the recording has vanished, so close this menu
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2005-05-16 14:45:11 +02:00
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
case kLeft | k_Repeat :
case kLeft :
case kRight | k_Repeat :
case kRight :
DisplayMenu ( ) - > Scroll ( NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft , NORMALKEY ( Key ) = = kLeft | | NORMALKEY ( Key ) = = kRight ) ;
2007-08-12 10:45:43 +02:00
cStatus : : MsgOsdTextItem ( NULL , NORMALKEY ( Key ) = = kUp | | NORMALKEY ( Key ) = = kLeft ) ;
2005-05-16 14:45:11 +02:00
return osContinue ;
2007-11-25 15:27:10 +01:00
case kInfo : return osBack ;
2005-05-16 14:45:11 +02:00
default : break ;
}
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
2006-01-15 15:06:19 +01:00
case kRed : if ( withButtons )
Key = kOk ; // will play the recording, even if recording commands are defined
case kGreen : if ( ! withButtons )
break ;
cRemote : : Put ( Key , true ) ;
2005-05-16 14:45:11 +02:00
// continue with osBack to close the info menu and process the key
case kOk : return osBack ;
2013-10-10 13:13:30 +02:00
case kBlue : if ( withButtons )
return AddSubMenu ( new cMenuRecordingEdit ( recording ) ) ;
break ;
2005-05-16 14:45:11 +02:00
default : break ;
}
}
return state ;
}
2000-03-11 11:22:37 +01:00
// --- cMenuRecordingItem ----------------------------------------------------
class cMenuRecordingItem : public cOsdItem {
2002-01-20 14:05:28 +01:00
private :
2015-09-01 11:14:27 +02:00
const cRecording * recording ;
2012-12-08 11:05:39 +01:00
int level ;
2002-01-20 14:05:28 +01:00
char * name ;
int totalEntries , newEntries ;
2000-03-11 11:22:37 +01:00
public :
2015-09-01 11:14:27 +02:00
cMenuRecordingItem ( const cRecording * Recording , int Level ) ;
2002-01-20 14:05:28 +01:00
~ cMenuRecordingItem ( ) ;
void IncrementCounter ( bool New ) ;
2017-12-04 14:55:13 +01:00
const char * Name ( void ) const { return name ; }
int Level ( void ) const { return level ; }
const cRecording * Recording ( void ) const { return recording ; }
bool IsDirectory ( void ) const { return name ! = NULL ; }
2015-09-01 11:14:27 +02:00
void SetRecording ( const cRecording * Recording ) { recording = Recording ; }
2012-12-08 11:05:39 +01:00
virtual void SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable ) ;
2000-03-11 11:22:37 +01:00
} ;
2015-09-01 11:14:27 +02:00
cMenuRecordingItem : : cMenuRecordingItem ( const cRecording * Recording , int Level )
2000-03-11 11:22:37 +01:00
{
2012-12-08 11:05:39 +01:00
recording = Recording ;
level = Level ;
2002-01-20 14:05:28 +01:00
name = NULL ;
totalEntries = newEntries = 0 ;
SetText ( Recording - > Title ( ' \t ' , true , Level ) ) ;
2017-12-10 13:04:38 +01:00
if ( * Text ( ) = = ' \t ' ) // this is a folder
2002-01-20 14:05:28 +01:00
name = strdup ( Text ( ) + 2 ) ; // 'Text() + 2' to skip the two '\t'
2017-12-10 13:04:38 +01:00
else { // this is an actual recording
int Usage = Recording - > IsInUse ( ) ;
if ( ( Usage & ruDst ) ! = 0 & & ( Usage & ( ruMove | ruCopy ) ) ! = 0 )
SetSelectable ( false ) ;
}
2002-01-20 14:05:28 +01:00
}
cMenuRecordingItem : : ~ cMenuRecordingItem ( )
{
2002-08-11 13:32:23 +02:00
free ( name ) ;
2000-03-11 11:22:37 +01:00
}
2002-01-20 14:05:28 +01:00
void cMenuRecordingItem : : IncrementCounter ( bool New )
2000-03-11 11:22:37 +01:00
{
2002-01-20 14:05:28 +01:00
totalEntries + + ;
if ( New )
newEntries + + ;
2011-08-27 11:14:54 +02:00
SetText ( cString : : sprintf ( " %d \t \t %d \t %s " , totalEntries , newEntries , name ) ) ;
2000-03-11 11:22:37 +01:00
}
2012-12-08 11:05:39 +01:00
void cMenuRecordingItem : : SetMenuItem ( cSkinDisplayMenu * DisplayMenu , int Index , bool Current , bool Selectable )
{
if ( ! DisplayMenu - > SetItemRecording ( recording , Index , Current , Selectable , level , totalEntries , newEntries ) )
DisplayMenu - > SetItem ( Text ( ) , Index , Current , Selectable ) ;
}
2000-03-11 11:22:37 +01:00
// --- cMenuRecordings -------------------------------------------------------
2013-10-10 13:13:30 +02:00
cString cMenuRecordings : : path ;
cString cMenuRecordings : : fileName ;
2013-12-25 12:13:00 +01:00
cMenuRecordings : : cMenuRecordings ( const char * Base , int Level , bool OpenSubMenus , const cRecordingFilter * Filter )
2011-08-27 11:14:54 +02:00
: cOsdMenu ( Base ? Base : tr ( " Recordings " ) , 9 , 6 , 6 )
2002-01-20 14:05:28 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcRecording ) ;
2002-01-20 14:05:28 +01:00
base = Base ? strdup ( Base ) : NULL ;
level = Setup . RecordingDirs ? Level : - 1 ;
2013-12-25 12:13:00 +01:00
filter = Filter ;
2005-11-06 09:44:58 +01:00
helpKeys = - 1 ;
2003-05-11 12:21:58 +02:00
Display ( ) ; // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay
2005-09-25 11:00:57 +02:00
Set ( ) ;
2004-06-13 20:26:51 +02:00
if ( Current ( ) < 0 )
SetCurrent ( First ( ) ) ;
2013-10-10 13:13:30 +02:00
else if ( OpenSubMenus & & ( cReplayControl : : LastReplayed ( ) | | * path | | * fileName ) ) {
if ( ! * path | | Level < strcountchr ( path , FOLDERDELIMCHAR ) ) {
if ( Open ( true ) )
return ;
}
}
2005-10-01 10:11:33 +02:00
Display ( ) ;
2002-01-20 14:05:28 +01:00
SetHelpKeys ( ) ;
}
cMenuRecordings : : ~ cMenuRecordings ( )
2000-03-11 11:22:37 +01:00
{
2014-03-09 15:15:48 +01:00
if ( cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ) {
if ( ! ri - > IsDirectory ( ) )
SetRecording ( ri - > Recording ( ) - > FileName ( ) ) ;
}
2002-08-11 13:32:23 +02:00
free ( base ) ;
2002-01-20 14:05:28 +01:00
}
void cMenuRecordings : : SetHelpKeys ( void )
{
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
2005-11-06 09:44:58 +01:00
int NewHelpKeys = 0 ;
2002-01-20 14:05:28 +01:00
if ( ri ) {
if ( ri - > IsDirectory ( ) )
NewHelpKeys = 1 ;
2013-10-10 13:13:30 +02:00
else
2002-01-20 14:05:28 +01:00
NewHelpKeys = 2 ;
2000-03-11 11:22:37 +01:00
}
2002-01-20 14:05:28 +01:00
if ( NewHelpKeys ! = helpKeys ) {
switch ( NewHelpKeys ) {
case 0 : SetHelp ( NULL ) ; break ;
2013-10-10 13:13:30 +02:00
case 1 : SetHelp ( tr ( " Button$Open " ) , NULL , NULL , tr ( " Button$Edit " ) ) ; break ;
case 2 : SetHelp ( RecordingCommands . Count ( ) ? tr ( " Commands " ) : tr ( " Button$Play " ) , tr ( " Button$Rewind " ) , tr ( " Button$Delete " ) , tr ( " Button$Info " ) ) ;
2009-12-06 12:57:45 +01:00
default : ;
2002-01-20 14:05:28 +01:00
}
helpKeys = NewHelpKeys ;
}
}
2005-09-25 11:00:57 +02:00
void cMenuRecordings : : Set ( bool Refresh )
{
2015-09-01 11:14:27 +02:00
if ( cRecordings : : GetRecordingsRead ( recordingsStateKey ) ) {
recordingsStateKey . Remove ( ) ;
cRecordings * Recordings = cRecordings : : GetRecordingsWrite ( recordingsStateKey ) ; // write access is necessary for sorting!
2018-02-10 12:34:10 +01:00
const char * CurrentRecording = NULL ;
if ( cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) )
CurrentRecording = ri - > Recording ( ) - > FileName ( ) ;
if ( ! CurrentRecording )
CurrentRecording = * fileName ? * fileName : cReplayControl : : LastReplayed ( ) ;
2016-12-09 15:00:55 +01:00
int current = Current ( ) ;
2015-09-01 11:14:27 +02:00
Clear ( ) ;
GetRecordingsSortMode ( DirectoryName ( ) ) ;
Recordings - > Sort ( ) ;
2018-03-24 11:58:00 +01:00
cMenuRecordingItem * CurrentItem = NULL ;
2018-02-10 12:34:10 +01:00
cMenuRecordingItem * LastItem = NULL ;
2015-09-01 11:14:27 +02:00
for ( const cRecording * Recording = Recordings - > First ( ) ; Recording ; Recording = Recordings - > Next ( Recording ) ) {
if ( ( ! filter | | filter - > Filter ( Recording ) ) & & ( ! base | | ( strstr ( Recording - > Name ( ) , base ) = = Recording - > Name ( ) & & Recording - > Name ( ) [ strlen ( base ) ] = = FOLDERDELIMCHAR ) ) ) {
cMenuRecordingItem * Item = new cMenuRecordingItem ( Recording , level ) ;
cMenuRecordingItem * LastDir = NULL ;
if ( Item - > IsDirectory ( ) ) {
// Sorting may ignore non-alphanumeric characters, so we need to explicitly handle directories in case they only differ in such characters:
for ( cMenuRecordingItem * p = LastItem ; p ; p = dynamic_cast < cMenuRecordingItem * > ( p - > Prev ( ) ) ) {
if ( p - > Name ( ) & & strcmp ( p - > Name ( ) , Item - > Name ( ) ) = = 0 ) {
LastDir = p ;
break ;
}
2013-01-16 16:08:20 +01:00
}
2015-09-01 11:14:27 +02:00
}
if ( * Item - > Text ( ) & & ! LastDir ) {
Add ( Item ) ;
LastItem = Item ;
if ( Item - > IsDirectory ( ) )
LastDir = Item ;
}
else
delete Item ;
if ( LastItem | | LastDir ) {
if ( * path ) {
if ( strcmp ( path , Recording - > Folder ( ) ) = = 0 )
2018-03-24 11:58:00 +01:00
CurrentItem = LastDir ? LastDir : LastItem ;
2015-09-01 11:14:27 +02:00
}
else if ( CurrentRecording & & strcmp ( CurrentRecording , Recording - > FileName ( ) ) = = 0 )
2018-03-24 11:58:00 +01:00
CurrentItem = LastDir ? LastDir : LastItem ;
2013-10-10 13:13:30 +02:00
}
2015-09-01 11:14:27 +02:00
if ( LastDir )
LastDir - > IncrementCounter ( Recording - > IsNew ( ) ) ;
2005-09-25 11:00:57 +02:00
}
}
2018-03-24 11:58:00 +01:00
SetCurrent ( CurrentItem ) ;
2016-12-09 15:00:55 +01:00
if ( Current ( ) < 0 )
SetCurrent ( Get ( current ) ) ; // last resort, in case the recording was deleted
2015-09-01 11:14:27 +02:00
SetMenuSortMode ( RecordingsSortMode = = rsmName ? msmName : msmTime ) ;
recordingsStateKey . Remove ( false ) ; // sorting doesn't count as a real modification
2016-12-09 15:00:55 +01:00
if ( Refresh )
Display ( ) ;
2015-09-01 11:14:27 +02:00
}
2005-09-25 11:00:57 +02:00
}
2013-10-10 13:13:30 +02:00
void cMenuRecordings : : SetPath ( const char * Path )
{
path = Path ;
}
void cMenuRecordings : : SetRecording ( const char * FileName )
{
fileName = FileName ;
}
2012-06-09 14:32:29 +02:00
cString cMenuRecordings : : DirectoryName ( void )
{
2013-09-11 12:20:37 +02:00
cString d ( cVideoDirectory : : Name ( ) ) ;
2012-06-09 14:32:29 +02:00
if ( base ) {
char * s = ExchangeChars ( strdup ( base ) , true ) ;
d = AddDirectory ( d , s ) ;
free ( s ) ;
}
return d ;
}
2002-01-20 14:05:28 +01:00
bool cMenuRecordings : : Open ( bool OpenSubMenus )
{
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
2013-10-10 13:13:30 +02:00
if ( ri & & ri - > IsDirectory ( ) & & ( ! * path | | strcountchr ( path , FOLDERDELIMCHAR ) > 0 ) ) {
2002-01-20 14:05:28 +01:00
const char * t = ri - > Name ( ) ;
2008-02-15 14:57:48 +01:00
cString buffer ;
2002-01-20 14:05:28 +01:00
if ( base ) {
2013-10-10 13:13:30 +02:00
buffer = cString : : sprintf ( " %s%c%s " , base , FOLDERDELIMCHAR , t ) ;
2002-01-20 14:05:28 +01:00
t = buffer ;
}
2013-12-27 09:00:24 +01:00
AddSubMenu ( new cMenuRecordings ( t , level + 1 , OpenSubMenus , filter ) ) ;
2002-01-20 14:05:28 +01:00
return true ;
}
return false ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuRecordings : : Play ( void )
{
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri ) {
2002-01-20 14:05:28 +01:00
if ( ri - > IsDirectory ( ) )
Open ( ) ;
else {
2012-12-08 11:05:39 +01:00
cReplayControl : : SetRecording ( ri - > Recording ( ) - > FileName ( ) ) ;
return osReplay ;
2002-01-20 14:05:28 +01:00
}
2000-03-11 11:22:37 +01:00
}
return osContinue ;
}
2001-02-11 11:04:41 +01:00
eOSState cMenuRecordings : : Rewind ( void )
{
2002-10-13 12:14:49 +02:00
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
2001-02-11 11:04:41 +01:00
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
2002-01-20 14:05:28 +01:00
if ( ri & & ! ri - > IsDirectory ( ) ) {
2012-12-08 11:05:39 +01:00
cDevice : : PrimaryDevice ( ) - > StopReplay ( ) ; // must do this first to be able to rewind the currently replayed recording
cResumeFile ResumeFile ( ri - > Recording ( ) - > FileName ( ) , ri - > Recording ( ) - > IsPesRecording ( ) ) ;
ResumeFile . Delete ( ) ;
return Play ( ) ;
2001-02-11 11:04:41 +01:00
}
return osContinue ;
}
2018-02-13 09:33:41 +01:00
static bool TimerStillRecording ( const char * FileName )
2000-03-11 11:22:37 +01:00
{
2018-02-13 09:33:41 +01:00
if ( cRecordControl * rc = cRecordControls : : GetRecordControl ( FileName ) ) {
// local timer
if ( Interface - > Confirm ( tr ( " Timer still recording - really delete? " ) ) ) {
LOCK_TIMERS_WRITE ;
if ( cTimer * Timer = rc - > Timer ( ) ) {
Timer - > Skip ( ) ;
cRecordControls : : Process ( Timers , time ( NULL ) ) ;
if ( Timer - > IsSingleEvent ( ) ) {
Timers - > Del ( Timer ) ;
isyslog ( " deleted timer %s " , * Timer - > ToDescr ( ) ) ;
}
}
}
else
return true ; // user didn't confirm deletion
}
else {
// remote timer
cString TimerId = GetRecordingTimerId ( FileName ) ;
if ( * TimerId ) {
int Id ;
char * RemoteBuf = NULL ;
cString Remote ;
if ( 2 = = sscanf ( TimerId , " %d@%m[^ \n ] " , & Id , & RemoteBuf ) ) {
Remote = RemoteBuf ;
free ( RemoteBuf ) ;
2002-02-17 14:29:13 +01:00
if ( Interface - > Confirm ( tr ( " Timer still recording - really delete? " ) ) ) {
2018-02-13 09:33:41 +01:00
LOCK_TIMERS_WRITE ;
if ( cTimer * Timer = Timers - > GetById ( Id , Remote ) ) {
2018-03-03 12:55:57 +01:00
cTimer OldTimer = * Timer ;
2015-09-01 11:14:27 +02:00
Timer - > Skip ( ) ;
2018-03-05 15:49:20 +01:00
Timers - > SetSyncStateKey ( StateKeySVDRPRemoteTimersPoll ) ;
2015-09-01 11:14:27 +02:00
if ( Timer - > IsSingleEvent ( ) ) {
2018-02-13 09:33:41 +01:00
if ( HandleRemoteModifications ( NULL , Timer ) )
Timers - > Del ( Timer ) ;
else
return true ; // error while deleting remote timer
2003-05-29 11:39:29 +02:00
}
2018-03-03 12:55:57 +01:00
else if ( ! HandleRemoteModifications ( Timer , & OldTimer ) )
2018-02-13 09:33:41 +01:00
return true ; // error while modifying remote timer
2002-01-20 14:05:28 +01:00
}
2000-03-11 11:22:37 +01:00
}
2002-02-17 14:29:13 +01:00
else
2018-02-13 09:33:41 +01:00
return true ; // user didn't confirm deletion
2000-03-11 11:22:37 +01:00
}
2018-02-13 09:33:41 +01:00
}
}
return false ;
}
eOSState cMenuRecordings : : Delete ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri & & ! ri - > IsDirectory ( ) ) {
if ( Interface - > Confirm ( tr ( " Delete recording? " ) ) ) {
if ( TimerStillRecording ( ri - > Recording ( ) - > FileName ( ) ) )
return osContinue ;
2016-12-11 13:06:58 +01:00
cString FileName ;
{
LOCK_RECORDINGS_READ ;
if ( const cRecording * Recording = Recordings - > GetByName ( ri - > Recording ( ) - > FileName ( ) ) ) {
FileName = Recording - > FileName ( ) ;
if ( RecordingsHandler . GetUsage ( FileName ) ) {
2016-12-13 13:54:00 +01:00
if ( ! Interface - > Confirm ( tr ( " Recording is being edited - really delete? " ) ) )
2016-12-11 13:06:58 +01:00
return osContinue ;
}
}
}
2016-12-13 13:54:00 +01:00
RecordingsHandler . Del ( FileName ) ; // must do this w/o holding a lock, because the cleanup section in cDirCopier::Action() might request one!
2012-12-08 11:05:39 +01:00
if ( cReplayControl : : NowReplaying ( ) & & strcmp ( cReplayControl : : NowReplaying ( ) , FileName ) = = 0 )
cControl : : Shutdown ( ) ;
2016-12-11 13:06:58 +01:00
cRecordings * Recordings = cRecordings : : GetRecordingsWrite ( recordingsStateKey ) ;
Recordings - > SetExplicitModify ( ) ;
cRecording * Recording = Recordings - > GetByName ( FileName ) ;
2015-09-01 11:14:27 +02:00
if ( ! Recording | | Recording - > Delete ( ) ) {
2012-12-08 11:05:39 +01:00
cReplayControl : : ClearLastReplayed ( FileName ) ;
2015-09-01 11:14:27 +02:00
Recordings - > DelByName ( FileName ) ;
2012-12-08 11:05:39 +01:00
cOsdMenu : : Del ( Current ( ) ) ;
SetHelpKeys ( ) ;
cVideoDiskUsage : : ForceCheck ( ) ;
2015-09-01 11:14:27 +02:00
Recordings - > SetModified ( ) ;
recordingsStateKey . Remove ( ) ;
2015-09-16 11:11:42 +02:00
Display ( ) ;
2012-12-08 11:05:39 +01:00
if ( ! Count ( ) )
2017-12-14 10:45:02 +01:00
return osUserRecEmpty ;
return osUserRecRemoved ;
2012-12-08 11:05:39 +01:00
}
else
Skins . Message ( mtError , tr ( " Error while deleting recording! " ) ) ;
2015-09-13 10:39:02 +02:00
recordingsStateKey . Remove ( ) ;
2002-02-17 14:29:13 +01:00
}
2000-03-11 11:22:37 +01:00
}
return osContinue ;
}
2005-05-16 14:45:11 +02:00
eOSState cMenuRecordings : : Info ( void )
2000-07-24 16:43:04 +02:00
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
2013-10-10 13:13:30 +02:00
if ( cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ) {
if ( ri - > IsDirectory ( ) )
return AddSubMenu ( new cMenuPathEdit ( cString ( ri - > Recording ( ) - > Name ( ) , strchrn ( ri - > Recording ( ) - > Name ( ) , FOLDERDELIMCHAR , ri - > Level ( ) + 1 ) ) ) ) ;
else
return AddSubMenu ( new cMenuRecording ( ri - > Recording ( ) , true ) ) ;
}
2000-07-24 16:43:04 +02:00
return osContinue ;
}
2002-10-13 12:14:49 +02:00
eOSState cMenuRecordings : : Commands ( eKeys Key )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri & & ! ri - > IsDirectory ( ) ) {
2012-12-08 11:05:39 +01:00
cMenuCommands * menu ;
eOSState state = AddSubMenu ( menu = new cMenuCommands ( tr ( " Recording commands " ) , & RecordingCommands , cString : : sprintf ( " \" %s \" " , * strescape ( ri - > Recording ( ) - > FileName ( ) , " \\ \" $ " ) ) ) ) ;
if ( Key ! = kNone )
state = menu - > ProcessKey ( Key ) ;
return state ;
2002-10-13 12:14:49 +02:00
}
return osContinue ;
}
2012-06-09 14:32:29 +02:00
eOSState cMenuRecordings : : Sort ( void )
{
if ( HasSubMenu ( ) )
return osContinue ;
2017-12-04 14:55:13 +01:00
if ( const cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) )
SetRecording ( ri - > Recording ( ) - > FileName ( ) ) ; // makes sure the Recordings menu will reposition to the current recording
2012-06-09 14:32:29 +02:00
IncRecordingsSortMode ( DirectoryName ( ) ) ;
2015-09-10 13:29:30 +02:00
recordingsStateKey . Reset ( ) ;
2012-06-09 14:32:29 +02:00
Set ( true ) ;
return osContinue ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuRecordings : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
2012-12-04 13:37:59 +01:00
case kPlayPause :
2007-10-19 14:22:03 +02:00
case kPlay :
2002-10-13 12:14:49 +02:00
case kOk : return Play ( ) ;
case kRed : return ( helpKeys > 1 & & RecordingCommands . Count ( ) ) ? Commands ( ) : Play ( ) ;
2001-02-11 11:04:41 +01:00
case kGreen : return Rewind ( ) ;
2002-10-06 10:40:27 +02:00
case kYellow : return Delete ( ) ;
2007-11-25 15:27:10 +01:00
case kInfo :
2005-05-16 14:45:11 +02:00
case kBlue : return Info ( ) ;
2012-06-09 14:32:29 +02:00
case k0 : return Sort ( ) ;
2002-10-13 12:14:49 +02:00
case k1 . . . k9 : return Commands ( Key ) ;
2000-03-11 11:22:37 +01:00
default : break ;
}
}
2017-12-14 10:45:02 +01:00
else if ( state = = osUserRecRenamed ) {
// a recording was renamed (within the same folder), so let's refresh the menu
CloseSubMenu ( false ) ; // this is the cMenuRecordingEdit/cMenuPathEdit
2013-10-10 13:13:30 +02:00
path = NULL ;
fileName = NULL ;
2017-12-14 10:45:02 +01:00
state = osContinue ;
2013-10-10 13:13:30 +02:00
}
2017-12-14 10:45:02 +01:00
else if ( state = = osUserRecMoved ) {
// a recording was moved to a different folder, so let's delete the old item
CloseSubMenu ( false ) ; // this is the cMenuRecordingEdit/cMenuPathEdit
path = NULL ;
fileName = NULL ;
cOsdMenu : : Del ( Current ( ) ) ;
Set ( ) ; // the recording might have been moved into a new subfolder of this folder
if ( ! Count ( ) )
return osUserRecEmpty ;
Display ( ) ;
state = osUserRecRemoved ;
}
else if ( state = = osUserRecRemoved ) {
// a recording was removed from a sub folder, so update the current item
if ( cOsdMenu * m = SubMenu ( ) ) {
if ( cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ) {
if ( cMenuRecordingItem * riSub = ( cMenuRecordingItem * ) m - > Get ( m - > Current ( ) ) )
ri - > SetRecording ( riSub - > Recording ( ) ) ;
}
2014-02-26 11:39:06 +01:00
}
2017-12-14 10:45:02 +01:00
// no state change here, this report goes upstream!
}
else if ( state = = osUserRecEmpty ) {
// a subfolder became empty, so let's go back up
CloseSubMenu ( false ) ; // this is the now empty submenu
cOsdMenu : : Del ( Current ( ) ) ; // the menu entry of the now empty subfolder
Set ( ) ; // in case a recording was moved into a new subfolder of this folder
if ( base & & ! Count ( ) ) // base: don't go up beyond the top level Recordings menu
return state ;
Display ( ) ;
state = osContinue ;
2014-02-26 11:39:06 +01:00
}
2008-02-16 12:04:12 +01:00
if ( ! HasSubMenu ( ) ) {
2016-12-09 15:00:55 +01:00
Set ( true ) ;
2008-02-16 12:04:12 +01:00
if ( Key ! = kNone )
SetHelpKeys ( ) ;
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
2002-05-11 13:44:58 +02:00
// --- cMenuSetupBase --------------------------------------------------------
class cMenuSetupBase : public cMenuSetupPage {
protected :
cSetup data ;
virtual void Store ( void ) ;
public :
cMenuSetupBase ( void ) ;
} ;
cMenuSetupBase : : cMenuSetupBase ( void )
{
data = Setup ;
}
void cMenuSetupBase : : Store ( void )
{
Setup = data ;
2009-06-21 10:02:49 +02:00
cOsdProvider : : UpdateOsdSize ( true ) ;
2002-05-11 13:44:58 +02:00
Setup . Save ( ) ;
}
2002-03-16 10:03:04 +01:00
// --- cMenuSetupOSD ---------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupOSD : public cMenuSetupBase {
2002-03-16 10:03:04 +01:00
private :
2004-05-16 10:35:36 +02:00
const char * useSmallFontTexts [ 3 ] ;
2015-04-18 13:43:29 +02:00
const char * recSortModeTexts [ 2 ] ;
2017-12-09 18:58:25 +01:00
const char * recSortDirTexts [ 2 ] ;
2012-09-09 14:37:15 +02:00
const char * keyColorTexts [ 4 ] ;
2007-08-11 12:39:06 +02:00
int osdLanguageIndex ;
2004-05-16 10:35:36 +02:00
int numSkins ;
int originalSkinIndex ;
int skinIndex ;
const char * * skinDescriptions ;
cThemes themes ;
2007-06-10 13:02:43 +02:00
int originalThemeIndex ;
2004-05-16 10:35:36 +02:00
int themeIndex ;
2007-06-17 11:12:46 +02:00
cStringList fontOsdNames , fontSmlNames , fontFixNames ;
2007-06-10 13:02:43 +02:00
int fontOsdIndex , fontSmlIndex , fontFixIndex ;
2002-03-16 10:03:04 +01:00
virtual void Set ( void ) ;
public :
2004-05-16 10:35:36 +02:00
cMenuSetupOSD ( void ) ;
virtual ~ cMenuSetupOSD ( ) ;
2002-05-11 13:44:58 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2002-03-16 10:03:04 +01:00
} ;
2004-05-16 10:35:36 +02:00
cMenuSetupOSD : : cMenuSetupOSD ( void )
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupOsd ) ;
2007-08-11 12:39:06 +02:00
osdLanguageIndex = I18nCurrentLanguage ( ) ;
2004-05-16 10:35:36 +02:00
numSkins = Skins . Count ( ) ;
skinIndex = originalSkinIndex = Skins . Current ( ) - > Index ( ) ;
skinDescriptions = new const char * [ numSkins ] ;
themes . Load ( Skins . Current ( ) - > Name ( ) ) ;
2007-06-10 13:02:43 +02:00
themeIndex = originalThemeIndex = Skins . Current ( ) - > Theme ( ) ? themes . GetThemeIndex ( Skins . Current ( ) - > Theme ( ) - > Description ( ) ) : 0 ;
2007-06-17 11:12:46 +02:00
cFont : : GetAvailableFontNames ( & fontOsdNames ) ;
cFont : : GetAvailableFontNames ( & fontSmlNames ) ;
cFont : : GetAvailableFontNames ( & fontFixNames , true ) ;
2007-06-17 11:54:54 +02:00
fontOsdNames . Insert ( strdup ( DefaultFontOsd ) ) ;
fontSmlNames . Insert ( strdup ( DefaultFontSml ) ) ;
fontFixNames . Insert ( strdup ( DefaultFontFix ) ) ;
2007-06-17 11:12:46 +02:00
fontOsdIndex = max ( 0 , fontOsdNames . Find ( Setup . FontOsd ) ) ;
fontSmlIndex = max ( 0 , fontSmlNames . Find ( Setup . FontSml ) ) ;
fontFixIndex = max ( 0 , fontFixNames . Find ( Setup . FontFix ) ) ;
2004-05-16 10:35:36 +02:00
Set ( ) ;
}
cMenuSetupOSD : : ~ cMenuSetupOSD ( )
{
2006-05-25 12:26:09 +02:00
delete [ ] skinDescriptions ;
2004-05-16 10:35:36 +02:00
}
2002-03-16 10:03:04 +01:00
void cMenuSetupOSD : : Set ( void )
2000-11-11 10:39:27 +01:00
{
2004-05-16 10:35:36 +02:00
int current = Current ( ) ;
for ( cSkin * Skin = Skins . First ( ) ; Skin ; Skin = Skins . Next ( Skin ) )
skinDescriptions [ Skin - > Index ( ) ] = Skin - > Description ( ) ;
useSmallFontTexts [ 0 ] = tr ( " never " ) ;
useSmallFontTexts [ 1 ] = tr ( " skin dependent " ) ;
useSmallFontTexts [ 2 ] = tr ( " always " ) ;
2015-04-18 13:43:29 +02:00
recSortModeTexts [ 0 ] = tr ( " by name " ) ;
recSortModeTexts [ 1 ] = tr ( " by time " ) ;
2017-12-09 18:58:25 +01:00
recSortDirTexts [ 0 ] = tr ( " ascending " ) ;
recSortDirTexts [ 1 ] = tr ( " descending " ) ;
2012-09-09 14:37:15 +02:00
keyColorTexts [ 0 ] = tr ( " Key$Red " ) ;
keyColorTexts [ 1 ] = tr ( " Key$Green " ) ;
keyColorTexts [ 2 ] = tr ( " Key$Yellow " ) ;
keyColorTexts [ 3 ] = tr ( " Key$Blue " ) ;
2000-11-11 10:39:27 +01:00
Clear ( ) ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " OSD " ) ) ;
2007-08-18 09:21:52 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Language " ) , & osdLanguageIndex , I18nNumLanguagesWithLocale ( ) , & I18nLanguages ( ) - > At ( 0 ) ) ) ;
2004-05-16 10:35:36 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Skin " ) , & skinIndex , numSkins , skinDescriptions ) ) ;
if ( themes . NumThemes ( ) )
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Theme " ) , & themeIndex , themes . NumThemes ( ) , themes . Descriptions ( ) ) ) ;
2009-05-03 14:15:21 +02:00
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Left (%) " ) , & data . OSDLeftP , 0.0 , 0.5 ) ) ;
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Top (%) " ) , & data . OSDTopP , 0.0 , 0.5 ) ) ;
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Width (%) " ) , & data . OSDWidthP , 0.5 , 1.0 ) ) ;
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Height (%) " ) , & data . OSDHeightP , 0.5 , 1.0 ) ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.OSD$Message time (s) " ) , & data . OSDMessageTime , 1 , 60 ) ) ;
2004-05-16 10:35:36 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Use small font " ) , & data . UseSmallFont , 3 , useSmallFontTexts ) ) ;
2007-06-10 13:02:43 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Anti-alias " ) , & data . AntiAlias ) ) ;
2007-06-17 12:33:53 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Default font " ) , & fontOsdIndex , fontOsdNames . Size ( ) , & fontOsdNames [ 0 ] ) ) ;
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Small font " ) , & fontSmlIndex , fontSmlNames . Size ( ) , & fontSmlNames [ 0 ] ) ) ;
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Fixed font " ) , & fontFixIndex , fontFixNames . Size ( ) , & fontFixNames [ 0 ] ) ) ;
2009-05-03 14:15:21 +02:00
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Default font size (%) " ) , & data . FontOsdSizeP , 0.01 , 0.1 , 1 ) ) ;
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Small font size (%) " ) , & data . FontSmlSizeP , 0.01 , 0.1 , 1 ) ) ;
Add ( new cMenuEditPrcItem ( tr ( " Setup.OSD$Fixed font size (%) " ) , & data . FontFixSizeP , 0.01 , 0.1 , 1 ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Channel info position " ) , & data . ChannelInfoPos , tr ( " bottom " ) , tr ( " top " ) ) ) ;
2005-02-05 11:40:04 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.OSD$Channel info time (s) " ) , & data . ChannelInfoTime , 1 , 60 ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Info on channel switch " ) , & data . ShowInfoOnChSwitch ) ) ;
2006-01-04 14:45:23 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Timeout requested channel info " ) , & data . TimeoutRequChInfo ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Scroll pages " ) , & data . MenuScrollPage ) ) ;
2005-06-18 10:44:30 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Scroll wraps " ) , & data . MenuScrollWrap ) ) ;
2007-02-25 11:39:40 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Menu key closes " ) , & data . MenuKeyCloses ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Recording directories " ) , & data . RecordingDirs ) ) ;
2010-03-12 16:46:45 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Folders in timer menu " ) , & data . FoldersInTimerMenu ) ) ;
2013-03-04 14:11:47 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Always sort folders first " ) , & data . AlwaysSortFoldersFirst ) ) ;
2015-04-18 13:43:29 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Default sort mode for recordings " ) , & data . DefaultSortModeRec , 2 , recSortModeTexts ) ) ;
2017-12-09 18:58:25 +01:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Sorting direction for recordings " ) , & data . RecSortingDirection , 2 , recSortDirTexts ) ) ;
2010-06-06 10:56:11 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.OSD$Number keys for characters " ) , & data . NumberKeysForChars ) ) ;
2012-09-09 14:37:15 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Color key 0 " ) , & data . ColorKey0 , 4 , keyColorTexts ) ) ;
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Color key 1 " ) , & data . ColorKey1 , 4 , keyColorTexts ) ) ;
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Color key 2 " ) , & data . ColorKey2 , 4 , keyColorTexts ) ) ;
Add ( new cMenuEditStraItem ( tr ( " Setup.OSD$Color key 3 " ) , & data . ColorKey3 , 4 , keyColorTexts ) ) ;
2004-05-16 10:35:36 +02:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
2002-03-16 10:03:04 +01:00
}
2002-05-11 13:44:58 +02:00
eOSState cMenuSetupOSD : : ProcessKey ( eKeys Key )
{
2009-05-03 14:15:21 +02:00
bool ModifiedAppearance = false ;
2007-06-10 13:02:43 +02:00
2004-05-16 10:35:36 +02:00
if ( Key = = kOk ) {
2007-08-11 12:39:06 +02:00
I18nSetLocale ( data . OSDLanguage ) ;
2004-05-16 10:35:36 +02:00
if ( skinIndex ! = originalSkinIndex ) {
cSkin * Skin = Skins . Get ( skinIndex ) ;
if ( Skin ) {
2007-06-16 10:41:21 +02:00
Utf8Strn0Cpy ( data . OSDSkin , Skin - > Name ( ) , sizeof ( data . OSDSkin ) ) ;
2004-05-16 10:35:36 +02:00
Skins . SetCurrent ( Skin - > Name ( ) ) ;
2009-05-03 14:15:21 +02:00
ModifiedAppearance = true ;
2004-05-16 10:35:36 +02:00
}
}
if ( themes . NumThemes ( ) & & Skins . Current ( ) - > Theme ( ) ) {
Skins . Current ( ) - > Theme ( ) - > Load ( themes . FileName ( themeIndex ) ) ;
2007-06-16 10:41:21 +02:00
Utf8Strn0Cpy ( data . OSDTheme , themes . Name ( themeIndex ) , sizeof ( data . OSDTheme ) ) ;
2009-05-03 14:15:21 +02:00
ModifiedAppearance | = themeIndex ! = originalThemeIndex ;
2007-06-10 13:02:43 +02:00
}
2009-12-06 12:57:45 +01:00
if ( ! ( DoubleEqual ( data . OSDLeftP , Setup . OSDLeftP ) & & DoubleEqual ( data . OSDTopP , Setup . OSDTopP ) & & DoubleEqual ( data . OSDWidthP , Setup . OSDWidthP ) & & DoubleEqual ( data . OSDHeightP , Setup . OSDHeightP ) ) )
2009-05-03 14:15:21 +02:00
ModifiedAppearance = true ;
2007-06-10 13:02:43 +02:00
if ( data . UseSmallFont ! = Setup . UseSmallFont | | data . AntiAlias ! = Setup . AntiAlias )
2009-05-03 14:15:21 +02:00
ModifiedAppearance = true ;
2007-06-17 11:12:46 +02:00
Utf8Strn0Cpy ( data . FontOsd , fontOsdNames [ fontOsdIndex ] , sizeof ( data . FontOsd ) ) ;
Utf8Strn0Cpy ( data . FontSml , fontSmlNames [ fontSmlIndex ] , sizeof ( data . FontSml ) ) ;
Utf8Strn0Cpy ( data . FontFix , fontFixNames [ fontFixIndex ] , sizeof ( data . FontFix ) ) ;
2009-12-06 12:57:45 +01:00
if ( strcmp ( data . FontOsd , Setup . FontOsd ) | | ! DoubleEqual ( data . FontOsdSizeP , Setup . FontOsdSizeP ) )
2009-05-03 14:15:21 +02:00
ModifiedAppearance = true ;
2009-12-06 12:57:45 +01:00
if ( strcmp ( data . FontSml , Setup . FontSml ) | | ! DoubleEqual ( data . FontSmlSizeP , Setup . FontSmlSizeP ) )
2009-05-03 14:15:21 +02:00
ModifiedAppearance = true ;
2009-12-06 12:57:45 +01:00
if ( strcmp ( data . FontFix , Setup . FontFix ) | | ! DoubleEqual ( data . FontFixSizeP , Setup . FontFixSizeP ) )
2009-05-03 14:15:21 +02:00
ModifiedAppearance = true ;
2017-12-09 18:58:25 +01:00
if ( data . AlwaysSortFoldersFirst ! = Setup . AlwaysSortFoldersFirst | | data . RecordingDirs ! = Setup . RecordingDirs | | data . RecSortingDirection ! = Setup . RecSortingDirection ) {
2015-09-01 11:14:27 +02:00
LOCK_RECORDINGS_WRITE ;
Recordings - > ClearSortNames ( ) ;
}
2004-05-16 10:35:36 +02:00
}
int oldSkinIndex = skinIndex ;
2007-08-11 12:39:06 +02:00
int oldOsdLanguageIndex = osdLanguageIndex ;
2002-05-11 13:44:58 +02:00
eOSState state = cMenuSetupBase : : ProcessKey ( Key ) ;
2017-04-03 12:49:56 +02:00
if ( ModifiedAppearance )
2009-05-03 14:15:21 +02:00
cOsdProvider : : UpdateOsdSize ( true ) ;
2007-06-10 13:02:43 +02:00
2007-08-11 12:39:06 +02:00
if ( osdLanguageIndex ! = oldOsdLanguageIndex | | skinIndex ! = oldSkinIndex ) {
strn0cpy ( data . OSDLanguage , I18nLocale ( osdLanguageIndex ) , sizeof ( data . OSDLanguage ) ) ;
int OriginalOSDLanguage = I18nCurrentLanguage ( ) ;
I18nSetLanguage ( osdLanguageIndex ) ;
2004-05-16 10:35:36 +02:00
cSkin * Skin = Skins . Get ( skinIndex ) ;
if ( Skin ) {
char * d = themes . NumThemes ( ) ? strdup ( themes . Descriptions ( ) [ themeIndex ] ) : NULL ;
themes . Load ( Skin - > Name ( ) ) ;
if ( skinIndex ! = oldSkinIndex )
themeIndex = d ? themes . GetThemeIndex ( d ) : 0 ;
free ( d ) ;
}
2006-01-08 11:44:37 +01:00
2002-05-11 13:44:58 +02:00
Set ( ) ;
2007-08-11 12:39:06 +02:00
I18nSetLanguage ( OriginalOSDLanguage ) ;
2002-05-11 13:44:58 +02:00
}
return state ;
}
2002-03-16 10:03:04 +01:00
// --- cMenuSetupEPG ---------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupEPG : public cMenuSetupBase {
2004-01-09 15:53:59 +01:00
private :
int originalNumLanguages ;
int numLanguages ;
void Setup ( void ) ;
2002-03-16 10:03:04 +01:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupEPG ( void ) ;
2004-01-09 15:53:59 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2002-03-16 10:03:04 +01:00
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupEPG : : cMenuSetupEPG ( void )
2002-03-16 10:03:04 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupEpg ) ;
2007-08-11 12:39:06 +02:00
for ( numLanguages = 0 ; numLanguages < I18nLanguages ( ) - > Size ( ) & & data . EPGLanguages [ numLanguages ] > = 0 ; numLanguages + + )
2004-01-09 15:53:59 +01:00
;
originalNumLanguages = numLanguages ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " EPG " ) ) ;
2006-01-07 15:54:10 +01:00
SetHelp ( tr ( " Button$Scan " ) ) ;
2004-01-09 15:53:59 +01:00
Setup ( ) ;
}
void cMenuSetupEPG : : Setup ( void )
{
int current = Current ( ) ;
Clear ( ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.EPG$EPG scan timeout (h) " ) , & data . EPGScanTimeout ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.EPG$EPG bugfix level " ) , & data . EPGBugfixLevel , 0 , MAXEPGBUGFIXLEVEL ) ) ;
2004-02-21 15:30:35 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.EPG$EPG linger time (min) " ) , & data . EPGLinger , 0 ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.EPG$Set system time " ) , & data . SetSystemTime ) ) ;
2004-01-09 15:53:59 +01:00
if ( data . SetSystemTime )
2004-05-16 12:58:04 +02:00
Add ( new cMenuEditTranItem ( tr ( " Setup.EPG$Use time from transponder " ) , & data . TimeTransponder , & data . TimeSource ) ) ;
2007-08-11 12:39:06 +02:00
// TRANSLATORS: note the plural!
Add ( new cMenuEditIntItem ( tr ( " Setup.EPG$Preferred languages " ) , & numLanguages , 0 , I18nLanguages ( ) - > Size ( ) ) ) ;
2004-01-09 15:53:59 +01:00
for ( int i = 0 ; i < numLanguages ; i + + )
2007-08-11 12:39:06 +02:00
// TRANSLATORS: note the singular!
Add ( new cMenuEditStraItem ( tr ( " Setup.EPG$Preferred language " ) , & data . EPGLanguages [ i ] , I18nLanguages ( ) - > Size ( ) , & I18nLanguages ( ) - > At ( 0 ) ) ) ;
2004-01-09 15:53:59 +01:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
}
eOSState cMenuSetupEPG : : ProcessKey ( eKeys Key )
{
if ( Key = = kOk ) {
bool Modified = numLanguages ! = originalNumLanguages ;
if ( ! Modified ) {
for ( int i = 0 ; i < numLanguages ; i + + ) {
if ( data . EPGLanguages [ i ] ! = : : Setup . EPGLanguages [ i ] ) {
Modified = true ;
break ;
}
}
}
if ( Modified )
cSchedules : : ResetVersions ( ) ;
}
2004-01-11 21:42:23 +01:00
int oldnumLanguages = numLanguages ;
int oldSetSystemTime = data . SetSystemTime ;
eOSState state = cMenuSetupBase : : ProcessKey ( Key ) ;
if ( Key ! = kNone ) {
2004-01-09 15:53:59 +01:00
if ( numLanguages ! = oldnumLanguages | | data . SetSystemTime ! = oldSetSystemTime ) {
for ( int i = oldnumLanguages ; i < numLanguages ; i + + ) {
data . EPGLanguages [ i ] = 0 ;
2007-08-11 12:39:06 +02:00
for ( int l = 0 ; l < I18nLanguages ( ) - > Size ( ) ; l + + ) {
2004-01-09 15:53:59 +01:00
int k ;
for ( k = 0 ; k < oldnumLanguages ; k + + ) {
if ( data . EPGLanguages [ k ] = = l )
break ;
}
if ( k > = oldnumLanguages ) {
data . EPGLanguages [ i ] = l ;
break ;
}
}
}
data . EPGLanguages [ numLanguages ] = - 1 ;
Setup ( ) ;
}
2004-01-17 15:38:11 +01:00
if ( Key = = kRed ) {
EITScanner . ForceScan ( ) ;
return osEnd ;
}
2004-01-09 15:53:59 +01:00
}
return state ;
2002-03-16 10:03:04 +01:00
}
// --- cMenuSetupDVB ---------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupDVB : public cMenuSetupBase {
2004-01-05 12:08:09 +01:00
private :
2005-01-05 10:48:22 +01:00
int originalNumAudioLanguages ;
int numAudioLanguages ;
2007-10-12 14:52:30 +02:00
int originalNumSubtitleLanguages ;
int numSubtitleLanguages ;
2005-01-05 10:48:22 +01:00
void Setup ( void ) ;
2005-02-20 13:39:49 +01:00
const char * videoDisplayFormatTexts [ 3 ] ;
2006-04-15 14:18:25 +02:00
const char * updateChannelsTexts [ 6 ] ;
2015-02-04 09:18:30 +01:00
const char * standardComplianceTexts [ 3 ] ;
2002-03-16 10:03:04 +01:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupDVB ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
2002-03-16 10:03:04 +01:00
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupDVB : : cMenuSetupDVB ( void )
2002-03-16 10:03:04 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupDvb ) ;
2007-08-11 12:39:06 +02:00
for ( numAudioLanguages = 0 ; numAudioLanguages < I18nLanguages ( ) - > Size ( ) & & data . AudioLanguages [ numAudioLanguages ] > = 0 ; numAudioLanguages + + )
2005-01-05 10:48:22 +01:00
;
2007-10-12 14:52:30 +02:00
for ( numSubtitleLanguages = 0 ; numSubtitleLanguages < I18nLanguages ( ) - > Size ( ) & & data . SubtitleLanguages [ numSubtitleLanguages ] > = 0 ; numSubtitleLanguages + + )
;
2005-01-05 10:48:22 +01:00
originalNumAudioLanguages = numAudioLanguages ;
2007-10-12 14:52:30 +02:00
originalNumSubtitleLanguages = numSubtitleLanguages ;
2005-02-20 13:39:49 +01:00
videoDisplayFormatTexts [ 0 ] = tr ( " pan&scan " ) ;
videoDisplayFormatTexts [ 1 ] = tr ( " letterbox " ) ;
videoDisplayFormatTexts [ 2 ] = tr ( " center cut out " ) ;
2004-01-05 12:08:09 +01:00
updateChannelsTexts [ 0 ] = tr ( " no " ) ;
updateChannelsTexts [ 1 ] = tr ( " names only " ) ;
2006-04-15 14:18:25 +02:00
updateChannelsTexts [ 2 ] = tr ( " PIDs only " ) ;
updateChannelsTexts [ 3 ] = tr ( " names and PIDs " ) ;
updateChannelsTexts [ 4 ] = tr ( " add new channels " ) ;
updateChannelsTexts [ 5 ] = tr ( " add new transponders " ) ;
2012-04-15 10:52:34 +02:00
standardComplianceTexts [ 0 ] = " DVB " ;
standardComplianceTexts [ 1 ] = " ANSI/SCTE " ;
2015-02-04 09:18:30 +01:00
standardComplianceTexts [ 2 ] = " NORDIG " ;
2004-01-05 12:08:09 +01:00
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " DVB " ) ) ;
2013-02-17 13:19:36 +01:00
SetHelp ( NULL , tr ( " Button$Audio " ) , tr ( " Button$Subtitles " ) , NULL ) ;
2005-01-05 10:48:22 +01:00
Setup ( ) ;
}
void cMenuSetupDVB : : Setup ( void )
{
int current = Current ( ) ;
Clear ( ) ;
2002-06-16 12:57:31 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.DVB$Primary DVB interface " ) , & data . PrimaryDVB , 1 , cDevice : : NumDevices ( ) ) ) ;
2015-02-04 09:18:30 +01:00
Add ( new cMenuEditStraItem ( tr ( " Setup.DVB$Standard compliance " ) , & data . StandardCompliance , 3 , standardComplianceTexts ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.DVB$Video format " ) , & data . VideoFormat , " 4:3 " , " 16:9 " ) ) ;
2005-03-05 15:48:26 +01:00
if ( data . VideoFormat = = 0 )
Add ( new cMenuEditStraItem ( tr ( " Setup.DVB$Video display format " ) , & data . VideoDisplayFormat , 3 , videoDisplayFormatTexts ) ) ;
2005-01-09 12:36:48 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.DVB$Use Dolby Digital " ) , & data . UseDolbyDigital ) ) ;
2006-04-15 14:18:25 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.DVB$Update channels " ) , & data . UpdateChannels , 6 , updateChannelsTexts ) ) ;
2007-08-11 12:39:06 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.DVB$Audio languages " ) , & numAudioLanguages , 0 , I18nLanguages ( ) - > Size ( ) ) ) ;
2005-01-05 10:48:22 +01:00
for ( int i = 0 ; i < numAudioLanguages ; i + + )
2007-08-11 12:39:06 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.DVB$Audio language " ) , & data . AudioLanguages [ i ] , I18nLanguages ( ) - > Size ( ) , & I18nLanguages ( ) - > At ( 0 ) ) ) ;
2007-10-12 14:52:30 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.DVB$Display subtitles " ) , & data . DisplaySubtitles ) ) ;
if ( data . DisplaySubtitles ) {
Add ( new cMenuEditIntItem ( tr ( " Setup.DVB$Subtitle languages " ) , & numSubtitleLanguages , 0 , I18nLanguages ( ) - > Size ( ) ) ) ;
for ( int i = 0 ; i < numSubtitleLanguages ; i + + )
Add ( new cMenuEditStraItem ( tr ( " Setup.DVB$Subtitle language " ) , & data . SubtitleLanguages [ i ] , I18nLanguages ( ) - > Size ( ) , & I18nLanguages ( ) - > At ( 0 ) ) ) ;
2008-02-24 10:11:14 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.DVB$Subtitle offset " ) , & data . SubtitleOffset , - 100 , 100 ) ) ;
2007-10-12 14:52:30 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.DVB$Subtitle foreground transparency " ) , & data . SubtitleFgTransparency , 0 , 9 ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.DVB$Subtitle background transparency " ) , & data . SubtitleBgTransparency , 0 , 10 ) ) ;
}
2005-01-05 10:48:22 +01:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
2002-03-16 10:03:04 +01:00
}
2002-05-11 13:44:58 +02:00
eOSState cMenuSetupDVB : : ProcessKey ( eKeys Key )
{
2005-02-20 13:39:49 +01:00
int oldVideoDisplayFormat = : : Setup . VideoDisplayFormat ;
2005-01-05 10:48:22 +01:00
bool oldVideoFormat = : : Setup . VideoFormat ;
2005-03-05 15:48:26 +01:00
bool newVideoFormat = data . VideoFormat ;
2007-10-12 14:52:30 +02:00
bool oldDisplaySubtitles = : : Setup . DisplaySubtitles ;
bool newDisplaySubtitles = data . DisplaySubtitles ;
2005-01-05 10:48:22 +01:00
int oldnumAudioLanguages = numAudioLanguages ;
2007-10-12 14:52:30 +02:00
int oldnumSubtitleLanguages = numSubtitleLanguages ;
2002-05-11 13:44:58 +02:00
eOSState state = cMenuSetupBase : : ProcessKey ( Key ) ;
2005-01-05 10:48:22 +01:00
if ( Key ! = kNone ) {
2011-08-27 09:55:35 +02:00
switch ( Key ) {
case kGreen : cRemote : : Put ( kAudio , true ) ;
state = osEnd ;
break ;
case kYellow : cRemote : : Put ( kSubtitles , true ) ;
state = osEnd ;
break ;
2013-02-17 13:19:36 +01:00
default : {
2011-08-27 09:55:35 +02:00
bool DoSetup = data . VideoFormat ! = newVideoFormat ;
DoSetup | = data . DisplaySubtitles ! = newDisplaySubtitles ;
if ( numAudioLanguages ! = oldnumAudioLanguages ) {
for ( int i = oldnumAudioLanguages ; i < numAudioLanguages ; i + + ) {
data . AudioLanguages [ i ] = 0 ;
for ( int l = 0 ; l < I18nLanguages ( ) - > Size ( ) ; l + + ) {
int k ;
for ( k = 0 ; k < oldnumAudioLanguages ; k + + ) {
if ( data . AudioLanguages [ k ] = = l )
break ;
}
if ( k > = oldnumAudioLanguages ) {
data . AudioLanguages [ i ] = l ;
break ;
}
}
2005-01-05 10:48:22 +01:00
}
2011-08-27 09:55:35 +02:00
data . AudioLanguages [ numAudioLanguages ] = - 1 ;
DoSetup = true ;
}
if ( numSubtitleLanguages ! = oldnumSubtitleLanguages ) {
for ( int i = oldnumSubtitleLanguages ; i < numSubtitleLanguages ; i + + ) {
data . SubtitleLanguages [ i ] = 0 ;
for ( int l = 0 ; l < I18nLanguages ( ) - > Size ( ) ; l + + ) {
int k ;
for ( k = 0 ; k < oldnumSubtitleLanguages ; k + + ) {
if ( data . SubtitleLanguages [ k ] = = l )
break ;
}
if ( k > = oldnumSubtitleLanguages ) {
data . SubtitleLanguages [ i ] = l ;
break ;
}
}
2007-10-12 14:52:30 +02:00
}
2011-08-27 09:55:35 +02:00
data . SubtitleLanguages [ numSubtitleLanguages ] = - 1 ;
DoSetup = true ;
}
if ( DoSetup )
Setup ( ) ;
2007-10-12 14:52:30 +02:00
}
2011-08-27 09:55:35 +02:00
}
2005-01-05 10:48:22 +01:00
}
2002-05-11 13:44:58 +02:00
if ( state = = osBack & & Key = = kOk ) {
2005-02-20 13:39:49 +01:00
if ( : : Setup . VideoDisplayFormat ! = oldVideoDisplayFormat )
cDevice : : PrimaryDevice ( ) - > SetVideoDisplayFormat ( eVideoDisplayFormat ( : : Setup . VideoDisplayFormat ) ) ;
2005-01-05 10:48:22 +01:00
if ( : : Setup . VideoFormat ! = oldVideoFormat )
cDevice : : PrimaryDevice ( ) - > SetVideoFormat ( : : Setup . VideoFormat ) ;
2007-10-12 14:52:30 +02:00
if ( : : Setup . DisplaySubtitles ! = oldDisplaySubtitles )
cDevice : : PrimaryDevice ( ) - > EnsureSubtitleTrack ( ) ;
cDvbSubtitleConverter : : SetupChanged ( ) ;
2002-05-11 13:44:58 +02:00
}
return state ;
}
2002-03-16 10:03:04 +01:00
// --- cMenuSetupLNB ---------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupLNB : public cMenuSetupBase {
2002-10-06 10:25:42 +02:00
private :
2011-12-04 12:45:26 +01:00
cSatCableNumbers satCableNumbers ;
2002-10-06 10:25:42 +02:00
void Setup ( void ) ;
2002-03-16 10:03:04 +01:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupLNB ( void ) ;
2002-10-06 10:25:42 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2002-03-16 10:03:04 +01:00
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupLNB : : cMenuSetupLNB ( void )
2011-12-04 12:45:26 +01:00
: satCableNumbers ( MAXDEVICES )
2002-03-16 10:03:04 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupLnb ) ;
2011-12-04 12:45:26 +01:00
satCableNumbers . FromString ( data . DeviceBondings ) ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " LNB " ) ) ;
2002-10-06 10:25:42 +02:00
Setup ( ) ;
}
void cMenuSetupLNB : : Setup ( void )
{
int current = Current ( ) ;
Clear ( ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.LNB$Use DiSEqC " ) , & data . DiSEqC ) ) ;
2002-10-06 10:25:42 +02:00
if ( ! data . DiSEqC ) {
Add ( new cMenuEditIntItem ( tr ( " Setup.LNB$SLOF (MHz) " ) , & data . LnbSLOF ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.LNB$Low LNB frequency (MHz) " ) , & data . LnbFrequLo ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.LNB$High LNB frequency (MHz) " ) , & data . LnbFrequHi ) ) ;
}
2011-12-04 12:45:26 +01:00
int NumSatDevices = 0 ;
for ( int i = 0 ; i < cDevice : : NumDevices ( ) ; i + + ) {
if ( cDevice : : GetDevice ( i ) - > ProvidesSource ( cSource : : stSat ) )
NumSatDevices + + ;
}
if ( NumSatDevices > 1 ) {
for ( int i = 0 ; i < cDevice : : NumDevices ( ) ; i + + ) {
if ( cDevice : : GetDevice ( i ) - > ProvidesSource ( cSource : : stSat ) )
Add ( new cMenuEditIntItem ( cString : : sprintf ( tr ( " Setup.LNB$Device %d connected to sat cable " ) , i + 1 ) , & satCableNumbers . Array ( ) [ i ] , 0 , NumSatDevices , tr ( " Setup.LNB$own " ) ) ) ;
2013-02-19 09:48:54 +01:00
else
satCableNumbers . Array ( ) [ i ] = 0 ;
2011-12-04 12:45:26 +01:00
}
}
2013-08-21 11:02:52 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.LNB$Use dish positioner " ) , & data . UsePositioner ) ) ;
if ( data . UsePositioner ) {
Add ( new cMenuEditIntxItem ( tr ( " Setup.LNB$Site latitude (degrees) " ) , & data . SiteLat , - 900 , 900 , 10 , tr ( " South " ) , tr ( " North " ) ) ) ;
Add ( new cMenuEditIntxItem ( tr ( " Setup.LNB$Site longitude (degrees) " ) , & data . SiteLon , - 1800 , 1800 , 10 , tr ( " West " ) , tr ( " East " ) ) ) ;
Add ( new cMenuEditIntxItem ( tr ( " Setup.LNB$Max. positioner swing (degrees) " ) , & data . PositionerSwing , 0 , 900 , 10 ) ) ;
Add ( new cMenuEditIntxItem ( tr ( " Setup.LNB$Positioner speed (degrees/s) " ) , & data . PositionerSpeed , 1 , 1800 , 10 ) ) ;
}
2002-10-06 10:25:42 +02:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
}
eOSState cMenuSetupLNB : : ProcessKey ( eKeys Key )
{
int oldDiSEqC = data . DiSEqC ;
2013-08-21 11:02:52 +02:00
int oldUsePositioner = data . UsePositioner ;
2011-12-04 12:45:26 +01:00
bool DeviceBondingsChanged = false ;
if ( Key = = kOk ) {
cString NewDeviceBondings = satCableNumbers . ToString ( ) ;
DeviceBondingsChanged = strcmp ( data . DeviceBondings , NewDeviceBondings ) ! = 0 ;
data . DeviceBondings = NewDeviceBondings ;
}
2002-10-06 10:25:42 +02:00
eOSState state = cMenuSetupBase : : ProcessKey ( Key ) ;
2013-08-21 11:02:52 +02:00
if ( Key ! = kNone & & ( data . DiSEqC ! = oldDiSEqC | | data . UsePositioner ! = oldUsePositioner ) )
2002-10-06 10:25:42 +02:00
Setup ( ) ;
2011-12-04 12:45:26 +01:00
else if ( DeviceBondingsChanged )
cDvbDevice : : BondDevices ( data . DeviceBondings ) ;
2002-10-06 10:25:42 +02:00
return state ;
2002-03-16 10:03:04 +01:00
}
2007-01-07 14:46:14 +01:00
// --- cMenuSetupCAM ---------------------------------------------------------
2002-03-16 10:03:04 +01:00
2007-01-07 14:46:14 +01:00
class cMenuSetupCAMItem : public cOsdItem {
2005-08-26 12:49:26 +02:00
private :
2007-01-07 14:46:14 +01:00
cCamSlot * camSlot ;
2005-08-26 12:49:26 +02:00
public :
2007-01-07 14:46:14 +01:00
cMenuSetupCAMItem ( cCamSlot * CamSlot ) ;
cCamSlot * CamSlot ( void ) { return camSlot ; }
bool Changed ( void ) ;
2005-08-26 12:49:26 +02:00
} ;
2007-01-07 14:46:14 +01:00
cMenuSetupCAMItem : : cMenuSetupCAMItem ( cCamSlot * CamSlot )
{
camSlot = CamSlot ;
SetText ( " " ) ;
Changed ( ) ;
}
bool cMenuSetupCAMItem : : Changed ( void )
2005-08-26 12:49:26 +02:00
{
2015-03-09 11:51:08 +01:00
cString AssignedDevice ( " " ) ;
2015-01-30 13:38:44 +01:00
const char * Activating = " " ;
2007-01-07 14:46:14 +01:00
const char * CamName = camSlot - > GetCamName ( ) ;
if ( ! CamName ) {
switch ( camSlot - > ModuleStatus ( ) ) {
case msReset : CamName = tr ( " CAM reset " ) ; break ;
case msPresent : CamName = tr ( " CAM present " ) ; break ;
case msReady : CamName = tr ( " CAM ready " ) ; break ;
default : CamName = " - " ; break ;
}
}
2015-01-30 13:38:44 +01:00
else if ( camSlot - > IsActivating ( ) )
// TRANSLATORS: note the leading blank!
Activating = tr ( " (activating) " ) ;
2019-05-28 15:54:22 +02:00
cVector < int > DeviceNumbers ;
2017-01-23 12:01:48 +01:00
for ( cCamSlot * CamSlot = CamSlots . First ( ) ; CamSlot ; CamSlot = CamSlots . Next ( CamSlot ) ) {
2017-03-18 16:33:59 +01:00
if ( CamSlot = = camSlot | | CamSlot - > MasterSlot ( ) = = camSlot )
2019-05-28 15:54:22 +02:00
CamSlot - > Devices ( DeviceNumbers ) ;
2017-01-23 12:01:48 +01:00
}
2019-05-28 15:54:22 +02:00
if ( DeviceNumbers . Size ( ) > 0 ) {
2017-03-18 16:33:59 +01:00
AssignedDevice = cString : : sprintf ( " %s " , tr ( " @ device " ) ) ;
2019-05-28 15:54:22 +02:00
DeviceNumbers . Sort ( CompareInts ) ;
for ( int i = 0 ; i < DeviceNumbers . Size ( ) ; i + + )
AssignedDevice = cString : : sprintf ( " %s %d " , * AssignedDevice , DeviceNumbers [ i ] ) ;
2017-03-18 16:33:59 +01:00
}
2015-03-09 11:51:08 +01:00
cString buffer = cString : : sprintf ( " %d %s%s%s " , camSlot - > SlotNumber ( ) , CamName , * AssignedDevice , Activating ) ;
2007-01-07 14:46:14 +01:00
if ( strcmp ( buffer , Text ( ) ) ! = 0 ) {
SetText ( buffer ) ;
return true ;
}
return false ;
2005-08-26 12:49:26 +02:00
}
2007-01-07 14:46:14 +01:00
class cMenuSetupCAM : public cMenuSetupBase {
2003-01-06 14:44:27 +01:00
private :
2017-12-04 15:33:41 +01:00
int currentChannel ;
2015-01-30 13:38:44 +01:00
const char * activationHelp ;
2003-01-06 14:44:27 +01:00
eOSState Menu ( void ) ;
eOSState Reset ( void ) ;
2015-01-30 13:38:44 +01:00
eOSState Activate ( void ) ;
void SetHelpKeys ( void ) ;
2002-03-16 10:03:04 +01:00
public :
2007-01-07 14:46:14 +01:00
cMenuSetupCAM ( void ) ;
2002-05-11 13:44:58 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2002-03-16 10:03:04 +01:00
} ;
2007-01-07 14:46:14 +01:00
cMenuSetupCAM : : cMenuSetupCAM ( void )
2002-03-16 10:03:04 +01:00
{
2017-12-04 15:33:41 +01:00
currentChannel = cDevice : : CurrentChannel ( ) ;
2015-01-30 13:38:44 +01:00
activationHelp = NULL ;
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupCam ) ;
2007-01-07 14:46:14 +01:00
SetSection ( tr ( " CAM " ) ) ;
SetCols ( 15 ) ;
SetHasHotkeys ( ) ;
2017-01-23 12:01:48 +01:00
for ( cCamSlot * CamSlot = CamSlots . First ( ) ; CamSlot ; CamSlot = CamSlots . Next ( CamSlot ) ) {
if ( CamSlot - > IsMasterSlot ( ) ) // we only list master CAM slots
Add ( new cMenuSetupCAMItem ( CamSlot ) ) ;
}
2015-01-30 13:38:44 +01:00
SetHelpKeys ( ) ;
}
void cMenuSetupCAM : : SetHelpKeys ( void )
{
if ( HasSubMenu ( ) )
return ;
cMenuSetupCAMItem * item = ( cMenuSetupCAMItem * ) Get ( Current ( ) ) ;
const char * NewActivationHelp = " " ;
if ( item ) {
cCamSlot * CamSlot = item - > CamSlot ( ) ;
if ( CamSlot - > IsActivating ( ) )
NewActivationHelp = tr ( " Button$Cancel activation " ) ;
else if ( CamSlot - > CanActivate ( ) )
NewActivationHelp = tr ( " Button$Activate " ) ;
}
if ( NewActivationHelp ! = activationHelp ) {
activationHelp = NewActivationHelp ;
SetHelp ( tr ( " Button$Menu " ) , tr ( " Button$Reset " ) , activationHelp ) ;
}
2003-01-06 14:44:27 +01:00
}
2007-01-07 14:46:14 +01:00
eOSState cMenuSetupCAM : : Menu ( void )
2003-01-06 14:44:27 +01:00
{
2007-01-07 14:46:14 +01:00
cMenuSetupCAMItem * item = ( cMenuSetupCAMItem * ) Get ( Current ( ) ) ;
2005-08-26 12:49:26 +02:00
if ( item ) {
2007-01-07 14:46:14 +01:00
if ( item - > CamSlot ( ) - > EnterMenu ( ) ) {
Skins . Message ( mtStatus , tr ( " Opening CAM menu... " ) ) ;
time_t t0 = time ( NULL ) ;
time_t t1 = t0 ;
while ( time ( NULL ) - t0 < = MAXWAITFORCAMMENU ) {
if ( item - > CamSlot ( ) - > HasUserIO ( ) )
break ;
2017-06-10 11:52:47 +02:00
if ( time ( NULL ) - t1 > = CAMMENURETRYTIMEOUT ) {
2007-01-07 14:46:14 +01:00
dsyslog ( " CAM %d: retrying to enter CAM menu... " , item - > CamSlot ( ) - > SlotNumber ( ) ) ;
item - > CamSlot ( ) - > EnterMenu ( ) ;
t1 = time ( NULL ) ;
}
cCondWait : : SleepMs ( 100 ) ;
}
Skins . Message ( mtStatus , NULL ) ;
if ( item - > CamSlot ( ) - > HasUserIO ( ) )
return AddSubMenu ( new cMenuCam ( item - > CamSlot ( ) ) ) ;
2005-10-02 14:43:56 +02:00
}
2007-01-07 14:46:14 +01:00
Skins . Message ( mtError , tr ( " Can't open CAM menu! " ) ) ;
2005-08-26 12:49:26 +02:00
}
2003-01-06 14:44:27 +01:00
return osContinue ;
}
2015-01-30 13:38:44 +01:00
eOSState cMenuSetupCAM : : Activate ( void )
{
cMenuSetupCAMItem * item = ( cMenuSetupCAMItem * ) Get ( Current ( ) ) ;
if ( item ) {
cCamSlot * CamSlot = item - > CamSlot ( ) ;
if ( CamSlot - > IsActivating ( ) )
CamSlot - > CancelActivation ( ) ;
else if ( CamSlot - > CanActivate ( ) ) {
2015-01-31 14:50:55 +01:00
if ( CamSlot - > Priority ( ) < LIVEPRIORITY ) { // don't interrupt recordings
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
if ( const cChannel * Channel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) ) {
2015-01-31 14:50:55 +01:00
for ( int i = 0 ; i < cDevice : : NumDevices ( ) ; i + + ) {
if ( cDevice * Device = cDevice : : GetDevice ( i ) ) {
if ( Device - > ProvidesChannel ( Channel ) ) {
if ( Device - > Priority ( ) < LIVEPRIORITY ) { // don't interrupt recordings
2017-03-18 16:33:59 +01:00
if ( CamSlot - > Assign ( Device , true ) ) { // query
cControl : : Shutdown ( ) ; // must end transfer mode before assigning CAM, otherwise it might be unassigned again
CamSlot = CamSlot - > MtdSpawn ( ) ;
if ( CamSlot - > Assign ( Device ) ) {
if ( Device - > SwitchChannel ( Channel , true ) ) {
CamSlot - > StartActivation ( ) ;
return osContinue ;
2015-01-30 13:38:44 +01:00
}
}
}
}
}
}
}
2015-01-31 14:50:55 +01:00
}
2015-01-30 13:38:44 +01:00
}
Skins . Message ( mtError , tr ( " Can't activate CAM! " ) ) ;
}
}
return osContinue ;
}
2007-01-07 14:46:14 +01:00
eOSState cMenuSetupCAM : : Reset ( void )
2003-01-06 14:44:27 +01:00
{
2007-01-07 14:46:14 +01:00
cMenuSetupCAMItem * item = ( cMenuSetupCAMItem * ) Get ( Current ( ) ) ;
2005-08-26 12:49:26 +02:00
if ( item ) {
2007-01-07 14:46:14 +01:00
if ( ! item - > CamSlot ( ) - > Device ( ) | | Interface - > Confirm ( tr ( " CAM is in use - really reset? " ) ) ) {
if ( ! item - > CamSlot ( ) - > Reset ( ) )
Skins . Message ( mtError , tr ( " Can't reset CAM! " ) ) ;
2005-08-26 12:49:26 +02:00
}
2003-02-09 11:54:22 +01:00
}
2003-01-06 14:44:27 +01:00
return osContinue ;
2002-03-16 10:03:04 +01:00
}
2007-01-07 14:46:14 +01:00
eOSState cMenuSetupCAM : : ProcessKey ( eKeys Key )
2002-05-11 13:44:58 +02:00
{
2007-01-07 14:46:14 +01:00
eOSState state = HasSubMenu ( ) ? cMenuSetupBase : : ProcessKey ( Key ) : cOsdMenu : : ProcessKey ( Key ) ;
2002-05-11 13:44:58 +02:00
2007-01-07 14:46:14 +01:00
if ( ! HasSubMenu ( ) ) {
2003-01-06 14:44:27 +01:00
switch ( Key ) {
2007-01-07 14:46:14 +01:00
case kOk :
2005-08-26 12:49:26 +02:00
case kRed : return Menu ( ) ;
2007-01-07 14:46:14 +01:00
case kGreen : state = Reset ( ) ; break ;
2015-01-30 13:38:44 +01:00
case kYellow : state = Activate ( ) ; break ;
2003-01-06 14:44:27 +01:00
default : break ;
}
2007-01-07 14:46:14 +01:00
for ( cMenuSetupCAMItem * ci = ( cMenuSetupCAMItem * ) First ( ) ; ci ; ci = ( cMenuSetupCAMItem * ) ci - > Next ( ) ) {
if ( ci - > Changed ( ) )
DisplayItem ( ci ) ;
}
2015-01-30 13:38:44 +01:00
SetHelpKeys ( ) ;
2003-01-06 14:44:27 +01:00
}
2017-12-04 15:33:41 +01:00
if ( currentChannel ! = cDevice : : CurrentChannel ( ) )
state = osEnd ;
2002-05-11 13:44:58 +02:00
return state ;
}
2002-03-16 10:03:04 +01:00
// --- cMenuSetupRecord ------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupRecord : public cMenuSetupBase {
2009-05-21 11:35:37 +02:00
private :
2015-09-11 08:29:41 +02:00
const char * recordKeyHandlingTexts [ 3 ] ;
2009-05-21 11:35:37 +02:00
const char * pauseKeyHandlingTexts [ 3 ] ;
2010-03-07 12:43:30 +01:00
const char * delTimeshiftRecTexts [ 3 ] ;
2002-03-16 10:03:04 +01:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupRecord ( void ) ;
2002-03-16 10:03:04 +01:00
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupRecord : : cMenuSetupRecord ( void )
2002-03-16 10:03:04 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupRecord ) ;
2015-09-11 08:29:41 +02:00
recordKeyHandlingTexts [ 0 ] = tr ( " no instant recording " ) ;
recordKeyHandlingTexts [ 1 ] = tr ( " confirm instant recording " ) ;
recordKeyHandlingTexts [ 2 ] = tr ( " record instantly " ) ;
2009-05-21 11:35:37 +02:00
pauseKeyHandlingTexts [ 0 ] = tr ( " do not pause live video " ) ;
pauseKeyHandlingTexts [ 1 ] = tr ( " confirm pause live video " ) ;
pauseKeyHandlingTexts [ 2 ] = tr ( " pause live video " ) ;
2010-03-07 12:43:30 +01:00
delTimeshiftRecTexts [ 0 ] = tr ( " no " ) ;
delTimeshiftRecTexts [ 1 ] = tr ( " confirm " ) ;
delTimeshiftRecTexts [ 2 ] = tr ( " yes " ) ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " Recording " ) ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Margin at start (min) " ) , & data . MarginStart ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Margin at stop (min) " ) , & data . MarginStop ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Default priority " ) , & data . DefaultPriority , 0 , MAXPRIORITY ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Default lifetime (d) " ) , & data . DefaultLifetime , 0 , MAXLIFETIME ) ) ;
2015-09-11 08:29:41 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.Recording$Record key handling " ) , & data . RecordKeyHandling , 3 , recordKeyHandlingTexts ) ) ;
2009-05-21 11:35:37 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.Recording$Pause key handling " ) , & data . PauseKeyHandling , 3 , pauseKeyHandlingTexts ) ) ;
2003-05-11 14:10:00 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Pause priority " ) , & data . PausePriority , 0 , MAXPRIORITY ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Pause lifetime (d) " ) , & data . PauseLifetime , 0 , MAXLIFETIME ) ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Recording$Use episode name " ) , & data . UseSubtitle ) ) ;
2004-02-29 14:21:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Recording$Use VPS " ) , & data . UseVps ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$VPS margin (s) " ) , & data . VpsMargin , 0 ) ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Recording$Mark instant recording " ) , & data . MarkInstantRecord ) ) ;
2007-11-03 15:06:00 +01:00
Add ( new cMenuEditStrItem ( tr ( " Setup.Recording$Name instant recording " ) , data . NameInstantRecord , sizeof ( data . NameInstantRecord ) ) ) ;
2012-09-15 13:57:39 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Instant rec. time (min) " ) , & data . InstantRecordTime , 0 , MAXINSTANTRECTIME , tr ( " Setup.Recording$present event " ) ) ) ;
2009-01-24 15:24:19 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Recording$Max. video file size (MB) " ) , & data . MaxVideoFileSize , MINVIDEOFILESIZE , MAXVIDEOFILESIZETS ) ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Recording$Split edited files " ) , & data . SplitEditedFiles ) ) ;
2010-03-07 12:43:30 +01:00
Add ( new cMenuEditStraItem ( tr ( " Setup.Recording$Delete timeshift recording " ) , & data . DelTimeshiftRec , 3 , delTimeshiftRecTexts ) ) ;
2002-03-16 10:03:04 +01:00
}
// --- cMenuSetupReplay ------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupReplay : public cMenuSetupBase {
2005-09-25 11:35:56 +02:00
protected :
virtual void Store ( void ) ;
2002-03-16 10:03:04 +01:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupReplay ( void ) ;
2002-03-16 10:03:04 +01:00
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupReplay : : cMenuSetupReplay ( void )
2002-03-16 10:03:04 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupReplay ) ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " Replay " ) ) ;
2002-03-17 14:11:22 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Multi speed mode " ) , & data . MultiSpeedMode ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Show replay mode " ) , & data . ShowReplayMode ) ) ;
2012-01-14 13:20:16 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Show remaining time " ) , & data . ShowRemainingTime ) ) ;
2012-12-05 11:49:33 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Replay$Progress display time (s) " ) , & data . ProgressDisplayTime , 0 , 60 ) ) ;
2012-12-05 10:07:12 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Pause replay when setting mark " ) , & data . PauseOnMarkSet ) ) ;
2015-01-26 10:20:51 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Pause replay when jumping to a mark " ) , & data . PauseOnMarkJump ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Skip edited parts " ) , & data . SkipEdited ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Pause replay at last mark " ) , & data . PauseAtLastMark ) ) ;
2015-02-06 10:25:25 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Replay$Initial duration for adaptive skipping (s) " ) , & data . AdaptiveSkipInitial , 10 , 600 ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Replay$Reset timeout for adaptive skipping (s) " ) , & data . AdaptiveSkipTimeout , 0 , 10 ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Alternate behavior for adaptive skipping " ) , & data . AdaptiveSkipAlternate ) ) ;
2015-02-10 12:51:07 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Replay$Use Prev/Next keys for adaptive skipping " ) , & data . AdaptiveSkipPrevNext ) ) ;
2015-02-10 12:18:39 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Replay$Skip distance with Green/Yellow keys (s) " ) , & data . SkipSeconds , 5 , 600 ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Replay$Skip distance with Green/Yellow keys in repeat (s) " ) , & data . SkipSecondsRepeat , 5 , 600 ) ) ;
2003-04-12 10:06:21 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Replay$Resume ID " ) , & data . ResumeID , 0 , 99 ) ) ;
2002-03-16 10:03:04 +01:00
}
2005-09-25 11:35:56 +02:00
void cMenuSetupReplay : : Store ( void )
{
2015-09-01 11:14:27 +02:00
if ( Setup . ResumeID ! = data . ResumeID ) {
LOCK_RECORDINGS_WRITE ;
Recordings - > ResetResume ( ) ;
}
2005-09-25 11:35:56 +02:00
cMenuSetupBase : : Store ( ) ;
}
2002-03-16 10:03:04 +01:00
// --- cMenuSetupMisc --------------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupMisc : public cMenuSetupBase {
2015-09-08 11:08:06 +02:00
private :
2017-06-30 09:50:44 +02:00
const char * svdrpPeeringModeTexts [ 3 ] ;
2017-06-10 15:34:23 +02:00
const char * showChannelNamesWithSourceTexts [ 3 ] ;
2015-09-08 11:08:06 +02:00
cStringList svdrpServerNames ;
void Set ( void ) ;
2002-03-16 10:03:04 +01:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupMisc ( void ) ;
2015-09-08 11:08:06 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2002-03-16 10:03:04 +01:00
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupMisc : : cMenuSetupMisc ( void )
2002-03-16 10:03:04 +01:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupMisc ) ;
2017-06-30 09:50:44 +02:00
svdrpPeeringModeTexts [ 0 ] = tr ( " off " ) ;
svdrpPeeringModeTexts [ 1 ] = tr ( " any hosts " ) ;
svdrpPeeringModeTexts [ 2 ] = tr ( " only default host " ) ;
2017-06-10 15:34:23 +02:00
showChannelNamesWithSourceTexts [ 0 ] = tr ( " off " ) ;
showChannelNamesWithSourceTexts [ 1 ] = tr ( " type " ) ;
showChannelNamesWithSourceTexts [ 2 ] = tr ( " full " ) ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " Miscellaneous " ) ) ;
2015-09-08 11:08:06 +02:00
Set ( ) ;
}
void cMenuSetupMisc : : Set ( void )
{
int current = Current ( ) ;
Clear ( ) ;
2002-03-31 13:39:56 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Min. event timeout (min) " ) , & data . MinEventTimeout ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Min. user inactivity (min) " ) , & data . MinUserInactivity ) ) ;
2002-05-01 14:57:12 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$SVDRP timeout (s) " ) , & data . SVDRPTimeout ) ) ;
2017-06-30 09:50:44 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.Miscellaneous$SVDRP peering " ) , & data . SVDRPPeering , 3 , svdrpPeeringModeTexts ) ) ;
2015-09-08 11:08:06 +02:00
if ( data . SVDRPPeering ) {
Add ( new cMenuEditStrItem ( tr ( " Setup.Miscellaneous$SVDRP host name " ) , data . SVDRPHostName , sizeof ( data . SVDRPHostName ) ) ) ;
if ( GetSVDRPServerNames ( & svdrpServerNames ) ) {
svdrpServerNames . Sort ( true ) ;
2015-09-10 10:39:45 +02:00
svdrpServerNames . Insert ( strdup ( " " ) ) ;
2015-09-08 11:08:06 +02:00
Add ( new cMenuEditStrlItem ( tr ( " Setup.Miscellaneous$SVDRP default host " ) , data . SVDRPDefaultHost , sizeof ( data . SVDRPDefaultHost ) , & svdrpServerNames ) ) ;
}
}
2003-08-17 08:58:02 +02:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Zap timeout (s) " ) , & data . ZapTimeout ) ) ;
2007-02-25 14:14:06 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Channel entry timeout (ms) " ) , & data . ChannelEntryTimeout , 0 ) ) ;
2013-02-03 15:58:46 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Remote control repeat delay (ms) " ) , & data . RcRepeatDelay , 0 ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Remote control repeat delta (ms) " ) , & data . RcRepeatDelta , 0 ) ) ;
2006-04-09 13:26:56 +02:00
Add ( new cMenuEditChanItem ( tr ( " Setup.Miscellaneous$Initial channel " ) , & data . InitialChannel , tr ( " Setup.Miscellaneous$as before " ) ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Initial volume " ) , & data . InitialVolume , - 1 , 255 , tr ( " Setup.Miscellaneous$as before " ) ) ) ;
2015-01-12 14:56:42 +01:00
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Volume steps " ) , & data . VolumeSteps , 5 , 255 ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Setup.Miscellaneous$Volume linearize " ) , & data . VolumeLinearize , - 20 , 20 ) ) ;
2010-01-17 15:21:28 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Miscellaneous$Channels wrap " ) , & data . ChannelsWrap ) ) ;
2017-06-10 15:34:23 +02:00
Add ( new cMenuEditStraItem ( tr ( " Setup.Miscellaneous$Show channel names with source " ) , & data . ShowChannelNamesWithSource , 3 , showChannelNamesWithSourceTexts ) ) ;
2007-11-25 14:20:03 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Setup.Miscellaneous$Emergency exit " ) , & data . EmergencyExit ) ) ;
2015-09-08 11:08:06 +02:00
SetCurrent ( Get ( current ) ) ;
Display ( ) ;
}
eOSState cMenuSetupMisc : : ProcessKey ( eKeys Key )
{
bool OldSVDRPPeering = data . SVDRPPeering ;
bool ModifiedSVDRPSettings = false ;
if ( Key = = kOk )
2018-01-26 14:34:31 +01:00
ModifiedSVDRPSettings = data . SVDRPPeering ! = Setup . SVDRPPeering | | strcmp ( data . SVDRPHostName , Setup . SVDRPHostName ) ;
2015-09-08 11:08:06 +02:00
eOSState state = cMenuSetupBase : : ProcessKey ( Key ) ;
if ( data . SVDRPPeering ! = OldSVDRPPeering )
Set ( ) ;
if ( ModifiedSVDRPSettings ) {
2018-02-25 13:57:21 +01:00
StopSVDRPHandler ( ) ;
{
LOCK_TIMERS_WRITE ;
Timers - > SetExplicitModify ( ) ;
if ( Timers - > StoreRemoteTimers ( NULL , NULL ) )
Timers - > SetModified ( ) ;
}
StartSVDRPHandler ( ) ;
2015-09-08 11:08:06 +02:00
}
return state ;
2002-03-16 10:03:04 +01:00
}
2002-05-09 16:26:56 +02:00
// --- cMenuSetupPluginItem --------------------------------------------------
class cMenuSetupPluginItem : public cOsdItem {
private :
int pluginIndex ;
public :
cMenuSetupPluginItem ( const char * Name , int Index ) ;
int PluginIndex ( void ) { return pluginIndex ; }
} ;
cMenuSetupPluginItem : : cMenuSetupPluginItem ( const char * Name , int Index )
: cOsdItem ( Name )
{
pluginIndex = Index ;
}
// --- cMenuSetupPlugins -----------------------------------------------------
2002-05-11 13:44:58 +02:00
class cMenuSetupPlugins : public cMenuSetupBase {
2002-05-09 16:26:56 +02:00
public :
2002-05-11 13:44:58 +02:00
cMenuSetupPlugins ( void ) ;
2002-05-09 16:26:56 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
2002-05-11 13:44:58 +02:00
cMenuSetupPlugins : : cMenuSetupPlugins ( void )
2002-05-09 16:26:56 +02:00
{
Added the new menu categories mcChannelEdit, mcTimerEdit, mcScheduleNow, mcScheduleNext, mcRecordingInfo, mcPluginSetup, mcSetupOsd, mcSetupEpg, mcSetupDvb, mcSetupLnb, mcSetupCam, mcSetupRecord, mcSetupReplay, mcSetupMisc and mcSetupPlugins
2012-12-21 11:22:26 +01:00
SetMenuCategory ( mcSetupPlugins ) ;
2002-05-11 13:44:58 +02:00
SetSection ( tr ( " Plugins " ) ) ;
2002-05-09 16:26:56 +02:00
SetHasHotkeys ( ) ;
for ( int i = 0 ; ; i + + ) {
cPlugin * p = cPluginManager : : GetPlugin ( i ) ;
2008-02-15 14:57:48 +01:00
if ( p )
Add ( new cMenuSetupPluginItem ( hk ( cString : : sprintf ( " %s (%s) - %s " , p - > Name ( ) , p - > Version ( ) , p - > Description ( ) ) ) , i ) ) ;
2002-05-09 16:26:56 +02:00
else
break ;
}
}
eOSState cMenuSetupPlugins : : ProcessKey ( eKeys Key )
{
2002-05-11 13:44:58 +02:00
eOSState state = HasSubMenu ( ) ? cMenuSetupBase : : ProcessKey ( Key ) : cOsdMenu : : ProcessKey ( Key ) ;
if ( Key = = kOk ) {
if ( state = = osUnknown ) {
cMenuSetupPluginItem * item = ( cMenuSetupPluginItem * ) Get ( Current ( ) ) ;
if ( item ) {
cPlugin * p = cPluginManager : : GetPlugin ( item - > PluginIndex ( ) ) ;
if ( p ) {
cMenuSetupPage * menu = p - > SetupMenu ( ) ;
if ( menu ) {
menu - > SetPlugin ( p ) ;
return AddSubMenu ( menu ) ;
}
2004-05-16 10:35:36 +02:00
Skins . Message ( mtInfo , tr ( " This plugin has no setup parameters! " ) ) ;
2002-05-11 13:44:58 +02:00
}
}
}
2012-04-24 09:19:48 +02:00
else if ( state = = osContinue ) {
2002-05-11 13:44:58 +02:00
Store ( ) ;
2012-04-24 09:19:48 +02:00
// Reinitialize OSD and skin, in case any plugin setup change has an influence on these:
cOsdProvider : : UpdateOsdSize ( true ) ;
Display ( ) ;
}
2002-05-09 16:26:56 +02:00
}
return state ;
}
2002-03-16 10:03:04 +01:00
// --- cMenuSetup ------------------------------------------------------------
class cMenuSetup : public cOsdMenu {
private :
virtual void Set ( void ) ;
2002-03-17 12:04:35 +01:00
eOSState Restart ( void ) ;
2002-03-16 10:03:04 +01:00
public :
cMenuSetup ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuSetup : : cMenuSetup ( void )
: cOsdMenu ( " " )
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcSetup ) ;
2002-03-16 10:03:04 +01:00
Set ( ) ;
}
void cMenuSetup : : Set ( void )
{
Clear ( ) ;
2002-05-09 16:26:56 +02:00
char buffer [ 64 ] ;
snprintf ( buffer , sizeof ( buffer ) , " %s - VDR %s " , tr ( " Setup " ) , VDRVERSION ) ;
SetTitle ( buffer ) ;
2002-03-16 10:03:04 +01:00
SetHasHotkeys ( ) ;
Add ( new cOsdItem ( hk ( tr ( " OSD " ) ) , osUser1 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " EPG " ) ) , osUser2 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " DVB " ) ) , osUser3 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " LNB " ) ) , osUser4 ) ) ;
2007-01-07 14:46:14 +01:00
Add ( new cOsdItem ( hk ( tr ( " CAM " ) ) , osUser5 ) ) ;
2002-03-16 10:03:04 +01:00
Add ( new cOsdItem ( hk ( tr ( " Recording " ) ) , osUser6 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " Replay " ) ) , osUser7 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " Miscellaneous " ) ) , osUser8 ) ) ;
2002-05-09 16:26:56 +02:00
if ( cPluginManager : : HasPlugins ( ) )
Add ( new cOsdItem ( hk ( tr ( " Plugins " ) ) , osUser9 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " Restart " ) ) , osUser10 ) ) ;
2002-03-17 12:04:35 +01:00
}
eOSState cMenuSetup : : Restart ( void )
{
2007-02-25 10:56:29 +01:00
if ( Interface - > Confirm ( tr ( " Really restart? " ) ) & & ShutdownHandler . ConfirmRestart ( true ) ) {
ShutdownHandler . Exit ( 1 ) ;
2002-03-17 12:04:35 +01:00
return osEnd ;
}
return osContinue ;
2000-09-10 10:51:58 +02:00
}
eOSState cMenuSetup : : ProcessKey ( eKeys Key )
{
2007-08-11 12:39:06 +02:00
int osdLanguage = I18nCurrentLanguage ( ) ;
2000-09-10 10:51:58 +02:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2002-03-16 10:03:04 +01:00
switch ( state ) {
case osUser1 : return AddSubMenu ( new cMenuSetupOSD ) ;
case osUser2 : return AddSubMenu ( new cMenuSetupEPG ) ;
case osUser3 : return AddSubMenu ( new cMenuSetupDVB ) ;
case osUser4 : return AddSubMenu ( new cMenuSetupLNB ) ;
2007-01-07 14:46:14 +01:00
case osUser5 : return AddSubMenu ( new cMenuSetupCAM ) ;
2002-03-16 10:03:04 +01:00
case osUser6 : return AddSubMenu ( new cMenuSetupRecord ) ;
case osUser7 : return AddSubMenu ( new cMenuSetupReplay ) ;
case osUser8 : return AddSubMenu ( new cMenuSetupMisc ) ;
2002-05-09 16:26:56 +02:00
case osUser9 : return AddSubMenu ( new cMenuSetupPlugins ) ;
case osUser10 : return Restart ( ) ;
2002-03-16 10:03:04 +01:00
default : ;
}
2007-08-11 12:39:06 +02:00
if ( I18nCurrentLanguage ( ) ! = osdLanguage ) {
2000-11-11 10:39:27 +01:00
Set ( ) ;
2002-03-16 10:03:04 +01:00
if ( ! HasSubMenu ( ) )
Display ( ) ;
2000-11-11 10:39:27 +01:00
}
2000-09-10 10:51:58 +02:00
return state ;
}
2002-05-09 16:26:56 +02:00
// --- cMenuPluginItem -------------------------------------------------------
class cMenuPluginItem : public cOsdItem {
private :
int pluginIndex ;
public :
cMenuPluginItem ( const char * Name , int Index ) ;
int PluginIndex ( void ) { return pluginIndex ; }
} ;
cMenuPluginItem : : cMenuPluginItem ( const char * Name , int Index )
: cOsdItem ( Name , osPlugin )
{
pluginIndex = Index ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuMain -------------------------------------------------------------
2007-08-11 12:39:06 +02:00
// TRANSLATORS: note the leading and trailing blanks!
# define STOP_RECORDING trNOOP(" Stop recording ")
2000-05-01 16:29:46 +02:00
2002-11-24 10:45:39 +01:00
cOsdObject * cMenuMain : : pluginOsdObject = NULL ;
2013-10-16 09:43:47 +02:00
cMenuMain : : cMenuMain ( eOSState State , bool OpenSubMenus )
2002-03-16 10:03:04 +01:00
: cOsdMenu ( " " )
2000-02-19 13:36:48 +01:00
{
2012-04-08 11:52:56 +02:00
SetMenuCategory ( mcMain ) ;
2005-12-24 15:53:53 +01:00
replaying = false ;
stopReplayItem = NULL ;
cancelEditingItem = NULL ;
stopRecordingItem = NULL ;
recordControlsState = 0 ;
2005-09-03 11:33:43 +02:00
Set ( ) ;
2002-03-16 10:03:04 +01:00
// Initial submenus:
switch ( State ) {
2002-10-27 14:32:06 +01:00
case osSchedule : AddSubMenu ( new cMenuSchedule ) ; break ;
case osChannels : AddSubMenu ( new cMenuChannels ) ; break ;
case osTimers : AddSubMenu ( new cMenuTimers ) ; break ;
2013-10-16 09:43:47 +02:00
case osRecordings : AddSubMenu ( new cMenuRecordings ( NULL , 0 , OpenSubMenus ) ) ; break ;
2002-10-27 14:32:06 +01:00
case osSetup : AddSubMenu ( new cMenuSetup ) ; break ;
case osCommands : AddSubMenu ( new cMenuCommands ( tr ( " Commands " ) , & Commands ) ) ; break ;
2002-03-16 10:03:04 +01:00
default : break ;
}
}
2002-11-24 10:45:39 +01:00
cOsdObject * cMenuMain : : PluginOsdObject ( void )
{
cOsdObject * o = pluginOsdObject ;
pluginOsdObject = NULL ;
return o ;
}
2005-09-03 11:33:43 +02:00
void cMenuMain : : Set ( void )
2002-03-16 10:03:04 +01:00
{
Clear ( ) ;
2005-12-24 15:53:53 +01:00
SetTitle ( " VDR " ) ;
2002-03-16 10:03:04 +01:00
SetHasHotkeys ( ) ;
2001-10-28 16:32:34 +01:00
// Basic menu items:
2001-08-03 14:18:08 +02:00
Add ( new cOsdItem ( hk ( tr ( " Schedule " ) ) , osSchedule ) ) ;
Add ( new cOsdItem ( hk ( tr ( " Channels " ) ) , osChannels ) ) ;
Add ( new cOsdItem ( hk ( tr ( " Timers " ) ) , osTimers ) ) ;
Add ( new cOsdItem ( hk ( tr ( " Recordings " ) ) , osRecordings ) ) ;
2002-05-09 16:26:56 +02:00
// Plugins:
for ( int i = 0 ; ; i + + ) {
cPlugin * p = cPluginManager : : GetPlugin ( i ) ;
if ( p ) {
const char * item = p - > MainMenuEntry ( ) ;
if ( item )
2005-09-03 11:33:43 +02:00
Add ( new cMenuPluginItem ( hk ( item ) , i ) ) ;
2002-05-09 16:26:56 +02:00
}
else
break ;
}
// More basic menu items:
2001-08-03 14:18:08 +02:00
Add ( new cOsdItem ( hk ( tr ( " Setup " ) ) , osSetup ) ) ;
2000-11-11 16:38:41 +01:00
if ( Commands . Count ( ) )
2001-08-03 14:18:08 +02:00
Add ( new cOsdItem ( hk ( tr ( " Commands " ) ) , osCommands ) ) ;
2001-10-28 16:32:34 +01:00
2005-12-24 15:53:53 +01:00
Update ( true ) ;
Display ( ) ;
}
bool cMenuMain : : Update ( bool Force )
{
bool result = false ;
2020-05-18 16:47:29 +02:00
bool NewReplaying = false ;
{
cMutexLock ControlMutexLock ;
NewReplaying = cControl : : Control ( ControlMutexLock ) ! = NULL ;
}
2005-12-24 15:53:53 +01:00
if ( Force | | NewReplaying ! = replaying ) {
replaying = NewReplaying ;
// Replay control:
if ( replaying & & ! stopReplayItem )
2007-08-11 12:39:06 +02:00
// TRANSLATORS: note the leading blank!
2005-12-24 15:53:53 +01:00
Add ( stopReplayItem = new cOsdItem ( tr ( " Stop replaying " ) , osStopReplay ) ) ;
else if ( stopReplayItem & & ! replaying ) {
Del ( stopReplayItem - > Index ( ) ) ;
stopReplayItem = NULL ;
2000-05-01 16:29:46 +02:00
}
2005-12-24 15:53:53 +01:00
// Color buttons:
2015-09-11 08:29:41 +02:00
SetHelp ( ! replaying & & Setup . RecordKeyHandling ? tr ( " Button$Record " ) : NULL , tr ( " Button$Audio " ) , replaying | | ! Setup . PauseKeyHandling ? NULL : tr ( " Button$Pause " ) , replaying ? tr ( " Button$Stop " ) : cReplayControl : : LastReplayed ( ) ? tr ( " Button$Resume " ) : tr ( " Button$Play " ) ) ;
2005-12-24 15:53:53 +01:00
result = true ;
}
2001-10-28 16:32:34 +01:00
// Editing control:
2013-10-10 13:13:30 +02:00
bool EditingActive = RecordingsHandler . Active ( ) ;
if ( EditingActive & & ! cancelEditingItem ) {
2007-08-11 12:39:06 +02:00
// TRANSLATORS: note the leading blank!
2005-12-24 15:53:53 +01:00
Add ( cancelEditingItem = new cOsdItem ( tr ( " Cancel editing " ) , osCancelEdit ) ) ;
result = true ;
}
2013-10-10 13:13:30 +02:00
else if ( cancelEditingItem & & ! EditingActive ) {
2005-12-24 15:53:53 +01:00
Del ( cancelEditingItem - > Index ( ) ) ;
cancelEditingItem = NULL ;
result = true ;
}
2001-10-28 16:32:34 +01:00
2005-12-24 15:53:53 +01:00
// Record control:
if ( cRecordControls : : StateChanged ( recordControlsState ) ) {
while ( stopRecordingItem ) {
cOsdItem * it = Next ( stopRecordingItem ) ;
Del ( stopRecordingItem - > Index ( ) ) ;
stopRecordingItem = it ;
}
const char * s = NULL ;
while ( ( s = cRecordControls : : GetInstantId ( s ) ) ! = NULL ) {
cOsdItem * item = new cOsdItem ( osStopRecord ) ;
2008-02-15 14:57:48 +01:00
item - > SetText ( cString : : sprintf ( " %s%s " , tr ( STOP_RECORDING ) , s ) ) ;
2005-12-24 15:53:53 +01:00
Add ( item ) ;
if ( ! stopRecordingItem )
stopRecordingItem = item ;
}
result = true ;
}
2001-10-28 16:32:34 +01:00
2005-12-24 15:53:53 +01:00
return result ;
2001-08-03 14:18:08 +02:00
}
2000-03-11 11:22:37 +01:00
eOSState cMenuMain : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
2003-04-26 13:53:50 +02:00
bool HadSubMenu = HasSubMenu ( ) ;
2007-08-11 12:39:06 +02:00
int osdLanguage = I18nCurrentLanguage ( ) ;
2000-03-11 11:22:37 +01:00
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
2003-04-26 13:53:50 +02:00
HadSubMenu | = HasSubMenu ( ) ;
2000-02-19 13:36:48 +01:00
2000-03-11 11:22:37 +01:00
switch ( state ) {
2000-10-29 13:17:22 +01:00
case osSchedule : return AddSubMenu ( new cMenuSchedule ) ;
2000-03-11 11:22:37 +01:00
case osChannels : return AddSubMenu ( new cMenuChannels ) ;
2000-11-11 10:39:27 +01:00
case osTimers : return AddSubMenu ( new cMenuTimers ) ;
2000-03-11 11:22:37 +01:00
case osRecordings : return AddSubMenu ( new cMenuRecordings ) ;
2000-09-10 10:51:58 +02:00
case osSetup : return AddSubMenu ( new cMenuSetup ) ;
2002-10-13 12:14:49 +02:00
case osCommands : return AddSubMenu ( new cMenuCommands ( tr ( " Commands " ) , & Commands ) ) ;
2000-12-28 12:57:16 +01:00
case osStopRecord : if ( Interface - > Confirm ( tr ( " Stop recording? " ) ) ) {
2015-09-01 11:14:27 +02:00
if ( cOsdItem * item = Get ( Current ( ) ) ) {
2007-08-11 12:39:06 +02:00
cRecordControls : : Stop ( item - > Text ( ) + strlen ( tr ( STOP_RECORDING ) ) ) ;
2000-05-01 16:29:46 +02:00
return osEnd ;
}
}
2000-12-28 12:57:16 +01:00
break ;
case osCancelEdit : if ( Interface - > Confirm ( tr ( " Cancel editing? " ) ) ) {
2013-10-10 13:13:30 +02:00
RecordingsHandler . DelAll ( ) ;
2000-12-28 12:57:16 +01:00
return osEnd ;
}
break ;
2002-05-09 16:26:56 +02:00
case osPlugin : {
cMenuPluginItem * item = ( cMenuPluginItem * ) Get ( Current ( ) ) ;
if ( item ) {
cPlugin * p = cPluginManager : : GetPlugin ( item - > PluginIndex ( ) ) ;
if ( p ) {
2002-11-24 10:45:39 +01:00
cOsdObject * menu = p - > MainMenuAction ( ) ;
if ( menu ) {
if ( menu - > IsMenu ( ) )
return AddSubMenu ( ( cOsdMenu * ) menu ) ;
else {
pluginOsdObject = menu ;
return osPlugin ;
}
}
2002-05-09 16:26:56 +02:00
}
}
state = osEnd ;
}
break ;
2000-05-27 16:10:47 +02:00
default : switch ( Key ) {
2002-10-27 14:32:06 +01:00
case kRecord :
2003-04-26 13:53:50 +02:00
case kRed : if ( ! HadSubMenu )
2015-09-11 08:29:41 +02:00
state = replaying | | ! Setup . RecordKeyHandling ? osContinue : osRecord ;
2001-08-03 14:18:08 +02:00
break ;
2003-04-26 13:53:50 +02:00
case kGreen : if ( ! HadSubMenu ) {
2005-01-23 19:27:43 +01:00
cRemote : : Put ( kAudio , true ) ;
state = osEnd ;
2001-08-03 14:18:08 +02:00
}
break ;
2003-04-26 13:53:50 +02:00
case kYellow : if ( ! HadSubMenu )
2013-09-07 12:52:14 +02:00
state = replaying | | ! Setup . PauseKeyHandling ? osContinue : osPause ;
2003-04-21 14:57:13 +02:00
break ;
2003-04-26 13:53:50 +02:00
case kBlue : if ( ! HadSubMenu )
2012-10-03 10:18:58 +02:00
state = replaying ? osStopReplay : cReplayControl : : LastReplayed ( ) ? osReplay : osRecordings ;
2001-08-03 14:18:08 +02:00
break ;
default : break ;
2000-05-27 16:10:47 +02:00
}
2000-02-19 13:36:48 +01:00
}
2005-12-26 15:44:27 +01:00
if ( ! HasSubMenu ( ) & & Update ( HadSubMenu ) )
2005-12-24 15:53:53 +01:00
Display ( ) ;
2002-03-16 10:03:04 +01:00
if ( Key ! = kNone ) {
2007-08-11 12:39:06 +02:00
if ( I18nCurrentLanguage ( ) ! = osdLanguage ) {
2002-03-16 10:03:04 +01:00
Set ( ) ;
if ( ! HasSubMenu ( ) )
Display ( ) ;
}
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
2005-01-08 10:15:30 +01:00
// --- SetTrackDescriptions --------------------------------------------------
2006-01-29 11:15:08 +01:00
static void SetTrackDescriptions ( int LiveChannel )
2005-01-08 10:15:30 +01:00
{
cDevice : : PrimaryDevice ( ) - > ClrAvailableTracks ( true ) ;
2005-05-16 14:45:11 +02:00
const cComponents * Components = NULL ;
2006-01-29 11:15:08 +01:00
if ( LiveChannel ) {
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
if ( const cChannel * Channel = Channels - > GetByNumber ( LiveChannel ) ) {
LOCK_SCHEDULES_READ ;
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( Channel ) ) {
const cEvent * Present = Schedule - > GetPresentEvent ( ) ;
if ( Present )
Components = Present - > Components ( ) ;
2005-01-08 10:15:30 +01:00
}
}
}
2006-10-20 13:42:14 +02:00
else if ( cReplayControl : : NowReplaying ( ) ) {
2015-09-01 11:14:27 +02:00
LOCK_RECORDINGS_READ ;
if ( const cRecording * Recording = Recordings - > GetByName ( cReplayControl : : NowReplaying ( ) ) )
2005-05-16 14:45:11 +02:00
Components = Recording - > Info ( ) - > Components ( ) ;
}
if ( Components ) {
int indexAudio = 0 ;
int indexDolby = 0 ;
2007-10-12 14:52:30 +02:00
int indexSubtitle = 0 ;
2005-05-16 14:45:11 +02:00
for ( int i = 0 ; i < Components - > NumComponents ( ) ; i + + ) {
const tComponent * p = Components - > Component ( i ) ;
2007-10-12 14:52:30 +02:00
switch ( p - > stream ) {
case 2 : if ( p - > type = = 0x05 )
cDevice : : PrimaryDevice ( ) - > SetAvailableTrack ( ttDolby , indexDolby + + , 0 , LiveChannel ? NULL : p - > language , p - > description ) ;
else
cDevice : : PrimaryDevice ( ) - > SetAvailableTrack ( ttAudio , indexAudio + + , 0 , LiveChannel ? NULL : p - > language , p - > description ) ;
break ;
case 3 : cDevice : : PrimaryDevice ( ) - > SetAvailableTrack ( ttSubtitle , indexSubtitle + + , 0 , LiveChannel ? NULL : p - > language , p - > description ) ;
break ;
2008-05-01 15:41:04 +02:00
case 4 : cDevice : : PrimaryDevice ( ) - > SetAvailableTrack ( ttDolby , indexDolby + + , 0 , LiveChannel ? NULL : p - > language , p - > description ) ;
break ;
2009-12-06 12:57:45 +01:00
default : ;
2007-10-12 14:52:30 +02:00
}
2005-05-16 14:45:11 +02:00
}
}
2005-01-08 10:15:30 +01:00
}
2000-11-01 15:41:33 +01:00
// --- cDisplayChannel -------------------------------------------------------
2000-09-10 14:56:18 +02:00
2006-01-22 14:27:53 +01:00
cDisplayChannel * cDisplayChannel : : currentDisplayChannel = NULL ;
2001-09-08 14:39:09 +02:00
cDisplayChannel : : cDisplayChannel ( int Number , bool Switched )
2002-05-18 12:41:18 +02:00
: cOsdObject ( true )
2000-11-01 15:41:33 +01:00
{
2006-01-22 14:27:53 +01:00
currentDisplayChannel = this ;
2001-09-08 14:39:09 +02:00
group = - 1 ;
withInfo = ! Switched | | Setup . ShowInfoOnChSwitch ;
2004-05-16 10:35:36 +02:00
displayChannel = Skins . Current ( ) - > DisplayChannel ( withInfo ) ;
2002-09-29 13:40:45 +02:00
number = 0 ;
2006-01-04 14:45:23 +01:00
timeout = Switched | | Setup . TimeoutRequChInfo ;
2015-01-15 11:33:58 +01:00
cOsdProvider : : OsdSizeChanged ( osdState ) ; // just to get the current state
2013-08-21 11:02:52 +02:00
positioner = NULL ;
2015-09-01 11:14:27 +02:00
channel = NULL ;
2018-05-06 09:41:03 +02:00
{
LOCK_CHANNELS_READ ;
channel = Channels - > GetByNumber ( Number ) ;
lastPresent = lastFollowing = NULL ;
if ( channel ) {
DisplayChannel ( ) ;
DisplayInfo ( ) ;
}
}
if ( channel )
2004-05-16 10:35:36 +02:00
displayChannel - > Flush ( ) ;
2006-01-22 14:49:54 +01:00
lastTime . Set ( ) ;
2000-11-01 15:41:33 +01:00
}
cDisplayChannel : : cDisplayChannel ( eKeys FirstKey )
2002-05-18 12:41:18 +02:00
: cOsdObject ( true )
2000-09-10 14:56:18 +02:00
{
2006-01-22 14:27:53 +01:00
currentDisplayChannel = this ;
2001-09-08 14:39:09 +02:00
group = - 1 ;
2000-09-10 14:56:18 +02:00
number = 0 ;
2006-01-22 14:27:53 +01:00
timeout = true ;
2004-05-16 10:35:36 +02:00
lastPresent = lastFollowing = NULL ;
2018-04-09 09:21:27 +02:00
cOsdProvider : : OsdSizeChanged ( osdState ) ; // just to get the current state
2006-01-22 14:49:54 +01:00
lastTime . Set ( ) ;
2003-05-29 11:45:13 +02:00
withInfo = Setup . ShowInfoOnChSwitch ;
2004-05-16 10:35:36 +02:00
displayChannel = Skins . Current ( ) - > DisplayChannel ( withInfo ) ;
2013-08-21 11:02:52 +02:00
positioner = NULL ;
2015-09-01 11:14:27 +02:00
channel = NULL ;
2018-05-27 09:55:30 +02:00
{
LOCK_CHANNELS_READ ;
channel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) ;
}
2000-09-10 14:56:18 +02:00
ProcessKey ( FirstKey ) ;
}
2000-11-01 15:41:33 +01:00
cDisplayChannel : : ~ cDisplayChannel ( )
2000-09-10 14:56:18 +02:00
{
2004-05-16 10:35:36 +02:00
delete displayChannel ;
2006-01-22 14:27:53 +01:00
currentDisplayChannel = NULL ;
2020-07-01 15:05:17 +02:00
cStatus : : MsgOsdClear ( ) ;
2000-09-10 14:56:18 +02:00
}
2003-12-22 13:29:24 +01:00
void cDisplayChannel : : DisplayChannel ( void )
2000-11-01 15:41:33 +01:00
{
2004-05-16 10:35:36 +02:00
displayChannel - > SetChannel ( channel , number ) ;
cStatus : : MsgOsdChannel ( ChannelString ( channel , number ) ) ;
lastPresent = lastFollowing = NULL ;
2017-11-02 15:36:24 +01:00
lastTime . Set ( ) ;
2000-11-01 15:41:33 +01:00
}
void cDisplayChannel : : DisplayInfo ( void )
{
2003-12-22 13:29:24 +01:00
if ( withInfo & & channel ) {
2015-09-01 11:14:27 +02:00
LOCK_SCHEDULES_READ ;
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( channel ) ) {
const cEvent * Present = Schedule - > GetPresentEvent ( ) ;
const cEvent * Following = Schedule - > GetFollowingEvent ( ) ;
if ( Present ! = lastPresent | | Following ! = lastFollowing ) {
SetTrackDescriptions ( channel - > Number ( ) ) ;
displayChannel - > SetEvents ( Present , Following ) ;
cStatus : : MsgOsdProgramme ( Present ? Present - > StartTime ( ) : 0 , Present ? Present - > Title ( ) : NULL , Present ? Present - > ShortText ( ) : NULL , Following ? Following - > StartTime ( ) : 0 , Following ? Following - > Title ( ) : NULL , Following ? Following - > ShortText ( ) : NULL ) ;
lastPresent = Present ;
lastFollowing = Following ;
2017-11-02 15:36:24 +01:00
lastTime . Set ( ) ;
2000-11-01 15:41:33 +01:00
}
}
}
}
2002-10-27 14:32:06 +01:00
void cDisplayChannel : : Refresh ( void )
{
2003-12-22 13:29:24 +01:00
DisplayChannel ( ) ;
2004-05-16 10:35:36 +02:00
displayChannel - > SetEvents ( NULL , NULL ) ;
2006-01-22 14:27:53 +01:00
}
2015-09-01 11:14:27 +02:00
const cChannel * cDisplayChannel : : NextAvailableChannel ( const cChannel * Channel , int Direction )
2006-01-22 14:27:53 +01:00
{
if ( Direction ) {
2018-07-16 09:33:21 +02:00
cControl : : Shutdown ( ) ; // prevents old channel from being shown too long if GetDevice() takes longer
2020-09-16 13:48:33 +02:00
// and, if decrypted, this removes the now superfluous PIDs from the CAM, too
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
2006-01-22 14:27:53 +01:00
while ( Channel ) {
2015-09-01 11:14:27 +02:00
Channel = Direction > 0 ? Channels - > Next ( Channel ) : Channels - > Prev ( Channel ) ;
2010-01-17 15:21:28 +01:00
if ( ! Channel & & Setup . ChannelsWrap )
2015-09-01 11:14:27 +02:00
Channel = Direction > 0 ? Channels - > First ( ) : Channels - > Last ( ) ;
2012-03-02 10:43:26 +01:00
if ( Channel & & ! Channel - > GroupSep ( ) & & cDevice : : GetDevice ( Channel , LIVEPRIORITY , true , true ) )
2006-01-22 14:27:53 +01:00
return Channel ;
}
}
return NULL ;
2002-10-27 14:32:06 +01:00
}
2000-11-01 15:41:33 +01:00
eOSState cDisplayChannel : : ProcessKey ( eKeys Key )
2000-09-10 14:56:18 +02:00
{
2015-01-15 11:33:58 +01:00
if ( cOsdProvider : : OsdSizeChanged ( osdState ) ) {
delete displayChannel ;
displayChannel = Skins . Current ( ) - > DisplayChannel ( withInfo ) ;
}
2015-09-01 11:14:27 +02:00
const cChannel * NewChannel = NULL ;
2006-01-22 14:27:53 +01:00
if ( Key ! = kNone )
lastTime . Set ( ) ;
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2000-11-01 15:41:33 +01:00
case k0 :
if ( number = = 0 ) {
// keep the "Toggle channels" function working
2002-09-29 13:40:45 +02:00
cRemote : : Put ( Key ) ;
2000-11-01 15:41:33 +01:00
return osEnd ;
}
case k1 . . . k9 :
2006-07-23 09:26:50 +02:00
group = - 1 ;
2000-09-10 14:56:18 +02:00
if ( number > = 0 ) {
2015-09-01 11:14:27 +02:00
if ( number > cChannels : : MaxNumber ( ) )
2006-02-18 12:47:01 +01:00
number = Key - k0 ;
else
number = number * 10 + Key - k0 ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ
channel = Channels - > GetByNumber ( number ) ;
2006-02-24 14:56:18 +01:00
Refresh ( ) ;
2006-01-22 14:27:53 +01:00
withInfo = false ;
// Lets see if there can be any useful further input:
int n = channel ? number * 10 : 0 ;
2006-01-22 14:38:54 +01:00
int m = 10 ;
2015-09-01 11:14:27 +02:00
const cChannel * ch = channel ;
while ( ch & & ( ch = Channels - > Next ( ch ) ) ! = NULL ) {
2006-01-22 14:27:53 +01:00
if ( ! ch - > GroupSep ( ) ) {
2006-01-22 14:38:54 +01:00
if ( n < = ch - > Number ( ) & & ch - > Number ( ) < n + m ) {
2006-01-22 14:27:53 +01:00
n = 0 ;
break ;
2003-06-13 14:44:31 +02:00
}
2006-01-22 14:38:54 +01:00
if ( ch - > Number ( ) > n ) {
2006-01-22 14:27:53 +01:00
n * = 10 ;
2006-01-22 14:38:54 +01:00
m * = 10 ;
}
2003-06-13 14:44:31 +02:00
}
}
2006-01-22 14:27:53 +01:00
if ( n > 0 ) {
// This channel is the only one that fits the input, so let's take it right away:
NewChannel = channel ;
withInfo = true ;
number = 0 ;
2006-02-24 14:55:20 +01:00
Refresh ( ) ;
2000-09-10 14:56:18 +02:00
}
}
break ;
2001-10-27 13:48:20 +02:00
case kLeft | k_Repeat :
2001-09-08 14:39:09 +02:00
case kLeft :
2001-10-27 13:48:20 +02:00
case kRight | k_Repeat :
2001-09-08 14:39:09 +02:00
case kRight :
2006-04-15 13:46:55 +02:00
case kNext | k_Repeat :
case kNext :
case kPrev | k_Repeat :
2015-09-01 11:14:27 +02:00
case kPrev : {
2001-09-08 14:39:09 +02:00
withInfo = false ;
2005-08-14 15:03:31 +02:00
number = 0 ;
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
2001-09-08 14:39:09 +02:00
if ( group < 0 ) {
2015-09-01 11:14:27 +02:00
if ( const cChannel * Channel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) )
group = Channel - > Index ( ) ;
2001-09-08 14:39:09 +02:00
}
if ( group > = 0 ) {
int SaveGroup = group ;
2006-04-15 13:46:55 +02:00
if ( NORMALKEY ( Key ) = = kRight | | NORMALKEY ( Key ) = = kNext )
2015-09-01 11:14:27 +02:00
group = Channels - > GetNextGroup ( group ) ;
2001-09-08 14:39:09 +02:00
else
2015-09-01 11:14:27 +02:00
group = Channels - > GetPrevGroup ( group < 1 ? 1 : group ) ;
2001-09-08 14:39:09 +02:00
if ( group < 0 )
group = SaveGroup ;
2015-09-01 11:14:27 +02:00
channel = Channels - > Get ( group ) ;
2001-09-08 14:39:09 +02:00
if ( channel ) {
2006-02-24 14:56:18 +01:00
Refresh ( ) ;
2002-10-06 10:25:42 +02:00
if ( ! channel - > GroupSep ( ) )
2001-09-08 14:39:09 +02:00
group = - 1 ;
}
}
break ;
2015-09-01 11:14:27 +02:00
}
2002-10-27 14:32:06 +01:00
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
case kChanUp | k_Repeat :
case kChanUp :
case kChanDn | k_Repeat :
2006-01-22 14:27:53 +01:00
case kChanDn : {
eKeys k = NORMALKEY ( Key ) ;
2015-09-01 11:14:27 +02:00
if ( const cChannel * Channel = NextAvailableChannel ( channel , ( k = = kUp | | k = = kChanUp ) ? 1 : - 1 ) )
channel = Channel ;
2006-01-28 12:43:26 +01:00
else if ( channel & & channel - > Number ( ) ! = cDevice : : CurrentChannel ( ) )
Key = k ; // immediately switches channel when hitting the beginning/end of the channel list with k_Repeat
2006-01-22 14:27:53 +01:00
}
// no break here
case kUp | k_Release :
case kDown | k_Release :
case kChanUp | k_Release :
case kChanDn | k_Release :
2006-04-15 13:46:55 +02:00
case kNext | k_Release :
case kPrev | k_Release :
2006-01-28 12:43:26 +01:00
if ( ! ( Key & k_Repeat ) & & channel & & channel - > Number ( ) ! = cDevice : : CurrentChannel ( ) )
2006-01-22 14:27:53 +01:00
NewChannel = channel ;
2003-10-03 14:38:49 +02:00
withInfo = true ;
2003-06-12 20:37:14 +02:00
group = - 1 ;
2005-08-14 15:03:31 +02:00
number = 0 ;
2002-10-27 14:32:06 +01:00
Refresh ( ) ;
break ;
2000-09-10 14:56:18 +02:00
case kNone :
2007-02-25 14:14:06 +01:00
if ( number & & Setup . ChannelEntryTimeout & & int ( lastTime . Elapsed ( ) ) > Setup . ChannelEntryTimeout ) {
2015-09-01 11:14:27 +02:00
LOCK_CHANNELS_READ ;
channel = Channels - > GetByNumber ( number ) ;
2006-01-22 14:27:53 +01:00
if ( channel )
NewChannel = channel ;
withInfo = true ;
number = 0 ;
Refresh ( ) ;
lastTime . Set ( ) ;
2000-09-10 14:56:18 +02:00
}
2000-11-01 15:41:33 +01:00
break ;
//TODO
//XXX case kGreen: return osEventNow;
//XXX case kYellow: return osEventNext;
2015-09-01 11:14:27 +02:00
case kOk : {
LOCK_CHANNELS_READ ;
2006-01-22 14:27:53 +01:00
if ( group > = 0 ) {
2015-09-01 11:14:27 +02:00
channel = Channels - > Get ( Channels - > GetNextNormal ( group ) ) ;
2006-01-22 14:27:53 +01:00
if ( channel )
NewChannel = channel ;
withInfo = true ;
group = - 1 ;
Refresh ( ) ;
}
else if ( number > 0 ) {
2015-09-01 11:14:27 +02:00
channel = Channels - > GetByNumber ( number ) ;
2006-01-22 14:27:53 +01:00
if ( channel )
NewChannel = channel ;
withInfo = true ;
number = 0 ;
Refresh ( ) ;
}
2015-09-01 11:14:27 +02:00
else {
2006-01-22 14:27:53 +01:00
return osEnd ;
2015-09-01 11:14:27 +02:00
}
}
2006-01-22 14:27:53 +01:00
break ;
default :
if ( ( Key & ( k_Repeat | k_Release ) ) = = 0 ) {
cRemote : : Put ( Key ) ;
return osEnd ;
}
2000-09-10 14:56:18 +02:00
} ;
2013-08-21 11:02:52 +02:00
if ( positioner | | ! timeout | | lastTime . Elapsed ( ) < ( uint64_t ) ( Setup . ChannelInfoTime * 1000 ) ) {
2018-05-06 09:41:03 +02:00
{
LOCK_CHANNELS_READ ;
if ( Key = = kNone & & ! number & & group < 0 & & ! NewChannel & & channel & & channel - > Number ( ) ! = cDevice : : CurrentChannel ( ) ) {
// makes sure a channel switch through the SVDRP CHAN command is displayed
channel = Channels - > GetByNumber ( cDevice : : CurrentChannel ( ) ) ;
Refresh ( ) ;
lastTime . Set ( ) ;
}
DisplayInfo ( ) ;
if ( NewChannel ) {
SetTrackDescriptions ( NewChannel - > Number ( ) ) ; // to make them immediately visible in the channel display
Channels - > SwitchTo ( NewChannel - > Number ( ) ) ;
SetTrackDescriptions ( NewChannel - > Number ( ) ) ; // switching the channel has cleared them
channel = NewChannel ;
}
const cPositioner * Positioner = cDevice : : ActualDevice ( ) - > Positioner ( ) ;
bool PositionerMoving = Positioner & & Positioner - > IsMoving ( ) ;
SetNeedsFastResponse ( PositionerMoving ) ;
if ( ! PositionerMoving ) {
if ( positioner )
lastTime . Set ( ) ; // to keep the channel display up a few seconds after the target position has been reached
Positioner = NULL ;
}
if ( Positioner | | positioner ) // making sure we call SetPositioner(NULL) if there is a switch from "with" to "without" positioner
displayChannel - > SetPositioner ( Positioner ) ;
positioner = Positioner ;
}
2013-08-21 11:02:52 +02:00
displayChannel - > Flush ( ) ;
2000-11-01 15:41:33 +01:00
return osContinue ;
}
return osEnd ;
2000-09-10 14:56:18 +02:00
}
2002-03-09 17:11:49 +01:00
// --- cDisplayVolume --------------------------------------------------------
# define VOLUMETIMEOUT 1000 //ms
# define MUTETIMEOUT 5000 //ms
2004-05-16 10:35:36 +02:00
cDisplayVolume * cDisplayVolume : : currentDisplayVolume = NULL ;
2002-03-09 17:11:49 +01:00
cDisplayVolume : : cDisplayVolume ( void )
2002-05-18 12:41:18 +02:00
: cOsdObject ( true )
2002-03-09 17:11:49 +01:00
{
2004-05-16 10:35:36 +02:00
currentDisplayVolume = this ;
2004-12-19 18:08:09 +01:00
timeout . Set ( cDevice : : PrimaryDevice ( ) - > IsMute ( ) ? MUTETIMEOUT : VOLUMETIMEOUT ) ;
2004-05-16 10:35:36 +02:00
displayVolume = Skins . Current ( ) - > DisplayVolume ( ) ;
2002-03-09 17:11:49 +01:00
Show ( ) ;
}
cDisplayVolume : : ~ cDisplayVolume ( )
{
2004-05-16 10:35:36 +02:00
delete displayVolume ;
currentDisplayVolume = NULL ;
2002-03-09 17:11:49 +01:00
}
void cDisplayVolume : : Show ( void )
{
2004-05-16 10:35:36 +02:00
displayVolume - > SetVolume ( cDevice : : CurrentVolume ( ) , MAXVOLUME , cDevice : : PrimaryDevice ( ) - > IsMute ( ) ) ;
2002-03-09 17:11:49 +01:00
}
cDisplayVolume * cDisplayVolume : : Create ( void )
{
2004-05-16 10:35:36 +02:00
if ( ! currentDisplayVolume )
2002-03-09 17:11:49 +01:00
new cDisplayVolume ;
2004-05-16 10:35:36 +02:00
return currentDisplayVolume ;
2002-03-09 17:11:49 +01:00
}
void cDisplayVolume : : Process ( eKeys Key )
{
2004-05-16 10:35:36 +02:00
if ( currentDisplayVolume )
currentDisplayVolume - > ProcessKey ( Key ) ;
2002-03-09 17:11:49 +01:00
}
eOSState cDisplayVolume : : ProcessKey ( eKeys Key )
{
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2002-03-09 17:11:49 +01:00
case kVolUp | k_Repeat :
case kVolUp :
case kVolDn | k_Repeat :
case kVolDn :
Show ( ) ;
2004-12-19 18:08:09 +01:00
timeout . Set ( VOLUMETIMEOUT ) ;
2002-03-09 17:11:49 +01:00
break ;
case kMute :
2002-06-16 12:57:31 +02:00
if ( cDevice : : PrimaryDevice ( ) - > IsMute ( ) ) {
2002-03-09 17:11:49 +01:00
Show ( ) ;
2004-12-19 18:08:09 +01:00
timeout . Set ( MUTETIMEOUT ) ;
2002-03-09 17:11:49 +01:00
}
else
2004-12-19 18:08:09 +01:00
timeout . Set ( ) ;
2002-03-09 17:11:49 +01:00
break ;
case kNone : break ;
default : if ( ( Key & k_Release ) = = 0 ) {
2002-09-29 13:40:45 +02:00
cRemote : : Put ( Key ) ;
2002-03-09 17:11:49 +01:00
return osEnd ;
}
}
2004-12-19 18:08:09 +01:00
return timeout . TimedOut ( ) ? osEnd : osContinue ;
2002-03-09 17:11:49 +01:00
}
2005-01-02 15:11:44 +01:00
// --- cDisplayTracks --------------------------------------------------------
# define TRACKTIMEOUT 5000 //ms
cDisplayTracks * cDisplayTracks : : currentDisplayTracks = NULL ;
cDisplayTracks : : cDisplayTracks ( void )
: cOsdObject ( true )
{
2005-02-06 11:33:13 +01:00
cDevice : : PrimaryDevice ( ) - > EnsureAudioTrack ( ) ;
2006-02-04 14:58:24 +01:00
SetTrackDescriptions ( ! cDevice : : PrimaryDevice ( ) - > Replaying ( ) | | cDevice : : PrimaryDevice ( ) - > Transferring ( ) ? cDevice : : CurrentChannel ( ) : 0 ) ;
2005-01-02 15:11:44 +01:00
currentDisplayTracks = this ;
numTracks = track = 0 ;
2005-01-09 12:08:34 +01:00
audioChannel = cDevice : : PrimaryDevice ( ) - > GetAudioChannel ( ) ;
2005-01-02 15:11:44 +01:00
eTrackType CurrentAudioTrack = cDevice : : PrimaryDevice ( ) - > GetCurrentAudioTrack ( ) ;
for ( int i = ttAudioFirst ; i < = ttDolbyLast ; i + + ) {
const tTrackId * TrackId = cDevice : : PrimaryDevice ( ) - > GetTrack ( eTrackType ( i ) ) ;
if ( TrackId & & TrackId - > id ) {
types [ numTracks ] = eTrackType ( i ) ;
2005-01-04 11:11:16 +01:00
descriptions [ numTracks ] = strdup ( * TrackId - > description ? TrackId - > description : * TrackId - > language ? TrackId - > language : * itoa ( i ) ) ;
2005-01-02 15:11:44 +01:00
if ( i = = CurrentAudioTrack )
track = numTracks ;
numTracks + + ;
}
}
2007-10-12 14:52:30 +02:00
descriptions [ numTracks ] = NULL ;
2005-01-02 15:11:44 +01:00
timeout . Set ( TRACKTIMEOUT ) ;
2006-01-07 15:54:10 +01:00
displayTracks = Skins . Current ( ) - > DisplayTracks ( tr ( " Button$Audio " ) , numTracks , descriptions ) ;
2005-01-02 15:11:44 +01:00
Show ( ) ;
}
cDisplayTracks : : ~ cDisplayTracks ( )
{
delete displayTracks ;
currentDisplayTracks = NULL ;
for ( int i = 0 ; i < numTracks ; i + + )
free ( descriptions [ i ] ) ;
cStatus : : MsgOsdClear ( ) ;
}
void cDisplayTracks : : Show ( void )
{
2005-01-09 12:08:34 +01:00
int ac = IS_AUDIO_TRACK ( types [ track ] ) ? audioChannel : - 1 ;
2005-01-02 15:11:44 +01:00
displayTracks - > SetTrack ( track , descriptions ) ;
2005-01-09 12:08:34 +01:00
displayTracks - > SetAudioChannel ( ac ) ;
2005-01-02 15:11:44 +01:00
displayTracks - > Flush ( ) ;
cStatus : : MsgSetAudioTrack ( track , descriptions ) ;
2005-01-09 12:08:34 +01:00
cStatus : : MsgSetAudioChannel ( ac ) ;
2005-01-02 15:11:44 +01:00
}
cDisplayTracks * cDisplayTracks : : Create ( void )
{
2005-01-04 13:40:38 +01:00
if ( cDevice : : PrimaryDevice ( ) - > NumAudioTracks ( ) > 0 ) {
if ( ! currentDisplayTracks )
new cDisplayTracks ;
return currentDisplayTracks ;
}
Skins . Message ( mtWarning , tr ( " No audio available! " ) ) ;
return NULL ;
2005-01-02 15:11:44 +01:00
}
void cDisplayTracks : : Process ( eKeys Key )
{
if ( currentDisplayTracks )
currentDisplayTracks - > ProcessKey ( Key ) ;
}
eOSState cDisplayTracks : : ProcessKey ( eKeys Key )
{
int oldTrack = track ;
2005-01-09 12:08:34 +01:00
int oldAudioChannel = audioChannel ;
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2005-01-02 15:11:44 +01:00
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
if ( NORMALKEY ( Key ) = = kUp & & track > 0 )
track - - ;
else if ( NORMALKEY ( Key ) = = kDown & & track < numTracks - 1 )
track + + ;
timeout . Set ( TRACKTIMEOUT ) ;
break ;
2005-01-06 13:50:17 +01:00
case kLeft | k_Repeat :
case kLeft :
case kRight | k_Repeat :
2005-01-09 12:08:34 +01:00
case kRight : if ( IS_AUDIO_TRACK ( types [ track ] ) ) {
static int ac [ ] = { 1 , 0 , 2 } ;
audioChannel = ac [ cDevice : : PrimaryDevice ( ) - > GetAudioChannel ( ) ] ;
if ( NORMALKEY ( Key ) = = kLeft & & audioChannel > 0 )
audioChannel - - ;
else if ( NORMALKEY ( Key ) = = kRight & & audioChannel < 2 )
audioChannel + + ;
audioChannel = ac [ audioChannel ] ;
timeout . Set ( TRACKTIMEOUT ) ;
}
2005-01-06 13:50:17 +01:00
break ;
2005-02-27 14:12:03 +01:00
case kAudio | k_Repeat :
2005-01-02 15:11:44 +01:00
case kAudio :
if ( + + track > = numTracks )
track = 0 ;
timeout . Set ( TRACKTIMEOUT ) ;
break ;
2005-01-04 12:52:17 +01:00
case kOk :
2007-10-12 14:52:30 +02:00
if ( types [ track ] ! = cDevice : : PrimaryDevice ( ) - > GetCurrentAudioTrack ( ) )
2005-01-04 12:52:17 +01:00
oldTrack = - 1 ; // make sure we explicitly switch to that track
timeout . Set ( ) ;
break ;
2005-01-02 15:11:44 +01:00
case kNone : break ;
2005-01-06 13:50:17 +01:00
default : if ( ( Key & k_Release ) = = 0 )
return osEnd ;
2005-01-02 15:11:44 +01:00
}
2005-01-09 12:08:34 +01:00
if ( track ! = oldTrack | | audioChannel ! = oldAudioChannel )
2005-01-02 15:11:44 +01:00
Show ( ) ;
2005-01-09 12:08:34 +01:00
if ( track ! = oldTrack ) {
2005-01-02 15:11:44 +01:00
cDevice : : PrimaryDevice ( ) - > SetCurrentAudioTrack ( types [ track ] ) ;
2005-01-08 13:53:30 +01:00
Setup . CurrentDolby = IS_DOLBY_TRACK ( types [ track ] ) ;
2005-01-02 15:11:44 +01:00
}
2005-01-09 12:08:34 +01:00
if ( audioChannel ! = oldAudioChannel )
cDevice : : PrimaryDevice ( ) - > SetAudioChannel ( audioChannel ) ;
2005-01-02 15:11:44 +01:00
return timeout . TimedOut ( ) ? osEnd : osContinue ;
}
2007-10-12 14:52:30 +02:00
// --- cDisplaySubtitleTracks ------------------------------------------------
cDisplaySubtitleTracks * cDisplaySubtitleTracks : : currentDisplayTracks = NULL ;
cDisplaySubtitleTracks : : cDisplaySubtitleTracks ( void )
: cOsdObject ( true )
{
SetTrackDescriptions ( ! cDevice : : PrimaryDevice ( ) - > Replaying ( ) | | cDevice : : PrimaryDevice ( ) - > Transferring ( ) ? cDevice : : CurrentChannel ( ) : 0 ) ;
currentDisplayTracks = this ;
numTracks = track = 0 ;
types [ numTracks ] = ttNone ;
descriptions [ numTracks ] = strdup ( tr ( " No subtitles " ) ) ;
numTracks + + ;
eTrackType CurrentSubtitleTrack = cDevice : : PrimaryDevice ( ) - > GetCurrentSubtitleTrack ( ) ;
for ( int i = ttSubtitleFirst ; i < = ttSubtitleLast ; i + + ) {
const tTrackId * TrackId = cDevice : : PrimaryDevice ( ) - > GetTrack ( eTrackType ( i ) ) ;
if ( TrackId & & TrackId - > id ) {
types [ numTracks ] = eTrackType ( i ) ;
descriptions [ numTracks ] = strdup ( * TrackId - > description ? TrackId - > description : * TrackId - > language ? TrackId - > language : * itoa ( i ) ) ;
if ( i = = CurrentSubtitleTrack )
track = numTracks ;
numTracks + + ;
}
}
descriptions [ numTracks ] = NULL ;
timeout . Set ( TRACKTIMEOUT ) ;
displayTracks = Skins . Current ( ) - > DisplayTracks ( tr ( " Button$Subtitles " ) , numTracks , descriptions ) ;
Show ( ) ;
}
cDisplaySubtitleTracks : : ~ cDisplaySubtitleTracks ( )
{
delete displayTracks ;
currentDisplayTracks = NULL ;
for ( int i = 0 ; i < numTracks ; i + + )
free ( descriptions [ i ] ) ;
cStatus : : MsgOsdClear ( ) ;
}
void cDisplaySubtitleTracks : : Show ( void )
{
displayTracks - > SetTrack ( track , descriptions ) ;
displayTracks - > Flush ( ) ;
2008-02-16 13:59:09 +01:00
cStatus : : MsgSetSubtitleTrack ( track , descriptions ) ;
2007-10-12 14:52:30 +02:00
}
cDisplaySubtitleTracks * cDisplaySubtitleTracks : : Create ( void )
{
if ( cDevice : : PrimaryDevice ( ) - > NumSubtitleTracks ( ) > 0 ) {
if ( ! currentDisplayTracks )
new cDisplaySubtitleTracks ;
return currentDisplayTracks ;
}
Skins . Message ( mtWarning , tr ( " No subtitles available! " ) ) ;
return NULL ;
}
void cDisplaySubtitleTracks : : Process ( eKeys Key )
{
if ( currentDisplayTracks )
currentDisplayTracks - > ProcessKey ( Key ) ;
}
eOSState cDisplaySubtitleTracks : : ProcessKey ( eKeys Key )
{
int oldTrack = track ;
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2007-10-12 14:52:30 +02:00
case kUp | k_Repeat :
case kUp :
case kDown | k_Repeat :
case kDown :
if ( NORMALKEY ( Key ) = = kUp & & track > 0 )
track - - ;
else if ( NORMALKEY ( Key ) = = kDown & & track < numTracks - 1 )
track + + ;
timeout . Set ( TRACKTIMEOUT ) ;
break ;
case kSubtitles | k_Repeat :
case kSubtitles :
if ( + + track > = numTracks )
track = 0 ;
timeout . Set ( TRACKTIMEOUT ) ;
break ;
case kOk :
if ( types [ track ] ! = cDevice : : PrimaryDevice ( ) - > GetCurrentSubtitleTrack ( ) )
oldTrack = - 1 ; // make sure we explicitly switch to that track
timeout . Set ( ) ;
break ;
case kNone : break ;
default : if ( ( Key & k_Release ) = = 0 )
return osEnd ;
}
if ( track ! = oldTrack ) {
Show ( ) ;
cDevice : : PrimaryDevice ( ) - > SetCurrentSubtitleTrack ( types [ track ] , true ) ;
}
return timeout . TimedOut ( ) ? osEnd : osContinue ;
}
2000-04-30 10:22:13 +02:00
// --- cRecordControl --------------------------------------------------------
2015-09-01 11:14:27 +02:00
cRecordControl : : cRecordControl ( cDevice * Device , cTimers * Timers , cTimer * Timer , bool Pause )
2000-04-30 10:22:13 +02:00
{
2017-06-07 15:41:12 +02:00
const char * LastReplayed = cReplayControl : : LastReplayed ( ) ; // must do this before locking schedules!
2012-04-25 11:14:12 +02:00
// Whatever happens here, the timers will be modified in some way...
2015-09-01 11:14:27 +02:00
Timers - > SetModified ( ) ;
2020-12-12 22:01:01 +01:00
cStateKey ChannelsStateKey ;
// To create a new timer, we need to make shure there is
// a lock on Channels prior to the Schedules locking below
if ( ! Timer )
cChannels : : GetChannelsRead ( ChannelsStateKey ) ;
2015-09-01 11:14:27 +02:00
// We're going to work with an event here, so we need to prevent
2005-05-16 14:45:11 +02:00
// others from modifying any EPG data:
2017-05-29 08:18:17 +02:00
cStateKey SchedulesStateKey ;
cSchedules : : GetSchedulesRead ( SchedulesStateKey ) ;
2005-05-16 14:45:11 +02:00
2003-12-22 13:29:24 +01:00
event = NULL ;
2001-09-23 14:02:11 +02:00
fileName = NULL ;
2002-06-16 12:57:31 +02:00
recorder = NULL ;
device = Device ;
if ( ! device ) device = cDevice : : PrimaryDevice ( ) ; //XXX
2000-04-30 10:22:13 +02:00
timer = Timer ;
if ( ! timer ) {
2003-05-11 14:10:00 +02:00
timer = new cTimer ( true , Pause ) ;
2015-09-01 11:14:27 +02:00
Timers - > Add ( timer ) ;
2019-05-28 15:54:22 +02:00
instantId = cString : : sprintf ( cDevice : : NumDevices ( ) > 1 ? " %s - %d " : " %s " , timer - > Channel ( ) - > Name ( ) , device - > DeviceNumber ( ) + 1 ) ;
2020-12-12 22:01:01 +01:00
ChannelsStateKey . Remove ( ) ;
2000-04-30 10:22:13 +02:00
}
2001-08-11 15:48:54 +02:00
timer - > SetPending ( true ) ;
2000-04-30 10:22:13 +02:00
timer - > SetRecording ( true ) ;
2004-02-29 14:21:22 +01:00
event = timer - > Event ( ) ;
2002-06-16 12:57:31 +02:00
2005-05-16 14:45:11 +02:00
if ( event | | GetEvent ( ) )
dsyslog ( " Title: '%s' Subtitle: '%s' " , event - > Title ( ) , event - > ShortText ( ) ) ;
cRecording Recording ( timer , event ) ;
2002-06-16 12:57:31 +02:00
fileName = strdup ( Recording . FileName ( ) ) ;
2003-05-25 12:56:26 +02:00
// crude attempt to avoid duplicate recordings:
if ( cRecordControls : : GetRecordControl ( fileName ) ) {
isyslog ( " already recording: '%s' " , fileName ) ;
if ( Timer ) {
timer - > SetPending ( false ) ;
timer - > SetRecording ( false ) ;
timer - > OnOff ( ) ;
}
else {
2015-09-01 11:14:27 +02:00
Timers - > Del ( timer ) ;
2017-06-07 15:41:12 +02:00
if ( ! LastReplayed ) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
2012-05-12 14:20:41 +02:00
cReplayControl : : SetRecording ( fileName ) ;
2003-05-25 12:56:26 +02:00
}
timer = NULL ;
2017-05-29 08:18:17 +02:00
SchedulesStateKey . Remove ( ) ;
2003-05-25 12:56:26 +02:00
return ;
}
2002-06-16 12:57:31 +02:00
cRecordingUserCommand : : InvokeCommand ( RUC_BEFORERECORDING , fileName ) ;
2003-08-02 13:23:58 +02:00
isyslog ( " record %s " , fileName ) ;
if ( MakeDirs ( fileName , true ) ) {
2018-03-08 17:03:51 +01:00
Recording . WriteInfo ( ) ; // we write this *before* attaching the recorder to the device, to make sure the info file is present when the recorder needs to update the fps value!
2003-08-02 13:23:58 +02:00
const cChannel * ch = timer - > Channel ( ) ;
2010-01-30 11:10:25 +01:00
recorder = new cRecorder ( fileName , ch , timer - > Priority ( ) ) ;
2003-08-02 13:23:58 +02:00
if ( device - > AttachReceiver ( recorder ) ) {
2005-12-31 15:20:19 +01:00
cStatus : : MsgRecording ( device , Recording . Name ( ) , Recording . FileName ( ) , true ) ;
2017-06-07 15:41:12 +02:00
if ( ! Timer & & ! LastReplayed ) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
2012-05-12 14:20:41 +02:00
cReplayControl : : SetRecording ( fileName ) ;
2017-05-29 08:18:17 +02:00
SchedulesStateKey . Remove ( ) ;
2015-09-01 11:14:27 +02:00
LOCK_RECORDINGS_WRITE ;
2018-02-25 13:28:19 +01:00
SetRecordingTimerId ( fileName , cString : : sprintf ( " %d@%s " , timer - > Id ( ) , Setup . SVDRPHostName ) ) ;
2018-03-08 17:03:51 +01:00
Recordings - > AddByName ( fileName ) ;
2004-11-20 11:00:26 +01:00
return ;
2003-08-02 13:23:58 +02:00
}
else
DELETENULL ( recorder ) ;
2001-06-02 10:47:40 +02:00
}
2011-08-06 13:20:07 +02:00
else
timer - > SetDeferred ( DEFERTIMER ) ;
2004-11-20 11:00:26 +01:00
if ( ! Timer ) {
2015-09-01 11:14:27 +02:00
Timers - > Del ( timer ) ;
2004-11-20 11:00:26 +01:00
timer = NULL ;
}
2017-05-29 08:18:17 +02:00
SchedulesStateKey . Remove ( ) ;
2000-04-30 10:22:13 +02:00
}
cRecordControl : : ~ cRecordControl ( )
{
2005-03-20 11:19:36 +01:00
Stop ( ) ;
2002-08-11 13:32:23 +02:00
free ( fileName ) ;
2000-04-30 11:15:16 +02:00
}
2002-02-17 16:03:49 +01:00
# define INSTANT_REC_EPG_LOOKAHEAD 300 // seconds to look into the EPG data for an instant recording
2003-12-22 13:29:24 +01:00
bool cRecordControl : : GetEvent ( void )
2001-08-19 14:45:31 +02:00
{
2015-09-01 11:14:27 +02:00
const cChannel * Channel = timer - > Channel ( ) ;
2004-02-29 14:21:22 +01:00
time_t Time = timer - > HasFlags ( tfInstant ) ? timer - > StartTime ( ) + INSTANT_REC_EPG_LOOKAHEAD : timer - > StartTime ( ) + ( timer - > StopTime ( ) - timer - > StartTime ( ) ) / 2 ;
2001-08-19 14:45:31 +02:00
for ( int seconds = 0 ; seconds < = MAXWAIT4EPGINFO ; seconds + + ) {
{
2015-09-01 11:14:27 +02:00
LOCK_SCHEDULES_READ ;
if ( const cSchedule * Schedule = Schedules - > GetSchedule ( Channel ) ) {
event = Schedule - > GetEventAround ( Time ) ;
if ( event ) {
if ( seconds > 0 )
dsyslog ( " got EPG info after %d seconds " , seconds ) ;
return true ;
2001-08-19 14:45:31 +02:00
}
}
}
if ( seconds = = 0 )
2002-05-13 16:35:49 +02:00
dsyslog ( " waiting for EPG info... " ) ;
2011-12-04 14:53:41 +01:00
cCondWait : : SleepMs ( 1000 ) ;
2001-08-19 14:45:31 +02:00
}
2002-05-13 16:35:49 +02:00
dsyslog ( " no EPG info available " ) ;
2001-08-19 14:45:31 +02:00
return false ;
}
2010-03-07 12:43:30 +01:00
void cRecordControl : : Stop ( bool ExecuteUserCommand )
2000-04-30 11:15:16 +02:00
{
if ( timer ) {
2021-05-19 11:22:20 +02:00
if ( recorder ) {
int Errors = recorder - > Errors ( ) ;
bool Finished = timer - > HasFlags ( tfActive ) & & ! timer - > Matches ( ) ;
isyslog ( " timer %s %s with %d error%s " , * timer - > ToDescr ( ) , Finished ? " finished " : " stopped " , Errors , Errors ! = 1 ? " s " : " " ) ;
if ( timer - > HasFlags ( tfAvoid ) & & Errors = = 0 & & Finished ) {
const char * p = strgetlast ( timer - > File ( ) , FOLDERDELIMCHAR ) ;
DoneRecordingsPattern . Append ( p ) ;
}
}
2002-06-16 12:57:31 +02:00
DELETENULL ( recorder ) ;
2000-04-30 11:15:16 +02:00
timer - > SetRecording ( false ) ;
timer = NULL ;
2018-02-13 09:33:41 +01:00
SetRecordingTimerId ( fileName , NULL ) ;
2005-12-31 15:20:19 +01:00
cStatus : : MsgRecording ( device , NULL , fileName , false ) ;
2010-03-07 12:43:30 +01:00
if ( ExecuteUserCommand )
cRecordingUserCommand : : InvokeCommand ( RUC_AFTERRECORDING , fileName ) ;
2000-04-30 10:22:13 +02:00
}
}
2001-09-01 15:04:14 +02:00
bool cRecordControl : : Process ( time_t t )
2000-04-30 10:22:13 +02:00
{
2008-03-16 11:16:28 +01:00
if ( ! recorder | | ! recorder - > IsAttached ( ) | | ! timer | | ! timer - > Matches ( t ) ) {
2021-05-19 11:22:20 +02:00
if ( timer )
2008-03-16 11:16:28 +01:00
timer - > SetPending ( false ) ;
2000-05-01 16:29:46 +02:00
return false ;
2008-03-16 11:16:28 +01:00
}
2000-05-01 16:29:46 +02:00
return true ;
}
// --- cRecordControls -------------------------------------------------------
2002-06-16 12:57:31 +02:00
cRecordControl * cRecordControls : : RecordControls [ MAXRECORDCONTROLS ] = { NULL } ;
2005-12-24 15:53:53 +01:00
int cRecordControls : : state = 0 ;
2000-05-01 16:29:46 +02:00
2015-09-01 11:14:27 +02:00
bool cRecordControls : : Start ( cTimers * Timers , cTimer * Timer , bool Pause )
2000-05-01 16:29:46 +02:00
{
2006-01-20 16:34:56 +01:00
static time_t LastNoDiskSpaceMessage = 0 ;
int FreeMB = 0 ;
2006-01-21 10:02:19 +01:00
if ( Timer ) {
AssertFreeDiskSpace ( Timer - > Priority ( ) , ! Timer - > Pending ( ) ) ;
Timer - > SetPending ( true ) ;
}
2013-09-11 12:20:37 +02:00
cVideoDirectory : : VideoDiskSpace ( & FreeMB ) ;
2006-01-20 16:34:56 +01:00
if ( FreeMB < MINFREEDISK ) {
if ( ! Timer | | time ( NULL ) - LastNoDiskSpaceMessage > NODISKSPACEDELTA ) {
isyslog ( " not enough disk space to start recording%s%s " , Timer ? " timer " : " " , Timer ? * Timer - > ToDescr ( ) : " " ) ;
Skins . Message ( mtWarning , tr ( " Not enough disk space to start recording! " ) ) ;
LastNoDiskSpaceMessage = time ( NULL ) ;
}
return false ;
}
LastNoDiskSpaceMessage = 0 ;
2005-12-24 15:53:53 +01:00
ChangeState ( ) ;
2020-12-12 22:01:01 +01:00
cStateKey StateKey ;
const cChannels * Channels = cChannels : : GetChannelsRead ( StateKey ) ;
2002-10-20 12:28:55 +02:00
int ch = Timer ? Timer - > Channel ( ) - > Number ( ) : cDevice : : CurrentChannel ( ) ;
2015-09-01 11:14:27 +02:00
if ( const cChannel * Channel = Channels - > GetByNumber ( ch ) ) {
2003-05-11 14:10:00 +02:00
int Priority = Timer ? Timer - > Priority ( ) : Pause ? Setup . PausePriority : Setup . DefaultPriority ;
2015-09-01 11:14:27 +02:00
cDevice * device = cDevice : : GetDevice ( Channel , Priority , false ) ;
2002-06-16 12:57:31 +02:00
if ( device ) {
2017-05-01 13:06:32 +02:00
dsyslog ( " switching device %d to channel %d %s (%s) " , device - > DeviceNumber ( ) + 1 , Channel - > Number ( ) , * Channel - > GetChannelID ( ) . ToString ( ) , Channel - > Name ( ) ) ;
2015-09-01 11:14:27 +02:00
if ( ! device - > SwitchChannel ( Channel , false ) ) {
2020-12-12 22:01:01 +01:00
StateKey . Remove ( ) ;
2007-02-25 10:56:29 +01:00
ShutdownHandler . RequestEmergencyExit ( ) ;
2002-09-06 14:10:17 +02:00
return false ;
2002-06-16 12:57:31 +02:00
}
2020-12-12 22:01:01 +01:00
StateKey . Remove ( ) ;
Channels = NULL ;
2004-02-29 14:21:22 +01:00
if ( ! Timer | | Timer - > Matches ( ) ) {
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
if ( ! RecordControls [ i ] ) {
2015-09-01 11:14:27 +02:00
RecordControls [ i ] = new cRecordControl ( device , Timers , Timer , Pause ) ;
2004-11-20 11:00:26 +01:00
return RecordControls [ i ] - > Process ( time ( NULL ) ) ;
2004-02-29 14:21:22 +01:00
}
2000-05-01 16:29:46 +02:00
}
2004-02-29 14:21:22 +01:00
}
2000-05-01 16:29:46 +02:00
}
2012-02-25 14:44:43 +01:00
else if ( ! Timer | | ! Timer - > Pending ( ) ) {
2015-09-01 11:14:27 +02:00
isyslog ( " no free DVB device to record channel %d (%s)! " , ch , Channel - > Name ( ) ) ;
2006-01-20 16:34:56 +01:00
Skins . Message ( mtError , tr ( " No free DVB device to record! " ) ) ;
}
2000-05-01 16:29:46 +02:00
}
else
2002-05-13 16:35:49 +02:00
esyslog ( " ERROR: channel %d not defined! " , ch ) ;
2020-12-12 22:01:01 +01:00
if ( Channels )
StateKey . Remove ( ) ;
2000-05-01 16:29:46 +02:00
return false ;
}
2015-09-01 11:14:27 +02:00
bool cRecordControls : : Start ( bool Pause )
{
LOCK_TIMERS_WRITE ;
return Start ( Timers , NULL , Pause ) ;
}
2000-05-01 16:29:46 +02:00
void cRecordControls : : Stop ( const char * InstantId )
{
2015-09-01 11:14:27 +02:00
LOCK_TIMERS_WRITE ;
2005-12-24 15:53:53 +01:00
ChangeState ( ) ;
2002-06-16 12:57:31 +02:00
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
2000-05-01 16:29:46 +02:00
if ( RecordControls [ i ] ) {
const char * id = RecordControls [ i ] - > InstantId ( ) ;
2005-03-20 11:19:36 +01:00
if ( id & & strcmp ( id , InstantId ) = = 0 ) {
2015-09-01 11:14:27 +02:00
cTimer * Timer = RecordControls [ i ] - > Timer ( ) ;
2000-05-01 16:29:46 +02:00
RecordControls [ i ] - > Stop ( ) ;
2015-09-01 11:14:27 +02:00
if ( Timer ) {
Timers - > Del ( Timer ) ;
2015-09-14 13:23:06 +02:00
isyslog ( " deleted timer %s " , * Timer - > ToDescr ( ) ) ;
2005-03-20 11:19:36 +01:00
}
break ;
}
2000-05-01 16:29:46 +02:00
}
}
}
2015-09-13 13:57:51 +02:00
void cRecordControls : : Stop ( cTimer * Timer )
{
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
if ( RecordControls [ i ] ) {
if ( RecordControls [ i ] - > Timer ( ) = = Timer ) {
DELETENULL ( RecordControls [ i ] ) ;
ChangeState ( ) ;
break ;
}
}
}
}
2003-04-21 14:57:13 +02:00
bool cRecordControls : : PauseLiveVideo ( void )
{
2004-05-16 10:35:36 +02:00
Skins . Message ( mtStatus , tr ( " Pausing live video... " ) ) ;
2012-05-12 14:20:41 +02:00
cReplayControl : : SetRecording ( NULL ) ; // make sure the new cRecordControl will set cReplayControl::LastReplayed()
2015-09-01 11:14:27 +02:00
if ( Start ( true ) ) {
2012-02-19 11:50:20 +01:00
cReplayControl * rc = new cReplayControl ( true ) ;
2003-04-21 14:57:13 +02:00
cControl : : Launch ( rc ) ;
cControl : : Attach ( ) ;
2004-05-16 10:35:36 +02:00
Skins . Message ( mtStatus , NULL ) ;
2003-04-21 14:57:13 +02:00
return true ;
}
2004-05-16 10:35:36 +02:00
Skins . Message ( mtStatus , NULL ) ;
2003-04-21 14:57:13 +02:00
return false ;
}
2000-05-01 16:29:46 +02:00
const char * cRecordControls : : GetInstantId ( const char * LastInstantId )
{
2002-06-16 12:57:31 +02:00
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
2000-05-01 16:29:46 +02:00
if ( RecordControls [ i ] ) {
if ( ! LastInstantId & & RecordControls [ i ] - > InstantId ( ) )
return RecordControls [ i ] - > InstantId ( ) ;
if ( LastInstantId & & LastInstantId = = RecordControls [ i ] - > InstantId ( ) )
LastInstantId = NULL ;
}
}
return NULL ;
}
2002-02-17 14:29:13 +01:00
cRecordControl * cRecordControls : : GetRecordControl ( const char * FileName )
{
2010-03-07 12:43:30 +01:00
if ( FileName ) {
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
if ( RecordControls [ i ] & & strcmp ( RecordControls [ i ] - > FileName ( ) , FileName ) = = 0 )
return RecordControls [ i ] ;
}
}
2002-02-17 14:29:13 +01:00
return NULL ;
}
2012-04-22 10:44:20 +02:00
cRecordControl * cRecordControls : : GetRecordControl ( const cTimer * Timer )
{
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
if ( RecordControls [ i ] & & RecordControls [ i ] - > Timer ( ) = = Timer )
return RecordControls [ i ] ;
}
return NULL ;
}
2015-09-01 11:14:27 +02:00
bool cRecordControls : : Process ( cTimers * Timers , time_t t )
2000-05-01 16:29:46 +02:00
{
2015-09-01 11:14:27 +02:00
bool Result = false ;
2002-06-16 12:57:31 +02:00
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
2000-05-01 16:29:46 +02:00
if ( RecordControls [ i ] ) {
2005-12-24 15:53:53 +01:00
if ( ! RecordControls [ i ] - > Process ( t ) ) {
2000-05-01 16:29:46 +02:00
DELETENULL ( RecordControls [ i ] ) ;
2005-12-24 15:53:53 +01:00
ChangeState ( ) ;
2015-09-01 11:14:27 +02:00
Result = true ;
2005-12-24 15:53:53 +01:00
}
2000-05-01 16:29:46 +02:00
}
}
2015-09-01 11:14:27 +02:00
return Result ;
2000-04-30 10:22:13 +02:00
}
2015-09-01 11:14:27 +02:00
void cRecordControls : : ChannelDataModified ( const cChannel * Channel )
2004-01-04 12:30:00 +01:00
{
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
if ( RecordControls [ i ] ) {
if ( RecordControls [ i ] - > Timer ( ) & & RecordControls [ i ] - > Timer ( ) - > Channel ( ) = = Channel ) {
2004-02-15 14:31:53 +01:00
if ( RecordControls [ i ] - > Device ( ) - > ProvidesTransponder ( Channel ) ) { // avoids retune on devices that don't really access the transponder
2015-01-14 12:17:39 +01:00
isyslog ( " stopping recording due to modification of channel %d (%s) " , Channel - > Number ( ) , Channel - > Name ( ) ) ;
2005-03-20 11:19:36 +01:00
RecordControls [ i ] - > Stop ( ) ;
2004-02-15 14:31:53 +01:00
// This will restart the recording, maybe even from a different
// device in case conditional access has changed.
2005-12-24 15:53:53 +01:00
ChangeState ( ) ;
2004-02-15 14:31:53 +01:00
}
2004-01-04 12:30:00 +01:00
}
}
}
}
2001-02-04 12:36:32 +01:00
bool cRecordControls : : Active ( void )
{
2002-06-16 12:57:31 +02:00
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + ) {
2001-02-04 12:36:32 +01:00
if ( RecordControls [ i ] )
return true ;
}
return false ;
}
2002-06-16 12:57:31 +02:00
void cRecordControls : : Shutdown ( void )
{
for ( int i = 0 ; i < MAXRECORDCONTROLS ; i + + )
DELETENULL ( RecordControls [ i ] ) ;
2005-12-24 15:53:53 +01:00
ChangeState ( ) ;
}
bool cRecordControls : : StateChanged ( int & State )
{
int NewState = state ;
bool Result = State ! = NewState ;
State = state ;
return Result ;
2002-06-16 12:57:31 +02:00
}
2015-02-06 10:25:25 +01:00
// --- cAdaptiveSkipper ------------------------------------------------------
2015-01-27 21:22:53 +01:00
2015-02-06 10:25:25 +01:00
cAdaptiveSkipper : : cAdaptiveSkipper ( void )
2015-01-27 21:22:53 +01:00
{
initialValue = NULL ;
currentValue = 0 ;
framesPerSecond = 0 ;
lastKey = kNone ;
}
2015-02-06 10:25:25 +01:00
void cAdaptiveSkipper : : Initialize ( int * InitialValue , double FramesPerSecond )
2015-01-27 21:22:53 +01:00
{
initialValue = InitialValue ;
framesPerSecond = FramesPerSecond ;
currentValue = 0 ;
}
2015-02-06 10:25:25 +01:00
int cAdaptiveSkipper : : GetValue ( eKeys Key )
2015-01-27 21:22:53 +01:00
{
if ( ! initialValue )
return 0 ;
if ( timeout . TimedOut ( ) ) {
currentValue = int ( round ( * initialValue * framesPerSecond ) ) ;
lastKey = Key ;
}
else if ( Key ! = lastKey ) {
currentValue / = 2 ;
2015-02-06 10:25:25 +01:00
if ( Setup . AdaptiveSkipAlternate )
2015-02-02 13:59:19 +01:00
lastKey = Key ; // only halve the value when the direction is changed
2015-02-06 10:25:25 +01:00
else
lastKey = kNone ; // once the direction has changed, every further call halves the value
2015-01-27 21:22:53 +01:00
}
2015-02-06 10:25:25 +01:00
timeout . Set ( Setup . AdaptiveSkipTimeout * 1000 ) ;
2015-01-27 21:22:53 +01:00
return max ( currentValue , 1 ) ;
}
2000-04-29 15:57:42 +02:00
// --- cReplayControl --------------------------------------------------------
2006-10-20 13:42:14 +02:00
cReplayControl * cReplayControl : : currentReplayControl = NULL ;
2012-05-12 14:20:41 +02:00
cString cReplayControl : : fileName ;
2000-04-29 15:57:42 +02:00
2012-02-19 11:50:20 +01:00
cReplayControl : : cReplayControl ( bool PauseLive )
: cDvbPlayerControl ( fileName , PauseLive )
2000-04-29 15:57:42 +02:00
{
2013-02-01 12:06:50 +01:00
cDevice : : PrimaryDevice ( ) - > SetKeepTracks ( PauseLive ) ;
2006-10-20 13:42:14 +02:00
currentReplayControl = this ;
2004-05-16 10:35:36 +02:00
displayReplay = NULL ;
2012-09-09 09:19:15 +02:00
marksModified = false ;
2001-09-14 14:06:43 +02:00
visible = modeOnly = shown = displayFrames = false ;
2001-07-28 13:16:23 +02:00
lastCurrent = lastTotal = - 1 ;
2004-05-16 10:35:36 +02:00
lastPlay = lastForward = false ;
2006-11-04 13:19:31 +01:00
lastSpeed = - 2 ; // an invalid value
2001-07-28 14:06:36 +02:00
timeoutShow = 0 ;
2001-08-11 14:30:21 +02:00
timeSearchActive = false ;
2002-07-14 11:03:30 +02:00
cRecording Recording ( fileName ) ;
2005-12-31 15:20:19 +01:00
cStatus : : MsgReplaying ( this , Recording . Name ( ) , Recording . FileName ( ) , true ) ;
2009-01-06 14:41:11 +01:00
marks . Load ( fileName , Recording . FramesPerSecond ( ) , Recording . IsPesRecording ( ) ) ;
2015-02-06 15:42:21 +01:00
SetMarks ( & marks ) ;
2015-02-06 10:25:25 +01:00
adaptiveSkipper . Initialize ( & Setup . AdaptiveSkipInitial , Recording . FramesPerSecond ( ) ) ;
2006-04-14 14:47:01 +02:00
SetTrackDescriptions ( false ) ;
2012-12-05 11:49:33 +01:00
if ( Setup . ProgressDisplayTime )
ShowTimed ( Setup . ProgressDisplayTime ) ;
2000-04-29 15:57:42 +02:00
}
cReplayControl : : ~ cReplayControl ( )
{
2013-02-01 12:06:50 +01:00
cDevice : : PrimaryDevice ( ) - > SetKeepTracks ( false ) ;
2002-06-16 12:57:31 +02:00
Stop ( ) ;
2006-10-20 13:42:14 +02:00
if ( currentReplayControl = = this )
currentReplayControl = NULL ;
2000-04-29 15:57:42 +02:00
}
2010-03-07 12:43:30 +01:00
void cReplayControl : : Stop ( void )
{
2017-11-26 15:07:00 +01:00
Hide ( ) ;
cStatus : : MsgReplaying ( this , NULL , fileName , false ) ;
2012-05-12 14:20:41 +02:00
if ( Setup . DelTimeshiftRec & & * fileName ) {
2010-03-07 12:43:30 +01:00
cRecordControl * rc = cRecordControls : : GetRecordControl ( fileName ) ;
if ( rc & & rc - > InstantId ( ) ) {
if ( Active ( ) ) {
if ( Setup . DelTimeshiftRec = = 2 | | Interface - > Confirm ( tr ( " Delete timeshift recording? " ) ) ) {
2015-09-01 11:14:27 +02:00
{
LOCK_TIMERS_WRITE ;
Timers - > SetExplicitModify ( ) ;
cTimer * Timer = rc - > Timer ( ) ;
rc - > Stop ( false ) ; // don't execute user command
if ( Timer ) {
Timers - > Del ( Timer ) ;
Timers - > SetModified ( ) ;
2015-09-14 13:23:06 +02:00
isyslog ( " deleted timer %s " , * Timer - > ToDescr ( ) ) ;
2015-09-01 11:14:27 +02:00
}
}
2010-03-07 12:43:30 +01:00
cDvbPlayerControl : : Stop ( ) ;
2018-01-17 10:27:37 +01:00
bool Error = false ;
{
LOCK_RECORDINGS_WRITE ;
Recordings - > SetExplicitModify ( ) ;
if ( cRecording * Recording = Recordings - > GetByName ( fileName ) ) {
if ( Recording - > Delete ( ) ) {
Recordings - > DelByName ( fileName ) ;
ClearLastReplayed ( fileName ) ;
Recordings - > SetModified ( ) ;
}
else
Error = true ;
}
}
if ( Error )
Skins . Message ( mtError , tr ( " Error while deleting recording! " ) ) ;
2010-03-07 12:43:30 +01:00
return ;
}
}
}
}
cDvbPlayerControl : : Stop ( ) ;
2014-03-09 15:15:48 +01:00
cMenuRecordings : : SetRecording ( NULL ) ; // make sure opening the Recordings menu navigates to the last replayed recording
2010-03-07 12:43:30 +01:00
}
2018-02-01 16:08:15 +01:00
void cReplayControl : : ClearEditingMarks ( void )
{
cStateKey StateKey ;
marks . Lock ( StateKey ) ;
while ( cMark * m = marks . First ( ) )
marks . Del ( m ) ;
StateKey . Remove ( ) ;
cStatus : : MsgMarksModified ( NULL ) ;
}
2012-05-12 14:20:41 +02:00
void cReplayControl : : SetRecording ( const char * FileName )
2000-04-29 15:57:42 +02:00
{
2012-05-12 14:20:41 +02:00
fileName = FileName ;
2000-04-29 15:57:42 +02:00
}
2000-04-23 15:38:16 +02:00
2006-10-20 13:42:14 +02:00
const char * cReplayControl : : NowReplaying ( void )
{
2012-05-12 14:20:41 +02:00
return currentReplayControl ? * fileName : NULL ;
2006-10-20 13:42:14 +02:00
}
2000-10-08 15:08:26 +02:00
const char * cReplayControl : : LastReplayed ( void )
{
2015-09-01 11:14:27 +02:00
LOCK_RECORDINGS_READ ;
if ( ! Recordings - > GetByName ( fileName ) )
2013-03-18 09:19:42 +01:00
fileName = NULL ;
2000-10-08 15:08:26 +02:00
return fileName ;
}
2000-10-08 15:41:30 +02:00
void cReplayControl : : ClearLastReplayed ( const char * FileName )
{
2012-05-12 14:20:41 +02:00
if ( * fileName & & FileName & & strcmp ( fileName , FileName ) = = 0 )
2000-10-08 15:41:30 +02:00
fileName = NULL ;
}
2003-05-24 16:41:35 +02:00
void cReplayControl : : ShowTimed ( int Seconds )
2000-04-23 15:38:16 +02:00
{
2001-09-21 16:18:51 +02:00
if ( modeOnly )
Hide ( ) ;
2000-04-29 15:57:42 +02:00
if ( ! visible ) {
2000-12-09 11:13:00 +01:00
shown = ShowProgress ( true ) ;
2001-09-21 16:01:45 +02:00
timeoutShow = ( shown & & Seconds > 0 ) ? time ( NULL ) + Seconds : 0 ;
2000-04-29 15:57:42 +02:00
}
2012-03-03 15:03:09 +01:00
else if ( timeoutShow & & Seconds > 0 )
timeoutShow = time ( NULL ) + Seconds ;
2000-04-23 15:38:16 +02:00
}
2003-05-24 16:41:35 +02:00
void cReplayControl : : Show ( void )
{
ShowTimed ( ) ;
}
2000-04-29 15:57:42 +02:00
void cReplayControl : : Hide ( void )
2000-04-23 15:38:16 +02:00
{
2000-04-29 15:57:42 +02:00
if ( visible ) {
2004-05-16 10:35:36 +02:00
delete displayReplay ;
displayReplay = NULL ;
2007-01-07 14:46:14 +01:00
SetNeedsFastResponse ( false ) ;
visible = false ;
2001-10-28 10:21:01 +01:00
modeOnly = false ;
2004-05-16 10:35:36 +02:00
lastPlay = lastForward = false ;
2006-11-04 13:19:31 +01:00
lastSpeed = - 2 ; // an invalid value
2004-10-16 16:12:02 +02:00
timeSearchActive = false ;
2012-03-03 15:03:09 +01:00
timeoutShow = 0 ;
2000-04-29 15:57:42 +02:00
}
2012-11-18 13:12:31 +01:00
if ( marksModified ) {
marks . Save ( ) ;
marksModified = false ;
}
2000-04-23 15:38:16 +02:00
}
2001-09-14 15:10:12 +02:00
void cReplayControl : : ShowMode ( void )
{
2004-10-16 10:26:34 +02:00
if ( visible | | Setup . ShowReplayMode & & ! cOsd : : IsOpen ( ) ) {
2001-09-14 14:06:43 +02:00
bool Play , Forward ;
int Speed ;
2004-05-16 10:35:36 +02:00
if ( GetReplayMode ( Play , Forward , Speed ) & & ( ! visible | | Play ! = lastPlay | | Forward ! = lastForward | | Speed ! = lastSpeed ) ) {
2001-09-21 16:24:06 +02:00
bool NormalPlay = ( Play & & Speed = = - 1 ) ;
2001-09-14 14:06:43 +02:00
if ( ! visible ) {
2001-09-21 16:24:06 +02:00
if ( NormalPlay )
return ; // no need to do indicate ">" unless there was a different mode displayed before
2001-09-14 14:06:43 +02:00
visible = modeOnly = true ;
2004-05-16 10:35:36 +02:00
displayReplay = Skins . Current ( ) - > DisplayReplay ( modeOnly ) ;
2001-09-14 14:06:43 +02:00
}
2001-09-21 16:24:06 +02:00
if ( modeOnly & & ! timeoutShow & & NormalPlay )
2001-09-21 16:01:45 +02:00
timeoutShow = time ( NULL ) + MODETIMEOUT ;
2004-05-16 10:35:36 +02:00
displayReplay - > SetMode ( Play , Forward , Speed ) ;
lastPlay = Play ;
lastForward = Forward ;
lastSpeed = Speed ;
2001-09-14 14:06:43 +02:00
}
}
}
2000-12-09 11:13:00 +01:00
bool cReplayControl : : ShowProgress ( bool Initial )
{
int Current , Total ;
2018-04-14 10:24:41 +02:00
if ( ! ( Initial | | updateTimer . TimedOut ( ) ) )
return visible ;
2018-04-03 08:00:12 +02:00
if ( GetFrameNumber ( Current , Total ) & & Total > 0 ) {
if ( ! visible ) {
displayReplay = Skins . Current ( ) - > DisplayReplay ( modeOnly ) ;
displayReplay - > SetMarks ( & marks ) ;
SetNeedsFastResponse ( true ) ;
visible = true ;
}
if ( Initial ) {
if ( * fileName ) {
LOCK_RECORDINGS_READ ;
if ( const cRecording * Recording = Recordings - > GetByName ( fileName ) )
displayReplay - > SetRecording ( Recording ) ;
2016-12-22 11:33:12 +01:00
}
2018-04-03 08:00:12 +02:00
lastCurrent = lastTotal = - 1 ;
}
if ( Current ! = lastCurrent | | Total ! = lastTotal ) {
if ( Setup . ShowRemainingTime | | Total ! = lastTotal ) {
int Index = Total ;
if ( Setup . ShowRemainingTime )
Index = Current - Index ;
displayReplay - > SetTotal ( IndexToHMSF ( Index , false , FramesPerSecond ( ) ) ) ;
2016-12-22 11:33:12 +01:00
}
2018-04-03 08:00:12 +02:00
displayReplay - > SetProgress ( Current , Total ) ;
displayReplay - > SetCurrent ( IndexToHMSF ( Current , displayFrames , FramesPerSecond ( ) ) ) ;
displayReplay - > Flush ( ) ;
lastCurrent = Current ;
2001-07-28 13:16:23 +02:00
}
2018-04-03 08:00:12 +02:00
lastTotal = Total ;
ShowMode ( ) ;
2018-04-14 10:24:41 +02:00
updateTimer . Set ( PROGRESSTIMEOUT ) ;
2018-04-03 08:00:12 +02:00
return true ;
2000-12-09 11:13:00 +01:00
}
return false ;
}
2001-08-11 14:30:21 +02:00
void cReplayControl : : TimeSearchDisplay ( void )
{
char buf [ 64 ] ;
2007-08-11 12:39:06 +02:00
// TRANSLATORS: note the trailing blank!
2001-08-11 14:30:21 +02:00
strcpy ( buf , tr ( " Jump: " ) ) ;
2002-03-31 15:26:18 +02:00
int len = strlen ( buf ) ;
char h10 = ' 0 ' + ( timeSearchTime > > 24 ) ;
char h1 = ' 0 ' + ( ( timeSearchTime & 0x00FF0000 ) > > 16 ) ;
char m10 = ' 0 ' + ( ( timeSearchTime & 0x0000FF00 ) > > 8 ) ;
char m1 = ' 0 ' + ( timeSearchTime & 0x000000FF ) ;
char ch10 = timeSearchPos > 3 ? h10 : ' - ' ;
char ch1 = timeSearchPos > 2 ? h1 : ' - ' ;
char cm10 = timeSearchPos > 1 ? m10 : ' - ' ;
char cm1 = timeSearchPos > 0 ? m1 : ' - ' ;
sprintf ( buf + len , " %c%c:%c%c " , ch10 , ch1 , cm10 , cm1 ) ;
2004-05-16 10:35:36 +02:00
displayReplay - > SetJump ( buf ) ;
2001-08-11 14:30:21 +02:00
}
void cReplayControl : : TimeSearchProcess ( eKeys Key )
{
2002-03-31 15:26:18 +02:00
# define STAY_SECONDS_OFF_END 10
int Seconds = ( timeSearchTime > > 24 ) * 36000 + ( ( timeSearchTime & 0x00FF0000 ) > > 16 ) * 3600 + ( ( timeSearchTime & 0x0000FF00 ) > > 8 ) * 600 + ( timeSearchTime & 0x000000FF ) * 60 ;
2009-01-24 11:42:24 +01:00
int Current = int ( round ( lastCurrent / FramesPerSecond ( ) ) ) ;
int Total = int ( round ( lastTotal / FramesPerSecond ( ) ) ) ;
2001-08-11 14:30:21 +02:00
switch ( Key ) {
case k0 . . . k9 :
2002-03-31 15:26:18 +02:00
if ( timeSearchPos < 4 ) {
timeSearchTime < < = 8 ;
timeSearchTime | = Key - k0 ;
timeSearchPos + + ;
TimeSearchDisplay ( ) ;
}
2001-08-11 14:30:21 +02:00
break ;
2002-10-27 14:32:06 +01:00
case kFastRew :
2001-08-11 14:30:21 +02:00
case kLeft :
2002-10-27 14:32:06 +01:00
case kFastFwd :
2002-03-31 15:26:18 +02:00
case kRight : {
2002-10-27 14:32:06 +01:00
int dir = ( ( Key = = kRight | | Key = = kFastFwd ) ? 1 : - 1 ) ;
2002-03-31 15:26:18 +02:00
if ( dir > 0 )
Seconds = min ( Total - Current - STAY_SECONDS_OFF_END , Seconds ) ;
2002-06-16 12:57:31 +02:00
SkipSeconds ( Seconds * dir ) ;
2001-08-11 14:30:21 +02:00
timeSearchActive = false ;
2002-03-31 15:26:18 +02:00
}
2001-08-11 14:30:21 +02:00
break ;
2012-12-04 13:37:59 +01:00
case kPlayPause :
2002-10-27 14:32:06 +01:00
case kPlay :
2001-08-11 14:30:21 +02:00
case kUp :
2002-10-27 14:32:06 +01:00
case kPause :
2001-08-11 14:30:21 +02:00
case kDown :
2006-02-25 10:29:37 +01:00
case kOk :
2013-01-17 14:24:58 +01:00
if ( timeSearchPos > 0 ) {
Seconds = min ( Total - STAY_SECONDS_OFF_END , Seconds ) ;
2015-01-13 09:51:20 +01:00
bool Still = Key = = kDown | | Key = = kPause | | Key = = kOk ;
Goto ( SecondsToFrames ( Seconds , FramesPerSecond ( ) ) , Still ) ;
2013-01-17 14:24:58 +01:00
}
2001-08-11 14:30:21 +02:00
timeSearchActive = false ;
break ;
default :
2008-02-09 12:29:04 +01:00
if ( ! ( Key & k_Flags ) ) // ignore repeat/release keys
timeSearchActive = false ;
2001-08-11 14:30:21 +02:00
break ;
}
if ( ! timeSearchActive ) {
if ( timeSearchHide )
Hide ( ) ;
else
2004-05-16 10:35:36 +02:00
displayReplay - > SetJump ( NULL ) ;
2001-09-14 14:06:43 +02:00
ShowMode ( ) ;
2001-08-11 14:30:21 +02:00
}
}
void cReplayControl : : TimeSearch ( void )
{
2002-03-31 15:26:18 +02:00
timeSearchTime = timeSearchPos = 0 ;
2001-08-11 14:30:21 +02:00
timeSearchHide = false ;
2001-09-15 10:36:31 +02:00
if ( modeOnly )
Hide ( ) ;
2001-08-11 14:30:21 +02:00
if ( ! visible ) {
Show ( ) ;
if ( visible )
timeSearchHide = true ;
else
return ;
}
2002-04-20 09:23:02 +02:00
timeoutShow = 0 ;
2001-08-11 14:30:21 +02:00
TimeSearchDisplay ( ) ;
timeSearchActive = true ;
}
2000-12-28 12:57:16 +01:00
void cReplayControl : : MarkToggle ( void )
{
int Current , Total ;
2002-06-16 12:57:31 +02:00
if ( GetIndex ( Current , Total , true ) ) {
2001-08-11 15:08:14 +02:00
lastCurrent = - 1 ; // triggers redisplay
2015-09-01 11:14:27 +02:00
cStateKey StateKey ;
marks . Lock ( StateKey ) ;
if ( cMark * m = marks . Get ( Current ) )
2000-12-28 12:57:16 +01:00
marks . Del ( m ) ;
2001-07-28 14:06:36 +02:00
else {
2000-12-28 12:57:16 +01:00
marks . Add ( Current ) ;
2003-09-06 10:35:24 +02:00
bool Play , Forward ;
int Speed ;
2013-04-27 10:31:23 +02:00
if ( Setup . PauseOnMarkSet | | GetReplayMode ( Play , Forward , Speed ) & & ! Play ) {
2003-09-06 10:35:24 +02:00
Goto ( Current , true ) ;
2013-04-27 10:31:23 +02:00
displayFrames = true ;
}
2001-07-28 14:06:36 +02:00
}
2015-09-01 11:14:27 +02:00
StateKey . Remove ( ) ;
2012-03-03 14:49:59 +01:00
ShowTimed ( 2 ) ;
2012-09-09 09:19:15 +02:00
marksModified = true ;
2018-01-29 14:09:59 +01:00
cStatus : : MsgMarksModified ( & marks ) ;
2000-12-28 12:57:16 +01:00
}
}
void cReplayControl : : MarkJump ( bool Forward )
{
2012-12-04 10:09:08 +01:00
int Current , Total ;
if ( GetIndex ( Current , Total ) ) {
if ( marks . Count ( ) ) {
2013-02-11 11:27:34 +01:00
if ( cMark * m = Forward ? marks . GetNext ( Current ) : marks . GetPrev ( Current ) ) {
2015-01-26 10:20:51 +01:00
if ( ! Setup . PauseOnMarkJump ) {
bool Playing , Fwd ;
int Speed ;
if ( GetReplayMode ( Playing , Fwd , Speed ) & & Playing & & Forward & & m - > Position ( ) < Total - SecondsToFrames ( 3 , FramesPerSecond ( ) ) ) {
Goto ( m - > Position ( ) ) ;
return ;
}
}
2011-08-21 11:34:30 +02:00
Goto ( m - > Position ( ) , true ) ;
2005-08-14 13:01:27 +02:00
displayFrames = true ;
2012-12-04 10:09:08 +01:00
return ;
2005-08-14 13:01:27 +02:00
}
2001-07-22 13:46:07 +02:00
}
2012-12-04 10:09:08 +01:00
// There are either no marks at all, or we already were at the first or last one,
// so jump to the very beginning or end:
Goto ( Forward ? Total : 0 , true ) ;
2000-12-28 12:57:16 +01:00
}
}
2015-01-27 21:22:53 +01:00
void cReplayControl : : MarkMove ( int Frames , bool MarkRequired )
2000-12-28 12:57:16 +01:00
{
int Current , Total ;
2002-06-16 12:57:31 +02:00
if ( GetIndex ( Current , Total ) ) {
2015-01-27 21:22:53 +01:00
bool Play , Forward ;
int Speed ;
GetReplayMode ( Play , Forward , Speed ) ;
cMark * m = marks . Get ( Current ) ;
if ( ! Play & & m ) {
2001-07-22 13:46:07 +02:00
displayFrames = true ;
2000-12-28 12:57:16 +01:00
cMark * m2 ;
2015-01-27 21:22:53 +01:00
if ( Frames > 0 ) {
// Handle marks at the same offset:
2012-11-18 13:00:33 +01:00
while ( ( m2 = marks . Next ( m ) ) ! = NULL & & m2 - > Position ( ) = = m - > Position ( ) )
m = m2 ;
2015-01-27 21:22:53 +01:00
// Don't skip the next mark:
if ( ( m2 = marks . Next ( m ) ) ! = NULL )
Frames = min ( Frames , m2 - > Position ( ) - m - > Position ( ) - 1 ) ;
2000-12-28 12:57:16 +01:00
}
else {
2015-01-27 21:22:53 +01:00
// Handle marks at the same offset:
2012-11-18 13:00:33 +01:00
while ( ( m2 = marks . Prev ( m ) ) ! = NULL & & m2 - > Position ( ) = = m - > Position ( ) )
m = m2 ;
2015-01-27 21:22:53 +01:00
// Don't skip the next mark:
if ( ( m2 = marks . Prev ( m ) ) ! = NULL )
Frames = - min ( - Frames , m - > Position ( ) - m2 - > Position ( ) - 1 ) ;
2000-12-28 12:57:16 +01:00
}
2015-01-27 21:22:53 +01:00
int p = SkipFrames ( Frames ) ;
2011-08-21 11:34:30 +02:00
m - > SetPosition ( p ) ;
Goto ( m - > Position ( ) , true ) ;
2012-09-09 09:19:15 +02:00
marksModified = true ;
2018-01-29 14:09:59 +01:00
cStatus : : MsgMarksModified ( & marks ) ;
2000-12-28 12:57:16 +01:00
}
2015-02-01 11:20:54 +01:00
else if ( ! MarkRequired )
2015-01-27 21:22:53 +01:00
Goto ( SkipFrames ( Frames ) , ! Play ) ;
2000-12-28 12:57:16 +01:00
}
}
void cReplayControl : : EditCut ( void )
{
2012-05-12 14:20:41 +02:00
if ( * fileName ) {
2001-10-27 12:04:36 +02:00
Hide ( ) ;
2013-10-10 13:13:30 +02:00
if ( ! RecordingsHandler . GetUsage ( fileName ) ) {
2003-05-16 12:46:15 +02:00
if ( ! marks . Count ( ) )
2004-05-16 10:35:36 +02:00
Skins . Message ( mtError , tr ( " No editing marks defined! " ) ) ;
2012-11-18 12:19:51 +01:00
else if ( ! marks . GetNumSequences ( ) )
Skins . Message ( mtError , tr ( " No editing sequences defined! " ) ) ;
2013-10-21 08:23:19 +02:00
else if ( access ( cCutter : : EditedFileName ( fileName ) , F_OK ) = = 0 & & ! Interface - > Confirm ( tr ( " Edited version already exists - overwrite? " ) ) )
;
2013-10-10 13:13:30 +02:00
else if ( ! RecordingsHandler . Add ( ruCut , fileName ) )
2004-05-16 10:35:36 +02:00
Skins . Message ( mtError , tr ( " Can't start editing process! " ) ) ;
2001-10-27 12:04:36 +02:00
else
2004-05-16 10:35:36 +02:00
Skins . Message ( mtInfo , tr ( " Editing process started " ) ) ;
2001-10-27 12:04:36 +02:00
}
2000-12-28 12:57:16 +01:00
else
2004-05-16 10:35:36 +02:00
Skins . Message ( mtError , tr ( " Editing process already active! " ) ) ;
2001-10-28 10:21:01 +01:00
ShowMode ( ) ;
2000-12-28 12:57:16 +01:00
}
}
void cReplayControl : : EditTest ( void )
{
int Current , Total ;
2002-06-16 12:57:31 +02:00
if ( GetIndex ( Current , Total ) ) {
2000-12-28 12:57:16 +01:00
cMark * m = marks . Get ( Current ) ;
if ( ! m )
m = marks . GetNext ( Current ) ;
if ( m ) {
2015-01-31 11:42:05 +01:00
if ( ( m - > Index ( ) & 0x01 ) ! = 0 & & ! Setup . SkipEdited ) // when skipping edited parts we also need to jump to end marks
2000-12-28 12:57:16 +01:00
m = marks . Next ( m ) ;
2015-02-01 11:20:54 +01:00
if ( m )
2011-08-21 11:34:30 +02:00
Goto ( m - > Position ( ) - SecondsToFrames ( 3 , FramesPerSecond ( ) ) ) ;
2000-12-28 12:57:16 +01:00
}
}
}
2006-01-06 12:53:28 +01:00
cOsdObject * cReplayControl : : GetInfo ( void )
{
2015-09-01 11:14:27 +02:00
LOCK_RECORDINGS_READ ;
if ( const cRecording * Recording = Recordings - > GetByName ( cReplayControl : : LastReplayed ( ) ) )
2006-01-15 15:06:19 +01:00
return new cMenuRecording ( Recording , false ) ;
2006-01-06 12:53:28 +01:00
return NULL ;
}
2012-04-28 13:09:42 +02:00
const cRecording * cReplayControl : : GetRecording ( void )
{
2015-09-01 11:14:27 +02:00
LOCK_RECORDINGS_READ ;
if ( const cRecording * Recording = Recordings - > GetByName ( LastReplayed ( ) ) )
2012-04-28 13:09:42 +02:00
return Recording ;
return NULL ;
}
2000-04-29 15:57:42 +02:00
eOSState cReplayControl : : ProcessKey ( eKeys Key )
2000-04-23 15:38:16 +02:00
{
2002-06-16 12:57:31 +02:00
if ( ! Active ( ) )
2000-04-29 15:57:42 +02:00
return osEnd ;
2013-02-11 11:27:34 +01:00
if ( Key = = kNone & & ! marksModified )
2011-02-27 13:40:43 +01:00
marks . Update ( ) ;
2001-07-28 14:06:36 +02:00
if ( visible ) {
if ( timeoutShow & & time ( NULL ) > timeoutShow ) {
Hide ( ) ;
2001-10-28 10:21:01 +01:00
ShowMode ( ) ;
2001-07-28 14:06:36 +02:00
timeoutShow = 0 ;
}
2002-03-31 10:57:28 +02:00
else if ( modeOnly )
ShowMode ( ) ;
2002-04-16 16:11:40 +02:00
else
2001-07-28 14:06:36 +02:00
shown = ShowProgress ( ! shown ) | | shown ;
}
2001-07-22 13:46:07 +02:00
bool DisplayedFrames = displayFrames ;
displayFrames = false ;
2001-08-11 14:30:21 +02:00
if ( timeSearchActive & & Key ! = kNone ) {
TimeSearchProcess ( Key ) ;
return osContinue ;
}
2012-12-04 13:37:59 +01:00
if ( Key = = kPlayPause ) {
bool Play , Forward ;
int Speed ;
GetReplayMode ( Play , Forward , Speed ) ;
2012-12-06 11:08:56 +01:00
if ( Speed > = 0 )
Key = Play ? kPlay : kPause ;
else
Key = Play ? kPause : kPlay ;
2012-12-04 13:37:59 +01:00
}
2001-09-14 14:06:43 +02:00
bool DoShowMode = true ;
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2000-12-28 12:57:16 +01:00
// Positioning:
2002-10-27 14:32:06 +01:00
case kPlay :
2002-06-16 12:57:31 +02:00
case kUp : Play ( ) ; break ;
2002-10-27 14:32:06 +01:00
case kPause :
2002-06-16 12:57:31 +02:00
case kDown : Pause ( ) ; break ;
2002-10-27 14:32:06 +01:00
case kFastRew | k_Release :
2000-10-08 11:39:11 +02:00
case kLeft | k_Release :
2001-09-09 12:52:41 +02:00
if ( Setup . MultiSpeedMode ) break ;
2002-10-27 14:32:06 +01:00
case kFastRew :
2002-06-16 12:57:31 +02:00
case kLeft : Backward ( ) ; break ;
2002-10-27 14:32:06 +01:00
case kFastFwd | k_Release :
2000-10-08 11:39:11 +02:00
case kRight | k_Release :
2001-09-09 12:52:41 +02:00
if ( Setup . MultiSpeedMode ) break ;
2002-10-27 14:32:06 +01:00
case kFastFwd :
2002-06-16 12:57:31 +02:00
case kRight : Forward ( ) ; break ;
2001-08-11 14:30:21 +02:00
case kRed : TimeSearch ( ) ; break ;
2000-10-08 11:39:11 +02:00
case kGreen | k_Repeat :
2015-02-10 12:18:39 +01:00
SkipSeconds ( - Setup . SkipSecondsRepeat ) ; break ;
case kGreen : SkipSeconds ( - Setup . SkipSeconds ) ; break ;
2000-10-08 11:39:11 +02:00
case kYellow | k_Repeat :
2015-02-10 12:18:39 +01:00
SkipSeconds ( Setup . SkipSecondsRepeat ) ; break ;
case kYellow : SkipSeconds ( Setup . SkipSeconds ) ; break ;
2002-10-27 14:32:06 +01:00
case kStop :
2017-11-26 15:07:00 +01:00
case kBlue : Stop ( ) ;
2000-12-28 12:57:16 +01:00
return osEnd ;
2001-07-22 13:46:07 +02:00
default : {
2001-09-14 14:06:43 +02:00
DoShowMode = false ;
2010-12-12 13:42:00 +01:00
switch ( int ( Key ) ) {
2001-07-22 13:46:07 +02:00
// Editing:
case kMarkToggle : MarkToggle ( ) ; break ;
2006-04-15 13:46:55 +02:00
case kPrev | k_Repeat :
2015-02-10 12:51:07 +01:00
case kPrev : if ( Setup . AdaptiveSkipPrevNext ) {
MarkMove ( - adaptiveSkipper . GetValue ( RAWKEY ( Key ) ) , false ) ;
break ;
}
// fall through...
2003-09-14 10:53:06 +02:00
case kMarkJumpBack | k_Repeat :
2001-07-22 13:46:07 +02:00
case kMarkJumpBack : MarkJump ( false ) ; break ;
2006-04-15 13:46:55 +02:00
case kNext | k_Repeat :
2015-02-10 12:51:07 +01:00
case kNext : if ( Setup . AdaptiveSkipPrevNext ) {
MarkMove ( + adaptiveSkipper . GetValue ( RAWKEY ( Key ) ) , false ) ;
break ;
}
// fall through...
2003-09-14 10:53:06 +02:00
case kMarkJumpForward | k_Repeat :
2001-07-22 13:46:07 +02:00
case kMarkJumpForward : MarkJump ( true ) ; break ;
case kMarkMoveBack | k_Repeat :
2015-01-27 21:22:53 +01:00
case kMarkMoveBack : MarkMove ( - 1 , true ) ; break ;
2001-07-22 13:46:07 +02:00
case kMarkMoveForward | k_Repeat :
2015-01-27 21:22:53 +01:00
case kMarkMoveForward : MarkMove ( + 1 , true ) ; break ;
case kMarkSkipBack | k_Repeat :
2015-02-06 10:25:25 +01:00
case kMarkSkipBack : MarkMove ( - adaptiveSkipper . GetValue ( RAWKEY ( Key ) ) , false ) ; break ;
2015-01-27 21:22:53 +01:00
case kMarkSkipForward | k_Repeat :
2015-02-06 10:25:25 +01:00
case kMarkSkipForward : MarkMove ( + adaptiveSkipper . GetValue ( RAWKEY ( Key ) ) , false ) ; break ;
2001-07-22 13:46:07 +02:00
case kEditCut : EditCut ( ) ; break ;
case kEditTest : EditTest ( ) ; break ;
default : {
displayFrames = DisplayedFrames ;
switch ( Key ) {
// Menu control:
2001-10-28 10:21:01 +01:00
case kOk : if ( visible & & ! modeOnly ) {
2001-09-21 16:18:51 +02:00
Hide ( ) ;
2001-10-28 10:21:01 +01:00
DoShowMode = true ;
}
2001-09-21 16:18:51 +02:00
else
Show ( ) ;
break ;
2017-11-26 15:07:00 +01:00
case kBack : Stop ( ) ;
2010-03-07 12:43:30 +01:00
return osRecordings ;
2001-07-22 13:46:07 +02:00
default : return osUnknown ;
}
}
}
}
2000-04-23 15:38:16 +02:00
}
2001-09-14 14:06:43 +02:00
if ( DoShowMode )
ShowMode ( ) ;
2000-04-29 15:57:42 +02:00
return osContinue ;
2000-04-23 15:38:16 +02:00
}