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 {
00229 int col = startCol;
00230 uint l = text.length();
00231 do {
00232 index = m_text.findRev( text, col, casesensitive );
00233 col--;
00234 } while ( col >= 0 && l + index >= startCol );
00235 }
00236 else
00237 index = m_text.find (text, startCol, casesensitive);
00238
00239 if (index > -1)
00240 {
00241 (*foundAtCol) = index;
00242 (*matchLen)=text.length();
00243 return true;
00244 }
00245
00246 return false;
00247 }
00248
00249 bool KateTextLine::searchText (uint startCol, const QRegExp ®exp, uint *foundAtCol, uint *matchLen, bool backwards)
00250 {
00251 int index;
00252
00253 if (backwards)
00254 {
00255 int col = startCol;
00256 do {
00257 index = regexp.searchRev (m_text, col);
00258 col--;
00259 } while ( col >= 0 && regexp.matchedLength() + index >= (int)startCol );
00260 }
00261 else
00262 index = regexp.search (m_text, startCol);
00263
00264 if (index > -1)
00265 {
00266 (*foundAtCol) = index;
00267 (*matchLen)=regexp.matchedLength();
00268 return true;
00269 }
00270
00271 return false;
00272 }
00273
00274 char *KateTextLine::dump (char *buf, bool withHighlighting) const
00275 {
00276 uint l = m_text.length();
00277 char f = m_flags;
00278
00279 if (!withHighlighting)
00280 f = f | KateTextLine::flagNoOtherData;
00281
00282 memcpy(buf, (char *) &f, 1);
00283 buf += 1;
00284
00285 memcpy(buf, &l, sizeof(uint));
00286 buf += sizeof(uint);
00287
00288 memcpy(buf, (char *) m_text.unicode(), sizeof(QChar)*l);
00289 buf += sizeof(QChar) * l;
00290
00291 if (!withHighlighting)
00292 return buf;
00293
00294 memcpy(buf, (char *)m_attributes.data(), sizeof(uchar) * l);
00295 buf += sizeof (uchar) * l;
00296
00297 uint lctx = m_ctx.size();
00298 uint lfold = m_foldingList.size();
00299 uint lind = m_indentationDepth.size();
00300
00301 memcpy(buf, &lctx, sizeof(uint));
00302 buf += sizeof(uint);
00303
00304 memcpy(buf, &lfold, sizeof(uint));
00305 buf += sizeof(uint);
00306
00307 memcpy(buf, &lind, sizeof(uint));
00308 buf += sizeof(uint);
00309
00310 memcpy(buf, (char *)m_ctx.data(), sizeof(short) * lctx);
00311 buf += sizeof (short) * lctx;
00312
00313 memcpy(buf, (char *)m_foldingList.data(), lfold);
00314 buf += sizeof (signed char) * lfold;
00315
00316 memcpy(buf, (char *)m_indentationDepth.data(), sizeof(unsigned short) * lind);
00317 buf += sizeof (unsigned short) * lind;
00318
00319 return buf;
00320 }
00321
00322 char *KateTextLine::restore (char *buf)
00323 {
00324 uint l = 0;
00325 char f = 0;
00326
00327 memcpy((char *) &f, buf, 1);
00328 buf += 1;
00329
00330
00331 memcpy((char *) &l, buf, sizeof(uint));
00332 buf += sizeof(uint);
00333
00334
00335 m_text.setUnicode ((QChar *) buf, l);
00336 buf += sizeof(QChar) * l;
00337
00338
00339 if (f & KateTextLine::flagNoOtherData)
00340 {
00341 m_flags = KateTextLine::flagVisible;
00342
00343 if (f & KateTextLine::flagAutoWrapped)
00344 m_flags = m_flags | KateTextLine::flagAutoWrapped;
00345
00346
00347 m_attributes.fill (0, l);
00348
00349 return buf;
00350 }
00351 else
00352 m_flags = f;
00353
00354 m_attributes.duplicate ((uchar *) buf, l);
00355 buf += sizeof(uchar) * l;
00356
00357 uint lctx = 0;
00358 uint lfold = 0;
00359 uint lind = 0;
00360
00361 memcpy((char *) &lctx, buf, sizeof(uint));
00362 buf += sizeof(uint);
00363
00364 memcpy((char *) &lfold, buf, sizeof(uint));
00365 buf += sizeof(uint);
00366
00367 memcpy((char *) &lind, buf, sizeof(uint));
00368 buf += sizeof(uint);
00369
00370 m_ctx.duplicate ((short *) buf, lctx);
00371 buf += sizeof(short) * lctx;
00372
00373 m_foldingList.duplicate ((signed char *) buf, lfold);
00374 buf += lfold;
00375
00376 m_indentationDepth.duplicate ((unsigned short *) buf, lind);
00377 buf += sizeof(unsigned short) * lind;
00378
00379 return buf;
00380 }
00381
00382