View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002424 | Far Manager | Editor | public | 2013-06-06 20:35 | 2013-06-28 16:26 |
Reporter | xarx | Assigned To | DrKnS | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 3.0 | ||||
Fixed in Version | 3.0 | ||||
Summary | 0002424: Undo не восстанавливает закладки | ||||
Description | Undo (CtrlZ) удаленного текста в редакторе не восстанавливает удаленные закладки (созданные через BM.add). http://forum.farmanager.com/viewtopic.php?f=9&t=8003 Patch fixing the issue is available. | ||||
Steps To Reproduce | 1. Create several bookmarks via BM.Add(), on different lines 2. Delete several lines including some of those, where bookmarks were created 3. Undo (CtrlZ) Now you see that the bookmarks that were on the deleted lines are not navigable, they were deleted permanently in step 2. | ||||
Additional Information | Это проблема прежде всего при частом использовании плагинов FilterLines, BlockProcessor,... Потому что каждый раз, когда я выполняю фильтрацию, все закладки в редакторе удаляют. | ||||
Tags | bookmarks, editor | ||||
Build | 3450 | ||||
|
undo_bookmarks.diff (11,767 bytes)
diff -ur orig/unicode_far/editor.cpp new/unicode_far/editor.cpp --- orig/unicode_far/editor.cpp 2013-06-01 05:47:05.226023900 +0200 +++ new/unicode_far/editor.cpp 2013-06-06 21:20:47.581933600 +0200 @@ -3188,35 +3188,6 @@ return; } - std::for_each(RANGE(SavePos, i) - { - if (i.Line != POS_NONE && UndoLine < static_cast<int>(i.Line)) - --i.Line; - }); - - if (SessionPos) - { - InternalEditorSessionBookMark *sb_temp = SessionPos, *sb_new; - - while (sb_temp->prev) - sb_temp=sb_temp->prev; - - while (sb_temp) - { - sb_new = sb_temp->next; - - if (UndoLine < static_cast<int>(sb_temp->Line)) - sb_temp->Line--; - else - { - if (UndoLine == static_cast<int>(sb_temp->Line)) - DeleteSessionBookmark(sb_temp); - } - - sb_temp = sb_new; - } - } - NumLastLine--; if(LastGetLine) @@ -3289,6 +3260,40 @@ if (UndoLine!=-1) AddUndoData(UNDO_DELSTR,DelPtr->GetStringAddr(),DelPtr->GetEOL(),UndoLine,0,DelPtr->GetLength()); + std::for_each(RANGE(SavePos, i) + { + //FIXME: it would be better to add the bookmarks for deleted line to UndoData + if (i.Line != POS_NONE && UndoLine < static_cast<int>(i.Line)) + --i.Line; + }); + + if (SessionPos) + { + InternalEditorSessionBookMark *sb_temp = SessionPos, *sb_new; + + while (sb_temp->prev) + sb_temp=sb_temp->prev; + + while (sb_temp) + { + sb_new = sb_temp->next; + + if (UndoLine < static_cast<int>(sb_temp->Line)) + sb_temp->Line--; + else + { + if (UndoLine == static_cast<int>(sb_temp->Line)) + { + if (UndoLine!=-1) + AddUndoData(sb_temp); + DeleteSessionBookmark(sb_temp); + } + } + + sb_temp = sb_new; + } + } + delete DelPtr; Change(ECTYPE_DELETED,UndoLine); @@ -4998,6 +5003,16 @@ } } +void Editor::AddUndoData(const InternalEditorSessionBookMark *BM) +{ + if (Flags.Check(FEDITOR_DISABLEUNDO)) + return; + if (UndoPos->Type != UNDO_DELSTR) + return; + + UndoPos->AddSessionBM(BM); +} + void Editor::Undo(int redo) { auto ustart = UndoPos; @@ -5082,6 +5097,16 @@ Pasting--; + { + InternalEditorSessionBookMark *BM = ud->BM; + while (BM) + { + InsertSessionBookmarkBack(BM); + BM = BM->next; + } + ud->DeleteAllSessionBM(); + } + if (ud->Str) { CurLine->SetString(ud->Str.get(),ud->Length); @@ -6497,6 +6522,7 @@ return FALSE; } +//Set the numbered bookmark (CtrlShift-0..9) int Editor::SetBookmark(int Pos) { if (Pos < static_cast<int>(SavePos.size())) @@ -6512,6 +6538,7 @@ return FALSE; } +//Restore the numbered bookmark (LeftCtrl-0..9) int Editor::GotoBookmark(int Pos) { if (Pos < static_cast<int>(SavePos.size())) @@ -6539,6 +6566,8 @@ return FALSE; } +//Remove all session bookmarks; +// SessionPos will be NULL int Editor::ClearSessionBookmarks() { NewSessionPos = FALSE; @@ -6550,7 +6579,7 @@ while (SessionPos) { sb_next = SessionPos->next; - xf_free(SessionPos); + delete SessionPos; SessionPos = sb_next; } @@ -6559,7 +6588,7 @@ while (SessionPos) { sb_prev = SessionPos->prev; - xf_free(SessionPos); + delete SessionPos; SessionPos = sb_prev; } } @@ -6567,6 +6596,8 @@ return TRUE; } +//Remove a particular session bookmark +// adjusts SessionPos if deleting the current bookmark int Editor::DeleteSessionBookmark(InternalEditorSessionBookMark *sb_delete) { NewSessionPos=FALSE; @@ -6589,10 +6620,11 @@ return FALSE; } +//Restore the current session bookmark int Editor::RestoreSessionBookmark() { NewSessionPos=FALSE; - + //only if the cursor is elsewhere if (SessionPos && ((int)SessionPos->Line!=NumLine || (int)SessionPos->Cursor!=CurLine->GetCurPos())) { GoToLine(SessionPos->Line); @@ -6613,10 +6645,13 @@ return FALSE; } +//Add current cursor pos to session bookmarks, after the current bookmark, +// and adjust SessionPos to it int Editor::AddSessionBookmark(BOOL blNewPos) { InternalEditorSessionBookMark *sb_old=SessionPos; + //remove all subsequent bookmarks if (SessionPos && SessionPos->next) { SessionPos=SessionPos->next; @@ -6626,8 +6661,8 @@ SessionPos->next=0; } + //append new bookmark auto sb_new = new InternalEditorSessionBookMark; - if (sb_new) { if (SessionPos) @@ -6647,6 +6682,67 @@ return FALSE; } +//Insert the session bookmark on its original position in the list of session bookmarks, if it still exists, +// otherwise do nothing +int Editor::InsertSessionBookmarkBack(InternalEditorSessionBookMark *sb_ins) +{ + //Search for the bookmark referred in sb_ins->prev. But it needs not exist already... + + //look up forward + InternalEditorSessionBookMark *sb_new = NULL, *sb_temp=SessionPos; + while (sb_temp && sb_temp != sb_ins->prev) + sb_temp=sb_temp->next; + + if (sb_temp) + { + //found, insert sb_ins immediately after sb_temp + sb_new = new InternalEditorSessionBookMark(*sb_ins); + if (sb_new) + { + sb_new->next = sb_temp->next; + sb_temp->next = sb_new; + if (sb_new->next) + sb_new->next->prev = sb_new; + } + } + else + { + //not found forward, look up backwards + sb_temp=SessionPos; + while (sb_temp && sb_temp->prev != sb_ins->prev) + sb_temp=sb_temp->prev; + + if (sb_temp) + { + //found, insert sb_ins immediately before sb_temp + sb_new = new InternalEditorSessionBookMark(*sb_ins); + if (sb_new) + { + sb_new->next = sb_temp; + sb_temp->prev = sb_new; + if (sb_new->prev) + sb_new->prev->next = sb_new; + } + } + else if (!sb_ins->prev) + { + //SessionPos is NULL, but sb_ins was the first sb in the list + sb_new = new InternalEditorSessionBookMark(*sb_ins); + if (sb_new) + { + sb_new->next = NULL; + SessionPos = sb_new; + } + } + else + sb_new = sb_ins; //just to mark success + } + + return sb_new?TRUE:FALSE; +} + +//Return the first session bookmark (and do not change SessionPos); +// On return, piCount will be set to the count of session bookmark preceding the current one InternalEditorSessionBookMark* Editor::PointerToFirstSessionBookmark(int *piCount) { InternalEditorSessionBookMark *sb_temp=SessionPos; @@ -6664,6 +6760,9 @@ return sb_temp; } +//Return the last session bookmark (and do not change SessionPos); +// piCount must be set to the count of session bookmarks preceding the current one +// On return piCount will be set to the total count of session bookmarks InternalEditorSessionBookMark* Editor::PointerToLastSessionBookmark(int *piCount) { InternalEditorSessionBookMark *sb_temp=SessionPos; @@ -6682,6 +6781,8 @@ return sb_temp; } +//Return the session bookmark of index iIdx (and do not change SessionPos); +// for iIdx==-1 the current bookmark is returned InternalEditorSessionBookMark* Editor::PointerToSessionBookmark(int iIdx) // Returns null_ptr if failed! { InternalEditorSessionBookMark *sb_temp=SessionPos; @@ -6717,6 +6818,7 @@ return FALSE; } +//Restore the previous session bookmark, if there is any, the current one otherwise int Editor::PrevSessionBookmark() { if (SessionPos) @@ -6732,6 +6834,7 @@ return FALSE; } +//Restore the next session bookmark, if there is any, the current one otherwise int Editor::NextSessionBookmark() { if (SessionPos) @@ -6747,6 +6850,7 @@ return FALSE; } +//Restore the last session bookmark int Editor::LastSessionBookmark() { if (SessionPos) @@ -6758,6 +6862,8 @@ return FALSE; } +//Restore the session bookmark at the specified index; +// does nothing if there is no such index int Editor::GotoSessionBookmark(int iIdx) { if (SessionPos) @@ -6773,17 +6879,20 @@ return FALSE; } +//Append new session bookmark as the last session bookmark, and move SessionPos to it int Editor::PushSessionBookMark() { SessionPos=PointerToLastSessionBookmark(); return AddSessionBookmark(FALSE); } +//Restore the last session bookmark and remove it int Editor::PopSessionBookMark() { return (LastSessionBookmark() && DeleteSessionBookmark(SessionPos)); } +//Return index of the current session bookmark, -1 if there is none int Editor::CurrentSessionBookmarkIdx() { int iIdx; @@ -6792,6 +6901,7 @@ return -1; } +//Get session bookmark at specified index into Param int Editor::GetSessionBookmark(int iIdx,InternalEditorBookmark *Param) { InternalEditorSessionBookMark *sb_temp = PointerToSessionBookmark(iIdx); @@ -6809,6 +6919,7 @@ return FALSE; } +//Get all session bookmarks into the Param array int Editor::GetSessionBookmarks(EditorBookmarks *Param) { int iCount=0; diff -ur orig/unicode_far/editor.hpp new/unicode_far/editor.hpp --- orig/unicode_far/editor.hpp 2013-06-01 05:47:04.599988100 +0200 +++ new/unicode_far/editor.hpp 2013-06-06 21:23:31.207292500 +0200 @@ -37,6 +37,7 @@ #include "poscache.hpp" #include "bitflags.hpp" #include "config.hpp" +#include <algorithm> class FileEditor; class KeyBar; @@ -66,13 +67,15 @@ wchar_t EOL[10]; int Length; wchar_t_ptr Str; + InternalEditorSessionBookMark *BM; //treat as uni-directional linked list static size_t UndoDataSize; EditorUndoData(int Type,const wchar_t *Str,const wchar_t *Eol,int StrNum,int StrPos,int Length=-1): Type(0), StrPos(0), StrNum(0), - Length(0) + Length(0), + BM(0) { SetData(Type, Str, Eol, StrNum, StrPos, Length); } @@ -81,9 +84,11 @@ { if (Length > 0) UndoDataSize -= Length; + DeleteAllSessionBM(); } - EditorUndoData(EditorUndoData&& Right) + EditorUndoData(EditorUndoData&& Right): + BM(0) { *this = std::move(Right); Right.Length = 0; @@ -97,6 +102,7 @@ Length = Right.Length; Str.swap(Right.Str); wcscpy(EOL, Right.EOL); + std::swap(BM, Right.BM); return *this; } @@ -124,6 +130,29 @@ } else this->Str.reset(); + DeleteAllSessionBM(); + } + + void AddSessionBM(const InternalEditorSessionBookMark *BM) + { + InternalEditorSessionBookMark *BM_new = new InternalEditorSessionBookMark(*BM); + if (BM_new) + { + BM_new->next = this->BM; + this->BM = BM_new; + } + } + + void DeleteAllSessionBM() + { + InternalEditorSessionBookMark *BM=this->BM, *BM_next; + this->BM = NULL; + while (BM) + { + BM_next = BM->next; + delete BM; + BM = BM_next; + } } }; @@ -232,8 +261,9 @@ int StartLine; int StartChar; + //numbered bookmarks (accessible by Ctrl-0..9) Bookmarks<editor_bookmark> SavePos; - + //pointer to the current "session" bookmark (in the list of "session" bookmarks accessible through BM.Goto(n)) InternalEditorSessionBookMark *SessionPos; BOOL NewSessionPos; @@ -279,6 +309,7 @@ void UnmarkMacroBlock(); void AddUndoData(int Type,const wchar_t *Str=nullptr,const wchar_t *Eol=nullptr,int StrNum=0,int StrPos=0,int Length=-1); + void AddUndoData(const InternalEditorSessionBookMark *BM); void Undo(int redo); void SelectAll(); //void SetStringsTable(); @@ -298,6 +329,7 @@ int DeleteSessionBookmark(InternalEditorSessionBookMark *sb_delete); int RestoreSessionBookmark(); int AddSessionBookmark(BOOL blNewPos=TRUE); + int InsertSessionBookmarkBack(InternalEditorSessionBookMark *sb_ins); InternalEditorSessionBookMark* PointerToFirstSessionBookmark(int *piCount=nullptr); InternalEditorSessionBookMark* PointerToLastSessionBookmark(int *piCount=nullptr); InternalEditorSessionBookMark* PointerToSessionBookmark(int iIdx); |
|
I have implemented the required functionality, and uploaded the patch (see above). undo_bookmarks2.diff is the newest patch, it improves behaviour in some special situations. |
|
undo_bookmarks2.diff (12,293 bytes)
diff -ur orig/unicode_far/editor.cpp new/unicode_far/editor.cpp --- orig/unicode_far/editor.cpp 2013-06-01 05:47:05.226023900 +0200 +++ new/unicode_far/editor.cpp 2013-06-07 00:46:08.848669800 +0200 @@ -3188,35 +3188,6 @@ return; } - std::for_each(RANGE(SavePos, i) - { - if (i.Line != POS_NONE && UndoLine < static_cast<int>(i.Line)) - --i.Line; - }); - - if (SessionPos) - { - InternalEditorSessionBookMark *sb_temp = SessionPos, *sb_new; - - while (sb_temp->prev) - sb_temp=sb_temp->prev; - - while (sb_temp) - { - sb_new = sb_temp->next; - - if (UndoLine < static_cast<int>(sb_temp->Line)) - sb_temp->Line--; - else - { - if (UndoLine == static_cast<int>(sb_temp->Line)) - DeleteSessionBookmark(sb_temp); - } - - sb_temp = sb_new; - } - } - NumLastLine--; if(LastGetLine) @@ -3289,6 +3260,40 @@ if (UndoLine!=-1) AddUndoData(UNDO_DELSTR,DelPtr->GetStringAddr(),DelPtr->GetEOL(),UndoLine,0,DelPtr->GetLength()); + std::for_each(RANGE(SavePos, i) + { + //FIXME: it would be better to add the bookmarks for deleted line to UndoData + if (i.Line != POS_NONE && UndoLine < static_cast<int>(i.Line)) + --i.Line; + }); + + if (SessionPos) + { + InternalEditorSessionBookMark *sb_temp = SessionPos, *sb_new; + + while (sb_temp->prev) + sb_temp=sb_temp->prev; + + while (sb_temp) + { + sb_new = sb_temp->next; + + if (UndoLine < static_cast<int>(sb_temp->Line)) + sb_temp->Line--; + else + { + if (UndoLine == static_cast<int>(sb_temp->Line)) + { + if (UndoLine!=-1) + AddUndoData(sb_temp); + DeleteSessionBookmark(sb_temp); + } + } + + sb_temp = sb_new; + } + } + delete DelPtr; Change(ECTYPE_DELETED,UndoLine); @@ -4998,6 +5003,16 @@ } } +void Editor::AddUndoData(const InternalEditorSessionBookMark *BM) +{ + if (Flags.Check(FEDITOR_DISABLEUNDO)) + return; + if (UndoPos->Type != UNDO_DELSTR) + return; + + UndoPos->AddSessionBM(BM); +} + void Editor::Undo(int redo) { auto ustart = UndoPos; @@ -5082,6 +5097,16 @@ Pasting--; + { + InternalEditorSessionBookMark *BM = ud->BM; + while (BM) + { + InsertSessionBookmarkBack(BM); + BM = BM->next; + } + ud->DeleteAllSessionBM(); + } + if (ud->Str) { CurLine->SetString(ud->Str.get(),ud->Length); @@ -6497,6 +6522,7 @@ return FALSE; } +//Set the numbered bookmark (CtrlShift-0..9) int Editor::SetBookmark(int Pos) { if (Pos < static_cast<int>(SavePos.size())) @@ -6512,6 +6538,7 @@ return FALSE; } +//Restore the numbered bookmark (LeftCtrl-0..9) int Editor::GotoBookmark(int Pos) { if (Pos < static_cast<int>(SavePos.size())) @@ -6539,6 +6566,8 @@ return FALSE; } +//Remove all session bookmarks; +// SessionPos will be NULL int Editor::ClearSessionBookmarks() { NewSessionPos = FALSE; @@ -6550,7 +6579,7 @@ while (SessionPos) { sb_next = SessionPos->next; - xf_free(SessionPos); + delete SessionPos; SessionPos = sb_next; } @@ -6559,7 +6588,7 @@ while (SessionPos) { sb_prev = SessionPos->prev; - xf_free(SessionPos); + delete SessionPos; SessionPos = sb_prev; } } @@ -6567,6 +6596,8 @@ return TRUE; } +//Remove a particular session bookmark +// adjusts SessionPos if deleting the current bookmark int Editor::DeleteSessionBookmark(InternalEditorSessionBookMark *sb_delete) { NewSessionPos=FALSE; @@ -6589,10 +6620,11 @@ return FALSE; } +//Restore the current session bookmark int Editor::RestoreSessionBookmark() { NewSessionPos=FALSE; - + //only if the cursor is elsewhere if (SessionPos && ((int)SessionPos->Line!=NumLine || (int)SessionPos->Cursor!=CurLine->GetCurPos())) { GoToLine(SessionPos->Line); @@ -6613,10 +6645,13 @@ return FALSE; } +//Add current cursor pos to session bookmarks, after the current bookmark, +// and adjust SessionPos to it int Editor::AddSessionBookmark(BOOL blNewPos) { InternalEditorSessionBookMark *sb_old=SessionPos; + //remove all subsequent bookmarks if (SessionPos && SessionPos->next) { SessionPos=SessionPos->next; @@ -6626,8 +6661,8 @@ SessionPos->next=0; } + //append new bookmark auto sb_new = new InternalEditorSessionBookMark; - if (sb_new) { if (SessionPos) @@ -6647,6 +6682,69 @@ return FALSE; } +//Insert the session bookmark on its original position in the list of session bookmarks, if it still exists, +// otherwise do nothing; sb_ins->prev is hashed to better differentiate among session bookmarks +int Editor::InsertSessionBookmarkBack(InternalEditorSessionBookMark *sb_ins) +{ + //Search for the bookmark referred in sb_ins->prev. But it needs not exist already... + + //look up forward + InternalEditorSessionBookMark *sb_new = NULL, *sb_temp=SessionPos; + while (sb_temp && EditorUndoData::HashBM(sb_temp) != sb_ins->prev) + sb_temp=sb_temp->next; + + if (sb_temp) + { + //found, insert sb_ins immediately after sb_temp + sb_new = new InternalEditorSessionBookMark(*sb_ins); + if (sb_new) + { + sb_new->prev = sb_temp; + sb_new->next = sb_temp->next; + sb_temp->next = sb_new; + if (sb_new->next) + sb_new->next->prev = sb_new; + } + } + else + { + //not found forward, look up backwards + sb_temp=SessionPos; + while (sb_temp && EditorUndoData::HashBM(sb_temp->prev) != sb_ins->prev) + sb_temp=sb_temp->prev; + + if (sb_temp) + { + //found, insert sb_ins immediately before sb_temp + sb_new = new InternalEditorSessionBookMark(*sb_ins); + if (sb_new) + { + sb_new->prev = sb_temp->prev; + sb_new->next = sb_temp; + sb_temp->prev = sb_new; + if (sb_new->prev) + sb_new->prev->next = sb_new; + } + } + else if (!sb_ins->prev) + { + //SessionPos is NULL, but sb_ins was the first sb in the list + sb_new = new InternalEditorSessionBookMark(*sb_ins); + if (sb_new) + { + sb_new->next = NULL; + SessionPos = sb_new; + } + } + else + sb_new = sb_ins; //just to mark success + } + + return sb_new?TRUE:FALSE; +} + +//Return the first session bookmark (and do not change SessionPos); +// On return, piCount will be set to the count of session bookmark preceding the current one InternalEditorSessionBookMark* Editor::PointerToFirstSessionBookmark(int *piCount) { InternalEditorSessionBookMark *sb_temp=SessionPos; @@ -6664,6 +6762,9 @@ return sb_temp; } +//Return the last session bookmark (and do not change SessionPos); +// piCount must be set to the count of session bookmarks preceding the current one +// On return piCount will be set to the total count of session bookmarks InternalEditorSessionBookMark* Editor::PointerToLastSessionBookmark(int *piCount) { InternalEditorSessionBookMark *sb_temp=SessionPos; @@ -6682,6 +6783,8 @@ return sb_temp; } +//Return the session bookmark of index iIdx (and do not change SessionPos); +// for iIdx==-1 the current bookmark is returned InternalEditorSessionBookMark* Editor::PointerToSessionBookmark(int iIdx) // Returns null_ptr if failed! { InternalEditorSessionBookMark *sb_temp=SessionPos; @@ -6717,6 +6820,7 @@ return FALSE; } +//Restore the previous session bookmark, if there is any, the current one otherwise int Editor::PrevSessionBookmark() { if (SessionPos) @@ -6732,6 +6836,7 @@ return FALSE; } +//Restore the next session bookmark, if there is any, the current one otherwise int Editor::NextSessionBookmark() { if (SessionPos) @@ -6747,6 +6852,7 @@ return FALSE; } +//Restore the last session bookmark int Editor::LastSessionBookmark() { if (SessionPos) @@ -6758,6 +6864,8 @@ return FALSE; } +//Restore the session bookmark at the specified index; +// does nothing if there is no such index int Editor::GotoSessionBookmark(int iIdx) { if (SessionPos) @@ -6773,17 +6881,20 @@ return FALSE; } +//Append new session bookmark as the last session bookmark, and move SessionPos to it int Editor::PushSessionBookMark() { SessionPos=PointerToLastSessionBookmark(); return AddSessionBookmark(FALSE); } +//Restore the last session bookmark and remove it int Editor::PopSessionBookMark() { return (LastSessionBookmark() && DeleteSessionBookmark(SessionPos)); } +//Return index of the current session bookmark, -1 if there is none int Editor::CurrentSessionBookmarkIdx() { int iIdx; @@ -6792,6 +6903,7 @@ return -1; } +//Get session bookmark at specified index into Param int Editor::GetSessionBookmark(int iIdx,InternalEditorBookmark *Param) { InternalEditorSessionBookMark *sb_temp = PointerToSessionBookmark(iIdx); @@ -6809,6 +6921,7 @@ return FALSE; } +//Get all session bookmarks into the Param array int Editor::GetSessionBookmarks(EditorBookmarks *Param) { int iCount=0; diff -ur orig/unicode_far/editor.hpp new/unicode_far/editor.hpp --- orig/unicode_far/editor.hpp 2013-06-01 05:47:04.599988100 +0200 +++ new/unicode_far/editor.hpp 2013-06-07 00:54:50.933531300 +0200 @@ -37,6 +37,7 @@ #include "poscache.hpp" #include "bitflags.hpp" #include "config.hpp" +#include <algorithm> class FileEditor; class KeyBar; @@ -66,13 +67,15 @@ wchar_t EOL[10]; int Length; wchar_t_ptr Str; + InternalEditorSessionBookMark *BM; //treat as uni-directional linked list static size_t UndoDataSize; EditorUndoData(int Type,const wchar_t *Str,const wchar_t *Eol,int StrNum,int StrPos,int Length=-1): Type(0), StrPos(0), StrNum(0), - Length(0) + Length(0), + BM(0) { SetData(Type, Str, Eol, StrNum, StrPos, Length); } @@ -81,9 +84,11 @@ { if (Length > 0) UndoDataSize -= Length; + DeleteAllSessionBM(); } - EditorUndoData(EditorUndoData&& Right) + EditorUndoData(EditorUndoData&& Right): + BM(0) { *this = std::move(Right); Right.Length = 0; @@ -97,6 +102,7 @@ Length = Right.Length; Str.swap(Right.Str); wcscpy(EOL, Right.EOL); + std::swap(BM, Right.BM); return *this; } @@ -124,6 +130,42 @@ } else this->Str.reset(); + DeleteAllSessionBM(); + } + + void AddSessionBM(const InternalEditorSessionBookMark *BM) + { + InternalEditorSessionBookMark *BM_new = new InternalEditorSessionBookMark(*BM); + if (BM_new) + { + BM_new->prev = HashBM(BM->prev); + BM_new->next = this->BM; + this->BM = BM_new; + } + } + + void DeleteAllSessionBM() + { + InternalEditorSessionBookMark *BM=this->BM, *BM_next; + this->BM = NULL; + while (BM) + { + BM_next = BM->next; + delete BM; + BM = BM_next; + } + } + + static InternalEditorSessionBookMark *HashBM(InternalEditorSessionBookMark *BM) + { + if (BM) + { + size_t x = reinterpret_cast<size_t>(BM); + x = x ^ (BM->Line<<16) ^ (BM->Cursor); + return reinterpret_cast<InternalEditorSessionBookMark *>(x); + } + else + return NULL; } }; @@ -232,8 +274,9 @@ int StartLine; int StartChar; + //numbered bookmarks (accessible by Ctrl-0..9) Bookmarks<editor_bookmark> SavePos; - + //pointer to the current "session" bookmark (in the list of "session" bookmarks accessible through BM.Goto(n)) InternalEditorSessionBookMark *SessionPos; BOOL NewSessionPos; @@ -279,6 +322,7 @@ void UnmarkMacroBlock(); void AddUndoData(int Type,const wchar_t *Str=nullptr,const wchar_t *Eol=nullptr,int StrNum=0,int StrPos=0,int Length=-1); + void AddUndoData(const InternalEditorSessionBookMark *BM); void Undo(int redo); void SelectAll(); //void SetStringsTable(); @@ -298,6 +342,7 @@ int DeleteSessionBookmark(InternalEditorSessionBookMark *sb_delete); int RestoreSessionBookmark(); int AddSessionBookmark(BOOL blNewPos=TRUE); + int InsertSessionBookmarkBack(InternalEditorSessionBookMark *sb_ins); InternalEditorSessionBookMark* PointerToFirstSessionBookmark(int *piCount=nullptr); InternalEditorSessionBookMark* PointerToLastSessionBookmark(int *piCount=nullptr); InternalEditorSessionBookMark* PointerToSessionBookmark(int iIdx); |
|
3450. |
|
Verified in build 3479. |
Date Modified | Username | Field | Change |
---|---|---|---|
2013-06-06 20:35 | xarx | New Issue | |
2013-06-06 20:35 | xarx | File Added: undo_bookmarks.diff | |
2013-06-06 20:37 | xarx | Note Added: 0011111 | |
2013-06-06 20:37 | xarx | Note Edited: 0011111 | |
2013-06-06 20:38 | xarx | Note Edited: 0011111 | |
2013-06-06 20:38 | xarx | Tag Attached: editor | |
2013-06-06 20:38 | xarx | Tag Attached: bookmarks | |
2013-06-07 00:01 | xarx | File Added: undo_bookmarks2.diff | |
2013-06-07 00:03 | xarx | Note Edited: 0011111 | |
2013-06-12 19:33 | DrKnS | Note Added: 0011131 | |
2013-06-12 19:33 | DrKnS | Assigned To | => DrKnS |
2013-06-12 19:33 | DrKnS | Status | new => feedback |
2013-06-28 10:26 | xarx | Note Added: 0011209 | |
2013-06-28 10:26 | xarx | Status | feedback => assigned |
2013-06-28 10:26 | xarx | Status | assigned => resolved |
2013-06-28 16:26 | DrKnS | Build | => 3450 |
2013-06-28 16:26 | DrKnS | Status | resolved => closed |
2013-06-28 16:26 | DrKnS | Resolution | open => fixed |
2013-06-28 16:26 | DrKnS | Fixed in Version | => 3.0 |