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
00025 #include <qregexp.h>
00026 #include <kglobal.h>
00027
00028 KateTextLine::KateTextLine ()
00029 : m_flags(KateTextLine::flagVisible)
00030 {
00031 }
00032
00033 KateTextLine::~KateTextLine()
00034 {
00035 }
00036
00037 void KateTextLine::insertText (uint pos, uint insLen, const QChar *insText, uchar *insAttribs)
00038 {
00039
00040 if (insLen == 0)
00041 return;
00042
00043
00044 uint oldTextLen = m_text.length();
00045 m_text.insert (pos, insText, insLen);
00046 uint textLen = m_text.length();
00047
00048
00049 m_attributes.resize (textLen);
00050
00051
00052 if (pos >= oldTextLen)
00053 {
00054 for (uint z = oldTextLen; z < pos; z++)
00055 m_attributes[z] = 0;
00056 }
00057
00058 else if (oldTextLen > 0)
00059 {
00060 for (int z = oldTextLen -1; z >= (int) pos; z--)
00061 m_attributes[z+insLen] = m_attributes[z];
00062 }
00063
00064
00065 for (uint z = 0; z < insLen; z++)
00066 {
00067 if (insAttribs == 0)
00068 m_attributes[z+pos] = 0;
00069 else
00070 m_attributes[z+pos] = insAttribs[z];
00071 }
00072 }
00073
00074 void KateTextLine::removeText (uint pos, uint delLen)
00075 {
00076
00077 if (delLen == 0)
00078 return;
00079
00080 uint textLen = m_text.length();
00081
00082 if (textLen == 0)
00083 return;
00084
00085 if (pos >= textLen)
00086 return;
00087
00088 if ((pos + delLen) > textLen)
00089 delLen = textLen - pos;
00090
00091
00092 for (uint z = pos; z < textLen - delLen; z++)
00093 m_attributes[z] = m_attributes[z+delLen];
00094
00095 m_text.remove (pos, delLen);
00096 m_attributes.resize (m_text.length ());
00097 }
00098
00099 void KateTextLine::truncate(uint newLen)
00100 {
00101 if (newLen < m_text.length())
00102 {
00103 m_text.truncate (newLen);
00104 m_attributes.truncate (newLen);
00105 }
00106 }
00107
00108 int KateTextLine::nextNonSpaceChar(uint pos) const
00109 {
00110 for(int i = pos; i < (int)m_text.length(); i++)
00111 {
00112 if(!m_text[i].isSpace())
00113 return i;
00114 }
00115
00116 return -1;
00117 }
00118
00119 int KateTextLine::previousNonSpaceChar(uint pos) const
00120 {
00121 if (pos >= m_text.length())
00122 pos = m_text.length() - 1;
00123
00124 for(int i = pos; i >= 0; i--)
00125 {
00126 if(!m_text[i].isSpace())
00127 return i;
00128 }
00129
00130 return -1;
00131 }
00132
00133 int KateTextLine::firstChar() const
00134 {
00135 return nextNonSpaceChar(0);
00136 }
00137
00138 int KateTextLine::lastChar() const
00139 {
00140 return previousNonSpaceChar(m_text.length() - 1);
00141 }
00142
00143 const QChar *KateTextLine::firstNonSpace() const
00144 {
00145 int first = firstChar();
00146 return (first > -1) ? ((QChar*)m_text.unicode())+first : m_text.unicode();
00147 }
00148
00149 uint KateTextLine::indentDepth (uint tabwidth) const
00150 {
00151 uint d = 0;
00152
00153 for(uint i = 0; i < m_text.length(); i++)
00154 {
00155 if(m_text[i].isSpace())
00156 {
00157 if (m_text[i] == QChar('\t'))
00158 d += tabwidth - (d % tabwidth);
00159 else
00160 d++;
00161 }
00162 else
00163 return d;
00164 }
00165
00166 return d;
00167 }
00168
00169 bool KateTextLine::stringAtPos(uint pos, const QString& match) const
00170 {
00171 return (m_text.mid(pos, match.length()) == match);
00172 }
00173
00174 bool KateTextLine::startingWith(const QString& match) const
00175 {
00176 return (m_text.left(match.length()) == match);
00177 }
00178
00179 bool KateTextLine::endingWith(const QString& match) const
00180 {
00181 return (m_text.right(match.length()) == match);
00182 }
00183
00184 int KateTextLine::cursorX(uint pos, uint tabChars) const
00185 {
00186 uint x = 0;
00187
00188 for ( uint z = 0; z < kMin (pos, m_text.length()); z++)
00189 {
00190 if (m_text[z] == QChar('\t'))
00191 x += tabChars - (x % tabChars);
00192 else
00193 x++;
00194 }
00195
00196 return x;
00197 }
00198
00199 uint KateTextLine::lengthWithTabs (uint tabChars) const
00200 {
00201 uint x = 0;
00202
00203 for ( uint z = 0; z < m_text.length(); z++)
00204 {
00205 if (m_text[z] == QChar('\t'))
00206 x += tabChars - (x % tabChars);
00207 else
00208 x++;
00209 }
00210
00211 return x;
00212 }
00213
00214 void KateTextLine::setAttribs(uchar attribute, uint start, uint end)
00215 {
00216 if (end > m_attributes.size())
00217 end = m_attributes.size();
00218
00219 for (uint z = start; z < end; z++)
00220 m_attributes[z] = attribute;
00221 }
00222
00223 bool KateTextLine::searchText (uint startCol, const QString &text, uint *foundAtCol, uint *matchLen, bool casesensitive, bool backwards)
00224 {
00225 int index;
00226
00227 if (backwards)
00228 index = m_text.findRev (text, startCol, casesensitive);
00229 else
00230 index = m_text.find (text, startCol, casesensitive);
00231
00232 if (index > -1)
00233 {
00234 (*foundAtCol) = index;
00235 (*matchLen)=text.length();
00236 return true;
00237 }
00238
00239 return false;
00240 }
00241
00242 bool KateTextLine::searchText (uint startCol, const QRegExp ®exp, uint *foundAtCol, uint *matchLen, bool backwards)
00243 {
00244 int index;
00245
00246 if (backwards)
00247 index = regexp.searchRev (m_text, startCol);
00248 else
00249 index = regexp.search (m_text, startCol);
00250
00251 if (index > -1)
00252 {
00253 (*foundAtCol) = index;
00254 (*matchLen)=regexp.matchedLength();
00255 return true;
00256 }
00257
00258 return false;
00259 }
00260
00261 char *KateTextLine::dump (char *buf, bool withHighlighting) const
00262 {
00263 uint l = m_text.length();
00264 char f = m_flags;
00265
00266 if (!withHighlighting)
00267 f = f | KateTextLine::flagNoOtherData;
00268
00269 memcpy(buf, (char *) &f, 1);
00270 buf += 1;
00271
00272 memcpy(buf, &l, sizeof(uint));
00273 buf += sizeof(uint);
00274
00275 memcpy(buf, (char *) m_text.unicode(), sizeof(QChar)*l);
00276 buf += sizeof(QChar) * l;
00277
00278 if (!withHighlighting)
00279 return buf;
00280
00281 memcpy(buf, (char *)m_attributes.data(), sizeof(uchar) * l);
00282 buf += sizeof (uchar) * l;
00283
00284 uint lctx = m_ctx.size();
00285 uint lfold = m_foldingList.size();
00286 uint lind = m_indentationDepth.size();
00287
00288 memcpy(buf, &lctx, sizeof(uint));
00289 buf += sizeof(uint);
00290
00291 memcpy(buf, &lfold, sizeof(uint));
00292 buf += sizeof(uint);
00293
00294 memcpy(buf, &lind, sizeof(uint));
00295 buf += sizeof(uint);
00296
00297 memcpy(buf, (char *)m_ctx.data(), sizeof(short) * lctx);
00298 buf += sizeof (short) * lctx;
00299
00300 memcpy(buf, (char *)m_foldingList.data(), lfold);
00301 buf += sizeof (signed char) * lfold;
00302
00303 memcpy(buf, (char *)m_indentationDepth.data(), sizeof(unsigned short) * lind);
00304 buf += sizeof (unsigned short) * lind;
00305
00306 return buf;
00307 }
00308
00309 char *KateTextLine::restore (char *buf)
00310 {
00311 uint l = 0;
00312 char f = 0;
00313
00314 memcpy((char *) &f, buf, 1);
00315 buf += 1;
00316
00317
00318 memcpy((char *) &l, buf, sizeof(uint));
00319 buf += sizeof(uint);
00320
00321
00322 m_text.setUnicode ((QChar *) buf, l);
00323 buf += sizeof(QChar) * l;
00324
00325
00326 if (f & KateTextLine::flagNoOtherData)
00327 {
00328 m_flags = KateTextLine::flagVisible;
00329
00330 if (f & KateTextLine::flagAutoWrapped)
00331 m_flags = m_flags | KateTextLine::flagAutoWrapped;
00332
00333
00334 m_attributes.fill (0, l);
00335
00336 return buf;
00337 }
00338 else
00339 m_flags = f;
00340
00341 m_attributes.duplicate ((uchar *) buf, l);
00342 buf += sizeof(uchar) * l;
00343
00344 uint lctx = 0;
00345 uint lfold = 0;
00346 uint lind = 0;
00347
00348 memcpy((char *) &lctx, buf, sizeof(uint));
00349 buf += sizeof(uint);
00350
00351 memcpy((char *) &lfold, buf, sizeof(uint));
00352 buf += sizeof(uint);
00353
00354 memcpy((char *) &lind, buf, sizeof(uint));
00355 buf += sizeof(uint);
00356
00357 m_ctx.duplicate ((short *) buf, lctx);
00358 buf += sizeof(short) * lctx;
00359
00360 m_foldingList.duplicate ((signed char *) buf, lfold);
00361 buf += lfold;
00362
00363 m_indentationDepth.duplicate ((unsigned short *) buf, lind);
00364 buf += sizeof(unsigned short) * lind;
00365
00366 return buf;
00367 }
00368
00369