You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
6.5 KiB
290 lines
6.5 KiB
13 years ago
|
// Scintilla source code edit control
|
||
|
/** @file ContractionState.cxx
|
||
|
** Manages visibility of lines for folding.
|
||
|
**/
|
||
|
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||
|
// 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<linesInDoc; lineInDoc++) {
|
||
|
lines[lineInDoc].displayLine = linesInDisplay;
|
||
|
if (lines[lineInDoc].visible) {
|
||
|
linesInDisplay += lines[lineInDoc].height;
|
||
|
}
|
||
|
}
|
||
|
if (sizeDocLines < linesInDisplay) {
|
||
|
delete []docLines;
|
||
|
int *docLinesNew = new int[linesInDisplay + growSize];
|
||
|
if (!docLinesNew) {
|
||
|
docLines = 0;
|
||
|
sizeDocLines = 0;
|
||
|
return;
|
||
|
}
|
||
|
docLines = docLinesNew;
|
||
|
sizeDocLines = linesInDisplay + growSize;
|
||
|
}
|
||
|
|
||
|
int lineInDisplay=0;
|
||
|
for (int line=0; line<linesInDoc; line++) {
|
||
|
if (lines[line].visible) {
|
||
|
for (int linePiece=0; linePiece<lines[line].height; linePiece++) {
|
||
|
docLines[lineInDisplay] = line;
|
||
|
lineInDisplay++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
valid = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ContractionState::Clear() {
|
||
|
delete []lines;
|
||
|
lines = 0;
|
||
|
size = 0;
|
||
|
linesInDoc = 1;
|
||
|
linesInDisplay = 1;
|
||
|
delete []docLines;
|
||
|
docLines = 0;
|
||
|
sizeDocLines = 0;
|
||
|
}
|
||
|
|
||
|
int ContractionState::LinesInDoc() const {
|
||
|
return linesInDoc;
|
||
|
}
|
||
|
|
||
|
int ContractionState::LinesDisplayed() const {
|
||
|
if (size != 0) {
|
||
|
MakeValid();
|
||
|
}
|
||
|
return linesInDisplay;
|
||
|
}
|
||
|
|
||
|
int ContractionState::DisplayFromDoc(int lineDoc) const {
|
||
|
if (size == 0) {
|
||
|
return lineDoc;
|
||
|
}
|
||
|
MakeValid();
|
||
|
if ((lineDoc >= 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<lineCount;d++) {
|
||
|
lines[lineDoc+d].visible = true; // Should inherit visibility from context ?
|
||
|
lines[lineDoc+d].height = 1;
|
||
|
lines[lineDoc+d].expanded = true;
|
||
|
}
|
||
|
valid = false;
|
||
|
}
|
||
|
|
||
|
void ContractionState::DeleteLines(int lineDoc, int lineCount) {
|
||
|
if (size == 0) {
|
||
|
linesInDoc -= lineCount;
|
||
|
linesInDisplay -= lineCount;
|
||
|
return;
|
||
|
}
|
||
|
int deltaDisplayed = 0;
|
||
|
for (int d=0;d<lineCount;d++) {
|
||
|
if (lines[lineDoc+d].visible)
|
||
|
deltaDisplayed -= lines[lineDoc+d].height;
|
||
|
}
|
||
|
for (int i = lineDoc; i < linesInDoc-lineCount; i++) {
|
||
|
if (i != 0) // Line zero is always visible
|
||
|
lines[i].visible = lines[i + lineCount].visible;
|
||
|
lines[i].expanded = lines[i + lineCount].expanded;
|
||
|
lines[i].height = lines[i + lineCount].height;
|
||
|
}
|
||
|
linesInDoc -= lineCount;
|
||
|
linesInDisplay += deltaDisplayed;
|
||
|
valid = false;
|
||
|
}
|
||
|
|
||
|
bool ContractionState::GetVisible(int lineDoc) const {
|
||
|
if (size == 0)
|
||
|
return true;
|
||
|
if ((lineDoc >= 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;
|
||
|
}
|