// Scintilla source code edit control /** @file ContractionState.cxx ** Manages visibility of lines for folding. **/ // Copyright 1998-2001 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; height = 1; expanded = true; } ContractionState::ContractionState() { lines = 0; size = 0; linesInDoc = 1; linesInDisplay = 1; valid = false; docLines = 0; sizeDocLines = 0; } 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. linesInDisplay = 0; for (int lineInDoc=0; lineInDoc= 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; if (size == 0) return lineDisplay; MakeValid(); if (docLines) { // Valid allocation return docLines[lineDisplay]; } else { return 0; } } 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; for (int i = linesInDoc; i >= lineDoc + lineCount; i--) { lines[i].visible = lines[i - lineCount].visible; lines[i].height = lines[i - lineCount].height; linesInDisplay += lines[i].height; 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 ? lines[line].height : -lines[line].height; 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) { if (expanded) { // If in completely expanded state then setting // one line to expanded has no effect. return false; } Grow(linesInDoc + growSize); } if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { if (lines[lineDoc].expanded != expanded) { lines[lineDoc].expanded = expanded; return true; } } return false; } int ContractionState::GetHeight(int lineDoc) const { if (size == 0) return 1; if ((lineDoc >= 0) && (lineDoc < linesInDoc)) { return lines[lineDoc].height; } else { return 1; } } // Set the number of display lines needed for this line. // Return true if this is a change. bool ContractionState::SetHeight(int lineDoc, int height) { if (lineDoc > linesInDoc) return false; if (size == 0) { if (height == 1) { // If in completely expanded state then all lines // assumed to have height of one so no effect here. return false; } Grow(linesInDoc + growSize); } if (lines[lineDoc].height != height) { lines[lineDoc].height = height; valid = false; return true; } else { return false; } } void ContractionState::ShowAll() { delete []lines; lines = 0; size = 0; delete []docLines; docLines = 0; sizeDocLines = 0; linesInDisplay = linesInDoc; }