Guest User

Untitled

a guest
Mar 11th, 2018
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 26.24 KB | None | 0 0
  1. # HG changeset patch
  2. # User Jérôme LAFORGE <jerome.laforge@gmail.com>
  3. # Date 1321047465 -3600
  4. # Node ID 2bfb11c2b9ae9ed46f1bb76fece40bda986af896
  5. # Parent  2c003ff12a8663eb51830764d440d59b238f8d1b
  6. Draft for ChangeLine.
  7.  
  8. diff -r 2c003ff12a86 -r 2bfb11c2b9ae include/Scintilla.h
  9. --- a/include/Scintilla.h   lun. nov. 07 12:55:32 2011 +1100
  10. +++ b/include/Scintilla.h   ven. nov. 11 22:37:45 2011 +0100
  11. @@ -2,7 +2,7 @@
  12.  /** @file Scintilla.h
  13.   ** Interface to the edit control.
  14.   **/
  15. -/* Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
  16. +/* Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
  17.   * The License.txt file describes the conditions under which this software may be distributed. */
  18.  
  19.  /* Most of this file is automatically generated from the Scintilla.iface interface definition
  20. @@ -832,6 +832,7 @@
  21.  #define SCI_SETTECHNOLOGY 2630
  22.  #define SCI_GETTECHNOLOGY 2631
  23.  #define SCI_CREATELOADER 2632
  24. +#define SCI_CLEARCHANGEMARGIN 2633
  25.  #define SCI_STARTRECORD 3001
  26.  #define SCI_STOPRECORD 3002
  27.  #define SCI_SETLEXER 4001
  28. diff -r 2c003ff12a86 -r 2bfb11c2b9ae include/Scintilla.iface
  29. --- a/include/Scintilla.iface   lun. nov. 07 12:55:32 2011 +1100
  30. +++ b/include/Scintilla.iface   ven. nov. 11 22:37:45 2011 +0100
  31. @@ -2205,6 +2205,9 @@
  32.  # Create an ILoader*.
  33.  fun int CreateLoader=2632(int bytes,)
  34.  
  35. +# Clear Change Margin
  36. +fun void ClearChangeMargin=2633(,)
  37. +
  38.  # Start notifying the container of all key presses and commands.
  39.  fun void StartRecord=3001(,)
  40.  
  41. diff -r 2c003ff12a86 -r 2bfb11c2b9ae src/CellBuffer.cxx
  42. --- a/src/CellBuffer.cxx    lun. nov. 07 12:55:32 2011 +1100
  43. +++ b/src/CellBuffer.cxx    ven. nov. 11 22:37:45 2011 +0100
  44. @@ -1,8 +1,10 @@
  45.  // Scintilla source code edit control
  46. +// -*- coding: utf-8 -*-
  47.  /** @file CellBuffer.cxx
  48.   ** Manages a buffer of cells.
  49.   **/
  50. -// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
  51. +// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
  52. +// 2011 : Add Line Change Margin by Jérôme LAFORGE <jerome.laforge@gmail.com>
  53.  // The License.txt file describes the conditions under which this software may be distributed.
  54.  
  55.  #include <stdio.h>
  56. @@ -21,6 +23,227 @@
  57.  using namespace Scintilla;
  58.  #endif
  59.  
  60. +ChangeUndo::ChangeUndo() {
  61. +   lineChangeUndo = NULL;
  62. +   line = -1;
  63. +   isFrozen = false;
  64. +}
  65. +
  66. +ChangeUndo::~ChangeUndo() {
  67. +   Destroy();
  68. +}
  69. +
  70. +void ChangeUndo::Create(int line) {
  71. +   Destroy();
  72. +   this->line = line;
  73. +}
  74. +
  75. +void ChangeUndo::Freeze() {
  76. +   isFrozen = true;
  77. +}
  78. +
  79. +void ChangeUndo::Update(LineChangeStatus status) {
  80. +   if (isFrozen || line == -1) return;
  81. +
  82. +   if (lineChangeUndo == NULL)
  83. +       lineChangeUndo = new std::vector<LineChangeStatus>();
  84. +   lineChangeUndo->push_back(status);
  85. +}
  86. +
  87. +void ChangeUndo::Destroy() {
  88. +   if (lineChangeUndo != NULL) {
  89. +       delete lineChangeUndo;
  90. +       lineChangeUndo = NULL;
  91. +   }
  92. +   line = -1;
  93. +   isFrozen = false;
  94. +}
  95. +
  96. +void ChangeMargin::SetNeedRedraw(int line, typeOfAction type) {
  97. +   //needRedraw = lineChange[line]->current == lineChange[line]->atSavePoint ||
  98. +   //      lineChange[line]->current == lineChange[line]->atSavePoint + (type == modifyOrRedo) ? 1 : -1; // perform redraw only if needed.
  99. +   // For debuging, force to redraw.
  100. +   needRedraw = true;
  101. +}
  102. +
  103. +bool ChangeMargin::IsEnabled() const {
  104. +   return isEnable;
  105. +}
  106. +
  107. +void ChangeMargin::SetEnabled(bool isEnable) {
  108. +   if (isEnable)
  109. +       Init();
  110. +   else
  111. +       Destroy();
  112. +}
  113. +
  114. +void ChangeMargin::Init() {
  115. +   if (isEnable) return;
  116. +   isEnable = true;
  117. +   needRedraw = false;
  118. +   // FIXME: When the empty file. Normally, lineChange[0].current have to be set to 1 (not 0).
  119. +   // Ensure at least one empty line.
  120. +   lineChange.EnsureLength(1);
  121. +   lineChange[0] = new LineChangeStatus();
  122. +   changeUndos.resize(100);
  123. +}
  124. +
  125. +void ChangeMargin::Destroy() {
  126. +   if (!isEnable) return;
  127. +   for (int i = 0; i < lineChange.Length(); i++)
  128. +       delete lineChange[i];
  129. +   lineChange.DeleteAll();
  130. +   ClearAllChangeUndo();
  131. +   isEnable = false;
  132. +}
  133. +
  134. +void ChangeMargin::InsertLine(int line, bool isRedoOrUndoStep, int undoAction, bool lineStart) {
  135. +   if (!isEnable) return;
  136. +
  137. +   if ((line > 0) && lineStart)
  138. +       line--;
  139. +
  140. +   LineChangeStatus *status = new LineChangeStatus(1);
  141. +
  142. +   if (undoAction > 0) {
  143. +       if (!isRedoOrUndoStep)
  144. +           undoAction--;
  145. +       int undoneLines = changeUndos[undoAction].line;
  146. +       if (changeUndos[undoAction].lineChangeUndo != NULL && (changeUndos[undoAction].lineChangeUndo->size() <= static_cast<size_t> (line - undoneLines)))
  147. +           line--;// Try to fix the line number.
  148. +       if (undoneLines != -1 && changeUndos[undoAction].lineChangeUndo != NULL) {
  149. +           status->atSavePoint = (*changeUndos[undoAction].lineChangeUndo)[line - undoneLines].atSavePoint;
  150. +           status->current = (*changeUndos[undoAction].lineChangeUndo)[line - undoneLines].current;
  151. +       }
  152. +   }
  153. +
  154. +   lineChange.Insert(line, status);
  155. +}
  156. +
  157. +void ChangeMargin::RemoveLine(int line, bool isRedoOrUndoStep, int undoAction) {
  158. +   if (!isEnable) return;
  159. +
  160. +   if (undoAction > 0) {
  161. +       if (!isRedoOrUndoStep)
  162. +           undoAction--;
  163. +       changeUndos[undoAction].Update(*(lineChange[line]));
  164. +   }
  165. +
  166. +   if (lineChange.Length() && (line < lineChange.Length())) {
  167. +       delete lineChange[line];
  168. +       lineChange.Delete(line);
  169. +   }
  170. +}
  171. +
  172. +void ChangeMargin::Modify(int line) {
  173. +   if (!isEnable) return;
  174. +
  175. +   if (lineChange[line]->current < lineChange[line]->atSavePoint){
  176. +       lineChange[line]->current = LineChangeStatus::sticky; // Impossible to come back to orginal, so the status is sticked.
  177. +   } else if (lineChange[line]->current != LineChangeStatus::sticky) {
  178. +       lineChange[line]->current += 1;
  179. +       SetNeedRedraw(line, modifyOrRedo);
  180. +   }
  181. +}
  182. +
  183. +void ChangeMargin::PerformUndoStep(int line) {
  184. +   if (!isEnable ||
  185. +           lineChange[line]->current == 0 ||
  186. +           lineChange[line]->current == LineChangeStatus::sticky)
  187. +       return;
  188. +
  189. +   lineChange[line]->current -= 1;
  190. +   SetNeedRedraw(line, undo);
  191. +}
  192. +
  193. +void ChangeMargin::PerformRedoStep(int line, bool ignorePreviousUpdate) {
  194. +   if (!isEnable || lineChange[line]->current >= LineChangeStatus::sticky - 1)
  195. +       return;
  196. +
  197. +   if (!ignorePreviousUpdate)
  198. +       lineChange[line]->current += 1;
  199. +   else
  200. +       lineChange[line]->current = 1;
  201. +   SetNeedRedraw(line, modifyOrRedo);
  202. +}
  203. +
  204. +void ChangeMargin::ReachSavePoint() {
  205. +   if (!isEnable) return;
  206. +   for (int i = 0; i < lineChange.Length(); i++) {
  207. +       if (lineChange[i]->current != lineChange[i]->atSavePoint) {
  208. +           if (lineChange[i]->current != LineChangeStatus::sticky) {
  209. +               if (lineChange[i]->current == 0)
  210. +                   lineChange[i]->current += 1; //undo all changes and save it, but this line still change. Otherwise, this line appears like unmodify.
  211. +               lineChange[i]->atSavePoint = lineChange[i]->current;
  212. +           } else {
  213. +               lineChange[i]->current = lineChange[i]->atSavePoint;
  214. +           }
  215. +           needRedraw = true;
  216. +       }
  217. +   }
  218. +}
  219. +
  220. +void ChangeMargin::ClearAll() {
  221. +   if (!isEnable) return;
  222. +   for (int i = 0; i < lineChange.Length(); i++) {
  223. +       if (lineChange[i]->current != 0) {
  224. +           lineChange[i]->current = 0;
  225. +           lineChange[i]->atSavePoint = 0;
  226. +           needRedraw = true;
  227. +       }
  228. +   }
  229. +   ClearAllChangeUndo();
  230. +}
  231. +
  232. +LineChangeStatus ChangeMargin::GetLineChange(int line) const {
  233. +   if (!isEnable) return LineChangeStatus();
  234. +
  235. +   return *lineChange[line];
  236. +}
  237. +
  238. +ChangeMargin::status ChangeMargin::GetStatus(int line) const {
  239. +   if (!isEnable) return original;
  240. +   LineChangeStatus status = GetLineChange(line);
  241. +   if (status.current < status.atSavePoint)
  242. +       return undone;
  243. +   else if (status.current == 0 && status.atSavePoint == 0)
  244. +       return original;
  245. +   else if (status.current == status.atSavePoint)
  246. +       return saved;
  247. +   else
  248. +       return changed;
  249. +}
  250. +
  251. +bool ChangeMargin::HasChangeOccuredAndClear() {
  252. +   bool b = needRedraw;
  253. +   needRedraw = false;
  254. +   return b;
  255. +}
  256. +
  257. +void ChangeMargin::EnsureUndoRoom(int size) {
  258. +   if (!isEnable) return;
  259. +   if (changeUndos.size() < static_cast<size_t> (size))
  260. +       changeUndos.resize(size);
  261. +}
  262. +
  263. +void ChangeMargin::StoreChangeUndo(int line, int undoAction) {
  264. +   changeUndos[undoAction].Create(line);
  265. +}
  266. +
  267. +void ChangeMargin::FreezeChangeUndo(int undoAction) {
  268. +   changeUndos[undoAction].Freeze();
  269. +}
  270. +
  271. +void ChangeMargin::DestroyChangeUndo(int undoAction) {
  272. +   if (!isEnable) return;
  273. +   changeUndos[undoAction].Destroy();
  274. +}
  275. +
  276. +void ChangeMargin::ClearAllChangeUndo() {
  277. +   if (!isEnable) return;
  278. +   changeUndos.clear();
  279. +}
  280. +
  281.  LineVector::LineVector() : starts(256), perLine(0) {
  282.     Init();
  283.  }
  284. @@ -329,6 +552,14 @@
  285.     currentAction++;
  286.  }
  287.  
  288. +int UndoHistory::GetCurrentAction() {
  289. +   return currentAction;
  290. +}
  291. +
  292. +int UndoHistory::GetLengthAction() {
  293. +   return lenActions;
  294. +}
  295. +
  296.  CellBuffer::CellBuffer() {
  297.     readOnly = false;
  298.     collectingUndo = true;
  299. @@ -388,9 +619,27 @@
  300.                 data[i] = s[i];
  301.             }
  302.             uh.AppendAction(insertAction, position, data, insertLength, startSequence);
  303. +
  304. +           if (cm.IsEnabled()) {
  305. +               cm.EnsureUndoRoom(uh.GetLengthAction());
  306. +               cm.StoreChangeUndo(LineFromPosition(position), uh.GetCurrentAction() - 1);
  307. +               cm.DestroyChangeUndo(uh.GetCurrentAction()); // Destroy for startAction.
  308. +           }
  309.         }
  310.  
  311. +       int previousNbLine = cm.IsEnabled() ? Lines() : -1;
  312. +       bool atLineStart = cm.IsEnabled() ? IsLineStartPosition(position) : false;
  313. +       bool atLineEnd = cm.IsEnabled() ? IsLineEndPosition(position + insertLength - 1) : false;
  314. +
  315.         BasicInsertString(position, s, insertLength);
  316. +      
  317. +       if (cm.IsEnabled()) {
  318. +           int newNbLine = Lines();
  319. +           if ((!atLineStart && !atLineEnd) || newNbLine == previousNbLine)
  320. +               cm.Modify(LineFromPosition(position));
  321. +           else if (!atLineStart && !atLineEnd && (newNbLine - previousNbLine > 1))
  322. +               cm.Modify(LineFromPosition(position + insertLength));
  323. +       }
  324.     }
  325.     return data;
  326.  }
  327. @@ -434,9 +683,20 @@
  328.                 data[i] = substance.ValueAt(position + i);
  329.             }
  330.             uh.AppendAction(removeAction, position, data, deleteLength, startSequence);
  331. +
  332. +           if (cm.IsEnabled()) {
  333. +               cm.EnsureUndoRoom(uh.GetLengthAction());
  334. +               cm.StoreChangeUndo(LineFromPosition(position), uh.GetCurrentAction() - 1);
  335. +           }
  336.         }
  337.  
  338. +       bool atLineStart = cm.IsEnabled() ? IsLineStartPosition(position) : false;
  339. +       bool atLineEnd = cm.IsEnabled() ? IsLineEndPosition(position + deleteLength - 1) : false;
  340. +
  341.         BasicDeleteChars(position, deleteLength);
  342. +
  343. +       if (cm.IsEnabled() && (!atLineStart || !atLineEnd))
  344. +           cm.Modify(LineFromPosition(position));
  345.     }
  346.     return data;
  347.  }
  348. @@ -467,6 +727,27 @@
  349.         return lv.LineStart(line);
  350.  }
  351.  
  352. +int CellBuffer::LineEnd(int line) const {
  353. +   if (line == Lines() - 1) {
  354. +       return lv.LineStart(line + 1);
  355. +   } else {
  356. +       int position = lv.LineStart(line + 1) - 1;
  357. +       // When line terminator is CR+LF, may need to go back one more
  358. +       if ((position > lv.LineStart(line)) && (CharAt(position - 1) == '\r')) {
  359. +           position--;
  360. +       }
  361. +       return position;
  362. +   }
  363. +}
  364. +
  365. +bool CellBuffer::IsLineStartPosition(int position) const {
  366. +   return LineStart(LineFromPosition(position)) == position;
  367. +}
  368. +
  369. +bool CellBuffer::IsLineEndPosition(int position) const {
  370. +   return LineEnd(LineFromPosition(position)) == position;
  371. +}
  372. +
  373.  bool CellBuffer::IsReadOnly() const {
  374.     return readOnly;
  375.  }
  376. @@ -477,6 +758,7 @@
  377.  
  378.  void CellBuffer::SetSavePoint() {
  379.     uh.SetSavePoint();
  380. +   cm.ReachSavePoint();
  381.  }
  382.  
  383.  bool CellBuffer::IsSavePoint() {
  384. @@ -487,10 +769,14 @@
  385.  
  386.  void CellBuffer::InsertLine(int line, int position, bool lineStart) {
  387.     lv.InsertLine(line, position, lineStart);
  388. +   cm.InsertLine(line, uh.GetRedoStep().at != startAction, uh.GetCurrentAction(), lineStart);
  389.  }
  390.  
  391. -void CellBuffer::RemoveLine(int line) {
  392. +void CellBuffer::RemoveLine(int line, bool atLineStart) {
  393.     lv.RemoveLine(line);
  394. +   if (atLineStart)
  395. +       line--;
  396. +   cm.RemoveLine(line, uh.GetRedoStep().at != startAction, uh.GetCurrentAction());
  397.  }
  398.  
  399.  void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
  400. @@ -501,6 +787,7 @@
  401.     substance.InsertFromArray(position, s, 0, insertLength);
  402.     style.InsertValue(position, insertLength, 0);
  403.  
  404. +
  405.     int lineInsert = lv.LineFromPosition(position) + 1;
  406.     bool atLineStart = lv.LineStart(lineInsert-1) == position;
  407.     // Point all the lines after the insertion point further along in the buffer
  408. @@ -546,11 +833,13 @@
  409.         // If whole buffer is being deleted, faster to reinitialise lines data
  410.         // than to delete each line.
  411.         lv.Init();
  412. +       cm.ClearAll(); // For now, we lost all informations (e.g. status for each line, undo history).
  413.     } else {
  414.         // Have to fix up line positions before doing deletion as looking at text in buffer
  415.         // to work out which lines have been removed
  416.  
  417.         int lineRemove = lv.LineFromPosition(position) + 1;
  418. +       bool atLineStart = IsLineStartPosition(position);
  419.         lv.InsertText(lineRemove-1, - (deleteLength));
  420.         char chPrev = substance.ValueAt(position - 1);
  421.         char chBefore = chPrev;
  422. @@ -568,16 +857,15 @@
  423.             chNext = substance.ValueAt(position + i + 1);
  424.             if (ch == '\r') {
  425.                 if (chNext != '\n') {
  426. -                   RemoveLine(lineRemove);
  427. +                   RemoveLine(lineRemove, atLineStart);
  428.                 }
  429.             } else if (ch == '\n') {
  430.                 if (ignoreNL) {
  431.                     ignoreNL = false;   // Further \n are real deletions
  432.                 } else {
  433. -                   RemoveLine(lineRemove);
  434. +                   RemoveLine(lineRemove, atLineStart);
  435.                 }
  436.             }
  437. -
  438.             ch = chNext;
  439.         }
  440.         // May have to fix up end if last deletion causes cr to be next to lf
  441. @@ -585,7 +873,7 @@
  442.         char chAfter = substance.ValueAt(position + deleteLength);
  443.         if (chBefore == '\r' && chAfter == '\n') {
  444.             // Using lineRemove-1 as cr ended line before start of deletion
  445. -           RemoveLine(lineRemove - 1);
  446. +           RemoveLine(lineRemove - 1, atLineStart);
  447.             lv.SetLineStart(lineRemove - 1, position + 1);
  448.         }
  449.     }
  450. @@ -614,10 +902,17 @@
  451.  void CellBuffer::AddUndoAction(int token, bool mayCoalesce) {
  452.     bool startSequence;
  453.     uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce);
  454. +
  455. +   if (cm.IsEnabled()) {
  456. +       cm.EnsureUndoRoom(uh.GetLengthAction());
  457. +       cm.DestroyChangeUndo(uh.GetCurrentAction() - 1);
  458. +   }
  459. +  
  460.  }
  461.  
  462.  void CellBuffer::DeleteUndoHistory() {
  463.     uh.DeleteUndoHistory();
  464. +   cm.ClearAllChangeUndo();
  465.  }
  466.  
  467.  bool CellBuffer::CanUndo() {
  468. @@ -633,12 +928,36 @@
  469.  }
  470.  
  471.  void CellBuffer::PerformUndoStep() {
  472. +   int previousNbLine = cm.IsEnabled() ? Lines() : -1;
  473.     const Action &actionStep = uh.GetUndoStep();
  474.     if (actionStep.at == insertAction) {
  475.         BasicDeleteChars(actionStep.position, actionStep.lenData);
  476.     } else if (actionStep.at == removeAction) {
  477.         BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData);
  478.     }
  479. +  
  480. +   if (cm.IsEnabled()) {
  481. +       bool atLineStart = IsLineStartPosition(actionStep.position);
  482. +       bool atLineEnd = IsLineEndPosition(actionStep.position);
  483. +       switch (actionStep.at) {
  484. +       case insertAction:
  485. +           if (!atLineStart || !atLineEnd)
  486. +               cm.PerformUndoStep(LineFromPosition(actionStep.position));
  487. +           break;
  488. +       case removeAction: {
  489. +           int newNbLine = Lines();
  490. +           bool atLineEnd = IsLineEndPosition(actionStep.position + actionStep.lenData - 1);
  491. +           if ((!atLineStart && !atLineEnd) || newNbLine == previousNbLine)
  492. +               cm.PerformUndoStep(LineFromPosition(actionStep.position));
  493. +           else if (!atLineStart)
  494. +               cm.PerformUndoStep(LineFromPosition(actionStep.position + actionStep.lenData));
  495. +       }
  496. +       default:
  497. +           //nothing to do.
  498. +           break;
  499. +       }
  500. +   }
  501. +   cm.FreezeChangeUndo(uh.GetCurrentAction());
  502.     uh.CompletedUndoStep();
  503.  }
  504.  
  505. @@ -655,12 +974,49 @@
  506.  }
  507.  
  508.  void CellBuffer::PerformRedoStep() {
  509. +   int previousNbLine = cm.IsEnabled() ? Lines() : -1;
  510.     const Action &actionStep = uh.GetRedoStep();
  511.     if (actionStep.at == insertAction) {
  512.         BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData);
  513.     } else if (actionStep.at == removeAction) {
  514.         BasicDeleteChars(actionStep.position, actionStep.lenData);
  515.     }
  516. +   if (cm.IsEnabled()) {
  517. +       bool atLineStart = IsLineStartPosition(actionStep.position);
  518. +       bool atLineEnd = IsLineEndPosition(actionStep.position + actionStep.lenData - 1);
  519. +       switch (actionStep.at) {
  520. +       case removeAction:
  521. +           if (!atLineStart)
  522. +               cm.PerformRedoStep(LineFromPosition(actionStep.position));
  523. +           break;
  524. +       case insertAction: {
  525. +           int newNbLine = Lines();
  526. +           if ((!atLineStart && !atLineEnd) || newNbLine == previousNbLine)
  527. +               cm.PerformRedoStep(LineFromPosition(actionStep.position));
  528. +           else if (!atLineStart)
  529. +               cm.PerformRedoStep(LineFromPosition(actionStep.position + actionStep.lenData), true);
  530. +       }
  531. +       default:
  532. +           //nothing to do.
  533. +           break;
  534. +       }
  535. +   }
  536. +   cm.FreezeChangeUndo(uh.GetCurrentAction());
  537.     uh.CompletedRedoStep();
  538.  }
  539.  
  540. +void CellBuffer::ClearChangeMargin() {
  541. +   cm.ClearAll();
  542. +}
  543. +
  544. +ChangeMargin::status CellBuffer::GetChangeMarginStatus(int line) const {
  545. +   return cm.GetStatus(line);
  546. +}
  547. +
  548. +LineChangeStatus CellBuffer::GetChangeMargin(int line) const {
  549. +   return cm.GetLineChange(line);
  550. +}
  551. +
  552. +bool CellBuffer::HasChangeMarginOccured() {
  553. +   return cm.HasChangeOccuredAndClear();
  554. +}
  555. diff -r 2c003ff12a86 -r 2bfb11c2b9ae src/CellBuffer.h
  556. --- a/src/CellBuffer.h  lun. nov. 07 12:55:32 2011 +1100
  557. +++ b/src/CellBuffer.h  ven. nov. 11 22:37:45 2011 +0100
  558. @@ -1,8 +1,10 @@
  559.  // Scintilla source code edit control
  560. +// -*- coding: utf-8 -*-
  561.  /** @file CellBuffer.h
  562.   ** Manages the text of the document.
  563.   **/
  564. -// Copyright 1998-2004 by Neil Hodgson <neilh@scintilla.org>
  565. +// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
  566. +// 2011 : Add Line Change Margin by Jérôme LAFORGE <jerome.laforge@gmail.com>
  567.  // The License.txt file describes the conditions under which this software may be distributed.
  568.  
  569.  #ifndef CELLBUFFER_H
  570. @@ -12,6 +14,84 @@
  571.  namespace Scintilla {
  572.  #endif
  573.  
  574. +#include <vector>
  575. +
  576. +struct LineChangeStatus {
  577. +   unsigned short int atSavePoint;
  578. +   unsigned short int current;
  579. +
  580. +   enum { noSaved = 0x0000, sticky = 0xFFFF };
  581. +   LineChangeStatus () {
  582. +       atSavePoint = noSaved;
  583. +       current = noSaved;
  584. +   }
  585. +
  586. +   LineChangeStatus(int current) {
  587. +       atSavePoint = noSaved;
  588. +       this->current = current;
  589. +   }
  590. +};
  591. +
  592. +class ChangeUndo {
  593. +public:
  594. +   std::vector<LineChangeStatus> *lineChangeUndo;
  595. +   int line;
  596. +   int isFrozen;
  597. +
  598. +   ChangeUndo();
  599. +   ~ChangeUndo();
  600. +   void Create(int line);
  601. +   void Freeze();
  602. +   void Update(LineChangeStatus status);
  603. +   void Destroy();
  604. +};
  605. +
  606. +class ChangeMargin {
  607. +private:
  608. +   bool isEnable;
  609. +   bool needRedraw;
  610. +   enum typeOfAction { modifyOrRedo, undo };
  611. +   void SetNeedRedraw(int line, typeOfAction type);
  612. +   SplitVector<LineChangeStatus *> lineChange;
  613. +   std::vector<ChangeUndo> changeUndos;
  614. +
  615. +public:
  616. +   enum status { original, changed, saved, undone };
  617. +
  618. +   ChangeMargin() : isEnable(false) {
  619. +       Init();
  620. +   }
  621. +   ~ChangeMargin() {
  622. +       Destroy();
  623. +   }
  624. +   bool IsEnabled() const;
  625. +   void SetEnabled(bool isEnable);
  626. +   void Init();
  627. +   void Destroy();
  628. +
  629. +   void InsertLine(int line, bool isRedoOrUndoStep, int undoAction, bool lineStart);
  630. +   void RemoveLine(int line, bool isRedoOrUndoStep, int undoAction);
  631. +
  632. +   void Modify(int line);
  633. +   void ReachSavePoint();
  634. +   void ClearAll();
  635. +  
  636. +   LineChangeStatus GetLineChange(int line) const;
  637. +   status GetStatus(int line) const;
  638. +   bool HasChangeOccuredAndClear();
  639. +
  640. +   // For managing the undo/redo.
  641. +   void PerformUndoStep(int line);
  642. +   void PerformRedoStep(int line, bool ignorePrevisousUpdate=false);
  643. +
  644. +   // For managing the undo stack.
  645. +   void EnsureUndoRoom(int size);
  646. +   void StoreChangeUndo(int line, int undoAction);
  647. +   void FreezeChangeUndo(int undoAction);
  648. +   void DestroyChangeUndo(int undoAction);
  649. +   void ClearAllChangeUndo();
  650. +};
  651. +
  652.  // Interface to per-line data that wants to see each line insertion and deletion
  653.  class PerLine {
  654.  public:
  655. @@ -124,6 +204,8 @@
  656.     int StartRedo();
  657.     const Action &GetRedoStep() const;
  658.     void CompletedRedoStep();
  659. +   int GetCurrentAction();
  660. +   int GetLengthAction();
  661.  };
  662.  
  663.  /**
  664. @@ -142,6 +224,8 @@
  665.  
  666.     LineVector lv;
  667.  
  668. +   ChangeMargin cm;
  669. +
  670.     /// Actions without undo
  671.     void BasicInsertString(int position, const char *s, int insertLength);
  672.     void BasicDeleteChars(int position, int deleteLength);
  673. @@ -163,9 +247,12 @@
  674.     void SetPerLine(PerLine *pl);
  675.     int Lines() const;
  676.     int LineStart(int line) const;
  677. +   int LineEnd(int line) const;
  678. +   bool IsLineStartPosition(int position) const;
  679. +   bool IsLineEndPosition(int position) const;
  680.     int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
  681.     void InsertLine(int line, int position, bool lineStart);
  682. -   void RemoveLine(int line);
  683. +   void RemoveLine(int line, bool lineStart=false);
  684.     const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
  685.  
  686.     /// Setting styles for positions outside the range of the buffer is safe and has no effect.
  687. @@ -200,6 +287,11 @@
  688.     int StartRedo();
  689.     const Action &GetRedoStep() const;
  690.     void PerformRedoStep();
  691. +
  692. +   void ClearChangeMargin();
  693. +   ChangeMargin::status GetChangeMarginStatus(int line) const;
  694. +   LineChangeStatus GetChangeMargin(int line) const;
  695. +   bool HasChangeMarginOccured();
  696.  };
  697.  
  698.  #ifdef SCI_NAMESPACE
  699. diff -r 2c003ff12a86 -r 2bfb11c2b9ae src/Document.cxx
  700. --- a/src/Document.cxx  lun. nov. 07 12:55:32 2011 +1100
  701. +++ b/src/Document.cxx  ven. nov. 11 22:37:45 2011 +0100
  702. @@ -2028,6 +2028,22 @@
  703.     return - 1;
  704.  }
  705.  
  706. +void Document::ClearChangeMargin() {
  707. +   return cb.ClearChangeMargin();
  708. +}
  709. +
  710. +ChangeMargin::status Document::GetChangeMarginStatus(int line) {
  711. +   return cb.GetChangeMarginStatus(line);
  712. +}
  713. +
  714. +LineChangeStatus Document::GetChangeMargin(int line) {
  715. +   return cb.GetChangeMargin(line);
  716. +}
  717. +
  718. +bool Document::HasChangeMarginOccured() {
  719. +   return cb.HasChangeMarginOccured();
  720. +}
  721. +
  722.  /**
  723.   * Implementation of RegexSearchBase for the default built-in regular expression engine
  724.   */
  725. diff -r 2c003ff12a86 -r 2bfb11c2b9ae src/Document.h
  726. --- a/src/Document.h    lun. nov. 07 12:55:32 2011 +1100
  727. +++ b/src/Document.h    ven. nov. 11 22:37:45 2011 +0100
  728. @@ -413,6 +413,11 @@
  729.     int IndentSize() { return actualIndentInChars; }
  730.     int BraceMatch(int position, int maxReStyle);
  731.  
  732. +   void ClearChangeMargin();
  733. +   ChangeMargin::status GetChangeMarginStatus(int line);
  734. +   LineChangeStatus GetChangeMargin(int line);
  735. +   bool HasChangeMarginOccured();
  736. +
  737.  private:
  738.     bool IsWordStartAt(int pos);
  739.     bool IsWordEndAt(int pos);
  740. diff -r 2c003ff12a86 -r 2bfb11c2b9ae src/Editor.cxx
  741. --- a/src/Editor.cxx    lun. nov. 07 12:55:32 2011 +1100
  742. +++ b/src/Editor.cxx    ven. nov. 11 22:37:45 2011 +0100
  743. @@ -659,6 +659,7 @@
  744.     PRectangle rcClient = GetClientRectangle();
  745.     wMain.InvalidateRectangle(rcClient);
  746.     //wMain.InvalidateAll();
  747. +   pdoc->HasChangeMarginOccured(); // Reset change line.
  748.  }
  749.  
  750.  void Editor::RedrawSelMargin(int line, bool allAfter) {
  751. @@ -1936,8 +1937,25 @@
  752.                 if (vs.ms[margin].style == SC_MARGIN_NUMBER) {
  753.                     char number[100];
  754.                     number[0] = '\0';
  755. -                   if (firstSubLine)
  756. -                       sprintf(number, "%d", lineDoc + 1);
  757. +                   if (firstSubLine) {
  758. +                       if (true) { // for testing and helping during the developpment process. Have to be removed after.
  759. +                           LineChangeStatus lineChange = pdoc->GetChangeMargin(lineDoc);
  760. +                           switch (pdoc->GetChangeMarginStatus(lineDoc)) {
  761. +                           case ChangeMargin::saved:
  762. +                               sprintf(number, "[%4X][%4X]#%d", lineChange.atSavePoint, lineChange.current, lineDoc + 1);
  763. +                               break;
  764. +                           case ChangeMargin::changed:
  765. +                           case ChangeMargin::undone:
  766. +                               sprintf(number, "[%4X][%4X]#%d", lineChange.atSavePoint, lineChange.current, lineDoc + 1);
  767. +                               break;
  768. +                           case ChangeMargin::original:
  769. +                               sprintf(number, "[%4X][%4X]-%d", lineChange.atSavePoint, lineChange.current, lineDoc + 1);
  770. +                               break;
  771. +                           }
  772. +                       } else {
  773. +                           sprintf(number, "%d", lineDoc + 1);
  774. +                       }
  775. +                   }
  776.                     if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) {
  777.                         int lev = pdoc->GetLevel(lineDoc);
  778.                         sprintf(number, "%c%c %03X %03X",
  779. @@ -1952,9 +1970,23 @@
  780.                     int width = surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, istrlen(number));
  781.                     int xpos = rcNumber.right - width - 3;
  782.                     rcNumber.left = xpos;
  783. +                   ColourDesired fore = vs.styles[STYLE_LINENUMBER].fore;
  784. +                   switch (pdoc->GetChangeMarginStatus(lineDoc)) {
  785. +                   case ChangeMargin::saved:
  786. +                       fore = ColourDesired(0, 255, 0);
  787. +                       break;
  788. +                   case ChangeMargin::changed:
  789. +                   case ChangeMargin::undone:
  790. +                       fore = ColourDesired(255, 0, 0);
  791. +                       break;
  792. +                   case ChangeMargin::original:
  793. +                       //do nothing
  794. +                       break;
  795. +                   }
  796.                     surface->DrawTextNoClip(rcNumber, vs.styles[STYLE_LINENUMBER].font,
  797.                             rcNumber.top + vs.maxAscent, number, istrlen(number),
  798. -                           vs.styles[STYLE_LINENUMBER].fore,
  799. +                           fore,
  800. +                           //vs.styles[STYLE_LINENUMBER].fore,
  801.                             vs.styles[STYLE_LINENUMBER].back);
  802.                 } else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) {
  803.                     if (firstSubLine) {
  804. @@ -4088,6 +4120,9 @@
  805.     if (recordingMacro) {
  806.         NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(s));
  807.     }
  808. +
  809. +   if (pdoc->HasChangeMarginOccured())
  810. +       RedrawSelMargin();
  811.  }
  812.  
  813.  void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) {
  814. @@ -4281,6 +4316,8 @@
  815.         if (newPos >= 0)
  816.             SetEmptySelection(newPos);
  817.         EnsureCaretVisible();
  818. +       if (pdoc->HasChangeMarginOccured())
  819. +           RedrawSelMargin();
  820.     }
  821.  }
  822.  
  823. @@ -4290,6 +4327,8 @@
  824.         if (newPos >= 0)
  825.             SetEmptySelection(newPos);
  826.         EnsureCaretVisible();
  827. +       if (pdoc->HasChangeMarginOccured())
  828. +           RedrawSelMargin();
  829.     }
  830.  }
  831.  
  832. @@ -4299,6 +4338,9 @@
  833.     }
  834.     // Avoid blinking during rapid typing:
  835.     ShowCaretAtCurrentPosition();
  836. +
  837. +   if (pdoc->HasChangeMarginOccured())
  838. +       RedrawSelMargin();
  839.  }
  840.  
  841.  void Editor::DelCharBack(bool allowLineStartDeletion) {
  842. @@ -4344,6 +4386,9 @@
  843.     sel.RemoveDuplicates();
  844.     // Avoid blinking during rapid typing:
  845.     ShowCaretAtCurrentPosition();
  846. +
  847. +   if (pdoc->HasChangeMarginOccured())
  848. +       RedrawSelMargin();
  849.  }
  850.  
  851.  void Editor::NotifyFocus(bool) {}
  852. @@ -5013,6 +5058,9 @@
  853.     EnsureCaretVisible();
  854.     // Avoid blinking during rapid typing:
  855.     ShowCaretAtCurrentPosition();
  856. +
  857. +   if (pdoc->HasChangeMarginOccured())
  858. +       RedrawSelMargin();
  859.  }
  860.  
  861.  void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) {
  862. @@ -7610,6 +7658,8 @@
  863.  
  864.     case SCI_SETSAVEPOINT:
  865.         pdoc->SetSavePoint();
  866. +       if (pdoc->HasChangeMarginOccured())
  867. +           RedrawSelMargin();
  868.         break;
  869.  
  870.     case SCI_GETSTYLEDTEXT: {
  871. @@ -9259,6 +9309,12 @@
  872.     case SCI_GETTECHNOLOGY:
  873.         return technology;
  874.  
  875. +   case SCI_CLEARCHANGEMARGIN:
  876. +       pdoc->ClearChangeMargin();
  877. +       if (pdoc->HasChangeMarginOccured())
  878. +           RedrawSelMargin();
  879. +       break;
  880. +
  881.     default:
  882.         return DefWndProc(iMessage, wParam, lParam);
  883.     }
Add Comment
Please, Sign In to add comment