diff --git a/sources b/sources index 1c6234a..10831ff 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (vdr-live-3.5.3.tar.gz) = b41e559d8bfe1d21301bfc852f91c92155baed49823d2bbf8fe9d36955b93ddd8aaebf4e4ba2fc1427c60876f2889a36846ca894f320fb5e6b7cdb37f6ac2a58 +SHA512 (vdr-plugin-live-e582514ede475574842b44ca6792335ff141172d.tar.bz2) = b05af30d46ea09dc38255de93600e0c3e143f25c874df76f9b45a57b8b3f0e788de7083841e28b57041e459dc921a34fafd93d9504713ac0f9d28bf95207a28f diff --git a/vdr-live.spec b/vdr-live.spec index 4c5997e..af8045a 100644 --- a/vdr-live.spec +++ b/vdr-live.spec @@ -1,41 +1,34 @@ -# https://github.com/MarkusEh/vdr-plugin-live/commit/9967f1d6757a4f4855a6b07abf526258838dd5ac -%global commit0 9967f1d6757a4f4855a6b07abf526258838dd5ac +# https://projects.vdr-developer.org/git/vdr-plugin-live.git/commit/?id=e582514ede475574842b44ca6792335ff141172d +%global commit0 e582514ede475574842b44ca6792335ff141172d %global shortcommit0 %(c=%{commit0}; echo ${c:0:7}) -%global gitdate 20241103 -# Set vdr_version based on Fedora version -%if 0%{?fedora} >= 43 -%global vdr_version 2.7.7 -%elif 0%{?fedora} == 42 -%global vdr_version 2.7.4 -%else -%global vdr_version 2.6.9 -%endif +%global gitdate 20170623 Name: vdr-live -Version: 3.5.3 -# Release: 0.2.%%{gitdate}git%%{shortcommit0}%%{?dist} -Release: 1%{?dist} -Summary: An interactive web interface with HTML5 live stream support for VDR +Version: 2.3.1 +Release: 11.%{gitdate}git%{shortcommit0}%{?dist} +Summary: An interactive web interface for VDR -# The entire source code is GPL-2.0-or-later except live/js/mootools/ which is LicenseRef-Callaway-MIT -License: GPL-2.0-or-later AND LicenseRef-Callaway-MIT -URL: https://github.com/MarkusEh/vdr-plugin-live -# Source0: https://github.com/MarkusEh/vdr-plugin-live/archive/%%{commit0}/%%{name}-%%{version}-%%{shortcommit0}.tar.gz -Source0: https://github.com/MarkusEh/vdr-plugin-live/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz +# The entire source code is GPLv2+ except live/js/mootools/ which is MIT +License: GPLv2+ and MIT +URL: http://projects.vdr-developer.org/projects/plg-live +# how to get the tarball +# go to http://projects.vdr-developer.org/git/vdr-plugin-live.git/commit/ +# click the link behind commit, then select the download links below. +Source0: http://projects.vdr-developer.org/git/vdr-plugin-live.git/snapshot/vdr-plugin-live-%{commit0}.tar.bz2 Source1: %{name}.conf +# Patch to mark and sort new recordings + more gadgets +# https://www.vdr-portal.de/index.php?attachment/42233-vdr-plugin-live-2018-11-04-diff/ +Patch0: vdr-plugin-live_2018-11-04.diff -BuildRequires: make BuildRequires: gcc-c++ -BuildRequires: gettext -BuildRequires: vdr-devel >= %{vdr_version} -BuildRequires: pcre2-devel +BuildRequires: vdr-devel >= 2.2.0 +BuildRequires: pcre-devel BuildRequires: tntnet-devel BuildRequires: cxxtools-devel Requires: vdr(abi)%{?_isa} = %{vdr_apiversion} Requires: %{name}-data = %{version}-%{release} %description -New version with HTML5 live stream support. Live, the "Live Interactive VDR Environment", is a plugin providing the possibility to interactively control the VDR and some of it's plugins by a web interface. @@ -53,8 +46,8 @@ Requires: %{name} = %{version}-%{release} This package contains images, themes and JavaScript. %prep -#%%autosetup -p1 -n vdr-plugin-live-%{commit0} -%autosetup -p1 -n vdr-plugin-live-%{version} +%setup -q -n vdr-plugin-live-%{commit0} +%patch0 -p1 # delete unused directories and files find -name .git -type d -or -name gitignore -type d | xargs rm -rfv @@ -64,11 +57,13 @@ rm -rf httpd iconv -f iso-8859-1 -t utf-8 README > README.utf8 ; mv README.utf8 README +sed -i -e 's|std::auto_ptr|std::unique_ptr|' thread.h + %build -%make_build CFLAGS="%{optflags} -fPIC" CXXFLAGS="%{optflags} -fPIC" +make CFLAGS="%{optflags} -fPIC" CXXFLAGS="%{optflags} -fPIC" all %install -%make_install +make install DESTDIR=%{buildroot} # live.conf install -Dpm 644 %{SOURCE1} \ @@ -76,287 +71,21 @@ install -Dpm 644 %{SOURCE1} \ %find_lang %{name} +install -dm 755 %{buildroot}%{vdr_resdir}/plugins/live +cp -pR live/* %{buildroot}%{vdr_resdir}/plugins/live + + %files -f %{name}.lang %doc CONTRIBUTORS README %license COPYING %config(noreplace) %{_sysconfdir}/sysconfig/vdr-plugins.d/live.conf -%config(noreplace) %{_sysconfdir}/vdr/plugins/live/ffmpeg.conf %{vdr_plugindir}/libvdr-*.so.%{vdr_apiversion} %files data %{vdr_resdir}/plugins/live/ + %changelog -* Fri Dec 19 2025 Martin Gansser - 3.5.3-1 -- Update to 3.5.3 - -* Fri Oct 10 2025 Martin Gansser - 3.5.2-1 -- Update to 3.5.2 - -* Fri Jul 25 2025 Martin Gansser - 3.5.1-3 -- Rebuilt for new VDR API version 2.7.7 - -* Fri Jul 25 2025 Fedora Release Engineering - 3.5.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Tue Jul 01 2025 Martin Gansser - 3.5.1-1 -- Update to 3.5.1 - -* Sat Jun 21 2025 Martin Gansser - 3.5.0-3 -- Rebuilt for new VDR API version 2.7.6 - -* Tue May 27 2025 Martin Gansser - 3.5.0-2 -- Rebuilt for new VDR API version 2.7.5 - -* Sat Apr 19 2025 Martin Gansser - 3.5.0-1 -- Update to 3.5.0 - -* Sun Mar 02 2025 Martin Gansser - 3.4.2-1 -- Update to 3.4.2 - -* Fri Feb 28 2025 Martin Gansser - 3.4.1-3 -- Rebuilt for new VDR API version 2.7.4 - -* Thu Feb 06 2025 Martin Gansser - 3.4.1-2 -- Rebuild - -* Tue Feb 04 2025 Martin Gansser - 3.4.1-1 -- Update to 3.4.1 - -* Sun Jan 19 2025 Fedora Release Engineering - 3.4.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Thu Jan 02 2025 Martin Gansser - 3.4.0-1 -- Update to 3.4.0 - -* Sun Dec 22 2024 Martin Gansser - 3.3.12-1 -- Update to 3.3.12 - -* Wed Dec 11 2024 Martin Gansser - 3.3.11-1 -- Update to 3.3.11 - -* Tue Nov 19 2024 Martin Gansser - 3.3.10-1 -- Update to 3.3.10 - -* Tue Nov 05 2024 Martin Gansser - 3.3.9-1 -- Update to 3.3.9 - -* Sun Nov 03 2024 Martin Gansser - 3.3.9-0.2.20241103git9967f1d -- Update to 3.3.9-0.2.20241103git9967f1d - -* Sat Nov 02 2024 Martin Gansser - 3.3.9-0.1.20241101gitf67dfc0 -- Update to 3.3.9-0.1.20241101gitf67dfc0 - -* Sat Oct 26 2024 Martin Gansser - 3.3.8-1 -- Update to 3.3.8 - -* Tue Oct 22 2024 Martin Gansser - 3.3.8-0.2.20241022git8b97db3 -- Update to 3.3.8-0.2.20241022git8b97db3 - -* Wed Oct 09 2024 Martin Gansser - 3.3.8-0.1.20241008git80b8da8 -- Rebuilt for new VDR API version 2.7.2 -- Update to 3.3.8-0.1.20241008git80b8da8 - -* Mon Sep 30 2024 Martin Gansser - 3.3.7-1 -- Update to 3.3.7 - -* Wed Sep 04 2024 Miroslav Suchý - 3.3.5-5 -- convert license to SPDX - -* Sat Jul 20 2024 Fedora Release Engineering - 3.3.5-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Mon Jul 15 2024 Martin Gansser - 3.3.5-3 -- Rebuilt for new VDR API version 2.6.9 - -* Fri Jul 12 2024 Martin Gansser - 3.3.5-2 -- Rebuilt for new VDR API version 2.6.8 - -* Fri Apr 12 2024 Martin Gansser - 3.3.5-1 -- Update to 3.3.5 -- Rebuilt for new VDR API version - -* Fri Jan 26 2024 Martin Gansser - 3.3.4-2 -- Rebuilt for new VDR API version - -* Fri Jan 05 2024 Martin Gansser - 3.3.4-1 -- Rebuilt for new VDR API version -- Add BR gettext for rawhide - -* Wed Dec 20 2023 Martin Gansser - 3.3.3-1 -- Update to 3.3.3 - -* Mon Nov 27 2023 Martin Gansser - 3.3.2-1 -- Update to 3.3.2 - -* Tue Nov 21 2023 Martin Gansser - 3.3.1-1 -- Update to 3.3.1 - -* Sun Nov 19 2023 Martin Gansser - 3.3.0-1 -- Update to 3.3.0 - -* Tue Oct 03 2023 Martin Gansser - 3.2.1-1 -- Update to 3.2.1 - -* Sat Jul 22 2023 Fedora Release Engineering - 3.2.0-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Sun Jun 11 2023 Martin Gansser - 3.2.0-1 -- Update to 3.2.0 - -* Sun Jun 11 2023 Martin Gansser - 3.1.12-1 -- Update to 3.1.12 -- Add %{name}-timerconflict.patch - -* Tue Jan 24 2023 Martin Gansser - 3.1.11-3 -- Rebuilt - -* Sat Jan 21 2023 Fedora Release Engineering - 3.1.11-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Wed Jan 18 2023 Martin Gansser - 3.1.11-1 -- Update to 3.1.11 - -* Fri Jan 06 2023 Martin Gansser - 3.1.10-2 -- Rebuilt - -* Mon Dec 26 2022 Martin Gansser - 3.1.10-1 -- Update to 3.1.10 - -* Wed Dec 14 2022 Martin Gansser - 3.1.9-3 -- Rebuilt for new VDR API version - -* Thu Dec 01 2022 Martin Gansser - 3.1.9-2 -- Rebuilt for new VDR API version - -* Sun Nov 27 2022 Martin Gansser - 3.1.9-1 -- Updatae to 3.1.9 - -* Thu Nov 17 2022 Martin Gansser - 3.1.8-2 -- Rebuilt due undefined symbol: _ZN7vdrlive6cUsers14logged_in_userB5cxx11E - -* Mon Oct 10 2022 Martin Gansser - 3.1.8-1 -- Updatae to 3.1.8 - -* Thu Jul 28 2022 Martin Gansser - 3.1.7-1 -- Updatae to 3.1.7 - -* Sat Jul 23 2022 Fedora Release Engineering - 3.1.6-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Mon Jun 20 2022 Martin Gansser - 3.1.6-2 -- Built against correct vdr-devel version - -* Sun Jun 19 2022 Martin Gansser - 3.1.6-1 -- Updatae to 3.1.6 - -* Sat Feb 12 2022 Martin Gansser - 3.1.5-2 -- Rebuilt - -* Thu Feb 03 2022 Martin Gansser - 3.1.5-1 -- Update to 3.1.5 - -* Sat Jan 29 2022 Martin Gansser - 3.1.4-0.4.20211228git0fbd9b3 -- Add %%undefine _package_note_flags to vdr main package -- rebuild for rawhide - -* Sat Jan 22 2022 Fedora Release Engineering - 3.1.4-0.3.20211228git0fbd9b3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Thu Dec 30 2021 Martin Gansser - 3.1.4-0.2.20211228git0fbd9b3 -- Build compatibility to g++11 - -* Tue Dec 28 2021 Martin Gansser - 3.1.4-0.1.20211228git0fbd9b3 -- Replace obsolete pcre by pcre2 -- Update to 3.1.4-0.1.20211228git0fbd9b3 - -* Mon Nov 15 2021 Martin Gansser - 3.1.3-1 -- Update to 3.1.3 - -* Fri Nov 5 2021 Dirk Nehring - 3.1.1-2 -- Build compatibility to g++11 - -* Mon Nov 01 2021 Martin Gansser - 3.1.1-1 -- Update to 3.1.1 - -* Thu Oct 28 2021 Martin Gansser - 3.1.0-1 -- Update to 3.1.0 - -* Fri Oct 15 2021 Martin Gansser - 3.0.12-1 -- Update to 3.0.12 - -* Sat Sep 11 2021 Martin Gansser - 3.0.10-3 -- Add vdr-plugin-live-noCopyTimer.patch to avoid copying vdr timer objects - -* Fri Aug 06 2021 Martin Gansser - 3.0.10-2 -- Rebuilt fixes unresolved symbol - -* Sun Jul 18 2021 Martin Gansser - 3.0.10-1 -- Update to 3.0.10 - -* Mon Jun 07 2021 Martin Gansser - 3.0.9-1 -- Update to 3.0.9 - -* Mon May 24 2021 Martin Gansser - 3.0.8-1 -- Update to 3.0.8 - -* Wed Apr 28 2021 Martin Gansser - 3.0.7-0.2.20210307git075080a -- Rebuilt for new VDR API version - -* Sun Mar 07 2021 Martin Gansser - 3.0.7-0.1.20210307git075080a -- Update to 3.0.7-0.1.20210307git075080a - -* Wed Mar 03 2021 Martin Gansser - 3.0.6-1 -- Update to 3.0.6 - -* Mon Mar 01 2021 Martin Gansser - 3.0.5-1 -- Rebuilt for cxxtools/tntnet-3.0 support -- Update to 3.0.5 - -* Sun Jan 31 2021 Martin Gansser - 3.0.4-1 -- Update to 3.0.4 - -* Wed Jan 27 2021 Fedora Release Engineering - 3.0.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Sun Jan 24 2021 Martin Gansser - 3.0.2-1 -- Update to 3.0.2 - -* Thu Jan 21 2021 Martin Gansser - 3.0.1-1 -- Update to 3.0.1 - -* Sat Jan 16 2021 Martin Gansser - 3.0.0-1 -- Update to 3.0.0 - -* Sat Jan 16 2021 Martin Gansser - 2.3.1-20.20210111gitf6cfefa -- Add check_existing_recording.patch - -* Mon Jan 11 2021 Martin Gansser - 2.3.1-19.20210111gitf6cfefa -- Update to 2.3.1-19.20210111gitf6cfefa - -* Mon Jan 11 2021 Martin Gansser - 2.3.1-18.20201122git3b24485 -- Use fork because its under maintenance -- Update to 2.3.1-18.20201122git3b24485 - -* Sun Jan 03 2021 Martin Gansser - 2.3.1-17.20170623gite582514 -- Rebuilt for new VDR API version - -* Tue Dec 08 2020 Jonathan Wakely - 2.3.1-16.20170623gite582514 -- Patched for GCC 11 compatibility. -- Remove sed command that is no longer needed. - -* Thu Aug 27 2020 Martin Gansser - 2.3.1-15.20170623gite582514 -- Rebuilt for new VDR API version - -* Wed Jul 29 2020 Fedora Release Engineering - 2.3.1-14.20170623gite582514 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Fri Jan 31 2020 Fedora Release Engineering - 2.3.1-13.20170623gite582514 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Sat Jul 27 2019 Fedora Release Engineering - 2.3.1-12.20170623gite582514 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - * Tue Jun 18 2019 Martin Gansser - 2.3.1-11.20170623gite582514 - Update to last git version 20170623gite582514 - Rebuilt for new VDR API version diff --git a/vdr-plugin-live_2018-11-04.diff b/vdr-plugin-live_2018-11-04.diff new file mode 100644 index 0000000..4cacfce --- /dev/null +++ b/vdr-plugin-live_2018-11-04.diff @@ -0,0 +1,383 @@ +diff --git a/css/styles.css b/css/styles.css +index d32e935..95eca4a 100644 +--- a/css/styles.css ++++ b/css/styles.css +@@ -1032,6 +1032,20 @@ div.recording_item { + cursor: pointer; + } + ++.recording_item div.recording_name_new { ++ font-weight: bold; ++ color: orangered; ++ cursor: pointer; ++} ++ ++.recording_item div.recording_name_new a { ++ color: orangered; ++} ++ ++.recording_item div.recording_name_new span { ++ font-weight: normal; ++} ++ + .recording_item div.recording_arch { + float: right; + padding-top: 0.5ex; +diff --git a/pages/channels_widget.ecpp b/pages/channels_widget.ecpp +index f575f15..e69f3bb 100644 +--- a/pages/channels_widget.ecpp ++++ b/pages/channels_widget.ecpp +@@ -42,6 +42,6 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); + % + % std::string listChannelId = *listChannel->GetChannelID().ToString(); + ++ <{ reply.out() << ( listChannelId == selected ? "selected=\"selected\"" : "" ); }>><$ listChannel->Number() $>: <$ listChannel->Name() $> + % } + +diff --git a/pages/menu.ecpp b/pages/menu.ecpp +index 6251ec7..4de9b40 100644 +--- a/pages/menu.ecpp ++++ b/pages/menu.ecpp +@@ -88,6 +88,7 @@ if (!component.empty()) { + if (LiveFeatures< features::epgsearch >().Recent()) { + + <& menu.component current=("search") &> ++ <& menu.component current=("searchepg") &> + <& menu.component current=("searchtimers") &> + <%cpp> + } +diff --git a/pages/multischedule.ecpp b/pages/multischedule.ecpp +index d06ac44..2fc85cf 100644 +--- a/pages/multischedule.ecpp ++++ b/pages/multischedule.ecpp +@@ -115,10 +115,12 @@ std::vector times_start; + { + std::string thisChannel; + try { +- if ( cur_group_count != 0 ) +- channel_groups_names.back() += std::string( " - " ); + size_t channelSep = thisGroup.find(','); + thisChannel = thisGroup.substr(0, channelSep ); ++ if ( cur_group_count++ != 0 ) ++ channel_groups_names.back() += std::string( " - " ); ++ else ++ channel_groups_names.back() += thisChannel += std::string( ": " ); + if ( channelSep != thisGroup.npos ) + thisGroup.erase( 0, channelSep+1 ); + else +@@ -136,7 +138,6 @@ std::vector times_start; + } + channel_groups_names.back() += std::string( Channel->Name() ); + channel_groups_numbers.back().push_back( Channel->Number() ); +- cur_group_count++; + if ( cur_group_count>=MAX_CHANNELS ) + { + // start new group if group gets too large +@@ -583,4 +584,8 @@ std::vector times_start; + % // <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &> + + ++| ++« Prev ++| ++Next » + +diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp +index 9ef8a0a..fc80823 100644 +--- a/pages/recordings.ecpp ++++ b/pages/recordings.ecpp +@@ -18,6 +18,23 @@ + using namespace vdrlive; + using namespace std; + ++bool checkNew(RecordingsTreePtr recordingsTree, vector p) { ++ bool newR = false; ++ RecordingsMap::iterator iter; ++ for (iter = recordingsTree->begin(p); iter != recordingsTree->end(p); iter++) { ++ RecordingsItemPtr recItem = iter->second; ++ if(!recItem->IsDir()) ++ newR |= recItem->Recording()->GetResume() <= 0; ++ else { ++ vector pp(p); ++ pp.push_back(recItem->Name()); ++ newR |= checkNew(recordingsTree, pp); ++ } ++ } ++ return newR; ++} ++ ++ + + <%args> + string sort; +@@ -213,9 +230,15 @@ else + for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { + RecordingsItemPtr recItem = *recIter; + counter++; ++ ++ /* search trough directory for new recordings */ ++ vector p(path); ++ p.push_back(recItem->Name()); ++ bool newR = checkNew(recordingsTree, p);; ++ + +
  • +- <& rec_item_dir name=(recItem->Name()) level=(recItem->Level()) &> ++ <& rec_item_dir name=(recItem->Name()) level=(recItem->Level()) newR=(newR ? "_new" : "") &> + <%cpp> + #if TNT_QUERYPARAMS_NO_BOOL + tnt::QueryParams recItemParams(qparam); +@@ -262,19 +285,20 @@ for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { + string dayLen(lexical_cast(day.length() - 1) + ".25em;"); + // TRANSLATORS: recording duration format HH:MM + string duration(recItem->Duration() < 0 ? "" : FormatDuration(tr("(%d:%02d)"), recItem->Duration() / 60, recItem->Duration() % 60)); ++ string newR(recItem->Recording()->GetResume() <= 0 ? "_new" : ""); + string shortDescr(recItem->RecInfo()->ShortText() ? recItem->RecInfo()->ShortText() : ""); + string description(recItem->RecInfo()->Description() ? recItem->RecInfo()->Description() : ""); + string hint(tr("Click to view details.")); + if (!shortDescr.empty()) hint = shortDescr + "
    " + hint; + else if (!description.empty()) hint = description + "
    " + hint; + #ifdef HAVE_LIBPCRECPP +- pcrecpp::RE re(filter.c_str(), pcrecpp::UTF8()); ++ pcrecpp::RE re(filter.c_str(), pcrecpp::UTF8().set_caseless(true)); + if (filter.empty() || re.PartialMatch(recItem->Name()) || re.PartialMatch(shortDescr) || re.PartialMatch(description)) + #endif + { + +
  • +- <& rec_item_file name=(recItem->Name()) level=(recItem->Level()) id=(recItem->Id()) day=(day) dayLen=(dayLen) startTime=(recItem->StartTime()) duration=(duration) hint=(hint) shortDescr=(shortDescr) archived=(RecordingsManager::GetArchiveDescr(recItem->Recording())) &> ++ <& rec_item_file name=(recItem->Name()) level=(recItem->Level()) id=(recItem->Id()) day=(day) dayLen=(dayLen) startTime=(recItem->StartTime()) duration=(duration) newR=(newR) hint=(hint) shortDescr=(shortDescr) archived=(RecordingsManager::GetArchiveDescr(recItem->Recording())) &> +
  • + <%cpp> + } +@@ -354,13 +378,14 @@ for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { + <%args> + string name; + int level; ++ string newR; + string collapseimg = "plus.png"; + string folderimg = "folder_closed.png"; + +
    +
    <%cpp> reply.out() << StringRepeat(level - 1, "\"\""); " alt="" />" alt="" />
    +
    +-
    <$ name $>
    ++
    <$ name $>
    +
    +
     
    +
    +@@ -379,6 +404,7 @@ for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { + string duration; + string hint; + string shortDescr; ++ string newR; + string archived; + +
    +@@ -386,7 +412,7 @@ for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) { + +
    + <%cpp> +diff --git a/pages/searchresults.ecpp b/pages/searchresults.ecpp +index 6e554ac..4928f7b 100644 +--- a/pages/searchresults.ecpp ++++ b/pages/searchresults.ecpp +@@ -18,6 +18,9 @@ using namespace std; + <%session scope="global"> + bool logged_in(false); + ++<%request scope="page"> ++ string searchterm=""; ++ + <%include>page_init.eh + <%cpp> + if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); +@@ -38,6 +41,8 @@ bool logged_in(false); + s.SetUseSubtitle(false); + s.SetUseDescription(false); + results.GetByQuery(s.ToText()); ++ ++ searchterm = searchplain; + } + + <& pageelems.doc_type &> +@@ -49,7 +54,7 @@ bool logged_in(false); + + + <& pageelems.logo &> +- <& menu active=("searchepg") &> ++ <& menu active=("searchepg") component=("searchresults.searchresults_actions") &> +
    + % if (results.size() == 0) { + <$ tr("No search results") $> +@@ -114,3 +119,6 @@ bool logged_in(false); + <%include>page_exit.eh + + ++<%def searchresults_actions> ++<$ tr("New search timer") $> ++ +diff --git a/pages/timerconflicts.ecpp b/pages/timerconflicts.ecpp +index 514a9c7..77381de 100644 +--- a/pages/timerconflicts.ecpp ++++ b/pages/timerconflicts.ecpp +@@ -108,7 +108,7 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html"); + longDescription = StringEscapeAndBreak(SortedTimers::GetTimerInfo(*timer)) + "
    " + + StringEscapeAndBreak(StringWordTruncate(epgEvent->LongDescr(), maximumDescriptionLength)) + + "

    " + tr("Click to view details."); +- searchTimName = SortedTimers::SearchTimerName(*timer); ++ searchTimName = SortedTimers::SearchTimerInfo(*timer, "searchtimer"); + title = epgEvent->Title(); + } + +diff --git a/pages/timers.ecpp b/pages/timers.ecpp +index 7b7be70..e627ca9 100644 +--- a/pages/timers.ecpp ++++ b/pages/timers.ecpp +@@ -79,6 +79,7 @@ static const size_t maximumDescriptionLength = 300; + EpgInfoPtr epgEvent; + string longDescription; + string searchTimName; ++ string searchTimId; + #if VDRVERSNUM >= 20301 + if (!timer->Event()) { + LOCK_SCHEDULES_READ; +@@ -93,7 +94,8 @@ static const size_t maximumDescriptionLength = 300; + longDescription = StringEscapeAndBreak(SortedTimers::GetTimerInfo(*timer)) + "
    " + + StringEscapeAndBreak(StringWordTruncate(epgEvent->LongDescr(), maximumDescriptionLength)) + + "

    " + tr("Click to view details."); +- searchTimName = SortedTimers::SearchTimerName(*timer); ++ searchTimName = SortedTimers::SearchTimerInfo(*timer, "searchtimer"); ++ searchTimId = SortedTimers::SearchTimerInfo(*timer, "s-id"); + } + string currentDay = SortedTimers::GetTimerDays(*timer); + SortedTimers::iterator nextTimer = timer; ++nextTimer; +@@ -157,7 +159,7 @@ static const size_t maximumDescriptionLength = 300; + % } + ><$ timer->File() $>
    + +- ">
    <$ searchTimName $>
    ++ "> + ">Flags() & tfActive) ? "active.png" : "inactive.png") $>" alt="" <& tooltip.hint text=(tr("Toggle timer active/inactive")) &>> + "><& pageelems.edit_timer timerId=(timers.GetTimerId(*timer)) &> + ">" alt="" <& tooltip.hint text=(tr("Delete timer")) &>> +diff --git a/recman.cpp b/recman.cpp +index 7bd7912..2dc072e 100644 +--- a/recman.cpp ++++ b/recman.cpp +@@ -343,32 +343,58 @@ namespace vdrlive { + + bool RecordingsItemPtrCompare::ByAscendingName(RecordingsItemPtr & first, RecordingsItemPtr & second) + { ++ unsigned int flen = first->Name().length(); ++ unsigned int fstart = 0; ++ while( flen > 0 && ispunct( (first->Name())[ fstart ] ) ) { ++ fstart++; ++ flen--; ++ } ++ // eliminate starting punctuation characters of second string ++ unsigned int slen = second->Name().length(); ++ unsigned int sstart = 0; ++ while( slen > 0 && ispunct( (second->Name())[ sstart ] ) ) { ++ sstart++; ++ slen--; ++ } ++ // check whether strings are ascending + unsigned int i = 0; +- while (i < first->Name().length() && i < second->Name().length()) { +- if (tolower((first->Name())[i]) < tolower((second->Name())[i])) ++ while( fstart + i < first->Name().length() && sstart + i < second->Name().length() ) { ++ if( tolower( (first->Name())[ fstart + i ] ) < tolower( (second->Name())[ sstart + i] ) ) { + return true; +- else if (tolower((first->Name())[i]) > tolower((second->Name())[i])) ++ } else if( tolower( (first->Name())[ fstart + i] ) > tolower( (second->Name())[ sstart + i ] ) ) { + return false; ++ } + ++i; + } +- if (first->Name().length() < second->Name().length()) +- return true; +- return false; ++ return( flen < slen ); + } + + bool RecordingsItemPtrCompare::ByDescendingName(RecordingsItemPtr & first, RecordingsItemPtr & second) + { ++ unsigned int flen = first->Name().length(); ++ unsigned int fstart = 0; ++ while( flen > 0 && ispunct( (first->Name())[ fstart ] ) ) { ++ fstart++; ++ flen--; ++ } ++ // eliminate starting punctuation characters of second string ++ unsigned int slen = second->Name().length(); ++ unsigned int sstart = 0; ++ while( slen > 0 && ispunct( (second->Name())[ sstart ] ) ) { ++ sstart++; ++ slen--; ++ } ++ // check whether strings are decending + unsigned int i = 0; +- while (i < first->Name().length() && i < second->Name().length()) { +- if (tolower((second->Name())[i]) < tolower((first->Name())[i])) ++ while( fstart + i < first->Name().length() && sstart + i < second->Name().length() ) { ++ if( tolower( (first->Name())[ fstart + i ] ) > tolower( (second->Name())[ sstart + i] ) ) { + return true; +- else if (tolower((second->Name())[i]) > tolower((first->Name())[i])) ++ } else if( tolower( (first->Name())[ fstart + i] ) < tolower( (second->Name())[ sstart + i ] ) ) { + return false; ++ } + ++i; + } +- if (second->Name().length() < first->Name().length()) +- return true; +- return false; ++ return( flen > slen ); + } + + +diff --git a/timers.cpp b/timers.cpp +index 98e4ad8..356ebed 100644 +--- a/timers.cpp ++++ b/timers.cpp +@@ -146,7 +146,7 @@ namespace vdrlive { + return info.str(); + } + +- string SortedTimers::SearchTimerName(cTimer const& timer) ++ string SortedTimers::SearchTimerInfo(cTimer const& timer, std::string const& value) + { + ostringstream info; + if (timer.Aux()) +@@ -154,9 +154,9 @@ namespace vdrlive { + string epgsearchinfo = GetXMLValue(timer.Aux(), "epgsearch"); + if (!epgsearchinfo.empty()) + { +- string searchtimer = GetXMLValue(epgsearchinfo, "searchtimer"); +- if (!searchtimer.empty()) +- info << searchtimer; ++ string data = GetXMLValue(epgsearchinfo, value); ++ if (!data.empty()) ++ info << data; + } + } + return info.str(); +diff --git a/timers.h b/timers.h +index 30583f3..0202d7c 100644 +--- a/timers.h ++++ b/timers.h +@@ -29,7 +29,7 @@ namespace vdrlive { + + static std::string GetTimerDays(cTimer const& timer); + static std::string GetTimerInfo(cTimer const& timer); +- static std::string SearchTimerName(cTimer const& timer); ++ static std::string SearchTimerInfo(cTimer const& timer, std::string const& value); + + private: + SortedTimers();