Qt 4.8
textwriter.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/textwriter_p.h"
43 
45 
46 using namespace QDeclarativeJS;
47 
49  :string(0), cursor(0)
50 {
51 }
52 
53 static bool overlaps(int posA, int lengthA, int posB, int lengthB) {
54  return (posA < posB + lengthB && posA + lengthA > posB + lengthB)
55  || (posA < posB && posA + lengthA > posB);
56 }
57 
58 bool TextWriter::hasOverlap(int pos, int length)
59 {
60  {
61  QListIterator<Replace> i(replaceList);
62  while (i.hasNext()) {
63  const Replace &cmd = i.next();
64  if (overlaps(pos, length, cmd.pos, cmd.length))
65  return true;
66  }
67  }
68  {
69  QListIterator<Move> i(moveList);
70  while (i.hasNext()) {
71  const Move &cmd = i.next();
72  if (overlaps(pos, length, cmd.pos, cmd.length))
73  return true;
74  }
75  return false;
76  }
77 }
78 
79 bool TextWriter::hasMoveInto(int pos, int length)
80 {
81  QListIterator<Move> i(moveList);
82  while (i.hasNext()) {
83  const Move &cmd = i.next();
84  if (cmd.to >= pos && cmd.to < pos + length)
85  return true;
86  }
87  return false;
88 }
89 
90 void TextWriter::replace(int pos, int length, const QString &replacement)
91 {
92  Q_ASSERT(!hasOverlap(pos, length));
93  Q_ASSERT(!hasMoveInto(pos, length));
94 
95  Replace cmd;
96  cmd.pos = pos;
97  cmd.length = length;
98  cmd.replacement = replacement;
99  replaceList += cmd;
100 }
101 
102 void TextWriter::move(int pos, int length, int to)
103 {
104  Q_ASSERT(!hasOverlap(pos, length));
105 
106  Move cmd;
107  cmd.pos = pos;
108  cmd.length = length;
109  cmd.to = to;
110  moveList += cmd;
111 }
112 
114 {
115  int diff = replace.replacement.size() - replace.length;
116  {
117  QMutableListIterator<Replace> i(replaceList);
118  while (i.hasNext()) {
119  Replace &c = i.next();
120  if (replace.pos < c.pos)
121  c.pos += diff;
122  else if (replace.pos + replace.length < c.pos + c.length)
123  c.length += diff;
124  }
125  }
126  {
127  QMutableListIterator<Move> i(moveList);
128  while (i.hasNext()) {
129  Move &c = i.next();
130  if (replace.pos < c.pos)
131  c.pos += diff;
132  else if (replace.pos + replace.length < c.pos + c.length)
133  c.length += diff;
134 
135  if (replace.pos < c.to)
136  c.to += diff;
137  }
138  }
139 
140  if (string) {
141  string->replace(replace.pos, replace.length, replace.replacement);
142  } else if (cursor) {
143  cursor->setPosition(replace.pos);
144  cursor->setPosition(replace.pos + replace.length, QTextCursor::KeepAnchor);
145  cursor->insertText(replace.replacement);
146  }
147 }
148 
150 {
151  QString text;
152  if (string) {
153  text = string->mid(move.pos, move.length);
154  } else if (cursor) {
155  cursor->setPosition(move.pos);
157  text = cursor->selectedText();
158  }
159 
160  Replace cut;
161  cut.pos = move.pos;
162  cut.length = move.length;
163  Replace paste;
164  paste.pos = move.to;
165  paste.length = 0;
166  paste.replacement = text;
167 
168  replaceList.append(cut);
169  replaceList.append(paste);
170 
171  Replace cmd;
172  while (!replaceList.isEmpty()) {
173  cmd = replaceList.first();
174  replaceList.removeFirst();
175  doReplace(cmd);
176  }
177 }
178 
180 {
181  string = s;
182  write_helper();
183  string = 0;
184 }
185 
187 {
188  cursor = textCursor;
189  write_helper();
190  cursor = 0;
191 }
192 
194 {
195  if (cursor)
197  {
198  Replace cmd;
199  while (!replaceList.isEmpty()) {
200  cmd = replaceList.first();
201  replaceList.removeFirst();
202  doReplace(cmd);
203  }
204  }
205  {
206  Move cmd;
207  while (!moveList.isEmpty()) {
208  cmd = moveList.first();
209  moveList.removeFirst();
210  doMove(cmd);
211  }
212  }
213  if (cursor)
214  cursor->endEditBlock();
215 }
216 
void endEditBlock()
Indicates the end of a block of editing operations on the document that should appear as a single ope...
bool hasMoveInto(int pos, int length)
Definition: textwriter.cpp:79
unsigned char c[8]
Definition: qnumeric_p.h:62
void doMove(const Move &move)
Definition: textwriter.cpp:149
void write(QString *s)
Definition: textwriter.cpp:179
bool hasOverlap(int pos, int length)
Definition: textwriter.cpp:58
void doReplace(const Replace &replace)
Definition: textwriter.cpp:113
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QString selectedText() const
Returns the current selection&#39;s text (which may be empty).
void insertText(const QString &text)
Inserts text at the current position, using the current character format.
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
The QTextCursor class offers an API to access and modify QTextDocuments.
Definition: qtextcursor.h:70
void replace(int pos, int length, const QString &replacement)
Definition: textwriter.cpp:90
#define QT_QML_END_NAMESPACE
static Bigint * diff(Bigint *a, Bigint *b)
#define QT_QML_BEGIN_NAMESPACE
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
void beginEditBlock()
Indicates the start of a block of editing operations on the document that should appear as a single o...
QList< Replace > replaceList
Definition: textwriter_p.h:67
void move(int pos, int length, int to)
Definition: textwriter.cpp:102
void setPosition(int pos, MoveMode mode=MoveAnchor)
Moves the cursor to the absolute position in the document specified by pos using a MoveMode specified...
static bool overlaps(int posA, int lengthA, int posB, int lengthB)
Definition: textwriter.cpp:53
#define text
Definition: qobjectdefs.h:80