diff options
-rw-r--r-- | CONTRIBUTORS | 38 | ||||
-rw-r--r-- | HISTORY | 98 | ||||
-rw-r--r-- | INSTALL | 17 | ||||
-rw-r--r-- | MANUAL | 5 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | PLUGINS/src/dvbhddevice/dvbhdffdevice.c | 173 | ||||
-rw-r--r-- | PLUGINS/src/dvbhddevice/hdffosd.c | 104 | ||||
-rw-r--r-- | PLUGINS/src/pictures/HISTORY | 4 | ||||
-rw-r--r-- | PLUGINS/src/pictures/pictures.c | 4 | ||||
-rw-r--r-- | PLUGINS/src/pictures/player.c | 7 | ||||
-rw-r--r-- | PLUGINS/src/pictures/player.h | 3 | ||||
-rw-r--r-- | PLUGINS/src/skincurses/HISTORY | 5 | ||||
-rw-r--r-- | PLUGINS/src/skincurses/skincurses.c | 20 | ||||
-rw-r--r-- | channels.c | 4 | ||||
-rw-r--r-- | ci.c | 3 | ||||
-rw-r--r-- | config.c | 11 | ||||
-rw-r--r-- | config.h | 21 | ||||
-rw-r--r-- | cutter.c | 4 | ||||
-rw-r--r-- | device.c | 13 | ||||
-rw-r--r-- | device.h | 8 | ||||
-rw-r--r-- | dvbdevice.c | 48 | ||||
-rw-r--r-- | dvbdevice.h | 3 | ||||
-rw-r--r-- | dvbplayer.c | 4 | ||||
-rw-r--r-- | dvbsubtitle.c | 4 | ||||
-rw-r--r-- | eit.c | 7 | ||||
-rw-r--r-- | eitscan.c | 4 | ||||
-rw-r--r-- | epg.c | 15 | ||||
-rw-r--r-- | epg.h | 8 | ||||
-rw-r--r-- | font.c | 9 | ||||
-rw-r--r-- | menu.c | 156 | ||||
-rw-r--r-- | menu.h | 12 | ||||
-rw-r--r-- | menuitems.c | 3 | ||||
-rw-r--r-- | osd.c | 38 | ||||
-rw-r--r-- | osd.h | 12 | ||||
-rw-r--r-- | osdbase.c | 14 | ||||
-rw-r--r-- | osdbase.h | 6 | ||||
-rw-r--r-- | pat.c | 68 | ||||
-rw-r--r-- | player.c | 16 | ||||
-rw-r--r-- | player.h | 19 | ||||
-rw-r--r-- | po/ar.po | 38 | ||||
-rw-r--r-- | po/ca_ES.po | 38 | ||||
-rw-r--r-- | po/cs_CZ.po | 38 | ||||
-rw-r--r-- | po/da_DK.po | 38 | ||||
-rw-r--r-- | po/de_DE.po | 38 | ||||
-rw-r--r-- | po/el_GR.po | 38 | ||||
-rw-r--r-- | po/es_ES.po | 38 | ||||
-rw-r--r-- | po/et_EE.po | 38 | ||||
-rw-r--r-- | po/fi_FI.po | 38 | ||||
-rw-r--r-- | po/fr_FR.po | 38 | ||||
-rw-r--r-- | po/hr_HR.po | 38 | ||||
-rw-r--r-- | po/hu_HU.po | 38 | ||||
-rw-r--r-- | po/it_IT.po | 38 | ||||
-rw-r--r-- | po/lt_LT.po | 38 | ||||
-rw-r--r-- | po/mk_MK.po | 38 | ||||
-rw-r--r-- | po/nl_NL.po | 38 | ||||
-rw-r--r-- | po/nn_NO.po | 38 | ||||
-rw-r--r-- | po/pl_PL.po | 38 | ||||
-rw-r--r-- | po/pt_PT.po | 38 | ||||
-rw-r--r-- | po/ro_RO.po | 38 | ||||
-rw-r--r-- | po/ru_RU.po | 38 | ||||
-rw-r--r-- | po/sk_SK.po | 38 | ||||
-rw-r--r-- | po/sl_SI.po | 38 | ||||
-rw-r--r-- | po/sr_SR.po | 38 | ||||
-rw-r--r-- | po/sv_SE.po | 38 | ||||
-rw-r--r-- | po/tr_TR.po | 38 | ||||
-rw-r--r-- | po/uk_UA.po | 38 | ||||
-rw-r--r-- | po/zh_CN.po | 38 | ||||
-rw-r--r-- | receiver.c | 18 | ||||
-rw-r--r-- | receiver.h | 9 | ||||
-rw-r--r-- | recording.c | 37 | ||||
-rw-r--r-- | recording.h | 14 | ||||
-rw-r--r-- | skinclassic.c | 20 | ||||
-rw-r--r-- | skinlcars.c | 2114 | ||||
-rw-r--r-- | skinlcars.h | 27 | ||||
-rw-r--r-- | skins.c | 13 | ||||
-rw-r--r-- | skins.h | 20 | ||||
-rw-r--r-- | skinsttng.c | 20 | ||||
-rw-r--r-- | svdrp.c | 34 | ||||
-rw-r--r-- | svdrp.h | 4 | ||||
-rw-r--r-- | thread.c | 4 | ||||
-rw-r--r-- | timers.c | 19 | ||||
-rw-r--r-- | timers.h | 7 | ||||
-rw-r--r-- | tools.c | 13 | ||||
-rw-r--r-- | tools.h | 22 | ||||
-rw-r--r-- | vdr.c | 4 | ||||
-rw-r--r-- | videodir.c | 42 | ||||
-rw-r--r-- | videodir.h | 40 |
87 files changed, 3812 insertions, 725 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 54bb679..baa09ee 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1140,6 +1140,7 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> for suggesting to change the Green button in the "Edit timer" menu from "Once" to "Single" for fixing reduced bpp support for DVB subtitles + for implementing "DVB Standard compliance" handling Ralf Klueber <ralf.klueber@vodafone.com> for reporting a bug in cutting a recording if there is only a single editing mark @@ -1309,6 +1310,7 @@ Reinhard Nissl <rnissl@gmx.de> for making cEITScanner process new transponders before old ones, to make sure transponder changes are recognized for helping to debug switching into time shift mode when pausing live video + for fixing a possible high CPU load when pausing replay Richard Robson <richard_robson@beeb.net> for reporting freezing replay if a timer starts while in Transfer Mode from the @@ -1782,6 +1784,7 @@ Joachim Wilke <vdr@joachim-wilke.de> for modifying cCharSetConv so that it can be used to convert from "whatever VDR uses" to a given code for adding some missing 'const' to cDevice + for making sure setup strings don't contain any newline characters Sascha Klek <sklek@gmx.de> for reporting a problem with the '0' key in the "Day" item of the "Timers" menu @@ -2591,6 +2594,9 @@ Sundararaj Reel <sundararaj.reel@googlemail.com> for reporting a memory leak in cRecordings::ScanVideoDir() in case there are too many link levels for reporting a bug in cListBase::Move() in case From and To are equal + for reporting a problem with the function cString::sprintf(const char *fmt, va_list &ap), + that might inadvertently be called with a 'char *' as the second argument on some + compilers and cause a crash Ales Jurik <ajurik@quick.cz> for reporting broken SI data on Czech/Slovak channels after changing the default @@ -2663,6 +2669,8 @@ Derek Kelly (user.vdr@gmail.com) could not be determined after resuming recording for reporting a problem with detecting frames for channels that split frames into several payloads + for reporting a problem with getting the maximum short channel name length in case there + are no short names at all Marcel Unbehaun <frostworks@gmx.de> for adding cRecordingInfo::GetEvent() @@ -2720,6 +2728,7 @@ Lars Hanisch <dvb@flensrocker.de> for suggesting to assign the source character 'V' to "Analog Video" for a patch that was used to implement SCR (Satellite Channel Routing) for implementing the SVDRP command 'UPDR' + for reporting that the SVDRP command UPDR didn't update the global recordings list Alex Lasnier <alex@fepg.org> for adding tuning support for ATSC devices @@ -2771,6 +2780,7 @@ Dominik Strasser <dominik@die-strassers.de> Joerg Bornkessel <hd_brummy@gentoo.org> for adding LDFLAGS to the linker calls in the Makefiles + for fixing font handling with fontconfig 2.9.0 or newer Andreas Oberritter <obi@opendreambox.org> for suggesting to retrieve the include path to the freetype2 header files @@ -2790,6 +2800,8 @@ Gerald Dachs <vdr@dachsweb.de> Juergen Lock <vdr-l@jelal.kn-bremen.de> for fixing cUnbufferedFile::Seek() in case it is compiled without USE_FADVISE + for reporting a problem with EPG scan on systems with only a single DVB device that + use software output Sergiu Dotenco <sergiu.dotenco@googlemail.com> for reporting a missing initialization in sDvbSpuRect @@ -2849,6 +2861,9 @@ Torsten Lang <info@torstenlang.de> of EPG data from BSkyB's "MTV MUSIC" for suggesting to make BIDI support check at runtime whether the system runs with UTF-8 + for reporting a bug in checking for UTF-8 support in cFont::Bidi() + for a patch that was used to implement caching the information whether a recording + is stored on the video directory file system within the cRecording data Christian Ruppert <idl0r@gentoo.org> for some improvements to the Makefiles @@ -2862,3 +2877,26 @@ Ralf Schueler <dl4mw@schueler.ws> from version 1.7.8 to 1.6.0-3 for backporting "Fixed cRecordings::DelByName() to avoid compilation errors with gcc 4.4" from version 1.7.9 to 1.6.0-3 + +Marcus Roscher <dad401@gmx.de> + for reporting a problem with cDevice::StillPicture(), which called the derived class's + function even if no buffer has been allocated + +Reinhard Mantey <geronimo013@gmx.de> + for reporting a problem with character comparisons in + cSubtitleObject::DecodeCharacterString() + for fixing a mismatched 'delete' in cSchedules::SetEpgDataFileName() + +Michael Schneider <vdrportal_midas@gmx.de> + for reporting a problem with the EPG scan in case a transponder is not receivable in + a setup with bonded devices + +Marco Skambraks <marco@ammec.de> + for fixing resetting CAMs + +Christian Richter <cr@crichter.net> + for extending the interface to the script that gets called for recordings, so that in + the "edited" case it also provides the name of the original recording + +Christian Kaiser <christian.kaiser@teleservice.com> + for adding DeleteEvent() to the EPG handler interface @@ -6603,7 +6603,7 @@ Video Disk Recorder Revision History - Now using pkg-config to get fribidi, freetype and fontconfig cflags and libs (thanks to Ville Skyttä). - The Makefile now also installs the include files (thanks to Ville Skyttä). -- Added handling of "ANSI/SCTE 57" descriptors (thanks too Rolf Ahrenberg). +- Added handling of "ANSI/SCTE 57" descriptors (thanks to Rolf Ahrenberg). - Avoiding an unecessary call to Recordings.ResetResume() (thanks to Reinhard Nissl). @@ -7051,3 +7051,99 @@ Video Disk Recorder Revision History - Reverted some improvements to Make.config.template (thanks to Christian Ruppert). - Fixed handling IDLEPRIORITY in cDvbDevice::ProvidesChannel() (thanks to Frank Schmirler). + +2012-06-03: Version 1.7.28 + +- Fixed cPixmapMemory::DrawEllipse() for quadrants -1 and -4. +- Fixed getting the maximum short channel name length in case there are no short names + at all (reported by Derek Kelly). +- The new function cDevice::DeviceType() returns a string identifying the type of + the given device. +- Now limiting the number of characters of a channel's (short) name to 16 in the + schedules menus, to keep that column from getting overly wide in case there is + a channel with a very long name that has no short name. +- Fixed EPG scan on systems with only a single DVB device that use software output + (reported by Juergen Lock). +- Skins can now inquire the menu category for which their cSkinDisplayMenu is currently + being used. This can be done either through a call to cSkinDisplayMenu::MenuCategory() + or by reimplementing cSkinDisplayMenu::SetMenuCategory(). This information allows a + skin to use special icons or decorations for the various types of menus in VDR. +- The new setup option "DVB/Standard compliance" can be used to switch between different + variations of the DVB standard (thanks to Rolf Ahrenberg). Currently there is "DVB" + (for the original DVB standard) and "ANSI/SCTE", which is used to properly handle + certain private stream types. +- The disk usage is no longer automatically added to the title of the main and + "Recordings" menus. This has always been a mekeshift solution and it is now up + to the individual skin if, where and how it wants to display this information. + A skin can use the new cVideoDiskUsage class to implement such a display. For + compatibility, the default skins "Classic VDR", "ST:TNG Panels" and "Text mode" + (i.e. curses) have been changed to behave like before. Other skins may want to + display the disk usage in totally different ways. +- A cOsdMenu can now handle skins that display different numbers of items in the + various menu categories. +- OSD and skin are now reinitialized after a plugin setup page has been confirmed, + to have them react immediately in case any change to a plugin's setup parameter + has an effect on the OSD. +- The Timers list is now marked as modified whenever a recording starts or ends. +- Fixed cDevice::StillPicture(), making sure it doesn't call the derived class's + function if no buffer has been allocated (reported by Marcus Roscher). +- Fixed the SVDRP command UPDR, which didn't update the global recordings list + (reported by Lars Hanisch). +- cControl::Control() now has an additional boolean parameter, which can be set to + true to get the current player control even if it is hidden. +- The new functions cControl::GetRecording() and cControl::GetHeader() can be used + to retrieve information about what the current player is playing. +- Fixed a possible high CPU load when pausing replay (thanks to Reinhard Nissl). +- Fixed character comparisons in cSubtitleObject::DecodeCharacterString() (reported + by Reinhard Mantey). +- Renamed the function cString::sprintf(const char *fmt, va_list &ap) to vsprintf(), + because it might inadvertently be called with a 'char *' as the second argument on + some compilers and cause a crash (reported by Sundararaj Reel). +- Removed the "bondedMasterFailed" mechanism from cDvbTuner, because it caused + problems with the EPG scan in case a transponder is not receivable in a setup with + bonded devices (reported by Michael Schneider). +- Making sure setup strings don't contain any newline characters (thanks to Joachim + Wilke). +- The new member function cSkinDisplayReplay::SetRecording() allows a skin to display + more information about the currently played recording. +- Fixed a mismatched 'delete' in cSchedules::SetEpgDataFileName() (thanks to Reinhard + Mantey). +- The DrawText() functions of the OSD now accept the new alignment flag taBorder, + which triggers keeping a proper distance from the edge that taLeft or taRight + aligns to. +- Fixed checking for UTF-8 support in cFont::Bidi() (reported by Torsten Lang). +- If a recording has no info file, the 'title' of the recording's info is now set + to the recording's name. +- cVector::Clear() now reinitializes any previously used members. +- Fixed resetting CAMs (thanks to Marco Skambraks). +- The new function RgbShade() (include osd.h) can be used to generate a brighter or + darker version of a given color. +- The new class cSortedTimers can be used to quickly get a list of all timers, sorted + by their start time. +- The new skin "LCARS" is an enhanced version of the "ST:TNG" skin (which is still + there in its original layout, for those who don't like the LCARS skin, or can't use + it due to OSD limitations). The LCARS skin utilizes the new "menu category" feature + to display additional information on the main menu page. It shows upcoming timers + and the system's devices, as well as which device is recording which timers. The + upper pane of the main menu displays the programme data in live and replay mode, + and a progress bar. An indicator on the right side of the device list shows which + device is currently used for live viewing, and whether it is in transfer mode. + The individual device displays show the device number, the device type, which CAM + (if any ) is currently assigned to the device, and the signal strength and quality. + On the left side of the OSD there is a permanent display of the current date and + time, the disk usage and the system load. + "LCARS" is the new default skin of VDR. It requires at least a 4bpp (16 color) full + screen OSD, but you can still operate it if your OSD can handle only fewer colors + (in which case you may want to switch to the "ST:TNG" or "Classic VDR" skin). +- Finally removed the code marked with __RECORDING_H_DEPRECATED_DIRECT_MEMBER_ACCESS + and LEGACY_CRECEIVER. +- Now making sure that the "small font" is never larger than the "osd font". +- Fixed font handling with fontconfig 2.9.0 or newer (thanks to Joerg Bornkessel). +- Extended the interface to the script that gets called for recordings, so that in + the "edited" case it also provides the name of the original recording (thanks to + Christian Richter). +- Added DeleteEvent() to the EPG handler interface, so that an EPG handler can trigger + deleting of an event (thanks to Christian Kaiser). +- Speeded up opening menus on systems with many (several thousands) of recordings, by + caching the information whether a recording is stored on the video directory file + system within the cRecording data (based on a patch from Torsten Lang). @@ -88,6 +88,15 @@ vdr:123:respawn:/usr/local/bin/vdr --terminal=/dev/tty8 -w 60 See the man page vdr(1) for complete information about all command line options. +Standard compliance +------------------- + +Basically VDR works according to the DVB standard, but there are countries/providers +that use other standards, which in some details deviate from the DVB standard. +This makes it necessary to handle things differently in some areas, depending on +which standard is actually used. If this is the case in your area, you may need +to adjust the option "DVB/Standard compliance" in the Setup menu accordingly. + Locale ------ @@ -235,8 +244,8 @@ You can use the '-r' option to define a program or script that gets called before and after a recording is performed, and after an editing process has finished. -The program will be called with two string parameters. The first parameter -is one of +The program will be called with two or three (in case of "edited") string +parameters. The first parameter is one of before if this is *before* a recording starts after if this is *after* a recording has finished @@ -244,7 +253,8 @@ is one of and the second parameter contains the full name of the recording's directory (which may not yet exists at that moment in the "before" case). -In the "edited" case it will be the name of the edited version. +In the "edited" case it will be the name of the edited version (second +parameter) and the name of the source version (third parameter). Within this program you can do anything you would like to do before and/or after a recording or after an editing process. However, the program must return @@ -265,6 +275,7 @@ case "$1" in ;; edited) echo "Edited recording $2" + echo "Source recording $3" ;; *) echo "ERROR: unknown state: $1" @@ -674,6 +674,11 @@ Version 1.6 from the primary DVB interface, so that the viewer will be disturbed as little as possible. + Standard Compliance = 0 + Defines the standard compliance mode: + 0 = DVB + 1 = ANSI/SCTE + Video format = 4:3 The video format (or aspect ratio) of the tv set in use (4:3 or 16:9). @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 2.26 2012/03/11 15:33:57 kls Exp $ +# $Id: Makefile 2.27 2012/04/15 13:21:31 kls Exp $ .DELETE_ON_ERROR: @@ -44,7 +44,7 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\ lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o\ receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\ - skinclassic.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ + skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ timers.o tools.o transfer.o vdr.o videodir.o ifndef NO_KBD diff --git a/PLUGINS/src/dvbhddevice/dvbhdffdevice.c b/PLUGINS/src/dvbhddevice/dvbhdffdevice.c index ced24f5..f8b47bd 100644 --- a/PLUGINS/src/dvbhddevice/dvbhdffdevice.c +++ b/PLUGINS/src/dvbhddevice/dvbhdffdevice.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: dvbhdffdevice.c 1.41 2012/03/07 13:52:41 kls Exp $ + * $Id: dvbhdffdevice.c 1.43 2012/05/08 11:40:32 kls Exp $ */ #include <stdint.h> @@ -50,7 +50,7 @@ cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend) mHdffCmdIf = new HDFF::cHdffCmdIf(fd_osd); /* reset some stuff in case the VDR was killed before and had no chance - to clean up. */ + to clean up. */ mHdffCmdIf->CmdOsdReset(); mHdffCmdIf->CmdAvSetVideoSpeed(0, 100); @@ -183,68 +183,72 @@ void cDvbHdFfDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect) gHdffSetup.GetOsdSize(Width, Height, PixelAspect); } -/*TODO obsolete? -bool cDvbHdFfDevice::SetAudioBypass(bool On) -{ - if (setTransferModeForDolbyDigital != 1) - return false; - return ioctl(fd_audio, AUDIO_SET_BYPASS_MODE, On) == 0; -} -TODO*/ - bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On) { - if (Handle->pid) { - dmx_pes_filter_params pesFilterParams; - memset(&pesFilterParams, 0, sizeof(pesFilterParams)); - if (On) { - if (Handle->handle < 0) { - Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true); - if (Handle->handle < 0) { - LOG_ERROR; - return false; - } - } - if (Type == ptPcr) - mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid); - else if (Type == ptVideo) { - if (Handle->streamType == 0x1B) - mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_H264); - else - mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_MPEG2); - } - else if (Type == ptAudio) - mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1); - else if (Type == ptDolby) - mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AC3); - if (!(Type <= ptDolby && Handle->used <= 1)) { - pesFilterParams.pid = Handle->pid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pes_type= DMX_PES_OTHER; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { - LOG_ERROR; - return false; - } - } + //printf("SetPid Type %d, On %d, PID %5d, streamtype %d, handle %d, used %d\n", Type, On, Handle->pid, Handle->streamType, Handle->handle, Handle->used); + if (Handle->pid) { + dmx_pes_filter_params pesFilterParams; + memset(&pesFilterParams, 0, sizeof(pesFilterParams)); + if (On) { + if (Handle->handle < 0) { + Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true); + if (Handle->handle < 0) { + LOG_ERROR; + return false; + } + } + if (Type == ptPcr) + mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid); + else if (Type == ptVideo) { + if (Handle->streamType == 0x1B) + mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_H264); + else + mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_MPEG2); + } + else if (Type == ptAudio) { + if (Handle->streamType == 0x03) + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1); + else if (Handle->streamType == 0x04) + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG2); + else if (Handle->streamType == SI::AC3DescriptorTag) + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AC3); + else if (Handle->streamType == SI::EnhancedAC3DescriptorTag) + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_EAC3); + else if (Handle->streamType == 0x0F) + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AAC); + else if (Handle->streamType == 0x11) + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_HE_AAC); + else + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1); + } + if (!(Type <= ptDolby && Handle->used <= 1)) { + pesFilterParams.pid = Handle->pid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pes_type= DMX_PES_OTHER; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { + LOG_ERROR; + return false; + } + } } - else if (!Handle->used) { - CHECK(ioctl(Handle->handle, DMX_STOP)); - if (Type == ptPcr) - mHdffCmdIf->CmdAvSetPcrPid(0, 0); - else if (Type == ptVideo) - mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1); - else if (Type == ptAudio) - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1); - else if (Type == ptDolby) - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_AC3); - //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid() - close(Handle->handle); - Handle->handle = -1; + else if (!Handle->used) { + CHECK(ioctl(Handle->handle, DMX_STOP)); + if (Type == ptPcr) + mHdffCmdIf->CmdAvSetPcrPid(0, 0); + else if (Type == ptVideo) + mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1); + else if (Type == ptAudio) + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1); + else if (Type == ptDolby) + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_AC3); + //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid() + close(Handle->handle); + Handle->handle = -1; } - } - return true; + } + return true; } void cDvbHdFfDevice::TurnOffLiveMode(bool LiveView) @@ -286,6 +290,8 @@ bool cDvbHdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) if (CamSlot() && !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlot()->SlotNumber())) StartTransferMode |= LiveView && IsPrimaryDevice() && Channel->Ca() >= CA_ENCRYPTED_MIN; + //printf("SetChannelDevice Transfer %d, Live %d\n", StartTransferMode, LiveView); + bool TurnOnLivePIDs = !StartTransferMode && LiveView; // Turn off live PIDs if necessary: @@ -301,13 +307,10 @@ bool cDvbHdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) // PID settings: if (TurnOnLivePIDs) { - //SetAudioBypass(false);//TODO obsolete? - if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo, Channel->Vtype()) && AddPid(apid, ptAudio))) { + if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo, Channel->Vtype()) && AddPid(apid ? apid : dpid, ptAudio, apid ? 0 : Channel->Dtype(0)))) { esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1); return false; } - if (IsPrimaryDevice()) - AddPid(Channel->Tpid(), ptTeletext);//TODO obsolete? } else if (StartTransferMode) cControl::Launch(new cTransferControl(this, Channel)); @@ -338,27 +341,31 @@ void cDvbHdFfDevice::SetDigitalAudioDevice(bool On) void cDvbHdFfDevice::SetAudioTrackDevice(eTrackType Type) { - //printf("SetAudioTrackDevice %d\n", Type); - const tTrackId *TrackId = GetTrack(Type); - if (TrackId && TrackId->id) { - if (IS_AUDIO_TRACK(Type)) { + //printf("SetAudioTrackDevice %d\n", Type); + const tTrackId *TrackId = GetTrack(Type); + if (TrackId && TrackId->id) { + int streamType = 0; + cChannel * channel = Channels.GetByNumber(CurrentChannel()); + if (channel) { + if (IS_AUDIO_TRACK(Type)) + streamType = channel->Atype(Type - ttAudioFirst); + else if (IS_DOLBY_TRACK(Type)) + streamType = channel->Dtype(Type - ttDolbyFirst); + } + //printf("SetAudioTrackDevice new %d %d, current %d\n", TrackId->id, streamType, pidHandles[ptAudio].pid); if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) { - DetachAll(pidHandles[ptAudio].pid); - if (CamSlot()) - CamSlot()->SetPid(pidHandles[ptAudio].pid, false); - pidHandles[ptAudio].pid = TrackId->id; - SetPid(&pidHandles[ptAudio], ptAudio, true); - if (CamSlot()) { - CamSlot()->SetPid(pidHandles[ptAudio].pid, true); - CamSlot()->StartDecrypting(); - } - } - } - else if (IS_DOLBY_TRACK(Type)) { - pidHandles[ptDolby].pid = TrackId->id; - SetPid(&pidHandles[ptDolby], ptDolby, true); + DetachAll(pidHandles[ptAudio].pid); + if (CamSlot()) + CamSlot()->SetPid(pidHandles[ptAudio].pid, false); + pidHandles[ptAudio].pid = TrackId->id; + pidHandles[ptAudio].streamType = streamType; + SetPid(&pidHandles[ptAudio], ptAudio, true); + if (CamSlot()) { + CamSlot()->SetPid(pidHandles[ptAudio].pid, true); + CamSlot()->StartDecrypting(); + } } - } + } } bool cDvbHdFfDevice::CanReplay(void) const diff --git a/PLUGINS/src/dvbhddevice/hdffosd.c b/PLUGINS/src/dvbhddevice/hdffosd.c index a492275..0b95707 100644 --- a/PLUGINS/src/dvbhddevice/hdffosd.c +++ b/PLUGINS/src/dvbhddevice/hdffosd.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: hdffosd.c 1.12 2011/12/04 15:31:41 kls Exp $ + * $Id: hdffosd.c 1.15 2012/05/17 13:29:50 kls Exp $ */ #include "hdffosd.h" @@ -40,7 +40,6 @@ private: int mDispHeight; bool shown; bool mChanged; - bool mBitmapModified; uint32_t mDisplay; tFontFace mFontFaces[MAX_NUM_FONTFACES]; tFont mFonts[MAX_NUM_FONTS]; @@ -53,7 +52,6 @@ protected: public: cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level); virtual ~cHdffOsd(); - cBitmap *GetBitmap(int Area); virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); virtual eOsdError SetAreas(const tArea *Areas, int NumAreas); virtual void SaveRegion(int x1, int y1, int x2, int y2); @@ -79,9 +77,8 @@ cHdffOsd::cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level) mTop = Top; shown = false; mChanged = false; - mBitmapModified = false; mBitmapPalette = HDFF_INVALID_HANDLE; - config.FontKerning = false; + config.FontKerning = true; config.FontAntialiasing = Setup.AntiAlias ? true : false; mHdffCmdIf->CmdOsdConfigure(&config); @@ -126,14 +123,6 @@ cHdffOsd::~cHdffOsd() mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); } -cBitmap * cHdffOsd::GetBitmap(int Area) -{ - //printf("GetBitmap %d\n", Area); - mChanged = true; - mBitmapModified = true; - return cOsd::GetBitmap(Area); -} - eOsdError cHdffOsd::CanHandleAreas(const tArea *Areas, int NumAreas) { eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); @@ -150,6 +139,9 @@ eOsdError cHdffOsd::CanHandleAreas(const tArea *Areas, int NumAreas) eOsdError cHdffOsd::SetAreas(const tArea *Areas, int NumAreas) { + eOsdError error; + cBitmap * bitmap; + for (int i = 0; i < NumAreas; i++) { //printf("SetAreas %d: %d %d %d %d %d\n", i, Areas[i].x1, Areas[i].y1, Areas[i].x2, Areas[i].y2, Areas[i].bpp); @@ -160,7 +152,14 @@ eOsdError cHdffOsd::SetAreas(const tArea *Areas, int NumAreas) mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); shown = false; } - return cOsd::SetAreas(Areas, NumAreas); + error = cOsd::SetAreas(Areas, NumAreas); + + for (int i = 0; (bitmap = GetBitmap(i)) != NULL; i++) + { + bitmap->Clean(); + } + + return error; } void cHdffOsd::SetActive(bool On) @@ -186,25 +185,22 @@ void cHdffOsd::SaveRegion(int x1, int y1, int x2, int y2) { mHdffCmdIf->CmdOsdSaveRegion(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1); mChanged = true; - mBitmapModified = false; } void cHdffOsd::RestoreRegion(void) { mHdffCmdIf->CmdOsdRestoreRegion(mDisplay); mChanged = true; - mBitmapModified = false; } void cHdffOsd::DrawPixel(int x, int y, tColor Color) { //printf("DrawPixel\n"); - mBitmapModified = false; } void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay) { - //printf("DrawBitmap %d %d %d\n", x, y, Overlay); + //printf("DrawBitmap %d %d %d x %d\n", x, y, Bitmap.Width(), Bitmap.Height()); int i; int numColors; const tColor * colors = Bitmap.Colors(numColors); @@ -230,37 +226,21 @@ void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, t mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette, HDFF_COLOR_FORMAT_ARGB, 0, numColors, mBitmapColors); } - mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y, - (uint8_t *) Bitmap.Data(0, 0), Bitmap.Width(), Bitmap.Height(), - Bitmap.Width() * Bitmap.Height(), HDFF_COLOR_TYPE_CLUT8, mBitmapPalette); -#if 0 - uint32_t * tmpBitmap = new uint32_t[Bitmap.Width() * Bitmap.Height()]; - for (int ix = 0; ix < Bitmap.Width(); ix++) + int width = Bitmap.Width(); + int height = Bitmap.Height(); + int chunk = MAX_BITMAP_SIZE / width; + if (chunk > height) + chunk = height; + for (int yc = 0; yc < height; yc += chunk) { - for (int iy = 0; iy < Bitmap.Height(); iy++) - { - const tIndex * pixel = Bitmap.Data(ix, iy); - tColor color = Bitmap.Color(*pixel); - if (!Overlay || *pixel != 0) - { - if (ColorFg || ColorBg) - { - if (*pixel == 0) - color = ColorBg; - else if (*pixel == 1) - color = ColorFg; - } - tmpBitmap[Bitmap.Width() * iy + ix] = color; - } - } + int hc = chunk; + if (yc + hc > height) + hc = height - yc; + mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y + yc, + (uint8_t *) Bitmap.Data(0, yc), width, hc, + width * hc, HDFF_COLOR_TYPE_CLUT8, mBitmapPalette); } - mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y, - (uint8_t *) tmpBitmap, Bitmap.Width(), Bitmap.Height(), - Bitmap.Width() * Bitmap.Height() * 4, HDFF::colorTypeARGB8888, InvalidHandle); - delete[] tmpBitmap; -#endif mChanged = true; - mBitmapModified = false; } void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment) @@ -365,11 +345,16 @@ void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Colo if (Width) { if ((Alignment & taLeft) != 0) - ; + { + if ((Alignment & taBorder) != 0) + x += max(h / TEXT_ALIGN_BORDER, 1); + } else if ((Alignment & taRight) != 0) { if (w < Width) x += Width - w; + if ((Alignment & taBorder) != 0) + x -= max(h / TEXT_ALIGN_BORDER, 1); } else { // taCentered @@ -413,14 +398,12 @@ void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Colo mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, false, 0, 0, 0, 0); //Font->DrawText(this, x, y, s, ColorFg, ColorBg, limit); mChanged = true; - mBitmapModified = false; } void cHdffOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color) { mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1, Color); mChanged = true; - mBitmapModified = false; } void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants) @@ -511,14 +494,12 @@ void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Qua } mHdffCmdIf->CmdOsdDrawEllipse(mDisplay, mLeft + cx, mTop + cy, rx, ry, Color, flags); mChanged = true; - mBitmapModified = false; } void cHdffOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type) { //printf("DrawSlope\n"); mChanged = true; - mBitmapModified = false; } void cHdffOsd::Flush(void) @@ -526,23 +507,30 @@ void cHdffOsd::Flush(void) if (!Active()) return; - if (!mChanged) - return; - //printf("Flush\n"); - if (mBitmapModified) + cBitmap * Bitmap; + + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { - cBitmap *Bitmap; - for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) + int x1; + int y1; + int x2; + int y2; + + if (Bitmap->Dirty(x1, y1, x2, y2)) { + //printf("dirty %d %d, %d %d\n", x1, y1, x2, y2); DrawBitmap(0, 0, *Bitmap); + Bitmap->Clean(); } } + if (!mChanged) + return; + mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); mChanged = false; - mBitmapModified = false; } diff --git a/PLUGINS/src/pictures/HISTORY b/PLUGINS/src/pictures/HISTORY index e0826ee..9426283 100644 --- a/PLUGINS/src/pictures/HISTORY +++ b/PLUGINS/src/pictures/HISTORY @@ -71,3 +71,7 @@ VDR Plugin 'pictures' Revision History 2012-02-27: Version 0.1.2 - Removed an obsolete command line option. + +2012-04-2r8 Version 0.1.3 + +- Added cPictureControl::GetHeader(). diff --git a/PLUGINS/src/pictures/pictures.c b/PLUGINS/src/pictures/pictures.c index 27febdf..77df0d9 100644 --- a/PLUGINS/src/pictures/pictures.c +++ b/PLUGINS/src/pictures/pictures.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: pictures.c 2.5 2012/02/27 11:40:15 kls Exp $ + * $Id: pictures.c 2.6 2012/04/28 11:58:42 kls Exp $ */ #include <getopt.h> @@ -11,7 +11,7 @@ #include "menu.h" #include "player.h" -static const char *VERSION = "0.1.2"; +static const char *VERSION = "0.1.3"; static const char *DESCRIPTION = trNOOP("A simple picture viewer"); static const char *MAINMENUENTRY = trNOOP("Pictures"); diff --git a/PLUGINS/src/pictures/player.c b/PLUGINS/src/pictures/player.c index 4b289ac..6048d4c 100644 --- a/PLUGINS/src/pictures/player.c +++ b/PLUGINS/src/pictures/player.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: player.c 2.1 2011/02/20 17:15:25 kls Exp $ + * $Id: player.c 2.2 2012/04/28 11:58:15 kls Exp $ */ #include "player.h" @@ -204,6 +204,11 @@ void cPictureControl::DisplayCaption(void) osd->Flush(); } +cString cPictureControl::GetHeader(void) +{ + return tr("Pictures"); +} + eOSState cPictureControl::ProcessKey(eKeys Key) { switch (Key) { diff --git a/PLUGINS/src/pictures/player.h b/PLUGINS/src/pictures/player.h index 67a274d..7a0b401 100644 --- a/PLUGINS/src/pictures/player.h +++ b/PLUGINS/src/pictures/player.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: player.h 2.0 2008/01/12 16:21:57 kls Exp $ + * $Id: player.h 2.1 2012/04/28 11:56:01 kls Exp $ */ #ifndef _PLAYER_H @@ -39,6 +39,7 @@ private: public: cPictureControl(cPictureEntry *Pictures, const cPictureEntry *PictureEntry, bool SlideShow = false); virtual ~cPictureControl(); + virtual cString GetHeader(void); virtual eOSState ProcessKey(eKeys Key); static bool Active(void) { return active > 0; } static const char *LastDisplayed(void); diff --git a/PLUGINS/src/skincurses/HISTORY b/PLUGINS/src/skincurses/HISTORY index 0ba892e..deb011b 100644 --- a/PLUGINS/src/skincurses/HISTORY +++ b/PLUGINS/src/skincurses/HISTORY @@ -96,3 +96,8 @@ VDR Plugin 'skincurses' Revision History 2012-03-11: Version 0.1.11 - Adapted menu column widths of 'skincurses' to the wider HD OSD sizes. + +2012-04-23: Version 0.1.12 + +- Now displaying disk usage in the title of the main and "Recordings" menu, + which is no longer done by the VDR core. diff --git a/PLUGINS/src/skincurses/skincurses.c b/PLUGINS/src/skincurses/skincurses.c index 1f120c7..587d0b9 100644 --- a/PLUGINS/src/skincurses/skincurses.c +++ b/PLUGINS/src/skincurses/skincurses.c @@ -3,15 +3,16 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: skincurses.c 2.8 2012/03/11 14:42:52 kls Exp $ + * $Id: skincurses.c 2.9 2012/04/23 08:53:13 kls Exp $ */ #include <ncurses.h> #include <vdr/osd.h> #include <vdr/plugin.h> #include <vdr/skins.h> +#include <vdr/videodir.h> -static const char *VERSION = "0.1.11"; +static const char *VERSION = "0.1.12"; static const char *DESCRIPTION = trNOOP("A text only skin"); static const char *MAINMENUENTRY = NULL; @@ -262,6 +263,9 @@ void cSkinCursesDisplayChannel::Flush(void) class cSkinCursesDisplayMenu : public cSkinDisplayMenu { private: cOsd *osd; + cString title; + int lastDiskUsageState; + void DrawTitle(void); void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown); void SetTextScrollbar(void); public: @@ -285,6 +289,7 @@ public: cSkinCursesDisplayMenu::cSkinCursesDisplayMenu(void) { osd = new cCursesOsd(0, 0); + lastDiskUsageState = -1; osd->DrawRectangle(0, 0, ScOsdWidth - 1, ScOsdHeight - 1, clrBackground); } @@ -332,9 +337,16 @@ void cSkinCursesDisplayMenu::Clear(void) textScroller.Reset(); } +void cSkinCursesDisplayMenu::DrawTitle(void) +{ + bool WithDisk = MenuCategory() == mcMain || MenuCategory() == mcRecording; + osd->DrawText(0, 0, WithDisk ? cString::sprintf("%s - %s", *title, *cVideoDiskUsage::String()) : title, clrBlack, clrCyan, &Font, ScOsdWidth); +} + void cSkinCursesDisplayMenu::SetTitle(const char *Title) { - osd->DrawText(0, 0, Title, clrBlack, clrCyan, &Font, ScOsdWidth); + title = Title; + DrawTitle(); } void cSkinCursesDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) @@ -475,6 +487,8 @@ void cSkinCursesDisplayMenu::SetText(const char *Text, bool FixedFont) void cSkinCursesDisplayMenu::Flush(void) { + if (cVideoDiskUsage::HasChanged(lastDiskUsageState)) + DrawTitle(); cString date = DayDateTime(); osd->DrawText(ScOsdWidth - Utf8StrLen(date) - 2, 0, date, clrBlack, clrCyan, &Font); osd->Flush(); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 2.21 2012/03/11 13:29:06 kls Exp $ + * $Id: channels.c 2.22 2012/04/01 09:27:08 kls Exp $ */ #include "channels.h" @@ -955,7 +955,7 @@ int cChannels::MaxShortChannelNameLength(void) if (!maxShortChannelNameLength) { for (cChannel *channel = First(); channel; channel = Next(channel)) { if (!channel->GroupSep()) - maxShortChannelNameLength = max(Utf8StrLen(channel->ShortName()), maxShortChannelNameLength); + maxShortChannelNameLength = max(Utf8StrLen(channel->ShortName(true)), maxShortChannelNameLength); } } return maxShortChannelNameLength; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.c 2.8 2012/02/29 10:24:41 kls Exp $ + * $Id: ci.c 2.9 2012/05/29 11:13:40 kls Exp $ */ #include "ci.h" @@ -1715,6 +1715,7 @@ bool cCamSlot::Reset(void) if (ciAdapter->Reset(slotIndex)) { resetTime = time(NULL); dbgprotocol("ok.\n"); + lastModuleStatus = msReset; return true; } dbgprotocol("failed!\n"); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 2.20 2012/02/29 10:15:54 kls Exp $ + * $Id: config.c 2.22 2012/05/11 11:06:57 kls Exp $ */ #include "config.h" @@ -309,9 +309,9 @@ cSetupLine::cSetupLine(void) cSetupLine::cSetupLine(const char *Name, const char *Value, const char *Plugin) { - name = strdup(Name); - value = strdup(Value); - plugin = Plugin ? strdup(Plugin) : NULL; + name = strreplace(strdup(Name), '\n', 0); + value = strreplace(strdup(Value), '\n', 0); + plugin = Plugin ? strreplace(strdup(Plugin), '\n', 0) : NULL; } cSetupLine::~cSetupLine() @@ -391,6 +391,7 @@ cSetup::cSetup(void) SetSystemTime = 0; TimeSource = 0; TimeTransponder = 0; + StandardCompliance = STANDARD_DVB; MarginStart = 2; MarginStop = 10; AudioLanguages[0] = -1; @@ -585,6 +586,7 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value); else if (!strcasecmp(Name, "TimeSource")) TimeSource = cSource::FromString(Value); else if (!strcasecmp(Name, "TimeTransponder")) TimeTransponder = atoi(Value); + else if (!strcasecmp(Name, "StandardCompliance")) StandardCompliance = atoi(Value); else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value); else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages); @@ -682,6 +684,7 @@ bool cSetup::Save(void) Store("SetSystemTime", SetSystemTime); Store("TimeSource", cSource::ToString(TimeSource)); Store("TimeTransponder", TimeTransponder); + Store("StandardCompliance", StandardCompliance); Store("MarginStart", MarginStart); Store("MarginStop", MarginStop); StoreLanguages("AudioLanguages", AudioLanguages); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 2.45 2012/03/11 10:41:44 kls Exp $ + * $Id: config.h 2.47 2012/04/15 10:45:32 kls Exp $ */ #ifndef __CONFIG_H @@ -22,13 +22,13 @@ // VDR's own version number: -#define VDRVERSION "1.7.27" -#define VDRVERSNUM 10727 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.7.28" +#define VDRVERSNUM 10728 // Version * 10000 + Major * 100 + Minor // The plugin API's version number: -#define APIVERSION "1.7.27" -#define APIVERSNUM 10727 // Version * 10000 + Major * 100 + Minor +#define APIVERSION "1.7.28" +#define APIVERSNUM 10728 // Version * 10000 + Major * 100 + Minor // When loading plugins, VDR searches them by their APIVERSION, which // may be smaller than VDRVERSION in case there have been no changes to @@ -52,6 +52,16 @@ #define MaxSkinName 16 #define MaxThemeName 16 +// Basically VDR works according to the DVB standard, but there are countries/providers +// that use other standards, which in some details deviate from the DVB standard. +// This makes it necessary to handle things differently in some areas, depending on +// which standard is actually used. The following macros are used to distinguish +// these cases (make sure to adjust cMenuSetupDVB::standardComplianceTexts accordingly +// when adding a new standard): + +#define STANDARD_DVB 0 +#define STANDARD_ANSISCTE 1 + typedef uint32_t in_addr_t; //XXX from /usr/include/netinet/in.h (apparently this is not defined on systems with glibc < 2.2) class cSVDRPhost : public cListObject { @@ -255,6 +265,7 @@ public: int SetSystemTime; int TimeSource; int TimeTransponder; + int StandardCompliance; int MarginStart, MarginStop; int AudioLanguages[I18N_MAX_LANGUAGES + 1]; int DisplaySubtitles; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: cutter.c 2.11 2012/02/16 12:08:39 kls Exp $ + * $Id: cutter.c 2.12 2012/06/02 13:46:55 kls Exp $ */ #include "cutter.h" @@ -270,7 +270,7 @@ bool cCutter::Active(const char *FileName) error = cuttingThread->Error(); Stop(); if (!error) - cRecordingUserCommand::InvokeCommand(RUC_EDITEDRECORDING, editedVersionName); + cRecordingUserCommand::InvokeCommand(RUC_EDITEDRECORDING, editedVersionName, originalVersionName); originalVersionName = NULL; editedVersionName = NULL; ended = true; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 2.58 2012/03/13 09:48:14 kls Exp $ + * $Id: device.c 2.60 2012/04/26 09:40:36 kls Exp $ */ #include "device.h" @@ -162,6 +162,11 @@ int cDevice::DeviceNumber(void) const return -1; } +cString cDevice::DeviceType(void) const +{ + return ""; +} + cString cDevice::DeviceName(void) const { return ""; @@ -1176,8 +1181,10 @@ void cDevice::StillPicture(const uchar *Data, int Length) return; } } - StillPicture(buf, Size); - free(buf); + if (buf) { + StillPicture(buf, Size); + free(buf); + } } } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 2.38 2012/03/13 10:17:16 kls Exp $ + * $Id: device.h 2.39 2012/04/04 09:48:21 kls Exp $ */ #ifndef __DEVICE_H @@ -201,6 +201,12 @@ public: ///< Returns the card index of this device (0 ... MAXDEVICES - 1). int DeviceNumber(void) const; ///< Returns the number of this device (0 ... numDevices). + virtual cString DeviceType(void) const; + ///< Returns a string identifying the type of this device (like "DVB-S"). + ///< If this device can receive different delivery systems, the returned + ///< string shall be that of the currently used system. + ///< The length of the returned string should not exceed 6 characters. + ///< The default implementation returns an empty string. virtual cString DeviceName(void) const; ///< Returns a string identifying the name of this device. ///< The default implementation returns an empty string. diff --git a/dvbdevice.c b/dvbdevice.c index 65e9a4b..55cb912 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 2.69 2012/03/25 10:41:45 kls Exp $ + * $Id: dvbdevice.c 2.71 2012/05/09 08:33:59 kls Exp $ */ #include "dvbdevice.h" @@ -285,6 +285,7 @@ class cDvbTuner : public cThread { private: static cMutex bondMutex; enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; + int frontendType; const cDvbDevice *device; int fd_frontend; int adapter, frontend; @@ -302,7 +303,6 @@ private: cCondVar newSet; cDvbTuner *bondedTuner; bool bondedMaster; - bool bondedMasterFailed; bool SetFrontendType(const cChannel *Channel); cString GetBondingParams(const cChannel *Channel = NULL) const; void ClearEventQueue(void) const; @@ -314,6 +314,7 @@ private: public: cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend); virtual ~cDvbTuner(); + int FrontendType(void) const { return frontendType; } bool Bond(cDvbTuner *Tuner); void UnBond(void); bool BondingOk(const cChannel *Channel, bool ConsiderOccupied = false) const; @@ -331,6 +332,7 @@ cMutex cDvbTuner::bondMutex; cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend) { + frontendType = SYS_UNDEFINED; device = Device; fd_frontend = Fd_Frontend; adapter = Adapter; @@ -345,7 +347,6 @@ cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int tunerStatus = tsIdle; bondedTuner = NULL; bondedMaster = false; - bondedMasterFailed = false; SetDescription("tuner on frontend %d/%d", adapter, frontend); Start(); } @@ -435,12 +436,8 @@ cDvbTuner *cDvbTuner::GetBondedMaster(void) if (!bondedTuner) return this; // an unbonded tuner is always "master" cMutexLock MutexLock(&bondMutex); - if (bondedMaster) { - if (!bondedMasterFailed) - return this; - else - bondedMaster = false; - } + if (bondedMaster) + return this; // This tuner is bonded, but it's not the master, so let's see if there is a master at all: if (cDvbTuner *t = bondedTuner) { while (t != this) { @@ -450,18 +447,9 @@ cDvbTuner *cDvbTuner::GetBondedMaster(void) } } // None of the other bonded tuners is master, so make this one the master: - cDvbTuner *t = this; - if (bondedMasterFailed) { - // This one has failed, so switch to the next one: - t = bondedTuner; - t->bondedMasterFailed = false; - cMutexLock MutexLock(&t->mutex); - t->channel = channel; - t->tunerStatus = tsSet; - } - t->bondedMaster = true; - dsyslog("tuner %d/%d is now bonded master", t->adapter, t->frontend); - return t; + bondedMaster = true; + dsyslog("tuner %d/%d is now bonded master", adapter, frontend); + return this; } bool cDvbTuner::IsTunedTo(const cChannel *Channel) const @@ -733,7 +721,7 @@ bool cDvbTuner::SetFrontend(void) cDvbTransponderParameters dtp(channel.Parameters()); // Determine the required frontend type: - int frontendType = GetRequiredDeliverySystem(&channel, &dtp); + frontendType = GetRequiredDeliverySystem(&channel, &dtp); if (frontendType == SYS_UNDEFINED) return false; @@ -875,9 +863,6 @@ void cDvbTuner::Action(void) isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder()); lastTimeoutReport = time(NULL); } - cMutexLock MutexLock(&bondMutex); - if (bondedTuner && bondedMaster) - bondedMasterFailed = true; // give an other tuner a chance in case the sat cable was disconnected continue; } WaitTime = 100; // allows for a quick change from tsTuned to tsLocked @@ -977,7 +962,7 @@ int cDvbDevice::setTransferModeForDolbyDigital = 1; cMutex cDvbDevice::bondMutex; const char *DeliverySystemNames[] = { - "UNDEFINED", + "", "DVB-C", "DVB-C", "DVB-T", @@ -1090,6 +1075,17 @@ bool cDvbDevice::Probe(int Adapter, int Frontend) return true; } +cString cDvbDevice::DeviceType(void) const +{ + if (dvbTuner) { + if (dvbTuner->FrontendType() != SYS_UNDEFINED) + return DeliverySystemNames[dvbTuner->FrontendType()]; + if (numDeliverySystems) + return DeliverySystemNames[deliverySystems[0]]; // to have some reasonable default + } + return ""; +} + cString cDvbDevice::DeviceName(void) const { return frontendInfo.name; diff --git a/dvbdevice.h b/dvbdevice.h index c53a208..7da9c56 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 2.25 2012/03/13 10:11:15 kls Exp $ + * $Id: dvbdevice.h 2.26 2012/03/31 11:13:31 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -138,6 +138,7 @@ public: int Adapter(void) const { return adapter; } int Frontend(void) const { return frontend; } virtual bool Ready(void); + virtual cString DeviceType(void) const; virtual cString DeviceName(void) const; static bool BondDevices(const char *Bondings); ///< Bonds the devices as defined in the given Bondings string. diff --git a/dvbplayer.c b/dvbplayer.c index 2bf27a3..b325c98 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbplayer.c 2.26 2012/03/12 14:36:55 kls Exp $ + * $Id: dvbplayer.c 2.27 2012/05/06 11:02:35 kls Exp $ */ #include "dvbplayer.h" @@ -408,7 +408,7 @@ void cDvbPlayer::Action(void) Goto(0, true); while (Running()) { if (WaitingForData) - nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data + WaitingForData = !nonBlockingFileReader->WaitForDataMs(3); // this keeps the CPU load low, but reacts immediately on new data else if (Sleep) { cPoller Poller; DevicePoll(Poller, 10); diff --git a/dvbsubtitle.c b/dvbsubtitle.c index ab755c4..9955069 100644 --- a/dvbsubtitle.c +++ b/dvbsubtitle.c @@ -7,7 +7,7 @@ * Original author: Marco Schluessler <marco@lordzodiac.de> * With some input from the "subtitle plugin" by Pekka Virtanen <pekka.virtanen@sci.fi> * - * $Id: dvbsubtitle.c 2.31 2012/03/16 11:56:56 kls Exp $ + * $Id: dvbsubtitle.c 2.32 2012/05/08 08:17:17 kls Exp $ */ @@ -217,7 +217,7 @@ void cSubtitleObject::DecodeCharacterString(const uchar *Data, int NumberOfCodes char txt[NumberOfCodes + 1]; char *p = txt; for (int i = 2; i < NumberOfCodes; ++i) { - char c = Data[i * 2 + 1] & 0xFF; + uchar c = Data[i * 2 + 1] & 0xFF; if (c == 0) break; if (' ' <= c && c <= '~' || c == '\n' || 0xA0 <= c) @@ -8,7 +8,7 @@ * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>. * - * $Id: eit.c 2.16 2012/03/14 10:11:15 kls Exp $ + * $Id: eit.c 2.17 2012/06/02 14:05:22 kls Exp $ */ #include "eit.h" @@ -290,6 +290,11 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo channel->SetLinkChannels(LinkChannels); Modified = true; EpgHandlers.HandleEvent(pEvent); + + if (EpgHandlers.DeleteEvent(pEvent)) { + pSchedule->DelEvent(pEvent); + pEvent = NULL; + } } if (Tid == 0x4E) { if (Empty && getSectionNumber() == 0) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.c 2.6 2012/03/07 13:54:34 kls Exp $ + * $Id: eitscan.c 2.7 2012/04/07 14:39:28 kls Exp $ */ #include "eitscan.h" @@ -148,7 +148,7 @@ void cEITScanner::Process(void) if (Channel) { if (!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= CA_ENCRYPTED_MIN) { if (Device->ProvidesTransponder(Channel)) { - if (!Device->Receiving()) { + if (Device->Priority() < 0) { bool MaySwitchTransponder = Device->MaySwitchTransponder(Channel); if (MaySwitchTransponder || Device->ProvidesTransponderExclusively(Channel) && now - lastActivity > Setup.EPGScanTimeout * 3600) { if (!MaySwitchTransponder) { @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.c 2.12 2012/03/10 13:14:27 kls Exp $ + * $Id: epg.c 2.14 2012/06/02 14:08:12 kls Exp $ */ #include "epg.h" @@ -1125,7 +1125,7 @@ cSchedulesLock::~cSchedulesLock() // --- cSchedules ------------------------------------------------------------ cSchedules cSchedules::schedules; -const char *cSchedules::epgDataFileName = NULL; +char *cSchedules::epgDataFileName = NULL; time_t cSchedules::lastCleanup = time(NULL); time_t cSchedules::lastDump = time(NULL); time_t cSchedules::modified = 0; @@ -1137,7 +1137,7 @@ const cSchedules *cSchedules::Schedules(cSchedulesLock &SchedulesLock) void cSchedules::SetEpgDataFileName(const char *FileName) { - delete epgDataFileName; + free(epgDataFileName); epgDataFileName = FileName ? strdup(FileName) : NULL; } @@ -1429,6 +1429,15 @@ void cEpgHandlers::HandleEvent(cEvent *Event) } } +bool cEpgHandlers::DeleteEvent(const cEvent *Event) +{ + for (cEpgHandler *eh = First(); eh; eh = Next(eh)) { + if (eh->DeleteEvent(Event)) + return true; + } + return false; +} + void cEpgHandlers::SortSchedule(cSchedule *Schedule) { for (cEpgHandler *eh = First(); eh; eh = Next(eh)) { @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>. * - * $Id: epg.h 2.8 2012/03/10 13:50:10 kls Exp $ + * $Id: epg.h 2.10 2012/06/02 14:07:51 kls Exp $ */ #ifndef __EPG_H @@ -192,7 +192,7 @@ class cSchedules : public cList<cSchedule> { private: cRwLock rwlock; static cSchedules schedules; - static const char *epgDataFileName; + static char *epgDataFileName; static time_t lastCleanup; static time_t lastDump; static time_t modified; @@ -258,6 +258,9 @@ public: virtual bool HandleEvent(cEvent *Event) { return false; } ///< After all modifications of the Event have been done, the EPG handler ///< can take a final look at it. + virtual bool DeleteEvent(const cEvent *Event) { return false; } + ///< After the complete processing of the Event is finished, an EPG handler + ///< can decide that this Event shall be deleted from its schedule. virtual bool SortSchedule(cSchedule *Schedule) { return false; } ///< Sorts the Schedule after the complete table has been processed. virtual bool DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version) { return false; } @@ -280,6 +283,7 @@ public: void SetVps(cEvent *Event, time_t Vps); void FixEpgBugs(cEvent *Event); void HandleEvent(cEvent *Event); + bool DeleteEvent(const cEvent *Event); void SortSchedule(cSchedule *Schedule); void DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version); }; @@ -6,7 +6,7 @@ * * BiDi support by Osama Alrawab <alrawab@hotmail.com> @2008 Tripoli-Libya. * - * $Id: font.c 2.10 2012/03/02 10:47:45 kls Exp $ + * $Id: font.c 2.13 2012/06/02 13:38:28 kls Exp $ */ #include "font.h" @@ -412,7 +412,7 @@ const cFont *cFont::GetFont(eDvbFont Font) if (!fonts[Font]) { switch (Font) { case fontOsd: SetFont(Font, Setup.FontOsd, Setup.FontOsdSize); break; - case fontSml: SetFont(Font, Setup.FontSml, Setup.FontSmlSize); break; + case fontSml: SetFont(Font, Setup.FontSml, min(Setup.FontSmlSize, Setup.FontOsdSize)); break; case fontFix: SetFont(Font, Setup.FontFix, Setup.FontFixSize); break; default: esyslog("ERROR: unknown Font %d (%s %d)", Font, __FUNCTION__, __LINE__); } @@ -482,7 +482,8 @@ cString cFont::GetFontFileName(const char *FontName) FcPatternAddBool(pat, FC_SCALABLE, FcTrue); FcConfigSubstitute(NULL, pat, FcMatchPattern); FcDefaultSubstitute(pat); - FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, NULL); + FcResult fresult; + FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, &fresult); if (fontset) { for (int i = 0; i < fontset->nfont; i++) { FcBool scalable; @@ -508,7 +509,7 @@ cString cFont::GetFontFileName(const char *FontName) #ifdef BIDI cString cFont::Bidi(const char *Ltr) { - if (cCharSetConv::SystemCharacterTable()) { // bidi requires UTF-8 + if (!cCharSetConv::SystemCharacterTable()) { // bidi requires UTF-8 fribidi_set_mirroring(true); fribidi_set_reorder_nsm(false); FriBidiCharSet fribidiCharset = FRIBIDI_CHAR_SET_UTF8; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 2.45 2012/03/13 13:14:38 kls Exp $ + * $Id: menu.c 2.54 2012/05/12 13:08:23 kls Exp $ */ #include "menu.h" @@ -34,7 +34,6 @@ #define MAXWAIT4EPGINFO 3 // seconds #define MODETIMEOUT 3 // seconds -#define DISKSPACECHEK 5 // seconds between disk space checks #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 @@ -47,50 +46,10 @@ #define CAMRESPONSETIMEOUT 5 // seconds to wait for a response from a CAM #define MINFREEDISK 300 // minimum free disk space (in MB) required to start recording #define NODISKSPACEDELTA 300 // seconds between "Not enough disk space to start recording!" messages +#define MAXCHNAMWIDTH 16 // maximum number of characters of channels' short names shown in schedules menus #define CHNUMWIDTH (numdigits(Channels.MaxNumber()) + 1) -#define CHNAMWIDTH (Channels.MaxShortChannelNameLength() + 1) - -// --- cFreeDiskSpace -------------------------------------------------------- - -#define MB_PER_MINUTE 25.75 // this is just an estimate! - -class cFreeDiskSpace { -private: - static time_t lastDiskSpaceCheck; - static int lastFreeMB; - static cString freeDiskSpaceString; -public: - static bool HasChanged(bool ForceCheck = false); - static const char *FreeDiskSpaceString(void) { HasChanged(); return freeDiskSpaceString; } - }; - -time_t cFreeDiskSpace::lastDiskSpaceCheck = 0; -int cFreeDiskSpace::lastFreeMB = 0; -cString cFreeDiskSpace::freeDiskSpaceString; - -cFreeDiskSpace FreeDiskSpace; - -bool cFreeDiskSpace::HasChanged(bool ForceCheck) -{ - if (ForceCheck || time(NULL) - lastDiskSpaceCheck > DISKSPACECHEK) { - int FreeMB; - int Percent = VideoDiskSpace(&FreeMB); - lastDiskSpaceCheck = time(NULL); - if (ForceCheck || FreeMB != lastFreeMB) { - int MBperMinute = Recordings.MBperMinute(); - if (MBperMinute <= 0) - MBperMinute = MB_PER_MINUTE; - int Minutes = int(double(FreeMB) / MBperMinute); - int Hours = Minutes / 60; - Minutes %= 60; - freeDiskSpaceString = cString::sprintf("%s %d%% - %2d:%02d %s", tr("Disk"), Percent, Hours, Minutes, tr("free")); - lastFreeMB = FreeMB; - return true; - } - } - return false; -} +#define CHNAMWIDTH (min(MAXCHNAMWIDTH, Channels.MaxShortChannelNameLength() + 1)) // --- cMenuEditCaItem ------------------------------------------------------- @@ -213,6 +172,7 @@ public: cMenuEditChannel::cMenuEditChannel(cChannel *Channel, bool New) :cOsdMenu(tr("Edit channel"), 16) { + SetMenuCategory(mcChannel); channel = Channel; sourceParam = NULL; *name = 0; @@ -390,6 +350,7 @@ public: cMenuChannels::cMenuChannels(void) :cOsdMenu(tr("Channels"), CHNUMWIDTH) { + SetMenuCategory(mcChannel); number = 0; Setup(); Channels.IncBeingEdited(); @@ -585,6 +546,7 @@ eOSState cMenuChannels::ProcessKey(eKeys Key) cMenuText::cMenuText(const char *Title, const char *Text, eDvbFont Font) :cOsdMenu(Title) { + SetMenuCategory(mcText); text = NULL; font = Font; SetText(Text); @@ -673,6 +635,7 @@ public: cMenuEditFolder::cMenuEditFolder(const char *Dir, cList<cNestedItem> *List, cNestedItem *Folder) :cOsdMenu(Folder ? tr("Edit folder") : tr("New folder"), 12) { + SetMenuCategory(mcFolder); list = List; folder = Folder; if (folder) { @@ -745,6 +708,7 @@ eOSState cMenuEditFolder::ProcessKey(eKeys Key) cMenuFolder::cMenuFolder(const char *Title, cNestedItemList *NestedItemList, const char *Path) :cOsdMenu(Title) { + SetMenuCategory(mcFolder); list = nestedItemList = NestedItemList; firstFolder = NULL; editing = false; @@ -756,6 +720,7 @@ cMenuFolder::cMenuFolder(const char *Title, cNestedItemList *NestedItemList, con cMenuFolder::cMenuFolder(const char *Title, cList<cNestedItem> *List, cNestedItemList *NestedItemList, const char *Dir, const char *Path) :cOsdMenu(Title) { + SetMenuCategory(mcFolder); list = List; nestedItemList = NestedItemList; dir = Dir; @@ -906,6 +871,7 @@ eOSState cMenuFolder::ProcessKey(eKeys Key) cMenuEditTimer::cMenuEditTimer(cTimer *Timer, bool New) :cOsdMenu(tr("Edit timer"), 12) { + SetMenuCategory(mcTimer); file = NULL; day = firstday = NULL; timer = Timer; @@ -1104,6 +1070,7 @@ public: cMenuTimers::cMenuTimers(void) :cOsdMenu(tr("Timers"), 2, CHNUMWIDTH, 10, 6, 6) { + SetMenuCategory(mcTimer); helpKeys = -1; for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { timer->SetEventFromSchedule(); // make sure the event is current @@ -1242,6 +1209,7 @@ eOSState cMenuTimers::ProcessKey(eKeys Key) cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch, bool Buttons) :cOsdMenu(tr("Event")) { + SetMenuCategory(mcEvent); event = Event; if (event) { cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true); @@ -1389,6 +1357,7 @@ const cEvent *cMenuWhatsOn::scheduleEvent = NULL; cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr) :cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, CHNAMWIDTH, 6, 4) { + SetMenuCategory(mcSchedule); now = Now; helpKeys = -1; timerState = 0; @@ -1553,6 +1522,7 @@ public: cMenuSchedule::cMenuSchedule(void) :cOsdMenu("") { + SetMenuCategory(mcSchedule); now = next = false; otherChannel = 0; helpKeys = -1; @@ -1810,6 +1780,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) cMenuCommands::cMenuCommands(const char *Title, cList<cNestedItem> *Commands, const char *Parameters) :cOsdMenu(Title) { + SetMenuCategory(mcCommand); result = NULL; SetHasHotkeys(); commands = Commands; @@ -1939,6 +1910,7 @@ public: cMenuCam::cMenuCam(cCamSlot *CamSlot) :cOsdMenu("", 1) // tab necessary for enquiry! { + SetMenuCategory(mcCam); camSlot = CamSlot; ciMenu = NULL; ciEnquiry = NULL; @@ -2118,6 +2090,7 @@ public: cMenuRecording::cMenuRecording(const cRecording *Recording, bool WithButtons) :cOsdMenu(tr("Recording info")) { + SetMenuCategory(mcRecording); recording = Recording; withButtons = WithButtons; if (withButtons) @@ -2212,13 +2185,13 @@ void cMenuRecordingItem::IncrementCounter(bool New) cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) :cOsdMenu(Base ? Base : tr("Recordings"), 9, 6, 6) { + SetMenuCategory(mcRecording); base = Base ? strdup(Base) : NULL; level = Setup.RecordingDirs ? Level : -1; Recordings.StateChanged(recordingsState); // just to get the current state helpKeys = -1; Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay Set(); - SetFreeDiskDisplay(true); if (Current() < 0) SetCurrent(First()); else if (OpenSubMenus && cReplayControl::LastReplayed() && Open(true)) @@ -2233,16 +2206,6 @@ cMenuRecordings::~cMenuRecordings() free(base); } -bool cMenuRecordings::SetFreeDiskDisplay(bool Force) -{ - if (FreeDiskSpace.HasChanged(Force)) { - //XXX -> skin function!!! - SetTitle(cString::sprintf("%s - %s", base ? base : tr("Recordings"), FreeDiskSpace.FreeDiskSpaceString())); - return true; - } - return false; -} - void cMenuRecordings::SetHelpKeys(void) { cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); @@ -2305,7 +2268,6 @@ void cMenuRecordings::Set(bool Refresh) } } free(LastItemText); - Refresh |= SetFreeDiskDisplay(Refresh); if (Refresh) Display(); } @@ -2343,7 +2305,7 @@ eOSState cMenuRecordings::Play(void) else { cRecording *recording = GetRecording(ri); if (recording) { - cReplayControl::SetRecording(recording->FileName(), recording->Title()); + cReplayControl::SetRecording(recording->FileName()); return osReplay; } } @@ -2411,7 +2373,7 @@ eOSState cMenuRecordings::Delete(void) Recordings.DelByName(ri->FileName()); cOsdMenu::Del(Current()); SetHelpKeys(); - SetFreeDiskDisplay(true); + cVideoDiskUsage::ForceCheck(); Display(); if (!Count()) return osBack; @@ -2484,8 +2446,6 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key) Display(); } if (!HasSubMenu()) { - if (HadSubMenu) - SetFreeDiskDisplay(); if (Key != kNone) SetHelpKeys(); } @@ -2767,6 +2727,7 @@ private: void Setup(void); const char *videoDisplayFormatTexts[3]; const char *updateChannelsTexts[6]; + const char *standardComplianceTexts[2]; public: cMenuSetupDVB(void); virtual eOSState ProcessKey(eKeys Key); @@ -2789,6 +2750,8 @@ cMenuSetupDVB::cMenuSetupDVB(void) updateChannelsTexts[3] = tr("names and PIDs"); updateChannelsTexts[4] = tr("add new channels"); updateChannelsTexts[5] = tr("add new transponders"); + standardComplianceTexts[0] = "DVB"; + standardComplianceTexts[1] = "ANSI/SCTE"; SetSection(tr("DVB")); SetHelp(NULL, tr("Button$Audio"), tr("Button$Subtitles"), NULL); @@ -2802,6 +2765,7 @@ void cMenuSetupDVB::Setup(void) Clear(); Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices())); + Add(new cMenuEditStraItem(tr("Setup.DVB$Standard compliance"), &data.StandardCompliance, 2, standardComplianceTexts)); Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9")); if (data.VideoFormat == 0) Add(new cMenuEditStraItem(tr("Setup.DVB$Video display format"), &data.VideoDisplayFormat, 3, videoDisplayFormatTexts)); @@ -3222,8 +3186,13 @@ eOSState cMenuSetupPlugins::ProcessKey(eKeys Key) } } } - else if (state == osContinue) + else if (state == osContinue) { Store(); + // Reinitialize OSD and skin, in case any plugin setup change has an influence on these: + cOsdProvider::UpdateOsdSize(true); + SetDisplayMenu(); + Display(); + } } return state; } @@ -3242,6 +3211,7 @@ public: cMenuSetup::cMenuSetup(void) :cOsdMenu("") { + SetMenuCategory(mcSetup); Set(); } @@ -3326,6 +3296,7 @@ cOsdObject *cMenuMain::pluginOsdObject = NULL; cMenuMain::cMenuMain(eOSState State) :cOsdMenu("") { + SetMenuCategory(mcMain); replaying = false; stopReplayItem = NULL; cancelEditingItem = NULL; @@ -3394,13 +3365,6 @@ bool cMenuMain::Update(bool Force) { bool result = false; - // Title with disk usage: - if (FreeDiskSpace.HasChanged(Force)) { - //XXX -> skin function!!! - SetTitle(cString::sprintf("%s - %s", tr("VDR"), FreeDiskSpace.FreeDiskSpaceString())); - result = true; - } - bool NewReplaying = cControl::Control() != NULL; if (Force || NewReplaying != replaying) { replaying = NewReplaying; @@ -4130,6 +4094,8 @@ eOSState cDisplaySubtitleTracks::ProcessKey(eKeys Key) cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) { + // Whatever happens here, the timers will be modified in some way... + Timers.SetModified(); // We're going to manipulate an event here, so we need to prevent // others from modifying any EPG data: cSchedulesLock SchedulesLock; @@ -4144,7 +4110,6 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) if (!timer) { timer = new cTimer(true, Pause); Timers.Add(timer); - Timers.SetModified(); instantId = cString::sprintf(cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->CardIndex() + 1); } timer->SetPending(true); @@ -4166,9 +4131,8 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) } else { Timers.Del(timer); - Timers.SetModified(); if (!cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() - cReplayControl::SetRecording(fileName, Recording.Name()); + cReplayControl::SetRecording(fileName); } timer = NULL; return; @@ -4183,7 +4147,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) Recording.WriteInfo(); cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true); if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() - cReplayControl::SetRecording(fileName, Recording.Name()); + cReplayControl::SetRecording(fileName); Recordings.AddByName(fileName); return; } @@ -4194,7 +4158,6 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) timer->SetDeferred(DEFERTIMER); if (!Timer) { Timers.Del(timer); - Timers.SetModified(); timer = NULL; } } @@ -4244,6 +4207,7 @@ void cRecordControl::Stop(bool ExecuteUserCommand) cStatus::MsgRecording(device, NULL, fileName, false); if (ExecuteUserCommand) cRecordingUserCommand::InvokeCommand(RUC_AFTERRECORDING, fileName); + Timers.SetModified(); } } @@ -4337,7 +4301,7 @@ void cRecordControls::Stop(const char *InstantId) bool cRecordControls::PauseLiveVideo(void) { Skins.Message(mtStatus, tr("Pausing live video...")); - cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed() + cReplayControl::SetRecording(NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed() if (Start(NULL, true)) { cReplayControl *rc = new cReplayControl(true); cControl::Launch(rc); @@ -4373,6 +4337,15 @@ cRecordControl *cRecordControls::GetRecordControl(const char *FileName) return NULL; } +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; +} + void cRecordControls::Process(time_t t) { for (int i = 0; i < MAXRECORDCONTROLS; i++) { @@ -4429,8 +4402,7 @@ bool cRecordControls::StateChanged(int &State) // --- cReplayControl -------------------------------------------------------- cReplayControl *cReplayControl::currentReplayControl = NULL; -char *cReplayControl::fileName = NULL; -char *cReplayControl::title = NULL; +cString cReplayControl::fileName; cReplayControl::cReplayControl(bool PauseLive) :cDvbPlayerControl(fileName, PauseLive) @@ -4460,7 +4432,7 @@ cReplayControl::~cReplayControl() void cReplayControl::Stop(void) { - if (Setup.DelTimeshiftRec && fileName) { + if (Setup.DelTimeshiftRec && *fileName) { cRecordControl* rc = cRecordControls::GetRecordControl(fileName); if (rc && rc->InstantId()) { if (Active()) { @@ -4473,7 +4445,7 @@ void cReplayControl::Stop(void) Timers.SetModified(); } cDvbPlayerControl::Stop(); - cRecording *recording = Recordings.GetByName(fileName);; + cRecording *recording = Recordings.GetByName(fileName); if (recording) { if (recording->Delete()) { Recordings.DelByName(fileName); @@ -4490,17 +4462,14 @@ void cReplayControl::Stop(void) cDvbPlayerControl::Stop(); } -void cReplayControl::SetRecording(const char *FileName, const char *Title) +void cReplayControl::SetRecording(const char *FileName) { - free(fileName); - free(title); - fileName = FileName ? strdup(FileName) : NULL; - title = Title ? strdup(Title) : NULL; + fileName = FileName; } const char *cReplayControl::NowReplaying(void) { - return currentReplayControl ? fileName : NULL; + return currentReplayControl ? *fileName : NULL; } const char *cReplayControl::LastReplayed(void) @@ -4510,10 +4479,8 @@ const char *cReplayControl::LastReplayed(void) void cReplayControl::ClearLastReplayed(const char *FileName) { - if (fileName && FileName && strcmp(fileName, FileName) == 0) { - free(fileName); + if (*fileName && FileName && strcmp(fileName, FileName) == 0) fileName = NULL; - } } void cReplayControl::ShowTimed(int Seconds) @@ -4585,8 +4552,10 @@ bool cReplayControl::ShowProgress(bool Initial) visible = true; } if (Initial) { - if (title) - displayReplay->SetTitle(title); + if (*fileName) { + if (cRecording *Recording = Recordings.GetByName(fileName)) + displayReplay->SetRecording(Recording); + } lastCurrent = lastTotal = -1; } if (Current != lastCurrent || Total != lastTotal) { @@ -4758,7 +4727,7 @@ void cReplayControl::MarkMove(bool Forward) void cReplayControl::EditCut(void) { - if (fileName) { + if (*fileName) { Hide(); if (!cCutter::Active()) { if (!marks.Count()) @@ -4800,6 +4769,13 @@ cOsdObject *cReplayControl::GetInfo(void) return NULL; } +const cRecording *cReplayControl::GetRecording(void) +{ + if (const cRecording *Recording = Recordings.GetByName(LastReplayed())) + return Recording; + return NULL; +} + eOSState cReplayControl::ProcessKey(eKeys Key) { if (!Active()) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 2.5 2012/03/08 13:11:40 kls Exp $ + * $Id: menu.h 2.9 2012/05/12 11:48:04 kls Exp $ */ #ifndef __MENU_H @@ -196,7 +196,6 @@ private: int level; int recordingsState; int helpKeys; - bool SetFreeDiskDisplay(bool Force = false); void SetHelpKeys(void); void Set(bool Refresh = false); bool Open(bool OpenSubMenus = false); @@ -243,6 +242,9 @@ public: static bool PauseLiveVideo(void); static const char *GetInstantId(const char *LastInstantId); static cRecordControl *GetRecordControl(const char *FileName); + static cRecordControl *GetRecordControl(const cTimer *Timer); + ///< Returns the cRecordControl for the given Timer. + ///< If there is no cRecordControl for Timer, NULL is returned. static void Process(time_t t); static void ChannelDataModified(cChannel *Channel); static bool Active(void); @@ -267,8 +269,7 @@ private: void TimeSearch(void); void ShowTimed(int Seconds = 0); static cReplayControl *currentReplayControl; - static char *fileName; - static char *title; + static cString fileName; void ShowMode(void); bool ShowProgress(bool Initial); void MarkToggle(void); @@ -281,11 +282,12 @@ public: virtual ~cReplayControl(); void Stop(void); virtual cOsdObject *GetInfo(void); + virtual const cRecording *GetRecording(void); virtual eOSState ProcessKey(eKeys Key); virtual void Show(void); virtual void Hide(void); bool Visible(void) { return visible; } - static void SetRecording(const char *FileName, const char *Title); + static void SetRecording(const char *FileName); static const char *NowReplaying(void); static const char *LastReplayed(void); static void ClearLastReplayed(const char *FileName); diff --git a/menuitems.c b/menuitems.c index ba205c0..416c2be 100644 --- a/menuitems.c +++ b/menuitems.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menuitems.c 2.13 2012/03/13 11:21:57 kls Exp $ + * $Id: menuitems.c 2.14 2012/04/08 11:20:37 kls Exp $ */ #include "menuitems.h" @@ -1126,6 +1126,7 @@ eOSState cMenuEditMapItem::ProcessKey(eKeys Key) cMenuSetupPage::cMenuSetupPage(void) :cOsdMenu("", 33) { + SetMenuCategory(mcSetup); plugin = NULL; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.c 2.27 2012/03/05 10:28:01 kls Exp $ + * $Id: osd.c 2.31 2012/06/02 13:32:38 kls Exp $ */ #include "osd.h" @@ -40,6 +40,16 @@ tColor HsvToColor(double H, double S, double V) } } +tColor RgbShade(tColor Color, double Factor) +{ + double f = fabs(constrain(Factor, -1.0, 1.0)); + double w = Factor > 0 ? f * 0xFF : 0; + return (Color & 0xFF000000) | + (min(0xFF, int((1 - f) * ((Color >> 16) & 0xFF) + w + 0.5)) << 16) | + (min(0xFF, int((1 - f) * ((Color >> 8) & 0xFF) + w + 0.5)) << 8) | + (min(0xFF, int((1 - f) * ( Color & 0xFF) + w + 0.5)) ); +} + #define USE_ALPHA_LUT #ifdef USE_ALPHA_LUT // Alpha blending with lookup table (by Reinhard Nissl <rnissl@gmx.de>) @@ -553,11 +563,15 @@ void cBitmap::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Color if (Width || Height) { limit = x + cw - x0; if (Width) { - if ((Alignment & taLeft) != 0) - ; + if ((Alignment & taLeft) != 0) { + if ((Alignment & taBorder) != 0) + x += max(h / TEXT_ALIGN_BORDER, 1); + } else if ((Alignment & taRight) != 0) { if (w < Width) x += Width - w; + if ((Alignment & taBorder) != 0) + x -= max(h / TEXT_ALIGN_BORDER, 1); } else { // taCentered if (w < Width) @@ -1280,11 +1294,15 @@ void cPixmapMemory::DrawText(const cPoint &Point, const char *s, tColor ColorFg, if (Width || Height) { limit = x + cw; if (Width) { - if ((Alignment & taLeft) != 0) - ; + if ((Alignment & taLeft) != 0) { + if ((Alignment & taBorder) != 0) + x += max(h / TEXT_ALIGN_BORDER, 1); + } else if ((Alignment & taRight) != 0) { if (w < Width) x += Width - w; + if ((Alignment & taBorder) != 0) + x -= max(h / TEXT_ALIGN_BORDER, 1); } else { // taCentered if (w < Width) @@ -1382,10 +1400,10 @@ void cPixmapMemory::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants) case 0: case 6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + 1, 1), Color); if (Quadrants == 6) break; case 8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + 1, 1), Color); break; - case -1: DrawRectangle(cRect(cx + x, cy - y, x2 - x + 1, 1), Color); break; + case -1: DrawRectangle(cRect(cx + x, cy - y, rx - x + 1, 1), Color); break; case -2: DrawRectangle(cRect(x1, cy - y, cx - x - x1 + 1, 1), Color); break; case -3: DrawRectangle(cRect(x1, cy + y, cx - x - x1 + 1, 1), Color); break; - case -4: DrawRectangle(cRect(cx + x, cy + y, x2 - x + 1, 1), Color); break; + case -4: DrawRectangle(cRect(cx + x, cy + y, rx - x + 1, 1), Color); break; default: ; } y++; @@ -1417,10 +1435,10 @@ void cPixmapMemory::DrawEllipse(const cRect &Rect, tColor Color, int Quadrants) case 0: case 6: DrawRectangle(cRect(cx - x, cy - y, 2 * x + 1, 1), Color); if (Quadrants == 6) break; case 8: DrawRectangle(cRect(cx - x, cy + y, 2 * x + 1, 1), Color); break; - case -1: DrawRectangle(cRect(cx + x, cy - y, x2 - x + 1, 1), Color); break; + case -1: DrawRectangle(cRect(cx + x, cy - y, rx - x + 1, 1), Color); break; case -2: DrawRectangle(cRect(x1, cy - y, cx - x - x1 + 1, 1), Color); break; case -3: DrawRectangle(cRect(x1, cy + y, cx - x - x1 + 1, 1), Color); break; - case -4: DrawRectangle(cRect(cx + x, cy + y, x2 - x + 1, 1), Color); break; + case -4: DrawRectangle(cRect(cx + x, cy + y, rx - x + 1, 1), Color); break; default: ; } x++; @@ -1988,7 +2006,7 @@ void cOsdProvider::UpdateOsdSize(bool Force) Setup.FontSmlSize = int(round(Height * Setup.FontSmlSizeP)); cFont::SetFont(fontOsd, Setup.FontOsd, Setup.FontOsdSize); cFont::SetFont(fontFix, Setup.FontFix, Setup.FontFixSize); - cFont::SetFont(fontSml, Setup.FontSml, Setup.FontSmlSize); + cFont::SetFont(fontSml, Setup.FontSml, min(Setup.FontSmlSize, Setup.FontOsdSize)); oldWidth = Width; oldHeight = Height; oldAspect = Aspect; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.h 2.15 2011/12/04 13:38:17 kls Exp $ + * $Id: osd.h 2.17 2012/06/02 10:32:38 kls Exp $ */ #ifndef __OSD_H @@ -25,6 +25,7 @@ #define ALPHA_TRANSPARENT 0x00 #define ALPHA_OPAQUE 0xFF #define IS_OPAQUE(c) ((c >> 24) == ALPHA_OPAQUE) +#define TEXT_ALIGN_BORDER 10 // fraction of the font height used for sizing border enum { //AARRGGBB @@ -69,6 +70,14 @@ inline tColor RgbToColor(double R, double G, double B) return RgbToColor(uint8_t(0xFF * R), uint8_t(0xFF * G), uint8_t(0xFF * B)); } +tColor RgbShade(tColor Color, double Factor); + ///< Returns a brighter (Factor > 0) or darker (Factor < 0) version + ///< of the given Color. + ///< If Factor is 0.0, the return value is the unchanged Color, + ///< If Factor is 1.0, white is returned. + ///< If Factor is -1.0, black is returned. + ///< The alpha value of Color is returned unchanged. + tColor HsvToColor(double H, double S, double V); ///< Converts the given Hue (0..360), Saturation (0..1) and Value (0..1) ///< to an RGB tColor value. The alpha value of the result is 0x00, so @@ -151,6 +160,7 @@ enum eTextAlignment { taCenter = 0x00, taRight = 0x02, taTop = 0x04, taBottom = 0x08, + taBorder = 0x10, // keeps some distance from the left or right alignment edge taDefault = taTop | taLeft }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osdbase.c 2.4 2012/03/02 15:49:57 kls Exp $ + * $Id: osdbase.c 2.6 2012/04/23 09:41:22 kls Exp $ */ #include "osdbase.h" @@ -72,14 +72,15 @@ void cOsdObject::Show(void) cSkinDisplayMenu *cOsdMenu::displayMenu = NULL; int cOsdMenu::displayMenuCount = 0; -int cOsdMenu::displayMenuItems = 0;//XXX dynamic??? cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4) { isMenu = true; digit = 0; hasHotkeys = false; + displayMenuItems = 0; title = NULL; + menuCategory = mcUnknown; SetTitle(Title); SetCols(c0, c1, c2, c3, c4); first = 0; @@ -103,6 +104,11 @@ cOsdMenu::~cOsdMenu() DELETENULL(displayMenu); } +void cOsdMenu::SetMenuCategory(eMenuCategory MenuCategory) +{ + menuCategory = MenuCategory; +} + void cOsdMenu::SetDisplayMenu(void) { if (displayMenu) { @@ -110,7 +116,6 @@ void cOsdMenu::SetDisplayMenu(void) delete displayMenu; } displayMenu = Skins.Current()->DisplayMenu(); - displayMenuItems = displayMenu->MaxItems(); } const char *cOsdMenu::hk(const char *s) @@ -212,6 +217,9 @@ void cOsdMenu::Display(void) displayMenu->SetMessage(mtStatus, NULL); displayMenu->Clear(); cStatus::MsgOsdClear(); + if (menuCategory != displayMenu->MenuCategory()) + displayMenu->SetMenuCategory(menuCategory); + displayMenuItems = displayMenu->MaxItems(); displayMenu->SetTabs(cols[0], cols[1], cols[2], cols[3], cols[4]);//XXX displayMenu->SetTitle(title); cStatus::MsgOsdTitle(title); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osdbase.h 2.2 2012/03/02 15:49:57 kls Exp $ + * $Id: osdbase.h 2.4 2012/04/23 09:40:07 kls Exp $ */ #ifndef __OSDBASE_H @@ -86,10 +86,11 @@ class cOsdMenu : public cOsdObject, public cList<cOsdItem> { private: static cSkinDisplayMenu *displayMenu; static int displayMenuCount; - static int displayMenuItems; + int displayMenuItems; char *title; int cols[cSkinDisplayMenu::MaxTabs]; int first, current, marked; + eMenuCategory menuCategory; cOsdMenu *subMenu; const char *helpRed, *helpGreen, *helpYellow, *helpBlue; bool helpDisplayed; @@ -128,6 +129,7 @@ public: cOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0); virtual ~cOsdMenu(); virtual bool NeedsFastResponse(void) { return subMenu ? subMenu->NeedsFastResponse() : cOsdObject::NeedsFastResponse(); } + void SetMenuCategory(eMenuCategory MenuCategory); int Current(void) const { return current; } void Add(cOsdItem *Item, bool Current = false, cOsdItem *After = NULL); void Ins(cOsdItem *Item, bool Current = false, cOsdItem *Before = NULL); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: pat.c 2.17 2012/03/02 10:56:45 kls Exp $ + * $Id: pat.c 2.18 2012/04/15 09:54:53 kls Exp $ */ #include "pat.h" @@ -456,37 +456,47 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length } } break; - case 0x80: // STREAMTYPE_USER_PRIVATE - DigiCipher II VIDEO (ANSI/SCTE 57) - Vpid = esPid; - Ppid = pmt.getPCRPid(); - Vtype = 0x02; // compression based upon MPEG-2 - ProcessCaDescriptors = true; - break; - case 0x81: // STREAMTYPE_USER_PRIVATE - ATSC A/53 AUDIO (ANSI/SCTE 57) - { - char lang[MAXLANGCODE1] = { 0 }; - SI::Descriptor *d; - for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { - switch (d->getDescriptorTag()) { - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; - strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1); - } - break; - default: ; + case 0x80: // STREAMTYPE_USER_PRIVATE + if (Setup.StandardCompliance == STANDARD_ANSISCTE) { // DigiCipher II VIDEO (ANSI/SCTE 57) + Vpid = esPid; + Ppid = pmt.getPCRPid(); + Vtype = 0x02; // compression based upon MPEG-2 + ProcessCaDescriptors = true; + break; + } + // fall through + case 0x81: // STREAMTYPE_USER_PRIVATE + if (Setup.StandardCompliance == STANDARD_ANSISCTE) { // ATSC A/53 AUDIO (ANSI/SCTE 57) + char lang[MAXLANGCODE1] = { 0 }; + SI::Descriptor *d; + for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { + switch (d->getDescriptorTag()) { + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; + strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1); + } + break; + default: ; + } + delete d; } - delete d; + if (NumDpids < MAXDPIDS) { + Dpids[NumDpids] = esPid; + Dtypes[NumDpids] = SI::AC3DescriptorTag; + strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1); + NumDpids++; + } + ProcessCaDescriptors = true; + break; } - if (NumDpids < MAXDPIDS) { - Dpids[NumDpids] = esPid; - Dtypes[NumDpids] = SI::AC3DescriptorTag; - strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1); - NumDpids++; + // fall through + case 0x82: // STREAMTYPE_USER_PRIVATE + if (Setup.StandardCompliance == STANDARD_ANSISCTE) { // STANDARD SUBTITLE (ANSI/SCTE 27) + //TODO + break; } - ProcessCaDescriptors = true; - } - break; - case 0x82 ... 0xFF: // STREAMTYPE_USER_PRIVATE + // fall through + case 0x83 ... 0xFF: // STREAMTYPE_USER_PRIVATE { char lang[MAXLANGCODE1] = { 0 }; bool IsAc3 = false; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: player.c 2.0 2007/07/20 15:25:24 kls Exp $ + * $Id: player.c 2.2 2012/04/28 11:52:50 kls Exp $ */ #include "player.h" @@ -60,10 +60,20 @@ cOsdObject *cControl::GetInfo(void) return NULL; } -cControl *cControl::Control(void) +const cRecording *cControl::GetRecording(void) +{ + return NULL; +} + +cString cControl::GetHeader(void) +{ + return ""; +} + +cControl *cControl::Control(bool Hidden) { cMutexLock MutexLock(&mutex); - return (control && !control->hidden) ? control : NULL; + return (control && (!control->hidden || Hidden)) ? control : NULL; } void cControl::Launch(cControl *Control) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: player.h 2.4 2009/03/08 12:29:10 kls Exp $ + * $Id: player.h 2.6 2012/04/28 13:04:17 kls Exp $ */ #ifndef __PLAYER_H @@ -86,13 +86,28 @@ public: virtual ~cControl(); virtual void Hide(void) = 0; virtual cOsdObject *GetInfo(void); + ///< Returns an OSD object that displays information about the currently + ///< played programme. If no such information is available, NULL will be + ///< returned. + virtual const cRecording *GetRecording(void); + ///< Returns the cRecording that is currently being replayed, or NULL if + ///< this player is not playing a cRecording. + virtual cString GetHeader(void); + ///< This can be used by players that don't play a cRecording, but rather + ///< do something completely different. The resulting string may be used by + ///< skins as a last resort, in case they want to display the state of the + ///< current player. The return value is expected to be a short, single line + ///< string. The default implementation returns an empty string. double FramesPerSecond(void) { return player->FramesPerSecond(); } bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { return player->GetIndex(Current, Total, SnapToIFrame); } bool GetReplayMode(bool &Play, bool &Forward, int &Speed) { return player->GetReplayMode(Play, Forward, Speed); } static void Launch(cControl *Control); static void Attach(void); static void Shutdown(void); - static cControl *Control(void); + static cControl *Control(bool Hidden = false); + ///< Returns the current replay control (if any) in case it is currently + ///< visible. If Hidden is true, the control will be returned even if it is + ///< currently hidden. }; #endif //__PLAYER_H @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-10-16 11:16-0400\n" "Last-Translator: Osama Alrawab <alrawab@hotmail.com>\n" "Language-Team: Arabic <ar@li.org>\n" @@ -517,12 +517,6 @@ msgstr "المستخدم 8" msgid "Key$User9" msgstr "المستخدم 9" -msgid "Disk" -msgstr "القرص الصلب" - -msgid "free" -msgstr "مساØØ© Øرة" - msgid "Free To Air" msgstr "غير مشÙر" @@ -944,6 +938,9 @@ msgstr "الترجمة" msgid "Setup.DVB$Primary DVB interface" msgstr "كرت الستالايت الاولى" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "نوع الÙيديو " @@ -1174,9 +1171,6 @@ msgstr " ايقا٠التسجيل " msgid "Schedule" msgstr "جدولة" -msgid "VDR" -msgstr "" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " ايقا٠الاعادة" @@ -1307,6 +1301,24 @@ msgstr "الصوت " msgid "Classic VDR" msgstr "VDR تقليدى " +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG شاشة " @@ -1370,3 +1382,9 @@ msgstr "اضغط اى زر لالغاء اعادة التشغيل" #, c-format msgid "VDR will shut down in %s minutes" msgstr "البرنامج سيقوم بالاغلاق بعد%s دقيقة " + +msgid "Disk" +msgstr "القرص الصلب" + +msgid "free" +msgstr "مساØØ© Øرة" diff --git a/po/ca_ES.po b/po/ca_ES.po index 801a399..cd017b2 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-03-02 19:02+0100\n" "Last-Translator: Luca Olivetti <luca@ventoso.org>\n" "Language-Team: Catalan <vdr@linuxtv.org>\n" @@ -512,12 +512,6 @@ msgstr "Usuari 8" msgid "Key$User9" msgstr "Usuari 9" -msgid "Disk" -msgstr "Disc" - -msgid "free" -msgstr "lliure" - msgid "Free To Air" msgstr "No codificat" @@ -926,6 +920,9 @@ msgstr "Subtítols" msgid "Setup.DVB$Primary DVB interface" msgstr "Tarja DVB primària" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Format del vídeo" @@ -1150,9 +1147,6 @@ msgstr " Aturar la gravació " msgid "Schedule" msgstr "Guia de Programació" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Aturar la reproducció" @@ -1282,6 +1276,24 @@ msgstr "Volum " msgid "Classic VDR" msgstr "VDR clasico" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Quadres ST:TNG" @@ -1344,3 +1356,9 @@ msgstr "Prem qualsevol tecla per cancel·lar el reinici" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR s'apagarà en %s minuts" + +msgid "Disk" +msgstr "Disc" + +msgid "free" +msgstr "lliure" diff --git a/po/cs_CZ.po b/po/cs_CZ.po index 50697d1..2feacbe 100644 --- a/po/cs_CZ.po +++ b/po/cs_CZ.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.14\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2010-05-06 11:00+0200\n" "Last-Translator: Radek Šťastný <dedkus@gmail.com>\n" "Language-Team: Czech <vdr@linuxtv.org>\n" @@ -511,12 +511,6 @@ msgstr "Uživatel8" msgid "Key$User9" msgstr "Uživatel9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "volno" - msgid "Free To Air" msgstr "volný" @@ -925,6 +919,9 @@ msgstr "Titulky" msgid "Setup.DVB$Primary DVB interface" msgstr "Primárnà DVB zaÅ™ÃzenÃ" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Formát videa" @@ -1149,9 +1146,6 @@ msgstr " Zastavit nahrávánà " msgid "Schedule" msgstr "Program (EPG)" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Zastavit pÅ™ehrávánÃ" @@ -1281,6 +1275,24 @@ msgstr "Hlasitost " msgid "Classic VDR" msgstr "Klasické VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG konzola" @@ -1343,3 +1355,9 @@ msgstr "Jakákoliv klávesa zruÅ¡Ã restart" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR se vypne za %s minut" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "volno" diff --git a/po/da_DK.po b/po/da_DK.po index 0777ee7..b5681b0 100644 --- a/po/da_DK.po +++ b/po/da_DK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n" "Language-Team: Danish <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "Bruger8" msgid "Key$User9" msgstr "Bruger9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "fri" - msgid "Free To Air" msgstr "Free To Air" @@ -923,6 +917,9 @@ msgstr "Undertekster" msgid "Setup.DVB$Primary DVB interface" msgstr "Primær DVB enhed" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video format" @@ -1147,9 +1144,6 @@ msgstr " Stop optagelse " msgid "Schedule" msgstr "Programoversigt" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Stop afspilning" @@ -1279,6 +1273,24 @@ msgstr "Lydstyrke " msgid "Classic VDR" msgstr "Klassisk VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG konsol" @@ -1341,3 +1353,9 @@ msgstr "Tryk vilkårlig knap for at annullere genstart" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR slukker om %s minutter" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "fri" diff --git a/po/de_DE.po b/po/de_DE.po index 6bcee52..088dbaf 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2010-01-16 16:46+0100\n" "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n" "Language-Team: German <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "Benutzer8" msgid "Key$User9" msgstr "Benutzer9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "frei" - msgid "Free To Air" msgstr "frei empfangbar" @@ -923,6 +917,9 @@ msgstr "Untertitel" msgid "Setup.DVB$Primary DVB interface" msgstr "Primäres DVB-Interface" +msgid "Setup.DVB$Standard compliance" +msgstr "Standardkonformität" + msgid "Setup.DVB$Video format" msgstr "Videoformat" @@ -1147,9 +1144,6 @@ msgstr " Aufzeichnung beenden " msgid "Schedule" msgstr "Programm" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Wiedergabe beenden" @@ -1279,6 +1273,24 @@ msgstr "Lautstärke " msgid "Classic VDR" msgstr "Klassischer VDR" +msgid "DISK" +msgstr "PLATTE" + +msgid "LOAD" +msgstr "LAST" + +msgid "TIMERS" +msgstr "TIMER" + +msgid "DEVICES" +msgstr "EMPFÄNGER" + +msgid "LIVE" +msgstr "LIVE" + +msgid "PLAY" +msgstr "WIEDERGABE" + msgid "ST:TNG Panels" msgstr "ST:TNG-Konsolen" @@ -1341,3 +1353,9 @@ msgstr "Taste drücken, um Neustart abzubrechen" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR wird in %s Minuten abgeschaltet" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "frei" diff --git a/po/el_GR.po b/po/el_GR.po index f2bd7ff..bb53086 100644 --- a/po/el_GR.po +++ b/po/el_GR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n" "Language-Team: Greek <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "" msgid "Key$User9" msgstr "" -msgid "Disk" -msgstr "Äßóêïò" - -msgid "free" -msgstr "Åëåýèåñïò" - msgid "Free To Air" msgstr "" @@ -923,6 +917,9 @@ msgstr "" msgid "Setup.DVB$Primary DVB interface" msgstr "Êýñéá DVB êÜñôá" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "ÌïñöÞ ïèüíçò" @@ -1147,9 +1144,6 @@ msgstr " ÔÝëïò åããáöÞò " msgid "Schedule" msgstr "Ðñüãñáììá" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " ÔÝëïò áíáðáñáãùãÞò" @@ -1279,6 +1273,24 @@ msgstr "¸íôáóç " msgid "Classic VDR" msgstr "Êëáóéêü VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ÌïñöÝò ST:TNG" @@ -1341,3 +1353,9 @@ msgstr "" #, c-format msgid "VDR will shut down in %s minutes" msgstr "" + +msgid "Disk" +msgstr "Äßóêïò" + +msgid "free" +msgstr "Åëåýèåñïò" diff --git a/po/es_ES.po b/po/es_ES.po index 3260e24..93ca669 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-03-02 19:02+0100\n" "Last-Translator: Luca Olivetti <luca@ventoso.org>\n" "Language-Team: Spanish <vdr@linuxtv.org>\n" @@ -510,12 +510,6 @@ msgstr "Usuario 8" msgid "Key$User9" msgstr "Usuario 9" -msgid "Disk" -msgstr "Disco" - -msgid "free" -msgstr "libre" - msgid "Free To Air" msgstr "en abierto" @@ -924,6 +918,9 @@ msgstr "Subtítulos" msgid "Setup.DVB$Primary DVB interface" msgstr "Interfaz DVB primario" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Formato de vídeo" @@ -1148,9 +1145,6 @@ msgstr " Parar grabación " msgid "Schedule" msgstr "Guía de Programación" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Parar reprodución" @@ -1280,6 +1274,24 @@ msgstr "Volumen " msgid "Classic VDR" msgstr "VDR clásico" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Paneles ST:TNG" @@ -1342,3 +1354,9 @@ msgstr "Pulse cualquier tecla para cancelar reinicio" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR se apagará en %s minutos" + +msgid "Disk" +msgstr "Disco" + +msgid "free" +msgstr "libre" diff --git a/po/et_EE.po b/po/et_EE.po index c808011..cfd61f0 100644 --- a/po/et_EE.po +++ b/po/et_EE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n" "Language-Team: Estonian <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "Lisaklahv8" msgid "Key$User9" msgstr "Lisaklahv9" -msgid "Disk" -msgstr "Ketas" - -msgid "free" -msgstr "vaba" - msgid "Free To Air" msgstr "FTA" @@ -923,6 +917,9 @@ msgstr "Subtiitrid" msgid "Setup.DVB$Primary DVB interface" msgstr "Esmane DVB seade" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "TV külgsuhe" @@ -1147,9 +1144,6 @@ msgstr " Lõpetada salvestamine " msgid "Schedule" msgstr "Kava" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Lõpetada taasesitamine" @@ -1279,6 +1273,24 @@ msgstr "Helitugevus " msgid "Classic VDR" msgstr "Classic VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Panels" @@ -1341,3 +1353,9 @@ msgstr "Restardi katkestamiseks vajuta suvalist klahvi" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR lülitub välja %s minuti pärast" + +msgid "Disk" +msgstr "Ketas" + +msgid "free" +msgstr "vaba" diff --git a/po/fi_FI.po b/po/fi_FI.po index 4e9ba73..af24f81 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2007-08-15 15:52+0200\n" "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n" "Language-Team: Finnish <vdr@linuxtv.org>\n" @@ -512,12 +512,6 @@ msgstr "Lisänäppäin 8" msgid "Key$User9" msgstr "Lisänäppäin 9" -msgid "Disk" -msgstr "Levy" - -msgid "free" -msgstr "vapaana" - msgid "Free To Air" msgstr "vapaa" @@ -926,6 +920,9 @@ msgstr "Tekstitys" msgid "Setup.DVB$Primary DVB interface" msgstr "Ensisijainen DVB-sovitin" +msgid "Setup.DVB$Standard compliance" +msgstr "Noudatettava standardi" + msgid "Setup.DVB$Video format" msgstr "Kuvasuhde" @@ -1150,9 +1147,6 @@ msgstr " Lopeta tallennus " msgid "Schedule" msgstr "Ohjelmisto" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Lopeta toisto" @@ -1282,6 +1276,24 @@ msgstr "Äänenvoimakkuus " msgid "Classic VDR" msgstr "Klassinen VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG konsoli" @@ -1344,3 +1356,9 @@ msgstr "Peru uudelleenkäynnistys painamalla mitä tahansa näppäintä" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR sammuu %s minuutin kuluttua" + +msgid "Disk" +msgstr "Levy" + +msgid "free" +msgstr "vapaana" diff --git a/po/fr_FR.po b/po/fr_FR.po index 4673b2e..44b2fa3 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-02-27 18:14+0100\n" "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n" "Language-Team: French <vdr@linuxtv.org>\n" @@ -515,12 +515,6 @@ msgstr "Utilisateur8" msgid "Key$User9" msgstr "Utilisateur9" -msgid "Disk" -msgstr "Disque" - -msgid "free" -msgstr "restant" - msgid "Free To Air" msgstr "En clair" @@ -929,6 +923,9 @@ msgstr "Sous-titres" msgid "Setup.DVB$Primary DVB interface" msgstr "Carte DVB primaire" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Format vidéo" @@ -1153,9 +1150,6 @@ msgstr " Arrêter l'enregistrement " msgid "Schedule" msgstr "Programmes" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Arrêter la lecture" @@ -1285,6 +1279,24 @@ msgstr "Volume " msgid "Classic VDR" msgstr "VDR classique" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Consoles ST:TNG" @@ -1347,3 +1359,9 @@ msgstr "Appuyer sur une touche pour annuler le redémarrage" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR s'arrêtera dans %s minutes" + +msgid "Disk" +msgstr "Disque" + +msgid "free" +msgstr "restant" diff --git a/po/hr_HR.po b/po/hr_HR.po index 91499ca..541c64e 100644 --- a/po/hr_HR.po +++ b/po/hr_HR.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-03-17 19:00+0100\n" "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n" "Language-Team: Croatian <vdr@linuxtv.org>\n" @@ -511,12 +511,6 @@ msgstr "Korisnik8" msgid "Key$User9" msgstr "Korisnik9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "slobodno" - msgid "Free To Air" msgstr "Slobodno" @@ -925,6 +919,9 @@ msgstr "Titlovi" msgid "Setup.DVB$Primary DVB interface" msgstr "Primarni DVB ureðaj" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video format" @@ -1149,9 +1146,6 @@ msgstr " Prekini snimanje " msgid "Schedule" msgstr "Raspored" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Prekini reprodukciju" @@ -1281,6 +1275,24 @@ msgstr "Glasnoæa " msgid "Classic VDR" msgstr "Klasièni VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Panele" @@ -1343,3 +1355,9 @@ msgstr "Pritisnite jednu tipku za poni¹tenje ponovnog podizanja" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR æe se iskljuèiti za %s minuta" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "slobodno" diff --git a/po/hu_HU.po b/po/hu_HU.po index 595fa6b..c7814ee 100644 --- a/po/hu_HU.po +++ b/po/hu_HU.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2012-01-02 11:54+0200\n" "Last-Translator: István Füley <ifuley@tigercomp.ro>\n" "Language-Team: Hungarian <vdr@linuxtv.org>\n" @@ -512,12 +512,6 @@ msgstr "Felhasználó8" msgid "Key$User9" msgstr "Felhasználó9" -msgid "Disk" -msgstr "Lemez" - -msgid "free" -msgstr "szabad" - msgid "Free To Air" msgstr "Kódolatlan" @@ -926,6 +920,9 @@ msgstr "Feliratok" msgid "Setup.DVB$Primary DVB interface" msgstr "Elsõ DVB interface" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video formátum" @@ -1151,9 +1148,6 @@ msgstr " Felvételt befejezni " msgid "Schedule" msgstr "Mûsorújság" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Lejátszást befejzni" @@ -1283,6 +1277,24 @@ msgstr "Hangerõ " msgid "Classic VDR" msgstr "Klasszikus VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Konzol" @@ -1345,3 +1357,9 @@ msgstr "Nyomj egy gombot az újraindítás megszakításához" #, c-format msgid "VDR will shut down in %s minutes" msgstr "A VDR leáll %s perc múlva" + +msgid "Disk" +msgstr "Lemez" + +msgid "free" +msgstr "szabad" diff --git a/po/it_IT.po b/po/it_IT.po index 54beaca..8027cb2 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2012-03-19 01:08+0100\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Language-Team: Italian <vdr@linuxtv.org>\n" @@ -516,12 +516,6 @@ msgstr "Utente8" msgid "Key$User9" msgstr "Utente9" -msgid "Disk" -msgstr "Disco" - -msgid "free" -msgstr "disponibili" - msgid "Free To Air" msgstr "in chiaro" @@ -930,6 +924,9 @@ msgstr "Sottotitoli" msgid "Setup.DVB$Primary DVB interface" msgstr "Scheda DVB primaria" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Formato video" @@ -1154,9 +1151,6 @@ msgstr " Ferma registrazione " msgid "Schedule" msgstr "Programmi" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Ferma riproduzione" @@ -1286,6 +1280,24 @@ msgstr "Volume " msgid "Classic VDR" msgstr "VDR Classico" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Consolle ST:TNG" @@ -1348,3 +1360,9 @@ msgstr "Premi un tasto per annullare il riavvio" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR si spegnerà tra %s minuti" + +msgid "Disk" +msgstr "Disco" + +msgid "free" +msgstr "disponibili" diff --git a/po/lt_LT.po b/po/lt_LT.po index 50cd11d..03d3508 100644 --- a/po/lt_LT.po +++ b/po/lt_LT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.16\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2010-10-30 11:55+0200\n" "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n" "Language-Team: Lithuanian <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "Vartotojas8" msgid "Key$User9" msgstr "Vartotojas9" -msgid "Disk" -msgstr "Diskas" - -msgid "free" -msgstr "laisva" - msgid "Free To Air" msgstr "Nekoduotas kanalas" @@ -923,6 +917,9 @@ msgstr "Subtitrai" msgid "Setup.DVB$Primary DVB interface" msgstr "PirminiÄ— DVB įvestis" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video formatas" @@ -1147,9 +1144,6 @@ msgstr " Sustabdyti įraÅ¡inÄ—jimÄ… " msgid "Schedule" msgstr "Programa" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Sustabdyti kartojimÄ…" @@ -1279,6 +1273,24 @@ msgstr "Garsas " msgid "Classic VDR" msgstr "Klasikinis VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Skydeliai" @@ -1341,3 +1353,9 @@ msgstr "Paspauskit bet kurį mygtukÄ… kad sustabdytumÄ—te perkrovimÄ…" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR iÅ¡sijungs per %s minutes" + +msgid "Disk" +msgstr "Diskas" + +msgid "free" +msgstr "laisva" diff --git a/po/mk_MK.po b/po/mk_MK.po index 94935c8..e62fac8 100644 --- a/po/mk_MK.po +++ b/po/mk_MK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR-1.7.14\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2010-03-11 00:54+0100\n" "Last-Translator: Dimitar Petrovski <dimeptr@gmail.com>\n" "Language-Team: Macedonian <en@li.org>\n" @@ -510,12 +510,6 @@ msgstr "КориÑник8" msgid "Key$User9" msgstr "КориÑник9" -msgid "Disk" -msgstr "ДиÑк" - -msgid "free" -msgstr "Ñлободен" - msgid "Free To Air" msgstr "Слободно" @@ -924,6 +918,9 @@ msgstr "Титл" msgid "Setup.DVB$Primary DVB interface" msgstr "Примарен DVB уред" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Видео формат" @@ -1148,9 +1145,6 @@ msgstr " Запри Ñнимање " msgid "Schedule" msgstr "РаÑпоред" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Запри пуштање" @@ -1280,6 +1274,24 @@ msgstr "ГлаÑ" msgid "Classic VDR" msgstr "КлаÑичен VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Панели" @@ -1342,3 +1354,9 @@ msgstr "ПритиÑнете копче за откажување на реÑÑ‚Ð #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR ќе Ñе иÑклучи за %s минути" + +msgid "Disk" +msgstr "ДиÑк" + +msgid "free" +msgstr "Ñлободен" diff --git a/po/nl_NL.po b/po/nl_NL.po index 20ee0cb..9d1fcde 100644 --- a/po/nl_NL.po +++ b/po/nl_NL.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-02-26 17:20+0100\n" "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n" "Language-Team: Dutch <vdr@linuxtv.org>\n" @@ -513,12 +513,6 @@ msgstr "Gebruiker8" msgid "Key$User9" msgstr "Gebruiker9" -msgid "Disk" -msgstr "Schijf" - -msgid "free" -msgstr "vrij" - msgid "Free To Air" msgstr "Vrij te ontvangen" @@ -927,6 +921,9 @@ msgstr "Ondertiteling" msgid "Setup.DVB$Primary DVB interface" msgstr "Eerste DVB kaart" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Videoformaat" @@ -1151,9 +1148,6 @@ msgstr " Stop opnemen " msgid "Schedule" msgstr "Programmagids" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Stop afspelen" @@ -1283,6 +1277,24 @@ msgstr "Volume " msgid "Classic VDR" msgstr "VDR Klassiek" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Consoles" @@ -1345,3 +1357,9 @@ msgstr "Druk een willekeurige toets om herstarten af te breken" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR zal na %s minuten uitschakelen" + +msgid "Disk" +msgstr "Schijf" + +msgid "free" +msgstr "vrij" diff --git a/po/nn_NO.po b/po/nn_NO.po index a51967b..44940e0 100644 --- a/po/nn_NO.po +++ b/po/nn_NO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Truls Slevigen <truls@slevigen.no>\n" "Language-Team: Norwegian Nynorsk <vdr@linuxtv.org>\n" @@ -510,12 +510,6 @@ msgstr "" msgid "Key$User9" msgstr "" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "ledig" - msgid "Free To Air" msgstr "" @@ -924,6 +918,9 @@ msgstr "" msgid "Setup.DVB$Primary DVB interface" msgstr "Hoved DVB-enhet" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "TV-Format" @@ -1148,9 +1145,6 @@ msgstr " Stopp opptak fra " msgid "Schedule" msgstr "Programmer" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Stopp avspilling" @@ -1280,6 +1274,24 @@ msgstr "Volum " msgid "Classic VDR" msgstr "" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "" @@ -1342,3 +1354,9 @@ msgstr "" #, c-format msgid "VDR will shut down in %s minutes" msgstr "" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "ledig" diff --git a/po/pl_PL.po b/po/pl_PL.po index 5471341..90a1762 100644 --- a/po/pl_PL.po +++ b/po/pl_PL.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-03-09 12:59+0100\n" "Last-Translator: Michael Rakowski <mrak@gmx.de>\n" "Language-Team: Polish <vdr@linuxtv.org>\n" @@ -510,12 +510,6 @@ msgstr "U¿ytkownik 8" msgid "Key$User9" msgstr "U¿ytkownik 9" -msgid "Disk" -msgstr "Dysk" - -msgid "free" -msgstr "wolnego" - msgid "Free To Air" msgstr "nieszyfrowany" @@ -924,6 +918,9 @@ msgstr "Napisy" msgid "Setup.DVB$Primary DVB interface" msgstr "Pierwszy interfejs DVB" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Format obrazu" @@ -1148,9 +1145,6 @@ msgstr " Zatrzymaj nagrywanie " msgid "Schedule" msgstr "Program" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Zatrzymaj odtwarzanie" @@ -1280,6 +1274,24 @@ msgstr "G³o¶no¶æ " msgid "Classic VDR" msgstr "Klasyczny VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Panel ST:TNG" @@ -1342,3 +1354,9 @@ msgstr "Naci¶nij dowolny klawisz aby nie zrestartowaæ" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR zostanie wy³±czony za %s minut" + +msgid "Disk" +msgstr "Dysk" + +msgid "free" +msgstr "wolnego" diff --git a/po/pt_PT.po b/po/pt_PT.po index 360a095..c201761 100644 --- a/po/pt_PT.po +++ b/po/pt_PT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.15\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2010-03-28 22:49+0100\n" "Last-Translator: Cris Silva <hudokkow@gmail.com>\n" "Language-Team: Portuguese <vdr@linuxtv.org>\n" @@ -510,12 +510,6 @@ msgstr "Definição8" msgid "Key$User9" msgstr "Definição9" -msgid "Disk" -msgstr "Disco" - -msgid "free" -msgstr "livre" - msgid "Free To Air" msgstr "FTA" @@ -924,6 +918,9 @@ msgstr "Legendas" msgid "Setup.DVB$Primary DVB interface" msgstr "Placa DVB primária" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Formato de vídeo" @@ -1148,9 +1145,6 @@ msgstr " Parar gravação " msgid "Schedule" msgstr "Programação" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Parar reprodução" @@ -1280,6 +1274,24 @@ msgstr "Volume " msgid "Classic VDR" msgstr "VDR Clássico" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Consola ST:TNG" @@ -1342,3 +1354,9 @@ msgstr "Pressione qualquer tecla para cancelar o reinicio" #, c-format msgid "VDR will shut down in %s minutes" msgstr "O VDR vai desligar daqui a %s minutos" + +msgid "Disk" +msgstr "Disco" + +msgid "free" +msgstr "livre" diff --git a/po/ro_RO.po b/po/ro_RO.po index 7d875d5..64aadc8 100644 --- a/po/ro_RO.po +++ b/po/ro_RO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.12\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2011-03-10 23:52+0100\n" "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n" "Language-Team: Romanian <vdr@linuxtv.org>\n" @@ -512,12 +512,6 @@ msgstr "Utilizator8" msgid "Key$User9" msgstr "Utilizator9" -msgid "Disk" -msgstr "Disc" - -msgid "free" -msgstr "liber" - msgid "Free To Air" msgstr "FTA (necriptat)" @@ -926,6 +920,9 @@ msgstr "Subtitrare" msgid "Setup.DVB$Primary DVB interface" msgstr "Dispozitiv DVB primar" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Format video" @@ -1150,9 +1147,6 @@ msgstr " Opreºte înregistrarea " msgid "Schedule" msgstr "Program (EPG)" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Opreºte redarea" @@ -1282,6 +1276,24 @@ msgstr "Volum " msgid "Classic VDR" msgstr "VDR clasic" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "Cons. ST:TNG" @@ -1344,3 +1356,9 @@ msgstr "Apãsaþi orice tastã pentru a anula repornirea" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR se va închide în %s minute" + +msgid "Disk" +msgstr "Disc" + +msgid "free" +msgstr "liber" diff --git a/po/ru_RU.po b/po/ru_RU.po index 203cb00..f3cd5c3 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-12-15 14:37+0100\n" "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n" "Language-Team: Russian <vdr@linuxtv.org>\n" @@ -510,12 +510,6 @@ msgstr "¿ÞÛì×ÞÒÐâÕÛì8" msgid "Key$User9" msgstr "¿ÞÛì×ÞÒÐâÕÛì9" -msgid "Disk" -msgstr "´ØáÚ" - -msgid "free" -msgstr "áÒÞÑÞÔÝÞ" - msgid "Free To Air" msgstr "FTA (ÝÕ×ÐÚÞÔØàÞÒÐÝÞ)" @@ -924,6 +918,9 @@ msgstr "ÁãÑâØâàë" msgid "Setup.DVB$Primary DVB interface" msgstr "¾áÝÞÒÝÞÕ DVB-ãáâàÞÙáâÒÞ" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "ÄÞàÜÐâ ÒØÔÕÞ" @@ -1148,9 +1145,6 @@ msgstr " ¿àÕÚàÐâØâì ×ÐßØáì " msgid "Schedule" msgstr "ÂÕÛÕÓØÔ" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " ¿àÕÚàÐâØâì ÒÞáßàÞØ×ÒÕÔÕÝØÕ" @@ -1280,6 +1274,24 @@ msgstr "³àÞÜÚÞáâì " msgid "Classic VDR" msgstr "ºÛÐááØçÕáÚØÙ" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG ßÐÝÕÛØ" @@ -1342,3 +1354,9 @@ msgstr "½ÐÖÜØâÕ ÛîÑãî ÚÝÞßÚã ÔÛï ÞâÜÕÝë ßÕàÕ×ÐÓàã×ÚØ" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR ÒëÚÛîçØâáï çÕàÕ× %s ÜØÝãâ" + +msgid "Disk" +msgstr "´ØáÚ" + +msgid "free" +msgstr "áÒÞÑÞÔÝÞ" diff --git a/po/sk_SK.po b/po/sk_SK.po index 65dc7bd..985435d 100644 --- a/po/sk_SK.po +++ b/po/sk_SK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.16\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2011-02-15 16:29+0100\n" "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n" "Language-Team: Slovak <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "U¾ívateµ8" msgid "Key$User9" msgstr "U¾ívateµ9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "volne" - msgid "Free To Air" msgstr "volne ¹íriteµný" @@ -923,6 +917,9 @@ msgstr "Titulky" msgid "Setup.DVB$Primary DVB interface" msgstr "Hlavné DVB rozhranie" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Formát videa" @@ -1147,9 +1144,6 @@ msgstr " Zastavi» nahrávanie" msgid "Schedule" msgstr "TV program" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Zastavi» prehrávanie" @@ -1279,6 +1273,24 @@ msgstr "Hlasitos»" msgid "Classic VDR" msgstr "Klasické VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG panely" @@ -1341,3 +1353,9 @@ msgstr "ktorákoµvek klávesa zru¹í re¹tart" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR sa vypne za %s minút" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "volne" diff --git a/po/sl_SI.po b/po/sl_SI.po index b785143..8b25fc3 100644 --- a/po/sl_SI.po +++ b/po/sl_SI.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-02-28 19:44+0100\n" "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n" "Language-Team: Slovenian <vdr@linuxtv.org>\n" @@ -510,12 +510,6 @@ msgstr "Uporabnik8" msgid "Key$User9" msgstr "Uporabnik9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "prosto" - msgid "Free To Air" msgstr "nekodiran" @@ -924,6 +918,9 @@ msgstr "Podnapisi" msgid "Setup.DVB$Primary DVB interface" msgstr "Primarna naprava" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video format" @@ -1148,9 +1145,6 @@ msgstr " Prekini snemanje " msgid "Schedule" msgstr "Program" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Prekini predvajanje" @@ -1280,6 +1274,24 @@ msgstr "Glasnost " msgid "Classic VDR" msgstr "Klasièni VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Konsola" @@ -1342,3 +1354,9 @@ msgstr "Pritisni katerokoli tipko za preklic ponovnega zagona" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR se bo zaustavil v %s minutah" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "prosto" diff --git a/po/sr_SR.po b/po/sr_SR.po index d5f7e9a..39bc9d2 100644 --- a/po/sr_SR.po +++ b/po/sr_SR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.1\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2011-01-09 15:57+0100\n" "Last-Translator: Milan Cvijanoviæ <elcom_cvijo@hotmail.com>\n" "Language-Team: Serbian <vdr@linuxtv.org>\n" @@ -511,12 +511,6 @@ msgstr "Korisnik8" msgid "Key$User9" msgstr "Korisnik9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "slobodno" - msgid "Free To Air" msgstr "Slobodno" @@ -942,6 +936,9 @@ msgstr "Titlovi" msgid "Setup.DVB$Primary DVB interface" msgstr "Primarni DVB ureðaj" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video format" @@ -1171,9 +1168,6 @@ msgstr " Zaustavi snimanje " msgid "Schedule" msgstr "Raspored Programa" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Zaustavi reprodukciju" @@ -1305,6 +1299,24 @@ msgstr "Jaèina " msgid "Classic VDR" msgstr "Klasièni VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG Panele" @@ -1368,3 +1380,9 @@ msgstr "Pritisni jedan taster za poni¹tenje restart-a" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR se iskljuèuje za %s minuta" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "slobodno" diff --git a/po/sv_SE.po b/po/sv_SE.po index 4e9aba8..7987755 100644 --- a/po/sv_SE.po +++ b/po/sv_SE.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-03-12 18:25+0100\n" "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n" "Language-Team: Swedish <vdr@linuxtv.org>\n" @@ -512,12 +512,6 @@ msgstr "Användare8" msgid "Key$User9" msgstr "Användare9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "ledigt" - msgid "Free To Air" msgstr "Okodad" @@ -926,6 +920,9 @@ msgstr "Knapp$Textning" msgid "Setup.DVB$Primary DVB interface" msgstr "Primär DVB enhet" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video format" @@ -1150,9 +1147,6 @@ msgstr " Avsluta inspelning " msgid "Schedule" msgstr "Program" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Avsluta uppspelning" @@ -1282,6 +1276,24 @@ msgstr "Volym " msgid "Classic VDR" msgstr "Klassisk VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG konsol" @@ -1344,3 +1356,9 @@ msgstr "Tryck valfri knapp för att återkalla omstart" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR kommer att stängas ned om %s minuter" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "ledigt" diff --git a/po/tr_TR.po b/po/tr_TR.po index c11769b..163b823 100644 --- a/po/tr_TR.po +++ b/po/tr_TR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2008-02-28 00:33+0100\n" "Last-Translator: Oktay Yolgeçen <oktay_73@yahoo.de>\n" "Language-Team: Turkish <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "Kullanýcý8" msgid "Key$User9" msgstr "Kullanýcý9" -msgid "Disk" -msgstr "Disk" - -msgid "free" -msgstr "boþ" - msgid "Free To Air" msgstr "Þifresiz" @@ -923,6 +917,9 @@ msgstr "Altyazý" msgid "Setup.DVB$Primary DVB interface" msgstr "Primer DVB arayüzü" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Video formatý" @@ -1147,9 +1144,6 @@ msgstr " Çekimi bitir " msgid "Schedule" msgstr "Program" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Gösteriþi bitir" @@ -1279,6 +1273,24 @@ msgstr "Volüm " msgid "Classic VDR" msgstr "Klasik VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG paneli" @@ -1341,3 +1353,9 @@ msgstr "Yeniden baþlatmayý iptal etmek için herhangi bir tuþa bas" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR %s dakikada kapanacak" + +msgid "Disk" +msgstr "Disk" + +msgid "free" +msgstr "boþ" diff --git a/po/uk_UA.po b/po/uk_UA.po index e175282..588cf7a 100644 --- a/po/uk_UA.po +++ b/po/uk_UA.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.7\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2010-04-25 16:35+0200\n" "Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n" "Language-Team: Ukrainian <vdr@linuxtv.org>\n" @@ -509,12 +509,6 @@ msgstr "КориÑтувач8" msgid "Key$User9" msgstr "КориÑтувач8" -msgid "Disk" -msgstr "ДиÑк" - -msgid "free" -msgstr "вільно" - msgid "Free To Air" msgstr "FTA (незакодовано)" @@ -923,6 +917,9 @@ msgstr "Субтитри" msgid "Setup.DVB$Primary DVB interface" msgstr "ОÑновний DVB-приÑтрій" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "Формат відео" @@ -1147,9 +1144,6 @@ msgstr " Зупинити Ð·Ð°Ð¿Ð¸Ñ " msgid "Schedule" msgstr "Телегід" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr " Зупинити програваннÑ" @@ -1279,6 +1273,24 @@ msgstr "ГучніÑÑ‚ÑŒ " msgid "Classic VDR" msgstr "КлаÑичний VDR" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG панелі" @@ -1341,3 +1353,9 @@ msgstr "ÐатиÑніть будь-Ñку кнопку Ð´Ð»Ñ Ð²Ñ–Ð´Ð¼Ñ–Ð½Ð¸ п #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR виключитьÑÑ Ñ‡ÐµÑ€ÐµÐ· %s хвилин" + +msgid "Disk" +msgstr "ДиÑк" + +msgid "free" +msgstr "вільно" diff --git a/po/zh_CN.po b/po/zh_CN.po index b878937..d087946 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2012-03-08 14:37+0100\n" +"POT-Creation-Date: 2012-06-02 15:10+0200\n" "PO-Revision-Date: 2009-09-23 23:50+0800\n" "Last-Translator: Nan Feng <nfgx@21cn.com>\n" "Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n" @@ -512,12 +512,6 @@ msgstr "用户8" msgid "Key$User9" msgstr "用户9" -msgid "Disk" -msgstr "硬盘已使用" - -msgid "free" -msgstr "å¯å½•åƒæ—¶é—´" - msgid "Free To Air" msgstr "剩余空间" @@ -926,6 +920,9 @@ msgstr "å—幕" msgid "Setup.DVB$Primary DVB interface" msgstr "使用ä¸å«æ˜Ÿå¡æŽ¥å£" +msgid "Setup.DVB$Standard compliance" +msgstr "" + msgid "Setup.DVB$Video format" msgstr "è§†é¢‘æ ¼å¼" @@ -1150,9 +1147,6 @@ msgstr "是å¦åœæ¢å½•åƒ?" msgid "Schedule" msgstr "任务列表" -msgid "VDR" -msgstr "VDR" - #. TRANSLATORS: note the leading blank! msgid " Stop replaying" msgstr "åœæ¢å›žæ”¾" @@ -1282,6 +1276,24 @@ msgstr "音é‡è°ƒæ•´" msgid "Classic VDR" msgstr "ç»å…¸VDRé¢æ¿" +msgid "DISK" +msgstr "" + +msgid "LOAD" +msgstr "" + +msgid "TIMERS" +msgstr "" + +msgid "DEVICES" +msgstr "" + +msgid "LIVE" +msgstr "" + +msgid "PLAY" +msgstr "" + msgid "ST:TNG Panels" msgstr "ST:TNG é¢æ¿" @@ -1344,3 +1356,9 @@ msgstr "请按任æ„é”®é‡å¯" #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR系统将è¦åœ¨%s分钟关é—" + +msgid "Disk" +msgstr "硬盘已使用" + +msgid "free" +msgstr "å¯å½•åƒæ—¶é—´" @@ -4,27 +4,13 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: receiver.c 2.5 2012/02/29 11:49:36 kls Exp $ + * $Id: receiver.c 2.7 2012/06/02 13:20:38 kls Exp $ */ #include "receiver.h" #include <stdio.h> #include "tools.h" -#ifdef LEGACY_CRECEIVER -cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3) -{ - device = NULL; - channelID = ChannelID; - priority = constrain(Priority, MINPRIORITY, MAXPRIORITY); - numPids = 0; - AddPid(Pid); - AddPids(Pids1); - AddPids(Pids2); - AddPids(Pids3); -} -#endif - cReceiver::cReceiver(const cChannel *Channel, int Priority) { device = NULL; @@ -83,7 +69,7 @@ bool cReceiver::SetPids(const cChannel *Channel) AddPids(Channel->Dpids()) && AddPids(Channel->Spids()); } -return true; + return true; } bool cReceiver::WantsPid(int Pid) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: receiver.h 2.6 2012/03/11 15:25:40 kls Exp $ + * $Id: receiver.h 2.8 2012/06/02 13:20:44 kls Exp $ */ #ifndef __RECEIVER_H @@ -14,8 +14,6 @@ #define MAXRECEIVEPIDS 64 // the maximum number of PIDs per receiver -//#define LEGACY_CRECEIVER // Code enclosed with this macro is deprecated and may be removed in a future version - class cReceiver { friend class cDevice; private: @@ -40,9 +38,6 @@ protected: ///< will be delivered only ONCE, so the cReceiver must make sure that ///< it will be able to buffer the data if necessary. public: -#ifdef LEGACY_CRECEIVER - cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); -#endif cReceiver(const cChannel *Channel = NULL, int Priority = MINPRIORITY); ///< Creates a new receiver for the given Channel with the given Priority. ///< If Channel is not NULL, its pids are set by a call to SetPids(). @@ -62,7 +57,7 @@ public: ///< Adds the given Pids to the list of PIDs of this receiver. bool SetPids(const cChannel *Channel); ///< Sets the PIDs of this receiver to those of the given Channel, - ///< replacing and previously stored PIDs. If Channel is NULL, all + ///< replacing any previously stored PIDs. If Channel is NULL, all ///< PIDs will be cleared. Parameters in the Setup may control whether ///< certain types of PIDs (like Dolby Digital, for instance) are ///< actually set. The Channel's ID is stored and can later be retrieved diff --git a/recording.c b/recording.c index e1f7ec9..2a73645 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 2.53 2012/03/13 13:17:57 kls Exp $ + * $Id: recording.c 2.56 2012/06/03 09:51:27 kls Exp $ */ #include "recording.h" @@ -153,7 +153,7 @@ void AssertFreeDiskSpace(int Priority, bool Force) cRecording *r = DeletedRecordings.First(); cRecording *r0 = NULL; while (r) { - if (IsOnVideoDirectoryFileSystem(r->FileName())) { // only remove recordings that will actually increase the free video disk space + if (r->IsOnVideoDirectoryFileSystem()) { // only remove recordings that will actually increase the free video disk space if (!r0 || r->Start() < r0->Start()) r0 = r; } @@ -180,7 +180,7 @@ void AssertFreeDiskSpace(int Priority, bool Force) cRecording *r = Recordings.First(); cRecording *r0 = NULL; while (r) { - if (IsOnVideoDirectoryFileSystem(r->FileName())) { // only delete recordings that will actually increase the free video disk space + if (r->IsOnVideoDirectoryFileSystem()) { // only delete recordings that will actually increase the free video disk space if (!r->IsEdited() && r->Lifetime() < MAXLIFETIME) { // edited recordings and recordings with MAXLIFETIME live forever if ((r->Lifetime() == 0 && Priority > r->Priority()) || // the recording has no guaranteed lifetime and the new recording has higher priority (r->Lifetime() > 0 && (time(NULL) - r->Start()) / SECSINDAY >= r->Lifetime())) { // the recording's guaranteed lifetime has expired @@ -617,6 +617,7 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event) channel = Timer->Channel()->Number(); instanceId = InstanceId; isPesRecording = false; + isOnVideoDirectoryFileSystem = -1; // unknown framesPerSecond = DEFAULTFRAMESPERSECOND; numFrames = -1; deleted = 0; @@ -677,6 +678,7 @@ cRecording::cRecording(const char *FileName) priority = MAXPRIORITY; // assume maximum in case there is no info file lifetime = MAXLIFETIME; isPesRecording = false; + isOnVideoDirectoryFileSystem = -1; // unknown framesPerSecond = DEFAULTFRAMESPERSECOND; numFrames = -1; deleted = 0; @@ -723,7 +725,9 @@ cRecording::cRecording(const char *FileName) } fclose(f); } - else if (errno != ENOENT) + else if (errno == ENOENT) + info->ownEvent->SetTitle(name); + else LOG_ERROR_STR(*InfoFileName); #ifdef SUMMARYFALLBACK // fall back to the old 'summary.vdr' if there was no 'info.vdr': @@ -950,6 +954,13 @@ bool cRecording::IsEdited(void) const return *s == '%'; } +bool cRecording::IsOnVideoDirectoryFileSystem(void) const +{ + if (isOnVideoDirectoryFileSystem < 0) + isOnVideoDirectoryFileSystem = ::IsOnVideoDirectoryFileSystem(FileName()); + return isOnVideoDirectoryFileSystem; +} + void cRecording::ReadInfo(void) { info->Read(); @@ -1251,7 +1262,7 @@ int cRecordings::TotalFileSizeMB(void) LOCK_THREAD; for (cRecording *recording = First(); recording; recording = Next(recording)) { int FileSizeMB = recording->FileSizeMB(); - if (FileSizeMB > 0 && IsOnVideoDirectoryFileSystem(recording->FileName())) + if (FileSizeMB > 0 && recording->IsOnVideoDirectoryFileSystem()) size += FileSizeMB; } return size; @@ -1263,7 +1274,7 @@ double cRecordings::MBperMinute(void) int length = 0; LOCK_THREAD; for (cRecording *recording = First(); recording; recording = Next(recording)) { - if (IsOnVideoDirectoryFileSystem(recording->FileName())) { + if (recording->IsOnVideoDirectoryFileSystem()) { int FileSizeMB = recording->FileSizeMB(); if (FileSizeMB > 0) { int LengthInSeconds = recording->LengthInSeconds(); @@ -1422,13 +1433,17 @@ cMark *cMarks::GetNext(int Position) const char *cRecordingUserCommand::command = NULL; -void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName) +void cRecordingUserCommand::InvokeCommand(const char *State, const char *RecordingFileName, const char *SourceFileName) { if (command) { - cString cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$")); - isyslog("executing '%s'", *cmd); - SystemExec(cmd); - } + cString cmd; + if (SourceFileName) + cmd = cString::sprintf("%s %s \"%s\" \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$"), *strescape(SourceFileName, "\\\"$")); + else + cmd = cString::sprintf("%s %s \"%s\"", command, State, *strescape(RecordingFileName, "\\\"$")); + isyslog("executing '%s'", *cmd); + SystemExec(cmd); + } } // --- cIndexFileGenerator --------------------------------------------------- diff --git a/recording.h b/recording.h index 5f94ee2..56659ed 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 2.30 2012/03/13 12:41:05 kls Exp $ + * $Id: recording.h 2.33 2012/06/03 09:49:09 kls Exp $ */ #ifndef __RECORDING_H @@ -22,8 +22,6 @@ #define TIMERMACRO_TITLE "TITLE" #define TIMERMACRO_EPISODE "EPISODE" -//#define __RECORDING_H_DEPRECATED_DIRECT_MEMBER_ACCESS // Code enclosed with this macro is deprecated and may be removed in a future version - extern bool VfatFileSystem; extern int InstanceId; @@ -93,6 +91,7 @@ private: int channel; int instanceId; bool isPesRecording; + mutable int isOnVideoDirectoryFileSystem; // -1 = unknown, 0 = no, 1 = yes double framesPerSecond; cRecordingInfo *info; cRecording(const cRecording&); // can't copy cRecording @@ -100,9 +99,6 @@ private: static char *StripEpisodeName(char *s); char *SortName(void) const; int GetResume(void) const; -#ifdef __RECORDING_H_DEPRECATED_DIRECT_MEMBER_ACCESS -public: -#endif time_t start; int priority; int lifetime; @@ -135,6 +131,7 @@ public: bool IsNew(void) const { return GetResume() <= 0; } bool IsEdited(void) const; bool IsPesRecording(void) const { return isPesRecording; } + bool IsOnVideoDirectoryFileSystem(void) const; void ReadInfo(void); bool WriteInfo(void); void SetStartTime(time_t Start); @@ -208,9 +205,6 @@ class cMark : public cListObject { friend class cMarks; // for sorting private: double framesPerSecond; -#ifdef __RECORDING_H_DEPRECATED_DIRECT_MEMBER_ACCESS -public: -#endif int position; cString comment; public: @@ -251,7 +245,7 @@ private: static const char *command; public: static void SetCommand(const char *Command) { command = Command; } - static void InvokeCommand(const char *State, const char *RecordingFileName); + static void InvokeCommand(const char *State, const char *RecordingFileName, const char *SourceFileName = NULL); }; // The maximum size of a single frame (up to HDTV 1920x1080): diff --git a/skinclassic.c b/skinclassic.c index 49f0bcb..64944de 100644 --- a/skinclassic.c +++ b/skinclassic.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skinclassic.c 2.6 2011/08/21 11:02:06 kls Exp $ + * $Id: skinclassic.c 2.7 2012/04/23 08:48:03 kls Exp $ */ #include "skinclassic.h" @@ -12,6 +12,7 @@ #include "i18n.h" #include "osd.h" #include "themes.h" +#include "videodir.h" #define ScrollWidth (Setup.FontOsdSize / 4) #define TextFrame (Setup.FontOsdSize / 10) @@ -170,7 +171,10 @@ private: int y0, y1, y2, y3, y4, y5; int lineHeight; int dateWidth; + cString title; cString lastDate; + int lastDiskUsageState; + void DrawTitle(void); void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown); void SetTextScrollbar(void); public: @@ -196,6 +200,7 @@ cSkinClassicDisplayMenu::cSkinClassicDisplayMenu(void) { const cFont *font = cFont::GetFont(fontOsd); lineHeight = font->Height(); + lastDiskUsageState = -1; dateWidth = 0; x0 = 0; x1 = x0 + 2 * TextSpacing; @@ -270,10 +275,17 @@ void cSkinClassicDisplayMenu::Clear(void) osd->DrawRectangle(x0, y1, x3 - 1, y4 - 1, Theme.Color(clrBackground)); } -void cSkinClassicDisplayMenu::SetTitle(const char *Title) +void cSkinClassicDisplayMenu::DrawTitle(void) { const cFont *font = cFont::GetFont(fontOsd); - osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x3 - x0 - dateWidth); + bool WithDisk = MenuCategory() == mcMain || MenuCategory() == mcRecording; + osd->DrawText(x0, y0, WithDisk ? cString::sprintf("%s - %s", *title, *cVideoDiskUsage::String()) : title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x3 - x0 - dateWidth); +} + +void cSkinClassicDisplayMenu::SetTitle(const char *Title) +{ + title = Title; + DrawTitle(); } void cSkinClassicDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) @@ -422,6 +434,8 @@ const cFont *cSkinClassicDisplayMenu::GetTextAreaFont(bool FixedFont) const void cSkinClassicDisplayMenu::Flush(void) { + if (cVideoDiskUsage::HasChanged(lastDiskUsageState)) + DrawTitle(); cString date = DayDateTime(); if (!*lastDate || strcmp(date, lastDate)) { const cFont *font = cFont::GetFont(fontOsd); diff --git a/skinlcars.c b/skinlcars.c new file mode 100644 index 0000000..a602923 --- /dev/null +++ b/skinlcars.c @@ -0,0 +1,2114 @@ +/* + * skinlcars.c: A VDR skin with Star Trek's "LCARS" layout + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: skinlcars.c 2.2 2012/06/03 10:17:00 kls Exp $ + */ + +// "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures, +// registered in the United States Patent and Trademark Office, all rights reserved. +// The LCARS system is based upon the designs of Michael Okuda and his Okudagrams. +// +// "LCARS" is short for "Library Computer Access and Retrieval System". +// Some resources used for writing this skin can be found at +// http://www.lcars.org.uk +// http://www.lcarsdeveloper.com +// http://www.lcarscom.net +// http://lds-jedi.deviantart.com/art/LCARS-Swept-Tutorial-213936938 +// http://lds-jedi.deviantart.com/art/LCARS-Button-Tutorial-210783437 +// http://zelldenver.deviantart.com/art/LCARS-Color-Standard-179565780 +// http://www.lcars47.com +// http://www.bracercom.com/tutorial/content/CoherentLCARSInterface/LCARSCoherentInterface.html +// http://www.bracercom.com/tutorial/content/lcars_manifesto/the_lcars_manifesto.html + +#include "skinlcars.h" +#include "font.h" +#include "menu.h" +#include "osd.h" +#include "themes.h" +#include "videodir.h" + +#include "symbols/arrowdown.xpm" +#include "symbols/arrowup.xpm" +#include "symbols/audio.xpm" +#include "symbols/audioleft.xpm" +#include "symbols/audioright.xpm" +#include "symbols/audiostereo.xpm" +#include "symbols/dolbydigital.xpm" +#include "symbols/encrypted.xpm" +#include "symbols/ffwd.xpm" +#include "symbols/ffwd1.xpm" +#include "symbols/ffwd2.xpm" +#include "symbols/ffwd3.xpm" +#include "symbols/frew.xpm" +#include "symbols/frew1.xpm" +#include "symbols/frew2.xpm" +#include "symbols/frew3.xpm" +#include "symbols/mute.xpm" +#include "symbols/pause.xpm" +#include "symbols/play.xpm" +#include "symbols/radio.xpm" +#include "symbols/recording.xpm" +#include "symbols/sfwd.xpm" +#include "symbols/sfwd1.xpm" +#include "symbols/sfwd2.xpm" +#include "symbols/sfwd3.xpm" +#include "symbols/srew.xpm" +#include "symbols/srew1.xpm" +#include "symbols/srew2.xpm" +#include "symbols/srew3.xpm" +#include "symbols/teletext.xpm" +#include "symbols/volume.xpm" + +#define Gap (Setup.FontOsdSize / 5 & ~1) // must be even +#define TextFrame (Setup.FontOsdSize / TEXT_ALIGN_BORDER) +#define TextSpacing (2 * TextFrame) +#define SymbolSpacing TextSpacing +#define ShowSeenExtent (Setup.FontOsdSize / 5) // pixels by which the "seen" bar extends out of the frame + +#define DISKUSAGEALERTLIMIT 95 // percent of disk usage above which the display goes into alert mode +#define SIGNALDISPLAYDELTA 2 // seconds between subsequent device signal displays + +static cTheme Theme; + +// Color domains: + +#define CLR_BACKGROUND 0x99000000 +#define CLR_MAIN_FRAME 0xFFF1DF6F +#define CLR_CHANNEL_FRAME 0xFFFFCC99 +#define CLR_REPLAY_FRAME 0xFFCC6666 +#define CLR_DATE 0xFF99CCFF +#define CLR_MENU_ITEMS 0xFFFFBC57 +#define CLR_TIMER 0xFF99CCFF +#define CLR_DEVICE 0xFFF1B1AF +#define CLR_CHANNEL_NAME 0xFF99CCFF +#define CLR_EVENT_TITLE 0xFF99CCFF +#define CLR_EVENT_TIME 0xFFFFCC66 +#define CLR_EVENT_SHORTTEXT 0xFFFFCC66 +#define CLR_TEXT 0xFF99CCFF +#define CLR_TRACK 0xFFFFCC66 +#define CLR_SEEN 0xFFCC99CC +#define CLR_ALERT 0xFFFF0000 +#define CLR_EXPOSED 0xFF990000 +#define CLR_WHITE 0xFFFFFFFF +#define CLR_RED 0xFFB20000 +#define CLR_GREEN 0xFF00B200 +#define CLR_YELLOW 0xFFB2B200 +#define CLR_BLUE 0xFF0000B2 +#define CLR_BLACK 0xFF000000 + +// General colors: + +THEME_CLR(Theme, clrBackground, CLR_BACKGROUND); +THEME_CLR(Theme, clrDateFg, CLR_BLACK); +THEME_CLR(Theme, clrDateBg, CLR_DATE); +THEME_CLR(Theme, clrTimerFg, CLR_BLACK); +THEME_CLR(Theme, clrTimerBg, CLR_TIMER); +THEME_CLR(Theme, clrDeviceFg, CLR_BLACK); +THEME_CLR(Theme, clrDeviceBg, CLR_DEVICE); +THEME_CLR(Theme, clrSignalValue, CLR_GREEN); +THEME_CLR(Theme, clrSignalRest, CLR_RED); +THEME_CLR(Theme, clrSeen, CLR_SEEN); +THEME_CLR(Theme, clrTrackName, CLR_TRACK); +THEME_CLR(Theme, clrAlertFg, CLR_WHITE); +THEME_CLR(Theme, clrAlertBg, CLR_ALERT); +THEME_CLR(Theme, clrChannelName, CLR_CHANNEL_NAME); +THEME_CLR(Theme, clrEventTitle, CLR_EVENT_TITLE); +THEME_CLR(Theme, clrEventTime, CLR_EVENT_TIME); +THEME_CLR(Theme, clrEventShortText, CLR_EVENT_SHORTTEXT); +THEME_CLR(Theme, clrEventDescription, CLR_TEXT); + +// Buttons: + +THEME_CLR(Theme, clrButtonRedFg, CLR_WHITE); +THEME_CLR(Theme, clrButtonRedBg, CLR_RED); +THEME_CLR(Theme, clrButtonGreenFg, CLR_BLACK); +THEME_CLR(Theme, clrButtonGreenBg, CLR_GREEN); +THEME_CLR(Theme, clrButtonYellowFg, CLR_BLACK); +THEME_CLR(Theme, clrButtonYellowBg, CLR_YELLOW); +THEME_CLR(Theme, clrButtonBlueFg, CLR_WHITE); +THEME_CLR(Theme, clrButtonBlueBg, CLR_BLUE); + +// Messages: + +THEME_CLR(Theme, clrMessageStatusFg, CLR_WHITE); +THEME_CLR(Theme, clrMessageStatusBg, CLR_BLUE); +THEME_CLR(Theme, clrMessageInfoFg, CLR_BLACK); +THEME_CLR(Theme, clrMessageInfoBg, CLR_GREEN); +THEME_CLR(Theme, clrMessageWarningFg, CLR_BLACK); +THEME_CLR(Theme, clrMessageWarningBg, CLR_YELLOW); +THEME_CLR(Theme, clrMessageErrorFg, CLR_WHITE); +THEME_CLR(Theme, clrMessageErrorBg, CLR_RED); + +// Volume: + +THEME_CLR(Theme, clrVolumeFrame, CLR_MAIN_FRAME); +THEME_CLR(Theme, clrVolumeSymbol, CLR_BLACK); +THEME_CLR(Theme, clrVolumeBarUpper, RgbShade(CLR_MAIN_FRAME, -0.2)); +THEME_CLR(Theme, clrVolumeBarLower, CLR_GREEN); + +// Channel display: + +THEME_CLR(Theme, clrChannelFrameFg, CLR_BLACK); +THEME_CLR(Theme, clrChannelFrameBg, CLR_CHANNEL_FRAME); +THEME_CLR(Theme, clrChannelSymbolOn, CLR_BLACK); +THEME_CLR(Theme, clrChannelSymbolOff, RgbShade(CLR_CHANNEL_FRAME, -0.2)); +THEME_CLR(Theme, clrChannelSymbolRecFg, CLR_WHITE); +THEME_CLR(Theme, clrChannelSymbolRecBg, CLR_RED); + +// Menu: + +THEME_CLR(Theme, clrMenuFrameFg, CLR_BLACK); +THEME_CLR(Theme, clrMenuFrameBg, CLR_MAIN_FRAME); +THEME_CLR(Theme, clrMenuTitle, CLR_MAIN_FRAME); +THEME_CLR(Theme, clrMenuMainBracket, CLR_MENU_ITEMS); +THEME_CLR(Theme, clrMenuTimerRecording, CLR_DEVICE); +THEME_CLR(Theme, clrMenuDeviceRecording, CLR_TIMER); +THEME_CLR(Theme, clrMenuItemCurrentFg, CLR_BLACK); +THEME_CLR(Theme, clrMenuItemCurrentBg, CLR_MENU_ITEMS); +THEME_CLR(Theme, clrMenuItemSelectable, CLR_MENU_ITEMS); +THEME_CLR(Theme, clrMenuItemNonSelectable, CLR_TEXT); +THEME_CLR(Theme, clrMenuScrollbarTotal, CLR_MENU_ITEMS); +THEME_CLR(Theme, clrMenuScrollbarShown, CLR_SEEN); +THEME_CLR(Theme, clrMenuScrollbarArrow, CLR_BLACK); +THEME_CLR(Theme, clrMenuText, CLR_TEXT); + +// Replay display: + +THEME_CLR(Theme, clrReplayFrameFg, CLR_BLACK); +THEME_CLR(Theme, clrReplayFrameBg, CLR_REPLAY_FRAME); +THEME_CLR(Theme, clrReplayPosition, CLR_SEEN); +THEME_CLR(Theme, clrReplayJumpFg, CLR_BLACK); +THEME_CLR(Theme, clrReplayJumpBg, CLR_SEEN); +THEME_CLR(Theme, clrReplayProgressSeen, CLR_SEEN); +THEME_CLR(Theme, clrReplayProgressRest, RgbShade(CLR_WHITE, -0.2)); +THEME_CLR(Theme, clrReplayProgressSelected, CLR_EXPOSED); +THEME_CLR(Theme, clrReplayProgressMark, CLR_BLACK); +THEME_CLR(Theme, clrReplayProgressCurrent, CLR_EXPOSED); + +// Track display: + +THEME_CLR(Theme, clrTrackFrameFg, CLR_BLACK); +THEME_CLR(Theme, clrTrackFrameBg, CLR_TRACK); +THEME_CLR(Theme, clrTrackItemFg, CLR_BLACK); +THEME_CLR(Theme, clrTrackItemBg, RgbShade(CLR_TRACK, 0.5)); +THEME_CLR(Theme, clrTrackItemCurrentFg, CLR_BLACK); +THEME_CLR(Theme, clrTrackItemCurrentBg, CLR_TRACK); + +// --- Helper functions ------------------------------------------------------ + +static cOsd *CreateOsd(int Left, int Top, int x0, int y0, int x1, int y1) +{ + cOsd *Osd = cOsdProvider::NewOsd(Left, Top); + int Bpp[] = { 32, 8, 4, 2, 1 }; + tArea Area = { x0, y0, x1, y1, 0 }; + for (unsigned int i = 0; i < sizeof(Bpp) / sizeof(int); i++) { + Area.bpp = Bpp[i]; + if (Osd->CanHandleAreas(&Area, 1) == oeOk) { + Osd->SetAreas(&Area, 1); + break; + } + } + return Osd; +} + +static cFont *CreateTinyFont(int LineHeight) +{ + // Creates a font that is not higher than half of LineHeight. + LineHeight /= 2; + int Height = LineHeight; + for (;;) { + cFont *TinyFont = cFont::CreateFont(Setup.FontOsd, Height); + if (Height < 2 || TinyFont->Height() <= LineHeight) + return TinyFont; + delete TinyFont; + Height -= 1; + } +} + +static bool DrawDeviceData(cOsd *Osd, const cDevice *Device, int x0, int y0, int x1, int y1, int &xs, const cFont *TinyFont, cString &LastDeviceType, cCamSlot *&LastCamSlot, bool Initial) +{ + cString DeviceType = Device->DeviceType(); + cCamSlot *CamSlot = Device->CamSlot(); + if (Initial || strcmp(DeviceType, LastDeviceType) || CamSlot != LastCamSlot) { + const cFont *font = cFont::GetFont(fontOsd); + tColor ColorFg = Theme.Color(clrDeviceFg); + tColor ColorBg = Theme.Color(clrDeviceBg); + Osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, ColorBg); + int x = x0; + // Device number: + cString Nr = itoa(Device->DeviceNumber() + 1); + int w = max(font->Width(Nr), y1 - y0); + Osd->DrawText(x, y0, Nr, ColorFg, ColorBg, font, w, y1 - y0, taCenter); + x += w; + // Device type: + Osd->DrawText(x, y0, DeviceType, ColorFg, ColorBg, TinyFont); + xs = max(xs, x + TinyFont->Width(DeviceType)); + LastDeviceType = DeviceType; + // CAM: + if (CamSlot) { + cString s = cString::sprintf("CAM %d", CamSlot->SlotNumber()); + Osd->DrawText(x, y1 - TinyFont->Height(), s, ColorFg, ColorBg, TinyFont); + xs = max(xs, x + TinyFont->Width(s)); + } + LastCamSlot = CamSlot; + return true; + } + return false; +} + +static void DrawDeviceSignal(cOsd *Osd, const cDevice *Device, int x0, int y0, int x1, int y1, int &LastSignalStrength, int &LastSignalQuality, bool Initial) +{ + int SignalStrength = Device->SignalStrength(); + int SignalQuality = Device->SignalQuality(); + int d = max((y1 - y0) / 10, 1); + int x00 = x0 + d; + int x01 = x1 - d; + int h = (y1 - y0 - 3 * d) / 2; + int w = x01 - x00; + int y00 = y0 + d; + int y01 = y00 + h; + int y03 = y1 - d; + int y02 = y03 - h; + if (SignalStrength >= 0 && (Initial || SignalStrength != LastSignalStrength)) { + int s = SignalStrength * w / 100; + Osd->DrawRectangle(x00, y00, x00 + s - 1, y01 - 1, Theme.Color(clrSignalValue)); + Osd->DrawRectangle(x00 + s, y00, x01 - 1, y01 - 1, Theme.Color(clrSignalRest)); + LastSignalStrength = SignalStrength; + } + if (SignalQuality >= 0 && (Initial || SignalQuality != LastSignalQuality)) { + int q = SignalQuality * w / 100; + Osd->DrawRectangle(x00, y02, x00 + q - 1, y03 - 1, Theme.Color(clrSignalValue)); + Osd->DrawRectangle(x00 + q, y02, x01 - 1, y03 - 1, Theme.Color(clrSignalRest)); + LastSignalQuality = SignalQuality; + } +} + +// --- cSkinLCARSDisplayChannel ---------------------------------------------- + +class cSkinLCARSDisplayChannel : public cSkinDisplayChannel { +private: + cOsd *osd; + int xc00, xc01, xc02, xc03, xc04, xc05, xc06, xc07, xc08, xc09, xc10, xc11, xc12, xc13, xc14, xc15; + int yc00, yc01, yc02, yc03, yc04, yc05, yc06, yc07, yc08, yc09, yc10, yc11, yc12; + int xs; // starting column for signal display + bool withInfo; + int lineHeight; + cFont *tinyFont; + cFont *tallFont; + tColor frameColor; + bool message; + const cEvent *present; + bool initial; + cString lastDate; + int lastSeen; + int lastDeviceNumber; + cString lastDeviceType; + cCamSlot *lastCamSlot; + int lastSignalStrength; + int lastSignalQuality; + time_t lastSignalDisplay; + tTrackId lastTrackId; + static cBitmap bmTeletext, bmRadio, bmAudio, bmDolbyDigital, bmEncrypted, bmRecording; + void DrawDate(void); + void DrawTrack(void); + void DrawSeen(int Current, int Total); + void DrawDevice(void); + void DrawSignal(void); +public: + cSkinLCARSDisplayChannel(bool WithInfo); + virtual ~cSkinLCARSDisplayChannel(); + virtual void SetChannel(const cChannel *Channel, int Number); + virtual void SetEvents(const cEvent *Present, const cEvent *Following); + virtual void SetMessage(eMessageType Type, const char *Text); + virtual void Flush(void); + }; + +cBitmap cSkinLCARSDisplayChannel::bmTeletext(teletext_xpm); +cBitmap cSkinLCARSDisplayChannel::bmRadio(radio_xpm); +cBitmap cSkinLCARSDisplayChannel::bmAudio(audio_xpm); +cBitmap cSkinLCARSDisplayChannel::bmDolbyDigital(dolbydigital_xpm); +cBitmap cSkinLCARSDisplayChannel::bmEncrypted(encrypted_xpm); +cBitmap cSkinLCARSDisplayChannel::bmRecording(recording_xpm); + +cSkinLCARSDisplayChannel::cSkinLCARSDisplayChannel(bool WithInfo) +{ + tallFont = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize * 1.8); + initial = true; + present = NULL; + lastSeen = -1; + lastDeviceNumber = -1; + lastCamSlot = NULL; + lastSignalStrength = -1; + lastSignalQuality = -1; + lastSignalDisplay = 0; + memset(&lastTrackId, 0, sizeof(lastTrackId)); + const cFont *font = cFont::GetFont(fontOsd); + withInfo = WithInfo; + lineHeight = font->Height(); + tinyFont = CreateTinyFont(lineHeight); + frameColor = Theme.Color(clrChannelFrameBg); + message = false; + int d = 5 * lineHeight; + xc00 = 0; + xc01 = xc00 + d / 2; + xc02 = xc00 + d; + xc03 = xc02 + lineHeight; + xc04 = xc02 + d / 4; + xc05 = xc02 + d; + xc06 = xc05 + Gap; + xc15 = cOsd::OsdWidth(); + xc14 = xc15 - lineHeight; + xc13 = xc14 - Gap; + xc07 = (xc15 + xc00) / 2; + xc08 = xc07 + Gap; + xc09 = xc08 + lineHeight; + xc10 = xc09 + Gap; + xc11 = (xc10 + xc13 + Gap) / 2; + xc12 = xc11 + Gap; + + yc00 = 0; + yc01 = yc00 + lineHeight; + yc02 = yc01 + lineHeight; + yc03 = yc02 + Gap; + yc04 = yc03 + 2 * lineHeight; + yc05 = yc04 + Gap; + yc06 = yc05 + 2 * lineHeight; + + yc07 = yc06 + Gap; + yc12 = yc07 + 3 * lineHeight + Gap / 2; + yc11 = yc12 - lineHeight; + yc10 = yc11 - lineHeight; + yc09 = yc11 - d / 4; + yc08 = yc12 - d / 2; + + xs = 0; + + int y1 = withInfo ? yc12 : yc02; + int y0 = cOsd::OsdTop() + (Setup.ChannelInfoPos ? 0 : cOsd::OsdHeight() - y1); + osd = CreateOsd(cOsd::OsdLeft(), y0, xc00, yc00, xc15 - 1, y1 - 1); + osd->DrawRectangle(xc00, yc00, xc15 - 1, y1 - 1, Theme.Color(clrBackground)); + // Rectangles: + osd->DrawRectangle(xc00, yc00, xc02 - 1, yc02 - 1, frameColor); + if (withInfo) { + osd->DrawRectangle(xc00, yc03, xc02 - 1, yc04 - 1, frameColor); + osd->DrawRectangle(xc00, yc05, xc02 - 1, yc06 - 1, frameColor); + // Elbow: + osd->DrawRectangle(xc00, yc07, xc01 - 1, yc08 - 1, frameColor); + osd->DrawRectangle(xc00, yc08, xc01 - 1, yc12 - 1, clrTransparent); + osd->DrawEllipse (xc00, yc08, xc01 - 1, yc12 - 1, frameColor, 3); + osd->DrawRectangle(xc01, yc07, xc02 - 1, yc12 - 1, frameColor); + osd->DrawEllipse (xc02, yc09, xc04 - 1, yc11 - 1, frameColor, -3); + osd->DrawRectangle(xc02, yc11, xc05 - 1, yc12 - 1, frameColor); + // Status area: + osd->DrawRectangle(xc06, yc11 + lineHeight / 2, xc07 - 1, yc12 - 1, frameColor); + osd->DrawRectangle(xc08, yc11, xc09 - 1, yc12 - 1, frameColor); + osd->DrawRectangle(xc10, yc11, xc11 - 1, yc12 - 1, Theme.Color(clrDeviceBg)); + osd->DrawRectangle(xc12, yc11, xc13 - 1, yc12 - 1, Theme.Color(clrDateBg)); + osd->DrawRectangle(xc14, yc11, xc14 + lineHeight / 2 - 1, yc12 - 1, frameColor); + osd->DrawRectangle(xc14 + lineHeight / 2, yc11 + lineHeight / 2, xc15 - 1, yc12 - 1, clrTransparent); + osd->DrawEllipse (xc14 + lineHeight / 2, yc11, xc15 - 1, yc12 - 1, frameColor, 5); + } + // Icons: + osd->DrawRectangle(xc14, yc00, xc14 + lineHeight / 2 - 1, yc01 - 1, frameColor); + osd->DrawRectangle(xc14 + lineHeight / 2, yc00, xc15 - 1, yc00 + lineHeight / 2 - 1, clrTransparent); + osd->DrawEllipse (xc14 + lineHeight / 2, yc00, xc15 - 1, yc01 - 1, frameColor, 5); +} + +cSkinLCARSDisplayChannel::~cSkinLCARSDisplayChannel() +{ + delete tallFont; + delete tinyFont; + delete osd; +} + +void cSkinLCARSDisplayChannel::DrawDate(void) +{ + cString s = DayDateTime(); + if (initial || strcmp(s, lastDate)) { + osd->DrawText(xc12, yc11, s, Theme.Color(clrDateFg), Theme.Color(clrDateBg), cFont::GetFont(fontOsd), xc13 - xc12, lineHeight, taRight | taBorder); + lastDate = s; + } +} + +void cSkinLCARSDisplayChannel::DrawTrack(void) +{ + cDevice *Device = cDevice::PrimaryDevice(); + const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack()); + if (!Track && *lastTrackId.description || Track && strcmp(lastTrackId.description, Track->description)) { + osd->DrawText(xc03, yc07, Track ? Track->description : "", Theme.Color(clrTrackName), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xc07 - xc03); + strn0cpy(lastTrackId.description, Track ? Track->description : "", sizeof(lastTrackId.description)); + } +} + +void cSkinLCARSDisplayChannel::DrawSeen(int Current, int Total) +{ + int Seen = min(xc07 - xc06, int((xc07 - xc06) * double(Current) / Total)); + if (initial || Seen != lastSeen) { + int y0 = yc11 - ShowSeenExtent; + int y1 = yc11 + lineHeight / 2 - Gap / 2; + osd->DrawRectangle(xc06, y0, xc06 + Seen - 1, y1 - 1, Theme.Color(clrSeen)); + osd->DrawRectangle(xc06 + Seen, y0, xc07 - 1, y1 - 1, Theme.Color(clrBackground)); + lastSeen = Seen; + } +} + +void cSkinLCARSDisplayChannel::DrawDevice(void) +{ + const cDevice *Device = cDevice::ActualDevice(); + if (DrawDeviceData(osd, Device, xc10, yc11, xc11, yc12, xs, tinyFont, lastDeviceType, lastCamSlot, Device->DeviceNumber() != lastDeviceNumber)) { + lastDeviceNumber = Device->DeviceNumber(); + // Make sure signal meters are redrawn: + lastSignalStrength = -1; + lastSignalQuality = -1; + lastSignalDisplay = 0; + } +} + +void cSkinLCARSDisplayChannel::DrawSignal(void) +{ + time_t Now = time(NULL); + if (Now != lastSignalDisplay) { + DrawDeviceSignal(osd, cDevice::ActualDevice(), xs + lineHeight / 2, yc11, xc11, yc12, lastSignalStrength, lastSignalQuality, initial); + lastSignalDisplay = Now; + } +} + +void cSkinLCARSDisplayChannel::SetChannel(const cChannel *Channel, int Number) +{ + int x = xc13; + int xi = x - SymbolSpacing - + bmRecording.Width() - SymbolSpacing - + bmEncrypted.Width() - SymbolSpacing - + bmDolbyDigital.Width() - SymbolSpacing - + bmAudio.Width() - SymbolSpacing - + max(bmTeletext.Width(), bmRadio.Width()) - SymbolSpacing; + osd->DrawRectangle(xi, yc00, xc13 - 1, yc01 - 1, frameColor); + if (Channel && !Channel->GroupSep()) { + bool rec = cRecordControls::Active(); + x -= bmRecording.Width() + SymbolSpacing; + osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmRecording.Height()) / 2, bmRecording, Theme.Color(rec ? clrChannelSymbolRecFg : clrChannelSymbolOff), rec ? Theme.Color(clrChannelSymbolRecBg) : frameColor); + x -= bmEncrypted.Width() + SymbolSpacing; + osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmEncrypted.Height()) / 2, bmEncrypted, Theme.Color(Channel->Ca() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor); + x -= bmDolbyDigital.Width() + SymbolSpacing; + osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmDolbyDigital.Height()) / 2, bmDolbyDigital, Theme.Color(Channel->Dpid(0) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor); + x -= bmAudio.Width() + SymbolSpacing; + osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmAudio.Height()) / 2, bmAudio, Theme.Color(Channel->Apid(1) ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor); + if (Channel->Vpid()) { + x -= bmTeletext.Width() + SymbolSpacing; + osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmTeletext.Height()) / 2, bmTeletext, Theme.Color(Channel->Tpid() ? clrChannelSymbolOn : clrChannelSymbolOff), frameColor); + } + else if (Channel->Apid(0)) { + x -= bmRadio.Width() + SymbolSpacing; + osd->DrawBitmap(x, yc00 + (yc01 - yc00 - bmRadio.Height()) / 2, bmRadio, Theme.Color(clrChannelSymbolOn), frameColor); + } + } + cString ChNumber(""); + cString ChName(""); + if (Channel) { + ChName = Channel->Name(); + if (!Channel->GroupSep()) + ChNumber = cString::sprintf("%d%s", Channel->Number(), Number ? "-" : ""); + } + else if (Number) + ChNumber = cString::sprintf("%d-", Number); + else + ChName = ChannelString(NULL, NULL); + osd->DrawText(xc00, yc00, ChNumber, Theme.Color(clrChannelFrameFg), frameColor, tallFont, xc02 - xc00, yc02 - yc00, taTop | taRight | taBorder); + osd->DrawText(xc03, yc00, ChName, Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xi - xc03 - lineHeight, 0, taTop | taLeft); + lastSignalDisplay = 0; + if (withInfo) + DrawDevice(); +} + +void cSkinLCARSDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following) +{ + if (!withInfo) + return; + if (present != Present) + lastSeen = -1; + present = Present; + for (int i = 0; i < 2; i++) { + const cEvent *e = !i ? Present : Following; + int y = !i ? yc03 : yc05; + if (e) { + osd->DrawText(xc00, y, e->GetTimeString(), Theme.Color(clrChannelFrameFg), frameColor, cFont::GetFont(fontOsd), xc02 - xc00, 0, taRight | taBorder); + osd->DrawText(xc03, y, e->Title(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xc13 - xc03); + osd->DrawText(xc03, y + lineHeight, e->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xc13 - xc03); + } + else { + osd->DrawRectangle(xc00, y, xc02 - 1, y + lineHeight, frameColor); + osd->DrawRectangle(xc02, y, xc13 - 1, y + 2 * lineHeight, Theme.Color(clrBackground)); + } + } +} + +void cSkinLCARSDisplayChannel::SetMessage(eMessageType Type, const char *Text) +{ + if (Text) { + int y0 = yc11 - ShowSeenExtent; + int y1 = yc11; + osd->SaveRegion(xc06, y0, xc13 - 1, yc12 - 1); + osd->DrawRectangle(xc06, y0, xc07, y1 - 1, Theme.Color(clrBackground)); // clears the "seen" bar + osd->DrawText(xc06, yc11, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xc13 - xc06, yc12 - yc11, taCenter); + } + else + osd->RestoreRegion(); +} + +void cSkinLCARSDisplayChannel::Flush(void) +{ + if (withInfo) { + if (!message) { + DrawDate(); + DrawTrack(); + DrawDevice(); + DrawSignal(); + } + int Current = 0; + int Total = 0; + if (present) { + time_t t = time(NULL); + if (t > present->StartTime()) + Current = t - present->StartTime(); + Total = present->Duration(); + } + DrawSeen(Current, Total); + } + osd->Flush(); + initial = false; +} + +// --- cSkinLCARSDisplayMenu ------------------------------------------------- + +class cSkinLCARSDisplayMenu : public cSkinDisplayMenu { +private: + cOsd *osd; + int xa00, xa01, xa02, xa03, xa04, xa05, xa06, xa07, xa08, xa09; + int yt00, yt01, yt02, yt03, yt04, yt05, yt06; + int yc00, yc01, yc02, yc03, yc04, yc05, yc06, yc07, yc08, yc09, yc10, yc11; + int yb00, yb01, yb02, yb03, yb04, yb05, yb06, yb07, yb08, yb09, yb10, yb11, yb12, yb13, yb14, yb15; + int xm00, xm01, xm02, xm03, xm04, xm05, xm06, xm07, xm08; + int ym00, ym01, ym02, ym03, ym04, ym05, ym06, ym07; + int xs00, xs01, xs02, xs03, xs04, xs05, xs06, xs07, xs08, xs09, xs10, xs11, xs12, xs13; + int ys00, ys01, ys02, ys03, ys04, ys05; + int xi00, xi01, xi02, xi03; + int yi00, yi01; + int xb00, xb01, xb02, xb03, xb04, xb05, xb06, xb07, xb08, xb09, xb10, xb11, xb12, xb13, xb14, xb15; + int xd00, xd01, xd02, xd03, xd04, xd05, xd06, xd07; + int yd00, yd01, yd02, yd03, yd04, yd05; + int xs; // starting column for signal display + int lineHeight; + cFont *tinyFont; + cFont *tallFont; + tColor frameColor; + int currentIndex; + cVector<int> deviceOffset; + cVector<bool> deviceRecording; + cString lastDeviceType[MAXDEVICES]; + cVector<cCamSlot *> lastCamSlot; + cVector<int> lastSignalStrength; + cVector<int> lastSignalQuality; + bool initial; + enum eCurrentMode { cmUnknown, cmLive, cmPlay }; + eCurrentMode lastMode; + cString lastDate; + int lastDiskUsageState; + bool lastDiskAlert; + double lastSystemLoad; + int lastTimersState; + time_t lastSignalDisplay; + int lastLiveIndicatorY; + bool lastLiveIndicatorTransferring; + const cChannel *lastChannel; + const cEvent *lastEvent; + const cRecording *lastRecording; + cString lastHeader; + int lastSeen; + static cBitmap bmArrowUp, bmArrowDown, bmTransferMode; + void DrawMainFrameUpper(tColor Color); + void DrawMainFrameLower(void); + void DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font); + void DrawMenuFrame(void); + void DrawMainBracket(void); + void DrawStatusElbows(void); + void DrawDate(void); + void DrawDisk(void); + void DrawLoad(void); + void DrawFrameDisplay(void); + void DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown); + void DrawTimer(const cTimer *Timer, int y, bool MultiRec); + void DrawTimers(void); + void DrawDevice(const cDevice *Device); + void DrawDevices(void); + void DrawLiveIndicator(void); + void DrawSignals(void); + void DrawLive(const cChannel *Channel); + void DrawPlay(cControl *Control); + void DrawInfo(const cEvent *Event, bool WithTime); + void DrawSeen(int Current, int Total); + void DrawTextScrollbar(void); +public: + cSkinLCARSDisplayMenu(void); + virtual ~cSkinLCARSDisplayMenu(); + virtual void Scroll(bool Up, bool Page); + virtual int MaxItems(void); + virtual void Clear(void); + virtual void SetMenuCategory(eMenuCategory MenuCategory); + virtual void SetTitle(const char *Title); + virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL); + virtual void SetMessage(eMessageType Type, const char *Text); + virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable); + virtual void SetScrollbar(int Total, int Offset); + virtual void SetEvent(const cEvent *Event); + virtual void SetRecording(const cRecording *Recording); + virtual void SetText(const char *Text, bool FixedFont); + virtual int GetTextAreaWidth(void) const; + virtual const cFont *GetTextAreaFont(bool FixedFont) const; + virtual void Flush(void); + }; + +cBitmap cSkinLCARSDisplayMenu::bmArrowUp(arrowup_xpm); +cBitmap cSkinLCARSDisplayMenu::bmArrowDown(arrowdown_xpm); +cBitmap cSkinLCARSDisplayMenu::bmTransferMode(play_xpm); + +cSkinLCARSDisplayMenu::cSkinLCARSDisplayMenu(void) +{ + tallFont = cFont::CreateFont(Setup.FontOsd, Setup.FontOsdSize * 1.8); + initial = true; + lastMode = cmUnknown; + lastChannel = NULL; + lastEvent = NULL; + lastRecording = NULL; + lastSeen = -1; + lastTimersState = -1; + lastSignalDisplay = 0; + lastLiveIndicatorY = -1; + lastLiveIndicatorTransferring = false; + lastDiskUsageState = -1; + lastDiskAlert = false; + lastSystemLoad = -1; + const cFont *font = cFont::GetFont(fontOsd); + lineHeight = font->Height(); + tinyFont = CreateTinyFont(lineHeight); + frameColor = Theme.Color(clrMenuFrameBg); + currentIndex = -1; + // The outer frame: + int d = 5 * lineHeight; + xa00 = 0; + xa01 = xa00 + d / 2; + xa02 = xa00 + d; + xa03 = xa02 + lineHeight; + xa04 = xa02 + d / 4; + xa05 = xa02 + d; + xa06 = xa05 + Gap; + xa09 = cOsd::OsdWidth(); + xa08 = xa09 - lineHeight; + xa07 = xa08 - Gap; + + yt00 = 0; + yt01 = yt00 + lineHeight; + yt02 = yt01 + lineHeight; + yt03 = yt01 + d / 4; + yt04 = yt02 + Gap; + yt05 = yt00 + d / 2; + yt06 = yt04 + 2 * lineHeight; + + yc00 = yt06 + Gap; + yc05 = yc00 + 3 * lineHeight + Gap / 2; + yc04 = yc05 - lineHeight; + yc03 = yc04 - lineHeight; + yc02 = yc04 - d / 4; + yc01 = yc05 - d / 2; + + yc06 = yc05 + Gap; + yc07 = yc06 + lineHeight; + yc08 = yc07 + lineHeight; + yc09 = yc07 + d / 4; + yc10 = yc06 + d / 2; + yc11 = yc06 + 3 * lineHeight + Gap / 2; + + yb00 = yc11 + Gap; + yb01 = yb00 + 2 * lineHeight; + yb02 = yb01 + Gap; + yb03 = yb02 + 2 * lineHeight; + yb04 = yb03 + Gap; + yb05 = yb04 + 2 * lineHeight; + yb06 = yb05 + Gap; + yb07 = yb06 + 2 * lineHeight; + yb08 = yb07 + Gap; + + yb15 = cOsd::OsdHeight(); + yb14 = yb15 - lineHeight; + yb13 = yb14 - lineHeight; + yb12 = yb14 - d / 4; + yb11 = yb15 - d / 2; + yb10 = yb13 - Gap - 2 * lineHeight; + yb09 = yb10 - Gap; + + // Compensate for large font size: + if (yb09 - yb08 < 2 * lineHeight) { + yb08 = yb06; + yb06 = 0; // drop empty rectangle + } + if (yb09 - yb08 < 2 * lineHeight) { + yb05 = yb09; + yb08 = 0; // drop "LCARS" display + } + if (yb05 - yb04 < 2 * lineHeight) { + yb03 = yb09; + yb04 = 0; // drop "LOAD" display + } + if (yb03 - yb02 < 2 * lineHeight) { + yb01 = yb09; + yb02 = 0; // drop "DISK" display + } + // Anything else is just insanely large... + + // The main command menu: + xm00 = xa03; + xm01 = xa05; + xm02 = xa06; + xm08 = (xa09 + xa00) / 2; + xm07 = xm08 - lineHeight; + xm06 = xm07 - lineHeight / 2; + xm05 = xm06 - lineHeight / 2; + xm04 = xm05 - lineHeight; + xm03 = xm04 - Gap; + ym00 = yc08; + ym01 = ym00 + lineHeight / 2; + ym02 = ym01 + lineHeight / 2; + ym03 = ym02 + Gap; + ym07 = yb15; + ym06 = ym07 - lineHeight / 2; + ym05 = ym06 - lineHeight / 2; + ym04 = ym05 - Gap; + + // The status area: + xs00 = xm08 + Gap + lineHeight + Gap; + xs13 = xa09; + xs12 = xa08; + xs11 = xa07; + xs05 = (xs00 + xs11 + Gap) / 2; + xs04 = xs05 - lineHeight / 2; + xs03 = xs04 - lineHeight / 2; + xs02 = xs03 - 2 * lineHeight; + xs01 = xs02 - Gap; + xs06 = xs05 + Gap; + xs07 = xs06 + lineHeight / 2; + xs08 = xs07 + lineHeight / 2; + xs09 = xs08 + 2 * lineHeight; + xs10 = xs09 + Gap; + ys00 = yc06; + ys01 = ys00 + lineHeight; + ys02 = ys01 + lineHeight / 2; + ys04 = ys01 + lineHeight; + ys03 = ys04 - Gap; + ys05 = yb15; + + // The color buttons in submenus: + xb00 = xa06; + xb15 = xa07; + int w = (xa08 - xa06) / 4; + xb01 = xb00 + lineHeight / 2; + xb02 = xb01 + Gap; + xb04 = xb00 + w; + xb03 = xb04 - Gap; + xb05 = xb04 + lineHeight / 2; + xb06 = xb05 + Gap; + xb08 = xb04 + w; + xb07 = xb08 - Gap; + xb09 = xb08 + lineHeight / 2; + xb10 = xb09 + Gap; + xb12 = xb08 + w; + xb11 = xb12 - Gap; + xb13 = xb12 + lineHeight / 2; + xb14 = xb13 + Gap;; + + // The color buttons in the main menu: + int r = lineHeight; + xd07 = xa09; + xd06 = xd07 - r; + xd05 = xd06 - 4 * r; + xd04 = xd05 - r; + xd03 = xd04 - Gap; + xd02 = xd03 - r; + xd01 = xd02 - 4 * r; + xd00 = xd01 - r; + yd00 = yt00; + yd05 = yc04 - Gap; + yd04 = yd05 - 2 * r; + yd03 = yd04 - Gap; + yd02 = yd03 - 2 * r; + yd01 = yd02 - Gap; + + xs = 0; + + osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop(), xa00, yt00, xa09 - 1, yb15 - 1); +} + +cSkinLCARSDisplayMenu::~cSkinLCARSDisplayMenu() +{ + delete tallFont; + delete tinyFont; + delete osd; +} + +void cSkinLCARSDisplayMenu::SetMenuCategory(eMenuCategory MenuCategory) +{ + if (initial || MenuCategory != cSkinDisplayMenu::MenuCategory()) { + cSkinDisplayMenu::SetMenuCategory(MenuCategory); + initial = true; + osd->DrawRectangle(xa00, yt00, xa09 - 1, yb15 - 1, Theme.Color(clrBackground)); + if (MenuCategory == mcMain) { + yi00 = ym03; + yi01 = ym04; + xi00 = xm00; + xi01 = xm03; + xi02 = xm04; + xi03 = xm05; + lastTimersState = -1; + DrawMainFrameLower(); + DrawMainBracket(); + DrawStatusElbows(); + } + else { + yi00 = yt02; + yi01 = yb13; + xi00 = xa03; + xi01 = xa07; + xi02 = xa08; + xi03 = xa09; + DrawMenuFrame(); + } + } +} + +void cSkinLCARSDisplayMenu::DrawMainFrameUpper(tColor Color) +{ + // Top left rectangles: + osd->DrawRectangle(xa00, yt00, xa02 - 1, yt02 - 1, Color); + osd->DrawRectangle(xa00, yt04, xa02 - 1, yt06 - 1, Color); + // Upper elbow: + osd->DrawRectangle(xa00, yc00, xa01 - 1, yc01 - 1, Color); + osd->DrawEllipse (xa00, yc01, xa01 - 1, yc05 - 1, Color, 3); + osd->DrawRectangle(xa01, yc00, xa02 - 1, yc05 - 1, Color); + osd->DrawEllipse (xa02, yc02, xa04 - 1, yc04 - 1, Color, -3); + osd->DrawRectangle(xa02, yc04, xa05 - 1, yc05 - 1, Color); + // Upper delimiter: + osd->DrawRectangle(xa06, yc04 + lineHeight / 2, xm08 - 1, yc05 - 1, Color); + osd->DrawRectangle(xm08 + Gap, yc04, xs00 - Gap - 1, yc05 - 1, Color); + osd->DrawRectangle(xs00, yc04, xs05 - 1, yc05 - 1, Color); + osd->DrawRectangle(xs06, yc04, xa07 - 1, yc05 - 1, Color); + osd->DrawRectangle(xa08, yc04, xa09 - 1, yc05 - 1, Color); +} + +void cSkinLCARSDisplayMenu::DrawMainFrameLower(void) +{ + const cFont *font = cFont::GetFont(fontOsd); + // Lower elbow: + osd->DrawRectangle(xa00, yc10, xa01 - 1, yc11 - 1, frameColor); + osd->DrawEllipse (xa00, yc06, xa01 - 1, yc10 - 1, frameColor, 2); + osd->DrawRectangle(xa01, yc06, xa02 - 1, yc11 - 1, frameColor); + osd->DrawEllipse (xa02, yc07, xa04 - 1, yc09 - 1, frameColor, -2); + osd->DrawRectangle(xa02, yc06, xa05 - 1, yc07 - 1, frameColor); + // Lower delimiter: + osd->DrawRectangle(xa06, yc06, xm08 - 1, yc07 - lineHeight / 2 - 1, frameColor); + osd->DrawRectangle(xm08 + Gap, yc06, xs00 - Gap - 1, yc07 - 1, frameColor); + osd->DrawRectangle(xa08, yc06, xa09 - 1, yc07 - 1, frameColor); + // VDR version: + osd->DrawRectangle(xa00, yb10, xa02 - 1, yb15 - 1, frameColor); + osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder); + osd->DrawText(xa00, yb15 - lineHeight, VDRVERSION, Theme.Color(clrMenuFrameFg), frameColor, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder); +} + +void cSkinLCARSDisplayMenu::DrawMainButton(const char *Text, int x0, int x1, int x2, int x3, int y0, int y1, tColor ColorFg, tColor ColorBg, const cFont *Font) +{ + int h = y1 - y0; + osd->DrawEllipse(x0, y0, x1 - 1, y1 - 1, ColorBg, 7); + osd->DrawText(x1 + Gap, y0, Text, ColorFg, ColorBg, Font, x2 - x1 - Gap, h, taBottom | taRight); + osd->DrawEllipse(x2, y0, x3 - 1, y1 - 1, ColorBg, 5); +} + +void cSkinLCARSDisplayMenu::DrawMenuFrame(void) +{ + // Upper elbow: + osd->DrawRectangle(xa00, yt05, xa01 - 1, yt06 - 1, frameColor); + osd->DrawRectangle(xa00, yt00, xa01 - 1, yt05 - 1, clrTransparent); + osd->DrawEllipse (xa00, yt00, xa01 - 1, yt05 - 1, frameColor, 2); + osd->DrawRectangle(xa01, yt00, xa02 - 1, yt06 - 1, frameColor); + osd->DrawEllipse (xa02, yt01, xa04 - 1, yt03 - 1, frameColor, -2); + osd->DrawRectangle(xa02, yt00, xa05 - 1, yt01 - 1, frameColor); + osd->DrawRectangle(xa06, yt00, xa07 - 1, yt01 - 1, frameColor); + osd->DrawRectangle(xa08, yt00, xa08 + lineHeight / 2 - 1, yt01 - 1, frameColor); + osd->DrawRectangle(xa08 + lineHeight / 2, yt00, xa09 - 1, yt00 + lineHeight / 2 - 1, clrTransparent); + osd->DrawEllipse (xa08 + lineHeight / 2, yt00, xa09 - 1, yt01 - 1, frameColor, 5); + // Center part: + osd->DrawRectangle(xa00, yc00, xa02 - 1, yc11 - 1, frameColor); + // Lower elbow: + osd->DrawRectangle(xa00, yb10, xa02 - 1, yb11 - 1, frameColor); + osd->DrawRectangle(xa00, yb11, xa01 - 1, yb15 - 1, clrTransparent); + osd->DrawEllipse (xa00, yb11, xa01 - 1, yb15 - 1, frameColor, 3); + osd->DrawRectangle(xa01, yb11, xa02 - 1, yb15 - 1, frameColor); + osd->DrawEllipse (xa02, yb12, xa04 - 1, yb14 - 1, frameColor, -3); + osd->DrawRectangle(xa02, yb14, xa05 - 1, yb15 - 1, frameColor); + osd->DrawRectangle(xa08, yb14, xa08 + lineHeight / 2 - 1, yb15 - 1, frameColor); + osd->DrawRectangle(xa08 + lineHeight / 2, yb14 + lineHeight / 2, xa09 - 1, yb15 - 1, clrTransparent); + osd->DrawEllipse (xa08 + lineHeight / 2, yb14, xa09 - 1, yb15 - 1, frameColor, 5); + osd->DrawText(xa00, yb10, "VDR", Theme.Color(clrMenuFrameFg), frameColor, tallFont, xa02 - xa00, yb11 - yb10, taTop | taRight | taBorder); + // Color buttons: + osd->DrawRectangle(xb00, yb14, xb01 - 1, yb15 - 1, Theme.Color(clrButtonRedBg)); + osd->DrawRectangle(xb04, yb14, xb05 - 1, yb15 - 1, Theme.Color(clrButtonGreenBg)); + osd->DrawRectangle(xb08, yb14, xb09 - 1, yb15 - 1, Theme.Color(clrButtonYellowBg)); + osd->DrawRectangle(xb12, yb14, xb13 - 1, yb15 - 1, Theme.Color(clrButtonBlueBg)); +} + +void cSkinLCARSDisplayMenu::DrawDate(void) +{ + cString s = DayDateTime(); + if (initial || strcmp(s, lastDate)) { + const cFont *font = cFont::GetFont(fontOsd); + tColor ColorFg = Theme.Color(clrDateFg); + tColor ColorBg = Theme.Color(clrDateBg); + lastDate = s; + const char *t = strrchr(s, ' '); + osd->DrawText(xa00, yb01 - lineHeight, t, ColorFg, ColorBg, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder); + s.Truncate(t - s); + osd->DrawText(xa00, yb00, s, ColorFg, ColorBg, font, xa02 - xa00, yb01 - yb00 - lineHeight, taTop | taRight | taBorder); + } +} + +void cSkinLCARSDisplayMenu::DrawDisk(void) +{ + if (yb02) { + if (cVideoDiskUsage::HasChanged(lastDiskUsageState) || initial) { // must call HasChanged() first, or it shows an outdated value in the 'initial' case! + const cFont *font = cFont::GetFont(fontOsd); + int DiskUsage = cVideoDiskUsage::UsedPercent(); + bool DiskAlert = DiskUsage > DISKUSAGEALERTLIMIT; + tColor ColorFg = DiskAlert ? Theme.Color(clrAlertFg) : Theme.Color(clrMenuFrameFg); + tColor ColorBg = DiskAlert ? Theme.Color(clrAlertBg) : frameColor; + if (initial || DiskAlert != lastDiskAlert) + osd->DrawText(xa00, yb02, tr("DISK"), ColorFg, ColorBg, tinyFont, xa02 - xa00, yb03 - yb02, taTop | taLeft | taBorder); + osd->DrawText(xa01, yb02, itoa(DiskUsage), ColorFg, ColorBg, font, xa02 - xa01, lineHeight, taBottom | taRight | taBorder); + osd->DrawText(xa00, yb03 - lineHeight, cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60), ColorFg, ColorBg, font, xa02 - xa00, 0, taBottom | taRight | taBorder); + lastDiskAlert = DiskAlert; + } + } +} + +void cSkinLCARSDisplayMenu::DrawLoad(void) +{ + if (yb04) { + tColor ColorFg = Theme.Color(clrMenuFrameFg); + tColor ColorBg = frameColor; + if (initial) + osd->DrawText(xa00, yb04, tr("LOAD"), ColorFg, ColorBg, tinyFont, xa02 - xa00, yb05 - yb04, taTop | taLeft | taBorder); + double SystemLoad; + if (getloadavg(&SystemLoad, 1) > 0) { + if (initial || SystemLoad != lastSystemLoad) { + osd->DrawText(xa00, yb05 - lineHeight, cString::sprintf("%.1f", SystemLoad), ColorFg, ColorBg, cFont::GetFont(fontOsd), xa02 - xa00, lineHeight, taBottom | taRight | taBorder); + lastSystemLoad = SystemLoad; + } + } + } +} + +void cSkinLCARSDisplayMenu::DrawMainBracket(void) +{ + tColor Color = Theme.Color(clrMenuMainBracket); + osd->DrawRectangle(xm00, ym00, xm01 - 1, ym01 - 1, Color); + osd->DrawRectangle(xm02, ym00, xm07 - 1, ym01 - 1, Color); + osd->DrawEllipse (xm07, ym00, xm08 - 1, ym02 - 1, Color, 1); + osd->DrawEllipse (xm06, ym01, xm07 - 1, ym02 - 1, Color, -1); + osd->DrawRectangle(xm07, ym03, xm08 - 1, ym04 - 1, Color); + osd->DrawEllipse (xm06, ym05, xm07 - 1, ym06 - 1, Color, -4); + osd->DrawEllipse (xm07, ym05, xm08 - 1, ym07 - 1, Color, 4); + osd->DrawRectangle(xm02, ym06, xm07 - 1, ym07 - 1, Color); + osd->DrawRectangle(xm00, ym06, xm01 - 1, ym07 - 1, Color); +} + +void cSkinLCARSDisplayMenu::DrawStatusElbows(void) +{ + const cFont *font = cFont::GetFont(fontOsd); + osd->DrawText (xs00, ys00, tr("TIMERS"), Theme.Color(clrMenuFrameFg), frameColor, font, xs01 - xs00, lineHeight, taBottom | taLeft | taBorder); + osd->DrawRectangle(xs02, ys00, xs03 - 1, ys01 - 1, frameColor); + osd->DrawEllipse (xs03, ys00, xs05 - 1, ys01 - 1, frameColor, 1); + osd->DrawEllipse (xs03, ys01, xs04 - 1, ys02 - 1, frameColor, -1); + osd->DrawRectangle(xs04, ys01, xs05 - 1, ys03 - 1, frameColor); + osd->DrawRectangle(xs04, ys04, xs05 - 1, ys05 - 1, frameColor); + osd->DrawText (xs10, ys00, tr("DEVICES"), Theme.Color(clrMenuFrameFg), frameColor, font, xs11 - xs10, lineHeight, taBottom | taRight | taBorder); + osd->DrawRectangle(xs08, ys00, xs09 - 1, ys01 - 1, frameColor); + osd->DrawEllipse (xs06, ys00, xs08 - 1, ys01 - 1, frameColor, 2); + osd->DrawEllipse (xs07, ys01, xs08 - 1, ys02 - 1, frameColor, -2); + osd->DrawRectangle(xs06, ys01, xs07 - 1, ys03 - 1, frameColor); + osd->DrawRectangle(xs06, ys04, xs07 - 1, ys05 - 1, frameColor); + osd->DrawRectangle(xs12, ys00, xs13 - 1, ys01 - 1, frameColor); +} + +void cSkinLCARSDisplayMenu::DrawFrameDisplay(void) +{ + DrawDate(); + DrawDisk(); + DrawLoad(); + if (initial) { + if (yb06) + osd->DrawRectangle(xa00, yb06, xa02 - 1, yb07 - 1, frameColor); + if (yb08) { + const cFont *font = cFont::GetFont(fontOsd); + osd->DrawRectangle(xa00, yb08, xa02 - 1, yb09 - 1, frameColor); + osd->DrawText(xa00, yb09 - lineHeight, "LCARS", Theme.Color(clrMenuFrameFg), frameColor, font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder); + } + } +} + +void cSkinLCARSDisplayMenu::DrawScrollbar(int Total, int Offset, int Shown, bool CanScrollUp, bool CanScrollDown) +{ + int x0, x1, tt, tb; + tColor ClearColor; + if (MenuCategory() == mcMain) { + x0 = xm07; + x1 = xm08; + tt = ym03; + tb = ym04; + ClearColor = Theme.Color(clrMenuMainBracket); + } + else { + x0 = xa02 + Gap; + x1 = x0 + lineHeight / 2; + tt = yc00; + tb = yc11; + ClearColor = Theme.Color(clrBackground); + int d = TextFrame; + if (CanScrollUp) + osd->DrawBitmap(xa02 - bmArrowUp.Width() - d, yc00 + d, bmArrowUp, Theme.Color(clrMenuScrollbarArrow), frameColor); + else + osd->DrawRectangle(xa02 - bmArrowUp.Width() - d, yc00 + d, xa02 - d - 1, yc00 + d + bmArrowUp.Height() - 1, frameColor); + if (CanScrollDown) + osd->DrawBitmap(xa02 - bmArrowDown.Width() - d, yc11 - d - bmArrowDown.Height(), bmArrowDown, Theme.Color(clrMenuScrollbarArrow), frameColor); + else + osd->DrawRectangle(xa02 - bmArrowDown.Width() - d, yc11 - d - bmArrowDown.Height(), xa02 - d - 1, yc11 - d - 1, frameColor); + } + if (Total > 0 && Total > Shown) { + int sw = x1 - x0; + int sh = max(int((tb - tt) * double(Shown) / Total + 0.5), sw); + int st = min(int(tt + (tb - tt) * double(Offset) / Total + 0.5), tb - sh); + int sb = min(st + sh, tb); + osd->DrawRectangle(x0, tt, x1 - 1, tb - 1, Theme.Color(clrMenuScrollbarTotal)); + osd->DrawRectangle(x0, st, x1 - 1, sb - 1, Theme.Color(clrMenuScrollbarShown)); + } + else if (MenuCategory() != mcMain) + osd->DrawRectangle(x0, tt, x1 - 1, tb - 1, ClearColor); +} + +void cSkinLCARSDisplayMenu::DrawTimer(const cTimer *Timer, int y, bool MultiRec) +{ + // The timer data: + bool Alert = !Timer->Recording() && Timer->Pending(); + tColor ColorFg = Alert ? Theme.Color(clrAlertFg) : Theme.Color(clrTimerFg); + tColor ColorBg = Alert ? Theme.Color(clrAlertFg) : Theme.Color(clrTimerBg); + osd->DrawRectangle(xs00, y, xs03 - 1, y + lineHeight - 1, ColorBg); + cString Date; + if (Timer->Recording()) + Date = cString::sprintf("-%s", *TimeString(Timer->StopTime())); + else { + time_t Now = time(NULL); + cString Today = WeekDayName(Now); + cString Time = TimeString(Timer->StartTime()); + cString Day = WeekDayName(Timer->StartTime()); + if (Timer->StartTime() > Now + 6 * SECSINDAY) + Date = DayDateTime(Timer->StartTime()); + else if (strcmp(Day, Today) != 0) + Date = cString::sprintf("%s %s", *Day, *Time); + else + Date = Time; + } + if (Timer->Flags() & tfVps) + Date = cString::sprintf("VPS %s", *Date); + const cChannel *Channel = Timer->Channel(); + const cEvent *Event = Timer->Event(); + int d = max(TextFrame / 2, 1); + if (Channel) { + osd->DrawText(xs00 + d, y, Channel->Name(), ColorFg, ColorBg, tinyFont, xs03 - xs00 - d); + osd->DrawText(xs03 - tinyFont->Width(Date) - d, y, Date, ColorFg, ColorBg, tinyFont); + } + if (Event) + osd->DrawText(xs00 + d, y + lineHeight - tinyFont->Height(), Event->Title(), ColorFg, ColorBg, tinyFont, xs03 - xs00 - 2 * d); + // The timer recording indicator: + if (Timer->Recording()) + osd->DrawRectangle(xs03 + Gap, y - (MultiRec ? Gap : 0), xs04 - Gap / 2 - 1, y + lineHeight - 1, Theme.Color(clrMenuTimerRecording)); +} + +void cSkinLCARSDisplayMenu::DrawTimers(void) +{ + if (Timers.Modified(lastTimersState)) { + deviceRecording.Clear(); + const cFont *font = cFont::GetFont(fontOsd); + osd->DrawRectangle(xs00, ys04, xs04 - 1, ys05 - 1, Theme.Color(clrBackground)); + osd->DrawRectangle(xs07, ys04, xs13 - 1, ys05 - 1, Theme.Color(clrBackground)); + cSortedTimers SortedTimers; + cVector<int> FreeDeviceSlots; + int y = ys04; + // Timers and recording devices: + while (1) { + int NumTimers = 0; + const cDevice *Device = NULL; + for (int i = 0; i < SortedTimers.Size(); i++) { + if (y + lineHeight > ys05) + break; + if (const cTimer *Timer = SortedTimers[i]) { + if (Timer->Recording()) { + if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(Timer)) { + if (!Device || Device == RecordControl->Device()) { + DrawTimer(Timer, y, NumTimers > 0); + NumTimers++; + if (!Device) { + Device = RecordControl->Device(); + deviceOffset[Device->DeviceNumber()] = y; + deviceRecording[Device->DeviceNumber()] = true; + } + else + FreeDeviceSlots.Append(y); + y += lineHeight + Gap; + } + else + continue; + } + SortedTimers[i] = NULL; + } + else if (!Device) { + DrawTimer(Timer, y, false); + FreeDeviceSlots.Append(y); + y += lineHeight + Gap; + SortedTimers[i] = NULL; + } + } + } + if (!Device) + break; + } + // Devices currently not recording: + int Slot = 0; + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (const cDevice *Device = cDevice::GetDevice(i)) { + if (!deviceRecording[Device->DeviceNumber()]) { + if (Slot < FreeDeviceSlots.Size()) { + y = FreeDeviceSlots[Slot]; + Slot++; + } + if (y + lineHeight > ys05) + break; + deviceOffset[Device->DeviceNumber()] = y; + y += lineHeight + Gap; + } + } + } + osd->DrawText(xs02, ys00, itoa(Timers.Count()), Theme.Color(clrMenuFrameFg), frameColor, font, xs03 - xs02, ys01 - ys00, taBottom | taLeft | taBorder); + osd->DrawText(xs08, ys00, itoa(cDevice::NumDevices()), Theme.Color(clrMenuFrameFg), frameColor, font, xs09 - xs08, ys01 - ys00, taBottom | taRight | taBorder); + lastSignalDisplay = 0; + initial = true; // forces redrawing of devices + } +} + +void cSkinLCARSDisplayMenu::DrawDevice(const cDevice *Device) +{ + int dn = Device->DeviceNumber(); + int y = deviceOffset[dn]; + if (y + lineHeight <= ys05) { + if (DrawDeviceData(osd, Device, xs08, y, xs11, y + lineHeight, xs, tinyFont, lastDeviceType[dn], lastCamSlot[dn], initial)) { + // Make sure signal meters are redrawn: + lastSignalStrength[dn] = -1; + lastSignalQuality[dn] = -1; + lastSignalDisplay = 0; + } + // The device recording indicator: + if (deviceRecording[dn]) + osd->DrawRectangle(xs07 + Gap / 2, y, xs08 - Gap - 1, y + lineHeight - 1, Theme.Color(clrMenuDeviceRecording)); + } +} + +void cSkinLCARSDisplayMenu::DrawDevices(void) +{ + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (const cDevice *Device = cDevice::GetDevice(i)) + DrawDevice(Device); + } +} + +void cSkinLCARSDisplayMenu::DrawLiveIndicator(void) +{ + cDevice *Device = cDevice::PrimaryDevice(); + int y = -1; + bool Transferring = Device->Transferring(); + if (!Device->Replaying() || Transferring) + y = deviceOffset[cDevice::ActualDevice()->DeviceNumber()]; + if (initial || y != lastLiveIndicatorY || Transferring != lastLiveIndicatorTransferring) { + if (lastLiveIndicatorY >= 0) + osd->DrawRectangle(xs12, lastLiveIndicatorY, xs13 - 1, lastLiveIndicatorY + lineHeight - 1, Theme.Color(clrBackground)); + if (y >= 0) { + osd->DrawRectangle(xs12, y, xs12 + lineHeight / 2 - 1, y + lineHeight - 1, frameColor); + osd->DrawEllipse (xs12 + lineHeight / 2, y, xs13 - 1, y + lineHeight - 1, frameColor, 5); + if (Transferring) + osd->DrawBitmap((xs12 + xs13 - bmTransferMode.Width()) / 2, y + (lineHeight - bmTransferMode.Height()) / 2, bmTransferMode, Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg)); + } + lastLiveIndicatorY = y; + lastLiveIndicatorTransferring = Transferring; + } +} + +void cSkinLCARSDisplayMenu::DrawSignals(void) +{ + time_t Now = time(NULL); + if (initial || Now - lastSignalDisplay >= SIGNALDISPLAYDELTA) { + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (const cDevice *Device = cDevice::GetDevice(i)) { + if (int y = deviceOffset[i]) + DrawDeviceSignal(osd, Device, xs + lineHeight / 2, y, xs11, y + lineHeight, lastSignalStrength[i], lastSignalQuality[i], initial); + } + } + lastSignalDisplay = Now; + } +} + +void cSkinLCARSDisplayMenu::DrawLive(const cChannel *Channel) +{ + if (lastMode != cmLive) { + initial = true; + lastMode = cmLive; + } + if (initial) { + DrawMainFrameUpper(Theme.Color(clrChannelFrameBg)); + osd->DrawText(xd00, yd00, tr("LIVE"), Theme.Color(clrChannelFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder); + } + if (initial || Channel != lastChannel) { + osd->DrawText(xa00, yt00, itoa(Channel->Number()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), tallFont, xa02 - xa00, yt02 - yt00, taTop | taRight | taBorder); + osd->DrawText(xa03, yt00, Channel->Name(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft); + lastChannel = Channel; + } + // The current programme: + cSchedulesLock SchedulesLock; + if (const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock)) { + if (const cSchedule *Schedule = Schedules->GetSchedule(Channel)) { + const cEvent *Event = Schedule->GetPresentEvent(); + if (initial || Event != lastEvent) { + DrawInfo(Event, true); + lastEvent = Event; + lastSeen = -1; + } + int Current = 0; + int Total = 0; + if (Event) { + time_t t = time(NULL); + if (t > Event->StartTime()) + Current = t - Event->StartTime(); + Total = Event->Duration(); + } + DrawSeen(Current, Total); + } + } +} + +void cSkinLCARSDisplayMenu::DrawPlay(cControl *Control) +{ + if (lastMode != cmPlay) { + initial = true; + lastMode = cmPlay; + } + if (initial) { + DrawMainFrameUpper(Theme.Color(clrReplayFrameBg)); + osd->DrawText(xd00, yd00, tr("PLAY"), Theme.Color(clrReplayFrameBg), Theme.Color(clrBackground), tallFont, xd07 - xd00, yd01 - yd00, taTop | taRight | taBorder); + } + // The current progress: + int Current = 0; + int Total = 0; + if (Control->GetIndex(Current, Total)) + DrawSeen(Current, Total); + // The current programme: + if (const cRecording *Recording = Control->GetRecording()) { + if (initial || Recording != lastRecording) { + const cFont *font = cFont::GetFont(fontOsd); + if (const cRecordingInfo *Info = Recording->Info()) { + osd->DrawText(xa03, yt00, Info->ChannelName(), Theme.Color(clrChannelName), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft); + DrawInfo(Info->GetEvent(), false); + } + else + osd->DrawText(xa03, yt04, Recording->Name(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), font, xd00 - xa03, 0, taTop | taLeft); + osd->DrawText(xa00, yt04, ShortDateString(Recording->Start()), Theme.Color(clrReplayFrameFg), Theme.Color(clrReplayFrameBg), font, xa02 - xa00, 0, taTop | taRight | taBorder); + osd->DrawText(xa00, yt06 - lineHeight, TimeString(Recording->Start()), Theme.Color(clrReplayFrameFg), Theme.Color(clrReplayFrameBg), font, xa02 - xa00, 0, taBottom | taRight | taBorder); + lastRecording = Recording; + } + } + else { + cString Header = Control->GetHeader(); + if (!*lastHeader || strcmp(Header, lastHeader)) { + osd->DrawText(xa03, yt00, Header, Theme.Color(clrMenuText), Theme.Color(clrBackground), tallFont, xd00 - xa03, yd01 - yd00, taTop | taLeft); + lastHeader = Header; + } + } +} + +void cSkinLCARSDisplayMenu::DrawInfo(const cEvent *Event, bool WithTime) +{ + if (Event) { + const cFont *font = cFont::GetFont(fontOsd); + int y = yt04; + osd->DrawText(xa03, y, Event->Title(), Theme.Color(clrEventTitle), Theme.Color(clrBackground), font, xd00 - xa03 - lineHeight, lineHeight, taBottom | taLeft); + y += lineHeight; + osd->DrawText(xa03, y, Event->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xd00 - xa03 - lineHeight, lineHeight, taTop | taLeft); + if (WithTime) { + osd->DrawText(xa00, yt04, Event->GetTimeString(), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), font, xa02 - xa00, lineHeight, taTop | taRight | taBorder); + osd->DrawText(xa00, yt06 - lineHeight, cString::sprintf("-%s", *Event->GetEndTimeString()), Theme.Color(clrChannelFrameFg), Theme.Color(clrChannelFrameBg), font, xa02 - xa00, lineHeight, taBottom | taRight | taBorder); + } + } +} + +void cSkinLCARSDisplayMenu::DrawSeen(int Current, int Total) +{ + int Seen = min(xm08 - xm02, int((xm08 - xm02) * double(Current) / Total)); + if (initial || Seen != lastSeen) { + int y0 = yc04 - ShowSeenExtent; + int y1 = yc04 + lineHeight / 2 - Gap / 2; + osd->DrawRectangle(xm02, y0, xm02 + Seen - 1, y1 - 1, Theme.Color(clrSeen)); + osd->DrawRectangle(xm02 + Seen, y0, xm08 - 1, y1 - 1, Theme.Color(clrBackground)); + lastSeen = Seen; + } +} + +void cSkinLCARSDisplayMenu::DrawTextScrollbar(void) +{ + if (textScroller.CanScroll()) + DrawScrollbar(textScroller.Total(), textScroller.Offset(), textScroller.Shown(), textScroller.CanScrollUp(), textScroller.CanScrollDown()); +} + +void cSkinLCARSDisplayMenu::Scroll(bool Up, bool Page) +{ + cSkinDisplayMenu::Scroll(Up, Page); + DrawTextScrollbar(); +} + +int cSkinLCARSDisplayMenu::MaxItems(void) +{ + if (MenuCategory() == mcMain) + return (ym04 - ym03) / lineHeight; + else + return (yb13 - yt02) / lineHeight; +} + +void cSkinLCARSDisplayMenu::Clear(void) +{ + textScroller.Reset(); + osd->DrawRectangle(xi00, yi00, xi03 - 1, yi01 - 1, Theme.Color(clrBackground)); +} + +void cSkinLCARSDisplayMenu::SetTitle(const char *Title) +{ + if (MenuCategory() != mcMain) { + const cFont *font = cFont::GetFont(fontOsd); + int w = font->Width(Title); + osd->DrawRectangle(xa06, yt00, xa07 - w - Gap - 1, yt01 - 1, frameColor); + osd->DrawText(xa07 - w - Gap, yt00, Title, Theme.Color(clrMenuTitle), Theme.Color(clrBackground), font, w + Gap, yt01 - yt00, taRight); + } +} + +void cSkinLCARSDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) +{ + const cFont *font = cFont::GetFont(fontSml); + if (MenuCategory() == mcMain) { + DrawMainButton(Red, xd00, xd01, xd02, xd03, yd02, yd03, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font); + DrawMainButton(Green, xd04, xd05, xd06, xd07, yd02, yd03, Theme.Color(clrButtonGreenFg), Theme.Color(clrButtonGreenBg), font); + DrawMainButton(Yellow, xd00, xd01, xd02, xd03, yd04, yd05, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font); + DrawMainButton(Blue, xd04, xd05, xd06, xd07, yd04, yd05, Theme.Color(clrButtonBlueFg), Theme.Color(clrButtonBlueBg), font); + } + else { + int h = yb15 - yb14; + osd->DrawText(xb02, yb14, Red, Theme.Color(clrButtonRedFg), Theme.Color(clrButtonRedBg), font, xb03 - xb02, h, taLeft | taBorder); + osd->DrawText(xb06, yb14, Green, Theme.Color(clrButtonGreenFg), Theme.Color(clrButtonGreenBg), font, xb07 - xb06, h, taLeft | taBorder); + osd->DrawText(xb10, yb14, Yellow, Theme.Color(clrButtonYellowFg), Theme.Color(clrButtonYellowBg), font, xb11 - xb10, h, taLeft | taBorder); + osd->DrawText(xb14, yb14, Blue, Theme.Color(clrButtonBlueFg), Theme.Color(clrButtonBlueBg), font, xb15 - xb14, h, taLeft | taBorder); + } +} + +void cSkinLCARSDisplayMenu::SetMessage(eMessageType Type, const char *Text) +{ + if (Text) { + osd->SaveRegion(xb00, yb14, xb15 - 1, yb15 - 1); + osd->DrawText(xb00, yb14, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xb15 - xb00, yb15 - yb14, taCenter); + } + else + osd->RestoreRegion(); +} + +void cSkinLCARSDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) +{ + int y = yi00 + Index * lineHeight; + tColor ColorFg, ColorBg; + if (Current) { + ColorFg = Theme.Color(clrMenuItemCurrentFg); + ColorBg = Theme.Color(clrMenuItemCurrentBg); + osd->DrawRectangle(xi00, y, xi01 - 1, y + lineHeight - 1, ColorBg); + osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, y + lineHeight - 1, ColorBg); + osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, y + lineHeight - 1, ColorBg, 5); + currentIndex = Index; + } + else { + ColorFg = Theme.Color(Selectable ? clrMenuItemSelectable : clrMenuItemNonSelectable); + ColorBg = Theme.Color(clrBackground); + if (currentIndex == Index) + osd->DrawRectangle(xi00, y, xi03 - 1, y + lineHeight - 1, Theme.Color(clrBackground)); + } + const cFont *font = cFont::GetFont(fontOsd); + for (int i = 0; i < MaxTabs; i++) { + const char *s = GetTabbedText(Text, i); + if (s) { + int xt = xi00 + TextSpacing + Tab(i); + osd->DrawText(xt, y, s, ColorFg, ColorBg, font, xi01 - xt); + } + if (!Tab(i + 1)) + break; + } + SetEditableWidth(xi02 - xi00 - TextSpacing - Tab(1)); +} + +void cSkinLCARSDisplayMenu::SetScrollbar(int Total, int Offset) +{ + DrawScrollbar(Total, Offset, MaxItems(), Offset > 0, Offset + MaxItems() < Total); +} + +void cSkinLCARSDisplayMenu::SetEvent(const cEvent *Event) +{ + if (!Event) + return; + const cFont *font = cFont::GetFont(fontOsd); + int xl = xi00; + int y = yi00; + cTextScroller ts; + char t[32]; + snprintf(t, sizeof(t), "%s %s - %s", *Event->GetDateString(), *Event->GetTimeString(), *Event->GetEndTimeString()); + ts.Set(osd, xl, y, xi01 - xl, yi01 - y, t, font, Theme.Color(clrEventTime), Theme.Color(clrBackground)); + if (Event->Vps() && Event->Vps() != Event->StartTime()) { + cString buffer = cString::sprintf(" VPS: %s ", *Event->GetVpsString()); + const cFont *font = cFont::GetFont(fontSml); + int w = font->Width(buffer); + osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w); + int yb = y + font->Height(); + osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor); + osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5); + } + y += ts.Height(); + if (Event->ParentalRating()) { + cString buffer = cString::sprintf(" %s ", *Event->GetParentalRatingString()); + const cFont *font = cFont::GetFont(fontSml); + int w = font->Width(buffer); + osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w); + int yb = y + font->Height(); + osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor); + osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5); + } + y += font->Height(); + ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Event->Title(), font, Theme.Color(clrEventTitle), Theme.Color(clrBackground)); + y += ts.Height(); + if (!isempty(Event->ShortText())) { + const cFont *font = cFont::GetFont(fontSml); + ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Event->ShortText(), font, Theme.Color(clrEventShortText), Theme.Color(clrBackground)); + y += ts.Height(); + } + y += font->Height(); + if (!isempty(Event->Description())) { + int yt = y; + int yb = yi01; + textScroller.Set(osd, xl, yt, xi01 - xl, yb - yt, Event->Description(), font, Theme.Color(clrEventDescription), Theme.Color(clrBackground)); + DrawTextScrollbar(); + } +} + +void cSkinLCARSDisplayMenu::SetRecording(const cRecording *Recording) +{ + if (!Recording) + return; + const cRecordingInfo *Info = Recording->Info(); + const cFont *font = cFont::GetFont(fontOsd); + int xl = xi00; + int y = yi00; + cTextScroller ts; + char t[32]; + snprintf(t, sizeof(t), "%s %s", *DateString(Recording->Start()), *TimeString(Recording->Start())); + ts.Set(osd, xl, y, xi01 - xl, yi01 - y, t, font, Theme.Color(clrEventTime), Theme.Color(clrBackground)); + y += ts.Height(); + if (Info->GetEvent()->ParentalRating()) { + cString buffer = cString::sprintf(" %s ", *Info->GetEvent()->GetParentalRatingString()); + const cFont *font = cFont::GetFont(fontSml); + int w = font->Width(buffer); + osd->DrawText(xi01 - w, y, buffer, Theme.Color(clrMenuFrameFg), frameColor, font, w); + int yb = y + font->Height(); + osd->DrawRectangle(xi02, y, xi02 + lineHeight / 2 - 1, yb - 1, frameColor); + osd->DrawEllipse (xi02 + lineHeight / 2, y, xi03 - 1, yb - 1, frameColor, 5); + } + y += font->Height(); + const char *Title = Info->Title(); + if (isempty(Title)) + Title = Recording->Name(); + ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Title, font, Theme.Color(clrEventTitle), Theme.Color(clrBackground)); + y += ts.Height(); + if (!isempty(Info->ShortText())) { + const cFont *font = cFont::GetFont(fontSml); + ts.Set(osd, xl, y, xi01 - xl, yi01 - y, Info->ShortText(), font, Theme.Color(clrEventShortText), Theme.Color(clrBackground)); + y += ts.Height(); + } + y += font->Height(); + if (!isempty(Info->Description())) { + int yt = y; + int yb = yi01; + textScroller.Set(osd, xl, yt, xi01 - xl, yb - yt, Info->Description(), font, Theme.Color(clrEventDescription), Theme.Color(clrBackground)); + DrawTextScrollbar(); + } +} + +void cSkinLCARSDisplayMenu::SetText(const char *Text, bool FixedFont) +{ + textScroller.Set(osd, xi00, yi00, GetTextAreaWidth(), yi01 - yi00, Text, GetTextAreaFont(FixedFont), Theme.Color(clrMenuText), Theme.Color(clrBackground)); + DrawTextScrollbar(); +} + +int cSkinLCARSDisplayMenu::GetTextAreaWidth(void) const +{ + return xi01 - xi00; +} + +const cFont *cSkinLCARSDisplayMenu::GetTextAreaFont(bool FixedFont) const +{ + const cFont *font = cFont::GetFont(FixedFont ? fontFix : fontOsd); + //XXX -> make a way to let the text define which font to use + return font; +} + +void cSkinLCARSDisplayMenu::Flush(void) +{ + if (MenuCategory() == mcMain) { + cDevice *Device = cDevice::PrimaryDevice(); + if (!Device->Replaying() || Device->Transferring()) { + const cChannel *Channel = Channels.GetByNumber(cDevice::PrimaryDevice()->CurrentChannel()); + DrawLive(Channel); + } + else if (cControl *Control = cControl::Control(true)) + DrawPlay(Control); + DrawTimers(); + DrawDevices(); + DrawLiveIndicator(); + DrawSignals(); + } + DrawFrameDisplay(); + osd->Flush(); + initial = false; +} + +// --- cSkinLCARSDisplayReplay ----------------------------------------------- + +class cSkinLCARSDisplayReplay : public cSkinDisplayReplay { +private: + cOsd *osd; + int xp00, xp01, xp02, xp03, xp04, xp05, xp06, xp07, xp08, xp09, xp10, xp11, xp12, xp13, xp14, xp15; + int yp00, yp01, yp02, yp03, yp04, yp05, yp06, yp07, yp08, yp09; + bool modeOnly; + int lineHeight; + tColor frameColor; + cString lastDate; + tTrackId lastTrackId; + void DrawDate(void); + void DrawTrack(void); +public: + cSkinLCARSDisplayReplay(bool ModeOnly); + virtual ~cSkinLCARSDisplayReplay(); + virtual void SetRecording(const cRecording *Recording); + virtual void SetTitle(const char *Title); + virtual void SetMode(bool Play, bool Forward, int Speed); + virtual void SetProgress(int Current, int Total); + virtual void SetCurrent(const char *Current); + virtual void SetTotal(const char *Total); + virtual void SetJump(const char *Jump); + virtual void SetMessage(eMessageType Type, const char *Text); + virtual void Flush(void); + }; + +cSkinLCARSDisplayReplay::cSkinLCARSDisplayReplay(bool ModeOnly) +{ + const cFont *font = cFont::GetFont(fontOsd); + modeOnly = ModeOnly; + lineHeight = font->Height(); + frameColor = Theme.Color(clrReplayFrameBg); + int d = 5 * lineHeight; + xp00 = 0; + xp01 = xp00 + d / 2; + xp02 = xp00 + d; + xp03 = xp02 + lineHeight; + xp04 = xp02 + d / 4; + xp05 = xp02 + d; + xp06 = xp05 + Gap; + xp15 = cOsd::OsdWidth(); + xp14 = xp15 - lineHeight; + xp13 = xp14 - Gap; + xp07 = (xp15 + xp00) / 2; + xp08 = xp07 + Gap; + xp09 = xp08 + lineHeight; + xp10 = xp09 + Gap; + xp11 = (xp10 + xp13 + Gap) / 2; + xp12 = xp11 + Gap; + + yp00 = 0; + yp01 = yp00 + 2 * lineHeight; + yp02 = yp01 + Gap; + yp03 = yp02 + 2 * lineHeight; + + yp04 = yp03 + Gap; + yp09 = yp04 + 3 * lineHeight + Gap / 2; + yp08 = yp09 - lineHeight; + yp07 = yp08 - lineHeight; + yp06 = yp08 - d / 4; + yp05 = yp09 - d / 2; + + osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - yp09, xp00, yp00, xp15 - 1, yp09 - 1); + osd->DrawRectangle(xp00, yp00, xp15 - 1, yp09 - 1, modeOnly ? clrTransparent : Theme.Color(clrBackground)); + // Rectangles: + if (!modeOnly) + osd->DrawRectangle(xp00, yp00, xp02 - 1, yp01 - 1, frameColor); + osd->DrawRectangle(xp00, yp02, xp02 - 1, yp03 - 1, frameColor); + if (!modeOnly) { + // Elbow: + osd->DrawRectangle(xp00, yp04, xp01 - 1, yp05 - 1, frameColor); + osd->DrawRectangle(xp00, yp05, xp01 - 1, yp09 - 1, clrTransparent); + osd->DrawEllipse (xp00, yp05, xp01 - 1, yp09 - 1, frameColor, 3); + osd->DrawRectangle(xp01, yp04, xp02 - 1, yp09 - 1, frameColor); + osd->DrawEllipse (xp02, yp06, xp04 - 1, yp08 - 1, frameColor, -3); + osd->DrawRectangle(xp02, yp08, xp05 - 1, yp09 - 1, frameColor); + // Status area: + osd->DrawRectangle(xp06, yp08, xp07 - 1, yp09 - 1, frameColor); + osd->DrawRectangle(xp08, yp08, xp09 - 1, yp09 - 1, frameColor); + osd->DrawRectangle(xp10, yp08, xp11 - 1, yp09 - 1, frameColor); + osd->DrawRectangle(xp12, yp08, xp13 - 1, yp09 - 1, Theme.Color(clrDateBg)); + osd->DrawRectangle(xp14, yp08, xp14 + lineHeight / 2 - 1, yp09 - 1, frameColor); + osd->DrawRectangle(xp14 + lineHeight / 2, yp08 + lineHeight / 2, xp15 - 1, yp09 - 1, clrTransparent); + osd->DrawEllipse (xp14 + lineHeight / 2, yp08, xp15 - 1, yp09 - 1, frameColor, 5); + } +} + +cSkinLCARSDisplayReplay::~cSkinLCARSDisplayReplay() +{ + delete osd; +} + +void cSkinLCARSDisplayReplay::DrawDate(void) +{ + cString s = DayDateTime(); + if (!*lastDate || strcmp(s, lastDate)) { + osd->DrawText(xp12, yp08, s, Theme.Color(clrDateFg), Theme.Color(clrDateBg), cFont::GetFont(fontOsd), xp13 - xp12, lineHeight, taRight | taBorder); + lastDate = s; + } +} + +void cSkinLCARSDisplayReplay::DrawTrack(void) +{ + cDevice *Device = cDevice::PrimaryDevice(); + const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack()); + if (!Track && *lastTrackId.description || Track && strcmp(lastTrackId.description, Track->description)) { + osd->DrawText(xp03, yp04, Track ? Track->description : "", Theme.Color(clrTrackName), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xp07 - xp03); + strn0cpy(lastTrackId.description, Track ? Track->description : "", sizeof(lastTrackId.description)); + } +} + +void cSkinLCARSDisplayReplay::SetRecording(const cRecording *Recording) +{ + const cRecordingInfo *RecordingInfo = Recording->Info(); + SetTitle(RecordingInfo->Title()); + osd->DrawText(xp03, yp01 - lineHeight, RecordingInfo->ShortText(), Theme.Color(clrEventShortText), Theme.Color(clrBackground), cFont::GetFont(fontSml), xp13 - xp03); + osd->DrawText(xp00, yp00, ShortDateString(Recording->Start()), Theme.Color(clrReplayFrameFg), frameColor, cFont::GetFont(fontOsd), xp02 - xp00, 0, taTop | taRight | taBorder); + osd->DrawText(xp00, yp01 - lineHeight, TimeString(Recording->Start()), Theme.Color(clrReplayFrameFg), frameColor, cFont::GetFont(fontOsd), xp02 - xp00, 0, taBottom | taRight | taBorder); +} + +void cSkinLCARSDisplayReplay::SetTitle(const char *Title) +{ + osd->DrawText(xp03, yp00, Title, Theme.Color(clrEventTitle), Theme.Color(clrBackground), cFont::GetFont(fontOsd), xp13 - xp03); +} + +static const char *const *ReplaySymbols[2][2][5] = { + { { pause_xpm, srew_xpm, srew1_xpm, srew2_xpm, srew3_xpm }, + { pause_xpm, sfwd_xpm, sfwd1_xpm, sfwd2_xpm, sfwd3_xpm }, }, + { { play_xpm, frew_xpm, frew1_xpm, frew2_xpm, frew3_xpm }, + { play_xpm, ffwd_xpm, ffwd1_xpm, ffwd2_xpm, ffwd3_xpm } } + }; + +void cSkinLCARSDisplayReplay::SetMode(bool Play, bool Forward, int Speed) +{ + Speed = constrain(Speed, -1, 3); + cBitmap bm(ReplaySymbols[Play][Forward][Speed + 1]); + osd->DrawBitmap(xp01 - bm.Width() / 2, (yp02 + yp03 - bm.Height()) / 2, bm, Theme.Color(clrReplayFrameFg), frameColor); +} + +void cSkinLCARSDisplayReplay::SetProgress(int Current, int Total) +{ + cProgressBar pb(xp13 - xp03, lineHeight, Current, Total, marks, Theme.Color(clrReplayProgressSeen), Theme.Color(clrReplayProgressRest), Theme.Color(clrReplayProgressSelected), Theme.Color(clrReplayProgressMark), Theme.Color(clrReplayProgressCurrent)); + osd->DrawBitmap(xp03, yp02, pb); +} + +void cSkinLCARSDisplayReplay::SetCurrent(const char *Current) +{ + const cFont *font = cFont::GetFont(fontOsd); + int w = font->Width(Current) + 10; + osd->DrawText(xp03, yp03 - lineHeight, Current, Theme.Color(clrReplayPosition), Theme.Color(clrBackground), font, w, 0, taLeft); +} + +void cSkinLCARSDisplayReplay::SetTotal(const char *Total) +{ + const cFont *font = cFont::GetFont(fontOsd); + int w = font->Width(Total) + 10; + osd->DrawText(xp13 - w, yp03 - lineHeight, Total, Theme.Color(clrReplayPosition), Theme.Color(clrBackground), font, w, 0, taRight); +} + +void cSkinLCARSDisplayReplay::SetJump(const char *Jump) +{ + osd->DrawText(xp06, yp08, Jump, Theme.Color(clrReplayJumpFg), Jump ? Theme.Color(clrReplayJumpBg) : frameColor, cFont::GetFont(fontOsd), xp07 - xp06, 0, taCenter); +} + +void cSkinLCARSDisplayReplay::SetMessage(eMessageType Type, const char *Text) +{ + if (Text) { + osd->SaveRegion(xp06, yp08, xp13 - 1, yp09 - 1); + osd->DrawText(xp06, yp08, Text, Theme.Color(clrMessageStatusFg + 2 * Type), Theme.Color(clrMessageStatusBg + 2 * Type), cFont::GetFont(fontSml), xp13 - xp06, 0, taCenter); + } + else + osd->RestoreRegion(); +} + +void cSkinLCARSDisplayReplay::Flush(void) +{ + if (!modeOnly) { + DrawDate(); + DrawTrack(); + } + osd->Flush(); +} + +// --- cSkinLCARSDisplayVolume ----------------------------------------------- + +class cSkinLCARSDisplayVolume : public cSkinDisplayVolume { +private: + cOsd *osd; + int x0, x1, x2, x3, x4, x5, x6, x7; + int y0, y1; + tColor frameColor; + int mute; +public: + cSkinLCARSDisplayVolume(void); + virtual ~cSkinLCARSDisplayVolume(); + virtual void SetVolume(int Current, int Total, bool Mute); + virtual void Flush(void); + }; + +cSkinLCARSDisplayVolume::cSkinLCARSDisplayVolume(void) +{ + const cFont *font = cFont::GetFont(fontOsd); + int lineHeight = font->Height(); + frameColor = Theme.Color(clrVolumeFrame); + mute = -1; + x0 = 0; + x1 = lineHeight / 2; + x2 = lineHeight; + x3 = x2 + Gap; + x7 = cOsd::OsdWidth(); + x6 = x7 - lineHeight / 2; + x5 = x6 - lineHeight / 2; + x4 = x5 - Gap; + y0 = 0; + y1 = lineHeight; + osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1, x0, y0, x7 - 1, y1 - 1); + osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, Theme.Color(clrBackground)); + osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent); + osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7); + osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor); + osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor); + osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, frameColor); + osd->DrawRectangle(x6, y0, x7 - 1, y1 - 1, clrTransparent); + osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, frameColor, 5); +} + +cSkinLCARSDisplayVolume::~cSkinLCARSDisplayVolume() +{ + delete osd; +} + +void cSkinLCARSDisplayVolume::SetVolume(int Current, int Total, bool Mute) +{ + int xl = x3 + TextSpacing; + int xr = x4 - TextSpacing; + int yt = y0 + TextFrame; + int yb = y1 - TextFrame; + if (mute != Mute) { + osd->DrawRectangle(x3, y0, x4 - 1, y1 - 1, frameColor); + mute = Mute; + } + cBitmap bm(Mute ? mute_xpm : volume_xpm); + osd->DrawBitmap(xl, y0 + (y1 - y0 - bm.Height()) / 2, bm, Theme.Color(clrVolumeSymbol), frameColor); + if (!Mute) { + xl += bm.Width() + TextSpacing; + int w = (y1 - y0) / 3; + int d = TextFrame; + int n = (xr - xl + d) / (w + d); + int x = xr - n * (w + d); + tColor Color = Theme.Color(clrVolumeBarLower); + for (int i = 0; i < n; i++) { + if (Total * i >= Current * n) + Color = Theme.Color(clrVolumeBarUpper); + osd->DrawRectangle(x, yt, x + w - 1, yb - 1, Color); + x += w + d; + } + } +} + +void cSkinLCARSDisplayVolume::Flush(void) +{ + osd->Flush(); +} + +// --- cSkinLCARSDisplayTracks ----------------------------------------------- + +class cSkinLCARSDisplayTracks : public cSkinDisplayTracks { +private: + cOsd *osd; + int xt00, xt01, xt02, xt03, xt04, xt05, xt06, xt07, xt08, xt09, xt10, xt11, xt12; + int yt00, yt01, yt02, yt03, yt04, yt05, yt06, yt07; + int lineHeight; + tColor frameColor; + int currentIndex; + static cBitmap bmAudioLeft, bmAudioRight, bmAudioStereo; + void SetItem(const char *Text, int Index, bool Current); +public: + cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks); + virtual ~cSkinLCARSDisplayTracks(); + virtual void SetTrack(int Index, const char * const *Tracks); + virtual void SetAudioChannel(int AudioChannel); + virtual void Flush(void); + }; + +cBitmap cSkinLCARSDisplayTracks::bmAudioLeft(audioleft_xpm); +cBitmap cSkinLCARSDisplayTracks::bmAudioRight(audioright_xpm); +cBitmap cSkinLCARSDisplayTracks::bmAudioStereo(audiostereo_xpm); + +cSkinLCARSDisplayTracks::cSkinLCARSDisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) +{ + const cFont *font = cFont::GetFont(fontOsd); + lineHeight = font->Height(); + frameColor = Theme.Color(clrTrackFrameBg); + currentIndex = -1; + xt00 = 0; + xt01 = xt00 + lineHeight / 2; + xt02 = xt01 + Gap; + xt03 = xt00 + 2 * lineHeight; + int ItemsWidth = font->Width(Title) + xt03 - xt02; + for (int i = 0; i < NumTracks; i++) + ItemsWidth = max(ItemsWidth, font->Width(Tracks[i]) + 2 * TextFrame); + xt04 = xt02 + ItemsWidth; + xt05 = xt04 + Gap; + xt06 = xt04 + lineHeight; + xt07 = xt05 + lineHeight; + xt08 = xt07 + lineHeight; + xt09 = xt08 + Gap; + xt10 = xt09 + lineHeight / 2; + xt11 = xt10 + Gap; + xt12 = xt11 + lineHeight; + yt00 = 0; + yt01 = yt00 + lineHeight; + yt02 = yt01 + lineHeight; + yt03 = yt02 + Gap; + yt04 = yt03 + NumTracks * lineHeight + (NumTracks - 1) * Gap; + yt05 = yt04 + Gap; + yt06 = yt05 + lineHeight; + yt07 = yt06 + lineHeight; + while (yt07 > cOsd::OsdHeight()) { + yt04 -= lineHeight + Gap; + yt05 = yt04 + Gap; + yt06 = yt05 + lineHeight; + yt07 = yt06 + lineHeight; + } + osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - yt07, xt00, yt00, xt12 - 1, yt07 - 1); + // The upper elbow: + osd->DrawRectangle(xt00, yt00, xt12 - 1, yt07 - 1, Theme.Color(clrBackground)); + osd->DrawRectangle(xt00, yt00, xt03 - 1, yt02 - 1, clrTransparent); + osd->DrawEllipse (xt00, yt00, xt03 - 1, yt02 - 1, frameColor, 2); + osd->DrawRectangle(xt03, yt00, xt04 - 1, yt02 - 1, frameColor); + osd->DrawRectangle(xt04, yt00, xt08 - 1, yt01 - 1, frameColor); + osd->DrawEllipse (xt04, yt01, xt06 - 1, yt02 - 1, frameColor, -2); + osd->DrawRectangle(xt09, yt00, xt10 - 1, yt01 - 1, frameColor); + osd->DrawRectangle(xt11, yt00, xt11 + lineHeight / 2 - 1, yt01 - 1, frameColor); + osd->DrawRectangle(xt11 + lineHeight / 2, yt00, xt12 - 1, yt00 + lineHeight / 2 - 1, clrTransparent); + osd->DrawEllipse (xt11 + lineHeight / 2, yt00, xt12 - 1, yt01 - 1, frameColor, 5); + osd->DrawText(xt03, yt00, Title, Theme.Color(clrTrackFrameFg), frameColor, font, xt04 - xt03, 0, taTop | taRight); + // The items: + for (int i = 0; i < NumTracks; i++) + SetItem(Tracks[i], i, false); + // The lower elbow: + osd->DrawRectangle(xt00, yt05, xt03 - 1, yt07 - 1, clrTransparent); + osd->DrawEllipse (xt00, yt05, xt03 - 1, yt07 - 1, frameColor, 3); + osd->DrawRectangle(xt03, yt05, xt04 - 1, yt07 - 1, frameColor); + osd->DrawRectangle(xt04, yt06, xt08 - 1, yt07 - 1, frameColor); + osd->DrawEllipse (xt04, yt05, xt06 - 1, yt06 - 1, frameColor, -3); + osd->DrawRectangle(xt09, yt06, xt10 - 1, yt07 - 1, frameColor); + osd->DrawRectangle(xt11, yt06, xt11 + lineHeight / 2 - 1, yt07 - 1, frameColor); + osd->DrawRectangle(xt11 + lineHeight / 2, yt06 + lineHeight / 2, xt12 - 1, yt07 - 1, clrTransparent); + osd->DrawEllipse (xt11 + lineHeight / 2, yt06, xt12 - 1, yt07 - 1, frameColor, 5); +} + +cSkinLCARSDisplayTracks::~cSkinLCARSDisplayTracks() +{ + delete osd; +} + +void cSkinLCARSDisplayTracks::SetItem(const char *Text, int Index, bool Current) +{ + int y0 = yt03 + Index * (lineHeight + Gap); + int y1 = y0 + lineHeight; + if (y1 > yt04) + return; + tColor ColorFg, ColorBg; + if (Current) { + ColorFg = Theme.Color(clrTrackItemCurrentFg); + ColorBg = Theme.Color(clrTrackItemCurrentBg); + osd->DrawRectangle(xt00, y0, xt01 - 1, y1 - 1, frameColor); + osd->DrawRectangle(xt02, y0, xt04 - 1, y1 - 1, ColorBg); + osd->DrawRectangle(xt05, y0, xt05 + lineHeight / 2 - 1, y1 - 1, ColorBg); + osd->DrawEllipse (xt05 + lineHeight / 2, y0, xt07 - 1, y1 - 1, ColorBg, 5); + currentIndex = Index; + } + else { + ColorFg = Theme.Color(clrTrackItemFg); + ColorBg = Theme.Color(clrTrackItemBg); + osd->DrawRectangle(xt00, y0, xt01 - 1, y1 - 1, frameColor); + osd->DrawRectangle(xt02, y0, xt04 - 1, y1 - 1, ColorBg); + if (currentIndex == Index) + osd->DrawRectangle(xt05, y0, xt07 - 1, y1 - 1, Theme.Color(clrBackground)); + } + const cFont *font = cFont::GetFont(fontOsd); + osd->DrawText(xt02, y0, Text, ColorFg, ColorBg, font, xt04 - xt02, y1 - y0, taTop | taLeft | taBorder); +} + +void cSkinLCARSDisplayTracks::SetTrack(int Index, const char * const *Tracks) +{ + if (currentIndex >= 0) + SetItem(Tracks[currentIndex], currentIndex, false); + SetItem(Tracks[Index], Index, true); +} + +void cSkinLCARSDisplayTracks::SetAudioChannel(int AudioChannel) +{ + cBitmap *bm = NULL; + switch (AudioChannel) { + case 0: bm = &bmAudioStereo; break; + case 1: bm = &bmAudioLeft; break; + case 2: bm = &bmAudioRight; break; + default: ; + } + if (bm) + osd->DrawBitmap(xt04 - bm->Width(), (yt06 + yt07 - bm->Height()) / 2, *bm, Theme.Color(clrTrackFrameFg), frameColor); + else + osd->DrawRectangle(xt03, yt06, xt04 - 1, yt07 - 1, frameColor); +} + +void cSkinLCARSDisplayTracks::Flush(void) +{ + osd->Flush(); +} + +// --- cSkinLCARSDisplayMessage ---------------------------------------------- + +class cSkinLCARSDisplayMessage : public cSkinDisplayMessage { +private: + cOsd *osd; + int x0, x1, x2, x3, x4, x5, x6, x7; + int y0, y1; +public: + cSkinLCARSDisplayMessage(void); + virtual ~cSkinLCARSDisplayMessage(); + virtual void SetMessage(eMessageType Type, const char *Text); + virtual void Flush(void); + }; + +cSkinLCARSDisplayMessage::cSkinLCARSDisplayMessage(void) +{ + const cFont *font = cFont::GetFont(fontOsd); + int lineHeight = font->Height(); + x0 = 0; + x1 = lineHeight / 2; + x2 = lineHeight; + x3 = x2 + Gap; + x7 = cOsd::OsdWidth(); + x6 = x7 - lineHeight / 2; + x5 = x6 - lineHeight / 2; + x4 = x5 - Gap; + y0 = 0; + y1 = lineHeight; + osd = CreateOsd(cOsd::OsdLeft(), cOsd::OsdTop() + cOsd::OsdHeight() - y1, x0, y0, x7 - 1, y1 - 1); +} + +cSkinLCARSDisplayMessage::~cSkinLCARSDisplayMessage() +{ + delete osd; +} + +void cSkinLCARSDisplayMessage::SetMessage(eMessageType Type, const char *Text) +{ + tColor ColorFg = Theme.Color(clrMessageStatusFg + 2 * Type); + tColor ColorBg = Theme.Color(clrMessageStatusBg + 2 * Type); + osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, Theme.Color(clrBackground)); + osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent); + osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, ColorBg, 7); + osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, ColorBg); + osd->DrawText(x3, y0, Text, ColorFg, ColorBg, cFont::GetFont(fontOsd), x4 - x3, 0, taCenter); + osd->DrawRectangle(x5, y0, x6 - 1, y1 - 1, ColorBg); + osd->DrawRectangle(x6, y0, x7 - 1, y1 - 1, clrTransparent); + osd->DrawEllipse (x6, y0, x7 - 1, y1 - 1, ColorBg, 5); +} + +void cSkinLCARSDisplayMessage::Flush(void) +{ + osd->Flush(); +} + +// --- cSkinLCARS ------------------------------------------------------------ + +cSkinLCARS::cSkinLCARS(void) +:cSkin("lcars", &::Theme) +{ +} + +const char *cSkinLCARS::Description(void) +{ + return "LCARS"; +} + +cSkinDisplayChannel *cSkinLCARS::DisplayChannel(bool WithInfo) +{ + return new cSkinLCARSDisplayChannel(WithInfo); +} + +cSkinDisplayMenu *cSkinLCARS::DisplayMenu(void) +{ + return new cSkinLCARSDisplayMenu; +} + +cSkinDisplayReplay *cSkinLCARS::DisplayReplay(bool ModeOnly) +{ + return new cSkinLCARSDisplayReplay(ModeOnly); +} + +cSkinDisplayVolume *cSkinLCARS::DisplayVolume(void) +{ + return new cSkinLCARSDisplayVolume; +} + +cSkinDisplayTracks *cSkinLCARS::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) +{ + return new cSkinLCARSDisplayTracks(Title, NumTracks, Tracks); +} + +cSkinDisplayMessage *cSkinLCARS::DisplayMessage(void) +{ + return new cSkinLCARSDisplayMessage; +} diff --git a/skinlcars.h b/skinlcars.h new file mode 100644 index 0000000..7306d12 --- /dev/null +++ b/skinlcars.h @@ -0,0 +1,27 @@ +/* + * skinlcars.h: A VDR skin with Star Trek's "LCARS" layout + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: skinlcars.h 1.1 2012/04/15 13:17:35 kls Exp $ + */ + +#ifndef __SKINLCARS_H +#define __SKINLCARS_H + +#include "skins.h" + +class cSkinLCARS : public cSkin { +public: + cSkinLCARS(void); + virtual const char *Description(void); + virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo); + virtual cSkinDisplayMenu *DisplayMenu(void); + virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly); + virtual cSkinDisplayVolume *DisplayVolume(void); + virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks); + virtual cSkinDisplayMessage *DisplayMessage(void); + }; + +#endif //__SKINLCARS_H @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skins.c 2.5 2012/03/11 14:36:11 kls Exp $ + * $Id: skins.c 2.10 2012/06/02 11:44:14 kls Exp $ */ #include "skins.h" @@ -67,9 +67,15 @@ cSkinDisplay::~cSkinDisplay() cSkinDisplayMenu::cSkinDisplayMenu(void) { + menuCategory = mcUndefined; SetTabs(0); } +void cSkinDisplayMenu::SetMenuCategory(eMenuCategory MenuCategory) +{ + menuCategory = MenuCategory; +} + void cSkinDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) { tabs[0] = 0; @@ -166,6 +172,11 @@ cSkinDisplayReplay::cSkinDisplayReplay(void) marks = NULL; } +void cSkinDisplayReplay::SetRecording(const cRecording *Recording) +{ + SetTitle(Recording->Title()); +} + void cSkinDisplayReplay::SetMarks(const cMarks *Marks) { marks = Marks; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skins.h 2.2 2012/03/11 14:38:23 kls Exp $ + * $Id: skins.h 2.5 2012/05/12 11:10:30 kls Exp $ */ #ifndef __SKINS_H @@ -72,6 +72,8 @@ public: */ }; +enum eMenuCategory { mcUndefined = -1, mcUnknown = 0, mcMain, mcSchedule, mcChannel, mcTimer, mcRecording, mcPlugin, mcSetup, mcCommand, mcEvent, mcText, mcFolder, mcCam }; + class cSkinDisplayMenu : public cSkinDisplay { ///< This class implements the general purpose menu display, which is ///< used throughout the program to display information and let the @@ -92,6 +94,7 @@ class cSkinDisplayMenu : public cSkinDisplay { public: enum { MaxTabs = 6 }; private: + eMenuCategory menuCategory; int tabs[MaxTabs]; protected: cTextScroller textScroller; @@ -104,6 +107,16 @@ protected: ///< part can be found, NULL will be returned. public: cSkinDisplayMenu(void); + eMenuCategory MenuCategory(void) const { return menuCategory; } + ///< Returns the menu category, set by a previous call to SetMenuCategory(). + virtual void SetMenuCategory(eMenuCategory MenuCategory); + ///< Sets the current menu category. This allows skins to handle known + ///< types of menus in different ways, for instance by displaying icons + ///< or special decorations. + ///< A derived class can reimplement this function to be informed of any + ///< changes in the menu category. If it does, it shall call the base class + ///< function in order to set the members accordingly for later calls to the + ///< MenuCategory() function. virtual void SetTabs(int Tab1, int Tab2 = 0, int Tab3 = 0, int Tab4 = 0, int Tab5 = 0); ///< Sets the tab columns to the given values, which are the number of ///< characters in each column. @@ -200,6 +213,11 @@ public: virtual void SetMarks(const cMarks *Marks); ///< Sets the editing marks to Marks, which shall be used to display the ///< progress bar through a cProgressBar object. + virtual void SetRecording(const cRecording *Recording); + ///< Sets the recording that is currently being played. + ///< The default implementation calls SetTitle() with the title and short + ///< text of the Recording. A derived class can use any information provided + ///< by the given Recording and display it. virtual void SetTitle(const char *Title) = 0; ///< Sets the title of the recording. virtual void SetMode(bool Play, bool Forward, int Speed) = 0; diff --git a/skinsttng.c b/skinsttng.c index 4c3b6a4..d985538 100644 --- a/skinsttng.c +++ b/skinsttng.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skinsttng.c 2.14 2012/03/11 14:06:05 kls Exp $ + * $Id: skinsttng.c 2.15 2012/04/23 08:39:11 kls Exp $ */ // "Star Trek: The Next Generation"(R) is a registered trademark of Paramount Pictures @@ -16,6 +16,7 @@ #include "osd.h" #include "menu.h" #include "themes.h" +#include "videodir.h" #include "symbols/arrowdown.xpm" #include "symbols/arrowup.xpm" @@ -401,8 +402,11 @@ private: int lineHeight; tColor frameColor; int currentIndex; + cString title; bool message; cString lastDate; + int lastDiskUsageState; + void DrawTitle(void); void DrawScrollbar(int Total, int Offset, int Shown, int Top, int Height, bool CanScrollUp, bool CanScrollDown); void SetTextScrollbar(void); public: @@ -429,6 +433,7 @@ cSkinSTTNGDisplayMenu::cSkinSTTNGDisplayMenu(void) const cFont *font = cFont::GetFont(fontOsd); lineHeight = font->Height(); frameColor = Theme.Color(clrMenuFrame); + lastDiskUsageState = -1; currentIndex = -1; message = false; x0 = 0; @@ -548,15 +553,22 @@ void cSkinSTTNGDisplayMenu::Clear(void) osd->DrawRectangle(x1, y3, x7 - 1, y4 - 1, Theme.Color(clrBackground)); } -void cSkinSTTNGDisplayMenu::SetTitle(const char *Title) +void cSkinSTTNGDisplayMenu::DrawTitle(void) { const cFont *font = cFont::GetFont(fontOsd); const char *VDR = " VDR"; + bool WithDisk = MenuCategory() == mcMain || MenuCategory() == mcRecording; int w = font->Width(VDR); - osd->DrawText(x3 + TextSpacing, y0, Title, Theme.Color(clrMenuTitle), frameColor, font, x4 - w - x3 - TextSpacing); + osd->DrawText(x3 + TextSpacing, y0, WithDisk ? cString::sprintf("%s - %s", *title, *cVideoDiskUsage::String()) : title, Theme.Color(clrMenuTitle), frameColor, font, x4 - w - x3 - TextSpacing); osd->DrawText(x4 - w, y0, VDR, frameColor, clrBlack, font, w, lineHeight); } +void cSkinSTTNGDisplayMenu::SetTitle(const char *Title) +{ + title = Title; + DrawTitle(); +} + void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) { cString date = DayDateTime(); @@ -749,6 +761,8 @@ const cFont *cSkinSTTNGDisplayMenu::GetTextAreaFont(bool FixedFont) const void cSkinSTTNGDisplayMenu::Flush(void) { + if (cVideoDiskUsage::HasChanged(lastDiskUsageState)) + DrawTitle(); if (!message) { cString date = DayDateTime(); if (!*lastDate || strcmp(date, lastDate)) { @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 2.16 2012/03/04 12:05:56 kls Exp $ + * $Id: svdrp.c 2.19 2012/05/12 11:55:18 kls Exp $ */ #include "svdrp.h" @@ -432,7 +432,7 @@ void cSVDRP::Reply(int Code, const char *fmt, ...) if (Code != 0) { va_list ap; va_start(ap, fmt); - cString buffer = cString::sprintf(fmt, ap); + cString buffer = cString::vsprintf(fmt, ap); va_end(ap); const char *s = buffer; while (s && *s) { @@ -662,14 +662,14 @@ void cSVDRP::CmdDELR(const char *Option) { if (*Option) { if (isnumber(Option)) { - cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1); + cRecording *recording = recordings.Get(strtol(Option, NULL, 10) - 1); if (recording) { cRecordControl *rc = cRecordControls::GetRecordControl(recording->FileName()); if (!rc) { if (!cCutter::Active(recording->FileName())) { if (recording->Delete()) { Reply(250, "Recording \"%s\" deleted", Option); - ::Recordings.DelByName(recording->FileName()); + Recordings.DelByName(recording->FileName()); } else Reply(554, "Error while deleting recording!"); @@ -681,7 +681,7 @@ void cSVDRP::CmdDELR(const char *Option) Reply(550, "Recording \"%s\" is in use by timer %d", Option, rc->Timer()->Index() + 1); } else - Reply(550, "Recording \"%s\" not found%s", Option, Recordings.Count() ? "" : " (use LSTR before deleting)"); + Reply(550, "Recording \"%s\" not found%s", Option, recordings.Count() ? "" : " (use LSTR before deleting)"); } else Reply(501, "Error in recording number \"%s\"", Option); @@ -723,7 +723,7 @@ void cSVDRP::CmdEDIT(const char *Option) { if (*Option) { if (isnumber(Option)) { - cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1); + cRecording *recording = recordings.Get(strtol(Option, NULL, 10) - 1); if (recording) { cMarks Marks; if (Marks.Load(recording->FileName(), recording->FramesPerSecond(), recording->IsPesRecording()) && Marks.Count()) { @@ -740,7 +740,7 @@ void cSVDRP::CmdEDIT(const char *Option) Reply(554, "No editing marks defined"); } else - Reply(550, "Recording \"%s\" not found%s", Option, Recordings.Count() ? "" : " (use LSTR before editing)"); + Reply(550, "Recording \"%s\" not found%s", Option, recordings.Count() ? "" : " (use LSTR before editing)"); } else Reply(501, "Error in recording number \"%s\"", Option); @@ -1076,10 +1076,10 @@ void cSVDRP::CmdLSTE(const char *Option) void cSVDRP::CmdLSTR(const char *Option) { - bool recordings = Recordings.Update(true); + recordings.Update(true); if (*Option) { if (isnumber(Option)) { - cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1); + cRecording *recording = recordings.Get(strtol(Option, NULL, 10) - 1); if (recording) { FILE *f = fdopen(file, "w"); if (f) { @@ -1097,11 +1097,11 @@ void cSVDRP::CmdLSTR(const char *Option) else Reply(501, "Error in recording number \"%s\"", Option); } - else if (recordings) { - cRecording *recording = Recordings.First(); + else if (recordings.Count()) { + cRecording *recording = recordings.First(); while (recording) { - Reply(recording == Recordings.Last() ? 250 : -250, "%d %s", recording->Index() + 1, recording->Title(' ', true)); - recording = Recordings.Next(recording); + Reply(recording == recordings.Last() ? 250 : -250, "%d %s", recording->Index() + 1, recording->Title(' ', true)); + recording = recordings.Next(recording); } } else @@ -1367,11 +1367,11 @@ void cSVDRP::CmdPLAY(const char *Option) char c = *option; *option = 0; if (isnumber(num)) { - cRecording *recording = Recordings.Get(strtol(num, NULL, 10) - 1); + cRecording *recording = recordings.Get(strtol(num, NULL, 10) - 1); if (recording) { if (c) option = skipspace(++option); - cReplayControl::SetRecording(NULL, NULL); + cReplayControl::SetRecording(NULL); cControl::Shutdown(); if (*option) { int pos = 0; @@ -1383,13 +1383,13 @@ void cSVDRP::CmdPLAY(const char *Option) else resume.Save(pos); } - cReplayControl::SetRecording(recording->FileName(), recording->Title()); + cReplayControl::SetRecording(recording->FileName()); cControl::Launch(new cReplayControl); cControl::Attach(); Reply(250, "Playing recording \"%s\" [%s]", num, recording->Title()); } else - Reply(550, "Recording \"%s\" not found%s", num, Recordings.Count() ? "" : " (use LSTR before playing)"); + Reply(550, "Recording \"%s\" not found%s", num, recordings.Count() ? "" : " (use LSTR before playing)"); } else Reply(501, "Error in recording number \"%s\"", num); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: svdrp.h 2.2 2012/02/16 12:37:53 kls Exp $ + * $Id: svdrp.h 2.3 2012/04/26 10:30:06 kls Exp $ */ #ifndef __SVDRP_H @@ -43,7 +43,7 @@ class cSVDRP { private: cSocket socket; cFile file; - cRecordings Recordings; + cRecordings recordings; cPUTEhandler *PUTEhandler; int numChars; int length; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 2.3 2009/04/13 13:50:39 kls Exp $ + * $Id: thread.c 2.4 2012/05/08 11:15:57 kls Exp $ */ #include "thread.h" @@ -239,7 +239,7 @@ void cThread::SetDescription(const char *Description, ...) if (Description) { va_list ap; va_start(ap, Description); - description = strdup(cString::sprintf(Description, ap)); + description = strdup(cString::vsprintf(Description, ap)); va_end(ap); } } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 2.8 2012/02/27 09:38:41 kls Exp $ + * $Id: timers.c 2.9 2012/04/25 09:02:03 kls Exp $ */ #include "timers.h" @@ -142,7 +142,7 @@ cTimer& cTimer::operator= (const cTimer &Timer) int cTimer::Compare(const cListObject &ListObject) const { - cTimer *ti = (cTimer *)&ListObject; + const cTimer *ti = (const cTimer *)&ListObject; time_t t1 = StartTime(); time_t t2 = ti->StartTime(); int r = t1 - t2; @@ -820,3 +820,18 @@ void cTimers::DeleteExpired(void) } lastDeleteExpired = time(NULL); } + +// --- cSortedTimers --------------------------------------------------------- + +static int CompareTimers(const void *a, const void *b) +{ + return (*(const cTimer **)a)->Compare(**(const cTimer **)b); +} + +cSortedTimers::cSortedTimers(void) +:cVector(Timers.Count()) +{ + for (const cTimer *Timer = Timers.First(); Timer; Timer = Timers.Next(Timer)) + Append(Timer); + Sort(CompareTimers); +} @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.h 2.3 2012/02/20 15:52:57 kls Exp $ + * $Id: timers.h 2.4 2012/04/15 13:21:31 kls Exp $ */ #ifndef __TIMERS_H @@ -135,4 +135,9 @@ public: extern cTimers Timers; +class cSortedTimers : public cVector<const cTimer *> { +public: + cSortedTimers(void); + }; + #endif //__TIMERS_H @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 2.22 2012/02/18 15:30:35 kls Exp $ + * $Id: tools.c 2.24 2012/05/12 13:29:20 kls Exp $ */ #include "tools.h" @@ -958,7 +958,7 @@ cString cString::sprintf(const char *fmt, ...) return cString(buffer, true); } -cString cString::sprintf(const char *fmt, va_list &ap) +cString cString::vsprintf(const char *fmt, va_list &ap) { char *buffer; if (!fmt || vasprintf(&buffer, fmt, ap) < 0) { @@ -1042,6 +1042,15 @@ cString DateString(time_t t) return buf; } +cString ShortDateString(time_t t) +{ + char buf[32]; + struct tm tm_r; + tm *tm = localtime_r(&t, &tm_r); + strftime(buf, sizeof(buf), "%d.%m.%y", tm); + return buf; +} + cString TimeString(time_t t) { char buf[25]; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 2.16 2012/02/29 10:41:00 kls Exp $ + * $Id: tools.h 2.21 2012/05/20 13:58:06 kls Exp $ */ #ifndef __TOOLS_H @@ -177,7 +177,7 @@ public: cString &operator=(const char *String); cString &Truncate(int Index); ///< Truncate the string at the given Index (if Index is < 0 it is counted from the end of the string). static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); - static cString sprintf(const char *fmt, va_list &ap); + static cString vsprintf(const char *fmt, va_list &ap); }; ssize_t safe_read(int filedes, void *buffer, size_t size); @@ -228,13 +228,26 @@ void TouchFile(const char *FileName); time_t LastModifiedTime(const char *FileName); off_t FileSize(const char *FileName); ///< returns the size of the given file, or -1 in case of an error (e.g. if the file doesn't exist) cString WeekDayName(int WeekDay); + ///< Converts the given WeekDay (0=Sunday, 1=Monday, ...) to a three letter + ///< day name. cString WeekDayName(time_t t); + ///< Converts the week day of the given time to a three letter day name. cString WeekDayNameFull(int WeekDay); + ///< Converts the given WeekDay (0=Sunday, 1=Monday, ...) to a full + ///< day name. cString WeekDayNameFull(time_t t); + ///< Converts the week day of the given time to a full day name. cString DayDateTime(time_t t = 0); + ///< Converts the given time to a string of the form "www dd.mm. hh:mm". + ///< If no time is given, the current time is taken. cString TimeToString(time_t t); + ///< Converts the given time to a string of the form "www mmm dd hh:mm:ss yyyy". cString DateString(time_t t); + ///< Converts the given time to a string of the form "www dd.mm.yyyy". +cString ShortDateString(time_t t); + ///< Converts the given time to a string of the form "dd.mm.yy". cString TimeString(time_t t); + ///< Converts the given time to a string of the form "hh:mm". uchar *RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality = 100); ///< Converts the given Memory to a JPEG image and returns a pointer ///< to the resulting image. Mem must point to a data block of exactly @@ -457,6 +470,7 @@ public: }; template<class T> class cVector { + ///< cVector may only be used for *simple* types, like int or pointers - not for class objects that allocate additional memory! private: mutable int allocated; mutable int size; @@ -515,7 +529,7 @@ public: virtual void Append(T Data) { if (size >= allocated) - Realloc(allocated * 4 / 2); // increase size by 50% + Realloc(allocated * 3 / 2); // increase size by 50% data[size++] = Data; } virtual void Remove(int Index) @@ -526,6 +540,8 @@ public: } virtual void Clear(void) { + for (int i = 0; i < size; i++) + data[i] = T(0); size = 0; } void Sort(__compar_fn_t Compare) @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 2.35 2012/03/14 09:09:19 kls Exp $ + * $Id: vdr.c 2.36 2012/04/26 09:23:41 kls Exp $ */ #include <getopt.h> @@ -56,6 +56,7 @@ #include "recording.h" #include "shutdown.h" #include "skinclassic.h" +#include "skinlcars.h" #include "skinsttng.h" #include "sourceparams.h" #include "sources.h" @@ -677,6 +678,7 @@ int main(int argc, char *argv[]) // Default skins: + new cSkinLCARS; new cSkinSTTNG; new cSkinClassic; Skins.SetCurrent(Setup.OSDSkin); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: videodir.c 2.0 2008/02/16 13:00:03 kls Exp $ + * $Id: videodir.c 2.1 2012/04/22 15:03:10 kls Exp $ */ #include "videodir.h" @@ -241,3 +241,43 @@ bool IsOnVideoDirectoryFileSystem(const char *FileName) } while (Dir.Next()); return false; } + +// --- cVideoDiskUsage ------------------------------------------------------- + +#define DISKSPACECHEK 5 // seconds between disk space checks +#define MB_PER_MINUTE 25.75 // this is just an estimate! + +int cVideoDiskUsage::state = 0; +time_t cVideoDiskUsage::lastChecked = 0; +int cVideoDiskUsage::usedPercent = 0; +int cVideoDiskUsage::freeMB = 0; +int cVideoDiskUsage::freeMinutes = 0; + +bool cVideoDiskUsage::HasChanged(int &State) +{ + if (time(NULL) - lastChecked > DISKSPACECHEK) { + int FreeMB; + int UsedPercent = VideoDiskSpace(&FreeMB); + if (FreeMB != freeMB) { + usedPercent = UsedPercent; + freeMB = FreeMB; + int MBperMinute = Recordings.MBperMinute(); + if (MBperMinute <= 0) + MBperMinute = MB_PER_MINUTE; + freeMinutes = int(double(FreeMB) / MBperMinute); + state++; + } + lastChecked = time(NULL); + } + if (State != state) { + State = state; + return true; + } + return false; +} + +cString cVideoDiskUsage::String(void) +{ + HasChanged(state); + return cString::sprintf("%s %d%% - %2d:%02d %s", tr("Disk"), usedPercent, freeMinutes / 60, freeMinutes % 60, tr("free")); +} @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: videodir.h 2.0 2008/02/16 12:53:11 kls Exp $ + * $Id: videodir.h 2.1 2012/04/22 15:07:56 kls Exp $ */ #ifndef __VIDEODIR_H @@ -25,4 +25,42 @@ cString PrefixVideoFileName(const char *FileName, char Prefix); void RemoveEmptyVideoDirectories(void); bool IsOnVideoDirectoryFileSystem(const char *FileName); +class cVideoDiskUsage { +private: + static int state; + static time_t lastChecked; + static int usedPercent; + static int freeMB; + static int freeMinutes; +public: + static bool HasChanged(int &State); + ///< Returns true if the usage of the video disk space has changed since the last + ///< call to this function with the given State variable. The caller should + ///< initialize State to -1, and it will be set to the current internal state + ///< value of the video disk usage checker upon return. Future calls with the same + ///< State variable can then quickly check for changes. + static void ForceCheck(void) { lastChecked = 0; } + ///< To avoid unnecessary load, the video disk usage is only actually checked + ///< every DISKSPACECHEK seconds. Calling ForceCheck() makes sure that the next call + ///< to HasChanged() will check the disk usage immediately. This is useful in case + ///< some files have been deleted and the result shall be displayed instantly. + static cString String(void); + ///< Returns a localized string of the form "Disk nn% - hh:mm free". + ///< This function is mainly for use in skins that want to retain the display of the + ///< free disk space in the menu title, as was the case until VDR version 1.7.27. + ///< An implicit call to HasChanged() is done in this function, to make sure the + ///< returned value is up to date. + static int UsedPercent(void) { return usedPercent; } + ///< Returns the used space of the video disk in percent. + ///< The caller should call HasChanged() first, to make sure the value is up to date. + static int FreeMB(void) { return freeMB; } + ///< Returns the amount of free space on the video disk in MB. + ///< The caller should call HasChanged() first, to make sure the value is up to date. + static int FreeMinutes(void) { return freeMinutes; } + ///< Returns the number of minutes that can still be recorded on the video disk. + ///< This is an estimate and depends on the data rate of the existing recordings. + ///< There is no guarantee that this value will actually be met. + ///< The caller should call HasChanged() first, to make sure the value is up to date. + }; + #endif //__VIDEODIR_H |