• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Kate

katetextline.cpp

Go to the documentation of this file.
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      KateTextLine : 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., 51 Franklin Street, Fifth Floor,
00020    Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "katetextline.h"
00024 #include "katerenderer.h"
00025 
00026 #include <kglobal.h>
00027 
00028 #include <qregexp.h>
00029 
00030 KateTextLine::KateTextLine ()
00031   : m_flags(0)
00032 {
00033 }
00034 
00035 KateTextLine::~KateTextLine()
00036 {
00037 }
00038 
00039 void KateTextLine::insertText (uint pos, uint insLen, const QChar *insText, uchar *insAttribs)
00040 {
00041   // nothing to do
00042   if (insLen == 0)
00043     return;
00044 
00045   // calc new textLen, store old
00046   uint oldTextLen = m_text.length();
00047   m_text.insert (pos, insText, insLen);
00048   uint textLen = m_text.length();
00049 
00050   // resize the array
00051   m_attributes.resize (textLen);
00052 
00053   // HA, insert behind text end, fill with spaces
00054   if (pos >= oldTextLen)
00055   {
00056     for (uint z = oldTextLen; z < pos; z++)
00057       m_attributes[z] = 0;
00058   }
00059   // HA, insert in text, move the old text behind pos
00060   else if (oldTextLen > 0)
00061   {
00062     for (int z = oldTextLen -1; z >= (int) pos; z--)
00063       m_attributes[z+insLen] = m_attributes[z];
00064   }
00065 
00066   // BUH, actually insert the new text
00067   for (uint z = 0; z < insLen; z++)
00068   {
00069     if (insAttribs == 0)
00070       m_attributes[z+pos] = 0;
00071     else
00072       m_attributes[z+pos] = insAttribs[z];
00073   }
00074 }
00075 
00076 void KateTextLine::removeText (uint pos, uint delLen)
00077 {
00078   // nothing to do
00079   if (delLen == 0)
00080     return;
00081 
00082   uint textLen = m_text.length();
00083 
00084   if (textLen == 0)
00085     return; // uh, again nothing real to do ;)
00086 
00087   if (pos >= textLen)
00088     return;
00089 
00090   if ((pos + delLen) > textLen)
00091     delLen = textLen - pos;
00092 
00093   // BU, MOVE THE OLD TEXT AROUND
00094   for (uint z = pos; z < textLen - delLen; z++)
00095     m_attributes[z] = m_attributes[z+delLen];
00096 
00097   m_text.remove (pos, delLen);
00098   m_attributes.resize (m_text.length ());
00099 }
00100 
00101 void KateTextLine::truncate(uint newLen)
00102 {
00103   if (newLen < m_text.length())
00104   {
00105     m_text.truncate (newLen);
00106     m_attributes.truncate (newLen);
00107   }
00108 }
00109 
00110 int KateTextLine::nextNonSpaceChar(uint pos) const
00111 {
00112   const uint len = m_text.length();
00113   const QChar *unicode = m_text.unicode();
00114 
00115   for(uint i = pos; i < len; i++)
00116   {
00117     if(!unicode[i].isSpace())
00118       return i;
00119   }
00120 
00121   return -1;
00122 }
00123 
00124 int KateTextLine::previousNonSpaceChar(uint pos) const
00125 {
00126   const int len = m_text.length();
00127 
00128   if (pos >= (uint)len)
00129     pos = len - 1;
00130 
00131   const QChar *unicode = m_text.unicode();
00132 
00133   for(int i = pos; i >= 0; i--)
00134   {
00135     if(!unicode[i].isSpace())
00136       return i;
00137   }
00138 
00139   return -1;
00140 }
00141 
00142 int KateTextLine::firstChar() const
00143 {
00144   return nextNonSpaceChar(0);
00145 }
00146 
00147 int KateTextLine::lastChar() const
00148 {
00149   return previousNonSpaceChar(m_text.length() - 1);
00150 }
00151 
00152 const QChar *KateTextLine::firstNonSpace() const
00153 {
00154   int first = firstChar();
00155   return (first > -1) ? ((QChar*)m_text.unicode())+first : m_text.unicode();
00156 }
00157 
00158 uint KateTextLine::indentDepth (uint tabwidth) const
00159 {
00160   uint d = 0;
00161   const uint len = m_text.length();
00162   const QChar *unicode = m_text.unicode();
00163 
00164   for(uint i = 0; i < len; i++)
00165   {
00166     if(unicode[i].isSpace())
00167     {
00168       if (unicode[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 KateTextLine::stringAtPos(uint pos, const QString& match) const
00181 {
00182   const uint len = m_text.length();
00183   const uint matchlen = match.length();
00184 
00185   if ((pos+matchlen) > len)
00186     return false;
00187 
00188   // (pos > len) in case the uint pos was assigned a signed -1, pos+matchlen can
00189   // overflow again which (pos+matchlen > len) does not catch; see bugs #129263 and #129580
00190   Q_ASSERT(pos < len);
00191 
00192   const QChar *unicode = m_text.unicode();
00193   const QChar *matchUnicode = match.unicode();
00194 
00195   for (uint i=0; i < matchlen; i++)
00196     if (unicode[i+pos] != matchUnicode[i])
00197       return false;
00198 
00199   return true;
00200 }
00201 
00202 bool KateTextLine::startingWith(const QString& match) const
00203 {
00204   const uint matchlen = match.length();
00205 
00206   if (matchlen > m_text.length())
00207     return false;
00208 
00209   const QChar *unicode = m_text.unicode();
00210   const QChar *matchUnicode = match.unicode();
00211 
00212   for (uint i=0; i < matchlen; i++)
00213     if (unicode[i] != matchUnicode[i])
00214       return false;
00215 
00216   return true;
00217 }
00218 
00219 bool KateTextLine::endingWith(const QString& match) const
00220 {
00221   const uint matchlen = match.length();
00222 
00223   if (matchlen > m_text.length())
00224     return false;
00225 
00226   const QChar *unicode = m_text.unicode();
00227   const QChar *matchUnicode = match.unicode();
00228 
00229   uint start = m_text.length() - matchlen;
00230   for (uint i=0; i < matchlen; i++)
00231     if (unicode[start+i] != matchUnicode[i])
00232       return false;
00233 
00234   return true;
00235 }
00236 
00237 int KateTextLine::cursorX(uint pos, uint tabChars) const
00238 {
00239   uint x = 0;
00240 
00241   const uint n = kMin (pos, m_text.length());
00242   const QChar *unicode = m_text.unicode();
00243 
00244   for ( uint z = 0; z < n; z++)
00245   {
00246     if (unicode[z] == QChar('\t'))
00247       x += tabChars - (x % tabChars);
00248     else
00249       x++;
00250   }
00251 
00252   return x;
00253 }
00254 
00255 
00256 uint KateTextLine::lengthWithTabs (uint tabChars) const
00257 {
00258   uint x = 0;
00259   const uint len = m_text.length();
00260   const QChar *unicode = m_text.unicode();
00261 
00262   for ( uint z = 0; z < len; z++)
00263   {
00264     if (unicode[z] == QChar('\t'))
00265       x += tabChars - (x % tabChars);
00266     else
00267       x++;
00268   }
00269 
00270   return x;
00271 }
00272 
00273 bool KateTextLine::searchText (uint startCol, const QString &text, uint *foundAtCol, uint *matchLen, bool casesensitive, bool backwards)
00274 {
00275   int index;
00276 
00277   if (backwards)
00278   {
00279     int col = startCol;
00280     uint l = text.length();
00281     // allow finding the string ending at eol
00282     if ( col == (int) m_text.length() ) ++startCol;
00283 
00284     do {
00285       index = m_text.findRev( text, col, casesensitive );
00286       col--;
00287     } while ( col >= 0 && l + index >= startCol );
00288   }
00289   else
00290     index = m_text.find (text, startCol, casesensitive);
00291 
00292   if (index > -1)
00293   {
00294     if (foundAtCol)
00295       (*foundAtCol) = index;
00296     if (matchLen)
00297       (*matchLen)=text.length();
00298     return true;
00299   }
00300 
00301   return false;
00302 }
00303 
00304 bool KateTextLine::searchText (uint startCol, const QRegExp &regexp, uint *foundAtCol, uint *matchLen, bool backwards)
00305 {
00306   int index;
00307 
00308   if (backwards)
00309   {
00310     int col = startCol;
00311 
00312     // allow finding the string ending at eol
00313     if ( col == (int) m_text.length() ) ++startCol;
00314     do {
00315       index = regexp.searchRev (m_text, col);
00316       col--;
00317     } while ( col >= 0 && regexp.matchedLength() + index >= (int)startCol );
00318   }
00319   else
00320     index = regexp.search (m_text, startCol);
00321 
00322   if (index > -1)
00323   {
00324     if (foundAtCol)
00325       (*foundAtCol) = index;
00326 
00327     if (matchLen)
00328       (*matchLen)=regexp.matchedLength();
00329     return true;
00330   }
00331 
00332   return false;
00333 }
00334 
00335 char *KateTextLine::dump (char *buf, bool withHighlighting) const
00336 {
00337   uint l = m_text.length();
00338   char f = m_flags;
00339 
00340   if (!withHighlighting)
00341     f = f | KateTextLine::flagNoOtherData;
00342 
00343   memcpy(buf, (char *) &f, 1);
00344   buf += 1;
00345 
00346   memcpy(buf, &l, sizeof(uint));
00347   buf += sizeof(uint);
00348 
00349   memcpy(buf, (char *) m_text.unicode(), sizeof(QChar)*l);
00350   buf += sizeof(QChar) * l;
00351 
00352   if (!withHighlighting)
00353     return buf;
00354 
00355   memcpy(buf, (char *)m_attributes.data(), sizeof(uchar) * l);
00356   buf += sizeof (uchar) * l;
00357 
00358   uint lctx = m_ctx.size();
00359   uint lfold = m_foldingList.size();
00360   uint lind = m_indentationDepth.size();
00361 
00362   memcpy(buf, &lctx, sizeof(uint));
00363   buf += sizeof(uint);
00364 
00365   memcpy(buf, &lfold, sizeof(uint));
00366   buf += sizeof(uint);
00367 
00368   memcpy(buf, &lind, sizeof(uint));
00369   buf += sizeof(uint);
00370 
00371   memcpy(buf, (char *)m_ctx.data(), sizeof(short) * lctx);
00372   buf += sizeof (short) * lctx;
00373 
00374   memcpy(buf, (char *)m_foldingList.data(), sizeof(uint)*lfold);
00375   buf += sizeof (uint) * lfold;
00376 
00377   memcpy(buf, (char *)m_indentationDepth.data(), sizeof(unsigned short) * lind);
00378   buf += sizeof (unsigned short) * lind;
00379 
00380   return buf;
00381 }
00382 
00383 char *KateTextLine::restore (char *buf)
00384 {
00385   uint l = 0;
00386   char f = 0;
00387 
00388   memcpy((char *) &f, buf, 1);
00389   buf += 1;
00390 
00391   // text + context length read
00392   memcpy((char *) &l, buf, sizeof(uint));
00393   buf += sizeof(uint);
00394 
00395   // text + attributes
00396   m_text.setUnicode ((QChar *) buf, l);
00397   buf += sizeof(QChar) * l;
00398 
00399   // we just restore a KateTextLine from a buffer first time
00400   if (f & KateTextLine::flagNoOtherData)
00401   {
00402     m_flags = 0;
00403 
00404     if (f & KateTextLine::flagAutoWrapped)
00405       m_flags = m_flags | KateTextLine::flagAutoWrapped;
00406 
00407     // fill with clean empty attribs !
00408     m_attributes.fill (0, l);
00409 
00410     return buf;
00411   }
00412   else
00413     m_flags = f;
00414 
00415   m_attributes.duplicate ((uchar *) buf, l);
00416   buf += sizeof(uchar) * l;
00417 
00418   uint lctx = 0;
00419   uint lfold = 0;
00420   uint lind = 0;
00421 
00422   memcpy((char *) &lctx, buf, sizeof(uint));
00423   buf += sizeof(uint);
00424 
00425   memcpy((char *) &lfold, buf, sizeof(uint));
00426   buf += sizeof(uint);
00427 
00428   memcpy((char *) &lind, buf, sizeof(uint));
00429   buf += sizeof(uint);
00430 
00431   m_ctx.duplicate ((short *) buf, lctx);
00432   buf += sizeof(short) * lctx;
00433 
00434   m_foldingList.duplicate ((uint *) buf, lfold);
00435   buf += sizeof(uint)*lfold;
00436 
00437   m_indentationDepth.duplicate ((unsigned short *) buf, lind);
00438   buf += sizeof(unsigned short) * lind;
00439 
00440   return buf;
00441 }
00442 
00443 // kate: space-indent on; indent-width 2; replace-tabs on;

Kate

Skip menu "Kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal