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 .
*
2001-08-03 14:18:08 +02:00
* $ Id : menu . c 1.90 2001 / 08 / 03 14 : 18 : 08 kls Exp $
2000-02-19 13:36:48 +01:00
*/
# include "menu.h"
# include <limits.h>
# 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>
# include "config.h"
2000-10-29 13:17:22 +01:00
# include "eit.h"
2000-11-11 10:39:27 +01:00
# include "i18n.h"
2000-02-19 13:36:48 +01:00
2000-05-01 16:29:46 +02:00
# define MENUTIMEOUT 120 // seconds
2000-07-16 15:02:33 +02:00
const char * FileNameChars = " aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789-.#^ " ;
2000-02-19 13:36:48 +01:00
// --- cMenuEditItem ---------------------------------------------------------
class cMenuEditItem : public cOsdItem {
private :
const char * name ;
const char * value ;
public :
cMenuEditItem ( const char * Name ) ;
~ cMenuEditItem ( ) ;
void SetValue ( const char * Value ) ;
} ;
cMenuEditItem : : cMenuEditItem ( const char * Name )
{
name = strdup ( Name ) ;
value = NULL ;
}
cMenuEditItem : : ~ cMenuEditItem ( )
{
delete name ;
delete value ;
}
void cMenuEditItem : : SetValue ( const char * Value )
{
delete value ;
value = strdup ( Value ) ;
char * buffer = NULL ;
asprintf ( & buffer , " %s: \t %s " , name , value ) ;
SetText ( buffer , false ) ;
Display ( ) ;
}
// --- cMenuEditIntItem ------------------------------------------------------
class cMenuEditIntItem : public cMenuEditItem {
protected :
int * value ;
int min , max ;
virtual void Set ( void ) ;
public :
cMenuEditIntItem ( const char * Name , int * Value , int Min = 0 , int Max = INT_MAX ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuEditIntItem : : cMenuEditIntItem ( const char * Name , int * Value , int Min , int Max )
: cMenuEditItem ( Name )
{
value = Value ;
min = Min ;
max = Max ;
Set ( ) ;
}
void cMenuEditIntItem : : Set ( void )
{
char buf [ 16 ] ;
snprintf ( buf , sizeof ( buf ) , " %d " , * value ) ;
SetValue ( buf ) ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditIntItem : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
2000-03-11 11:22:37 +01:00
eOSState state = cMenuEditItem : : 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
int newValue ;
if ( k0 < = Key & & Key < = k9 ) {
if ( fresh ) {
* value = 0 ;
fresh = false ;
}
newValue = * value * 10 + ( Key - k0 ) ;
}
2000-10-08 11:39:11 +02:00
else if ( NORMALKEY ( Key ) = = kLeft ) { // TODO might want to increase the delta if repeated quickly?
2000-02-19 13:36:48 +01:00
newValue = * value - 1 ;
fresh = true ;
}
2000-10-08 11:39:11 +02:00
else if ( NORMALKEY ( Key ) = = kRight ) {
2000-02-19 13:36:48 +01:00
newValue = * value + 1 ;
fresh = true ;
}
else
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
if ( ( ! fresh | | min < = newValue ) & & newValue < = max ) {
* value = newValue ;
Set ( ) ;
}
2000-03-11 11:22:37 +01:00
state = osContinue ;
2000-02-19 13:36:48 +01:00
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
// --- cMenuEditBoolItem -----------------------------------------------------
class cMenuEditBoolItem : public cMenuEditIntItem {
protected :
2001-06-16 14:31:14 +02:00
const char * falseString , * trueString ;
2000-02-19 13:36:48 +01:00
virtual void Set ( void ) ;
public :
2001-06-16 14:31:14 +02:00
cMenuEditBoolItem ( const char * Name , int * Value , const char * FalseString = NULL , const char * TrueString = NULL ) ;
2000-02-19 13:36:48 +01:00
} ;
2001-06-16 14:31:14 +02:00
cMenuEditBoolItem : : cMenuEditBoolItem ( const char * Name , int * Value , const char * FalseString , const char * TrueString )
2000-02-19 13:36:48 +01:00
: cMenuEditIntItem ( Name , Value , 0 , 1 )
{
2001-06-16 14:31:14 +02:00
falseString = FalseString ? FalseString : tr ( " no " ) ;
trueString = TrueString ? TrueString : tr ( " yes " ) ;
2000-02-19 13:36:48 +01:00
Set ( ) ;
}
void cMenuEditBoolItem : : Set ( void )
{
char buf [ 16 ] ;
2001-06-16 14:31:14 +02:00
snprintf ( buf , sizeof ( buf ) , " %s " , * value ? trueString : falseString ) ;
2000-02-19 13:36:48 +01:00
SetValue ( buf ) ;
}
// --- cMenuEditChanItem -----------------------------------------------------
class cMenuEditChanItem : public cMenuEditIntItem {
protected :
virtual void Set ( void ) ;
public :
cMenuEditChanItem ( const char * Name , int * Value ) ;
} ;
cMenuEditChanItem : : cMenuEditChanItem ( const char * Name , int * Value )
2000-09-09 14:57:43 +02:00
: cMenuEditIntItem ( Name , Value , 1 , Channels . MaxNumber ( ) )
2000-02-19 13:36:48 +01:00
{
Set ( ) ;
}
void cMenuEditChanItem : : Set ( void )
{
char buf [ 255 ] ;
2000-09-09 14:57:43 +02:00
cChannel * channel = Channels . GetByNumber ( * value ) ;
2000-02-19 13:36:48 +01:00
if ( channel )
snprintf ( buf , sizeof ( buf ) , " %d %s " , * value , channel - > name ) ;
else
* buf = 0 ;
SetValue ( buf ) ;
}
// --- cMenuEditDayItem ------------------------------------------------------
class cMenuEditDayItem : public cMenuEditIntItem {
protected :
static int days [ ] ;
int d ;
virtual void Set ( void ) ;
public :
cMenuEditDayItem ( const char * Name , int * Value ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
int cMenuEditDayItem : : days [ ] = { cTimer : : ParseDay ( " M------ " ) ,
cTimer : : ParseDay ( " -T----- " ) ,
cTimer : : ParseDay ( " --W---- " ) ,
cTimer : : ParseDay ( " ---T--- " ) ,
cTimer : : ParseDay ( " ----F-- " ) ,
cTimer : : ParseDay ( " -----S- " ) ,
cTimer : : ParseDay ( " ------S " ) ,
cTimer : : ParseDay ( " MTWTF-- " ) ,
cTimer : : ParseDay ( " MTWTFS- " ) ,
cTimer : : ParseDay ( " MTWTFSS " ) ,
cTimer : : ParseDay ( " -----SS " ) ,
0 } ;
cMenuEditDayItem : : cMenuEditDayItem ( const char * Name , int * Value )
: cMenuEditIntItem ( Name , Value , - INT_MAX , 31 )
{
d = - 1 ;
if ( * value < 0 ) {
int n = 0 ;
while ( days [ n ] ) {
if ( days [ n ] = = * value ) {
d = n ;
break ;
}
n + + ;
}
}
Set ( ) ;
}
void cMenuEditDayItem : : Set ( void )
{
SetValue ( cTimer : : PrintDay ( * value ) ) ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditDayItem : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
switch ( Key ) {
2000-10-08 11:39:11 +02:00
case kLeft | k_Repeat :
2000-02-19 13:36:48 +01:00
case kLeft : if ( d > 0 )
* value = days [ - - d ] ;
else if ( d = = 0 ) {
* value = 31 ;
d = - 1 ;
}
else if ( * value = = 1 ) {
d = sizeof ( days ) / sizeof ( int ) - 2 ;
* value = days [ d ] ;
}
else
return cMenuEditIntItem : : ProcessKey ( Key ) ;
Set ( ) ;
break ;
2000-10-08 11:39:11 +02:00
case kRight | k_Repeat :
2000-02-19 13:36:48 +01:00
case kRight : if ( d > = 0 ) {
* value = days [ + + d ] ;
if ( * value = = 0 ) {
* value = 1 ;
d = - 1 ;
}
}
else if ( * value = = 31 ) {
d = 0 ;
* value = days [ d ] ;
}
else
return cMenuEditIntItem : : ProcessKey ( Key ) ;
Set ( ) ;
break ;
default : return cMenuEditIntItem : : ProcessKey ( Key ) ;
}
return osContinue ;
}
// --- cMenuEditTimeItem -----------------------------------------------------
class cMenuEditTimeItem : public cMenuEditItem {
protected :
int * value ;
int hh , mm ;
int pos ;
virtual void Set ( void ) ;
public :
cMenuEditTimeItem ( const char * Name , int * Value ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuEditTimeItem : : cMenuEditTimeItem ( const char * Name , int * Value )
: cMenuEditItem ( Name )
{
value = Value ;
hh = * value / 100 ;
mm = * value % 100 ;
pos = 0 ;
Set ( ) ;
}
void cMenuEditTimeItem : : Set ( void )
{
char buf [ 10 ] ;
2001-07-28 13:48:52 +02:00
switch ( pos ) {
case 1 : snprintf ( buf , sizeof ( buf ) , " %01d-:-- " , hh / 10 ) ; break ;
case 2 : snprintf ( buf , sizeof ( buf ) , " %02d:-- " , hh ) ; break ;
case 3 : snprintf ( buf , sizeof ( buf ) , " %02d:%01d- " , hh , mm / 10 ) ; break ;
default : snprintf ( buf , sizeof ( buf ) , " %02d:%02d " , hh , mm ) ;
}
2000-02-19 13:36:48 +01:00
SetValue ( buf ) ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditTimeItem : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
2000-03-11 11:22:37 +01:00
eOSState state = cMenuEditItem : : 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 ( k0 < = Key & & Key < = k9 ) {
if ( fresh | | pos > 3 ) {
pos = 0 ;
fresh = false ;
}
int n = Key - k0 ;
switch ( pos ) {
case 0 : if ( n < = 2 ) {
hh = n * 10 ;
mm = 0 ;
pos + + ;
}
break ;
case 1 : if ( hh + n < = 23 ) {
hh + = n ;
pos + + ;
}
break ;
case 2 : if ( n < = 5 ) {
mm + = n * 10 ;
pos + + ;
}
break ;
case 3 : if ( mm + n < = 59 ) {
mm + = n ;
pos + + ;
}
break ;
}
}
2000-10-08 11:39:11 +02:00
else if ( NORMALKEY ( Key ) = = kLeft ) { // TODO might want to increase the delta if repeated quickly?
2000-02-19 13:36:48 +01:00
if ( - - mm < 0 ) {
mm = 59 ;
if ( - - hh < 0 )
hh = 23 ;
}
fresh = true ;
}
2000-10-08 11:39:11 +02:00
else if ( NORMALKEY ( Key ) = = kRight ) {
2000-02-19 13:36:48 +01:00
if ( + + mm > 59 ) {
mm = 0 ;
if ( + + hh > 23 )
hh = 0 ;
}
fresh = true ;
}
else
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
* value = hh * 100 + mm ;
Set ( ) ;
2000-03-11 11:22:37 +01:00
state = osContinue ;
2000-02-19 13:36:48 +01:00
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
// --- cMenuEditChrItem ------------------------------------------------------
class cMenuEditChrItem : public cMenuEditItem {
private :
char * value ;
const char * allowed ;
const char * current ;
virtual void Set ( void ) ;
public :
cMenuEditChrItem ( const char * Name , char * Value , const char * Allowed ) ;
~ cMenuEditChrItem ( ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuEditChrItem : : cMenuEditChrItem ( const char * Name , char * Value , const char * Allowed )
: cMenuEditItem ( Name )
{
value = Value ;
allowed = strdup ( Allowed ) ;
current = strchr ( allowed , * Value ) ;
if ( ! current )
current = allowed ;
Set ( ) ;
}
cMenuEditChrItem : : ~ cMenuEditChrItem ( )
{
delete allowed ;
}
void cMenuEditChrItem : : Set ( void )
{
char buf [ 2 ] ;
snprintf ( buf , sizeof ( buf ) , " %c " , * value ) ;
SetValue ( buf ) ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditChrItem : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
2000-03-11 11:22:37 +01:00
eOSState state = cMenuEditItem : : ProcessKey ( Key ) ;
2000-02-19 13:36:48 +01:00
2000-03-11 11:22:37 +01:00
if ( state = = osUnknown ) {
2000-10-08 11:39:11 +02:00
if ( NORMALKEY ( Key ) = = kLeft ) {
2000-02-19 13:36:48 +01:00
if ( current > allowed )
current - - ;
}
2000-10-08 11:39:11 +02:00
else if ( NORMALKEY ( Key ) = = kRight ) {
2000-02-19 13:36:48 +01:00
if ( * ( current + 1 ) )
current + + ;
}
else
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
* value = * current ;
Set ( ) ;
2000-03-11 11:22:37 +01:00
state = osContinue ;
2000-02-19 13:36:48 +01:00
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
// --- cMenuEditStrItem ------------------------------------------------------
class cMenuEditStrItem : public cMenuEditItem {
private :
char * value ;
int length ;
const char * allowed ;
int pos ;
virtual void Set ( void ) ;
char Inc ( char c , bool Up ) ;
public :
cMenuEditStrItem ( const char * Name , char * Value , int Length , const char * Allowed ) ;
~ cMenuEditStrItem ( ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuEditStrItem : : cMenuEditStrItem ( const char * Name , char * Value , int Length , const char * Allowed )
: cMenuEditItem ( Name )
{
value = Value ;
length = Length ;
allowed = strdup ( Allowed ) ;
pos = - 1 ;
Set ( ) ;
}
cMenuEditStrItem : : ~ cMenuEditStrItem ( )
{
delete allowed ;
}
void cMenuEditStrItem : : Set ( void )
{
char buf [ 1000 ] ;
if ( pos > = 0 ) {
strncpy ( buf , value , pos ) ;
2000-07-16 15:02:33 +02:00
const char * s = value [ pos ] ! = ' ^ ' ? value + pos + 1 : " " ;
2000-02-19 13:36:48 +01:00
snprintf ( buf + pos , sizeof ( buf ) - pos - 2 , " [%c]%s " , * ( value + pos ) , s ) ;
SetValue ( buf ) ;
}
else
SetValue ( value ) ;
}
char cMenuEditStrItem : : Inc ( char c , bool Up )
{
const char * p = strchr ( allowed , c ) ;
if ( ! p )
p = allowed ;
if ( Up ) {
if ( ! * + + p )
p = allowed ;
}
else if ( - - p < allowed )
p = allowed + strlen ( allowed ) - 1 ;
return * p ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditStrItem : : ProcessKey ( eKeys Key )
2000-02-19 13:36:48 +01:00
{
switch ( Key ) {
2000-10-08 11:39:11 +02:00
case kLeft | k_Repeat :
2000-02-19 13:36:48 +01:00
case kLeft : if ( pos > 0 ) {
2000-07-16 15:02:33 +02:00
if ( value [ pos ] = = ' ^ ' )
2000-02-19 13:36:48 +01:00
value [ pos ] = 0 ;
pos - - ;
}
break ;
2000-10-08 11:39:11 +02:00
case kRight | k_Repeat :
2000-07-16 15:02:33 +02:00
case kRight : if ( pos < length & & value [ pos ] ! = ' ^ ' & & ( pos < int ( strlen ( value ) - 1 ) | | value [ pos ] ! = ' ' ) ) {
2000-02-19 13:36:48 +01:00
if ( + + pos > = int ( strlen ( value ) ) ) {
value [ pos ] = ' ' ;
value [ pos + 1 ] = 0 ;
}
}
break ;
2000-10-08 11:39:11 +02:00
case kUp | k_Repeat :
2000-02-19 13:36:48 +01:00
case kUp :
2000-10-08 11:39:11 +02:00
case kDown | k_Repeat :
2000-02-19 13:36:48 +01:00
case kDown : if ( pos > = 0 )
2000-10-08 11:39:11 +02:00
value [ pos ] = Inc ( value [ pos ] , NORMALKEY ( Key ) = = kUp ) ;
2000-02-19 13:36:48 +01:00
else
return cMenuEditItem : : ProcessKey ( Key ) ;
break ;
case kOk : if ( pos > = 0 ) {
2000-07-16 15:02:33 +02:00
if ( value [ pos ] = = ' ^ ' )
2000-02-19 13:36:48 +01:00
value [ pos ] = 0 ;
pos = - 1 ;
break ;
}
// run into default
default : return cMenuEditItem : : ProcessKey ( Key ) ;
}
Set ( ) ;
return osContinue ;
}
2000-11-11 10:39:27 +01:00
// --- cMenuEditStraItem -----------------------------------------------------
class cMenuEditStraItem : public cMenuEditIntItem {
private :
const char * const * strings ;
protected :
virtual void Set ( void ) ;
public :
cMenuEditStraItem ( const char * Name , int * Value , int NumStrings , const char * const * Strings ) ;
} ;
cMenuEditStraItem : : cMenuEditStraItem ( const char * Name , int * Value , int NumStrings , const char * const * Strings )
: cMenuEditIntItem ( Name , Value , 0 , NumStrings - 1 )
{
strings = Strings ;
Set ( ) ;
}
void cMenuEditStraItem : : Set ( void )
{
SetValue ( strings [ * value ] ) ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuEditChannel ------------------------------------------------------
class cMenuEditChannel : public cOsdMenu {
private :
cChannel * channel ;
cChannel data ;
public :
cMenuEditChannel ( int Index ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuEditChannel : : cMenuEditChannel ( int Index )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Edit Channel " ) , 14 )
2000-02-19 13:36:48 +01:00
{
channel = Channels . Get ( Index ) ;
if ( channel ) {
data = * channel ;
2000-11-11 10:39:27 +01:00
Add ( new cMenuEditStrItem ( tr ( " Name " ) , data . name , sizeof ( data . name ) , FileNameChars ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Frequency " ) , & data . frequency , 10000 , 13000 ) ) ; //TODO exact limits???
Add ( new cMenuEditChrItem ( tr ( " Polarization " ) , & data . polarization , " hv " ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Diseqc " ) , & data . diseqc , 0 , 10 ) ) ; //TODO exact limits???
2001-07-27 10:28:55 +02:00
Add ( new cMenuEditIntItem ( tr ( " Srate " ) , & data . srate , 22000 , 30000 ) ) ; //TODO exact limits - toggle???
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditIntItem ( tr ( " Vpid " ) , & data . vpid , 0 , 0xFFFE ) ) ;
2001-06-03 13:07:20 +02:00
Add ( new cMenuEditIntItem ( tr ( " Apid1 " ) , & data . apid1 , 0 , 0xFFFE ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Apid2 " ) , & data . apid2 , 0 , 0xFFFE ) ) ;
2001-06-24 17:42:19 +02:00
Add ( new cMenuEditIntItem ( tr ( " Dpid1 " ) , & data . dpid1 , 0 , 0xFFFE ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Dpid2 " ) , & data . dpid2 , 0 , 0xFFFE ) ) ;
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditIntItem ( tr ( " Tpid " ) , & data . tpid , 0 , 0xFFFE ) ) ;
2000-11-11 10:39:27 +01:00
Add ( new cMenuEditIntItem ( tr ( " CA " ) , & data . ca , 0 , cDvbApi : : NumDvbApis ) ) ;
Add ( new cMenuEditIntItem ( tr ( " Pnr " ) , & data . pnr , 0 ) ) ;
2000-02-19 13:36:48 +01:00
}
}
2000-03-11 11:22:37 +01:00
eOSState cMenuEditChannel : : 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-02-19 13:36:48 +01:00
if ( Key = = kOk ) {
if ( channel )
* channel = data ;
Channels . Save ( ) ;
2000-03-11 11:22:37 +01:00
state = osBack ;
2000-02-19 13:36:48 +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 {
private :
int index ;
cChannel * channel ;
public :
cMenuChannelItem ( int Index , cChannel * Channel ) ;
virtual void Set ( void ) ;
2000-03-11 11:22:37 +01:00
void SetIndex ( int Index ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuChannelItem : : cMenuChannelItem ( int Index , cChannel * Channel )
{
index = Index ;
channel = Channel ;
2000-09-09 14:57:43 +02:00
if ( channel - > groupSep )
2001-07-31 15:32:02 +02:00
SetColor ( clrCyan , clrBackground ) ;
2000-02-19 13:36:48 +01:00
Set ( ) ;
}
void cMenuChannelItem : : Set ( void )
{
char * buffer = NULL ;
2000-09-09 14:57:43 +02:00
if ( ! channel - > groupSep )
asprintf ( & buffer , " %d \t %s " , channel - > number , channel - > name ) ;
else
2001-07-31 15:32:02 +02:00
asprintf ( & buffer , " --- \t %s ---------------------------------------------------------------- " , channel - > name ) ;
2000-02-19 13:36:48 +01:00
SetText ( buffer , false ) ;
}
2000-03-11 11:22:37 +01:00
void cMenuChannelItem : : SetIndex ( int Index )
{
index = Index ;
Set ( ) ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuChannels ---------------------------------------------------------
class cMenuChannels : public cOsdMenu {
2000-03-11 11:22:37 +01:00
protected :
eOSState Switch ( void ) ;
eOSState Edit ( void ) ;
eOSState New ( void ) ;
eOSState Del ( void ) ;
virtual void Move ( int From , int To ) ;
2000-02-19 13:36:48 +01:00
public :
cMenuChannels ( void ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
cMenuChannels : : cMenuChannels ( void )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Channels " ) , 4 )
2000-02-19 13:36:48 +01:00
{
//TODO
int i = 0 ;
cChannel * channel ;
2000-11-05 18:39:17 +01:00
int curr = ( ( channel = Channels . GetByNumber ( cDvbApi : : CurrentChannel ( ) ) ) ! = NULL ) ? channel - > Index ( ) : - 1 ;
2000-02-19 13:36:48 +01:00
while ( ( channel = Channels . Get ( i ) ) ! = NULL ) {
2000-09-09 14:57:43 +02:00
Add ( new cMenuChannelItem ( i , channel ) , i = = curr ) ;
2000-02-19 13:36:48 +01:00
i + + ;
}
2000-11-11 10:39:27 +01:00
SetHelp ( tr ( " Edit " ) , tr ( " New " ) , tr ( " Delete " ) , tr ( " Mark " ) ) ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuChannels : : Switch ( void )
{
cChannel * ch = Channels . Get ( Current ( ) ) ;
if ( ch )
ch - > Switch ( ) ;
return osEnd ;
}
eOSState cMenuChannels : : Edit ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
2000-04-15 17:38:11 +02:00
isyslog ( LOG_INFO , " editing channel %d " , Current ( ) + 1 ) ;
2000-03-11 11:22:37 +01:00
return AddSubMenu ( new cMenuEditChannel ( Current ( ) ) ) ;
}
eOSState cMenuChannels : : New ( void )
{
if ( HasSubMenu ( ) )
return osContinue ;
cChannel * channel = new cChannel ( Channels . Get ( Current ( ) ) ) ;
Channels . Add ( channel ) ;
2000-09-09 14:57:43 +02:00
Channels . ReNumber ( ) ;
2000-03-11 11:22:37 +01:00
Add ( new cMenuChannelItem ( channel - > Index ( ) /*XXX*/ , channel ) , true ) ;
Channels . Save ( ) ;
2000-09-09 14:57:43 +02:00
isyslog ( LOG_INFO , " channel %d added " , channel - > number ) ;
2000-03-11 11:22:37 +01:00
return AddSubMenu ( new cMenuEditChannel ( Current ( ) ) ) ;
2000-02-19 13:36:48 +01:00
}
2000-03-11 11:22:37 +01:00
eOSState cMenuChannels : : Del ( void )
2000-02-19 13:36:48 +01:00
{
2000-03-11 11:22:37 +01:00
if ( Count ( ) > 0 ) {
int Index = Current ( ) ;
2000-09-09 14:57:43 +02:00
cChannel * channel = Channels . Get ( Index ) ;
int DeletedChannel = channel - > number ;
2000-03-11 11:22:37 +01:00
// Check if there is a timer using this channel:
for ( cTimer * ti = Timers . First ( ) ; ti ; ti = ( cTimer * ) ti - > Next ( ) ) {
2000-09-09 14:57:43 +02:00
if ( ti - > channel = = DeletedChannel ) {
2000-11-11 10:39:27 +01:00
Interface - > Error ( tr ( " Channel is being used by a timer! " ) ) ;
2000-03-11 11:22:37 +01:00
return osContinue ;
}
}
2000-12-28 12:57:16 +01:00
if ( Interface - > Confirm ( tr ( " Delete channel? " ) ) ) {
2000-03-11 11:22:37 +01:00
// Move and renumber the channels:
2000-09-09 14:57:43 +02:00
Channels . Del ( channel ) ;
Channels . ReNumber ( ) ;
2000-03-11 11:22:37 +01:00
cOsdMenu : : Del ( Index ) ;
int i = 0 ;
for ( cMenuChannelItem * ci = ( cMenuChannelItem * ) First ( ) ; ci ; ci = ( cMenuChannelItem * ) ci - > Next ( ) )
ci - > SetIndex ( i + + ) ;
Channels . Save ( ) ;
2000-09-09 14:57:43 +02:00
isyslog ( LOG_INFO , " channel %d deleted " , DeletedChannel ) ;
2000-03-11 11:22:37 +01:00
// Fix the timers:
bool TimersModified = false ;
for ( cTimer * ti = Timers . First ( ) ; ti ; ti = ( cTimer * ) ti - > Next ( ) ) {
int OldChannel = ti - > channel ;
2000-09-09 14:57:43 +02:00
if ( ti - > channel > DeletedChannel )
2000-03-11 11:22:37 +01:00
ti - > channel - - ;
if ( ti - > channel ! = OldChannel ) {
TimersModified = true ;
isyslog ( LOG_INFO , " timer %d: channel changed from %d to %d " , ti - > Index ( ) + 1 , OldChannel , ti - > channel ) ;
}
}
if ( TimersModified )
Timers . Save ( ) ;
Display ( ) ;
}
}
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 )
{
2000-09-09 14:57:43 +02:00
int FromNumber = Channels . Get ( From ) - > number ;
int ToNumber = Channels . Get ( To ) - > number ;
2000-03-11 11:22:37 +01:00
// Move and renumber the channels:
Channels . Move ( From , To ) ;
2000-09-09 14:57:43 +02:00
Channels . ReNumber ( ) ;
2000-03-11 11:22:37 +01:00
cOsdMenu : : Move ( From , To ) ;
int i = 0 ;
for ( cMenuChannelItem * ci = ( cMenuChannelItem * ) First ( ) ; ci ; ci = ( cMenuChannelItem * ) ci - > Next ( ) )
ci - > SetIndex ( i + + ) ;
Channels . Save ( ) ;
2000-09-09 14:57:43 +02:00
isyslog ( LOG_INFO , " channel %d moved to %d " , FromNumber , ToNumber ) ;
2000-03-11 11:22:37 +01:00
// Fix the timers:
bool TimersModified = false ;
From + + ; // user visible channel numbers start with '1'
To + + ;
for ( cTimer * ti = Timers . First ( ) ; ti ; ti = ( cTimer * ) ti - > Next ( ) ) {
int OldChannel = ti - > channel ;
2000-09-09 14:57:43 +02:00
if ( ti - > channel = = FromNumber )
ti - > channel = ToNumber ;
else if ( ti - > channel > FromNumber & & ti - > channel < = ToNumber )
2000-03-11 11:22:37 +01:00
ti - > channel - - ;
2000-09-09 14:57:43 +02:00
else if ( ti - > channel < FromNumber & & ti - > channel > = ToNumber )
2000-03-11 11:22:37 +01:00
ti - > channel + + ;
if ( ti - > channel ! = OldChannel ) {
TimersModified = true ;
isyslog ( LOG_INFO , " timer %d: channel changed from %d to %d " , ti - > Index ( ) + 1 , OldChannel , ti - > channel ) ;
}
}
if ( TimersModified )
Timers . Save ( ) ;
Display ( ) ;
}
eOSState cMenuChannels : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
2000-02-19 13:36:48 +01:00
switch ( Key ) {
2000-03-11 11:22:37 +01:00
case kOk : return Switch ( ) ;
case kRed : return Edit ( ) ;
case kGreen : return New ( ) ;
case kYellow : return Del ( ) ;
case kBlue : Mark ( ) ; break ;
2000-02-19 13:36:48 +01:00
default : break ;
}
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
2000-11-01 11:45:05 +01:00
// --- cMenuTextItem ---------------------------------------------------------
class cMenuTextItem : public cOsdItem {
private :
char * text ;
int x , y , w , h , lines , offset ;
eDvbColor fgColor , bgColor ;
2000-11-18 15:46:00 +01:00
eDvbFont font ;
2000-11-01 11:45:05 +01:00
public :
2000-11-18 15:46:00 +01:00
cMenuTextItem ( const char * Text , int X , int Y , int W , int H = - 1 , eDvbColor FgColor = clrWhite , eDvbColor BgColor = clrBackground , eDvbFont Font = fontOsd ) ;
2000-11-01 11:45:05 +01:00
~ cMenuTextItem ( ) ;
int Height ( void ) { return h ; }
void Clear ( void ) ;
virtual void Display ( int Offset = - 1 , eDvbColor FgColor = clrWhite , eDvbColor BgColor = clrBackground ) ;
bool CanScrollUp ( void ) { return offset > 0 ; }
bool CanScrollDown ( void ) { return h + offset < lines ; }
void ScrollUp ( void ) ;
void ScrollDown ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
2000-11-18 15:46:00 +01:00
cMenuTextItem : : cMenuTextItem ( const char * Text , int X , int Y , int W , int H , eDvbColor FgColor , eDvbColor BgColor , eDvbFont Font )
2000-11-01 11:45:05 +01:00
{
x = X ;
y = Y ;
w = W ;
h = H ;
fgColor = FgColor ;
bgColor = BgColor ;
2000-11-18 15:46:00 +01:00
font = Font ;
2000-11-01 11:45:05 +01:00
offset = 0 ;
2000-11-18 15:46:00 +01:00
eDvbFont oldFont = Interface - > SetFont ( font ) ;
2000-11-01 11:45:05 +01:00
text = Interface - > WrapText ( Text , w - 1 , & lines ) ;
2000-11-18 15:46:00 +01:00
Interface - > SetFont ( oldFont ) ;
2000-11-01 11:45:05 +01:00
if ( h < 0 )
h = lines ;
}
cMenuTextItem : : ~ cMenuTextItem ( )
{
delete text ;
}
void cMenuTextItem : : Clear ( void )
{
2000-11-01 15:41:33 +01:00
Interface - > Fill ( x , y , w , h , bgColor ) ;
2000-11-01 11:45:05 +01:00
}
void cMenuTextItem : : Display ( int Offset , eDvbColor FgColor , eDvbColor BgColor )
{
int l = 0 ;
char * t = text ;
2000-11-18 15:46:00 +01:00
eDvbFont oldFont = Interface - > SetFont ( font ) ;
2000-11-01 11:45:05 +01:00
while ( * t ) {
char * n = strchr ( t , ' \n ' ) ;
if ( l > = offset ) {
if ( n )
* n = 0 ;
Interface - > Write ( x , y + l - offset , t , fgColor , bgColor ) ;
if ( n )
* n = ' \n ' ;
else
break ;
}
if ( ! n )
break ;
t = n + 1 ;
if ( + + l > = h + offset )
break ;
}
2000-11-18 15:46:00 +01:00
Interface - > SetFont ( oldFont ) ;
2000-11-01 11:45:05 +01:00
// scroll indicators use inverted color scheme!
if ( CanScrollUp ( ) ) Interface - > Write ( x + w - 1 , y , " ^ " , bgColor , fgColor ) ;
if ( CanScrollDown ( ) ) Interface - > Write ( x + w - 1 , y + h - 1 , " v " , bgColor , fgColor ) ;
}
void cMenuTextItem : : ScrollUp ( void )
{
if ( CanScrollUp ( ) ) {
Clear ( ) ;
offset - - ;
Display ( ) ;
}
}
void cMenuTextItem : : ScrollDown ( void )
{
if ( CanScrollDown ( ) ) {
Clear ( ) ;
offset + + ;
Display ( ) ;
}
}
eOSState cMenuTextItem : : ProcessKey ( eKeys Key )
{
switch ( Key ) {
case kUp | k_Repeat :
case kUp : ScrollUp ( ) ; break ;
case kDown | k_Repeat :
case kDown : ScrollDown ( ) ; break ;
default : return osUnknown ;
}
return osContinue ;
}
2000-11-11 16:38:41 +01:00
// --- cMenuText -------------------------------------------------------------
2000-07-24 16:43:04 +02:00
2000-11-11 16:38:41 +01:00
class cMenuText : public cOsdMenu {
2000-07-24 16:43:04 +02:00
public :
2000-11-18 15:46:00 +01:00
cMenuText ( const char * Title , const char * Text , eDvbFont Font = fontOsd ) ;
2000-07-24 16:43:04 +02:00
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
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
{
2001-07-27 11:51:42 +02:00
Add ( new cMenuTextItem ( Text , 1 , 2 , Setup . OSDwidth - 2 , MAXOSDITEMS , clrWhite , clrBackground , Font ) ) ;
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
{
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 ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuEditTimer --------------------------------------------------------
class cMenuEditTimer : public cOsdMenu {
private :
cTimer * timer ;
cTimer data ;
public :
2000-04-15 17:38:11 +02:00
cMenuEditTimer ( int Index , bool New = false ) ;
2000-03-11 11:22:37 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
2000-04-15 17:38:11 +02:00
cMenuEditTimer : : cMenuEditTimer ( int Index , bool New )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Edit Timer " ) , 12 )
2000-02-19 13:36:48 +01:00
{
timer = Timers . Get ( Index ) ;
if ( timer ) {
data = * timer ;
2000-04-15 17:38:11 +02:00
if ( New )
data . active = 1 ;
2000-11-11 10:39:27 +01:00
Add ( new cMenuEditBoolItem ( tr ( " Active " ) , & data . active ) ) ;
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditChanItem ( tr ( " Channel " ) , & data . channel ) ) ;
Add ( new cMenuEditDayItem ( tr ( " Day " ) , & data . day ) ) ;
Add ( new cMenuEditTimeItem ( tr ( " Start " ) , & data . start ) ) ;
Add ( new cMenuEditTimeItem ( tr ( " Stop " ) , & data . stop ) ) ;
2000-02-19 13:36:48 +01:00
//TODO VPS???
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 ) ) ;
2000-11-11 10:39:27 +01:00
Add ( new cMenuEditStrItem ( tr ( " File " ) , data . file , sizeof ( data . file ) , FileNameChars ) ) ;
2000-02-19 13:36:48 +01:00
}
}
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 ) {
case kOk : if ( ! * data . file )
strcpy ( data . file , Channels . GetChannelNameByNumber ( data . channel ) ) ;
if ( timer & & memcmp ( timer , & data , sizeof ( data ) ) ! = 0 ) {
* timer = data ;
2001-02-24 15:05:07 +01:00
if ( timer - > active )
timer - > active = 1 ; // allows external programs to mark active timers with values > 1 and recognize if the user has modified them
2000-11-11 12:55:10 +01:00
Timers . Save ( ) ;
isyslog ( LOG_INFO , " timer %d modified (%s) " , timer - > Index ( ) + 1 , timer - > active ? " active " : " inactive " ) ;
}
return osBack ;
case kRed :
case kGreen :
case kYellow :
case kBlue : return osContinue ;
default : break ;
}
2000-02-19 13:36:48 +01:00
}
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
// --- cMenuTimerItem --------------------------------------------------------
class cMenuTimerItem : public cOsdItem {
private :
int index ;
cTimer * timer ;
public :
cMenuTimerItem ( int Index , cTimer * Timer ) ;
virtual void Set ( void ) ;
} ;
cMenuTimerItem : : cMenuTimerItem ( int Index , cTimer * Timer )
{
index = Index ;
timer = Timer ;
Set ( ) ;
}
void cMenuTimerItem : : Set ( void )
{
char * buffer = NULL ;
2000-03-11 11:22:37 +01:00
asprintf ( & buffer , " %c \t %d \t %s \t %02d:%02d \t %02d:%02d \t %s " ,
2001-06-02 10:47:40 +02:00
timer - > active ? ' > ' : ' ' ,
timer - > channel ,
timer - > PrintDay ( timer - > day ) ,
2000-02-19 13:36:48 +01:00
timer - > start / 100 ,
timer - > start % 100 ,
timer - > stop / 100 ,
2000-03-11 11:22:37 +01:00
timer - > stop % 100 ,
timer - > file ) ;
2000-02-19 13:36:48 +01:00
SetText ( buffer , false ) ;
}
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 :
eOSState Activate ( bool On ) ;
eOSState Edit ( void ) ;
eOSState New ( void ) ;
eOSState Del ( void ) ;
virtual void Move ( int From , int To ) ;
2000-07-24 16:43:04 +02:00
eOSState Summary ( void ) ;
2000-02-19 13:36:48 +01:00
public :
2000-03-11 11:22:37 +01:00
cMenuTimers ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-02-19 13:36:48 +01:00
} ;
2000-03-11 11:22:37 +01:00
cMenuTimers : : cMenuTimers ( void )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Timers " ) , 2 , 4 , 10 , 6 , 6 )
2000-02-19 13:36:48 +01:00
{
int i = 0 ;
cTimer * timer ;
while ( ( timer = Timers . Get ( i ) ) ! = NULL ) {
Add ( new cMenuTimerItem ( i , timer ) ) ;
i + + ;
}
2000-11-11 10:39:27 +01:00
SetHelp ( tr ( " Edit " ) , tr ( " New " ) , tr ( " Delete " ) , tr ( " Mark " ) ) ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuTimers : : Activate ( bool On )
{
cTimer * timer = Timers . Get ( Current ( ) ) ;
if ( timer & & timer - > active ! = On ) {
timer - > active = On ;
RefreshCurrent ( ) ;
DisplayCurrent ( true ) ;
isyslog ( LOG_INFO , " timer %d %sactivated " , timer - > Index ( ) + 1 , timer - > active ? " " : " de " ) ;
Timers . Save ( ) ;
}
return osContinue ;
}
eOSState cMenuTimers : : Edit ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
isyslog ( LOG_INFO , " editing timer %d " , Current ( ) + 1 ) ;
return AddSubMenu ( new cMenuEditTimer ( Current ( ) ) ) ;
}
eOSState cMenuTimers : : New ( void )
{
if ( HasSubMenu ( ) )
return osContinue ;
cTimer * timer = new cTimer ;
Timers . Add ( timer ) ;
Add ( new cMenuTimerItem ( timer - > Index ( ) /*XXX*/ , timer ) , true ) ;
Timers . Save ( ) ;
isyslog ( LOG_INFO , " timer %d added " , timer - > Index ( ) + 1 ) ;
2000-04-15 17:38:11 +02:00
return AddSubMenu ( new cMenuEditTimer ( Current ( ) , true ) ) ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuTimers : : Del ( void )
{
// Check if this timer is active:
int Index = Current ( ) ;
cTimer * ti = Timers . Get ( Index ) ;
if ( ti ) {
if ( ! ti - > recording ) {
2000-12-28 12:57:16 +01:00
if ( Interface - > Confirm ( tr ( " Delete timer? " ) ) ) {
2000-03-11 11:22:37 +01:00
Timers . Del ( Timers . Get ( Index ) ) ;
cOsdMenu : : Del ( Index ) ;
Timers . Save ( ) ;
Display ( ) ;
isyslog ( LOG_INFO , " timer %d deleted " , Index + 1 ) ;
}
}
else
2000-11-11 10:39:27 +01:00
Interface - > Error ( tr ( " Timer is recording! " ) ) ;
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 cMenuTimers : : Move ( int From , int To )
2000-02-19 13:36:48 +01:00
{
2000-03-11 11:22:37 +01:00
Timers . Move ( From , To ) ;
cOsdMenu : : Move ( From , To ) ;
Timers . Save ( ) ;
Display ( ) ;
isyslog ( LOG_INFO , " timer %d moved to %d " , From + 1 , To + 1 ) ;
}
2000-02-19 13:36:48 +01:00
2000-07-24 16:43:04 +02:00
eOSState cMenuTimers : : Summary ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
cTimer * ti = Timers . Get ( Current ( ) ) ;
if ( ti & & ti - > summary & & * ti - > summary )
2000-11-11 16:38:41 +01:00
return AddSubMenu ( new cMenuText ( tr ( " Summary " ) , ti - > summary ) ) ;
2000-07-24 16:43:04 +02:00
return Edit ( ) ; // convenience for people not using the Summary feature ;-)
}
2000-03-11 11:22:37 +01:00
eOSState cMenuTimers : : ProcessKey ( eKeys Key )
{
2001-02-03 14:35:28 +01:00
// Must do these before calling cOsdMenu::ProcessKey() because cOsdMenu
// uses them to page up/down:
2001-02-03 15:32:47 +01:00
if ( ! HasSubMenu ( ) ) {
switch ( Key ) {
case kLeft :
case kRight : return Activate ( Key = = kRight ) ;
default : break ;
}
}
2001-02-03 14:35:28 +01:00
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 ) {
2001-02-03 15:32:47 +01:00
case kLeft :
case kRight : return Activate ( Key = = kRight ) ;
2000-07-24 16:43:04 +02:00
case kOk : return Summary ( ) ;
2000-03-11 11:22:37 +01:00
case kRed : return Edit ( ) ;
case kGreen : return New ( ) ;
case kYellow : return Del ( ) ;
case kBlue : Mark ( ) ; break ;
2000-02-19 13:36:48 +01:00
default : break ;
}
}
2000-03-11 11:22:37 +01:00
return state ;
}
2000-10-29 13:17:22 +01:00
// --- cMenuEvent ------------------------------------------------------------
class cMenuEvent : public cOsdMenu {
private :
const cEventInfo * eventInfo ;
public :
cMenuEvent ( const cEventInfo * EventInfo , bool CanSwitch = false ) ;
2000-11-01 15:41:33 +01:00
cMenuEvent ( bool Now ) ;
2000-11-01 11:45:05 +01:00
virtual eOSState ProcessKey ( eKeys Key ) ;
2000-10-29 13:17:22 +01:00
} ;
cMenuEvent : : cMenuEvent ( const cEventInfo * EventInfo , bool CanSwitch )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Event " ) )
2000-10-29 13:17:22 +01:00
{
eventInfo = EventInfo ;
2000-11-01 11:45:05 +01:00
if ( eventInfo ) {
cChannel * channel = Channels . GetByServiceID ( eventInfo - > GetServiceID ( ) ) ;
if ( channel ) {
char * buffer ;
2000-11-05 13:04:23 +01:00
asprintf ( & buffer , " %-17.*s \t %.*s %s - %s " , 17 , channel - > name , 5 , eventInfo - > GetDate ( ) , eventInfo - > GetTimeString ( ) , eventInfo - > GetEndTimeString ( ) ) ;
2000-11-01 11:45:05 +01:00
SetTitle ( buffer , false ) ;
int Line = 2 ;
cMenuTextItem * item ;
2000-11-18 14:13:26 +01:00
const char * Title = eventInfo - > GetTitle ( ) ;
const char * Subtitle = eventInfo - > GetSubtitle ( ) ;
const char * ExtendedDescription = eventInfo - > GetExtendedDescription ( ) ;
// Some channels send a 'Subtitle' that should actually be the 'ExtendedDescription'
// (their 'ExtendedDescription' is then empty). In order to handle this correctly
// we silently shift that text to where it belongs.
// The German TV station 'VOX' is notorious for this - why can't they do it correctly
// like all the others? Well, at least like those who actually send the full range
// of information (like, e.g., 'Sat.1'). Some stations (like 'RTL') don't even
// bother sending anything but the 'Title'...
2001-07-27 11:51:42 +02:00
if ( isempty ( ExtendedDescription ) & & ! isempty ( Subtitle ) & & int ( strlen ( Subtitle ) ) > 2 * Setup . OSDwidth ) {
2000-11-18 14:13:26 +01:00
ExtendedDescription = Subtitle ;
Subtitle = NULL ;
}
if ( ! isempty ( Title ) ) {
2001-07-27 11:51:42 +02:00
Add ( item = new cMenuTextItem ( Title , 1 , Line , Setup . OSDwidth - 2 , - 1 , clrCyan ) ) ;
2000-11-01 11:45:05 +01:00
Line + = item - > Height ( ) + 1 ;
}
2000-11-18 14:13:26 +01:00
if ( ! isempty ( Subtitle ) ) {
2001-07-27 11:51:42 +02:00
Add ( item = new cMenuTextItem ( Subtitle , 1 , Line , Setup . OSDwidth - 2 , - 1 , clrYellow ) ) ;
2000-11-01 11:45:05 +01:00
Line + = item - > Height ( ) + 1 ;
}
2000-11-18 14:13:26 +01:00
if ( ! isempty ( ExtendedDescription ) )
2001-07-27 11:51:42 +02:00
Add ( new cMenuTextItem ( ExtendedDescription , 1 , Line , Setup . OSDwidth - 2 , Height ( ) - Line - 2 , clrCyan ) , true ) ;
2000-11-11 10:39:27 +01:00
SetHelp ( tr ( " Record " ) , NULL , NULL , CanSwitch ? tr ( " Switch " ) : NULL ) ;
2000-11-01 11:45:05 +01:00
}
2000-10-29 13:17:22 +01:00
}
}
2000-11-01 11:45:05 +01:00
eOSState cMenuEvent : : ProcessKey ( eKeys Key )
2000-10-29 13:17:22 +01:00
{
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
}
// --- cMenuWhatsOnItem ------------------------------------------------------
class cMenuWhatsOnItem : public cOsdItem {
public :
const cEventInfo * eventInfo ;
cMenuWhatsOnItem ( const cEventInfo * EventInfo ) ;
} ;
cMenuWhatsOnItem : : cMenuWhatsOnItem ( const cEventInfo * EventInfo )
{
eventInfo = EventInfo ;
char * buffer = NULL ;
cChannel * channel = Channels . GetByNumber ( eventInfo - > GetChannelNumber ( ) ) ;
asprintf ( & buffer , " %d \t %.*s \t %.*s \t %s " , eventInfo - > GetChannelNumber ( ) , 6 , channel ? channel - > name : " ??? " , 5 , eventInfo - > GetTimeString ( ) , eventInfo - > GetTitle ( ) ) ;
SetText ( buffer , false ) ;
}
// --- cMenuWhatsOn ----------------------------------------------------------
class cMenuWhatsOn : public cOsdMenu {
private :
eOSState Record ( void ) ;
eOSState Switch ( void ) ;
2001-02-10 15:37:21 +01:00
static int currentChannel ;
2000-11-12 16:48:50 +01:00
static const cEventInfo * scheduleEventInfo ;
2000-10-29 13:17:22 +01:00
public :
2001-02-10 15:37:21 +01:00
cMenuWhatsOn ( const cSchedules * Schedules , bool Now , int CurrentChannelNr ) ;
static int CurrentChannel ( void ) { return currentChannel ; }
static void SetCurrentChannel ( int ChannelNr ) { currentChannel = ChannelNr ; }
2000-11-12 16:48:50 +01:00
static const cEventInfo * ScheduleEventInfo ( 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 ;
2000-11-12 16:48:50 +01:00
const cEventInfo * cMenuWhatsOn : : scheduleEventInfo = NULL ;
2000-10-29 13:17:22 +01:00
static int CompareEventChannel ( const void * p1 , const void * p2 )
{
return ( int ) ( ( * ( const cEventInfo * * ) p1 ) - > GetChannelNumber ( ) - ( * ( const cEventInfo * * ) p2 ) - > GetChannelNumber ( ) ) ;
}
2001-02-10 15:37:21 +01:00
cMenuWhatsOn : : cMenuWhatsOn ( const cSchedules * Schedules , bool Now , int CurrentChannelNr )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( Now ? tr ( " What's on now? " ) : tr ( " What's on next? " ) , 4 , 7 , 6 )
2000-10-29 13:17:22 +01:00
{
const cSchedule * Schedule = Schedules - > First ( ) ;
const cEventInfo * * pArray = NULL ;
int num = 0 ;
while ( Schedule ) {
pArray = ( const cEventInfo * * ) realloc ( pArray , ( num + 1 ) * sizeof ( cEventInfo * ) ) ;
pArray [ num ] = Now ? Schedule - > GetPresentEvent ( ) : Schedule - > GetFollowingEvent ( ) ;
if ( pArray [ num ] ) {
cChannel * channel = Channels . GetByServiceID ( pArray [ num ] - > GetServiceID ( ) ) ;
if ( channel ) {
pArray [ num ] - > SetChannelNumber ( channel - > number ) ;
num + + ;
}
}
Schedule = ( const cSchedule * ) Schedules - > Next ( Schedule ) ;
}
qsort ( pArray , num , sizeof ( cEventInfo * ) , CompareEventChannel ) ;
for ( int a = 0 ; a < num ; a + + )
2001-02-10 15:37:21 +01:00
Add ( new cMenuWhatsOnItem ( pArray [ a ] ) , pArray [ a ] - > GetChannelNumber ( ) = = CurrentChannelNr ) ;
2000-10-29 13:17:22 +01:00
2001-02-10 15:37:21 +01:00
currentChannel = CurrentChannelNr ;
2000-10-29 13:17:22 +01:00
delete pArray ;
2000-11-11 10:39:27 +01:00
SetHelp ( tr ( " Record " ) , Now ? tr ( " Next " ) : tr ( " Now " ) , tr ( " Schedule " ) , tr ( " Switch " ) ) ;
2000-10-29 13:17:22 +01:00
}
2000-11-12 16:48:50 +01:00
const cEventInfo * cMenuWhatsOn : : ScheduleEventInfo ( void )
{
const cEventInfo * ei = scheduleEventInfo ;
scheduleEventInfo = NULL ;
return ei ;
}
2000-10-29 13:17:22 +01:00
eOSState cMenuWhatsOn : : Switch ( void )
{
cMenuWhatsOnItem * item = ( cMenuWhatsOnItem * ) Get ( Current ( ) ) ;
if ( item ) {
cChannel * channel = Channels . GetByServiceID ( item - > eventInfo - > GetServiceID ( ) ) ;
if ( channel & & channel - > Switch ( ) )
return osEnd ;
}
2000-11-11 10:39:27 +01:00
Interface - > Error ( tr ( " Can't switch channel! " ) ) ;
2000-10-29 13:17:22 +01:00
return osContinue ;
}
eOSState cMenuWhatsOn : : Record ( void )
{
cMenuWhatsOnItem * item = ( cMenuWhatsOnItem * ) Get ( Current ( ) ) ;
2001-06-02 10:47:40 +02:00
if ( item ) {
2000-10-29 13:17:22 +01:00
cTimer * timer = new cTimer ( item - > eventInfo ) ;
2000-11-11 12:55:10 +01:00
cTimer * t = Timers . GetTimer ( timer ) ;
if ( ! t ) {
Timers . Add ( timer ) ;
Timers . Save ( ) ;
isyslog ( LOG_INFO , " timer %d added " , timer - > Index ( ) + 1 ) ;
}
else {
delete timer ;
timer = t ;
}
2000-10-29 13:17:22 +01:00
return AddSubMenu ( new cMenuEditTimer ( timer - > Index ( ) , true ) ) ;
}
return osContinue ;
}
eOSState cMenuWhatsOn : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
case kRed : return Record ( ) ;
2001-02-10 15:37:21 +01:00
case kYellow : state = osBack ;
// continue with kGreen
case kGreen : {
2000-11-12 16:48:50 +01:00
cMenuWhatsOnItem * mi = ( cMenuWhatsOnItem * ) Get ( Current ( ) ) ;
2001-02-10 15:37:21 +01:00
if ( mi ) {
2000-11-12 16:48:50 +01:00
scheduleEventInfo = mi - > eventInfo ;
2001-02-10 15:37:21 +01:00
currentChannel = mi - > eventInfo - > GetChannelNumber ( ) ;
}
2000-11-12 16:48:50 +01:00
}
2001-02-10 15:37:21 +01:00
break ;
2000-10-29 13:17:22 +01:00
case kBlue : return Switch ( ) ;
2000-11-01 15:50:00 +01:00
case kOk : if ( Count ( ) )
return AddSubMenu ( new cMenuEvent ( ( ( cMenuWhatsOnItem * ) Get ( Current ( ) ) ) - > eventInfo , true ) ) ;
break ;
2000-10-29 13:17:22 +01:00
default : break ;
}
}
return state ;
}
// --- cMenuScheduleItem -----------------------------------------------------
class cMenuScheduleItem : public cOsdItem {
public :
const cEventInfo * eventInfo ;
cMenuScheduleItem ( const cEventInfo * EventInfo ) ;
} ;
cMenuScheduleItem : : cMenuScheduleItem ( const cEventInfo * EventInfo )
{
eventInfo = EventInfo ;
char * buffer = NULL ;
asprintf ( & buffer , " %.*s \t %.*s \t %s " , 5 , eventInfo - > GetDate ( ) , 5 , eventInfo - > GetTimeString ( ) , eventInfo - > GetTitle ( ) ) ;
SetText ( buffer , false ) ;
}
// --- cMenuSchedule ---------------------------------------------------------
class cMenuSchedule : public cOsdMenu {
private :
cThreadLock threadLock ;
const cSchedules * schedules ;
bool now , next ;
2000-11-26 16:18:52 +01:00
int otherChannel ;
2000-10-29 13:17:22 +01:00
eOSState Record ( void ) ;
2000-11-26 16:18:52 +01:00
eOSState Switch ( void ) ;
2000-11-12 16:48:50 +01:00
void PrepareSchedule ( cChannel * Channel ) ;
2000-10-29 13:17:22 +01:00
public :
cMenuSchedule ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuSchedule : : cMenuSchedule ( void )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( " " , 6 , 6 )
2000-10-29 13:17:22 +01:00
{
now = next = false ;
2000-11-26 16:18:52 +01:00
otherChannel = 0 ;
2000-11-05 18:39:17 +01:00
cChannel * channel = Channels . GetByNumber ( cDvbApi : : CurrentChannel ( ) ) ;
2000-10-29 13:17:22 +01:00
if ( channel ) {
2001-02-10 15:37:21 +01:00
cMenuWhatsOn : : SetCurrentChannel ( channel - > number ) ;
2000-11-12 16:48:50 +01:00
schedules = cDvbApi : : PrimaryDvbApi - > Schedules ( & threadLock ) ;
PrepareSchedule ( channel ) ;
2000-11-11 10:39:27 +01:00
SetHelp ( tr ( " Record " ) , tr ( " Now " ) , tr ( " Next " ) ) ;
2000-10-29 13:17:22 +01:00
}
}
static int CompareEventTime ( const void * p1 , const void * p2 )
{
return ( int ) ( ( * ( cEventInfo * * ) p1 ) - > GetTime ( ) - ( * ( cEventInfo * * ) p2 ) - > GetTime ( ) ) ;
}
2000-11-12 16:48:50 +01:00
void cMenuSchedule : : PrepareSchedule ( cChannel * Channel )
2000-10-29 13:17:22 +01:00
{
2000-11-12 16:48:50 +01:00
Clear ( ) ;
char * buffer = NULL ;
asprintf ( & buffer , tr ( " Schedule - %s " ) , Channel - > name ) ;
SetTitle ( buffer , false ) ;
2000-10-29 13:17:22 +01:00
if ( schedules ) {
2000-11-12 16:48:50 +01:00
const cSchedule * Schedule = Channel - > pnr ? schedules - > GetSchedule ( Channel - > pnr ) : schedules - > GetSchedule ( ) ;
2000-10-29 13:17:22 +01:00
int num = Schedule - > NumEvents ( ) ;
const cEventInfo * * pArray = ( const cEventInfo * * ) malloc ( num * sizeof ( cEventInfo * ) ) ;
if ( pArray ) {
time_t now = time ( NULL ) ;
int numreal = 0 ;
for ( int a = 0 ; a < num ; a + + ) {
const cEventInfo * EventInfo = Schedule - > GetEventNumber ( a ) ;
if ( EventInfo - > GetTime ( ) + EventInfo - > GetDuration ( ) > now )
pArray [ numreal + + ] = EventInfo ;
}
qsort ( pArray , numreal , sizeof ( cEventInfo * ) , CompareEventTime ) ;
for ( int a = 0 ; a < numreal ; a + + )
Add ( new cMenuScheduleItem ( pArray [ a ] ) ) ;
delete pArray ;
}
}
}
eOSState cMenuSchedule : : Record ( void )
{
cMenuScheduleItem * item = ( cMenuScheduleItem * ) Get ( Current ( ) ) ;
2001-06-02 10:47:40 +02:00
if ( item ) {
2000-10-29 13:17:22 +01:00
cTimer * timer = new cTimer ( item - > eventInfo ) ;
2000-11-11 12:55:10 +01:00
cTimer * t = Timers . GetTimer ( timer ) ;
if ( ! t ) {
Timers . Add ( timer ) ;
Timers . Save ( ) ;
isyslog ( LOG_INFO , " timer %d added " , timer - > Index ( ) + 1 ) ;
}
else {
delete timer ;
timer = t ;
}
2000-10-29 13:17:22 +01:00
return AddSubMenu ( new cMenuEditTimer ( timer - > Index ( ) , true ) ) ;
}
return osContinue ;
}
2000-11-26 16:18:52 +01:00
eOSState cMenuSchedule : : Switch ( void )
{
if ( otherChannel ) {
if ( Channels . SwitchTo ( otherChannel ) )
return osEnd ;
}
Interface - > Error ( tr ( " Can't switch channel! " ) ) ;
return osContinue ;
}
2000-10-29 13:17:22 +01:00
eOSState cMenuSchedule : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
case kRed : return Record ( ) ;
2001-03-18 10:16:56 +01:00
case kGreen : if ( schedules ) {
if ( ! now & & ! next ) {
int ChannelNr = 0 ;
if ( Count ( ) ) {
cChannel * channel = Channels . GetByServiceID ( ( ( cMenuScheduleItem * ) Get ( Current ( ) ) ) - > eventInfo - > GetServiceID ( ) ) ;
if ( channel )
ChannelNr = channel - > number ;
}
now = true ;
return AddSubMenu ( new cMenuWhatsOn ( schedules , true , ChannelNr ) ) ;
}
now = ! now ;
next = ! next ;
return AddSubMenu ( new cMenuWhatsOn ( schedules , now , cMenuWhatsOn : : CurrentChannel ( ) ) ) ;
}
case kYellow : if ( schedules )
return AddSubMenu ( new cMenuWhatsOn ( schedules , false , cMenuWhatsOn : : CurrentChannel ( ) ) ) ;
break ;
case kBlue : if ( Count ( ) )
return Switch ( ) ;
break ;
2000-11-01 15:50:00 +01:00
case kOk : if ( Count ( ) )
2000-11-26 16:18:52 +01:00
return AddSubMenu ( new cMenuEvent ( ( ( cMenuScheduleItem * ) Get ( Current ( ) ) ) - > eventInfo , otherChannel ) ) ;
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 ;
2000-11-12 16:48:50 +01:00
const cEventInfo * ei = cMenuWhatsOn : : ScheduleEventInfo ( ) ;
if ( ei ) {
cChannel * channel = Channels . GetByServiceID ( ei - > GetServiceID ( ) ) ;
if ( channel ) {
PrepareSchedule ( channel ) ;
2000-11-26 16:18:52 +01:00
if ( channel - > number ! = cDvbApi : : CurrentChannel ( ) ) {
otherChannel = channel - > number ;
SetHelp ( tr ( " Record " ) , tr ( " Now " ) , tr ( " Next " ) , tr ( " Switch " ) ) ;
}
2000-11-12 16:48:50 +01:00
Display ( ) ;
}
}
}
2000-10-29 13:17:22 +01:00
return state ;
}
2000-03-11 11:22:37 +01:00
// --- cMenuRecordingItem ----------------------------------------------------
class cMenuRecordingItem : public cOsdItem {
public :
cRecording * recording ;
cMenuRecordingItem ( cRecording * Recording ) ;
virtual void Set ( void ) ;
} ;
cMenuRecordingItem : : cMenuRecordingItem ( cRecording * Recording )
{
recording = Recording ;
Set ( ) ;
}
void cMenuRecordingItem : : Set ( void )
{
2000-10-03 12:44:15 +02:00
SetText ( recording - > Title ( ' \t ' , true ) ) ;
2000-03-11 11:22:37 +01:00
}
// --- cMenuRecordings -------------------------------------------------------
cMenuRecordings : : cMenuRecordings ( void )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Recordings " ) , 6 , 6 )
2000-03-11 11:22:37 +01:00
{
if ( Recordings . Load ( ) ) {
2000-10-08 15:08:26 +02:00
const char * lastReplayed = cReplayControl : : LastReplayed ( ) ;
2000-03-11 11:22:37 +01:00
cRecording * recording = Recordings . First ( ) ;
while ( recording ) {
2000-10-08 15:08:26 +02:00
Add ( new cMenuRecordingItem ( recording ) , lastReplayed & & strcmp ( lastReplayed , recording - > FileName ( ) ) = = 0 ) ;
2000-03-11 11:22:37 +01:00
recording = Recordings . Next ( recording ) ;
}
}
2001-02-11 11:04:41 +01:00
SetHelp ( tr ( " Play " ) , tr ( " Rewind " ) , tr ( " Delete " ) , tr ( " Summary " ) ) ;
2000-10-08 15:08:26 +02:00
Display ( ) ;
2000-03-11 11:22:37 +01:00
}
eOSState cMenuRecordings : : Play ( void )
{
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri ) {
2000-04-29 15:57:42 +02:00
cReplayControl : : SetRecording ( ri - > recording - > FileName ( ) , ri - > recording - > Title ( ) ) ;
return osReplay ;
2000-03-11 11:22:37 +01:00
}
return osContinue ;
}
2001-02-11 11:04:41 +01:00
eOSState cMenuRecordings : : Rewind ( void )
{
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri ) {
cDvbApi : : PrimaryDvbApi - > StopReplay ( ) ; // must do this first to be able to rewind the currently replayed recording
cResumeFile ResumeFile ( ri - > recording - > FileName ( ) ) ;
ResumeFile . Delete ( ) ;
return Play ( ) ;
}
return osContinue ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuRecordings : : Del ( void )
{
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri ) {
//XXX what if this recording's file is currently in use???
//XXX if (!ti->recording) {
2000-12-28 12:57:16 +01:00
if ( Interface - > Confirm ( tr ( " Delete recording? " ) ) ) {
2000-03-11 11:22:37 +01:00
if ( ri - > recording - > Delete ( ) ) {
2000-10-08 15:41:30 +02:00
cReplayControl : : ClearLastReplayed ( ri - > recording - > FileName ( ) ) ;
2000-03-11 11:22:37 +01:00
cOsdMenu : : Del ( Current ( ) ) ;
Display ( ) ;
}
else
2000-11-11 10:39:27 +01:00
Interface - > Error ( tr ( " Error while deleting recording! " ) ) ;
2000-03-11 11:22:37 +01:00
}
//XXX }
//XXX else
2000-11-11 10:39:27 +01:00
//XXX Interface->Error(tr("Timer is recording!"));
2000-03-11 11:22:37 +01:00
}
return osContinue ;
}
2000-07-24 16:43:04 +02:00
eOSState cMenuRecordings : : Summary ( void )
{
if ( HasSubMenu ( ) | | Count ( ) = = 0 )
return osContinue ;
cMenuRecordingItem * ri = ( cMenuRecordingItem * ) Get ( Current ( ) ) ;
if ( ri & & ri - > recording - > Summary ( ) & & * ri - > recording - > Summary ( ) )
2000-11-11 16:38:41 +01:00
return AddSubMenu ( new cMenuText ( tr ( " Summary " ) , ri - > recording - > Summary ( ) ) ) ;
2000-07-24 16:43:04 +02:00
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 ) {
case kOk :
case kRed : return Play ( ) ;
2001-02-11 11:04:41 +01:00
case kGreen : return Rewind ( ) ;
2000-03-11 11:22:37 +01:00
case kYellow : return Del ( ) ;
2000-07-24 16:43:04 +02:00
case kBlue : return Summary ( ) ;
2000-10-08 15:08:26 +02:00
case kMenu : return osEnd ;
2000-03-11 11:22:37 +01:00
default : break ;
}
}
return state ;
2000-02-19 13:36:48 +01:00
}
2001-08-03 14:18:08 +02:00
// --- cMenuDVDItem ----------------------------------------------------------
class cMenuDVDItem : public cOsdItem {
private :
int title ;
int chapters ;
virtual void Set ( void ) ;
public :
cMenuDVDItem ( int Title , int Chapters ) ;
int Title ( void ) { return title ; }
} ;
cMenuDVDItem : : cMenuDVDItem ( int Title , int Chapters )
{
title = Title ;
chapters = Chapters ;
Set ( ) ;
}
void cMenuDVDItem : : Set ( void )
{
char * buffer = NULL ;
asprintf ( & buffer , " %2d. \t Title - \t %2d \t Chapters " , title + 1 , chapters ) ;
SetText ( buffer , false ) ;
}
// --- cMenuDVD --------------------------------------------------------------
cMenuDVD : : cMenuDVD ( void )
: cOsdMenu ( tr ( " DVD " ) , 5 , 8 , 3 )
{
if ( ( dvd = cDVD : : getDVD ( ) ) ) {
dvd - > Open ( ) ;
ifo_handle_t * vmg = dvd - > openVMG ( ) ;
if ( vmg ) {
dsyslog ( LOG_INFO , " DVD: vmg: %p " , vmg ) ; //XXX
tt_srpt_t * tt_srpt = vmg - > tt_srpt ;
dsyslog ( LOG_INFO , " DVD: tt_srpt: %p " , tt_srpt ) ; //XXX
for ( int i = 0 ; i < tt_srpt - > nr_of_srpts ; i + + )
Add ( new cMenuDVDItem ( i , tt_srpt - > title [ i ] . nr_of_ptts ) ) ;
}
}
SetHelp ( tr ( " Play " ) , NULL , NULL , NULL ) ;
Display ( ) ;
}
eOSState cMenuDVD : : Play ( void )
{
cMenuDVDItem * ri = ( cMenuDVDItem * ) Get ( Current ( ) ) ;
if ( ri ) {
cReplayControl : : SetDVD ( dvd , ri - > Title ( ) ) ;
isyslog ( LOG_INFO , " DVD: playing title %d " , ri - > Title ( ) ) ;
return osReplay ;
}
return osContinue ;
}
eOSState cMenuDVD : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
case kOk :
case kRed : return Play ( ) ;
case kMenu : return osEnd ;
default : break ;
}
}
return state ;
}
2000-09-10 10:51:58 +02:00
// --- cMenuSetup ------------------------------------------------------------
class cMenuSetup : public cOsdMenu {
private :
cSetup data ;
2000-11-11 10:39:27 +01:00
int osdLanguage ;
void Set ( void ) ;
2000-09-10 10:51:58 +02:00
public :
cMenuSetup ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuSetup : : cMenuSetup ( void )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( " " , 25 )
2000-09-10 10:51:58 +02:00
{
data = Setup ;
2000-11-11 10:39:27 +01:00
osdLanguage = Setup . OSDLanguage ;
Set ( ) ;
}
void cMenuSetup : : Set ( void )
{
Clear ( ) ;
SetTitle ( tr ( " Setup " ) ) ;
Add ( new cMenuEditStraItem ( tr ( " OSD-Language " ) , & data . OSDLanguage , NumLanguages , Languages ( ) ) ) ;
Add ( new cMenuEditIntItem ( tr ( " PrimaryDVB " ) , & data . PrimaryDVB , 1 , cDvbApi : : NumDvbApis ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " ShowInfoOnChSwitch " ) , & data . ShowInfoOnChSwitch ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " MenuScrollPage " ) , & data . MenuScrollPage ) ) ;
Add ( new cMenuEditBoolItem ( tr ( " MarkInstantRecord " ) , & data . MarkInstantRecord ) ) ;
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditIntItem ( tr ( " LnbSLOF " ) , & data . LnbSLOF ) ) ;
2000-11-11 10:39:27 +01:00
Add ( new cMenuEditIntItem ( tr ( " LnbFrequLo " ) , & data . LnbFrequLo ) ) ;
Add ( new cMenuEditIntItem ( tr ( " LnbFrequHi " ) , & data . LnbFrequHi ) ) ;
2001-07-27 13:45:55 +02:00
Add ( new cMenuEditBoolItem ( tr ( " DiSEqC " ) , & data . DiSEqC ) ) ;
2000-11-11 10:39:27 +01:00
Add ( new cMenuEditBoolItem ( tr ( " SetSystemTime " ) , & data . SetSystemTime ) ) ;
Add ( new cMenuEditIntItem ( tr ( " MarginStart " ) , & data . MarginStart ) ) ;
Add ( new cMenuEditIntItem ( tr ( " MarginStop " ) , & data . MarginStop ) ) ;
2000-11-18 13:57:32 +01:00
Add ( new cMenuEditIntItem ( tr ( " EPGScanTimeout " ) , & data . EPGScanTimeout ) ) ;
2001-02-18 14:18:13 +01:00
Add ( new cMenuEditIntItem ( tr ( " SVDRPTimeout " ) , & data . SVDRPTimeout ) ) ;
2001-06-02 10:47:40 +02:00
Add ( new cMenuEditIntItem ( tr ( " PrimaryLimit " ) , & data . PrimaryLimit , 0 , MAXPRIORITY ) ) ;
Add ( new cMenuEditIntItem ( tr ( " DefaultPriority " ) , & data . DefaultPriority , 0 , MAXPRIORITY ) ) ;
Add ( new cMenuEditIntItem ( tr ( " DefaultLifetime " ) , & data . DefaultLifetime , 0 , MAXLIFETIME ) ) ;
2001-06-16 14:31:14 +02:00
Add ( new cMenuEditBoolItem ( tr ( " VideoFormat " ) , & data . VideoFormat , " 4:3 " , " 16:9 " ) ) ;
2001-07-27 10:59:50 +02:00
Add ( new cMenuEditBoolItem ( tr ( " ChannelInfoPos " ) , & data . ChannelInfoPos , tr ( " bottom " ) , tr ( " top " ) ) ) ;
2001-07-27 11:51:42 +02:00
Add ( new cMenuEditIntItem ( tr ( " OSDwidth " ) , & data . OSDwidth , MINOSDWIDTH , MAXOSDWIDTH ) ) ;
Add ( new cMenuEditIntItem ( tr ( " OSDheight " ) , & data . OSDheight , MINOSDHEIGHT , MAXOSDHEIGHT ) ) ;
2000-09-10 10:51:58 +02:00
}
eOSState cMenuSetup : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
2000-11-11 10:39:27 +01:00
case kOk : state = ( Setup . PrimaryDVB ! = data . PrimaryDVB ) ? osSwitchDvb : osEnd ;
2000-10-29 13:17:22 +01:00
cDvbApi : : PrimaryDvbApi - > SetUseTSTime ( data . SetSystemTime ) ;
2001-06-16 14:31:14 +02:00
cDvbApi : : PrimaryDvbApi - > SetVideoFormat ( data . VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3 ) ;
2000-09-10 10:51:58 +02:00
Setup = data ;
Setup . Save ( ) ;
break ;
default : break ;
}
}
2000-11-11 10:39:27 +01:00
if ( data . OSDLanguage ! = osdLanguage ) {
int OriginalOSDLanguage = Setup . OSDLanguage ;
Setup . OSDLanguage = data . OSDLanguage ;
Set ( ) ;
Display ( ) ;
osdLanguage = data . OSDLanguage ;
Setup . OSDLanguage = OriginalOSDLanguage ;
}
2000-09-10 10:51:58 +02:00
return state ;
}
2000-11-11 16:38:41 +01:00
// --- cMenuCommands ---------------------------------------------------------
class cMenuCommands : public cOsdMenu {
private :
eOSState Execute ( void ) ;
public :
cMenuCommands ( void ) ;
virtual eOSState ProcessKey ( eKeys Key ) ;
} ;
cMenuCommands : : cMenuCommands ( void )
: cOsdMenu ( tr ( " Commands " ) )
{
int i = 0 ;
cCommand * command ;
while ( ( command = Commands . Get ( i ) ) ! = NULL ) {
Add ( new cOsdItem ( command - > Title ( ) ) ) ;
i + + ;
}
2001-02-03 15:28:49 +01:00
SetHasHotkeys ( ) ;
2000-11-11 16:38:41 +01:00
}
eOSState cMenuCommands : : Execute ( void )
{
cCommand * command = Commands . Get ( Current ( ) ) ;
if ( command ) {
const char * Result = command - > Execute ( ) ;
if ( Result )
2000-11-18 15:46:00 +01:00
return AddSubMenu ( new cMenuText ( command - > Title ( ) , Result , fontFix ) ) ;
2000-11-11 16:38:41 +01:00
}
return osContinue ;
}
eOSState cMenuCommands : : ProcessKey ( eKeys Key )
{
eOSState state = cOsdMenu : : ProcessKey ( Key ) ;
if ( state = = osUnknown ) {
switch ( Key ) {
case kOk : return Execute ( ) ;
default : break ;
}
}
return state ;
}
2000-02-19 13:36:48 +01:00
// --- cMenuMain -------------------------------------------------------------
2001-03-04 11:42:20 +01:00
# define STOP_RECORDING tr(" Stop recording ")
2000-05-01 16:29:46 +02:00
cMenuMain : : cMenuMain ( bool Replaying )
2000-11-11 10:39:27 +01:00
: cOsdMenu ( tr ( " Main " ) )
2000-02-19 13:36:48 +01:00
{
2001-08-03 14:18:08 +02:00
digit = 0 ;
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 ) ) ;
Add ( new cOsdItem ( hk ( tr ( " DVD " ) ) , osDVD ) ) ;
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 ) ) ;
2000-05-01 16:29:46 +02:00
if ( Replaying )
2001-08-03 14:18:08 +02:00
Add ( new cOsdItem ( hk ( tr ( " Stop replaying " ) ) , osStopReplay ) ) ;
2000-05-01 16:29:46 +02:00
const char * s = NULL ;
while ( ( s = cRecordControls : : GetInstantId ( s ) ) ! = NULL ) {
char * buffer = NULL ;
asprintf ( & buffer , " %s%s " , STOP_RECORDING , s ) ;
2001-08-03 14:18:08 +02:00
Add ( new cOsdItem ( hk ( buffer ) , osStopRecord ) ) ;
2000-05-01 16:29:46 +02:00
delete buffer ;
}
2000-12-28 12:57:16 +01:00
if ( cVideoCutter : : Active ( ) )
2001-08-03 14:18:08 +02:00
Add ( new cOsdItem ( hk ( tr ( " Cancel editing " ) ) , osCancelEdit ) ) ;
SetHelp ( tr ( " Record " ) , cDvbApi : : PrimaryDvbApi - > CanToggleAudioTrack ( ) ? tr ( " Language " ) : NULL , /*XXX only if DVD loaded?*/ tr ( " Eject DVD " ) , cReplayControl : : LastReplayed ( ) ? tr ( " Resume " ) : NULL ) ;
2000-04-30 10:22:13 +02:00
Display ( ) ;
2000-05-01 16:29:46 +02:00
lastActivity = time ( NULL ) ;
2001-02-03 15:28:49 +01:00
SetHasHotkeys ( ) ;
2000-02-19 13:36:48 +01:00
}
2001-08-03 14:18:08 +02:00
const char * cMenuMain : : hk ( const char * s )
{
static char buffer [ 32 ] ;
if ( digit < 9 ) {
snprintf ( buffer , sizeof ( buffer ) , " %d %s " , + + digit , s ) ;
return buffer ;
}
else
return s ;
}
2000-03-11 11:22:37 +01:00
eOSState cMenuMain : : 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
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 ) ;
2001-08-03 14:18:08 +02:00
case osDVD : return AddSubMenu ( new cMenuDVD ) ;
2000-09-10 10:51:58 +02:00
case osSetup : return AddSubMenu ( new cMenuSetup ) ;
2000-11-11 16:38:41 +01:00
case osCommands : return AddSubMenu ( new cMenuCommands ) ;
2000-12-28 12:57:16 +01:00
case osStopRecord : if ( Interface - > Confirm ( tr ( " Stop recording? " ) ) ) {
2000-05-01 16:29:46 +02:00
cOsdItem * item = Get ( Current ( ) ) ;
if ( item ) {
cRecordControls : : Stop ( item - > Text ( ) + strlen ( STOP_RECORDING ) ) ;
return osEnd ;
}
}
2000-12-28 12:57:16 +01:00
break ;
case osCancelEdit : if ( Interface - > Confirm ( tr ( " Cancel editing? " ) ) ) {
cVideoCutter : : Stop ( ) ;
return osEnd ;
}
break ;
2000-05-27 16:10:47 +02:00
default : switch ( Key ) {
2001-08-03 14:18:08 +02:00
case kMenu : state = osEnd ; break ;
case kRed : if ( ! HasSubMenu ( ) )
state = osRecord ;
break ;
case kGreen : if ( ! HasSubMenu ( ) ) {
if ( cDvbApi : : PrimaryDvbApi - > CanToggleAudioTrack ( ) ) {
Interface - > Clear ( ) ;
cDvbApi : : PrimaryDvbApi - > ToggleAudioTrack ( ) ;
state = osEnd ;
}
}
break ;
case kYellow : if ( ! HasSubMenu ( ) ) {
cDVD * dvd ;
if ( ( dvd = cDVD : : getDVD ( ) ) ) {
dvd - > Eject ( ) ;
state = osEnd ;
}
}
break ;
case kBlue : if ( ! HasSubMenu ( ) )
state = osReplay ;
break ;
default : break ;
2000-05-27 16:10:47 +02:00
}
2000-02-19 13:36:48 +01:00
}
2000-05-01 16:29:46 +02:00
if ( Key ! = kNone )
lastActivity = time ( NULL ) ;
else if ( time ( NULL ) - lastActivity > MENUTIMEOUT )
state = osEnd ;
2000-03-11 11:22:37 +01:00
return state ;
2000-02-19 13:36:48 +01:00
}
2000-11-01 15:41:33 +01:00
// --- cDisplayChannel -------------------------------------------------------
2000-09-10 14:56:18 +02:00
2001-07-12 14:19:43 +02:00
# define DIRECTCHANNELTIMEOUT 1000 //ms
2000-11-01 15:41:33 +01:00
# define INFOTIMEOUT 5000 //ms
2000-09-10 14:56:18 +02:00
2000-11-01 15:41:33 +01:00
cDisplayChannel : : cDisplayChannel ( int Number , bool Switched , bool Group )
: cOsdBase ( true )
{
group = Group ;
withInfo = ! group & & ( ! Switched | | Setup . ShowInfoOnChSwitch ) ;
lines = 0 ;
oldNumber = number = 0 ;
cChannel * channel = Group ? Channels . Get ( Number ) : Channels . GetByNumber ( Number ) ;
2001-07-27 11:51:42 +02:00
Interface - > Open ( Setup . OSDwidth , Setup . ChannelInfoPos ? 5 : - 5 ) ;
2000-11-01 15:41:33 +01:00
if ( channel ) {
DisplayChannel ( channel ) ;
DisplayInfo ( ) ;
}
lastTime = time_ms ( ) ;
}
cDisplayChannel : : cDisplayChannel ( eKeys FirstKey )
2000-09-10 14:56:18 +02:00
: cOsdBase ( true )
{
2000-11-05 18:39:17 +01:00
oldNumber = cDvbApi : : CurrentChannel ( ) ;
2000-09-10 14:56:18 +02:00
number = 0 ;
lastTime = time_ms ( ) ;
2001-07-27 11:51:42 +02:00
Interface - > Open ( Setup . OSDwidth , Setup . ChannelInfoPos ? 5 : - 5 ) ;
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
{
if ( number < 0 )
2000-11-01 15:41:33 +01:00
Interface - > DisplayChannelNumber ( oldNumber ) ;
2000-10-08 12:24:30 +02:00
Interface - > Close ( ) ;
2000-09-10 14:56:18 +02:00
}
2000-11-01 15:41:33 +01:00
void cDisplayChannel : : DisplayChannel ( const cChannel * Channel )
{
2001-07-22 15:17:51 +02:00
if ( Channel & & Channel - > number > 0 )
2001-01-13 13:08:43 +01:00
Interface - > DisplayChannelNumber ( Channel - > number ) ;
int BufSize = Width ( ) + 1 ;
char buffer [ BufSize ] ;
2001-07-22 15:17:51 +02:00
if ( Channel & & Channel - > number > 0 )
2001-07-12 14:19:43 +02:00
snprintf ( buffer , BufSize , " %d%s %s " , Channel - > number , number ? " - " : " " , Channel - > name ) ;
2001-01-13 13:08:43 +01:00
else
snprintf ( buffer , BufSize , " %s " , Channel ? Channel - > name : tr ( " *** Invalid Channel *** " ) ) ;
2001-07-27 11:51:42 +02:00
Interface - > Fill ( 0 , 0 , Setup . OSDwidth , 1 , clrBackground ) ;
2001-01-13 13:08:43 +01:00
Interface - > Write ( 0 , 0 , buffer ) ;
time_t t = time ( NULL ) ;
struct tm * now = localtime ( & t ) ;
snprintf ( buffer , BufSize , " %02d:%02d " , now - > tm_hour , now - > tm_min ) ;
Interface - > Write ( - 5 , 0 , buffer ) ;
2000-11-01 15:41:33 +01:00
}
void cDisplayChannel : : DisplayInfo ( void )
{
if ( withInfo ) {
const cEventInfo * Present = NULL , * Following = NULL ;
cThreadLock ThreadLock ;
const cSchedules * Schedules = cDvbApi : : PrimaryDvbApi - > Schedules ( & ThreadLock ) ;
if ( Schedules ) {
const cSchedule * Schedule = Schedules - > GetSchedule ( ) ;
if ( Schedule ) {
const char * PresentTitle = NULL , * PresentSubtitle = NULL , * FollowingTitle = NULL , * FollowingSubtitle = NULL ;
int Lines = 0 ;
if ( ( Present = Schedule - > GetPresentEvent ( ) ) ! = NULL ) {
PresentTitle = Present - > GetTitle ( ) ;
if ( ! isempty ( PresentTitle ) )
Lines + + ;
PresentSubtitle = Present - > GetSubtitle ( ) ;
if ( ! isempty ( PresentSubtitle ) )
Lines + + ;
}
if ( ( Following = Schedule - > GetFollowingEvent ( ) ) ! = NULL ) {
FollowingTitle = Following - > GetTitle ( ) ;
if ( ! isempty ( FollowingTitle ) )
Lines + + ;
FollowingSubtitle = Following - > GetSubtitle ( ) ;
if ( ! isempty ( FollowingSubtitle ) )
Lines + + ;
}
if ( Lines > lines ) {
const int t = 6 ;
int l = 1 ;
2001-07-27 11:51:42 +02:00
Interface - > Fill ( 0 , 1 , Setup . OSDwidth , Lines , clrBackground ) ;
2000-11-01 15:41:33 +01:00
if ( ! isempty ( PresentTitle ) ) {
Interface - > Write ( 0 , l , Present - > GetTimeString ( ) , clrYellow , clrBackground ) ;
Interface - > Write ( t , l , PresentTitle , clrCyan , clrBackground ) ;
l + + ;
}
if ( ! isempty ( PresentSubtitle ) ) {
Interface - > Write ( t , l , PresentSubtitle , clrCyan , clrBackground ) ;
l + + ;
}
if ( ! isempty ( FollowingTitle ) ) {
Interface - > Write ( 0 , l , Following - > GetTimeString ( ) , clrYellow , clrBackground ) ;
Interface - > Write ( t , l , FollowingTitle , clrCyan , clrBackground ) ;
l + + ;
}
if ( ! isempty ( FollowingSubtitle ) ) {
Interface - > Write ( t , l , FollowingSubtitle , clrCyan , clrBackground ) ;
}
Interface - > Flush ( ) ;
lines = Lines ;
lastTime = time_ms ( ) ;
}
}
}
}
}
eOSState cDisplayChannel : : ProcessKey ( eKeys Key )
2000-09-10 14:56:18 +02:00
{
switch ( Key ) {
2000-11-01 15:41:33 +01:00
case k0 :
if ( number = = 0 ) {
// keep the "Toggle channels" function working
Interface - > PutKey ( Key ) ;
return osEnd ;
}
case k1 . . . k9 :
2000-09-10 14:56:18 +02:00
if ( number > = 0 ) {
number = number * 10 + Key - k0 ;
2000-11-01 15:41:33 +01:00
if ( number > 0 ) {
cChannel * channel = Channels . GetByNumber ( number ) ;
DisplayChannel ( channel ) ;
lastTime = time_ms ( ) ;
if ( ! channel ) {
number = - 1 ;
lastTime + = 1000 ;
}
2000-09-10 14:56:18 +02:00
}
}
break ;
case kNone :
2000-11-01 15:41:33 +01:00
if ( number & & time_ms ( ) - lastTime > DIRECTCHANNELTIMEOUT ) {
2000-09-10 14:56:18 +02:00
if ( number > 0 & & ! Channels . SwitchTo ( number ) )
number = - 1 ;
2000-11-01 15:41:33 +01:00
return osEnd ;
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;
case kOk : if ( group )
Channels . SwitchTo ( Channels . Get ( Channels . GetNextNormal ( CurrentGroup ) ) - > number ) ;
return osEnd ;
default : Interface - > PutKey ( Key ) ;
return osEnd ;
2000-09-10 14:56:18 +02:00
} ;
2000-11-01 15:41:33 +01:00
if ( time_ms ( ) - lastTime < INFOTIMEOUT ) {
DisplayInfo ( ) ;
return osContinue ;
}
return osEnd ;
2000-09-10 14:56:18 +02:00
}
2000-04-30 10:22:13 +02:00
// --- cRecordControl --------------------------------------------------------
2000-05-01 16:29:46 +02:00
cRecordControl : : cRecordControl ( cDvbApi * DvbApi , cTimer * Timer )
2000-04-30 10:22:13 +02:00
{
2000-05-01 16:29:46 +02:00
instantId = NULL ;
dvbApi = DvbApi ;
if ( ! dvbApi ) dvbApi = cDvbApi : : PrimaryDvbApi ; //XXX
2000-04-30 10:22:13 +02:00
timer = Timer ;
if ( ! timer ) {
timer = new cTimer ( true ) ;
Timers . Add ( timer ) ;
Timers . Save ( ) ;
2000-11-11 10:39:27 +01:00
asprintf ( & instantId , cDvbApi : : NumDvbApis > 1 ? " %s - %d " : " %s " , Channels . GetChannelNameByNumber ( timer - > channel ) , dvbApi - > Index ( ) + 1 ) ;
2000-04-30 10:22:13 +02:00
}
timer - > SetRecording ( true ) ;
2001-06-02 10:47:40 +02:00
if ( Channels . SwitchTo ( timer - > channel , dvbApi ) ) {
cRecording Recording ( timer ) ;
if ( dvbApi - > StartRecord ( Recording . FileName ( ) , Channels . GetByNumber ( timer - > channel ) - > ca , timer - > priority ) )
Recording . WriteSummary ( ) ;
Interface - > DisplayRecording ( dvbApi - > Index ( ) , true ) ;
}
else
cThread : : EmergencyExit ( true ) ;
2000-04-30 10:22:13 +02:00
}
cRecordControl : : ~ cRecordControl ( )
{
2000-04-30 11:15:16 +02:00
Stop ( true ) ;
2000-05-01 16:29:46 +02:00
delete instantId ;
2000-04-30 11:15:16 +02:00
}
void cRecordControl : : Stop ( bool KeepInstant )
{
if ( timer ) {
2000-05-01 16:29:46 +02:00
dvbApi - > StopRecord ( ) ;
2000-04-30 11:15:16 +02:00
timer - > SetRecording ( false ) ;
2000-05-01 16:29:46 +02:00
if ( ( IsInstant ( ) & & ! KeepInstant ) | | ( timer - > IsSingleEvent ( ) & & ! timer - > Matches ( ) ) ) {
2000-04-30 11:15:16 +02:00
// checking timer->Matches() to make sure we don't delete the timer
// if the program was cancelled before the timer's stop time!
isyslog ( LOG_INFO , " deleting timer %d " , timer - > Index ( ) + 1 ) ;
Timers . Del ( timer ) ;
Timers . Save ( ) ;
}
timer = NULL ;
2001-01-13 13:08:43 +01:00
Interface - > DisplayRecording ( dvbApi - > Index ( ) , false ) ;
2000-04-30 10:22:13 +02:00
}
}
2000-05-01 16:29:46 +02:00
bool cRecordControl : : Process ( void )
2000-04-30 10:22:13 +02:00
{
2000-05-01 16:29:46 +02:00
if ( ! timer | | ! timer - > Matches ( ) )
return false ;
2001-06-02 10:47:40 +02:00
AssertFreeDiskSpace ( timer - > priority ) ;
2000-05-01 16:29:46 +02:00
return true ;
}
// --- cRecordControls -------------------------------------------------------
cRecordControl * cRecordControls : : RecordControls [ MAXDVBAPI ] = { NULL } ;
bool cRecordControls : : Start ( cTimer * Timer )
{
2000-11-05 18:39:17 +01:00
int ch = Timer ? Timer - > channel : cDvbApi : : CurrentChannel ( ) ;
2000-09-09 14:57:43 +02:00
cChannel * channel = Channels . GetByNumber ( ch ) ;
2000-05-01 16:29:46 +02:00
if ( channel ) {
2001-06-02 10:47:40 +02:00
cDvbApi * dvbApi = cDvbApi : : GetDvbApi ( channel - > ca , Timer ? Timer - > priority : Setup . DefaultPriority ) ;
2000-05-01 16:29:46 +02:00
if ( dvbApi ) {
2000-11-12 14:06:53 +01:00
Stop ( dvbApi ) ;
2000-05-01 16:29:46 +02:00
for ( int i = 0 ; i < MAXDVBAPI ; i + + ) {
if ( ! RecordControls [ i ] ) {
RecordControls [ i ] = new cRecordControl ( dvbApi , Timer ) ;
return true ;
}
}
}
2001-02-24 14:03:39 +01:00
else if ( ! Timer | | Timer - > priority > = Setup . PrimaryLimit )
2000-09-09 14:57:43 +02:00
esyslog ( LOG_ERR , " ERROR: no free DVB device to record channel %d! " , ch ) ;
2000-05-01 16:29:46 +02:00
}
else
2000-09-09 14:57:43 +02:00
esyslog ( LOG_ERR , " ERROR: channel %d not defined! " , ch ) ;
2000-05-01 16:29:46 +02:00
return false ;
}
void cRecordControls : : Stop ( const char * InstantId )
{
for ( int i = 0 ; i < MAXDVBAPI ; i + + ) {
if ( RecordControls [ i ] ) {
const char * id = RecordControls [ i ] - > InstantId ( ) ;
if ( id & & strcmp ( id , InstantId ) = = 0 )
RecordControls [ i ] - > Stop ( ) ;
}
}
}
2000-11-12 14:06:53 +01:00
void cRecordControls : : Stop ( cDvbApi * DvbApi )
{
for ( int i = 0 ; i < MAXDVBAPI ; i + + ) {
if ( RecordControls [ i ] ) {
if ( RecordControls [ i ] - > Uses ( DvbApi ) ) {
isyslog ( LOG_INFO , " stopping recording on DVB device %d due to higher priority " , DvbApi - > Index ( ) + 1 ) ;
2001-01-13 13:08:43 +01:00
RecordControls [ i ] - > Stop ( true ) ;
2000-11-12 14:06:53 +01:00
}
}
}
}
2000-05-01 16:29:46 +02:00
const char * cRecordControls : : GetInstantId ( const char * LastInstantId )
{
for ( int i = 0 ; i < MAXDVBAPI ; i + + ) {
if ( RecordControls [ i ] ) {
if ( ! LastInstantId & & RecordControls [ i ] - > InstantId ( ) )
return RecordControls [ i ] - > InstantId ( ) ;
if ( LastInstantId & & LastInstantId = = RecordControls [ i ] - > InstantId ( ) )
LastInstantId = NULL ;
}
}
return NULL ;
}
void cRecordControls : : Process ( void )
{
for ( int i = 0 ; i < MAXDVBAPI ; i + + ) {
if ( RecordControls [ i ] ) {
if ( ! RecordControls [ i ] - > Process ( ) )
DELETENULL ( RecordControls [ i ] ) ;
}
}
2000-04-30 10:22:13 +02:00
}
2001-02-04 12:36:32 +01:00
bool cRecordControls : : Active ( void )
{
for ( int i = 0 ; i < MAXDVBAPI ; i + + ) {
if ( RecordControls [ i ] )
return true ;
}
return false ;
}
2000-12-28 12:57:16 +01:00
// --- cProgressBar ----------------------------------------------------------
class cProgressBar : public cBitmap {
protected :
int total ;
int Pos ( int p ) { return p * width / total ; }
void Mark ( int x , bool Start , bool Current ) ;
public :
cProgressBar ( int Width , int Height , int Current , int Total , const cMarks & Marks ) ;
} ;
cProgressBar : : cProgressBar ( int Width , int Height , int Current , int Total , const cMarks & Marks )
2001-07-22 12:33:45 +02:00
: cBitmap ( Width , Height , 2 )
2000-12-28 12:57:16 +01:00
{
total = Total ;
if ( total > 0 ) {
int p = Pos ( Current ) ;
Fill ( 0 , 0 , p , Height - 1 , clrGreen ) ;
Fill ( p + 1 , 0 , Width - 1 , Height - 1 , clrWhite ) ;
bool Start = true ;
for ( const cMark * m = Marks . First ( ) ; m ; m = Marks . Next ( m ) ) {
int p1 = Pos ( m - > position ) ;
if ( Start ) {
const cMark * m2 = Marks . Next ( m ) ;
int p2 = Pos ( m2 ? m2 - > position : total ) ;
int h = Height / 3 ;
Fill ( p1 , h , p2 , Height - h , clrRed ) ;
}
Mark ( p1 , Start , m - > position = = Current ) ;
Start = ! Start ;
}
}
}
void cProgressBar : : Mark ( int x , bool Start , bool Current )
{
Fill ( x , 0 , x , height - 1 , clrBlack ) ;
const int d = height / ( Current ? 3 : 9 ) ;
for ( int i = 0 ; i < d ; i + + ) {
int h = Start ? i : height - 1 - i ;
Fill ( x - d + i , h , x + d - i , h , Current ? clrRed : clrBlack ) ;
}
}
2000-04-29 15:57:42 +02:00
// --- cReplayControl --------------------------------------------------------
char * cReplayControl : : fileName = NULL ;
char * cReplayControl : : title = NULL ;
2001-08-03 14:18:08 +02:00
cDVD * cReplayControl : : dvd = NULL ; //XXX
int cReplayControl : : titleid = 0 ; //XXX
2000-04-29 15:57:42 +02:00
cReplayControl : : cReplayControl ( void )
{
2000-12-09 11:13:00 +01:00
dvbApi = cDvbApi : : PrimaryDvbApi ;
2000-12-28 12:57:16 +01:00
visible = shown = displayFrames = false ;
2001-07-28 13:16:23 +02:00
lastCurrent = lastTotal = - 1 ;
2001-07-28 14:06:36 +02:00
timeoutShow = 0 ;
2000-12-28 12:57:16 +01:00
if ( fileName ) {
marks . Load ( fileName ) ;
2000-12-09 11:13:00 +01:00
dvbApi - > StartReplay ( fileName ) ;
2000-12-28 12:57:16 +01:00
}
2001-08-03 14:18:08 +02:00
else if ( dvd )
dvbApi - > StartDVDplay ( dvd , titleid ) ; //XXX
2000-04-29 15:57:42 +02:00
}
cReplayControl : : ~ cReplayControl ( )
{
Hide ( ) ;
2000-12-08 16:23:32 +01:00
dvbApi - > StopReplay ( ) ;
2000-04-29 15:57:42 +02:00
}
void cReplayControl : : SetRecording ( const char * FileName , const char * Title )
{
delete fileName ;
delete title ;
fileName = FileName ? strdup ( FileName ) : NULL ;
title = Title ? strdup ( Title ) : NULL ;
}
2000-04-23 15:38:16 +02:00
2001-08-03 14:18:08 +02:00
void cReplayControl : : SetDVD ( cDVD * DVD , int Title ) //XXX
{
SetRecording ( NULL , NULL ) ;
dvd = DVD ;
titleid = Title ;
}
2000-10-08 15:08:26 +02:00
const char * cReplayControl : : LastReplayed ( void )
{
return fileName ;
}
2000-10-08 15:41:30 +02:00
void cReplayControl : : ClearLastReplayed ( const char * FileName )
{
if ( fileName & & FileName & & strcmp ( fileName , FileName ) = = 0 ) {
delete fileName ;
fileName = NULL ;
}
}
2001-07-28 14:06:36 +02:00
void cReplayControl : : Show ( int Seconds )
2000-04-23 15:38:16 +02:00
{
2000-04-29 15:57:42 +02:00
if ( ! visible ) {
2001-07-27 11:51:42 +02:00
Interface - > Open ( Setup . OSDwidth , - 3 ) ;
2000-04-30 10:22:13 +02:00
needsFastResponse = visible = true ;
2000-12-09 11:13:00 +01:00
shown = ShowProgress ( true ) ;
2001-07-28 16:32:40 +02:00
if ( Seconds > 0 )
2001-07-28 14:06:36 +02:00
timeoutShow = time ( NULL ) + Seconds ;
2000-04-29 15:57:42 +02:00
}
2000-04-23 15:38:16 +02:00
}
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 ) {
2000-10-08 12:24:30 +02:00
Interface - > Close ( ) ;
2000-04-30 10:22:13 +02:00
needsFastResponse = visible = false ;
2000-04-29 15:57:42 +02:00
}
2000-04-23 15:38:16 +02:00
}
2000-12-09 11:13:00 +01:00
bool cReplayControl : : ShowProgress ( bool Initial )
{
int Current , Total ;
2000-12-28 12:57:16 +01:00
if ( dvbApi - > GetIndex ( Current , Total ) & & Total > 0 ) {
2000-12-09 11:13:00 +01:00
if ( Initial ) {
Interface - > Clear ( ) ;
if ( title )
Interface - > Write ( 0 , 0 , title ) ;
2001-07-28 16:32:40 +02:00
lastCurrent = lastTotal = - 1 ;
2000-12-09 11:13:00 +01:00
}
2001-07-28 13:16:23 +02:00
if ( Total ! = lastTotal ) {
Interface - > Write ( - 7 , 2 , IndexToHMSF ( Total ) ) ;
Interface - > Flush ( ) ;
lastTotal = Total ;
}
if ( Current ! = lastCurrent ) {
2000-12-09 11:13:00 +01:00
# ifdef DEBUG_OSD
2001-07-28 13:16:23 +02:00
int p = Width ( ) * Current / Total ;
Interface - > Fill ( 0 , 1 , p , 1 , clrGreen ) ;
Interface - > Fill ( p , 1 , Width ( ) - p , 1 , clrWhite ) ;
2000-12-09 11:13:00 +01:00
# else
2001-07-28 13:16:23 +02:00
cProgressBar ProgressBar ( Width ( ) * dvbApi - > CellWidth ( ) , dvbApi - > LineHeight ( ) , Current , Total , marks ) ;
Interface - > SetBitmap ( 0 , dvbApi - > LineHeight ( ) , ProgressBar ) ;
Interface - > Flush ( ) ;
2000-12-09 11:13:00 +01:00
# endif
2001-07-28 13:16:23 +02:00
Interface - > Write ( 0 , 2 , IndexToHMSF ( Current , displayFrames ) ) ;
Interface - > Flush ( ) ;
lastCurrent = Current ;
}
2000-12-09 11:13:00 +01:00
return true ;
}
return false ;
}
2000-12-28 12:57:16 +01:00
void cReplayControl : : MarkToggle ( void )
{
int Current , Total ;
if ( dvbApi - > GetIndex ( Current , Total , true ) ) {
cMark * m = marks . Get ( Current ) ;
if ( m )
marks . Del ( m ) ;
2001-07-28 14:06:36 +02:00
else {
2000-12-28 12:57:16 +01:00
marks . Add ( Current ) ;
2001-07-28 14:06:36 +02:00
Show ( 2 ) ;
}
2000-12-28 12:57:16 +01:00
marks . Save ( ) ;
}
}
void cReplayControl : : MarkJump ( bool Forward )
{
2001-07-22 13:46:07 +02:00
if ( marks . Count ( ) ) {
int Current , Total ;
if ( dvbApi - > GetIndex ( Current , Total ) ) {
cMark * m = Forward ? marks . GetNext ( Current ) : marks . GetPrev ( Current ) ;
if ( m )
dvbApi - > Goto ( m - > position , true ) ;
}
displayFrames = true ;
2000-12-28 12:57:16 +01:00
}
}
void cReplayControl : : MarkMove ( bool Forward )
{
int Current , Total ;
if ( dvbApi - > GetIndex ( Current , Total ) ) {
cMark * m = marks . Get ( Current ) ;
if ( m ) {
2001-07-22 13:46:07 +02:00
displayFrames = true ;
2000-12-28 12:57:16 +01:00
int p = dvbApi - > SkipFrames ( Forward ? 1 : - 1 ) ;
cMark * m2 ;
if ( Forward ) {
if ( ( m2 = marks . Next ( m ) ) ! = NULL & & m2 - > position < = p )
return ;
}
else {
if ( ( m2 = marks . Prev ( m ) ) ! = NULL & & m2 - > position > = p )
return ;
}
2001-01-07 17:00:50 +01:00
dvbApi - > Goto ( m - > position = p , true ) ;
2000-12-28 12:57:16 +01:00
marks . Save ( ) ;
}
}
}
void cReplayControl : : EditCut ( void )
{
Hide ( ) ;
if ( ! cVideoCutter : : Active ( ) ) {
if ( ! cVideoCutter : : Start ( fileName ) )
Interface - > Error ( tr ( " Can't start editing process! " ) ) ;
else
Interface - > Info ( tr ( " Editing process started " ) ) ;
}
else
Interface - > Error ( tr ( " Editing process already active! " ) ) ;
}
void cReplayControl : : EditTest ( void )
{
int Current , Total ;
if ( dvbApi - > GetIndex ( Current , Total ) ) {
cMark * m = marks . Get ( Current ) ;
if ( ! m )
m = marks . GetNext ( Current ) ;
if ( m ) {
if ( ( m - > Index ( ) & 0x01 ) ! = 0 )
m = marks . Next ( m ) ;
if ( m ) {
dvbApi - > Goto ( m - > position - dvbApi - > SecondsToFrames ( 3 ) ) ;
dvbApi - > Play ( ) ;
}
}
}
}
2000-04-29 15:57:42 +02:00
eOSState cReplayControl : : ProcessKey ( eKeys Key )
2000-04-23 15:38:16 +02:00
{
2000-05-01 16:29:46 +02:00
if ( ! dvbApi - > Replaying ( ) )
2000-04-29 15:57:42 +02:00
return osEnd ;
2001-07-28 14:06:36 +02:00
if ( visible ) {
if ( timeoutShow & & time ( NULL ) > timeoutShow ) {
Hide ( ) ;
timeoutShow = 0 ;
}
else
shown = ShowProgress ( ! shown ) | | shown ;
}
2001-07-22 13:46:07 +02:00
bool DisplayedFrames = displayFrames ;
displayFrames = false ;
2000-04-23 15:38:16 +02:00
switch ( Key ) {
2000-12-28 12:57:16 +01:00
// Positioning:
2000-07-30 16:14:22 +02:00
case kUp : dvbApi - > Play ( ) ; break ;
case kDown : dvbApi - > Pause ( ) ; break ;
case kLeft : dvbApi - > Backward ( ) ; break ;
case kRight : dvbApi - > Forward ( ) ; break ;
2000-10-08 11:39:11 +02:00
case kLeft | k_Release :
case kRight | k_Release :
dvbApi - > Play ( ) ; break ;
case kGreen | k_Repeat :
2000-12-28 12:57:16 +01:00
case kGreen : dvbApi - > SkipSeconds ( - 60 ) ; break ;
2000-10-08 11:39:11 +02:00
case kYellow | k_Repeat :
2000-12-28 12:57:16 +01:00
case kYellow : dvbApi - > SkipSeconds ( 60 ) ; break ;
case kBlue : Hide ( ) ;
dvbApi - > StopReplay ( ) ;
return osEnd ;
2001-07-22 13:46:07 +02:00
default : {
switch ( Key ) {
// Editing:
//XXX should we do this only when the ProgressDisplay is on???
case kMarkToggle : MarkToggle ( ) ; break ;
case kMarkJumpBack : MarkJump ( false ) ; break ;
case kMarkJumpForward : MarkJump ( true ) ; break ;
case kMarkMoveBack | k_Repeat :
case kMarkMoveBack : MarkMove ( false ) ; break ;
case kMarkMoveForward | k_Repeat :
case kMarkMoveForward : MarkMove ( true ) ; break ;
case kEditCut : EditCut ( ) ; break ;
case kEditTest : EditTest ( ) ; break ;
default : {
displayFrames = DisplayedFrames ;
switch ( Key ) {
// Menu control:
case kMenu : Hide ( ) ; return osMenu ; // allow direct switching to menu
case kOk : visible ? Hide ( ) : Show ( ) ; break ;
case kBack : return osRecordings ;
default : return osUnknown ;
}
}
}
}
2000-04-23 15:38:16 +02:00
}
2001-07-22 13:46:07 +02:00
if ( DisplayedFrames & & ! displayFrames )
Interface - > Fill ( 0 , 2 , Width ( ) / 2 , 1 , clrBackground ) ;
2000-04-29 15:57:42 +02:00
return osContinue ;
2000-04-23 15:38:16 +02:00
}