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 TextLine::TextLine ()
00029 : m_flags(
TextLine::flagVisible)
00030 {
00031 }
00032
00033 TextLine::~TextLine()
00034 {
00035 }
00036
00037 void TextLine::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 TextLine::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 textLen = m_text.length ();
00097 m_attributes.resize (textLen);
00098 }
00099
00100 void TextLine::append(
const QChar *s, uint l)
00101 {
00102
insertText (m_text.length(), l, s, 0);
00103 }
00104
00105 void TextLine::truncate(uint newLen)
00106 {
00107
if (newLen < m_text.length())
00108 {
00109 m_text.truncate (newLen);
00110 m_attributes.truncate (newLen);
00111 }
00112 }
00113
00114 int TextLine::nextNonSpaceChar(uint pos)
const
00115
{
00116
for(
int i = pos; i < (
int)m_text.length(); i++)
00117 {
00118
if(!m_text[i].isSpace())
00119
return i;
00120 }
00121
00122
return -1;
00123 }
00124
00125 int TextLine::previousNonSpaceChar(uint pos)
const
00126
{
00127
if (pos >= m_text.length())
00128 pos = m_text.length() - 1;
00129
00130
for(
int i = pos; i >= 0; i--)
00131 {
00132
if(!m_text[i].isSpace())
00133
return i;
00134 }
00135
00136
return -1;
00137 }
00138
00139 int TextLine::firstChar()
const
00140
{
00141
return nextNonSpaceChar(0);
00142 }
00143
00144 int TextLine::lastChar()
const
00145
{
00146
return previousNonSpaceChar(m_text.length() - 1);
00147 }
00148
00149 QString TextLine::withoutTrailingSpaces()
00150 {
00151
return m_text.left (
lastChar() + 1);
00152 }
00153
00154
const QChar *TextLine::firstNonSpace()
const
00155
{
00156
int first =
firstChar();
00157
return (first > -1) ? ((
QChar*)m_text.unicode())+first : m_text.unicode();
00158 }
00159
00160 uint TextLine::indentDepth (uint tabwidth)
const
00161
{
00162 uint d = 0;
00163
00164
for(uint i = 0; i < m_text.length(); i++)
00165 {
00166
if(m_text[i].isSpace())
00167 {
00168
if (m_text[i] ==
QChar(
'\t'))
00169 d += tabwidth - (d % tabwidth);
00170
else
00171 d++;
00172 }
00173
else
00174
return d;
00175 }
00176
00177
return d;
00178 }
00179
00180 bool TextLine::stringAtPos(uint pos,
const QString& match)
const
00181
{
00182
return (m_text.mid(pos, match.length()) == match);
00183 }
00184
00185 bool TextLine::startingWith(
const QString& match)
const
00186
{
00187
return (m_text.left(match.length()) == match);
00188 }
00189
00190 bool TextLine::endingWith(
const QString& match)
const
00191
{
00192
return (m_text.right(match.length()) == match);
00193 }
00194
00195 int TextLine::cursorX(uint pos, uint tabChars)
const
00196
{
00197 uint x = 0;
00198
00199
for (uint z = 0; z < kMin (pos, m_text.length()); z++)
00200 {
00201
if (m_text[z] ==
QChar(
'\t'))
00202 x += tabChars - (x % tabChars);
00203
else
00204 x++;
00205 }
00206
00207
return x;
00208 }
00209
00210 void TextLine::setAttribs(uchar attribute, uint start, uint end)
00211 {
00212
if (end > m_text.length())
00213 end = m_text.length();
00214
00215
for (uint z = start; z < end; z++)
00216 m_attributes[z] = attribute;
00217 }
00218
00219
bool TextLine::searchText (uint startCol,
const QString &text, uint *foundAtCol, uint *matchLen,
bool casesensitive,
bool backwards)
00220 {
00221
int index;
00222
00223
if (backwards)
00224 {
00225 uint col = startCol;
00226 uint l = text.length();
00227
do {
00228 index = m_text.findRev( text, col, casesensitive );
00229 col--;
00230 }
while ( col >= 0 && l + index >= startCol );
00231 }
00232
else
00233 index = m_text.find (text, startCol, casesensitive);
00234
00235
if (index > -1)
00236 {
00237 (*foundAtCol) = index;
00238 (*matchLen)=text.length();
00239
return true;
00240 }
00241
00242
return false;
00243 }
00244
00245
bool TextLine::searchText (uint startCol,
const QRegExp ®exp, uint *foundAtCol, uint *matchLen,
bool backwards)
00246 {
00247
int index;
00248
00249
if (backwards)
00250 {
00251 uint col = startCol;
00252
do {
00253 index = regexp.searchRev (m_text, col);
00254 col--;
00255 }
while ( col >= 0 && regexp.matchedLength() + index >= startCol );
00256 }
00257
else
00258 index = regexp.search (m_text, startCol);
00259
00260
if (index > -1)
00261 {
00262 (*foundAtCol) = index;
00263 (*matchLen)=regexp.matchedLength();
00264
return true;
00265 }
00266
00267
return false;
00268 }
00269
00270 uint
TextLine::dumpSize ()
const
00271
{
00272 uint attributesLen = 0;
00273
00274
if ( ! m_attributes.isEmpty())
00275 {
00276 attributesLen = 1;
00277
00278 uint lastAttrib = m_attributes[0];
00279
00280
for (uint z=0; z < m_attributes.size(); z++)
00281 {
00282
if (m_attributes[z] != lastAttrib)
00283 {
00284 attributesLen++;
00285 lastAttrib = m_attributes[z];
00286 }
00287 }
00288 }
00289
00290
return (1 + 5*
sizeof(uint)) + (m_text.length()*
sizeof(
QChar)) + (attributesLen * (
sizeof(uchar) +
sizeof(uint))) + (m_ctx.size() *
sizeof(
short)) + (m_foldingList.size() *
sizeof(
signed char) + (m_indentationDepth.size() *
sizeof(
unsigned short)));
00291 }
00292
00293 char *
TextLine::dump (
char *buf)
const
00294
{
00295 uint l = m_text.length();
00296 uint lctx = m_ctx.size();
00297 uint lfold = m_foldingList.size();
00298 uint lind = m_indentationDepth.size();
00299
00300 memcpy(buf, &l,
sizeof(uint));
00301 buf +=
sizeof(uint);
00302
00303 memcpy(buf, (
char *) m_text.unicode(),
sizeof(
QChar)*l);
00304 buf +=
sizeof(
QChar)*l;
00305
00306 memcpy(buf, (
char *) &m_flags, 1);
00307 buf += 1;
00308
00309
char *attribLenPos = buf;
00310 buf +=
sizeof(uint);
00311
00312 memcpy(buf, &lctx,
sizeof(uint));
00313 buf +=
sizeof(uint);
00314
00315 memcpy(buf, &lfold,
sizeof(uint));
00316 buf +=
sizeof(uint);
00317
00318 memcpy(buf, &lind,
sizeof(uint));
00319 buf +=
sizeof(uint);
00320
00321
00322
00323 uint attributesLen = 0;
00324
00325
if ( ! m_attributes.isEmpty() )
00326 {
00327 attributesLen = 1;
00328
00329 uchar lastAttrib = m_attributes[0];
00330 uint lastStart = 0;
00331 uint
length = 0;
00332
00333
for (uint z=0; z < m_attributes.size(); z++)
00334 {
00335
if (m_attributes[z] != lastAttrib)
00336 {
00337 length = z - lastStart;
00338
00339 memcpy(buf, &lastAttrib,
sizeof(uchar));
00340 buf +=
sizeof(uchar);
00341
00342 memcpy(buf, &length,
sizeof(uint));
00343 buf +=
sizeof(uint);
00344
00345 lastStart = z;
00346 lastAttrib = m_attributes[z];
00347
00348 attributesLen ++;
00349 }
00350 }
00351
00352 length = m_attributes.size() - lastStart;
00353
00354 memcpy(buf, &lastAttrib,
sizeof(uchar));
00355 buf +=
sizeof(uchar);
00356
00357 memcpy(buf, &length,
sizeof(uint));
00358 buf +=
sizeof(uint);
00359 }
00360
00361 memcpy(attribLenPos, &attributesLen,
sizeof(uint));
00362
00363
00364
00365 memcpy(buf, (
char *)m_ctx.data(),
sizeof(
short) * lctx);
00366 buf +=
sizeof (
short) * lctx;
00367
00368 memcpy(buf, (
char *)m_foldingList.data(), lfold);
00369 buf +=
sizeof (
signed char) * lfold;
00370
00371 memcpy(buf, (
char *)m_indentationDepth.data(),
sizeof(
unsigned short) * lind);
00372 buf +=
sizeof (
unsigned short) * lind;
00373
00374
return buf;
00375 }
00376
00377 char *
TextLine::restore (
char *buf)
00378 {
00379 uint l = 0;
00380 uint lattrib = 0;
00381 uint lctx = 0;
00382 uint lfold = 0;
00383 uint lind = 0;
00384
00385
00386 memcpy((
char *) &l, buf,
sizeof(uint));
00387 buf +=
sizeof(uint);
00388
00389
00390 m_text.setUnicode ((
QChar *) buf, l);
00391 buf +=
sizeof(
QChar)*l;
00392
00393 m_attributes.resize (l);
00394
00395 memcpy((
char *) &m_flags, buf, 1);
00396 buf += 1;
00397
00398
00399
if (m_flags == TextLine::flagNoOtherData)
00400 {
00401 m_flags = TextLine::flagVisible;
00402 m_attributes.fill (0);
00403
00404
return buf;
00405 }
00406
00407 memcpy((
char *) &lattrib, buf,
sizeof(uint));
00408 buf +=
sizeof(uint);
00409
00410 memcpy((
char *) &lctx, buf,
sizeof(uint));
00411 buf +=
sizeof(uint);
00412
00413 memcpy((
char *) &lfold, buf,
sizeof(uint));
00414 buf +=
sizeof(uint);
00415
00416 memcpy((
char *) &lind, buf,
sizeof(uint));
00417 buf +=
sizeof(uint);
00418
00419
00420
00421 uchar *attr = m_attributes.data();
00422
00423 uchar attrib = 0;
00424 uint
length = 0;
00425 uint pos = 0;
00426
00427
for (uint z=0; z < lattrib; z++)
00428 {
00429
if (pos >= m_attributes.size())
00430
break;
00431
00432 memcpy((
char *) &attrib, buf,
sizeof(uchar));
00433 buf +=
sizeof(uchar);
00434
00435 memcpy((
char *) &length, buf,
sizeof(uint));
00436 buf +=
sizeof(uint);
00437
00438
if ((pos+length) > m_attributes.size())
00439 length = m_attributes.size() - pos;
00440
00441 memset (attr, attrib, length);
00442
00443 pos += length;
00444 attr += length;
00445 }
00446
00447
00448
00449 m_ctx.duplicate ((
short *) buf, lctx);
00450 buf +=
sizeof(
short) * lctx;
00451
00452 m_foldingList.duplicate ((
signed char *) buf, lfold);
00453 buf += lfold;
00454
00455 m_indentationDepth.duplicate ((
unsigned short *) buf, lind);
00456 buf +=
sizeof(
unsigned short) * lind;
00457
00458
return buf;
00459 }
00460
00461