00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "katetextline.h"
00024 #include <kdebug.h>
00025
00026 TextLine::TextLine(uchar attribute, int context)
00027 : text(0L), attributes(0L), attr(attribute), ctx(context), myMark (0)
00028 {
00029 }
00030
00031 TextLine::~TextLine()
00032 {
00033 }
00034
00035
00036 void TextLine::replace(uint pos, uint delLen, const QChar *insText, uint insLen, uchar *insAttribs)
00037 {
00038 uint oldLen = text.length();
00039
00040 text.remove (pos, delLen);
00041 text.insert (pos, insText, insLen);
00042
00043 if (oldLen<text.length()) attributes.resize (text.length());
00044
00045 if (text.length() == 0)
00046 {
00047 attributes.resize (0);
00048 return;
00049 }
00050
00051 if (pos >= oldLen)
00052 {
00053 for (uint t=oldLen; t < attributes.size(); t++)
00054 {
00055 attributes[t]=0;
00056 }
00057 }
00058
00059 int newAtStuff = insLen-delLen;
00060 for (uint m=pos+delLen; m < attributes.size(); m++)
00061 {
00062 if (m+newAtStuff >= attributes.size()) break;
00063 if (m >= attributes.size()) break;
00064
00065 attributes[m+newAtStuff]=attributes[m];
00066 }
00067
00068 if (insAttribs == 0L)
00069 {
00070 for (uint m3=pos; m3 < pos+insLen; m3++)
00071 {
00072 if (m3 < attributes.size()) attributes[m3]=0;
00073 }
00074 }
00075 else
00076 {
00077 for (uint m2=pos; m2 < pos+insLen; m2++)
00078 {
00079 if (m2 < attributes.size()) attributes[m2]=insAttribs[m2-pos];
00080 }
00081 }
00082
00083 if (oldLen>text.length()) attributes.resize (text.length());
00084 }
00085
00086 void TextLine::wrap(TextLine::Ptr nextLine, uint pos)
00087 {
00088 int l = text.length() - pos;
00089
00090 if (l > 0)
00091 {
00092 nextLine->replace(0, 0, &text.unicode()[pos], l, &attributes[pos]);
00093 attr = attributes[pos];
00094 truncate(pos);
00095 }
00096 }
00097
00098 void TextLine::unWrap(uint pos, TextLine::Ptr nextLine, uint len) {
00099
00100 replace(pos, 0, nextLine->text.unicode(), len, nextLine->attributes.data());
00101 attr = nextLine->getRawAttr(len);
00102 nextLine->replace(0, len, 0L, 0);
00103 }
00104
00105 int TextLine::firstChar() const {
00106 uint z = 0;
00107
00108 while (z < text.length() && text[z].isSpace()) z++;
00109
00110 if (z < text.length())
00111 return z;
00112 else
00113 return -1;
00114 }
00115
00116 int TextLine::lastChar() const {
00117 uint z = text.length();
00118
00119 while (z > 0 && text[z - 1].isSpace()) z--;
00120 return z;
00121 }
00122
00123 void TextLine::removeSpaces() {
00124
00125 while (text.length() > 0 && text[text.length() - 1].isSpace()) text.truncate (text.length()-1);
00126 }
00127
00128 QChar TextLine::getChar(uint pos) const {
00129 if (pos < text.length()) return text.constref(pos);
00130 return ' ';
00131 }
00132 const QChar *TextLine::firstNonSpace()
00133 {
00134 const QChar *ptr=getText();
00135 int first=firstChar();
00136 return (first > -1) ? ptr+first : ptr;
00137 }
00138
00139 bool TextLine::startingWith(QString& match)
00140 {
00141 return text.startsWith (match);
00142 }
00143
00144 bool TextLine::endingWith(QString& match) {
00145
00146 int matchLen = match.length();
00147
00148
00149 QString lastChars = text.right(matchLen);
00150
00151 return (lastChars == match);
00152 }
00153
00154 int TextLine::cursorX(uint pos, uint tabChars) const {
00155 int l, x, z;
00156
00157 l = (pos < text.length()) ? pos : text.length();
00158 x = 0;
00159 for (z = 0; z < l; z++) {
00160 if (text[z] == '\t') x += tabChars - (x % tabChars); else x++;
00161 }
00162 x += pos - l;
00163 return x;
00164 }
00165
00166 void TextLine::setAttribs(uchar attribute, uint start, uint end) {
00167 uint z;
00168
00169 if (end > text.length()) end = text.length();
00170 for (z = start; z < end; z++) attributes[z] = (attributes[z] & taSelected) | attribute;
00171 }
00172
00173 void TextLine::setAttr(uchar attribute) {
00174 attr = (attr & taSelected) | attribute;
00175 }
00176
00177 uchar TextLine::getAttr(uint pos) const {
00178 if (pos < text.length()) return attributes[pos] & taAttrMask;
00179 return attr & taAttrMask;
00180 }
00181
00182 uchar TextLine::getAttr() const {
00183 return attr & taAttrMask;
00184 }
00185
00186 uchar TextLine::getRawAttr(uint pos) const {
00187 if (pos < text.length()) return attributes[pos];
00188 return (attr & taSelected) ? attr : attr | 256;
00189 }
00190
00191 uchar TextLine::getRawAttr() const {
00192 return attr;
00193 }
00194
00195 void TextLine::setContext(int context) {
00196 ctx = context;
00197 }
00198
00199 int TextLine::getContext() const {
00200 return ctx;
00201 }
00202
00203
00204 void TextLine::select(bool sel, uint start, uint end) {
00205 uint z;
00206
00207 if (end > text.length()) end = text.length();
00208 if (sel) {
00209 for (z = start; z < end; z++) attributes[z] |= taSelected;
00210 } else {
00211 for (z = start; z < end; z++) attributes[z] &= ~taSelected;
00212 }
00213 }
00214
00215 void TextLine::selectEol(bool sel, uint pos) {
00216 uint z;
00217
00218 if (sel) {
00219 for (z = pos; z < text.length(); z++) attributes[z] |= taSelected;
00220 attr |= taSelected;
00221 } else {
00222 for (z = pos; z < text.length(); z++) attributes[z] &= ~taSelected;
00223 attr &= ~taSelected;
00224 }
00225 }
00226
00227
00228 void TextLine::toggleSelect(uint start, uint end) {
00229 uint z;
00230
00231 if (end > text.length()) end = text.length();
00232 for (z = start; z < end; z++) attributes[z] = attributes[z] ^ taSelected;
00233 }
00234
00235
00236 void TextLine::toggleSelectEol(uint pos) {
00237 uint z;
00238
00239 for (z = pos; z < text.length(); z++) attributes[z] = attributes[z] ^ taSelected;
00240 attr = attr ^ taSelected;
00241 }
00242
00243
00244 int TextLine::numSelected() const {
00245 uint z, n;
00246
00247 n = 0;
00248 for (z = 0; z < text.length(); z++) if (attributes[z] & taSelected) n++;
00249 return n;
00250 }
00251
00252 bool TextLine::isSelected(uint pos) const {
00253 if (pos < text.length()) return (attributes[pos] & taSelected);
00254 return (attr & taSelected);
00255 }
00256
00257 bool TextLine::isSelected() const {
00258 return (attr & taSelected);
00259 }
00260
00261 int TextLine::findSelected(uint pos) const {
00262 while (pos < text.length() && attributes[pos] & taSelected) pos++;
00263 return pos;
00264 }
00265
00266 int TextLine::findUnselected(uint pos) const {
00267 while (pos < text.length() && !(attributes[pos] & taSelected)) pos++;
00268 return pos;
00269 }
00270
00271 int TextLine::findRevSelected(uint pos) const {
00272 while (pos > 0 && attributes[pos - 1] & taSelected) pos--;
00273 return pos;
00274 }
00275
00276 int TextLine::findRevUnselected(uint pos) const {
00277 while (pos > 0 && !(attributes[pos - 1] & taSelected)) pos--;
00278 return pos;
00279 }
00280
00281 void TextLine::addMark (uint m)
00282 {
00283 myMark = myMark | m;
00284 }
00285
00286 void TextLine::delMark (uint m)
00287 {
00288 myMark = myMark & ~m;
00289 }