kate Library API Documentation

katetextline.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2001-2003 Christoph Cullmann <cullmann@kde.org> 00003 Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org> 00004 00005 Based on: 00006 TextLine : Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License version 2 as published by the Free Software Foundation. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 Boston, MA 02111-1307, USA. 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 // nothing to do 00040 if (insLen == 0) 00041 return; 00042 00043 // calc new textLen, store old 00044 uint oldTextLen = m_text.length(); 00045 m_text.insert (pos, insText, insLen); 00046 uint textLen = m_text.length(); 00047 00048 // resize the array 00049 m_attributes.resize (textLen); 00050 00051 // HA, insert behind text end, fill with spaces 00052 if (pos >= oldTextLen) 00053 { 00054 for (uint z = oldTextLen; z < pos; z++) 00055 m_attributes[z] = 0; 00056 } 00057 // HA, insert in text, move the old text behind pos 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 // BUH, actually insert the new text 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 // nothing to do 00077 if (delLen == 0) 00078 return; 00079 00080 uint textLen = m_text.length(); 00081 00082 if (textLen == 0) 00083 return; // uh, again nothing real to do ;) 00084 00085 if (pos >= textLen) 00086 return; 00087 00088 if ((pos + delLen) > textLen) 00089 delLen = textLen - pos; 00090 00091 // BU, MOVE THE OLD TEXT AROUND 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 &regexp, 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 // hl size runlength encoding START 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 // hl size runlength encoding STOP 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 // text + context length read 00386 memcpy((char *) &l, buf, sizeof(uint)); 00387 buf += sizeof(uint); 00388 00389 // text + attributes 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 // we just restore a TextLine from a buffer first time 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 // hl size runlength encoding START 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 // hl size runlength encoding STOP 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 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Logo
This file is part of the documentation for kate Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 8 11:16:27 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003