Ticket #8901: cutlist_undo_stack_v6.patch
File cutlist_undo_stack_v6.patch, 20.8 KB (added by , 13 years ago) |
---|
-
mythtv/libs/libmyth/programinfo.cpp
diff --git a/mythtv/libs/libmyth/programinfo.cpp b/mythtv/libs/libmyth/programinfo.cpp index 2a3ea00..ebdfc37 100644
a b AutoExpireType ProgramInfo::QueryAutoExpire(void) const 2687 2687 return kDisableAutoExpire; 2688 2688 } 2689 2689 2690 void ProgramInfo::QueryCutList(frm_dir_map_t &delMap) const2690 bool ProgramInfo::QueryCutList(frm_dir_map_t &delMap, bool loadAutoSave) const 2691 2691 { 2692 QueryMarkupMap(delMap, MARK_CUT_START); 2693 QueryMarkupMap(delMap, MARK_CUT_END, true); 2694 QueryMarkupMap(delMap, MARK_PLACEHOLDER, true); 2692 frm_dir_map_t autosaveMap; 2693 QueryMarkupMap(autosaveMap, MARK_TMP_CUT_START); 2694 QueryMarkupMap(autosaveMap, MARK_TMP_CUT_END, true); 2695 QueryMarkupMap(autosaveMap, MARK_PLACEHOLDER, true); 2696 bool result = !autosaveMap.isEmpty(); 2697 2698 if (loadAutoSave) 2699 { 2700 // Convert the temporary marks into regular marks. 2701 delMap.clear(); 2702 frm_dir_map_t::const_iterator i = autosaveMap.constBegin(); 2703 for (; i != autosaveMap.constEnd(); ++i) 2704 { 2705 uint64_t frame = i.key(); 2706 MarkTypes mark = i.value(); 2707 if (mark == MARK_TMP_CUT_START) 2708 mark = MARK_CUT_START; 2709 else if (mark == MARK_TMP_CUT_END) 2710 mark = MARK_CUT_END; 2711 delMap[frame] = mark; 2712 } 2713 } 2714 else 2715 { 2716 QueryMarkupMap(delMap, MARK_CUT_START); 2717 QueryMarkupMap(delMap, MARK_CUT_END, true); 2718 QueryMarkupMap(delMap, MARK_PLACEHOLDER, true); 2719 } 2720 2721 return result; 2695 2722 } 2696 2723 2697 void ProgramInfo::SaveCutList(frm_dir_map_t &delMap ) const2724 void ProgramInfo::SaveCutList(frm_dir_map_t &delMap, bool isAutoSave) const 2698 2725 { 2699 ClearMarkupMap(MARK_CUT_START); 2700 ClearMarkupMap(MARK_CUT_END); 2726 if (!isAutoSave) 2727 { 2728 ClearMarkupMap(MARK_CUT_START); 2729 ClearMarkupMap(MARK_CUT_END); 2730 } 2701 2731 ClearMarkupMap(MARK_PLACEHOLDER); 2702 SaveMarkupMap(delMap); 2732 ClearMarkupMap(MARK_TMP_CUT_START); 2733 ClearMarkupMap(MARK_TMP_CUT_END); 2734 2735 frm_dir_map_t tmpDelMap; 2736 frm_dir_map_t::const_iterator i = delMap.constBegin(); 2737 for (; i != delMap.constEnd(); ++i) 2738 { 2739 uint64_t frame = i.key(); 2740 MarkTypes mark = i.value(); 2741 if (isAutoSave) 2742 { 2743 if (mark == MARK_CUT_START) 2744 mark = MARK_TMP_CUT_START; 2745 else if (mark == MARK_CUT_END) 2746 mark = MARK_TMP_CUT_END; 2747 } 2748 tmpDelMap[frame] = mark; 2749 } 2750 SaveMarkupMap(tmpDelMap); 2703 2751 2704 2752 if (IsRecording()) 2705 2753 { -
mythtv/libs/libmyth/programinfo.h
diff --git a/mythtv/libs/libmyth/programinfo.h b/mythtv/libs/libmyth/programinfo.h index fb131bc..1c573d7 100644
a b class MPUBLIC ProgramInfo 534 534 bool forceCheckLocal = false) const; 535 535 536 536 // Edit flagging map 537 void QueryCutList(frm_dir_map_t &) const;538 void SaveCutList(frm_dir_map_t & ) const;537 bool QueryCutList(frm_dir_map_t &, bool loadAutosave=false) const; 538 void SaveCutList(frm_dir_map_t &, bool isAutoSave=false) const; 539 539 540 540 // Commercial flagging map 541 541 void QueryCommBreakList(frm_dir_map_t &) const; -
mythtv/libs/libmyth/programtypes.cpp
diff --git a/mythtv/libs/libmyth/programtypes.cpp b/mythtv/libs/libmyth/programtypes.cpp index 019655c..f38643a 100644
a b QString toString(MarkTypes type) 22 22 switch (type) 23 23 { 24 24 case MARK_UNSET: return "UNSET"; 25 case MARK_TMP_CUT_END: return "TMP_CUT_END"; 26 case MARK_TMP_CUT_START:return "TMP_CUT_START"; 25 27 case MARK_UPDATED_CUT: return "UPDATED_CUT"; 26 28 case MARK_PLACEHOLDER: return "PLACEHOLDER"; 27 29 case MARK_CUT_END: return "CUT_END"; -
mythtv/libs/libmyth/programtypes.h
diff --git a/mythtv/libs/libmyth/programtypes.h b/mythtv/libs/libmyth/programtypes.h index 23e1bf6..64c386e 100644
a b typedef QMap<uint64_t, uint64_t> frm_pos_map_t; 40 40 typedef enum { 41 41 MARK_ALL = -100, 42 42 MARK_UNSET = -10, 43 MARK_TMP_CUT_END = -5, 44 MARK_TMP_CUT_START = -4, 43 45 MARK_UPDATED_CUT = -3, 44 46 MARK_PLACEHOLDER = -2, 45 47 MARK_CUT_END = 0, -
mythtv/libs/libmythtv/deletemap.cpp
diff --git a/mythtv/libs/libmythtv/deletemap.cpp b/mythtv/libs/libmythtv/deletemap.cpp index 7cda7ac..3376d11 100644
a b 10 10 #define EDIT_CHECK if(!m_editing) \ 11 11 { VERBOSE(VB_IMPORTANT, LOC_ERR + "Cannot edit outside editmode."); return; } 12 12 13 DeleteMapUndoEntry::DeleteMapUndoEntry(frm_dir_map_t dm, QString msg) : 14 deleteMap(dm), message(msg) { } 15 16 DeleteMapUndoEntry::DeleteMapUndoEntry(void) 17 { 18 frm_dir_map_t dm; 19 deleteMap = dm; 20 message = ""; 21 } 22 23 void DeleteMap::Push(QString undoMessage) 24 { 25 DeleteMapUndoEntry entry(m_deleteMap, undoMessage); 26 // Remove all "redo" entries 27 while (m_undoStack.size() > m_undoStackPointer + 1) 28 m_undoStack.pop_back(); 29 m_undoStack.append(entry); 30 m_undoStackPointer ++; 31 SaveMap(0, m_ctx, true); 32 } 33 34 bool DeleteMap::Undo(void) 35 { 36 if (!HasUndo()) 37 return false; 38 m_undoStackPointer --; 39 m_deleteMap = m_undoStack[m_undoStackPointer].deleteMap; 40 m_changed = true; 41 SaveMap(0, m_ctx, true); 42 return true; 43 } 44 45 bool DeleteMap::Redo(void) 46 { 47 if (!HasRedo()) 48 return false; 49 m_undoStackPointer ++; 50 m_deleteMap = m_undoStack[m_undoStackPointer].deleteMap; 51 m_changed = true; 52 SaveMap(0, m_ctx, true); 53 return true; 54 } 55 56 QString DeleteMap::GetUndoMessage(void) 57 { 58 return (HasUndo() ? m_undoStack[m_undoStackPointer].message : 59 QObject::tr("(No more undo operations)")); 60 } 61 62 QString DeleteMap::GetRedoMessage(void) 63 { 64 return (HasRedo() ? m_undoStack[m_undoStackPointer + 1].message : 65 QObject::tr("(No more redo operations)")); 66 } 67 13 68 bool DeleteMap::HandleAction(QString &action, uint64_t frame, 14 69 uint64_t played, uint64_t total, double rate) 15 70 { … … bool DeleteMap::HandleAction(QString &action, uint64_t frame, 21 76 else if (action == "DOWN") 22 77 UpdateSeekAmount(-1, rate); 23 78 else if (action == "CLEARMAP") 24 Clear( );79 Clear(QObject::tr("Clear Cut List")); 25 80 else if (action == "INVERTMAP") 26 81 ReverseAll(total); 27 82 else if (action == "MOVEPREV") … … bool DeleteMap::HandleAction(QString &action, uint64_t frame, 29 84 else if (action == "MOVENEXT") 30 85 MoveRelative(frame, total, true); 31 86 else if (action == "CUTTOBEGINNING") 32 Add(frame, total, MARK_CUT_END );87 Add(frame, total, MARK_CUT_END, QObject::tr("Cut To Beginning")); 33 88 else if (action == "CUTTOEND") 34 Add(frame, total, MARK_CUT_START );89 Add(frame, total, MARK_CUT_START, QObject::tr("Cut To End")); 35 90 else if (action == "NEWCUT") 36 91 NewCut(frame, total); 37 92 else if (action == "DELETE") 38 Delete(frame, total); 93 Delete(frame, total, QObject::tr("Delete Cut Area")); 94 else if (action == "UNDO") 95 Undo(); 96 else if (action == "REDO") 97 Redo(); 39 98 else 40 99 handled = false; 41 100 return handled; … … bool DeleteMap::IsEmpty(void) 150 209 } 151 210 152 211 /// Clears the deleteMap. 153 void DeleteMap::Clear( void)212 void DeleteMap::Clear(QString undoMessage) 154 213 { 155 214 m_deleteMap.clear(); 156 215 m_changed = true; 216 if (!undoMessage.isEmpty()) 217 Push(undoMessage); 157 218 } 158 219 159 220 /// Reverses the direction of each mark in the map. … … void DeleteMap::ReverseAll(uint64_t total) 165 226 Add(it.key(), it.value() == MARK_CUT_END ? MARK_CUT_START : 166 227 MARK_CUT_END); 167 228 CleanMap(total); 229 Push(QObject::tr("Invert Cut List")); 168 230 } 169 231 170 232 /** … … void DeleteMap::ReverseAll(uint64_t total) 172 234 * existing redundant mark of that type is removed. This simplifies 173 235 * the cleanup code. 174 236 */ 175 void DeleteMap::Add(uint64_t frame, uint64_t total, MarkTypes type) 237 void DeleteMap::Add(uint64_t frame, uint64_t total, MarkTypes type, 238 QString undoMessage) 176 239 { 177 240 EDIT_CHECK 178 241 if ((MARK_CUT_START != type) && (MARK_CUT_END != type) && … … void DeleteMap::Add(uint64_t frame, uint64_t total, MarkTypes type) 186 249 { 187 250 // Delete the temporary mark before putting a real mark at its 188 251 // location 189 Delete(frame, total );252 Delete(frame, total, ""); 190 253 } 191 254 else // Don't add a mark on top of a mark 192 255 return; … … void DeleteMap::Add(uint64_t frame, uint64_t total, MarkTypes type) 241 304 Delete((uint64_t)remove); 242 305 Add(frame, type); 243 306 CleanMap(total); 307 if (!undoMessage.isEmpty()) 308 Push(undoMessage); 244 309 } 245 310 246 311 /// Remove the mark at the given frame. 247 void DeleteMap::Delete(uint64_t frame, uint64_t total )312 void DeleteMap::Delete(uint64_t frame, uint64_t total, QString undoMessage) 248 313 { 249 314 EDIT_CHECK 250 315 if (m_deleteMap.isEmpty()) … … void DeleteMap::Delete(uint64_t frame, uint64_t total) 271 336 if (prev != next) 272 337 Delete(next); 273 338 CleanMap(total); 339 if (!undoMessage.isEmpty()) 340 Push(undoMessage); 274 341 } 275 342 276 343 /// Reverse the direction of the mark at the given frame. … … void DeleteMap::Reverse(uint64_t frame, uint64_t total) 278 345 { 279 346 EDIT_CHECK 280 347 int type = Delete(frame); 281 Add(frame, total, type == MARK_CUT_END ? MARK_CUT_START : MARK_CUT_END); 348 Add(frame, total, type == MARK_CUT_END ? MARK_CUT_START : MARK_CUT_END, ""); 349 Push(QObject::tr("Reverse Mark Direction")); 282 350 } 283 351 284 352 /// Add a new cut marker (to start or end a cut region) … … void DeleteMap::NewCut(uint64_t frame, uint64_t total) 376 444 Add(frame, MARK_PLACEHOLDER); 377 445 378 446 CleanMap(total); 447 Push(QObject::tr("New Cut")); 379 448 } 380 449 381 450 /// Move the previous (!right) or next (right) cut to frame. … … void DeleteMap::MoveRelative(uint64_t frame, uint64_t total, bool right) 397 466 { 398 467 // If on a mark, don't collapse a cut region to 0; 399 468 // instead, delete the region 400 Delete(frame, total );469 Delete(frame, total, QObject::tr("Delete Cut Area")); 401 470 return; 402 471 } 403 472 else if (MARK_PLACEHOLDER == type) 404 473 { 405 474 // Delete the temporary mark before putting a real mark at its 406 475 // location 407 Delete(frame, total );476 Delete(frame, total, ""); 408 477 } 409 478 } 410 479 … … void DeleteMap::Move(uint64_t frame, uint64_t to, uint64_t total) 424 493 else if (frame == total) 425 494 type = MARK_CUT_END; 426 495 } 427 Add(to, total, type );496 Add(to, total, type, QObject::tr("Move Mark")); 428 497 } 429 498 430 499 /// Private addition to the deleteMap. … … void DeleteMap::SetMap(const frm_dir_map_t &map) 582 651 Clear(); 583 652 m_deleteMap = map; 584 653 m_deleteMap.detach(); 654 Push(QObject::tr("Set New Cut List")); 585 655 } 586 656 587 657 /// Loads the given commercial break map into the deleteMap. … … void DeleteMap::LoadCommBreakMap(uint64_t total, frm_dir_map_t &map) 593 663 Add(it.key(), it.value() == MARK_COMM_START ? 594 664 MARK_CUT_START : MARK_CUT_END); 595 665 CleanMap(total); 666 Push(QObject::tr("Load Commskip List")); 596 667 } 597 668 598 669 /// Loads the delete map from the database. 599 void DeleteMap::LoadMap(uint64_t total, PlayerContext *ctx )670 void DeleteMap::LoadMap(uint64_t total, PlayerContext *ctx, QString undoMessage) 600 671 { 601 672 if (!ctx || !ctx->playingInfo || gCoreContext->IsDatabaseIgnored()) 602 673 return; … … void DeleteMap::LoadMap(uint64_t total, PlayerContext *ctx) 606 677 ctx->playingInfo->QueryCutList(m_deleteMap); 607 678 ctx->UnlockPlayingInfo(__FILE__, __LINE__); 608 679 CleanMap(total); 680 if (!undoMessage.isEmpty()) 681 Push(undoMessage); 682 } 683 684 /// Returns true if an auto-save map was loaded. 685 /// Does nothing and returns false if not. 686 bool DeleteMap::LoadAutoSaveMap(uint64_t total, PlayerContext *ctx) 687 { 688 if (!ctx || !ctx->playingInfo || gCoreContext->IsDatabaseIgnored()) 689 return false; 690 691 frm_dir_map_t tmpDeleteMap = m_deleteMap; 692 Clear(); 693 ctx->LockPlayingInfo(__FILE__, __LINE__); 694 bool result = ctx->playingInfo->QueryCutList(m_deleteMap, true); 695 ctx->UnlockPlayingInfo(__FILE__, __LINE__); 696 CleanMap(total); 697 if (result) 698 Push(QObject::tr("Load Auto-Save Cut List")); 699 else 700 m_deleteMap = tmpDeleteMap; 701 702 return result; 609 703 } 610 704 611 705 /// Saves the delete map to the database. 612 void DeleteMap::SaveMap(uint64_t total, PlayerContext *ctx )706 void DeleteMap::SaveMap(uint64_t total, PlayerContext *ctx, bool isAutoSave) 613 707 { 614 708 if (!ctx || !ctx->playingInfo || gCoreContext->IsDatabaseIgnored()) 615 709 return; 616 710 711 if (!isAutoSave) 712 { 617 713 // Remove temporary placeholder marks 618 714 QMutableMapIterator<uint64_t, MarkTypes> it(m_deleteMap); 619 715 while (it.hasNext()) … … void DeleteMap::SaveMap(uint64_t total, PlayerContext *ctx) 627 723 } 628 724 629 725 CleanMap(total); 726 } 630 727 ctx->LockPlayingInfo(__FILE__, __LINE__); 631 728 ctx->playingInfo->SaveMarkupFlag(MARK_UPDATED_CUT); 632 ctx->playingInfo->SaveCutList(m_deleteMap );729 ctx->playingInfo->SaveCutList(m_deleteMap, isAutoSave); 633 730 ctx->UnlockPlayingInfo(__FILE__, __LINE__); 634 731 } 635 732 -
mythtv/libs/libmythtv/deletemap.h
diff --git a/mythtv/libs/libmythtv/deletemap.h b/mythtv/libs/libmythtv/deletemap.h index e6a599b..1253014 100644
a b 4 4 #include "programinfo.h" 5 5 #include "playercontext.h" 6 6 7 class DeleteMap; 8 9 typedef struct DeleteMapUndoEntry 10 { 11 frm_dir_map_t deleteMap; 12 QString message; // how we got from previous map to this map 13 DeleteMapUndoEntry(frm_dir_map_t dm, QString msg); 14 DeleteMapUndoEntry(void); 15 } DeleteMapUndoEntry; 16 7 17 class DeleteMap 8 18 { 9 19 public: 10 20 DeleteMap(): m_editing(false), m_nextCutStart(0), m_changed(true), 11 m_seekamountpos(4), m_seekamount(30) { } 21 m_seekamountpos(4), m_seekamount(30), 22 m_ctx(0), m_undoStackPointer(-1) { Push(""); } 12 23 24 void SetPlayerContext(PlayerContext *ctx) { m_ctx = ctx; } 13 25 bool HandleAction(QString &action, uint64_t frame, uint64_t played, 14 26 uint64_t total, double rate); 15 27 int GetSeekAmount(void) { return m_seekamount; } … … class DeleteMap 28 40 29 41 void SetMap(const frm_dir_map_t &map); 30 42 void LoadCommBreakMap(uint64_t total, frm_dir_map_t &map); 31 void SaveMap(uint64_t total, PlayerContext *ctx); 32 void LoadMap(uint64_t total, PlayerContext *ctx); 43 void SaveMap(uint64_t total, PlayerContext *ctx, bool isAutoSave=false); 44 void LoadMap(uint64_t total, PlayerContext *ctx, QString undoMessage=""); 45 bool LoadAutoSaveMap(uint64_t total, PlayerContext *ctx); 33 46 void CleanMap(uint64_t total); 34 47 35 void Clear( void);48 void Clear(QString undoMessage=""); 36 49 void ReverseAll(uint64_t total); 37 void Add(uint64_t frame, uint64_t total, MarkTypes type); 50 void Add(uint64_t frame, uint64_t total, MarkTypes type, 51 QString undoMessage); 38 52 void NewCut(uint64_t frame, uint64_t total); 39 void Delete(uint64_t frame, uint64_t total );53 void Delete(uint64_t frame, uint64_t total, QString undoMessage); 40 54 void Reverse(uint64_t frame, uint64_t total); 41 55 void MoveRelative(uint64_t frame, uint64_t total, bool right); 42 56 void Move(uint64_t frame, uint64_t to, uint64_t total); … … class DeleteMap 50 64 void TrackerReset(uint64_t frame, uint64_t total); 51 65 bool TrackerWantsToJump(uint64_t frame, uint64_t total, uint64_t &to); 52 66 67 bool Undo(void); 68 bool Redo(void); 69 bool HasUndo(void) { return m_undoStackPointer > 0; } 70 bool HasRedo(void) { return m_undoStackPointer < m_undoStack.size() - 1; } 71 QString GetUndoMessage(void); 72 QString GetRedoMessage(void); 73 53 74 private: 54 75 void Add(uint64_t frame, MarkTypes type); 55 76 MarkTypes Delete(uint64_t frame); 56 77 78 void Push(QString undoMessage); 79 57 80 bool m_editing; 58 81 uint64_t m_nextCutStart; 59 82 frm_dir_map_t m_deleteMap; … … class DeleteMap 61 84 bool m_changed; 62 85 int m_seekamountpos; 63 86 int m_seekamount; 87 PlayerContext *m_ctx; 88 89 // Invariant: m_undoStack[m_undoStackPointer].deleteMap == m_deleteMap 90 QVector<DeleteMapUndoEntry> m_undoStack; 91 int m_undoStackPointer; 64 92 }; 65 93 66 94 #endif // DELETEMAP_H -
mythtv/libs/libmythtv/mythplayer.cpp
diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index 198e1fa..d6b6f75 100644
a b void MythPlayer::ClearAfterSeek(bool clearvideobuffers) 3483 3483 void MythPlayer::SetPlayerInfo(TV *tv, QWidget *widget, 3484 3484 bool frame_exact_seek, PlayerContext *ctx) 3485 3485 { 3486 deleteMap.SetPlayerContext(ctx); 3486 3487 m_tv = tv; 3487 3488 parentWidget = widget; 3488 3489 exactseeks = frame_exact_seek; … … bool MythPlayer::EnableEdit(void) 3511 3512 osd->DialogQuit(); 3512 3513 ResetCaptions(); 3513 3514 osd->HideAll(); 3515 3516 bool loadedAutoSave = deleteMap.LoadAutoSaveMap(totalFrames, player_ctx); 3517 (void)loadedAutoSave; // XXX - should we display an OSD message? 3518 3514 3519 deleteMap.UpdateSeekAmount(0, video_frame_rate); 3515 3520 deleteMap.UpdateOSD(framesPlayed, totalFrames, video_frame_rate, 3516 3521 player_ctx, osd); … … void MythPlayer::DisableEdit(bool save) 3528 3533 { 3529 3534 osdLock.lock(); 3530 3535 deleteMap.SetEditing(false, osd); 3531 if (save) 3532 deleteMap.SaveMap(totalFrames, player_ctx); 3533 else 3536 if (!save) 3534 3537 deleteMap.LoadMap(totalFrames, player_ctx); 3538 // Unconditionally save to remove temporary marks from the DB. 3539 deleteMap.SaveMap(totalFrames, player_ctx); 3535 3540 deleteMap.TrackerReset(framesPlayed, totalFrames); 3536 3541 deleteMap.SetFileEditing(player_ctx, false); 3537 3542 player_ctx->LockPlayingInfo(__FILE__, __LINE__); … … bool MythPlayer::HandleProgramEditorActions(QStringList &actions, 3628 3633 { 3629 3634 if (IsInDelete(frame)) 3630 3635 { 3631 deleteMap.Delete(frame, totalFrames); 3636 deleteMap.Delete(frame, totalFrames, 3637 QObject::tr("Delete cut area")); 3632 3638 refresh = true; 3633 3639 } 3634 3640 } 3635 3641 else if (action == "REVERT") 3636 3642 { 3637 deleteMap.LoadMap(totalFrames, player_ctx); 3643 deleteMap.LoadMap(totalFrames, player_ctx, 3644 QObject::tr("Load Cut List")); 3638 3645 refresh = true; 3639 3646 } 3640 3647 else if (action == "REVERTEXIT") -
mythtv/libs/libmythtv/mythplayer.h
diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index b776296..8857c89 100644
a b class MPUBLIC MythPlayer 412 412 bool IsTemporaryMark(uint64_t frame); 413 413 bool HasTemporaryMark(void); 414 414 bool IsCutListSaved(PlayerContext *ctx) { return deleteMap.IsSaved(ctx); } 415 bool DeleteMapHasUndo(void) { return deleteMap.HasUndo(); } 416 bool DeleteMapHasRedo(void) { return deleteMap.HasRedo(); } 417 QString DeleteMapGetUndoMessage(void) { return deleteMap.GetUndoMessage(); } 418 QString DeleteMapGetRedoMessage(void) { return deleteMap.GetRedoMessage(); } 415 419 416 420 // Reinit 417 421 void ReinitOSD(void); -
mythtv/libs/libmythtv/tv_play.cpp
diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index d7a381c..6765b94 100644
a b void TV::InitKeys(void) 767 767 "Jump back 10x the normal amount"), ",,<"); 768 768 REG_KEY("TV Editing", "BIGJUMPFWD", QT_TRANSLATE_NOOP("MythControls", 769 769 "Jump forward 10x the normal amount"), ">,."); 770 REG_KEY("TV Editing", "UNDO", QT_TRANSLATE_NOOP("MythControls", 771 "Undo"), "Ctrl+Z"); 772 REG_KEY("TV Editing", "REDO", QT_TRANSLATE_NOOP("MythControls", 773 "Redo"), "Ctrl+Y"); 770 774 771 775 /* Teletext keys */ 772 776 REG_KEY("Teletext Menu", "NEXTPAGE", QT_TRANSLATE_NOOP("MythControls", … … void TV::ShowOSDCutpoint(PlayerContext *ctx, const QString &type) 9085 9089 if ("EDIT_CUT_POINTS" == type) 9086 9090 osd->DialogAddButton(QObject::tr("Cut List Options"), 9087 9091 "DIALOG_CUTPOINT_CUTLISTOPTIONS_0", true); 9092 if (ctx->player->DeleteMapHasUndo()) 9093 osd->DialogAddButton(QObject::tr("Undo") + " - " + 9094 ctx->player->DeleteMapGetUndoMessage(), 9095 QString("DIALOG_CUTPOINT_UNDO_0")); 9096 if (ctx->player->DeleteMapHasRedo()) 9097 osd->DialogAddButton(QObject::tr("Redo") + " - " + 9098 ctx->player->DeleteMapGetRedoMessage(), 9099 QString("DIALOG_CUTPOINT_REDO_0")); 9088 9100 } 9089 9101 else if ("CUT_LIST_OPTIONS" == type) 9090 9102 {