// Scintilla source code edit control // ContractionState.cxx - manages visibility of lines for folding // Copyright 1998-2000 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. #include "Platform.h" #include "ContractionState.h" OneLine::OneLine() { displayLine = 0; docLine = 0; visible = true; expanded = true; } ContractionState::ContractionState() { lines = 0; size = 0; linesInDoc = 1; linesInDisplay = 1; valid = false; } ContractionState::~ContractionState() { Clear(); } void ContractionState::MakeValid() const { if (!valid) { // Could be cleverer by keeping the index of the last still valid entry // rather than invalidating all. int lineDisplay = 0; for (int line=0; line= 0) && (lineDoc < linesInDoc)) { return lines[lineDoc].displayLine; } return -1; } int ContractionState::DocFromDisplay(int lineDisplay) const { if (lineDisplay <= 0) return 0; if (lineDisplay >= linesInDisplay) return linesInDoc-1; if (size == 0) return lineDisplay; MakeValid(); return lines[lineDisplay].docLine; } void ContractionState::Grow(int sizeNew) { OneLine *linesNew = new OneLine[sizeNew]; if (linesNew) { int i = 0; for (; i < size; i++) { linesNew[i] = lines[i]; } for (; i < sizeNew; i++) { linesNew[i].displayLine = i; } delete []lines; lines = linesNew; size = sizeNew; valid = false; } else { Platform::DebugPrintf("No memory available\n"); // TODO: Blow up } } void ContractionState::InsertLines(int lineDoc, int lineCount) { if (size == 0) { linesInDoc += lineCount; linesInDisplay += lineCount; return; } //Platform::DebugPrintf("InsertLine[%d] = %d\n", lineDoc); if ((linesInDoc + lineCount + 2) >= size) { Grow(linesInDoc + lineCount + growSize); } linesInDoc += lineCount; linesInDisplay += lineCount; for (int i = linesInDoc; i >= lineDoc + lineCount; i--) { lines[i].visible = lines[i - lineCount].visible; lines[i].expanded = lines[i - lineCount].expanded; } for (int d=0;d= 0) && (lineDoc < linesInDoc)) { return lines[lineDoc].visible; } else { return false; } } bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { if (lineDocStart == 0) lineDocStart++; if (lineDocStart > lineDocEnd) return false; if (size == 0) { Grow(linesInDoc + growSize); } // TODO: modify docLine members to mirror displayLine int delta = 0; // Change lineDocs if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < linesInDoc)) { for (int line=lineDocStart; line <= lineDocEnd; line++) { if (lines[line].visible != visible) { delta += visible ? 1 : -1; lines[line].visible = visible; } } } linesInDisplay += delta; valid = false; return delta != 0; } bool ContractionState::GetExpanded(int lineDoc) const { if (size == 0) return true; if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { return lines[lineDoc].expanded; } else { return false; } } bool ContractionState::SetExpanded(int lineDoc, bool expanded) { if (size == 0) { Grow(linesInDoc + growSize); } if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { if (lines[lineDoc].expanded != expanded) { lines[lineDoc].expanded = expanded; return true; } } return false; } void ContractionState::ShowAll() { delete []lines; lines = 0; size = 0; }