diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index ecc11b914..262c4fb43 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -2398,6 +2398,7 @@ recordingmenu.multimenu.info_stop_all %d von %d Aufnahmen werden beendet. recordingmenu.multimenu.rec_akt Starte Aufnahme recordingmenu.multimenu.stop_all Alle Aufnahmen beenden recordingmenu.multimenu.timeshift Starte Timeshift +recordingmenu.multimenu.timeshift2record Behalte Timeshift-Aufnahme nach Beendigung recordingmenu.off aus recordingmenu.record_is_not_running Keine laufende Aufnahme verfügbar! recordingmenu.record_is_running Aufnahme läuft! diff --git a/src/driver/record.cpp b/src/driver/record.cpp index 235786529..984101fa9 100644 --- a/src/driver/record.cpp +++ b/src/driver/record.cpp @@ -134,6 +134,7 @@ CRecordInstance::CRecordInstance(const CTimerd::RecordingInfo * const eventinfo, Directory = dir; autoshift = timeshift; + move_ts2rec = false; numpids = 0; cMovieInfo = new CMovieInfo(); @@ -324,7 +325,9 @@ bool CRecordInstance::Stop(bool remove_event) CCamManager::getInstance()->Stop(channel_id, CCamManager::RECORD); - if (autoshift && g_settings.auto_delete) + if (autoshift && move_ts2rec) + CMoviePlayerGui::getInstance().moveTimeshift(); + else if (autoshift && g_settings.auto_delete) CMoviePlayerGui::getInstance().deleteTimeshift(); if(recording_id && remove_event) { @@ -874,6 +877,7 @@ CRecordManager::CRecordManager() durations.clear(); autoshift = false; shift_timer = 0; + menu = NULL; //NI #if 0 check_timer = 0; @@ -1512,6 +1516,20 @@ int CRecordManager::exec(CMenuTarget* parent, const std::string & actionKey ) { StartTimeshift(); return menu_return::RETURN_EXIT_ALL; + } else if(actionKey == "Timeshift2Record") + { + for (recmap_iterator_t it = recmap.begin(); it != recmap.end(); it++) + { + CRecordInstance *inst = it->second; + if (inst->Timeshift()) + { + inst->move_ts2rec = !inst->move_ts2rec; + CMenuItem* item = menu->getItem(menu->getSelected()); + CMenuForwarder *f = static_cast(item); + f->setInfoIconRight(inst->move_ts2rec ? NEUTRINO_ICON_MARKER_DIALOG_OK : NEUTRINO_ICON_MARKER_DIALOG_OFF); + } + } + return menu_return::RETURN_REPAINT; } else if(actionKey == "Stop_record") { if (!CRecordManager::getInstance()->RecordingStatus()) @@ -1540,10 +1558,10 @@ bool CRecordManager::ShowMenu(void) CMenuSelectorTarget * selector = new CMenuSelectorTarget(&select); - CMenuWidget menu(LOCALE_MAINMENU_RECORDING, NEUTRINO_ICON_RECORDING /*, width*/); + menu = new CMenuWidget(LOCALE_MAINMENU_RECORDING, NEUTRINO_ICON_RECORDING /*, width*/); if (rec_count == 0) - menu.addKey(CRCInput::RC_stop, this, "Exit"); - menu.addIntroItems(NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); + menu->addKey(CRCInput::RC_stop, this, "Exit"); + menu->addIntroItems(NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL); // Record / Timeshift t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); @@ -1553,19 +1571,31 @@ bool CRecordManager::ShowMenu(void) //bool status_rec = rec_mode & RECMODE_REC; //record item - iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_REC_AKT, true /*!status_rec*/, NULL, - this, "Record", CRCInput::RC_red); + iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_REC_AKT, true /*!status_rec*/, NULL, this, "Record", CRCInput::RC_red); //if no recordings are running, set the focus to the record menu item - menu.addItem(iteml, rec_count == 0 ? true: false); + menu->addItem(iteml, rec_count == 0 ? true: false); - //timeshift item - iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_TIMESHIFT, !status_ts, NULL, - this, "Timeshift", CRCInput::RC_yellow); - menu.addItem(iteml, false); - - if(rec_count > 0) + if (!status_ts) { - menu.addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MAINMENU_RECORDING_STOP)); + //timeshift item + iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_TIMESHIFT, true /*!status_ts*/, NULL, this, "Timeshift", CRCInput::RC_yellow); + } + else + { + //keep timeshift record + iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_TIMESHIFT2RECORD, true /*status_ts*/, NULL, this, "Timeshift2Record", CRCInput::RC_yellow); + for (recmap_iterator_t it = recmap.begin(); it != recmap.end(); it++) + { + CRecordInstance *inst = it->second; + if (inst->Timeshift()) + iteml->setInfoIconRight(inst->move_ts2rec ? NEUTRINO_ICON_MARKER_DIALOG_OK : NEUTRINO_ICON_MARKER_DIALOG_OFF); + } + } + menu->addItem(iteml, false); + + if (rec_count > 0) + { + menu->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_MAINMENU_RECORDING_STOP)); mutex.lock(); int i = 0 , shortcut = 1; @@ -1587,7 +1617,8 @@ bool CRecordManager::ShowMenu(void) //define stop key if only one record is running, otherwise define shortcuts neutrino_msg_t rc_key = CRCInput::convertDigitToKey(shortcut++); const char * btn_icon = NEUTRINO_ICON_BUTTON_OKAY; - if (rec_count == 1){ + if (rec_count == 1) + { rc_key = CRCInput::RC_stop; btn_icon = NEUTRINO_ICON_BUTTON_STOP; } @@ -1595,25 +1626,24 @@ bool CRecordManager::ShowMenu(void) item->setItemButton(btn_icon, true); //if only one recording is running, set the focus to this menu item - menu.addItem(item, rec_count == 1 ? true: false); + menu->addItem(item, rec_count == 1 ? true: false); i++; if (i >= RECORD_MAX_COUNT) break; } - if(i > 1) //menu item "stopp all records" + if (i > 1) //menu item "stopp all records" { - menu.addItem(GenericMenuSeparatorLine); - iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_STOP_ALL, true, NULL, - this, "StopAll", CRCInput::RC_stop); + menu->addItem(GenericMenuSeparatorLine); + iteml = new CMenuForwarder(LOCALE_RECORDINGMENU_MULTIMENU_STOP_ALL, true, NULL, this, "StopAll", CRCInput::RC_stop); iteml->setItemButton(NEUTRINO_ICON_BUTTON_STOP, true); //if more than one recording is running, set the focus to menu item 'stopp all records' - menu.addItem(iteml, rec_count > 1 ? true: false); + menu->addItem(iteml, rec_count > 1 ? true: false); } mutex.unlock(); } - menu.exec(NULL, ""); + menu->exec(NULL, ""); delete selector; if (select >= 0 && select < RECORD_MAX_COUNT) { diff --git a/src/driver/record.h b/src/driver/record.h index ee225911a..38ac02503 100644 --- a/src/driver/record.h +++ b/src/driver/record.h @@ -131,6 +131,7 @@ class CRecordInstance const char * GetFileName() { return filename; }; bool Timeshift() { return autoshift; }; int tshift_mode; + bool move_ts2rec; void SetStopMessage(const char* text) {rec_stop_msg = text;} ; //NI #if 0 @@ -164,6 +165,8 @@ class CRecordManager : public CMenuTarget /*, public CChangeObserver*/ int last_mode; bool autoshift; uint32_t shift_timer; + CMenuWidget *menu; + //NI #if 0 uint32_t check_timer; diff --git a/src/gui/movieplayer.cpp b/src/gui/movieplayer.cpp index b876a9046..cbfcc4f24 100644 --- a/src/gui/movieplayer.cpp +++ b/src/gui/movieplayer.cpp @@ -596,6 +596,7 @@ void CMoviePlayerGui::Cleanup() p_movie_info = NULL; autoshot_done = false; timeshift_deletion = false; + timeshift_to_record = false; currentaudioname = "Unk"; } @@ -2072,18 +2073,47 @@ void CMoviePlayerGui::PlayFileEnd(bool restore) stopped = true; printf("%s: stopped\n", __func__); - if (timeshift_deletion && (file_name.find("_temp.ts") == file_name.size() - 8)) + if (file_name.find("_temp.ts") == file_name.size() - 8) { - std::string file = file_name; - printf("%s: delete %s\n", __func__, file.c_str()); - unlink(file.c_str()); + std::string ts_src = file_name; + std::string xml_src = file_name; CMovieInfo mi; - if (mi.convertTs2XmlName(file)) + if (!mi.convertTs2XmlName(xml_src)) + xml_src.clear(); + + if (timeshift_to_record) { - printf("%s: delete %s\n", __func__, file.c_str()); - unlink(file.c_str()); + if (g_settings.timeshiftdir != g_settings.network_nfs_recordingdir) + { + std::string ts_dst = g_settings.network_nfs_recordingdir + "/" + ts_src.substr(ts_src.find_last_of('/') + 1); + std::string xml_dst = g_settings.network_nfs_recordingdir + "/" + xml_src.substr(xml_src.find_last_of('/') + 1);; + + str_replace("_temp", "_ts", ts_dst); + str_replace("_temp", "_ts", xml_dst); + + printf("%s: move %s\n", __func__, ts_src.c_str()); + printf("%s: to %s\n", __func__, ts_dst.c_str()); + rename(ts_src.c_str(), ts_dst.c_str()); + if (!xml_src.empty()) + { + printf("%s: move %s\n", __func__, xml_src.c_str()); + printf("%s: to %s\n", __func__, xml_dst.c_str()); + rename(xml_src.c_str(), xml_dst.c_str()); + } + } + timeshift_to_record = false; + } + else if (timeshift_deletion) + { + printf("%s: delete %s\n", __func__, ts_src.c_str()); + unlink(ts_src.c_str()); + if (!xml_src.empty()) + { + printf("%s: delete %s\n", __func__, xml_src.c_str()); + unlink(xml_src.c_str()); + } + timeshift_deletion = false; } - timeshift_deletion = false; } if (!filelist.empty() && filelist_it != filelist.end()) { diff --git a/src/gui/movieplayer.h b/src/gui/movieplayer.h index d03350ddc..bf085236d 100644 --- a/src/gui/movieplayer.h +++ b/src/gui/movieplayer.h @@ -175,6 +175,7 @@ class CMoviePlayerGui : public CMenuTarget int menu_ret; bool autoshot_done; bool timeshift_deletion; + bool timeshift_to_record; //std::vector liveStreamList; /* playback from bookmark */ @@ -252,6 +253,7 @@ class CMoviePlayerGui : public CMenuTarget void UpdatePosition(); int timeshift; void deleteTimeshift() { timeshift_deletion = true; } + void moveTimeshift() { timeshift_to_record = true; } int file_prozent; cPlayback *getPlayback() { return playback; } void SetFile(std::string &name, std::string &file, std::string info1="", std::string info2="") { pretty_name = name; file_name = file; info_1 = info1; info_2 = info2; } diff --git a/src/system/locals.h b/src/system/locals.h index 069c2298f..ba72aba5a 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -2425,6 +2425,7 @@ typedef enum LOCALE_RECORDINGMENU_MULTIMENU_REC_AKT, LOCALE_RECORDINGMENU_MULTIMENU_STOP_ALL, LOCALE_RECORDINGMENU_MULTIMENU_TIMESHIFT, + LOCALE_RECORDINGMENU_MULTIMENU_TIMESHIFT2RECORD, LOCALE_RECORDINGMENU_OFF, LOCALE_RECORDINGMENU_RECORD_IS_NOT_RUNNING, LOCALE_RECORDINGMENU_RECORD_IS_RUNNING, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 1775187a0..ca6a9b5b3 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -2425,6 +2425,7 @@ const char * locale_real_names[] = "recordingmenu.multimenu.rec_akt", "recordingmenu.multimenu.stop_all", "recordingmenu.multimenu.timeshift", + "recordingmenu.multimenu.timeshift2record", "recordingmenu.off", "recordingmenu.record_is_not_running", "recordingmenu.record_is_running",