/* This file is part of the KDE libraries * Copyright (C) 2007 Mirko Stocker * Copyright (C) 2003-2005 Hamish Rodda * Copyright (C) 2002 Christian Couder * Copyright (C) 2001, 2003 Christoph Cullmann * Copyright (C) 2001 Joseph Wenninger * Copyright (C) 1999 Jochen Wilhelmy * * 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)); } 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;