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 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 &regexp, 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 // hl size runlength encoding START 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 // hl size runlength encoding STOP 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 // text + context length read 00373 memcpy((char *) &l, buf, sizeof(uint)); 00374 buf += sizeof(uint); 00375 00376 // text + attributes 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 // we just restore a TextLine from a buffer first time 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 // hl size runlength encoding START 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 // hl size runlength encoding STOP 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 // 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 Wed Mar 16 17:24:02 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003