• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

Kate

katetextrange.cpp

Go to the documentation of this file.
00001 /*  This file is part of the Kate project.
00002  *
00003  *  Copyright (C) 2010 Christoph Cullmann <cullmann@kde.org>
00004  *
00005  *  Based on code of the SmartCursor/Range by:
00006  *  Copyright (C) 2003-2005 Hamish Rodda <rodda@kde.org>
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 as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Library General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Library General Public License
00019  *  along with this library; see the file COPYING.LIB.  If not, write to
00020  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021  *  Boston, MA 02110-1301, USA.
00022  */
00023 
00024 #include "katetextrange.h"
00025 #include "katetextbuffer.h"
00026 
00027 namespace Kate {
00028 
00029 TextRange::TextRange (TextBuffer &buffer, const KTextEditor::Range &range, InsertBehaviors insertBehavior, EmptyBehavior emptyBehavior)
00030   : m_buffer (buffer)
00031   , m_start (buffer, this, range.start(), (insertBehavior & ExpandLeft) ? Kate::TextCursor::StayOnInsert : Kate::TextCursor::MoveOnInsert)
00032   , m_end (buffer, this, range.end(), (insertBehavior & ExpandRight) ? Kate::TextCursor::MoveOnInsert : Kate::TextCursor::StayOnInsert)
00033   , m_view (0)
00034   , m_feedback (0)
00035   , m_zDepth (0.0)
00036   , m_attributeOnlyForViews (false)
00037   , m_invalidateIfEmpty (emptyBehavior == InvalidateIfEmpty)
00038 {
00039   // remember this range in buffer
00040   m_buffer.m_ranges.insert (this);
00041 
00042   // check if range now invalid, there can happen no feedback, as m_feedback == 0
00043   checkValidity ();
00044 }
00045 
00046 TextRange::~TextRange ()
00047 {
00051   m_feedback = 0;
00052 
00053   // remove range from m_ranges
00054   fixLookup (m_start.line(), m_end.line(), -1, -1);
00055 
00056   // remove this range from the buffer
00057   m_buffer.m_ranges.remove (this);
00058 
00064   if (m_attribute)
00065     m_buffer.notifyAboutRangeChange (m_view, m_start.line(), m_end.line(), true /* we have a attribute */);
00066 }
00067 
00068 void TextRange::setInsertBehaviors (InsertBehaviors _insertBehaviors)
00069 {
00073   if (_insertBehaviors == insertBehaviors ())
00074     return;
00075 
00079   m_start.setInsertBehavior ((_insertBehaviors & ExpandLeft) ? KTextEditor::MovingCursor::StayOnInsert : KTextEditor::MovingCursor::MoveOnInsert);
00080   m_end.setInsertBehavior ((_insertBehaviors & ExpandRight) ? KTextEditor::MovingCursor::MoveOnInsert : KTextEditor::MovingCursor::StayOnInsert);
00081 
00085   if (m_attribute || m_feedback)
00086     m_buffer.notifyAboutRangeChange (m_view, m_start.line(), m_end.line(), true /* we have a attribute */);
00087 }
00088 
00089 KTextEditor::MovingRange::InsertBehaviors TextRange::insertBehaviors () const
00090 {
00091   InsertBehaviors behaviors = DoNotExpand;
00092 
00093   if (m_start.insertBehavior() == KTextEditor::MovingCursor::StayOnInsert)
00094     behaviors = behaviors & ExpandLeft;
00095 
00096   if (m_end.insertBehavior() == KTextEditor::MovingCursor::MoveOnInsert)
00097     behaviors = behaviors & ExpandRight;
00098 
00099   return behaviors;
00100 }
00101 
00102 void TextRange::setEmptyBehavior (EmptyBehavior emptyBehavior)
00103 {
00107   if (m_invalidateIfEmpty == (emptyBehavior == InvalidateIfEmpty))
00108     return;
00109 
00113   m_invalidateIfEmpty = (emptyBehavior == InvalidateIfEmpty);
00114 
00118   if (end() <= start())
00119     setRange (KTextEditor::Range::invalid());
00120 }
00121 
00122 void TextRange::setRange (const KTextEditor::Range &range)
00123 {
00124   // avoid work if nothing changed!
00125   if (range == toRange())
00126     return;
00127 
00128   // remember old line range
00129   int oldStartLine = m_start.line();
00130   int oldEndLine = m_end.line();
00131 
00132   // change start and end cursor
00133   m_start.setPosition (range.start ());
00134   m_end.setPosition (range.end ());
00135 
00136   // check if range now invalid, don't emit feedback here, will be handled below
00137   // otherwise you can't delete ranges in feedback!
00138   checkValidity (oldStartLine, oldEndLine, false);
00139 
00140   // no attribute or feedback set, be done
00141   if (!m_attribute && !m_feedback)
00142     return;
00143 
00144   // get full range
00145   int startLineMin = oldStartLine;
00146   if (oldStartLine == -1 || (m_start.line() != -1 && m_start.line() < oldStartLine))
00147     startLineMin = m_start.line();
00148 
00149   int endLineMax = oldEndLine;
00150   if (oldEndLine == -1 || m_end.line() > oldEndLine)
00151     endLineMax = m_end.line();
00152 
00157   m_buffer.notifyAboutRangeChange (m_view, startLineMin, endLineMax, m_attribute);
00158 
00159   // perhaps need to notify stuff!
00160   if (m_feedback) {
00161     // do this last: may delete this range
00162     if (!toRange().isValid())
00163       m_feedback->rangeInvalid (this);
00164     else if (toRange().isEmpty())
00165       m_feedback->rangeEmpty (this);
00166   }
00167 }
00168 
00169 void TextRange::checkValidity (int oldStartLine, int oldEndLine, bool notifyAboutChange)
00170 {
00174   if (!m_start.isValid() || !m_end.isValid() || (m_invalidateIfEmpty && m_end <= m_start)) {
00175     m_start.setPosition (-1, -1);
00176     m_end.setPosition (-1, -1);
00177   }
00178 
00182   if (!m_invalidateIfEmpty && m_end < m_start)
00183     m_end.setPosition (m_start);
00184 
00185   // fix lookup
00186   fixLookup (oldStartLine, oldEndLine, m_start.line(), m_end.line());
00187 
00188   // perhaps need to notify stuff!
00189   if (notifyAboutChange && m_feedback) {
00190     m_buffer.notifyAboutRangeChange (m_view, m_start.line(), m_end.line(), false /* attribute not interesting here */);
00191 
00192     // do this last: may delete this range
00193     if (!toRange().isValid())
00194       m_feedback->rangeInvalid (this);
00195     else if (toRange().isEmpty())
00196       m_feedback->rangeEmpty (this);
00197   }
00198 }
00199 
00200 void TextRange::fixLookup (int oldStartLine, int oldEndLine, int startLine, int endLine)
00201 {
00202   // nothing changed?
00203   if (oldStartLine == startLine && oldEndLine == endLine)
00204     return;
00205 
00206   // now, not both can be invalid
00207   Q_ASSERT (oldStartLine >= 0 || startLine >= 0);
00208   Q_ASSERT (oldEndLine >= 0 || endLine >= 0);
00209 
00210   // get full range
00211   int startLineMin = oldStartLine;
00212   if (oldStartLine == -1 || (startLine != -1 && startLine < oldStartLine))
00213     startLineMin = startLine;
00214 
00215   int endLineMax = oldEndLine;
00216   if (oldEndLine == -1 || endLine > oldEndLine)
00217     endLineMax = endLine;
00218 
00219   // get start block
00220   int blockIndex = m_buffer.blockForLine (startLineMin);
00221   Q_ASSERT (blockIndex >= 0);
00222 
00223   // remove this range from m_ranges
00224   for (; blockIndex < m_buffer.m_blocks.size(); ++blockIndex) {
00225     // get block
00226     TextBlock *block = m_buffer.m_blocks[blockIndex];
00227 
00228     // either insert or remove range
00229     if ((endLine < block->startLine()) || (startLine >= (block->startLine() + block->lines())))
00230       block->removeRange (this);
00231     else
00232       block->updateRange (this);
00233 
00234     // ok, reached end block
00235     if (endLineMax < (block->startLine() + block->lines()))
00236       return;
00237   }
00238 
00239   // we should not be here, really, then endLine is wrong
00240   Q_ASSERT (false);
00241 }
00242 
00243 void TextRange::setView (KTextEditor::View *view)
00244 {
00248   if (view == m_view)
00249     return;
00250 
00254   m_view = view;
00255 
00260   if (m_attribute || m_feedback)
00261     m_buffer.notifyAboutRangeChange (0, m_start.line(), m_end.line(), m_attribute);
00262 }
00263 
00264 void TextRange::setAttribute ( KTextEditor::Attribute::Ptr attribute )
00265 {
00269   m_attribute = attribute;
00270 
00275   m_buffer.notifyAboutRangeChange (m_view, m_start.line(), m_end.line(), m_attribute);
00276 }
00277 
00278 void TextRange::setFeedback (KTextEditor::MovingRangeFeedback *feedback)
00279 {
00283   if (feedback == m_feedback)
00284     return;
00285 
00289   m_feedback = feedback;
00290 
00295   m_buffer.notifyAboutRangeChange (m_view, m_start.line(), m_end.line(), m_attribute);
00296 }
00297 
00298 void TextRange::setAttributeOnlyForViews (bool onlyForViews)
00299 {
00303     m_attributeOnlyForViews = onlyForViews;
00304 }
00305 
00306 void TextRange::setZDepth (qreal zDepth)
00307 {
00311   if (zDepth == m_zDepth)
00312     return;
00313 
00317   m_zDepth = zDepth;
00318 
00322   if (m_attribute)
00323     m_buffer.notifyAboutRangeChange (m_view, m_start.line(), m_end.line(), m_attribute);
00324 }
00325 
00326 KTextEditor::Document *Kate::TextRange::document () const
00327 {
00328     return m_buffer.document();
00329 }
00330 
00331 }

Kate

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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