/* TUIpeer works in conjunction with an implementation of java.awt.Toolkit to provide a Text User Interface for programs using the Java AWT. Copyright (C) 1997-2000 Stuart D. Gathman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #pragma implementation #include #include "textselect.h" #include #include TextSelection::TextSelection(class TextArray &t): txt(t) { markrow = row = 0; col = markcol = 0; isgap = true; } long TextSelection::getPos(int line,int offset) const { // normalize line and offset if (line < 0) return 0L; long pos = 0; int n = txt.size(); if (line >= n) { line = n; offset = 0; } for (int i = 0; i < line; ++i) pos += strlen(txt[i]) + 1; virtpos p(txt[line]); return pos + p.mappos(offset); } long TextSelection::getStart() const { return (isgap || isReversed()) ? getPos(row,col) : getPos(markrow,markcol); } long TextSelection::getEnd() const { return (isReversed() && !isgap) ? getPos(markrow,markcol) : getPos(row,col); } void TextSelection::setCursor(int r,int c) { int orow = row; int ocol = col; row = r; col = c; if (!isgap) { if (cmpCursor(orow,ocol,row,col) < 0) selectionChanged(orow,ocol,row,col); else selectionChanged(row,col,orow,ocol); } } void TextSelection::setPos(long pos) { int n = txt.size(); for (int line = 0; line < n; ++line) { int len = strlen(txt[line]) + 1; if (len > pos) { virtpos p(txt[line]); setCursor(line,p.mapidx((int)pos)); return; } pos -= len; } setCursor(n,0); } void TextSelection::select(long start, long end) { isgap = true; if (start != end) { setPos(start); mark(); } setPos(end); } void TextSelection::mark() { // set mark = cursor isgap = !isgap; if (isgap) { if (isReversed()) selectionChanged(row,col,markrow,markcol); else selectionChanged(markrow,markcol,row,col); } markrow = row; markcol = col; } bool TextSelection::rowSelected(int r) const { if (isgap) return false; if (row <= markrow) return r >= row && r <= markrow; else return r >= markrow && r <= row; } bool TextSelection::isSelected(int r,int c) const { if (isgap) return false; if (isReversed()) return cmpCursor(row,col,r,c) <= 0 && cmpCursor(markrow,markcol,r,c) > 0; return cmpCursor(row,col,r,c) > 0 && cmpCursor(markrow,markcol,r,c) <= 0; } bool TextSelection::isGap() const { return isgap || markrow == row && markcol == col; } bool TextSelection::isReversed() const { return cmpCursor(row,col,markrow,markcol) < 0; } string TextSelection::getSelectedText() const { if (isGap()) return ""; int r1 = getStartRow(); virtpos p1(txt[r1]); int c1 = p1.mappos(getStartCol()); int r2 = getRow(); if (r1 == r2) { int c2 = p1.mappos(getCol()); return string(txt[r1] + c1,c2 - c1); } virtpos p2(txt[r2]); int c2 = p2.mappos(getCol()); string s(txt[r1] + c1); while (++r1 < r2) { s += '\n'; s += txt[r1]; } s += '\n'; return s + string(txt[r2],c2); } int TextSelection::getStartRow() const { return (isgap || isReversed()) ? row : markrow; } int TextSelection::getStartCol() const { return (isgap || isReversed()) ? col : markcol; } int TextSelection::getEndRow() const { return (!isgap && isReversed()) ? markrow : row; } int TextSelection::getEndCol() const { return (!isgap && isReversed()) ? markcol : col; }