Kate
katetextline.cpp
Go to the documentation of this file.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 #include "katerenderer.h"
00025
00026 #include <kglobal.h>
00027 #include <kdebug.h>
00028
00029 #include <QtCore/QRegExp>
00030
00031 KateTextLine::KateTextLine ()
00032 : m_flags(0)
00033 {
00034 }
00035
00036 KateTextLine::KateTextLine (const QChar *data, int length)
00037 : m_text (data, length), m_flags(0)
00038 {
00039 }
00040
00041 KateTextLine::~KateTextLine()
00042 {
00043 }
00044
00045 void KateTextLine::insertText (int pos, const QString& insText)
00046 {
00047
00048 if (insText.length() == 0)
00049 return;
00050
00051 m_text.insert (pos, insText);
00052 }
00053
00054 void KateTextLine::removeText (uint pos, uint delLen)
00055 {
00056
00057 if (delLen == 0)
00058 return;
00059
00060 uint textLen = m_text.length();
00061
00062 if (textLen == 0)
00063 return;
00064
00065 if (pos >= textLen)
00066 return;
00067
00068 if ((pos + delLen) > textLen)
00069 delLen = textLen - pos;
00070
00071 m_text.remove (pos, delLen);
00072 }
00073
00074 void KateTextLine::truncate(int newLen)
00075 {
00076 if (newLen < 0)
00077 newLen = 0;
00078
00079 if (newLen < m_text.length())
00080 m_text.truncate (newLen);
00081 }
00082
00083 int KateTextLine::nextNonSpaceChar(uint pos) const
00084 {
00085 const int len = m_text.length();
00086 const QChar *unicode = m_text.unicode();
00087
00088 for(int i = pos; i < len; i++)
00089 {
00090 if(!unicode[i].isSpace())
00091 return i;
00092 }
00093
00094 return -1;
00095 }
00096
00097 int KateTextLine::previousNonSpaceChar(int pos) const
00098 {
00099 const int len = m_text.length();
00100 const QChar *unicode = m_text.unicode();
00101
00102 if (pos < 0)
00103 pos = 0;
00104
00105 if (pos >= len)
00106 pos = len - 1;
00107
00108 for(int i = pos; i >= 0; i--)
00109 {
00110 if(!unicode[i].isSpace())
00111 return i;
00112 }
00113
00114 return -1;
00115 }
00116
00117 int KateTextLine::firstChar() const
00118 {
00119 return nextNonSpaceChar(0);
00120 }
00121
00122 int KateTextLine::lastChar() const
00123 {
00124 return previousNonSpaceChar(m_text.length() - 1);
00125 }
00126
00127 QString KateTextLine::leadingWhitespace() const
00128 {
00129 if (firstChar() < 0)
00130 return string(0, length());
00131
00132 return string(0, firstChar());
00133 }
00134
00135 int KateTextLine::indentDepth (int tabWidth) const
00136 {
00137 int d = 0;
00138 const int len = m_text.length();
00139 const QChar *unicode = m_text.unicode();
00140
00141 for(int i = 0; i < len; ++i)
00142 {
00143 if(unicode[i].isSpace())
00144 {
00145 if (unicode[i] == QChar('\t'))
00146 d += tabWidth - (d % tabWidth);
00147 else
00148 d++;
00149 }
00150 else
00151 return d;
00152 }
00153
00154 return d;
00155 }
00156
00157 bool KateTextLine::matchesAt(int column, const QString& match) const
00158 {
00159 if (column < 0)
00160 return false;
00161
00162 const int len = m_text.length();
00163 const int matchlen = match.length();
00164
00165 if ((column + matchlen) > len)
00166 return false;
00167
00168 const QChar *unicode = m_text.unicode();
00169 const QChar *matchUnicode = match.unicode();
00170
00171 for (int i=0; i < matchlen; ++i)
00172 if (unicode[i+column] != matchUnicode[i])
00173 return false;
00174
00175 return true;
00176 }
00177
00178 int KateTextLine::toVirtualColumn (int column, int tabWidth) const
00179 {
00180 if (column < 0)
00181 return 0;
00182
00183 int x = 0;
00184 const int zmax = qMin(column, m_text.length());
00185 const QChar *unicode = m_text.unicode();
00186
00187 for ( int z = 0; z < zmax; ++z)
00188 {
00189 if (unicode[z] == QChar('\t'))
00190 x += tabWidth - (x % tabWidth);
00191 else
00192 x++;
00193 }
00194
00195 return x;
00196 }
00197
00198 int KateTextLine::fromVirtualColumn (int column, int tabWidth) const
00199 {
00200 if (column < 0)
00201 return 0;
00202
00203 const int zmax = qMin(m_text.length(), column);
00204 const QChar *unicode = m_text.unicode();
00205
00206 int x = 0;
00207 int z = 0;
00208 for (; z < zmax; ++z)
00209 {
00210 int diff = 1;
00211 if (unicode[z] == QChar('\t'))
00212 diff = tabWidth - (x % tabWidth);
00213
00214 if (x + diff > column)
00215 break;
00216 x += diff;
00217 }
00218
00219 return z;
00220 }
00221
00222 int KateTextLine::virtualLength (int tabWidth) const
00223 {
00224 int x = 0;
00225 const int len = m_text.length();
00226 const QChar *unicode = m_text.unicode();
00227
00228 for ( int z = 0; z < len; ++z)
00229 {
00230 if (unicode[z] == QChar('\t'))
00231 x += tabWidth - (x % tabWidth);
00232 else
00233 x++;
00234 }
00235
00236 return x;
00237 }
00238
00239 bool KateTextLine::searchText (uint startCol, uint endCol, const QString &text, uint *foundAtCol,
00240 uint *matchLen, bool casesensitive, bool backwards) const
00241 {
00242 int index;
00243
00244
00245
00246 int l = text.length();
00247
00248 if (backwards)
00249 {
00250 int col = -1;
00251 int start_col=startCol-m_text.length();
00252
00253
00254
00255
00256
00257 do {
00258 index = m_text.lastIndexOf( text, col, casesensitive?Qt::CaseSensitive:Qt::CaseInsensitive);
00259 col--;
00260
00261
00262
00263 } while ( (col>=start_col) && (index >= (int)startCol) && ((l + index) > (int)endCol) );
00264 }
00265 else
00266 index = m_text.indexOf (text, startCol, casesensitive?Qt::CaseSensitive:Qt::CaseInsensitive);
00267
00268 if (index > -1)
00269 {
00270 if ( (index>=(int)startCol) && ( (index+l)<=(int)endCol) ) {
00271 if (foundAtCol)
00272 (*foundAtCol) = index;
00273 if (matchLen)
00274 (*matchLen)=text.length();
00275 return true;
00276 }
00277 }
00278
00279 return false;
00280 }
00281
00282 bool KateTextLine::searchText (uint startCol, const QRegExp ®exp, uint *foundAtCol, uint *matchLen, bool backwards) const
00283 {
00284 int index;
00285
00286 if (backwards)
00287 {
00288 int col = startCol;
00289
00290
00291 if ( col == (int) m_text.length() ) ++startCol;
00292 do {
00293 index = regexp.lastIndexIn (m_text, col);
00294 col--;
00295 } while ( col >= 0 && regexp.matchedLength() + index >= (int)startCol );
00296 }
00297 else
00298 index = regexp.indexIn (m_text, startCol);
00299
00300 if (index > -1)
00301 {
00302 if (foundAtCol)
00303 (*foundAtCol) = index;
00304
00305 if (matchLen)
00306 (*matchLen)=regexp.matchedLength();
00307 return true;
00308 }
00309
00310 return false;
00311 }
00312
00313 void KateTextLine::addAttribute (int start, int length, int attribute)
00314 {
00315
00316
00317
00318 if ((m_attributesList.size() > 2) && (m_attributesList[m_attributesList.size()-1] == attribute)
00319 && (m_attributesList[m_attributesList.size()-3]+m_attributesList[m_attributesList.size()-2]
00320 == start))
00321 {
00322 m_attributesList[m_attributesList.size()-2] += length;
00323 return;
00324 }
00325
00326 m_attributesList.resize (m_attributesList.size()+3);
00327 m_attributesList[m_attributesList.size()-3] = start;
00328 m_attributesList[m_attributesList.size()-2] = length;
00329 m_attributesList[m_attributesList.size()-1] = attribute;
00330 }
00331
00332