From dbf38b7c68911187b6a48688b738c31612d35984 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 14 Oct 2007 18:00:00 +0200 Subject: =?UTF-8?q?Version=201.5.10=20-=20Implemented=20handling=20DVB=20s?= =?UTF-8?q?ubtitles=20(thanks=20to=20Marco=20Schl=C3=BC=C3=9Fler,=20and=20?= =?UTF-8?q?also=20to=20=20=20Pekka=20Virtanen=20for=20writing=20the=20subt?= =?UTF-8?q?itle=20plugin,=20which=20helped=20in=20implementing=20=20=20sub?= =?UTF-8?q?title=20handling=20in=20VDR).=20-=20The=20new=20remote=20contro?= =?UTF-8?q?l=20key=20"Subtitles"=20can=20be=20used=20to=20bring=20up=20the?= =?UTF-8?q?=20list=20=20=20of=20available=20subtitles.=20-=20The=20new=20s?= =?UTF-8?q?etup=20option=20"DVB/Subtitle=20languages"=20can=20be=20used=20?= =?UTF-8?q?to=20define=20the=20=20=20preferred=20languages=20for=20subtitl?= =?UTF-8?q?es.=20-=20Fixed=20selecting=20the=20audio=20track=20when=20pres?= =?UTF-8?q?sing=20Ok=20in=20the=20Audio=20menu=20(thanks=20=20=20to=20Marc?= =?UTF-8?q?o=20Schl=C3=BC=C3=9Fler).=20-=20Implemented=20display=20of=20DV?= =?UTF-8?q?B=20subtitles=20in=20live=20viewing=20mode.=20-=20Implemented?= =?UTF-8?q?=20subtitle=20track=20selection.=20-=20Implemented=20bitmap=20c?= =?UTF-8?q?olor=20reduction=20and=20shrinking=20to=20display=20subtitles?= =?UTF-8?q?=20even=20=20=20on=20devices=20that=20can't=20display=20the=20n?= =?UTF-8?q?ecessary=20number=20of=20colors.=20-=20Added=20compatibility=20?= =?UTF-8?q?mode=20for=20playback=20of=20recordings=20made=20with=20the=20s?= =?UTF-8?q?ubtitles=20=20=20plugin=20(with=20some=20help=20from=20Rolf=20A?= =?UTF-8?q?hrenberg).=20-=20The=20new=20setup=20option=20"DVB/Subtitle=20o?= =?UTF-8?q?ffset"=20can=20be=20used=20to=20shift=20the=20location=20=20=20?= =?UTF-8?q?of=20the=20subtitles=20in=20the=20vertical=20direction.=20-=20T?= =?UTF-8?q?he=20new=20setup=20options=20"DVB/Subtitle=20foreground/backgro?= =?UTF-8?q?und=20transparency"=20=20=20define=20an=20additional=20level=20?= =?UTF-8?q?of=20transparency=20for=20the=20foreground=20and=20background?= =?UTF-8?q?=20=20=20color=20of=20subtitles.=20-=20Existing=20recordings=20?= =?UTF-8?q?made=20with=20the=20subtitle=20plugin=20can=20be=20given=20an?= =?UTF-8?q?=20'X'=20record=20=20=20in=20their=20info.vdr=20file,=20so=20th?= =?UTF-8?q?at=20subtitles=20can=20be=20automatically=20selected=20upon=20?= =?UTF-8?q?=20=20replay,=20according=20to=20the=20preferred=20language=20s?= =?UTF-8?q?etup,=20as=20in=20=20=20X=203=2003=20ger=20deutsch=20=20=20(see?= =?UTF-8?q?=20vdr.5).=20Note=20that=20these=20entries=20need=20to=20be=20a?= =?UTF-8?q?dded=20in=20the=20proper=20sequence,=20=20=20so=20that=20they?= =?UTF-8?q?=20correspond=20with=20the=20actual=20track=20languages=20in=20?= =?UTF-8?q?the=20recording.=20-=20Now=20generating=20translation=20files?= =?UTF-8?q?=20without=20line=20numbers=20to=20avoid=20unnecessarily=20=20?= =?UTF-8?q?=20large=20diffs.=20Plugin=20authors=20may=20want=20to=20replac?= =?UTF-8?q?e=20the=20-F=20option=20with=20=20=20--no-location=20in=20the?= =?UTF-8?q?=20xgettext=20and=20msgmerge=20calls=20in=20their=20Makefiles.?= =?UTF-8?q?=20-=20Updated=20the=20Finnish=20OSD=20texts=20(thanks=20to=20R?= =?UTF-8?q?olf=20Ahrenberg).=20-=20Added=20a=20missing=20Channels.SetModif?= =?UTF-8?q?ied(true)=20call=20when=20deleting=20or=20moving=20a=20=20=20ch?= =?UTF-8?q?annel=20in=20the=20Channels=20menu=20(reported=20by=20Halim=20S?= =?UTF-8?q?ahin).=20-=20Fixed=20a=20missing=20'-'=20at=20the=20next=20to?= =?UTF-8?q?=20last=20line=20of=20SVDRP=20help=20texts=20(reported=20by=20?= =?UTF-8?q?=20=20Denis=20Knauf).=20-=20Added=20a=20missing=20SetVolumeDevi?= =?UTF-8?q?ce()=20call=20in=20cDevice::SetPrimaryDevice()=20(reported=20?= =?UTF-8?q?=20=20by=20Reinhard=20Nissl).=20-=20Fixed=20a=20crash=20when=20?= =?UTF-8?q?pressing=20Left=20while=20at=20the=20first=20character=20of=20a?= =?UTF-8?q?=20cMenuEditStrItem=20=20=20(thanks=20to=20Christian=20Wieninge?= =?UTF-8?q?r).=20-=20Only=20creating=20a=20new=20cDvbOsdProvider=20in=20cD?= =?UTF-8?q?vbDevice::MakePrimaryDevice()=20if=20'On'=20=20=20is=20true=20(?= =?UTF-8?q?i.e.=20this=20device=20is=20being=20made=20the=20primary=20devi?= =?UTF-8?q?ce).=20-=20Updated=20the=20Italian=20OSD=20texts=20(thanks=20to?= =?UTF-8?q?=20Diego=20Pierotto).=20-=20Fixed=20handling=20reallocated=20me?= =?UTF-8?q?mory=20in=20cCharSetConv::Convert()=20(reported=20by=20Udo=20?= =?UTF-8?q?=20=20Richter).=20-=20Fixed=20a=20new[]/delete=20mismatch=20in?= =?UTF-8?q?=20cMenuEditStrItem::LeaveEditMode()=20(thanks=20to=20=20=20Udo?= =?UTF-8?q?=20Richter).=20-=20Implemented=20sending=20all=20frames=20to=20?= =?UTF-8?q?devices=20that=20can=20handle=20them=20in=20fast=20forward=20?= =?UTF-8?q?=20=20trick=20speeds=20(thanks=20to=20Timo=20Eskola).=20-=20Upd?= =?UTF-8?q?ated=20the=20Hungarian=20language=20texts=20(thanks=20to=20Thom?= =?UTF-8?q?as=20G=C3=BCnther).=20-=20Fixed=20description=20of=20DeviceSetA?= =?UTF-8?q?vailableTrack()=20and=20cReceiver(),=20and=20added=20an=20=20?= =?UTF-8?q?=20example=20~cMyReceiver()=20in=20PLUGINS.html=20(thanks=20to?= =?UTF-8?q?=20Marco=20Schl=C3=BC=C3=9Fler).=20-=20Improved=20the=20descrip?= =?UTF-8?q?tion=20of=20where=20logging=20goes=20in=20the=20INSTALL=20file?= =?UTF-8?q?=20(thanks=20to=20=20=20Elias=20Luttinen).=20-=20Added=20a=20no?= =?UTF-8?q?te=20about=20how=20to=20initiate=20internationalization=20suppo?= =?UTF-8?q?rt=20to=20the=20=20=20README.i18n=20file.=20The=20Makefile=20ge?= =?UTF-8?q?nerated=20by=20the=20'newplugin'=20script=20now=20has=20the=20?= =?UTF-8?q?=20=20'i18n'=20target=20automatically=20create=20an=20initial?= =?UTF-8?q?=20'po/pluginname.pot'=20file.=20=20=20Plugin=20authors=20may?= =?UTF-8?q?=20want=20to=20add=20the=20'$(I18Npot)'=20dependency=20to=20the?= =?UTF-8?q?=20'i18n'=20=20=20target=20in=20their=20Makefiles,=20as=20in=20?= =?UTF-8?q?=20=20i18n:=20$(I18Npot)=20$(I18Nmo)=20=20=20(based=20on=20a=20?= =?UTF-8?q?suggestion=20by=20Torsten=20Kunkel).=20-=20Removed=20a=20duplic?= =?UTF-8?q?ate=20','=20from=20the=20ca=5FES.po=20file=20(thanks=20to=20Tho?= =?UTF-8?q?mas=20G=C3=BCnther).=20-=20Added=20the=20'=C3=9F'=20character?= =?UTF-8?q?=20to=20the=20"allowed=20characters"=20in=20the=20de=5FDE.po=20?= =?UTF-8?q?file=20=20=20(suggested=20by=20Thomas=20G=C3=BCnther).=20-=20Ma?= =?UTF-8?q?de=20the=20default=20copy=20ctor=20of=20cRecording=20private=20?= =?UTF-8?q?(thanks=20to=20Markus=20Hahn).=20=20=20Same=20for=20the=20assig?= =?UTF-8?q?n=20operator.=20-=20Added=20cRecording::Undelete()=20(based=20o?= =?UTF-8?q?n=20a=20patch=20from=20Markus=20Hahn).=20-=20Added=20cDevice::C?= =?UTF-8?q?loseFilter()=20to=20allow=20a=20device=20to=20have=20complete?= =?UTF-8?q?=20control=20over=20=20=20both=20opening=20and=20closing=20sect?= =?UTF-8?q?ion=20filters=20(thanks=20to=20Rolf=20Ahrenberg).=20-=20Some=20?= =?UTF-8?q?fixes=20to=20PLUGINS.html=20(thanks=20to=20Rolf=20Ahrenberg).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- menu.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 155 insertions(+), 9 deletions(-) (limited to 'menu.c') diff --git a/menu.c b/menu.c index 444fd75..853d1e7 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.461 2007/08/24 13:15:48 kls Exp $ + * $Id: menu.c 1.463 2007/10/13 10:10:20 kls Exp $ */ #include "menu.h" @@ -260,6 +260,8 @@ void cMenuEditChannel::Setup(void) Add(new cMenuEditIntItem( tr("Apid2"), &data.apids[1], 0, 0x1FFF)); Add(new cMenuEditIntItem( tr("Dpid1"), &data.dpids[0], 0, 0x1FFF)); Add(new cMenuEditIntItem( tr("Dpid2"), &data.dpids[1], 0, 0x1FFF)); + Add(new cMenuEditIntItem( tr("Spid1"), &data.spids[0], 0, 0x1FFF)); + Add(new cMenuEditIntItem( tr("Spid2"), &data.spids[1], 0, 0x1FFF)); Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0x1FFF)); Add(new cMenuEditCaItem( tr("CA"), &data.caids[0])); Add(new cMenuEditIntItem( tr("Sid"), &data.sid, 1, 0xFFFF)); @@ -523,6 +525,7 @@ eOSState cMenuChannels::Delete(void) Channels.Del(channel); cOsdMenu::Del(Index); Propagate(); + Channels.SetModified(true); isyslog("channel %d deleted", DeletedChannel); if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) @@ -547,6 +550,7 @@ void cMenuChannels::Move(int From, int To) Channels.Move(FromChannel, ToChannel); cOsdMenu::Move(From, To); Propagate(); + Channels.SetModified(true); isyslog("channel %d moved to %d", FromNumber, ToNumber); if (CurrentChannel && CurrentChannel->Number() != CurrentChannelNr) { if (!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring()) @@ -2400,6 +2404,8 @@ class cMenuSetupDVB : public cMenuSetupBase { private: int originalNumAudioLanguages; int numAudioLanguages; + int originalNumSubtitleLanguages; + int numSubtitleLanguages; void Setup(void); const char *videoDisplayFormatTexts[3]; const char *updateChannelsTexts[6]; @@ -2412,7 +2418,10 @@ cMenuSetupDVB::cMenuSetupDVB(void) { for (numAudioLanguages = 0; numAudioLanguages < I18nLanguages()->Size() && data.AudioLanguages[numAudioLanguages] >= 0; numAudioLanguages++) ; + for (numSubtitleLanguages = 0; numSubtitleLanguages < I18nLanguages()->Size() && data.SubtitleLanguages[numSubtitleLanguages] >= 0; numSubtitleLanguages++) + ; originalNumAudioLanguages = numAudioLanguages; + originalNumSubtitleLanguages = numSubtitleLanguages; videoDisplayFormatTexts[0] = tr("pan&scan"); videoDisplayFormatTexts[1] = tr("letterbox"); videoDisplayFormatTexts[2] = tr("center cut out"); @@ -2442,6 +2451,15 @@ void cMenuSetupDVB::Setup(void) Add(new cMenuEditIntItem( tr("Setup.DVB$Audio languages"), &numAudioLanguages, 0, I18nLanguages()->Size())); for (int i = 0; i < numAudioLanguages; i++) Add(new cMenuEditStraItem(tr("Setup.DVB$Audio language"), &data.AudioLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0))); + Add(new cMenuEditBoolItem(tr("Setup.DVB$Display subtitles"), &data.DisplaySubtitles)); + if (data.DisplaySubtitles) { + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle languages"), &numSubtitleLanguages, 0, I18nLanguages()->Size())); + for (int i = 0; i < numSubtitleLanguages; i++) + Add(new cMenuEditStraItem(tr("Setup.DVB$Subtitle language"), &data.SubtitleLanguages[i], I18nLanguages()->Size(), &I18nLanguages()->At(0))); + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle offset"), &data.SubtitleOffset, -50, 50)); + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); + } SetCurrent(Get(current)); Display(); @@ -2453,11 +2471,15 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key) int oldVideoDisplayFormat = ::Setup.VideoDisplayFormat; bool oldVideoFormat = ::Setup.VideoFormat; bool newVideoFormat = data.VideoFormat; + bool oldDisplaySubtitles = ::Setup.DisplaySubtitles; + bool newDisplaySubtitles = data.DisplaySubtitles; int oldnumAudioLanguages = numAudioLanguages; + int oldnumSubtitleLanguages = numSubtitleLanguages; eOSState state = cMenuSetupBase::ProcessKey(Key); if (Key != kNone) { bool DoSetup = data.VideoFormat != newVideoFormat; + DoSetup |= data.DisplaySubtitles != newDisplaySubtitles; if (numAudioLanguages != oldnumAudioLanguages) { for (int i = oldnumAudioLanguages; i < numAudioLanguages; i++) { data.AudioLanguages[i] = 0; @@ -2476,6 +2498,24 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key) data.AudioLanguages[numAudioLanguages] = -1; DoSetup = true; } + if (numSubtitleLanguages != oldnumSubtitleLanguages) { + for (int i = oldnumSubtitleLanguages; i < numSubtitleLanguages; i++) { + data.SubtitleLanguages[i] = 0; + for (int l = 0; l < I18nLanguages()->Size(); l++) { + int k; + for (k = 0; k < oldnumSubtitleLanguages; k++) { + if (data.SubtitleLanguages[k] == l) + break; + } + if (k >= oldnumSubtitleLanguages) { + data.SubtitleLanguages[i] = l; + break; + } + } + } + data.SubtitleLanguages[numSubtitleLanguages] = -1; + DoSetup = true; + } if (DoSetup) Setup(); } @@ -2486,6 +2526,9 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key) cDevice::PrimaryDevice()->SetVideoDisplayFormat(eVideoDisplayFormat(::Setup.VideoDisplayFormat)); if (::Setup.VideoFormat != oldVideoFormat) cDevice::PrimaryDevice()->SetVideoFormat(::Setup.VideoFormat); + if (::Setup.DisplaySubtitles != oldDisplaySubtitles) + cDevice::PrimaryDevice()->EnsureSubtitleTrack(); + cDvbSubtitleConverter::SetupChanged(); } return state; } @@ -3128,14 +3171,18 @@ static void SetTrackDescriptions(int LiveChannel) if (Components) { int indexAudio = 0; int indexDolby = 0; + int indexSubtitle = 0; for (int i = 0; i < Components->NumComponents(); i++) { const tComponent *p = Components->Component(i); - if (p->stream == 2) { - if (p->type == 0x05) - cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, LiveChannel ? NULL : p->language, p->description); - else - cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, LiveChannel ? NULL : p->language, p->description); - } + switch (p->stream) { + case 2: if (p->type == 0x05) + cDevice::PrimaryDevice()->SetAvailableTrack(ttDolby, indexDolby++, 0, LiveChannel ? NULL : p->language, p->description); + else + cDevice::PrimaryDevice()->SetAvailableTrack(ttAudio, indexAudio++, 0, LiveChannel ? NULL : p->language, p->description); + break; + case 3: cDevice::PrimaryDevice()->SetAvailableTrack(ttSubtitle, indexSubtitle++, 0, LiveChannel ? NULL : p->language, p->description); + break; + } } } } @@ -3491,7 +3538,7 @@ cDisplayTracks::cDisplayTracks(void) numTracks++; } } - descriptions[numTracks] = 0; + descriptions[numTracks] = NULL; timeout.Set(TRACKTIMEOUT); displayTracks = Skins.Current()->DisplayTracks(tr("Button$Audio"), numTracks, descriptions); Show(); @@ -3569,7 +3616,7 @@ eOSState cDisplayTracks::ProcessKey(eKeys Key) timeout.Set(TRACKTIMEOUT); break; case kOk: - if (track != cDevice::PrimaryDevice()->GetCurrentAudioTrack()) + if (types[track] != cDevice::PrimaryDevice()->GetCurrentAudioTrack()) oldTrack = -1; // make sure we explicitly switch to that track timeout.Set(); break; @@ -3588,6 +3635,105 @@ eOSState cDisplayTracks::ProcessKey(eKeys Key) return timeout.TimedOut() ? osEnd : osContinue; } +// --- cDisplaySubtitleTracks ------------------------------------------------ + +cDisplaySubtitleTracks *cDisplaySubtitleTracks::currentDisplayTracks = NULL; + +cDisplaySubtitleTracks::cDisplaySubtitleTracks(void) +:cOsdObject(true) +{ + SetTrackDescriptions(!cDevice::PrimaryDevice()->Replaying() || cDevice::PrimaryDevice()->Transferring() ? cDevice::CurrentChannel() : 0); + currentDisplayTracks = this; + numTracks = track = 0; + types[numTracks] = ttNone; + descriptions[numTracks] = strdup(tr("No subtitles")); + numTracks++; + eTrackType CurrentSubtitleTrack = cDevice::PrimaryDevice()->GetCurrentSubtitleTrack(); + for (int i = ttSubtitleFirst; i <= ttSubtitleLast; i++) { + const tTrackId *TrackId = cDevice::PrimaryDevice()->GetTrack(eTrackType(i)); + if (TrackId && TrackId->id) { + types[numTracks] = eTrackType(i); + descriptions[numTracks] = strdup(*TrackId->description ? TrackId->description : *TrackId->language ? TrackId->language : *itoa(i)); + if (i == CurrentSubtitleTrack) + track = numTracks; + numTracks++; + } + } + descriptions[numTracks] = NULL; + timeout.Set(TRACKTIMEOUT); + displayTracks = Skins.Current()->DisplayTracks(tr("Button$Subtitles"), numTracks, descriptions); + Show(); +} + +cDisplaySubtitleTracks::~cDisplaySubtitleTracks() +{ + delete displayTracks; + currentDisplayTracks = NULL; + for (int i = 0; i < numTracks; i++) + free(descriptions[i]); + cStatus::MsgOsdClear(); +} + +void cDisplaySubtitleTracks::Show(void) +{ + displayTracks->SetTrack(track, descriptions); + displayTracks->Flush(); + //cStatus::MsgSetSubtitleTrack(track, descriptions); //TODO better make a more general cStatus::MsgSetTrack(tr("Subtitles"), track, descriptions) +} + +cDisplaySubtitleTracks *cDisplaySubtitleTracks::Create(void) +{ + if (cDevice::PrimaryDevice()->NumSubtitleTracks() > 0) { + if (!currentDisplayTracks) + new cDisplaySubtitleTracks; + return currentDisplayTracks; + } + Skins.Message(mtWarning, tr("No subtitles available!")); + return NULL; +} + +void cDisplaySubtitleTracks::Process(eKeys Key) +{ + if (currentDisplayTracks) + currentDisplayTracks->ProcessKey(Key); +} + +eOSState cDisplaySubtitleTracks::ProcessKey(eKeys Key) +{ + int oldTrack = track; + switch (Key) { + case kUp|k_Repeat: + case kUp: + case kDown|k_Repeat: + case kDown: + if (NORMALKEY(Key) == kUp && track > 0) + track--; + else if (NORMALKEY(Key) == kDown && track < numTracks - 1) + track++; + timeout.Set(TRACKTIMEOUT); + break; + case kSubtitles|k_Repeat: + case kSubtitles: + if (++track >= numTracks) + track = 0; + timeout.Set(TRACKTIMEOUT); + break; + case kOk: + if (types[track] != cDevice::PrimaryDevice()->GetCurrentSubtitleTrack()) + oldTrack = -1; // make sure we explicitly switch to that track + timeout.Set(); + break; + case kNone: break; + default: if ((Key & k_Release) == 0) + return osEnd; + } + if (track != oldTrack) { + Show(); + cDevice::PrimaryDevice()->SetCurrentSubtitleTrack(types[track], true); + } + return timeout.TimedOut() ? osEnd : osContinue; +} + // --- cRecordControl -------------------------------------------------------- cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) -- cgit v1.2.3