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