Ticket #8901: cutlist_undo_stack_v2.patch
File cutlist_undo_stack_v2.patch, 11.1 KB (added by , 14 years ago) |
---|
-
libs/libmythtv/deletemap.h
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_undoStackPointer(-1) { Push(""); } 12 23 13 24 bool HandleAction(QString &action, uint64_t frame, uint64_t played, 14 25 uint64_t total, double rate); … … 33 44 34 45 void Clear(void); 35 46 void ReverseAll(uint64_t total); 36 void Add(uint64_t frame, uint64_t total, MarkTypes type); 47 void Add(uint64_t frame, uint64_t total, MarkTypes type, 48 QString undoMessage); 37 49 void NewCut(uint64_t frame, uint64_t total); 38 void Delete(uint64_t frame, uint64_t total );50 void Delete(uint64_t frame, uint64_t total, QString undoMessage); 39 51 void Reverse(uint64_t frame, uint64_t total); 40 52 void MoveRelative(uint64_t frame, uint64_t total, bool right); 41 53 void Move(uint64_t frame, uint64_t to, uint64_t total); … … 49 61 void TrackerReset(uint64_t frame, uint64_t total); 50 62 bool TrackerWantsToJump(uint64_t frame, uint64_t total, uint64_t &to); 51 63 64 bool Undo(void); 65 bool Redo(void); 66 bool HasUndo(void) { return m_undoStackPointer > 0; } 67 bool HasRedo(void) { return m_undoStackPointer < m_undoStack.size() - 1; } 68 QString GetUndoMessage(void); 69 QString GetRedoMessage(void); 70 52 71 private: 53 72 void Add(uint64_t frame, MarkTypes type); 54 73 MarkTypes Delete(uint64_t frame); 55 74 75 void Push(QString undoMessage); 76 56 77 bool m_editing; 57 78 uint64_t m_nextCutStart; 58 79 frm_dir_map_t m_deleteMap; … … 60 81 bool m_changed; 61 82 int m_seekamountpos; 62 83 int m_seekamount; 84 85 // Invariant: m_undoStack[m_undoStackPointer].deleteMap == m_deleteMap 86 QVector<DeleteMapUndoEntry> m_undoStack; 87 int m_undoStackPointer; 63 88 }; 64 89 65 90 #endif // DELETEMAP_H -
libs/libmythtv/mythplayer.h
301 301 uint64_t GetNearestMark(uint64_t frame, bool right); 302 302 bool IsTemporaryMark(uint64_t frame); 303 303 bool HasTemporaryMark(void); 304 bool DeleteMapHasUndo(void) { return deleteMap.HasUndo(); } 305 bool DeleteMapHasRedo(void) { return deleteMap.HasRedo(); } 306 QString DeleteMapGetUndoMessage(void) { return deleteMap.GetUndoMessage(); } 307 QString DeleteMapGetRedoMessage(void) { return deleteMap.GetRedoMessage(); } 304 308 305 309 // Decoder stuff.. 306 310 VideoFrame *GetNextVideoFrame(bool allow_unsafe = true); -
libs/libmythtv/tv_play.cpp
774 774 "Jump back 10x the normal amount"), ",,<"); 775 775 REG_KEY("TV Editing", "BIGJUMPFWD", QT_TRANSLATE_NOOP("MythControls", 776 776 "Jump forward 10x the normal amount"), ">,."); 777 REG_KEY("TV Editing", "UNDO", QT_TRANSLATE_NOOP("MythControls", 778 "Undo"), "Ctrl+Z"); 779 REG_KEY("TV Editing", "REDO", QT_TRANSLATE_NOOP("MythControls", 780 "Redo"), "Ctrl+Y"); 777 781 778 782 /* Teletext keys */ 779 783 REG_KEY("Teletext Menu", "NEXTPAGE", QT_TRANSLATE_NOOP("MythControls", … … 9310 9314 if ("EDIT_CUT_POINTS" == type) 9311 9315 osd->DialogAddButton(QObject::tr("Cut List Options"), 9312 9316 "DIALOG_CUTPOINT_CUTLISTOPTIONS_0", true); 9317 if (ctx->player->DeleteMapHasUndo()) 9318 osd->DialogAddButton(QObject::tr("Undo") + " - " + 9319 ctx->player->DeleteMapGetUndoMessage(), 9320 QString("DIALOG_CUTPOINT_UNDO_0")); 9321 if (ctx->player->DeleteMapHasRedo()) 9322 osd->DialogAddButton(QObject::tr("Redo") + " - " + 9323 ctx->player->DeleteMapGetRedoMessage(), 9324 QString("DIALOG_CUTPOINT_REDO_0")); 9313 9325 } 9314 9326 else if ("CUT_LIST_OPTIONS" == type) 9315 9327 { -
libs/libmythtv/deletemap.cpp
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 } 32 33 bool DeleteMap::Undo(void) 34 { 35 if (!HasUndo()) 36 return false; 37 m_undoStackPointer --; 38 m_deleteMap = m_undoStack[m_undoStackPointer].deleteMap; 39 m_changed = true; 40 return true; 41 } 42 43 bool DeleteMap::Redo(void) 44 { 45 if (!HasRedo()) 46 return false; 47 m_undoStackPointer ++; 48 m_deleteMap = m_undoStack[m_undoStackPointer].deleteMap; 49 m_changed = true; 50 return true; 51 } 52 53 QString DeleteMap::GetUndoMessage(void) 54 { 55 return (HasUndo() ? m_undoStack[m_undoStackPointer].message : 56 QObject::tr("(No more undo operations)")); 57 } 58 59 QString DeleteMap::GetRedoMessage(void) 60 { 61 return (HasRedo() ? m_undoStack[m_undoStackPointer + 1].message : 62 QObject::tr("(No more redo operations)")); 63 } 64 13 65 bool DeleteMap::HandleAction(QString &action, uint64_t frame, 14 66 uint64_t played, uint64_t total, double rate) 15 67 { … … 29 81 else if (action == "MOVENEXT") 30 82 MoveRelative(frame, total, true); 31 83 else if (action == "CUTTOBEGINNING") 32 Add(frame, total, MARK_CUT_END );84 Add(frame, total, MARK_CUT_END, QObject::tr("Cut To Beginning")); 33 85 else if (action == "CUTTOEND") 34 Add(frame, total, MARK_CUT_START );86 Add(frame, total, MARK_CUT_START, QObject::tr("Cut To End")); 35 87 else if (action == "NEWCUT") 36 88 NewCut(frame, total); 37 89 else if (action == "DELETE") 38 Delete(frame, total); 90 Delete(frame, total, QObject::tr("Delete Cut Area")); 91 else if (action == "UNDO") 92 Undo(); 93 else if (action == "REDO") 94 Redo(); 39 95 else 40 96 handled = false; 41 97 return handled; … … 154 210 { 155 211 m_deleteMap.clear(); 156 212 m_changed = true; 213 Push(QObject::tr("Clear Cut List")); 157 214 } 158 215 159 216 /// Reverses the direction of each mark in the map. … … 165 222 Add(it.key(), it.value() == MARK_CUT_END ? MARK_CUT_START : 166 223 MARK_CUT_END); 167 224 CleanMap(total); 225 Push(QObject::tr("Invert Cut List")); 168 226 } 169 227 170 228 /** … … 172 230 * existing redundant mark of that type is removed. This simplifies 173 231 * the cleanup code. 174 232 */ 175 void DeleteMap::Add(uint64_t frame, uint64_t total, MarkTypes type) 233 void DeleteMap::Add(uint64_t frame, uint64_t total, MarkTypes type, 234 QString undoMessage) 176 235 { 177 236 EDIT_CHECK 178 237 if ((MARK_CUT_START != type) && (MARK_CUT_END != type) && … … 186 245 { 187 246 // Delete the temporary mark before putting a real mark at its 188 247 // location 189 Delete(frame, total );248 Delete(frame, total, ""); 190 249 } 191 250 else // Don't add a mark on top of a mark 192 251 return; … … 241 300 Delete((uint64_t)remove); 242 301 Add(frame, type); 243 302 CleanMap(total); 303 if (!undoMessage.isEmpty()) 304 Push(undoMessage); 244 305 } 245 306 246 307 /// Remove the mark at the given frame. 247 void DeleteMap::Delete(uint64_t frame, uint64_t total )308 void DeleteMap::Delete(uint64_t frame, uint64_t total, QString undoMessage) 248 309 { 249 310 EDIT_CHECK 250 311 if (m_deleteMap.isEmpty()) … … 271 332 if (prev != next) 272 333 Delete(next); 273 334 CleanMap(total); 335 if (!undoMessage.isEmpty()) 336 Push(undoMessage); 274 337 } 275 338 276 339 /// Reverse the direction of the mark at the given frame. … … 278 341 { 279 342 EDIT_CHECK 280 343 int type = Delete(frame); 281 Add(frame, total, type == MARK_CUT_END ? MARK_CUT_START : MARK_CUT_END); 344 Add(frame, total, type == MARK_CUT_END ? MARK_CUT_START : MARK_CUT_END, ""); 345 Push(QObject::tr("Reverse Mark Direction")); 282 346 } 283 347 284 348 /// Add a new cut marker (to start or end a cut region) … … 376 440 Add(frame, MARK_PLACEHOLDER); 377 441 378 442 CleanMap(total); 443 Push(QObject::tr("New Cut")); 379 444 } 380 445 381 446 /// Move the previous (!right) or next (right) cut to frame. … … 397 462 { 398 463 // If on a mark, don't collapse a cut region to 0; 399 464 // instead, delete the region 400 Delete(frame, total );465 Delete(frame, total, QObject::tr("Delete Cut Area")); 401 466 return; 402 467 } 403 468 else if (MARK_PLACEHOLDER == type) 404 469 { 405 470 // Delete the temporary mark before putting a real mark at its 406 471 // location 407 Delete(frame, total );472 Delete(frame, total, ""); 408 473 } 409 474 } 410 475 … … 424 489 else if (frame == total) 425 490 type = MARK_CUT_END; 426 491 } 427 Add(to, total, type );492 Add(to, total, type, QObject::tr("Move Mark")); 428 493 } 429 494 430 495 /// Private addition to the deleteMap. … … 582 647 Clear(); 583 648 m_deleteMap = map; 584 649 m_deleteMap.detach(); 650 Push(QObject::tr("Set New Cut List")); 585 651 } 586 652 587 653 /// Loads the given commercial break map into the deleteMap. … … 593 659 Add(it.key(), it.value() == MARK_COMM_START ? 594 660 MARK_CUT_START : MARK_CUT_END); 595 661 CleanMap(total); 662 Push(QObject::tr("Load Commskip List")); 596 663 } 597 664 598 665 /// Loads the delete map from the database. … … 606 673 ctx->playingInfo->QueryCutList(m_deleteMap); 607 674 ctx->UnlockPlayingInfo(__FILE__, __LINE__); 608 675 CleanMap(total); 676 Push(QObject::tr("Load Cut List")); 609 677 } 610 678 611 679 /// Saves the delete map to the database. -
libs/libmythtv/mythplayer.cpp
3485 3485 { 3486 3486 if (IsInDelete(frame)) 3487 3487 { 3488 deleteMap.Delete(frame, totalFrames); 3488 deleteMap.Delete(frame, totalFrames, 3489 QObject::tr("Delete cut area")); 3489 3490 refresh = true; 3490 3491 } 3491 3492 }