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 index = m_text.
findRev (text, startCol, casesensitive);
00225
else
00226 index = m_text.
find (text, startCol, casesensitive);
00227
00228
if (index > -1)
00229 {
00230 (*foundAtCol) = index;
00231 (*matchLen)=text.
length();
00232
return true;
00233 }
00234
00235
return false;
00236 }
00237
00238
bool TextLine::searchText (uint startCol,
const QRegExp ®exp, uint *foundAtCol, uint *matchLen,
bool backwards)
00239 {
00240
int index;
00241
00242
if (backwards)
00243 index = regexp.
searchRev (m_text, startCol);
00244
else
00245 index = regexp.
search (m_text, startCol);
00246
00247
if (index > -1)
00248 {
00249 (*foundAtCol) = index;
00250 (*matchLen)=regexp.
matchedLength();
00251
return true;
00252 }
00253
00254
return false;
00255 }
00256
00257 uint
TextLine::dumpSize ()
const
00258
{
00259 uint attributesLen = 0;
00260
00261
if ( ! m_attributes.
isEmpty())
00262 {
00263 attributesLen = 1;
00264
00265 uint lastAttrib = m_attributes[0];
00266
00267
for (uint z=0; z < m_attributes.size(); z++)
00268 {
00269
if (m_attributes[z] != lastAttrib)
00270 {
00271 attributesLen++;
00272 lastAttrib = m_attributes[z];
00273 }
00274 }
00275 }
00276
00277
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)));
00278 }
00279
00280 char *
TextLine::dump (
char *buf)
const
00281
{
00282 uint l = m_text.
length();
00283 uint lctx = m_ctx.
size();
00284 uint lfold = m_foldingList.
size();
00285 uint lind = m_indentationDepth.
size();
00286
00287 memcpy(buf, &l,
sizeof(uint));
00288 buf +=
sizeof(uint);
00289
00290 memcpy(buf, (
char *) m_text.
unicode(),
sizeof(
QChar)*l);
00291 buf +=
sizeof(
QChar)*l;
00292
00293 memcpy(buf, (
char *) &m_flags, 1);
00294 buf += 1;
00295
00296
char *attribLenPos = buf;
00297 buf +=
sizeof(uint);
00298
00299 memcpy(buf, &lctx,
sizeof(uint));
00300 buf +=
sizeof(uint);
00301
00302 memcpy(buf, &lfold,
sizeof(uint));
00303 buf +=
sizeof(uint);
00304
00305 memcpy(buf, &lind,
sizeof(uint));
00306 buf +=
sizeof(uint);
00307
00308
00309
00310 uint attributesLen = 0;
00311
00312
if ( ! m_attributes.
isEmpty() )
00313 {
00314 attributesLen = 1;
00315
00316 uchar lastAttrib = m_attributes[0];
00317 uint lastStart = 0;
00318 uint
length = 0;
00319
00320
for (uint z=0; z < m_attributes.size(); z++)
00321 {
00322
if (m_attributes[z] != lastAttrib)
00323 {
00324 length = z - lastStart;
00325
00326 memcpy(buf, &lastAttrib,
sizeof(uchar));
00327 buf +=
sizeof(uchar);
00328
00329 memcpy(buf, &length,
sizeof(uint));
00330 buf +=
sizeof(uint);
00331
00332 lastStart = z;
00333 lastAttrib = m_attributes[z];
00334
00335 attributesLen ++;
00336 }
00337 }
00338
00339 length = m_attributes.size() - lastStart;
00340
00341 memcpy(buf, &lastAttrib,
sizeof(uchar));
00342 buf +=
sizeof(uchar);
00343
00344 memcpy(buf, &length,
sizeof(uint));
00345 buf +=
sizeof(uint);
00346 }
00347
00348 memcpy(attribLenPos, &attributesLen,
sizeof(uint));
00349
00350
00351
00352 memcpy(buf, (
char *)m_ctx.
data(),
sizeof(
short) * lctx);
00353 buf +=
sizeof (
short) * lctx;
00354
00355 memcpy(buf, (
char *)m_foldingList.
data(), lfold);
00356 buf +=
sizeof (
signed char) * lfold;
00357
00358 memcpy(buf, (
char *)m_indentationDepth.
data(),
sizeof(
unsigned short) * lind);
00359 buf +=
sizeof (
unsigned short) * lind;
00360
00361
return buf;
00362 }
00363
00364 char *
TextLine::restore (
char *buf)
00365 {
00366 uint l = 0;
00367 uint lattrib = 0;
00368 uint lctx = 0;
00369 uint lfold = 0;
00370 uint lind = 0;
00371
00372
00373 memcpy((
char *) &l, buf,
sizeof(uint));
00374 buf +=
sizeof(uint);
00375
00376
00377 m_text.
setUnicode ((
QChar *) buf, l);
00378 buf +=
sizeof(
QChar)*l;
00379
00380 m_attributes.
resize (l);
00381
00382 memcpy((
char *) &m_flags, buf, 1);
00383 buf += 1;
00384
00385
00386
if (m_flags == TextLine::flagNoOtherData)
00387 {
00388 m_flags = TextLine::flagVisible;
00389 m_attributes.
fill (0);
00390
00391
return buf;
00392 }
00393
00394 memcpy((
char *) &lattrib, buf,
sizeof(uint));
00395 buf +=
sizeof(uint);
00396
00397 memcpy((
char *) &lctx, buf,
sizeof(uint));
00398 buf +=
sizeof(uint);
00399
00400 memcpy((
char *) &lfold, buf,
sizeof(uint));
00401 buf +=
sizeof(uint);
00402
00403 memcpy((
char *) &lind, buf,
sizeof(uint));
00404 buf +=
sizeof(uint);
00405
00406
00407
00408 uchar *attr = m_attributes.
data();
00409
00410 uchar attrib = 0;
00411 uint
length = 0;
00412 uint pos = 0;
00413
00414
for (uint z=0; z < lattrib; z++)
00415 {
00416
if (pos >= m_attributes.
size())
00417
break;
00418
00419 memcpy((
char *) &attrib, buf,
sizeof(uchar));
00420 buf +=
sizeof(uchar);
00421
00422 memcpy((
char *) &length, buf,
sizeof(uint));
00423 buf +=
sizeof(uint);
00424
00425
if ((pos+length) > m_attributes.
size())
00426 length = m_attributes.
size() - pos;
00427
00428 memset (attr, attrib, length);
00429
00430 pos += length;
00431 attr += length;
00432 }
00433
00434
00435
00436 m_ctx.
duplicate ((
short *) buf, lctx);
00437 buf +=
sizeof(
short) * lctx;
00438
00439 m_foldingList.
duplicate ((
signed char *) buf, lfold);
00440 buf += lfold;
00441
00442 m_indentationDepth.
duplicate ((
unsigned short *) buf, lind);
00443 buf +=
sizeof(
unsigned short) * lind;
00444
00445
return buf;
00446 }
00447
00448