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.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 22 14:26:27 2004 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2003