1 /***************************************************************************
2 Copyright 2006 David Nolden <david.nolden.kdevelop@art-master.de>
3 ***************************************************************************/
5 /***************************************************************************
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 ***************************************************************************/
13 #include "indocumentreference.h"
16 /* Exclude this file from doublequote_chars check as krazy doesn't understand
18 //krazy:excludeall=doublequote_chars
20 QString
InDocumentReference::createReference( const QString
& file
, int startLine
, int startCol
, int endLine
, int endCol
) {
22 if( startLine
!= -1 ) ret
.append( QString( ":%1" ).arg( startLine
) );
23 if( startCol
!= -1 ) ret
.append( QString( ":%1" ).arg( startCol
) );
24 if( endLine
!= -1 ) ret
.append( QString( ":%1" ).arg( endLine
) );
25 if( endCol
!= -1 ) ret
.append( QString( ":%1" ).arg( endCol
) );
29 void InDocumentReference::parseReference( const QString
& ref
, QString
& file
, int& startLine
, int& startCol
, int& endLine
, int& endCol
) {
31 startLine
= endLine
= startCol
= endCol
= -1;
32 if ( ref
.indexOf( ':' ) != -1 ) {
33 file
= ref
.left( ref
.indexOf( ':' ) );
35 QString tail
= ref
.mid( file
.length()+1 );
37 int refs
[4] = {-1, -1, -1, -1};
38 for( int a
= 0; a
< 4; a
++ ) {
39 if( tail
.isEmpty() ) break;
40 int nextPos
= tail
.indexOf( ':' );
41 if( nextPos
== -1 ) nextPos
= tail
.length();
42 refs
[a
] = tail
.left( nextPos
).toInt();
43 tail
= tail
.mid( nextPos
+1 );
44 if( tail
.isEmpty() ) break;
54 ///This creates a reference that refers to a position, but not intelligently.
55 InDocumentReference::InDocumentReference( bool start
, const QString
& ref
) : m_line( -1 ), m_col( -1 ) {
59 parseReference( ref
, doc
, m_line
, m_col
, d1
, d2
);
61 parseReference( ref
, doc
, d1
, d2
, m_line
, m_col
);
65 InDocumentReference::InDocumentReference( const QString
& document
, int line
, int col
, const QString
& text
) {
67 m_document
= ~document
;
69 if ( !text
.isEmpty() )
73 void InDocumentReference::useText( const QString
& text
) {
76 int index
= lineColToIndex( text
, m_line
, m_col
== -1 ? 0 : m_col
);
78 SumSearch
<10> search( ~text
);
79 m_position
= search
.getReference( index
);
83 QString
InDocumentReference::document() const {
87 struct InDocumentReference::TextSearchInstance::Private
: public Shared
{
91 Private( const QString
& txt
) : search( ~txt
), text( txt
) {
97 InDocumentReference::TextSearchInstance::TextSearchInstance( const TextSearchInstance
& rhs
) {
101 InDocumentReference::TextSearchInstance::TextSearchInstance( const QString
& txt
) {
102 m_data
= new Private( txt
);
105 InDocumentReference::TextSearchInstance::TextSearchInstance() {
108 QString
InDocumentReference::TextSearchInstance::text() const {
109 if( !m_data
) return "";
114 InDocumentReference::TextSearchInstance::~TextSearchInstance() {
117 InDocumentReference::TextSearchInstance
& InDocumentReference::TextSearchInstance::operator = ( const TextSearchInstance
& rhs
) {
122 InDocumentReference::TextSearchInstance::operator bool() const {
126 ///Finds the reference-position dynamically within the given text. If the search fails, puts -1 -1.
127 void InDocumentReference::findInText( const TextSearchInstance
& text
, int& line
, int& col
) const {
128 if ( !isValid() || !text
) {
133 int pos
= text
.m_data
->search
.findReference( m_position
);
140 ///Fall bock to returning the fixed line- and column-numbers
147 indexToLineCol( pos
, text
.m_data
->text
, line
, col
);
151 bool InDocumentReference::isValid() const {
152 return ( m_line
!= -1 ) && !m_document
.empty();
155 bool InDocumentReference::isDynamic() const {
156 return m_position
.isValid();
159 InDocumentReference::operator bool() const {
163 ///findInText(..) should be preferred, because it can find the correct position even if the text changed.
164 int InDocumentReference::line() const {
168 QString
InDocumentReference::asText() const {
169 QString ret
= QString( "%1" ).arg( m_line
);
170 if ( m_col
!= 0 && m_col
!= -1 )
171 ret
+= QString( ":%1" ).arg( m_col
);
172 if ( m_position
.isValid() )
177 int InDocumentReference::col() const {
184 DocumentContextLines::DocumentContextLines() : m_lineOffset( 0 ) {}
186 DocumentContextLines::DocumentContextLines( const InDocumentReference
& beginRef
, const InDocumentReference
& endRef
, const QString
& text
, int /*contextSize*/ ) : m_lineOffset( 0 ) {
187 int startLine
= beginRef
.line();
188 int endLine
= endRef
.line();
189 if ( startLine
== -1 )
191 m_lineOffset
= startLine
- 5;
194 int end
= endLine
+ 5;
195 if ( m_lineOffset
< 0 )
197 if ( end
< m_lineOffset
)
198 end
= m_lineOffset
+ 1;
200 int i
= lineColToIndex( text
, m_lineOffset
, 0 );
205 int endI
= lineColToIndex( text
, end
, 0 );
209 m_lines
= ~text
.mid( i
, endI
- i
);
212 DocumentContextLines::operator bool() const {
213 return !m_lines
.empty();
216 QString
DocumentContextLines::text() const {
220 int DocumentContextLines::lineOffset() const {