kdelibs/interfaces/ktexteditor/range.cpp
2014-11-13 01:04:59 +02:00

337 lines
6.9 KiB
C++

/* This file is part of the KDE libraries
* Copyright (C) 2007 Mirko Stocker <me@misto.ch>
* Copyright (C) 2003-2005 Hamish Rodda <rodda@kde.org>
* Copyright (C) 2002 Christian Couder <christian@kdevelop.org>
* Copyright (C) 2001, 2003 Christoph Cullmann <cullmann@kde.org>
* Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
* Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "range.h"
using namespace KTextEditor;
Range::Range()
: m_start(new Cursor())
, m_end(new Cursor())
{
m_start->setRange(this);
m_end->setRange(this);
}
Range::Range(const Cursor& start, const Cursor& end)
{
if (start <= end) {
m_start = new Cursor(start);
m_end = new Cursor(end);
} else {
m_start = new Cursor(end);
m_end = new Cursor(start);
}
m_start->setRange(this);
m_end->setRange(this);
}
Range::Range(const Cursor& start, int width)
: m_start(new Cursor(start))
, m_end(new Cursor(start.line(), start.column() + width))
{
m_start->setRange(this);
m_end->setRange(this);
}
Range::Range(const Cursor& start, int endLine, int endColumn)
: m_start(new Cursor(start))
, m_end(new Cursor(endLine, endColumn))
{
if (*m_end < *m_start) {
Cursor* temp = m_end;
m_end = m_start;
m_start = temp;
}
m_start->setRange(this);
m_end->setRange(this);
}
Range::Range(int startLine, int startColumn, int endLine, int endColumn)
: m_start(new Cursor(startLine, startColumn))
, m_end(new Cursor(endLine, endColumn))
{
if (*m_end < *m_start) {
Cursor* temp = m_end;
m_end = m_start;
m_start = temp;
}
m_start->setRange(this);
m_end->setRange(this);
}
Range::Range(Cursor* start, Cursor* end)
: m_start(start)
, m_end(end)
{
if (*m_end < *m_start) {
Cursor temp = *m_end;
*m_end = *m_start;
*m_start = temp;
}
m_start->setRange(this);
m_end->setRange(this);
}
Range::Range(const Range& copy)
: m_start(new Cursor(copy.start()))
, m_end(new Cursor(copy.end()))
{
m_start->setRange(this);
m_end->setRange(this);
}
Range::~Range()
{
delete m_start;
delete m_end;
}
bool Range::isValid( ) const
{
return start().isValid() && end().isValid();
}
Range Range::invalid()
{
return Range (Cursor(-1, -1), Cursor(-1, -1));
}
void Range::setRange(const Range& range)
{
*m_start = range.start();
*m_end = range.end();
}
void Range::setRange( const Cursor & start, const Cursor & end )
{
if (start > end)
setRange(Range(end, start));
else
setRange(Range(start, end));
}
bool Range::containsLine(int line) const
{
return (line > start().line() || (line == start().line() && !start().column())) && line < end().line();
}
bool Range::overlapsLine(int line) const
{
return line >= start().line() && line <= end().line();
}
bool Range::overlapsColumn( int col ) const
{
return start().column() <= col && end().column() > col;
}
bool Range::contains( const Cursor& cursor ) const
{
return cursor >= start() && cursor < end();
}
bool Range::contains( const Range& range ) const
{
return range.start() >= start() && range.end() <= end();
}
bool Range::containsColumn( int column ) const
{
return column >= start().column() && column < end().column();
}
bool Range::overlaps( const Range& range ) const
{
if (range.start() <= start())
return range.end() > start();
else if (range.end() >= end())
return range.start() < end();
else
return contains(range);
}
bool Range::boundaryAtCursor(const Cursor& cursor) const
{
return cursor == start() || cursor == end();
}
bool Range::boundaryOnLine(int line) const
{
return start().line() == line || end().line() == line;
}
bool Range::confineToRange(const Range& range)
{
if (start() < range.start())
if (end() > range.end())
setRange(range);
else
start() = range.start();
else if (end() > range.end())
end() = range.end();
else
return false;
return true;
}
bool Range::expandToRange(const Range& range)
{
if (start() > range.start())
if (end() < range.end())
setRange(range);
else
start() = range.start();
else if (end() < range.end())
end() = range.end();
else
return false;
return true;
}
void Range::rangeChanged( Cursor * c, const Range& )
{
if (c == m_start) {
if (*c > *m_end)
*m_end = *c;
} else if (c == m_end) {
if (*c < *m_start)
*m_start = *c;
}
}
void Range::setBothLines( int line )
{
setRange(Range(line, start().column(), line, end().column()));
}
bool KTextEditor::Range::onSingleLine( ) const
{
return start().line() == end().line();
}
int KTextEditor::Range::columnWidth( ) const
{
return end().column() - start().column();
}
int KTextEditor::Range::numberOfLines( ) const
{
return end().line() - start().line();
}
bool KTextEditor::Range::isEmpty( ) const
{
return start() == end();
}
int Range::positionRelativeToCursor( const Cursor & cursor ) const
{
if (end() <= cursor)
return -1;
if (start() > cursor)
return +1;
return 0;
}
int Range::positionRelativeToLine( int line ) const
{
if (end().line() < line)
return -1;
if (start().line() > line)
return +1;
return 0;
}
void KTextEditor::Range::setBothColumns( int column )
{
setRange(Range(start().line(), column, end().line(), column));
}
bool KTextEditor::Range::isSmartRange( ) const
{
return false;
}
SmartRange* KTextEditor::Range::toSmartRange( ) const
{
return 0L;
}
Cursor& KTextEditor::Range::start()
{
return *m_start;
}
const Cursor& KTextEditor::Range::start() const
{
return *m_start;
}
Cursor& KTextEditor::Range::end()
{
return *m_end;
}
const Cursor& KTextEditor::Range::end() const
{
return *m_end;
}
Range KTextEditor::Range::intersect( const Range & range ) const
{
if (!isValid() || !range.isValid() || *this > range || *this < range)
return invalid();
return Range(qMax(start(), range.start()), qMin(end(), range.end()));
}
Range KTextEditor::Range::encompass( const Range & range ) const
{
if (!isValid())
if (range.isValid())
return range;
else
return invalid();
else if (!range.isValid())
return *this;
else
return Range(qMin(start(), range.start()), qMax(end(), range.end()));
}
// kate: space-indent on; indent-width 2; replace-tabs on;