~ubuntu-branches/ubuntu/vivid/kate/vivid-proposed

« back to all changes in this revision

Viewing changes to part/search/kateplaintextsearch.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2014-12-04 16:49:41 UTC
  • mfrom: (1.6.6)
  • Revision ID: package-import@ubuntu.com-20141204164941-l3qbvsly83hhlw2v
Tags: 4:14.11.97-0ubuntu1
* New upstream release
* Update build-deps and use pkg-kde v3 for Qt 5 build
* kate-data now kate5-data for co-installability

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  This file is part of the KDE libraries and the Kate part.
2
 
 *
3
 
 *  Copyright (C) 2009-2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
4
 
 *  Copyright (C) 2007 Sebastian Pipping <webmaster@hartwork.org>
5
 
 *
6
 
 *  This library is free software; you can redistribute it and/or
7
 
 *  modify it under the terms of the GNU Library General Public
8
 
 *  License as published by the Free Software Foundation; either
9
 
 *  version 2 of the License, or (at your option) any later version.
10
 
 *
11
 
 *  This library is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 *  Library General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU Library General Public License
17
 
 *  along with this library; see the file COPYING.LIB.  If not, write to
18
 
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
 
 *  Boston, MA 02110-1301, USA.
20
 
 */
21
 
 
22
 
//BEGIN includes
23
 
#include "kateplaintextsearch.h"
24
 
 
25
 
#include "kateregexpsearch.h"
26
 
 
27
 
#include <ktexteditor/document.h>
28
 
 
29
 
#include <kdebug.h>
30
 
//END  includes
31
 
 
32
 
 
33
 
//BEGIN d'tor, c'tor
34
 
//
35
 
// KateSearch Constructor
36
 
//
37
 
KatePlainTextSearch::KatePlainTextSearch ( KTextEditor::Document *document, Qt::CaseSensitivity caseSensitivity, bool wholeWords )
38
 
: m_document (document)
39
 
, m_caseSensitivity (caseSensitivity)
40
 
, m_wholeWords (wholeWords)
41
 
{
42
 
}
43
 
 
44
 
//
45
 
// KateSearch Destructor
46
 
//
47
 
KatePlainTextSearch::~KatePlainTextSearch()
48
 
{
49
 
}
50
 
//END
51
 
 
52
 
KTextEditor::Range KatePlainTextSearch::search (const QString & text, const KTextEditor::Range & inputRange, bool backwards)
53
 
{
54
 
  // abuse regex for whole word plaintext search
55
 
  if (m_wholeWords)
56
 
  {
57
 
    // escape dot and friends
58
 
    const QString workPattern = "\\b" + QRegExp::escape(text) + "\\b";
59
 
 
60
 
    return KateRegExpSearch(m_document, m_caseSensitivity).search(workPattern, inputRange, backwards)[0];
61
 
  }
62
 
 
63
 
  if (text.isEmpty() || !inputRange.isValid() || (inputRange.start() == inputRange.end()))
64
 
  {
65
 
    return KTextEditor::Range::invalid();
66
 
  }
67
 
 
68
 
  // split multi-line needle into single lines
69
 
  const QStringList needleLines = text.split("\n");
70
 
 
71
 
  if (needleLines.count() > 1)
72
 
  {
73
 
    // multi-line plaintext search (both forwards or backwards)
74
 
    const int forMin  = inputRange.start().line(); // first line in range
75
 
    const int forMax  = inputRange.end().line() + 1 - needleLines.count(); // last line in range
76
 
    const int forInit = backwards ? forMax : forMin;
77
 
    const int forInc  = backwards ? -1 : +1;
78
 
 
79
 
    for (int j = forInit; (forMin <= j) && (j <= forMax); j += forInc)
80
 
    {
81
 
      // try to match all lines
82
 
      const int startCol = m_document->lineLength(j) - needleLines[0].length();
83
 
      for (int k = 0; k < needleLines.count(); k++)
84
 
      {
85
 
        // which lines to compare
86
 
        const QString & needleLine = needleLines[k];
87
 
        const QString & hayLine = m_document->line(j + k);
88
 
 
89
 
        // position specific comparison (first, middle, last)
90
 
        if (k == 0) {
91
 
          // first line
92
 
          if (forMin == j && startCol < inputRange.start().column())
93
 
            break;
94
 
          if (!hayLine.endsWith(needleLine, m_caseSensitivity))
95
 
            break;
96
 
        } else if (k == needleLines.count() - 1) {
97
 
          // last line
98
 
          const int maxRight = (j + k == inputRange.end().line()) ? inputRange.end().column() : hayLine.length();
99
 
 
100
 
          if (hayLine.startsWith(needleLine, m_caseSensitivity) && needleLine.length() <= maxRight)
101
 
            return KTextEditor::Range(j, startCol, j + k, needleLine.length());
102
 
        } else {
103
 
          // mid lines
104
 
          if (hayLine.compare(needleLine, m_caseSensitivity) != 0) {
105
 
            break;
106
 
          }
107
 
        }
108
 
      }
109
 
    }
110
 
 
111
 
    // not found
112
 
    return KTextEditor::Range::invalid();
113
 
  }
114
 
  else
115
 
  {
116
 
    // single-line plaintext search (both forward of backward mode)
117
 
    const int startCol  = inputRange.start().column();
118
 
    const int endCol    = inputRange.end().column(); // first not included
119
 
    const int startLine = inputRange.start().line();
120
 
    const int endLine   = inputRange.end().line();
121
 
    const int forInc    = backwards ? -1 : +1;
122
 
 
123
 
    for (int line = backwards ? endLine : startLine; (startLine <= line) && (line <= endLine); line += forInc)
124
 
    {
125
 
      if ((line < 0) || (m_document->lines() <= line))
126
 
      {
127
 
        kWarning() << "line " << line << " is not within interval [0.." << m_document->lines() << ") ... returning invalid range";
128
 
        return KTextEditor::Range::invalid();
129
 
      }
130
 
 
131
 
      const QString textLine = m_document->line(line);
132
 
 
133
 
      const int offset   = (line == startLine) ? startCol : 0;
134
 
      const int line_end = (line ==   endLine) ?   endCol : textLine.length();
135
 
      const int foundAt = backwards ? textLine.lastIndexOf(text, line_end-text.length(), m_caseSensitivity) :
136
 
                                      textLine.indexOf(text, offset, m_caseSensitivity);
137
 
 
138
 
      if ((offset <= foundAt) && (foundAt + text.length() <= line_end))
139
 
        return KTextEditor::Range(line, foundAt, line, foundAt + text.length());
140
 
    }
141
 
  }
142
 
  return KTextEditor::Range::invalid();
143
 
}
144
 
 
145
 
// kate: space-indent on; indent-width 2; replace-tabs on;