summaryrefslogtreecommitdiff
authorpaule <paule>2007-01-13 07:24:51 (UTC)
committer paule <paule>2007-01-13 07:24:51 (UTC)
commit4892c61a3e76c031d7b882854dcb0dfbd575f045 (patch) (unidiff)
tree5c5de924caf9683ad844fd1ef6d27aff433a560b
parent80d1934bbbfaea40ee08cf6be738c6517de9477c (diff)
downloadopie-4892c61a3e76c031d7b882854dcb0dfbd575f045.zip
opie-4892c61a3e76c031d7b882854dcb0dfbd575f045.tar.gz
opie-4892c61a3e76c031d7b882854dcb0dfbd575f045.tar.bz2
Clear document modified flag on save
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/tinykate/libkate/document/katedocument.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/noncore/apps/tinykate/libkate/document/katedocument.cpp b/noncore/apps/tinykate/libkate/document/katedocument.cpp
index a70f3aa..b82a86a 100644
--- a/noncore/apps/tinykate/libkate/document/katedocument.cpp
+++ b/noncore/apps/tinykate/libkate/document/katedocument.cpp
@@ -1,1904 +1,1909 @@
1/*************************************************************************** 1/***************************************************************************
2 katedocument.cpp - description 2 katedocument.cpp - description
3 ------------------- 3 -------------------
4 begin : Mon Jan 15 2001 4 begin : Mon Jan 15 2001
5 copyright : (C) 2001 by Christoph "Crossfire" Cullmann 5 copyright : (C) 2001 by Christoph "Crossfire" Cullmann
6 (C) 2002 by Joseph Wenninger 6 (C) 2002 by Joseph Wenninger
7 email : crossfire@babylon2k.de 7 email : crossfire@babylon2k.de
8 jowenn@kde.org 8 jowenn@kde.org
9 9
10***************************************************************************/ 10***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * * 13 * *
14 * This program is free software; you can redistribute it and/or modify * 14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by * 15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or * 16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. * 17 * (at your option) any later version. *
18 * * 18 * *
19 ***************************************************************************/ 19 ***************************************************************************/
20 20
21/* 21/*
22 Copyright (C) 1998, 1999 Jochen Wilhelmy 22 Copyright (C) 1998, 1999 Jochen Wilhelmy
23 digisnap@cs.tu-berlin.de 23 digisnap@cs.tu-berlin.de
24 24
25 This library is free software; you can redistribute it and/or 25 This library is free software; you can redistribute it and/or
26 modify it under the terms of the GNU Library General Public 26 modify it under the terms of the GNU Library General Public
27 License as published by the Free Software Foundation; either 27 License as published by the Free Software Foundation; either
28 version 2 of the License, or (at your option) any later version. 28 version 2 of the License, or (at your option) any later version.
29 29
30 This library is distributed in the hope that it will be useful, 30 This library is distributed in the hope that it will be useful,
31 but WITHOUT ANY WARRANTY; without even the implied warranty of 31 but WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 Library General Public License for more details. 33 Library General Public License for more details.
34 34
35 You should have received a copy of the GNU Library General Public License 35 You should have received a copy of the GNU Library General Public License
36 along with this library; see the file COPYING.LIB. If not, write to 36 along with this library; see the file COPYING.LIB. If not, write to
37 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 37 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
38 Boston, MA 02111-1307, USA. 38 Boston, MA 02111-1307, USA.
39*/ 39*/
40 40
41#include "katedocument.h" 41#include "katedocument.h"
42#include "kmessagebox.h" 42#include "kmessagebox.h"
43#include "kglobal.h" 43#include "kglobal.h"
44 44
45//#include "kcharsets.h" 45//#include "kcharsets.h"
46#include "kdebug.h" 46#include "kdebug.h"
47//#include "kinstance.h" 47//#include "kinstance.h"
48 48
49#include "kglobalsettings.h" 49#include "kglobalsettings.h"
50//#include "kaction.h" 50//#include "kaction.h"
51//#include "kstdaction.h" 51//#include "kstdaction.h"
52 52
53#include "../view/kateview.h" 53#include "../view/kateview.h"
54#include "katebuffer.h" 54#include "katebuffer.h"
55#include "katetextline.h" 55#include "katetextline.h"
56 56
57#include "katecmd.h" 57#include "katecmd.h"
58 58
59/* OPIE */ 59/* OPIE */
60#include <opie2/odebug.h> 60#include <opie2/odebug.h>
61#include <qpe/config.h> 61#include <qpe/config.h>
62 62
63/* QT */ 63/* QT */
64#include <qfileinfo.h> 64#include <qfileinfo.h>
65#include <qdatetime.h> 65#include <qdatetime.h>
66#include <qstring.h> 66#include <qstring.h>
67#include <qtimer.h> 67#include <qtimer.h>
68#include <qobject.h> 68#include <qobject.h>
69#include <qapplication.h> 69#include <qapplication.h>
70#include <qclipboard.h> 70#include <qclipboard.h>
71#include <qfont.h> 71#include <qfont.h>
72#include <qpainter.h> 72#include <qpainter.h>
73#include <qfile.h> 73#include <qfile.h>
74#include <qtextstream.h> 74#include <qtextstream.h>
75#include <qtextcodec.h> 75#include <qtextcodec.h>
76 76
77/* STD */ 77/* STD */
78#include <sys/time.h> 78#include <sys/time.h>
79#include <unistd.h> 79#include <unistd.h>
80#include <stdio.h> 80#include <stdio.h>
81 81
82KateAction::KateAction(Action a, PointStruc &cursor, int len, const QString &text) 82KateAction::KateAction(Action a, PointStruc &cursor, int len, const QString &text)
83 : action(a), cursor(cursor), len(len), text(text) { 83 : action(a), cursor(cursor), len(len), text(text) {
84} 84}
85 85
86KateActionGroup::KateActionGroup(PointStruc &aStart, int type) 86KateActionGroup::KateActionGroup(PointStruc &aStart, int type)
87 : start(aStart), action(0L), undoType(type) { 87 : start(aStart), action(0L), undoType(type) {
88} 88}
89 89
90KateActionGroup::~KateActionGroup() { 90KateActionGroup::~KateActionGroup() {
91 KateAction *current, *next; 91 KateAction *current, *next;
92 92
93 current = action; 93 current = action;
94 while (current) { 94 while (current) {
95 next = current->next; 95 next = current->next;
96 delete current; 96 delete current;
97 current = next; 97 current = next;
98 } 98 }
99} 99}
100 100
101void KateActionGroup::insertAction(KateAction *a) { 101void KateActionGroup::insertAction(KateAction *a) {
102 a->next = action; 102 a->next = action;
103 action = a; 103 action = a;
104} 104}
105 105
106const char * KateActionGroup::typeName(int type) 106const char * KateActionGroup::typeName(int type)
107{ 107{
108 // return a short text description of the given undo group type suitable for a menu 108 // return a short text description of the given undo group type suitable for a menu
109 // not the lack of i18n's, the caller is expected to handle translation 109 // not the lack of i18n's, the caller is expected to handle translation
110 switch (type) { 110 switch (type) {
111 case ugPaste : return "Paste Text"; 111 case ugPaste : return "Paste Text";
112 case ugDelBlock : return "Selection Overwrite"; 112 case ugDelBlock : return "Selection Overwrite";
113 case ugIndent : return "Indent"; 113 case ugIndent : return "Indent";
114 case ugUnindent : return "Unindent"; 114 case ugUnindent : return "Unindent";
115 case ugComment : return "Comment"; 115 case ugComment : return "Comment";
116 case ugUncomment : return "Uncomment"; 116 case ugUncomment : return "Uncomment";
117 case ugReplace : return "Text Replace"; 117 case ugReplace : return "Text Replace";
118 case ugSpell : return "Spell Check"; 118 case ugSpell : return "Spell Check";
119 case ugInsChar : return "Typing"; 119 case ugInsChar : return "Typing";
120 case ugDelChar : return "Delete Text"; 120 case ugDelChar : return "Delete Text";
121 case ugInsLine : return "New Line"; 121 case ugInsLine : return "New Line";
122 case ugDelLine : return "Delete Line"; 122 case ugDelLine : return "Delete Line";
123 } 123 }
124 return ""; 124 return "";
125} 125}
126 126
127const int KateDocument::maxAttribs = 32; 127const int KateDocument::maxAttribs = 32;
128 128
129QStringList KateDocument::searchForList = QStringList(); 129QStringList KateDocument::searchForList = QStringList();
130QStringList KateDocument::replaceWithList = QStringList(); 130QStringList KateDocument::replaceWithList = QStringList();
131 131
132uint KateDocument::uniqueID = 0; 132uint KateDocument::uniqueID = 0;
133 133
134QPtrDict<KateDocument::KateDocPrivate>* KateDocument::d_ptr = 0; 134QPtrDict<KateDocument::KateDocPrivate>* KateDocument::d_ptr = 0;
135 135
136 136
137KateDocument::KateDocument(bool bSingleViewMode, bool bBrowserView, 137KateDocument::KateDocument(bool bSingleViewMode, bool bBrowserView,
138 QWidget *parentWidget, const char *widgetName, 138 QWidget *parentWidget, const char *widgetName,
139 QObject *, const char *) 139 QObject *, const char *)
140 : Kate::Document (), 140 : Kate::Document (),
141 myFont(KGlobalSettings::generalFont()), myFontBold(KGlobalSettings::generalFont()), myFontItalic(KGlobalSettings::generalFont()), myFontBI(KGlobalSettings::generalFont()), 141 myFont(KGlobalSettings::generalFont()), myFontBold(KGlobalSettings::generalFont()), myFontItalic(KGlobalSettings::generalFont()), myFontBI(KGlobalSettings::generalFont()),
142 myFontMetrics (myFont), myFontMetricsBold (myFontBold), myFontMetricsItalic (myFontItalic), myFontMetricsBI (myFontBI), 142 myFontMetrics (myFont), myFontMetricsBold (myFontBold), myFontMetricsItalic (myFontItalic), myFontMetricsBI (myFontBI),
143 hlManager(HlManager::self ()) 143 hlManager(HlManager::self ())
144{ 144{
145 145
146 d(this)->hlSetByUser = false; 146 d(this)->hlSetByUser = false;
147 PreHighlightedTill=0; 147 PreHighlightedTill=0;
148 RequestPreHighlightTill=0; 148 RequestPreHighlightTill=0;
149 149
150 m_bSingleViewMode=bSingleViewMode; 150 m_bSingleViewMode=bSingleViewMode;
151 m_bBrowserView = bBrowserView; 151 m_bBrowserView = bBrowserView;
152 152
153 m_url = QString::null; 153 m_url = QString::null;
154 154
155 // NOTE: QFont::CharSet doesn't provide all the charsets KDE supports 155 // NOTE: QFont::CharSet doesn't provide all the charsets KDE supports
156 // (esp. it doesn't distinguish between UTF-8 and iso10646-1) 156 // (esp. it doesn't distinguish between UTF-8 and iso10646-1)
157 157
158 myEncoding = QString::fromLatin1(QTextCodec::codecForLocale()->name()); 158 myEncoding = QString::fromLatin1(QTextCodec::codecForLocale()->name());
159 159
160 maxLength = -1; 160 maxLength = -1;
161 161
162 setFont (KGlobalSettings::generalFont()); 162 setFont (KGlobalSettings::generalFont());
163 163
164 myDocID = uniqueID; 164 myDocID = uniqueID;
165 uniqueID++; 165 uniqueID++;
166 166
167 myDocName = QString (""); 167 myDocName = QString ("");
168 fileInfo = new QFileInfo (); 168 fileInfo = new QFileInfo ();
169 169
170 myCmd = new KateCmd (this); 170 myCmd = new KateCmd (this);
171 171
172 connect(this,SIGNAL(modifiedChanged()),this,SLOT(slotModChanged())); 172 connect(this,SIGNAL(modifiedChanged()),this,SLOT(slotModChanged()));
173 173
174 buffer = new KWBuffer; 174 buffer = new KWBuffer;
175 connect(buffer, SIGNAL(linesChanged(int)), this, SLOT(slotBufferChanged())); 175 connect(buffer, SIGNAL(linesChanged(int)), this, SLOT(slotBufferChanged()));
176// connect(buffer, SIGNAL(textChanged()), this, SIGNAL(textChanged())); 176// connect(buffer, SIGNAL(textChanged()), this, SIGNAL(textChanged()));
177 connect(buffer, SIGNAL(needHighlight(long,long)),this,SLOT(slotBufferHighlight(long,long))); 177 connect(buffer, SIGNAL(needHighlight(long,long)),this,SLOT(slotBufferHighlight(long,long)));
178 178
179 colors[0] = KGlobalSettings::baseColor(); 179 colors[0] = KGlobalSettings::baseColor();
180 colors[1] = KGlobalSettings::highlightColor(); 180 colors[1] = KGlobalSettings::highlightColor();
181 181
182 m_attribs = new Attribute[maxAttribs]; 182 m_attribs = new Attribute[maxAttribs];
183 183
184 m_highlight = 0L; 184 m_highlight = 0L;
185 tabChars = 8; 185 tabChars = 8;
186 186
187 m_singleSelection = false; 187 m_singleSelection = false;
188 188
189 newDocGeometry = false; 189 newDocGeometry = false;
190 readOnly = false; 190 readOnly = false;
191 newDoc = false; 191 newDoc = false;
192 192
193 modified = false; 193 modified = false;
194 194
195 undoList.setAutoDelete(true); 195 undoList.setAutoDelete(true);
196 undoState = 0; 196 undoState = 0;
197 undoSteps = 50; 197 undoSteps = 50;
198 198
199 pseudoModal = 0L; 199 pseudoModal = 0L;
200 clear(); 200 clear();
201 201
202 setHighlight(0); //calls updateFontData() 202 setHighlight(0); //calls updateFontData()
203 // if the user changes the highlight with the dialog, notify the doc 203 // if the user changes the highlight with the dialog, notify the doc
204 connect(hlManager,SIGNAL(changed()),SLOT(hlChanged())); 204 connect(hlManager,SIGNAL(changed()),SLOT(hlChanged()));
205 205
206 newDocGeometry = false; 206 newDocGeometry = false;
207 207
208 readConfig(); 208 readConfig();
209 209
210 setReadOnly(false); 210 setReadOnly(false);
211} 211}
212 212
213void KateDocument::setDontChangeHlOnSave() 213void KateDocument::setDontChangeHlOnSave()
214{ 214{
215 d(this)->hlSetByUser = true; 215 d(this)->hlSetByUser = true;
216} 216}
217 217
218void KateDocument::setFont (QFont font) 218void KateDocument::setFont (QFont font)
219{ 219{
220 kdDebug()<<"Kate:: setFont"<<endl; 220 kdDebug()<<"Kate:: setFont"<<endl;
221 int oldwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 221 int oldwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
222 myFont = font; 222 myFont = font;
223 myFontBold = QFont (font); 223 myFontBold = QFont (font);
224 myFontBold.setBold (true); 224 myFontBold.setBold (true);
225 225
226 myFontItalic = QFont (font); 226 myFontItalic = QFont (font);
227 myFontItalic.setItalic (true); 227 myFontItalic.setItalic (true);
228 228
229 myFontBI = QFont (font); 229 myFontBI = QFont (font);
230 myFontBI.setBold (true); 230 myFontBI.setBold (true);
231 myFontBI.setItalic (true); 231 myFontBI.setItalic (true);
232 232
233 myFontMetrics = CachedFontMetrics (myFont); 233 myFontMetrics = CachedFontMetrics (myFont);
234 myFontMetricsBold = CachedFontMetrics (myFontBold); 234 myFontMetricsBold = CachedFontMetrics (myFontBold);
235 myFontMetricsItalic = CachedFontMetrics (myFontItalic); 235 myFontMetricsItalic = CachedFontMetrics (myFontItalic);
236 myFontMetricsBI = CachedFontMetrics (myFontBI); 236 myFontMetricsBI = CachedFontMetrics (myFontBI);
237 int newwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 237 int newwidth=myFontMetrics.width('W'); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
238 maxLength=maxLength*(float)newwidth/(float)oldwidth; //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 238 maxLength=maxLength*(float)newwidth/(float)oldwidth; //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
239 239
240 updateFontData(); 240 updateFontData();
241 updateViews(); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0 241 updateViews(); //Quick & Dirty Hack (by JoWenn) //Remove in KDE 3.0
242 242
243} 243}
244 244
245long KateDocument::needPreHighlight(long till) 245long KateDocument::needPreHighlight(long till)
246{ 246{
247 int max=numLines()-1; 247 int max=numLines()-1;
248 if (till>max) 248 if (till>max)
249 { 249 {
250 till=max; 250 till=max;
251 } 251 }
252 if (PreHighlightedTill>=till) return -1; 252 if (PreHighlightedTill>=till) return -1;
253 253
254 long tmp=RequestPreHighlightTill; 254 long tmp=RequestPreHighlightTill;
255 if (RequestPreHighlightTill<till) 255 if (RequestPreHighlightTill<till)
256 { 256 {
257 RequestPreHighlightTill=till; 257 RequestPreHighlightTill=till;
258 if (tmp<=PreHighlightedTill) QTimer::singleShot(10,this,SLOT(doPreHighlight())); 258 if (tmp<=PreHighlightedTill) QTimer::singleShot(10,this,SLOT(doPreHighlight()));
259 } 259 }
260 return RequestPreHighlightTill; 260 return RequestPreHighlightTill;
261} 261}
262 262
263void KateDocument::doPreHighlight() 263void KateDocument::doPreHighlight()
264{ 264{
265 int from = PreHighlightedTill; 265 int from = PreHighlightedTill;
266 int till = PreHighlightedTill+200; 266 int till = PreHighlightedTill+200;
267 int max = numLines()-1; 267 int max = numLines()-1;
268 if (till > max) 268 if (till > max)
269 { 269 {
270 till = max; 270 till = max;
271 } 271 }
272 PreHighlightedTill = till; 272 PreHighlightedTill = till;
273 updateLines(from,till); 273 updateLines(from,till);
274 emit preHighlightChanged(PreHighlightedTill); 274 emit preHighlightChanged(PreHighlightedTill);
275 if (PreHighlightedTill<RequestPreHighlightTill) 275 if (PreHighlightedTill<RequestPreHighlightTill)
276 QTimer::singleShot(10,this,SLOT(doPreHighlight())); 276 QTimer::singleShot(10,this,SLOT(doPreHighlight()));
277} 277}
278 278
279KateDocument::~KateDocument() 279KateDocument::~KateDocument()
280{ 280{
281 m_highlight->release(); 281 m_highlight->release();
282 writeConfig(); 282 writeConfig();
283 283
284 if ( !m_bSingleViewMode ) 284 if ( !m_bSingleViewMode )
285 { 285 {
286 m_views.setAutoDelete( true ); 286 m_views.setAutoDelete( true );
287 m_views.clear(); 287 m_views.clear();
288 m_views.setAutoDelete( false ); 288 m_views.setAutoDelete( false );
289 } 289 }
290 delete_d(this); 290 delete_d(this);
291} 291}
292 292
293void KateDocument::openURL(const QString &filename) 293void KateDocument::openURL(const QString &filename)
294{ 294{
295 295
296 m_file=filename; 296 m_file=filename;
297 fileInfo->setFile (m_file); 297 fileInfo->setFile (m_file);
298 setMTime(); 298 setMTime();
299 299
300 if (!fileInfo->exists() || !fileInfo->isReadable()) 300 if (!fileInfo->exists() || !fileInfo->isReadable())
301 { 301 {
302 odebug << "File doesn't exit or couldn't be read" << oendl; 302 odebug << "File doesn't exit or couldn't be read" << oendl;
303 return ; 303 return ;
304 } 304 }
305 305
306 buffer->clear(); 306 buffer->clear();
307#warning fixme 307#warning fixme
308// buffer->insertFile(0, m_file, KGlobal::charsets()->codecForName(myEncoding)); 308// buffer->insertFile(0, m_file, KGlobal::charsets()->codecForName(myEncoding));
309 odebug << "Telling buffer to open file" << oendl; 309 odebug << "Telling buffer to open file" << oendl;
310 buffer->insertFile(0, m_file, QTextCodec::codecForLocale()); 310 buffer->insertFile(0, m_file, QTextCodec::codecForLocale());
311 311
312 setMTime(); 312 setMTime();
313 313
314 if (myWordWrap) 314 if (myWordWrap)
315 wrapText (myWordWrapAt); 315 wrapText (myWordWrapAt);
316 316
317 int hl = hlManager->wildcardFind( m_file ); 317 int hl = hlManager->wildcardFind( m_file );
318 318
319 setHighlight(hl); 319 setHighlight(hl);
320 320
321 updateLines(); 321 updateLines();
322 updateViews(); 322 updateViews();
323 323
324 emit fileNameChanged(); 324 emit fileNameChanged();
325 325
326 return ; 326 return ;
327} 327}
328 328
329bool KateDocument::saveFile() 329bool KateDocument::saveFile()
330{ 330{
331 331
332 QFile f( m_file ); 332 QFile f( m_file );
333 if ( !f.open( IO_WriteOnly ) ) 333 if ( !f.open( IO_WriteOnly ) )
334 return false; // Error 334 return false; // Error
335 335
336 QTextStream stream(&f); 336 QTextStream stream(&f);
337 337
338 stream.setEncoding(QTextStream::RawUnicode); // disable Unicode headers 338 stream.setEncoding(QTextStream::RawUnicode); // disable Unicode headers
339#warning fixme 339#warning fixme
340// stream.setCodec(KGlobal::charsets()->codecForName(myEncoding)); 340// stream.setCodec(KGlobal::charsets()->codecForName(myEncoding));
341 stream.setCodec(QTextCodec::codecForLocale()); // this line sets the mapper to the correct codec 341 stream.setCodec(QTextCodec::codecForLocale()); // this line sets the mapper to the correct codec
342 342
343 int maxLine = numLines(); 343 int maxLine = numLines();
344 int line = 0; 344 int line = 0;
345 while(true) 345 while(true)
346 { 346 {
347 stream << getTextLine(line)->getString(); 347 stream << getTextLine(line)->getString();
348 line++; 348 line++;
349 if (line >= maxLine) break; 349 if (line >= maxLine) break;
350 350
351 if (eolMode == KateDocument::eolUnix) stream << "\n"; 351 if (eolMode == KateDocument::eolUnix) stream << "\n";
352 else if (eolMode == KateDocument::eolDos) stream << "\r\n"; 352 else if (eolMode == KateDocument::eolDos) stream << "\r\n";
353 else if (eolMode == KateDocument::eolMacintosh) stream << '\r'; 353 else if (eolMode == KateDocument::eolMacintosh) stream << '\r';
354 }; 354 };
355 f.close(); 355 f.close();
356 356
357 fileInfo->setFile (m_file); 357 fileInfo->setFile (m_file);
358 setMTime(); 358 setMTime();
359 359
360 if (!(d(this)->hlSetByUser)) 360 if (!(d(this)->hlSetByUser))
361 { 361 {
362 int hl = hlManager->wildcardFind( m_file ); 362 int hl = hlManager->wildcardFind( m_file );
363 363
364 setHighlight(hl); 364 setHighlight(hl);
365 } 365 }
366 emit fileNameChanged (); 366 emit fileNameChanged ();
367 367
368 return (f.status() == IO_Ok); 368 if(f.status() == IO_Ok) {
369 setModified(false);
370 return true;
371 }
372 else
373 return false;
369} 374}
370 375
371KTextEditor::View *KateDocument::createView( QWidget *parent, const char *name ) 376KTextEditor::View *KateDocument::createView( QWidget *parent, const char *name )
372{ 377{
373 return new KateView( this, parent, name); 378 return new KateView( this, parent, name);
374} 379}
375 380
376QString KateDocument::textLine( int line ) const 381QString KateDocument::textLine( int line ) const
377{ 382{
378 TextLine::Ptr l = getTextLine( line ); 383 TextLine::Ptr l = getTextLine( line );
379 if ( !l ) 384 if ( !l )
380 return QString(); 385 return QString();
381 386
382 return l->getString(); 387 return l->getString();
383} 388}
384 389
385void KateDocument::replaceLine(const QString& s,int line) 390void KateDocument::replaceLine(const QString& s,int line)
386{ 391{
387 remove_Line(line,false); 392 remove_Line(line,false);
388 insert_Line(s,line,true); 393 insert_Line(s,line,true);
389} 394}
390 395
391void KateDocument::insertLine( const QString &str, int l ) { 396void KateDocument::insertLine( const QString &str, int l ) {
392 insert_Line(str,l,true); 397 insert_Line(str,l,true);
393} 398}
394 399
395void KateDocument::insert_Line(const QString& s,int line, bool update) 400void KateDocument::insert_Line(const QString& s,int line, bool update)
396{ 401{
397 kdDebug(13020)<<"KateDocument::insertLine "<<s<<QString(" %1").arg(line)<<endl; 402 kdDebug(13020)<<"KateDocument::insertLine "<<s<<QString(" %1").arg(line)<<endl;
398 TextLine::Ptr TL=new TextLine(); 403 TextLine::Ptr TL=new TextLine();
399 TL->append(s.unicode(),s.length()); 404 TL->append(s.unicode(),s.length());
400 buffer->insertLine(line,TL); 405 buffer->insertLine(line,TL);
401 if (update) 406 if (update)
402 { 407 {
403 newDocGeometry=true; 408 newDocGeometry=true;
404 updateLines(line); 409 updateLines(line);
405 updateViews(); 410 updateViews();
406 } 411 }
407} 412}
408 413
409void KateDocument::insertAt( const QString &s, int line, int col, bool ) 414void KateDocument::insertAt( const QString &s, int line, int col, bool )
410{ 415{
411 VConfig c; 416 VConfig c;
412 c.view = 0; // ### FIXME 417 c.view = 0; // ### FIXME
413 c.cursor.x = col; 418 c.cursor.x = col;
414 c.cursor.y = line; 419 c.cursor.y = line;
415 c.cXPos = 0; // ### FIXME 420 c.cXPos = 0; // ### FIXME
416 c.flags = 0; // ### FIXME 421 c.flags = 0; // ### FIXME
417 insert( c, s ); 422 insert( c, s );
418} 423}
419 424
420void KateDocument::removeLine( int line ) { 425void KateDocument::removeLine( int line ) {
421 remove_Line(line,true); 426 remove_Line(line,true);
422} 427}
423 428
424void KateDocument::remove_Line(int line,bool update) 429void KateDocument::remove_Line(int line,bool update)
425{ 430{
426 kdDebug(13020)<<"KateDocument::removeLine "<<QString("%1").arg(line)<<endl; 431 kdDebug(13020)<<"KateDocument::removeLine "<<QString("%1").arg(line)<<endl;
427 buffer->removeLine(line); 432 buffer->removeLine(line);
428// newDocGeometry=true; 433// newDocGeometry=true;
429// if line==0) 434// if line==0)
430 if (update) 435 if (update)
431 { 436 {
432 updateLines(line); 437 updateLines(line);
433 updateViews(); 438 updateViews();
434 } 439 }
435} 440}
436 441
437int KateDocument::length() const 442int KateDocument::length() const
438{ 443{
439 return text().length(); 444 return text().length();
440} 445}
441 446
442void KateDocument::setSelection( int , int , int , int ) 447void KateDocument::setSelection( int , int , int , int )
443{ 448{
444} 449}
445 450
446bool KateDocument::hasSelection() const 451bool KateDocument::hasSelection() const
447{ 452{
448 return (selectEnd >= selectStart); 453 return (selectEnd >= selectStart);
449} 454}
450 455
451QString KateDocument::selection() const 456QString KateDocument::selection() const
452{ 457{
453 uint flags = 0; 458 uint flags = 0;
454 TextLine::Ptr textLine; 459 TextLine::Ptr textLine;
455 int len, z, start, end, i; 460 int len, z, start, end, i;
456 461
457 len = 1; 462 len = 1;
458 if (!(flags & KateView::cfVerticalSelect)) { 463 if (!(flags & KateView::cfVerticalSelect)) {
459 for (z = selectStart; z <= selectEnd; z++) { 464 for (z = selectStart; z <= selectEnd; z++) {
460 textLine = getTextLine(z); 465 textLine = getTextLine(z);
461 len += textLine->numSelected(); 466 len += textLine->numSelected();
462 if (textLine->isSelected()) len++; 467 if (textLine->isSelected()) len++;
463 } 468 }
464 QString s; 469 QString s;
465 len = 0; 470 len = 0;
466 for (z = selectStart; z <= selectEnd; z++) { 471 for (z = selectStart; z <= selectEnd; z++) {
467 textLine = getTextLine(z); 472 textLine = getTextLine(z);
468 end = 0; 473 end = 0;
469 do { 474 do {
470 start = textLine->findUnselected(end); 475 start = textLine->findUnselected(end);
471 end = textLine->findSelected(start); 476 end = textLine->findSelected(start);
472 for (i = start; i < end; i++) { 477 for (i = start; i < end; i++) {
473 s[len] = textLine->getChar(i); 478 s[len] = textLine->getChar(i);
474 len++; 479 len++;
475 } 480 }
476 } while (start < end); 481 } while (start < end);
477 if (textLine->isSelected()) { 482 if (textLine->isSelected()) {
478 s[len] = '\n'; 483 s[len] = '\n';
479 len++; 484 len++;
480 } 485 }
481 } 486 }
482// s[len] = '\0'; 487// s[len] = '\0';
483 return s; 488 return s;
484 } else { 489 } else {
485 for (z = selectStart; z <= selectEnd; z++) { 490 for (z = selectStart; z <= selectEnd; z++) {
486 textLine = getTextLine(z); 491 textLine = getTextLine(z);
487 len += textLine->numSelected() + 1; 492 len += textLine->numSelected() + 1;
488 } 493 }
489 QString s; 494 QString s;
490 len = 0; 495 len = 0;
491 for (z = selectStart; z <= selectEnd; z++) { 496 for (z = selectStart; z <= selectEnd; z++) {
492 textLine = getTextLine(z); 497 textLine = getTextLine(z);
493 end = 0; 498 end = 0;
494 do { 499 do {
495 start = textLine->findUnselected(end); 500 start = textLine->findUnselected(end);
496 end = textLine->findSelected(start); 501 end = textLine->findSelected(start);
497 for (i = start; i < end; i++) { 502 for (i = start; i < end; i++) {
498 s[len] = textLine->getChar(i); 503 s[len] = textLine->getChar(i);
499 len++; 504 len++;
500 } 505 }
501 } while (start < end); 506 } while (start < end);
502 s[len] = '\n'; 507 s[len] = '\n';
503 len++; 508 len++;
504 } 509 }
505// s[len] = '\0'; // the final \0 is not counted in length() 510// s[len] = '\0'; // the final \0 is not counted in length()
506 return s; 511 return s;
507 } 512 }
508} 513}
509 514
510int KateDocument::numLines() const 515int KateDocument::numLines() const
511{ 516{
512 return buffer->count(); 517 return buffer->count();
513} 518}
514 519
515 520
516TextLine::Ptr KateDocument::getTextLine(int line) const 521TextLine::Ptr KateDocument::getTextLine(int line) const
517{ 522{
518 // This is a hack to get this stuff working. 523 // This is a hack to get this stuff working.
519 return buffer->line(line); 524 return buffer->line(line);
520} 525}
521 526
522int KateDocument::textLength(int line) { 527int KateDocument::textLength(int line) {
523 TextLine::Ptr textLine = getTextLine(line); 528 TextLine::Ptr textLine = getTextLine(line);
524 if (!textLine) return 0; 529 if (!textLine) return 0;
525 return textLine->length(); 530 return textLine->length();
526} 531}
527 532
528void KateDocument::setTabWidth(int chars) { 533void KateDocument::setTabWidth(int chars) {
529 if (tabChars == chars) return; 534 if (tabChars == chars) return;
530 if (chars < 1) chars = 1; 535 if (chars < 1) chars = 1;
531 if (chars > 16) chars = 16; 536 if (chars > 16) chars = 16;
532 tabChars = chars; 537 tabChars = chars;
533 updateFontData(); 538 updateFontData();
534 539
535 maxLength = -1; 540 maxLength = -1;
536 for (int i=0; i < buffer->count(); i++) 541 for (int i=0; i < buffer->count(); i++)
537 { 542 {
538 TextLine::Ptr textLine = buffer->line(i); 543 TextLine::Ptr textLine = buffer->line(i);
539 int len = textWidth(textLine,textLine->length()); 544 int len = textWidth(textLine,textLine->length());
540 if (len > maxLength) { 545 if (len > maxLength) {
541 maxLength = len; 546 maxLength = len;
542 longestLine = textLine; 547 longestLine = textLine;
543 } 548 }
544 } 549 }
545} 550}
546 551
547void KateDocument::setReadOnly(bool m) { 552void KateDocument::setReadOnly(bool m) {
548 KTextEditor::View *view; 553 KTextEditor::View *view;
549 554
550 if (m != readOnly) { 555 if (m != readOnly) {
551 readOnly = m; 556 readOnly = m;
552// if (readOnly) recordReset(); 557// if (readOnly) recordReset();
553 for (view = m_views.first(); view != 0L; view = m_views.next() ) { 558 for (view = m_views.first(); view != 0L; view = m_views.next() ) {
554 emit static_cast<KateView *>( view )->newStatus(); 559 emit static_cast<KateView *>( view )->newStatus();
555 } 560 }
556 } 561 }
557} 562}
558 563
559bool KateDocument::isReadOnly() const { 564bool KateDocument::isReadOnly() const {
560 return readOnly; 565 return readOnly;
561} 566}
562 567
563void KateDocument::setNewDoc( bool m ) 568void KateDocument::setNewDoc( bool m )
564{ 569{
565// KTextEditor::View *view; 570// KTextEditor::View *view;
566 571
567 if ( m != newDoc ) 572 if ( m != newDoc )
568 { 573 {
569 newDoc = m; 574 newDoc = m;
570//// if (readOnly) recordReset(); 575//// if (readOnly) recordReset();
571// for (view = m_views.first(); view != 0L; view = m_views.next() ) { 576// for (view = m_views.first(); view != 0L; view = m_views.next() ) {
572// emit static_cast<KateView *>( view )->newStatus(); 577// emit static_cast<KateView *>( view )->newStatus();
573// } 578// }
574 } 579 }
575} 580}
576 581
577bool KateDocument::isNewDoc() const { 582bool KateDocument::isNewDoc() const {
578 return newDoc; 583 return newDoc;
579} 584}
580 585
581void KateDocument::setModified(bool m) { 586void KateDocument::setModified(bool m) {
582 KTextEditor::View *view; 587 KTextEditor::View *view;
583 588
584 if (m != modified) { 589 if (m != modified) {
585 modified = m; 590 modified = m;
586 for (view = m_views.first(); view != 0L; view = m_views.next() ) { 591 for (view = m_views.first(); view != 0L; view = m_views.next() ) {
587 emit static_cast<KateView *>( view )->newStatus(); 592 emit static_cast<KateView *>( view )->newStatus();
588 } 593 }
589 emit modifiedChanged (); 594 emit modifiedChanged ();
590 } 595 }
591} 596}
592 597
593bool KateDocument::isModified() const { 598bool KateDocument::isModified() const {
594 return modified; 599 return modified;
595} 600}
596 601
597void KateDocument::readConfig() 602void KateDocument::readConfig()
598{ 603{
599 KateConfig *config = KGlobal::config(); 604 KateConfig *config = KGlobal::config();
600 config->setGroup("Kate Document"); 605 config->setGroup("Kate Document");
601 606
602 myWordWrap = config->readBoolEntry("Word Wrap On", false); 607 myWordWrap = config->readBoolEntry("Word Wrap On", false);
603 myWordWrapAt = config->readNumEntry("Word Wrap At", 80); 608 myWordWrapAt = config->readNumEntry("Word Wrap At", 80);
604 if (myWordWrap) 609 if (myWordWrap)
605 wrapText (myWordWrapAt); 610 wrapText (myWordWrapAt);
606 611
607 setTabWidth(config->readNumEntry("TabWidth", 8)); 612 setTabWidth(config->readNumEntry("TabWidth", 8));
608 setUndoSteps(config->readNumEntry("UndoSteps", 50)); 613 setUndoSteps(config->readNumEntry("UndoSteps", 50));
609 m_singleSelection = config->readBoolEntry("SingleSelection", false); 614 m_singleSelection = config->readBoolEntry("SingleSelection", false);
610 myEncoding = config->readEntry("Encoding", QString::fromLatin1(QTextCodec::codecForLocale()->name())); 615 myEncoding = config->readEntry("Encoding", QString::fromLatin1(QTextCodec::codecForLocale()->name()));
611 setFont (config->readFontEntry("Font", myFont)); 616 setFont (config->readFontEntry("Font", myFont));
612 617
613 colors[0] = config->readColorEntry("Color Background", colors[0]); 618 colors[0] = config->readColorEntry("Color Background", colors[0]);
614 colors[1] = config->readColorEntry("Color Selected", colors[1]); 619 colors[1] = config->readColorEntry("Color Selected", colors[1]);
615 620
616// config->sync(); 621// config->sync();
617} 622}
618 623
619void KateDocument::writeConfig() 624void KateDocument::writeConfig()
620{ 625{
621 KateConfig *config = KGlobal::config(); 626 KateConfig *config = KGlobal::config();
622 config->setGroup("Kate Document"); 627 config->setGroup("Kate Document");
623 config->writeEntry("Word Wrap On", myWordWrap); 628 config->writeEntry("Word Wrap On", myWordWrap);
624 config->writeEntry("Word Wrap At", myWordWrapAt); 629 config->writeEntry("Word Wrap At", myWordWrapAt);
625 config->writeEntry("TabWidth", tabChars); 630 config->writeEntry("TabWidth", tabChars);
626 config->writeEntry("UndoSteps", undoSteps); 631 config->writeEntry("UndoSteps", undoSteps);
627 config->writeEntry("SingleSelection", m_singleSelection); 632 config->writeEntry("SingleSelection", m_singleSelection);
628 config->writeEntry("Encoding", myEncoding); 633 config->writeEntry("Encoding", myEncoding);
629 config->writeEntry("Font", myFont); 634 config->writeEntry("Font", myFont);
630 config->writeEntry("Color Background", colors[0]); 635 config->writeEntry("Color Background", colors[0]);
631 config->writeEntry("Color Selected", colors[1]); 636 config->writeEntry("Color Selected", colors[1]);
632// config->sync(); 637// config->sync();
633} 638}
634 639
635void KateDocument::readSessionConfig(KateConfig *config) 640void KateDocument::readSessionConfig(KateConfig *config)
636{ 641{
637 m_url = config->readEntry("URL"); // ### doesn't this break the encoding? (Simon) 642 m_url = config->readEntry("URL"); // ### doesn't this break the encoding? (Simon)
638 setHighlight(hlManager->nameFind(config->readEntry("Highlight"))); 643 setHighlight(hlManager->nameFind(config->readEntry("Highlight")));
639 // anders: restore bookmarks if possible 644 // anders: restore bookmarks if possible
640 QValueList<int> l = config->readIntListEntry("Bookmarks"); 645 QValueList<int> l = config->readIntListEntry("Bookmarks");
641 if ( l.count() ) { 646 if ( l.count() ) {
642 for (uint i=0; i < l.count(); i++) { 647 for (uint i=0; i < l.count(); i++) {
643 if ( numLines() < l[i] ) break; 648 if ( numLines() < l[i] ) break;
644 getTextLine( l[i] )->addMark( Bookmark ); 649 getTextLine( l[i] )->addMark( Bookmark );
645 } 650 }
646 } 651 }
647} 652}
648 653
649void KateDocument::writeSessionConfig(KateConfig *config) 654void KateDocument::writeSessionConfig(KateConfig *config)
650{ 655{
651#if 0 656#if 0
652 config->writeEntry("URL", m_url); // ### encoding?? (Simon) 657 config->writeEntry("URL", m_url); // ### encoding?? (Simon)
653 config->writeEntry("Highlight", m_highlight->name()); 658 config->writeEntry("Highlight", m_highlight->name());
654 // anders: save bookmarks 659 // anders: save bookmarks
655 QList<Kate::Mark> l = marks(); 660 QList<Kate::Mark> l = marks();
656 QValueList<int> ml; 661 QValueList<int> ml;
657 for (uint i=0; i < l.count(); i++) { 662 for (uint i=0; i < l.count(); i++) {
658 if ( l.at(i)->type == 1) // only save bookmarks 663 if ( l.at(i)->type == 1) // only save bookmarks
659 ml << l.at(i)->line; 664 ml << l.at(i)->line;
660 } 665 }
661 if ( ml.count() ) 666 if ( ml.count() )
662 config->writeEntry("Bookmarks", ml); 667 config->writeEntry("Bookmarks", ml);
663#endif 668#endif
664} 669}
665 670
666 671
667void KateDocument::setHighlight(int n) { 672void KateDocument::setHighlight(int n) {
668 Highlight *h; 673 Highlight *h;
669 674
670// hlNumber = n; 675// hlNumber = n;
671 676
672 h = hlManager->getHl(n); 677 h = hlManager->getHl(n);
673 if (h == m_highlight) { 678 if (h == m_highlight) {
674 updateLines(); 679 updateLines();
675 } else { 680 } else {
676 if (m_highlight != 0L) m_highlight->release(); 681 if (m_highlight != 0L) m_highlight->release();
677 h->use(); 682 h->use();
678 m_highlight = h; 683 m_highlight = h;
679 makeAttribs(); 684 makeAttribs();
680 } 685 }
681 PreHighlightedTill=0; 686 PreHighlightedTill=0;
682 RequestPreHighlightTill=0; 687 RequestPreHighlightTill=0;
683 emit(highlightChanged()); 688 emit(highlightChanged());
684} 689}
685 690
686void KateDocument::makeAttribs() { 691void KateDocument::makeAttribs() {
687 odebug << "KateDocument::makeAttribs()" << oendl; 692 odebug << "KateDocument::makeAttribs()" << oendl;
688 m_numAttribs = hlManager->makeAttribs(m_highlight, m_attribs, maxAttribs); 693 m_numAttribs = hlManager->makeAttribs(m_highlight, m_attribs, maxAttribs);
689 updateFontData(); 694 updateFontData();
690 updateLines(); 695 updateLines();
691} 696}
692 697
693void KateDocument::updateFontData() { 698void KateDocument::updateFontData() {
694 int maxAscent, maxDescent; 699 int maxAscent, maxDescent;
695 int tabWidth; 700 int tabWidth;
696 KateView *view; 701 KateView *view;
697 702
698 maxAscent = myFontMetrics.ascent(); 703 maxAscent = myFontMetrics.ascent();
699 maxDescent = myFontMetrics.descent(); 704 maxDescent = myFontMetrics.descent();
700 tabWidth = myFontMetrics.width(' '); 705 tabWidth = myFontMetrics.width(' ');
701 706
702 fontHeight = maxAscent + maxDescent + 1; 707 fontHeight = maxAscent + maxDescent + 1;
703 fontAscent = maxAscent; 708 fontAscent = maxAscent;
704 m_tabWidth = tabChars*tabWidth; 709 m_tabWidth = tabChars*tabWidth;
705 710
706 for (view = views.first(); view != 0L; view = views.next() ) { 711 for (view = views.first(); view != 0L; view = views.next() ) {
707 view->myViewInternal->drawBuffer->resize(view->width(),fontHeight); 712 view->myViewInternal->drawBuffer->resize(view->width(),fontHeight);
708 view->tagAll(); 713 view->tagAll();
709 view->updateCursor(); 714 view->updateCursor();
710 } 715 }
711} 716}
712 717
713void KateDocument::hlChanged() { //slot 718void KateDocument::hlChanged() { //slot
714 makeAttribs(); 719 makeAttribs();
715 updateViews(); 720 updateViews();
716} 721}
717 722
718 723
719void KateDocument::addView(KTextEditor::View *view) { 724void KateDocument::addView(KTextEditor::View *view) {
720 views.append( static_cast<KateView *>( view ) ); 725 views.append( static_cast<KateView *>( view ) );
721 KTextEditor::Document::addView( view ); 726 KTextEditor::Document::addView( view );
722 connect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) ); 727 connect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
723} 728}
724 729
725void KateDocument::removeView(KTextEditor::View *view) { 730void KateDocument::removeView(KTextEditor::View *view) {
726// if (undoView == view) recordReset(); 731// if (undoView == view) recordReset();
727 disconnect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) ); 732 disconnect( static_cast<KateView *>( view ), SIGNAL( destroyed() ), this, SLOT( slotViewDestroyed() ) );
728 views.removeRef( static_cast<KateView *>( view ) ); 733 views.removeRef( static_cast<KateView *>( view ) );
729 KTextEditor::Document::removeView( view ); 734 KTextEditor::Document::removeView( view );
730} 735}
731 736
732void KateDocument::slotViewDestroyed() 737void KateDocument::slotViewDestroyed()
733{ 738{
734 views.removeRef( static_cast<const KateView *>( sender() ) ); 739 views.removeRef( static_cast<const KateView *>( sender() ) );
735} 740}
736 741
737bool KateDocument::ownedView(KateView *view) { 742bool KateDocument::ownedView(KateView *view) {
738 // do we own the given view? 743 // do we own the given view?
739 return (views.containsRef(view) > 0); 744 return (views.containsRef(view) > 0);
740} 745}
741 746
742bool KateDocument::isLastView(int numViews) { 747bool KateDocument::isLastView(int numViews) {
743 return ((int) views.count() == numViews); 748 return ((int) views.count() == numViews);
744} 749}
745 750
746int KateDocument::textWidth(const TextLine::Ptr &textLine, int cursorX) { 751int KateDocument::textWidth(const TextLine::Ptr &textLine, int cursorX) {
747 int x; 752 int x;
748 int z; 753 int z;
749 QChar ch; 754 QChar ch;
750 Attribute *a; 755 Attribute *a;
751 756
752 x = 0; 757 x = 0;
753 for (z = 0; z < cursorX; z++) { 758 for (z = 0; z < cursorX; z++) {
754 ch = textLine->getChar(z); 759 ch = textLine->getChar(z);
755 a = &m_attribs[textLine->getAttr(z)]; 760 a = &m_attribs[textLine->getAttr(z)];
756 761
757 if (ch == '\t') 762 if (ch == '\t')
758 x += m_tabWidth - (x % m_tabWidth); 763 x += m_tabWidth - (x % m_tabWidth);
759 else if (a->bold && a->italic) 764 else if (a->bold && a->italic)
760 x += myFontMetricsBI.width(ch); 765 x += myFontMetricsBI.width(ch);
761 else if (a->bold) 766 else if (a->bold)
762 x += myFontMetricsBold.width(ch); 767 x += myFontMetricsBold.width(ch);
763 else if (a->italic) 768 else if (a->italic)
764 x += myFontMetricsItalic.width(ch); 769 x += myFontMetricsItalic.width(ch);
765 else 770 else
766 x += myFontMetrics.width(ch); 771 x += myFontMetrics.width(ch);
767 } 772 }
768 return x; 773 return x;
769} 774}
770 775
771int KateDocument::textWidth(PointStruc &cursor) { 776int KateDocument::textWidth(PointStruc &cursor) {
772 if (cursor.x < 0) 777 if (cursor.x < 0)
773 cursor.x = 0; 778 cursor.x = 0;
774 if (cursor.y < 0) 779 if (cursor.y < 0)
775 cursor.y = 0; 780 cursor.y = 0;
776 if (cursor.y >= numLines()) 781 if (cursor.y >= numLines())
777 cursor.y = lastLine(); 782 cursor.y = lastLine();
778 return textWidth(getTextLine(cursor.y),cursor.x); 783 return textWidth(getTextLine(cursor.y),cursor.x);
779} 784}
780 785
781int KateDocument::textWidth(bool wrapCursor, PointStruc &cursor, int xPos) { 786int KateDocument::textWidth(bool wrapCursor, PointStruc &cursor, int xPos) {
782 int len; 787 int len;
783 int x, oldX; 788 int x, oldX;
784 int z; 789 int z;
785 QChar ch; 790 QChar ch;
786 Attribute *a; 791 Attribute *a;
787 792
788 if (cursor.y < 0) cursor.y = 0; 793 if (cursor.y < 0) cursor.y = 0;
789 if (cursor.y > lastLine()) cursor.y = lastLine(); 794 if (cursor.y > lastLine()) cursor.y = lastLine();
790 TextLine::Ptr textLine = getTextLine(cursor.y); 795 TextLine::Ptr textLine = getTextLine(cursor.y);
791 len = textLine->length(); 796 len = textLine->length();
792 797
793 x = oldX = z = 0; 798 x = oldX = z = 0;
794 while (x < xPos && (!wrapCursor || z < len)) { 799 while (x < xPos && (!wrapCursor || z < len)) {
795 oldX = x; 800 oldX = x;
796 ch = textLine->getChar(z); 801 ch = textLine->getChar(z);
797 a = &m_attribs[textLine->getAttr(z)]; 802 a = &m_attribs[textLine->getAttr(z)];
798 803
799 if (ch == '\t') 804 if (ch == '\t')
800 x += m_tabWidth - (x % m_tabWidth); 805 x += m_tabWidth - (x % m_tabWidth);
801 else if (a->bold && a->italic) 806 else if (a->bold && a->italic)
802 x += myFontMetricsBI.width(ch); 807 x += myFontMetricsBI.width(ch);
803 else if (a->bold) 808 else if (a->bold)
804 x += myFontMetricsBold.width(ch); 809 x += myFontMetricsBold.width(ch);
805 else if (a->italic) 810 else if (a->italic)
806 x += myFontMetricsItalic.width(ch); 811 x += myFontMetricsItalic.width(ch);
807 else 812 else
808 x += myFontMetrics.width(ch); 813 x += myFontMetrics.width(ch);
809 814
810 z++; 815 z++;
811 } 816 }
812 if (xPos - oldX < x - xPos && z > 0) { 817 if (xPos - oldX < x - xPos && z > 0) {
813 z--; 818 z--;
814 x = oldX; 819 x = oldX;
815 } 820 }
816 cursor.x = z; 821 cursor.x = z;
817 return x; 822 return x;
818} 823}
819 824
820 825
821int KateDocument::textPos(const TextLine::Ptr &textLine, int xPos) { 826int KateDocument::textPos(const TextLine::Ptr &textLine, int xPos) {
822 int x, oldX; 827 int x, oldX;
823 int z; 828 int z;
824 QChar ch; 829 QChar ch;
825 Attribute *a; 830 Attribute *a;
826 831
827 x = oldX = z = 0; 832 x = oldX = z = 0;
828 while (x < xPos) { // && z < len) { 833 while (x < xPos) { // && z < len) {
829 oldX = x; 834 oldX = x;
830 ch = textLine->getChar(z); 835 ch = textLine->getChar(z);
831 a = &m_attribs[textLine->getAttr(z)]; 836 a = &m_attribs[textLine->getAttr(z)];
832 837
833 if (ch == '\t') 838 if (ch == '\t')
834 x += m_tabWidth - (x % m_tabWidth); 839 x += m_tabWidth - (x % m_tabWidth);
835 else if (a->bold && a->italic) 840 else if (a->bold && a->italic)
836 x += myFontMetricsBI.width(ch); 841 x += myFontMetricsBI.width(ch);
837 else if (a->bold) 842 else if (a->bold)
838 x += myFontMetricsBold.width(ch); 843 x += myFontMetricsBold.width(ch);
839 else if (a->italic) 844 else if (a->italic)
840 x += myFontMetricsItalic.width(ch); 845 x += myFontMetricsItalic.width(ch);
841 else 846 else
842 x += myFontMetrics.width(ch); 847 x += myFontMetrics.width(ch);
843 848
844 z++; 849 z++;
845 } 850 }
846 if (xPos - oldX < x - xPos && z > 0) { 851 if (xPos - oldX < x - xPos && z > 0) {
847 z--; 852 z--;
848 // newXPos = oldX; 853 // newXPos = oldX;
849 }// else newXPos = x; 854 }// else newXPos = x;
850 return z; 855 return z;
851} 856}
852 857
853int KateDocument::textWidth() { 858int KateDocument::textWidth() {
854 return int(maxLength + 8); 859 return int(maxLength + 8);
855} 860}
856 861
857int KateDocument::textHeight() { 862int KateDocument::textHeight() {
858 return numLines()*fontHeight; 863 return numLines()*fontHeight;
859} 864}
860 865
861void KateDocument::insert(VConfig &c, const QString &s) { 866void KateDocument::insert(VConfig &c, const QString &s) {
862 int pos; 867 int pos;
863 QChar ch; 868 QChar ch;
864 QString buf; 869 QString buf;
865 870
866 if (s.isEmpty()) return; 871 if (s.isEmpty()) return;
867 872
868 recordStart(c, KateActionGroup::ugPaste); 873 recordStart(c, KateActionGroup::ugPaste);
869 874
870 pos = 0; 875 pos = 0;
871 if (!(c.flags & KateView::cfVerticalSelect)) { 876 if (!(c.flags & KateView::cfVerticalSelect)) {
872 do { 877 do {
873 ch = s[pos]; 878 ch = s[pos];
874 if (ch.isPrint() || ch == '\t') { 879 if (ch.isPrint() || ch == '\t') {
875 buf += ch; // append char to buffer 880 buf += ch; // append char to buffer
876 } else if (ch == '\n') { 881 } else if (ch == '\n') {
877 recordAction(KateAction::newLine, c.cursor); // wrap contents behind cursor to new line 882 recordAction(KateAction::newLine, c.cursor); // wrap contents behind cursor to new line
878 recordInsert(c, buf); // append to old line 883 recordInsert(c, buf); // append to old line
879// c.cursor.x += buf.length(); 884// c.cursor.x += buf.length();
880 buf.truncate(0); // clear buffer 885 buf.truncate(0); // clear buffer
881 c.cursor.y++; 886 c.cursor.y++;
882 c.cursor.x = 0; 887 c.cursor.x = 0;
883 } 888 }
884 pos++; 889 pos++;
885 } while (pos < (int) s.length()); 890 } while (pos < (int) s.length());
886 } else { 891 } else {
887 int xPos; 892 int xPos;
888 893
889 xPos = textWidth(c.cursor); 894 xPos = textWidth(c.cursor);
890 do { 895 do {
891 ch = s[pos]; 896 ch = s[pos];
892 if (ch.isPrint() || ch == '\t') { 897 if (ch.isPrint() || ch == '\t') {
893 buf += ch; 898 buf += ch;
894 } else if (ch == '\n') { 899 } else if (ch == '\n') {
895 recordInsert(c, buf); 900 recordInsert(c, buf);
896 c.cursor.x += buf.length(); 901 c.cursor.x += buf.length();
897 buf.truncate(0); 902 buf.truncate(0);
898 c.cursor.y++; 903 c.cursor.y++;
899 if (c.cursor.y >= numLines()) 904 if (c.cursor.y >= numLines())
900 recordAction(KateAction::insLine, c.cursor); 905 recordAction(KateAction::insLine, c.cursor);
901 c.cursor.x = textPos(getTextLine(c.cursor.y), xPos); 906 c.cursor.x = textPos(getTextLine(c.cursor.y), xPos);
902 } 907 }
903 pos++; 908 pos++;
904 } while (pos < (int) s.length()); 909 } while (pos < (int) s.length());
905 } 910 }
906 recordInsert(c, buf); 911 recordInsert(c, buf);
907 c.cursor.x += buf.length(); 912 c.cursor.x += buf.length();
908 recordEnd(c); 913 recordEnd(c);
909} 914}
910 915
911void KateDocument::insertFile(VConfig &c, QIODevice &dev) 916void KateDocument::insertFile(VConfig &c, QIODevice &dev)
912{ 917{
913 recordStart(c, KateActionGroup::ugPaste); 918 recordStart(c, KateActionGroup::ugPaste);
914 919
915 QString buf; 920 QString buf;
916 QChar ch, last; 921 QChar ch, last;
917 922
918 QTextStream stream( &dev ); 923 QTextStream stream( &dev );
919 924
920 while ( !stream.atEnd() ) { 925 while ( !stream.atEnd() ) {
921 stream >> ch; 926 stream >> ch;
922 927
923 if (ch.isPrint() || ch == '\t') { 928 if (ch.isPrint() || ch == '\t') {
924 buf += ch; 929 buf += ch;
925 } else if (ch == '\n' || ch == '\r') { 930 } else if (ch == '\n' || ch == '\r') {
926 if (last != '\r' || ch != '\n') { 931 if (last != '\r' || ch != '\n') {
927 recordAction(KateAction::newLine, c.cursor); 932 recordAction(KateAction::newLine, c.cursor);
928 recordInsert(c, buf); 933 recordInsert(c, buf);
929 buf.truncate(0); 934 buf.truncate(0);
930 c.cursor.y++; 935 c.cursor.y++;
931 c.cursor.x = 0; 936 c.cursor.x = 0;
932 } 937 }
933 last = ch; 938 last = ch;
934 } 939 }
935 } 940 }
936 941
937 recordInsert(c, buf); 942 recordInsert(c, buf);
938 recordEnd(c); 943 recordEnd(c);
939} 944}
940 945
941int KateDocument::currentColumn(PointStruc &cursor) { 946int KateDocument::currentColumn(PointStruc &cursor) {
942 return getTextLine(cursor.y)->cursorX(cursor.x,tabChars); 947 return getTextLine(cursor.y)->cursorX(cursor.x,tabChars);
943} 948}
944 949
945bool KateDocument::insertChars(VConfig &c, const QString &chars) { 950bool KateDocument::insertChars(VConfig &c, const QString &chars) {
946 int z, pos, l; 951 int z, pos, l;
947 bool onlySpaces; 952 bool onlySpaces;
948 QChar ch; 953 QChar ch;
949 QString buf; 954 QString buf;
950 955
951 TextLine::Ptr textLine = getTextLine(c.cursor.y); 956 TextLine::Ptr textLine = getTextLine(c.cursor.y);
952 957
953 pos = 0; 958 pos = 0;
954 onlySpaces = true; 959 onlySpaces = true;
955 for (z = 0; z < (int) chars.length(); z++) { 960 for (z = 0; z < (int) chars.length(); z++) {
956 ch = chars[z]; 961 ch = chars[z];
957 if (ch == '\t' && c.flags & KateView::cfReplaceTabs) { 962 if (ch == '\t' && c.flags & KateView::cfReplaceTabs) {
958 l = tabChars - (textLine->cursorX(c.cursor.x, tabChars) % tabChars); 963 l = tabChars - (textLine->cursorX(c.cursor.x, tabChars) % tabChars);
959 while (l > 0) { 964 while (l > 0) {
960 buf.insert(pos, ' '); 965 buf.insert(pos, ' ');
961 pos++; 966 pos++;
962 l--; 967 l--;
963 } 968 }
964 } else if (ch.isPrint() || ch == '\t') { 969 } else if (ch.isPrint() || ch == '\t') {
965 buf.insert(pos, ch); 970 buf.insert(pos, ch);
966 pos++; 971 pos++;
967 if (ch != ' ') onlySpaces = false; 972 if (ch != ' ') onlySpaces = false;
968 if (c.flags & KateView::cfAutoBrackets) { 973 if (c.flags & KateView::cfAutoBrackets) {
969 if (ch == '(') buf.insert(pos, ')'); 974 if (ch == '(') buf.insert(pos, ')');
970 if (ch == '[') buf.insert(pos, ']'); 975 if (ch == '[') buf.insert(pos, ']');
971 if (ch == '{') buf.insert(pos, '}'); 976 if (ch == '{') buf.insert(pos, '}');
972 } 977 }
973 } 978 }
974 } 979 }
975 //pos = cursor increment 980 //pos = cursor increment
976 981
977 //return false if nothing has to be inserted 982 //return false if nothing has to be inserted
978 if (buf.isEmpty()) return false; 983 if (buf.isEmpty()) return false;
979 984
980 //auto deletion of the marked text occurs not very often and can therefore 985 //auto deletion of the marked text occurs not very often and can therefore
981 // be recorded separately 986 // be recorded separately
982 if (c.flags &KateView:: cfDelOnInput) delMarkedText(c); 987 if (c.flags &KateView:: cfDelOnInput) delMarkedText(c);
983 988
984 recordStart(c, KateActionGroup::ugInsChar); 989 recordStart(c, KateActionGroup::ugInsChar);
985 recordReplace(c/*.cursor*/, (c.flags & KateView::cfOvr) ? buf.length() : 0, buf); 990 recordReplace(c/*.cursor*/, (c.flags & KateView::cfOvr) ? buf.length() : 0, buf);
986 c.cursor.x += pos; 991 c.cursor.x += pos;
987 992
988 if (myWordWrap && myWordWrapAt > 0) { 993 if (myWordWrap && myWordWrapAt > 0) {
989 int line; 994 int line;
990 const QChar *s; 995 const QChar *s;
991// int pos; 996// int pos;
992 PointStruc actionCursor; 997 PointStruc actionCursor;
993 998
994 line = c.cursor.y; 999 line = c.cursor.y;
995 do { 1000 do {
996 textLine = getTextLine(line); 1001 textLine = getTextLine(line);
997 s = textLine->getText(); 1002 s = textLine->getText();
998 l = textLine->length(); 1003 l = textLine->length();
999 for (z = myWordWrapAt; z < l; z++) if (!s[z].isSpace()) break; //search for text to wrap 1004 for (z = myWordWrapAt; z < l; z++) if (!s[z].isSpace()) break; //search for text to wrap
1000 if (z >= l) break; // nothing more to wrap 1005 if (z >= l) break; // nothing more to wrap
1001 pos = myWordWrapAt; 1006 pos = myWordWrapAt;
1002 for (; z >= 0; z--) { //find wrap position 1007 for (; z >= 0; z--) { //find wrap position
1003 if (s[z].isSpace()) { 1008 if (s[z].isSpace()) {
1004 pos = z + 1; 1009 pos = z + 1;
1005 break; 1010 break;
1006 } 1011 }
1007 } 1012 }
1008 //pos = wrap position 1013 //pos = wrap position
1009 1014
1010 if (line == c.cursor.y && pos <= c.cursor.x) { 1015 if (line == c.cursor.y && pos <= c.cursor.x) {
1011 //wrap cursor 1016 //wrap cursor
1012 c.cursor.y++; 1017 c.cursor.y++;
1013 c.cursor.x -= pos; 1018 c.cursor.x -= pos;
1014 } 1019 }
1015 1020
1016 if (line == lastLine() || (getTextLine(line+1)->length() == 0) ) { 1021 if (line == lastLine() || (getTextLine(line+1)->length() == 0) ) {
1017 //at end of doc: create new line 1022 //at end of doc: create new line
1018 actionCursor.x = pos; 1023 actionCursor.x = pos;
1019 actionCursor.y = line; 1024 actionCursor.y = line;
1020 recordAction(KateAction::newLine,actionCursor); 1025 recordAction(KateAction::newLine,actionCursor);
1021 } else { 1026 } else {
1022 //wrap 1027 //wrap
1023 actionCursor.y = line + 1; 1028 actionCursor.y = line + 1;
1024 if (!s[l - 1].isSpace()) { //add space in next line if necessary 1029 if (!s[l - 1].isSpace()) { //add space in next line if necessary
1025 actionCursor.x = 0; 1030 actionCursor.x = 0;
1026 recordInsert(actionCursor, " "); 1031 recordInsert(actionCursor, " ");
1027 } 1032 }
1028 actionCursor.x = textLine->length() - pos; 1033 actionCursor.x = textLine->length() - pos;
1029 recordAction(KateAction::wordWrap, actionCursor); 1034 recordAction(KateAction::wordWrap, actionCursor);
1030 } 1035 }
1031 line++; 1036 line++;
1032 } while (true); 1037 } while (true);
1033 } 1038 }
1034 recordEnd(c); 1039 recordEnd(c);
1035 return true; 1040 return true;
1036} 1041}
1037 1042
1038QString tabString(int pos, int tabChars) { 1043QString tabString(int pos, int tabChars) {
1039 QString s; 1044 QString s;
1040 while (pos >= tabChars) { 1045 while (pos >= tabChars) {
1041 s += '\t'; 1046 s += '\t';
1042 pos -= tabChars; 1047 pos -= tabChars;
1043 } 1048 }
1044 while (pos > 0) { 1049 while (pos > 0) {
1045 s += ' '; 1050 s += ' ';
1046 pos--; 1051 pos--;
1047 } 1052 }
1048 return s; 1053 return s;
1049} 1054}
1050 1055
1051void KateDocument::newLine(VConfig &c) { 1056void KateDocument::newLine(VConfig &c) {
1052 1057
1053 //auto deletion of marked text is done by the view to have a more 1058 //auto deletion of marked text is done by the view to have a more
1054 // "low level" KateDocument::newLine method 1059 // "low level" KateDocument::newLine method
1055 recordStart(c, KateActionGroup::ugInsLine); 1060 recordStart(c, KateActionGroup::ugInsLine);
1056 1061
1057 if (!(c.flags & KateView::cfAutoIndent)) { 1062 if (!(c.flags & KateView::cfAutoIndent)) {
1058 recordAction(KateAction::newLine,c.cursor); 1063 recordAction(KateAction::newLine,c.cursor);
1059 c.cursor.y++; 1064 c.cursor.y++;
1060 c.cursor.x = 0; 1065 c.cursor.x = 0;
1061 } else { 1066 } else {
1062 TextLine::Ptr textLine = getTextLine(c.cursor.y); 1067 TextLine::Ptr textLine = getTextLine(c.cursor.y);
1063 int pos = textLine->firstChar(); 1068 int pos = textLine->firstChar();
1064 if (c.cursor.x < pos) c.cursor.x = pos; // place cursor on first char if before 1069 if (c.cursor.x < pos) c.cursor.x = pos; // place cursor on first char if before
1065 1070
1066 int y = c.cursor.y; 1071 int y = c.cursor.y;
1067 while ((y > 0) && (pos < 0)) { // search a not empty text line 1072 while ((y > 0) && (pos < 0)) { // search a not empty text line
1068 textLine = getTextLine(--y); 1073 textLine = getTextLine(--y);
1069 pos = textLine->firstChar(); 1074 pos = textLine->firstChar();
1070 } 1075 }
1071 recordAction(KateAction::newLine, c.cursor); 1076 recordAction(KateAction::newLine, c.cursor);
1072 c.cursor.y++; 1077 c.cursor.y++;
1073 c.cursor.x = 0; 1078 c.cursor.x = 0;
1074 if (pos > 0) { 1079 if (pos > 0) {
1075 pos = textLine->cursorX(pos, tabChars); 1080 pos = textLine->cursorX(pos, tabChars);
1076// if (getTextLine(c.cursor.y)->length() > 0) { 1081// if (getTextLine(c.cursor.y)->length() > 0) {
1077 QString s = tabString(pos, (c.flags & KateView::cfSpaceIndent) ? 0xffffff : tabChars); 1082 QString s = tabString(pos, (c.flags & KateView::cfSpaceIndent) ? 0xffffff : tabChars);
1078 recordInsert(c.cursor, s); 1083 recordInsert(c.cursor, s);
1079 pos = s.length(); 1084 pos = s.length();
1080// } 1085// }
1081// recordInsert(c.cursor, QString(textLine->getText(), pos)); 1086// recordInsert(c.cursor, QString(textLine->getText(), pos));
1082 c.cursor.x = pos; 1087 c.cursor.x = pos;
1083 } 1088 }
1084 } 1089 }
1085 1090
1086 recordEnd(c); 1091 recordEnd(c);
1087} 1092}
1088 1093
1089void KateDocument::killLine(VConfig &c) { 1094void KateDocument::killLine(VConfig &c) {
1090 1095
1091 recordStart(c, KateActionGroup::ugDelLine); 1096 recordStart(c, KateActionGroup::ugDelLine);
1092 c.cursor.x = 0; 1097 c.cursor.x = 0;
1093 recordDelete(c.cursor, 0xffffff); 1098 recordDelete(c.cursor, 0xffffff);
1094 if (c.cursor.y < lastLine()) { 1099 if (c.cursor.y < lastLine()) {
1095 recordAction(KateAction::killLine, c.cursor); 1100 recordAction(KateAction::killLine, c.cursor);
1096 } 1101 }
1097 recordEnd(c); 1102 recordEnd(c);
1098} 1103}
1099 1104
1100void KateDocument::backspace(VConfig &c) { 1105void KateDocument::backspace(VConfig &c) {
1101 1106
1102 if (c.cursor.x <= 0 && c.cursor.y <= 0) return; 1107 if (c.cursor.x <= 0 && c.cursor.y <= 0) return;
1103 1108
1104 if (c.cursor.x > 0) { 1109 if (c.cursor.x > 0) {
1105 recordStart(c, KateActionGroup::ugDelChar); 1110 recordStart(c, KateActionGroup::ugDelChar);
1106 if (!(c.flags & KateView::cfBackspaceIndents)) { 1111 if (!(c.flags & KateView::cfBackspaceIndents)) {
1107 // ordinary backspace 1112 // ordinary backspace
1108 c.cursor.x--; 1113 c.cursor.x--;
1109 recordDelete(c.cursor, 1); 1114 recordDelete(c.cursor, 1);
1110 } else { 1115 } else {
1111 // backspace indents: erase to next indent position 1116 // backspace indents: erase to next indent position
1112 int l = 1; // del one char 1117 int l = 1; // del one char
1113 1118
1114 TextLine::Ptr textLine = getTextLine(c.cursor.y); 1119 TextLine::Ptr textLine = getTextLine(c.cursor.y);
1115 int pos = textLine->firstChar(); 1120 int pos = textLine->firstChar();
1116 if (pos < 0 || pos >= c.cursor.x) { 1121 if (pos < 0 || pos >= c.cursor.x) {
1117 // only spaces on left side of cursor 1122 // only spaces on left side of cursor
1118 // search a line with less spaces 1123 // search a line with less spaces
1119 int y = c.cursor.y; 1124 int y = c.cursor.y;
1120 while (y > 0) { 1125 while (y > 0) {
1121 textLine = getTextLine(--y); 1126 textLine = getTextLine(--y);
1122 pos = textLine->firstChar(); 1127 pos = textLine->firstChar();
1123 if (pos >= 0 && pos < c.cursor.x) { 1128 if (pos >= 0 && pos < c.cursor.x) {
1124 l = c.cursor.x - pos; // del more chars 1129 l = c.cursor.x - pos; // del more chars
1125 break; 1130 break;
1126 } 1131 }
1127 } 1132 }
1128 } 1133 }
1129 // break effectively jumps here 1134 // break effectively jumps here
1130 c.cursor.x -= l; 1135 c.cursor.x -= l;
1131 recordDelete(c.cursor, l); 1136 recordDelete(c.cursor, l);
1132 } 1137 }
1133 } else { 1138 } else {
1134 // c.cursor.x == 0: wrap to previous line 1139 // c.cursor.x == 0: wrap to previous line
1135 recordStart(c, KateActionGroup::ugDelLine); 1140 recordStart(c, KateActionGroup::ugDelLine);
1136 c.cursor.y--; 1141 c.cursor.y--;
1137 c.cursor.x = getTextLine(c.cursor.y)->length(); 1142 c.cursor.x = getTextLine(c.cursor.y)->length();
1138 recordAction(KateAction::delLine,c.cursor); 1143 recordAction(KateAction::delLine,c.cursor);
1139 } 1144 }
1140 recordEnd(c); 1145 recordEnd(c);
1141} 1146}
1142 1147
1143 1148
1144void KateDocument::del(VConfig &c) { 1149void KateDocument::del(VConfig &c) {
1145 TextLine::Ptr textLine = getTextLine(c.cursor.y); 1150 TextLine::Ptr textLine = getTextLine(c.cursor.y);
1146 int len = (c.flags & KateView::cfRemoveSpaces) ? textLine->lastChar() : textLine->length(); 1151 int len = (c.flags & KateView::cfRemoveSpaces) ? textLine->lastChar() : textLine->length();
1147 if (c.cursor.x < len/*getTextLine(c.cursor.y)->length()*/) { 1152 if (c.cursor.x < len/*getTextLine(c.cursor.y)->length()*/) {
1148 // delete one character 1153 // delete one character
1149 recordStart(c, KateActionGroup::ugDelChar); 1154 recordStart(c, KateActionGroup::ugDelChar);
1150 recordDelete(c.cursor, 1); 1155 recordDelete(c.cursor, 1);
1151 recordEnd(c); 1156 recordEnd(c);
1152 } else { 1157 } else {
1153 if (c.cursor.y < lastLine()) { 1158 if (c.cursor.y < lastLine()) {
1154 // wrap next line to this line 1159 // wrap next line to this line
1155 textLine->truncate(c.cursor.x); // truncate spaces 1160 textLine->truncate(c.cursor.x); // truncate spaces
1156 recordStart(c, KateActionGroup::ugDelLine); 1161 recordStart(c, KateActionGroup::ugDelLine);
1157 recordAction(KateAction::delLine,c.cursor); 1162 recordAction(KateAction::delLine,c.cursor);
1158 recordEnd(c); 1163 recordEnd(c);
1159 } 1164 }
1160 } 1165 }
1161} 1166}
1162 1167
1163void KateDocument::clear() { 1168void KateDocument::clear() {
1164 PointStruc cursor; 1169 PointStruc cursor;
1165 KateView *view; 1170 KateView *view;
1166 1171
1167 setPseudoModal(0L); 1172 setPseudoModal(0L);
1168 cursor.x = cursor.y = 0; 1173 cursor.x = cursor.y = 0;
1169 for (view = views.first(); view != 0L; view = views.next() ) { 1174 for (view = views.first(); view != 0L; view = views.next() ) {
1170 view->updateCursor(cursor); 1175 view->updateCursor(cursor);
1171 view->tagAll(); 1176 view->tagAll();
1172 } 1177 }
1173 1178
1174 eolMode = KateDocument::eolUnix; 1179 eolMode = KateDocument::eolUnix;
1175 1180
1176 buffer->clear(); 1181 buffer->clear();
1177 longestLine = buffer->line(0); 1182 longestLine = buffer->line(0);
1178 1183
1179 maxLength = 0; 1184 maxLength = 0;
1180 1185
1181 select.x = -1; 1186 select.x = -1;
1182 1187
1183 selectStart = 0xffffff; 1188 selectStart = 0xffffff;
1184 selectEnd = 0; 1189 selectEnd = 0;
1185 oldMarkState = false; 1190 oldMarkState = false;
1186 1191
1187 setModified(false); 1192 setModified(false);
1188 1193
1189 undoList.clear(); 1194 undoList.clear();
1190 currentUndo = 0; 1195 currentUndo = 0;
1191 newUndo(); 1196 newUndo();
1192} 1197}
1193 1198
1194void KateDocument::cut(VConfig &c) { 1199void KateDocument::cut(VConfig &c) {
1195 1200
1196 if (selectEnd < selectStart) return; 1201 if (selectEnd < selectStart) return;
1197 1202
1198 copy(c.flags); 1203 copy(c.flags);
1199 delMarkedText(c); 1204 delMarkedText(c);
1200} 1205}
1201 1206
1202void KateDocument::copy(int flags) { 1207void KateDocument::copy(int flags) {
1203 1208
1204 if (selectEnd < selectStart) return; 1209 if (selectEnd < selectStart) return;
1205 1210
1206 QString s = markedText(flags); 1211 QString s = markedText(flags);
1207 if (!s.isEmpty()) { 1212 if (!s.isEmpty()) {
1208//#if defined(_WS_X11_) 1213//#if defined(_WS_X11_)
1209 if (m_singleSelection) 1214 if (m_singleSelection)
1210 disconnect(QApplication::clipboard(), SIGNAL(dataChanged()), this, 0); 1215 disconnect(QApplication::clipboard(), SIGNAL(dataChanged()), this, 0);
1211//#endif 1216//#endif
1212 QApplication::clipboard()->setText(s); 1217 QApplication::clipboard()->setText(s);
1213//#if defined(_WS_X11_) 1218//#if defined(_WS_X11_)
1214 if (m_singleSelection) { 1219 if (m_singleSelection) {
1215 connect(QApplication::clipboard(), SIGNAL(dataChanged()), 1220 connect(QApplication::clipboard(), SIGNAL(dataChanged()),
1216 this, SLOT(clipboardChanged())); 1221 this, SLOT(clipboardChanged()));
1217 } 1222 }
1218//#endif 1223//#endif
1219 } 1224 }
1220} 1225}
1221 1226
1222void KateDocument::paste(VConfig &c) { 1227void KateDocument::paste(VConfig &c) {
1223 QString s = QApplication::clipboard()->text(); 1228 QString s = QApplication::clipboard()->text();
1224 if (!s.isEmpty()) { 1229 if (!s.isEmpty()) {
1225 insert(c, s); 1230 insert(c, s);
1226 } 1231 }
1227} 1232}
1228 1233
1229void KateDocument::toggleRect(int start, int end, int x1, int x2) { 1234void KateDocument::toggleRect(int start, int end, int x1, int x2) {
1230 int z, line; 1235 int z, line;
1231 bool t; 1236 bool t;
1232 1237
1233 if (x1 > x2) { 1238 if (x1 > x2) {
1234 z = x1; 1239 z = x1;
1235 x1 = x2; 1240 x1 = x2;
1236 x2 = z; 1241 x2 = z;
1237 } 1242 }
1238 if (start > end) { 1243 if (start > end) {
1239 z = start; 1244 z = start;
1240 start = end; 1245 start = end;
1241 end = z; 1246 end = z;
1242 } 1247 }
1243 1248
1244 t = false; 1249 t = false;
1245 for (line = start; line < end; line++) { 1250 for (line = start; line < end; line++) {
1246 int x, oldX, s, e, newX1, newX2; 1251 int x, oldX, s, e, newX1, newX2;
1247 QChar ch; 1252 QChar ch;
1248 Attribute *a; 1253 Attribute *a;
1249 1254
1250 TextLine::Ptr textLine = getTextLine(line); 1255 TextLine::Ptr textLine = getTextLine(line);
1251 1256
1252 //--- speed optimization 1257 //--- speed optimization
1253 //s = textPos(textLine, x1, newX1); 1258 //s = textPos(textLine, x1, newX1);
1254 x = oldX = z = 0; 1259 x = oldX = z = 0;
1255 while (x < x1) { // && z < len) { 1260 while (x < x1) { // && z < len) {
1256 oldX = x; 1261 oldX = x;
1257 ch = textLine->getChar(z); 1262 ch = textLine->getChar(z);
1258 a = &m_attribs[textLine->getAttr(z)]; 1263 a = &m_attribs[textLine->getAttr(z)];
1259 1264
1260 if (ch == '\t') 1265 if (ch == '\t')
1261 x += m_tabWidth - (x % m_tabWidth); 1266 x += m_tabWidth - (x % m_tabWidth);
1262 else if (a->bold && a->italic) 1267 else if (a->bold && a->italic)
1263 x += myFontMetricsBI.width(ch); 1268 x += myFontMetricsBI.width(ch);
1264 else if (a->bold) 1269 else if (a->bold)
1265 x += myFontMetricsBold.width(ch); 1270 x += myFontMetricsBold.width(ch);
1266 else if (a->italic) 1271 else if (a->italic)
1267 x += myFontMetricsItalic.width(ch); 1272 x += myFontMetricsItalic.width(ch);
1268 else 1273 else
1269 x += myFontMetrics.width(ch); 1274 x += myFontMetrics.width(ch);
1270 1275
1271 z++; 1276 z++;
1272 } 1277 }
1273 s = z; 1278 s = z;
1274 if (x1 - oldX < x - x1 && z > 0) { 1279 if (x1 - oldX < x - x1 && z > 0) {
1275 s--; 1280 s--;
1276 newX1 = oldX; 1281 newX1 = oldX;
1277 } else newX1 = x; 1282 } else newX1 = x;
1278 //e = textPos(textLine, x2, newX2); 1283 //e = textPos(textLine, x2, newX2);
1279 while (x < x2) { // && z < len) { 1284 while (x < x2) { // && z < len) {
1280 oldX = x; 1285 oldX = x;
1281 ch = textLine->getChar(z); 1286 ch = textLine->getChar(z);
1282 a = &m_attribs[textLine->getAttr(z)]; 1287 a = &m_attribs[textLine->getAttr(z)];
1283 1288
1284 if (ch == '\t') 1289 if (ch == '\t')
1285 x += m_tabWidth - (x % m_tabWidth); 1290 x += m_tabWidth - (x % m_tabWidth);
1286 else if (a->bold && a->italic) 1291 else if (a->bold && a->italic)
1287 x += myFontMetricsBI.width(ch); 1292 x += myFontMetricsBI.width(ch);
1288 else if (a->bold) 1293 else if (a->bold)
1289 x += myFontMetricsBold.width(ch); 1294 x += myFontMetricsBold.width(ch);
1290 else if (a->italic) 1295 else if (a->italic)
1291 x += myFontMetricsItalic.width(ch); 1296 x += myFontMetricsItalic.width(ch);
1292 else 1297 else
1293 x += myFontMetrics.width(ch); 1298 x += myFontMetrics.width(ch);
1294 1299
1295 z++; 1300 z++;
1296 } 1301 }
1297 e = z; 1302 e = z;
1298 if (x2 - oldX < x - x2 && z > 0) { 1303 if (x2 - oldX < x - x2 && z > 0) {
1299 e--; 1304 e--;
1300 newX2 = oldX; 1305 newX2 = oldX;
1301 } else newX2 = x; 1306 } else newX2 = x;
1302 //--- 1307 //---
1303 1308
1304 if (e > s) { 1309 if (e > s) {
1305 textLine->toggleSelect(s, e); 1310 textLine->toggleSelect(s, e);
1306 tagLineRange(line, newX1, newX2); 1311 tagLineRange(line, newX1, newX2);
1307 t = true; 1312 t = true;
1308 } 1313 }
1309 } 1314 }
1310 if (t) { 1315 if (t) {
1311 end--; 1316 end--;
1312// tagLines(start, end); 1317// tagLines(start, end);
1313 1318
1314 if (start < selectStart) selectStart = start; 1319 if (start < selectStart) selectStart = start;
1315 if (end > selectEnd) selectEnd = end; 1320 if (end > selectEnd) selectEnd = end;
1316 emit selectionChanged(); 1321 emit selectionChanged();
1317 } 1322 }
1318} 1323}
1319 1324
1320void KateDocument::selectTo(VConfig &c, PointStruc &cursor, int cXPos) { 1325void KateDocument::selectTo(VConfig &c, PointStruc &cursor, int cXPos) {
1321 //c.cursor = old cursor position 1326 //c.cursor = old cursor position
1322 //cursor = new cursor position 1327 //cursor = new cursor position
1323 1328
1324 if (c.cursor.x != select.x || c.cursor.y != select.y) { 1329 if (c.cursor.x != select.x || c.cursor.y != select.y) {
1325 //new selection 1330 //new selection
1326 1331
1327 if (!(c.flags & KateView::cfKeepSelection)) deselectAll(); 1332 if (!(c.flags & KateView::cfKeepSelection)) deselectAll();
1328// else recordReset(); 1333// else recordReset();
1329 1334
1330 anchor = c.cursor; 1335 anchor = c.cursor;
1331 aXPos = c.cXPos; 1336 aXPos = c.cXPos;
1332 } 1337 }
1333 1338
1334 if (!(c.flags & KateView::cfVerticalSelect)) { 1339 if (!(c.flags & KateView::cfVerticalSelect)) {
1335 //horizontal selections 1340 //horizontal selections
1336 int x, y, sXPos; 1341 int x, y, sXPos;
1337 int ex, ey, eXPos; 1342 int ex, ey, eXPos;
1338 bool sel; 1343 bool sel;
1339 1344
1340 if (cursor.y > c.cursor.y || (cursor.y == c.cursor.y && cursor.x > c.cursor.x)) { 1345 if (cursor.y > c.cursor.y || (cursor.y == c.cursor.y && cursor.x > c.cursor.x)) {
1341 x = c.cursor.x; 1346 x = c.cursor.x;
1342 y = c.cursor.y; 1347 y = c.cursor.y;
1343 sXPos = c.cXPos; 1348 sXPos = c.cXPos;
1344 ex = cursor.x; 1349 ex = cursor.x;
1345 ey = cursor.y; 1350 ey = cursor.y;
1346 eXPos = cXPos; 1351 eXPos = cXPos;
1347 sel = true; 1352 sel = true;
1348 } else { 1353 } else {
1349 x = cursor.x; 1354 x = cursor.x;
1350 y = cursor.y; 1355 y = cursor.y;
1351 sXPos = cXPos; 1356 sXPos = cXPos;
1352 ex = c.cursor.x; 1357 ex = c.cursor.x;
1353 ey = c.cursor.y; 1358 ey = c.cursor.y;
1354 eXPos = c.cXPos; 1359 eXPos = c.cXPos;
1355 sel = false; 1360 sel = false;
1356 } 1361 }
1357 1362
1358// tagLines(y, ye); 1363// tagLines(y, ye);
1359 if (y < ey) { 1364 if (y < ey) {
1360 //tagLineRange(y, sXPos, 0xffffff); 1365 //tagLineRange(y, sXPos, 0xffffff);
1361 tagLines(y, ey -1); 1366 tagLines(y, ey -1);
1362 tagLineRange(ey, 0, eXPos); 1367 tagLineRange(ey, 0, eXPos);
1363 } else tagLineRange(y, sXPos, eXPos); 1368 } else tagLineRange(y, sXPos, eXPos);
1364 1369
1365 if (y < selectStart) selectStart = y; 1370 if (y < selectStart) selectStart = y;
1366 if (ey > selectEnd) selectEnd = ey; 1371 if (ey > selectEnd) selectEnd = ey;
1367 1372
1368 TextLine::Ptr textLine = getTextLine(y); 1373 TextLine::Ptr textLine = getTextLine(y);
1369 1374
1370 if (c.flags & KateView::cfXorSelect) { 1375 if (c.flags & KateView::cfXorSelect) {
1371 //xor selection with old selection 1376 //xor selection with old selection
1372 while (y < ey) { 1377 while (y < ey) {
1373 textLine->toggleSelectEol(x); 1378 textLine->toggleSelectEol(x);
1374 x = 0; 1379 x = 0;
1375 y++; 1380 y++;
1376 textLine = getTextLine(y); 1381 textLine = getTextLine(y);
1377 } 1382 }
1378 textLine->toggleSelect(x, ex); 1383 textLine->toggleSelect(x, ex);
1379 } else { 1384 } else {
1380 //set selection over old selection 1385 //set selection over old selection
1381 1386
1382 if (anchor.y > y || (anchor.y == y && anchor.x > x)) { 1387 if (anchor.y > y || (anchor.y == y && anchor.x > x)) {
1383 if (anchor.y < ey || (anchor.y == ey && anchor.x < ex)) { 1388 if (anchor.y < ey || (anchor.y == ey && anchor.x < ex)) {
1384 sel = !sel; 1389 sel = !sel;
1385 while (y < anchor.y) { 1390 while (y < anchor.y) {
1386 textLine->selectEol(sel, x); 1391 textLine->selectEol(sel, x);
1387 x = 0; 1392 x = 0;
1388 y++; 1393 y++;
1389 textLine = getTextLine(y); 1394 textLine = getTextLine(y);
1390 } 1395 }
1391 textLine->select(sel, x, anchor.x); 1396 textLine->select(sel, x, anchor.x);
1392 x = anchor.x; 1397 x = anchor.x;
1393 } 1398 }
1394 sel = !sel; 1399 sel = !sel;
1395 } 1400 }
1396 while (y < ey) { 1401 while (y < ey) {
1397 textLine->selectEol(sel, x); 1402 textLine->selectEol(sel, x);
1398 x = 0; 1403 x = 0;
1399 y++; 1404 y++;
1400 textLine = getTextLine(y); 1405 textLine = getTextLine(y);
1401 } 1406 }
1402 textLine->select(sel, x, ex); 1407 textLine->select(sel, x, ex);
1403 } 1408 }
1404 } else { 1409 } else {
1405 //vertical (block) selections 1410 //vertical (block) selections
1406// int ax, sx, ex; 1411// int ax, sx, ex;
1407 1412
1408// ax = textWidth(anchor); 1413// ax = textWidth(anchor);
1409// sx = textWidth(start); 1414// sx = textWidth(start);
1410// ex = textWidth(end); 1415// ex = textWidth(end);
1411 1416
1412 toggleRect(c.cursor.y + 1, cursor.y + 1, aXPos, c.cXPos); 1417 toggleRect(c.cursor.y + 1, cursor.y + 1, aXPos, c.cXPos);
1413 toggleRect(anchor.y, cursor.y + 1, c.cXPos, cXPos); 1418 toggleRect(anchor.y, cursor.y + 1, c.cXPos, cXPos);
1414 } 1419 }
1415 select = cursor; 1420 select = cursor;
1416 optimizeSelection(); 1421 optimizeSelection();
1417 emit selectionChanged(); 1422 emit selectionChanged();
1418} 1423}
1419 1424
1420 1425
1421void KateDocument::selectAll() { 1426void KateDocument::selectAll() {
1422 int z; 1427 int z;
1423 TextLine::Ptr textLine; 1428 TextLine::Ptr textLine;
1424 1429
1425 select.x = -1; 1430 select.x = -1;
1426 1431
1427// if (selectStart != 0 || selectEnd != lastLine()) recordReset(); 1432// if (selectStart != 0 || selectEnd != lastLine()) recordReset();
1428 1433
1429 selectStart = 0; 1434 selectStart = 0;
1430 selectEnd = lastLine(); 1435 selectEnd = lastLine();
1431 1436
1432 tagLines(selectStart,selectEnd); 1437 tagLines(selectStart,selectEnd);
1433 1438
1434 for (z = selectStart; z < selectEnd; z++) { 1439 for (z = selectStart; z < selectEnd; z++) {
1435 textLine = getTextLine(z); 1440 textLine = getTextLine(z);
1436 textLine->selectEol(true,0); 1441 textLine->selectEol(true,0);
1437 } 1442 }
1438 textLine = getTextLine(z); 1443 textLine = getTextLine(z);
1439 textLine->select(true,0,textLine->length()); 1444 textLine->select(true,0,textLine->length());
1440 emit selectionChanged(); 1445 emit selectionChanged();
1441} 1446}
1442 1447
1443void KateDocument::deselectAll() { 1448void KateDocument::deselectAll() {
1444 select.x = -1; 1449 select.x = -1;
1445 if (selectEnd < selectStart) return; 1450 if (selectEnd < selectStart) return;
1446 1451
1447// recordReset(); 1452// recordReset();
1448 1453
1449 tagLines(selectStart,selectEnd); 1454 tagLines(selectStart,selectEnd);
1450 1455
1451 for (int z = selectStart; z <= selectEnd; z++) { 1456 for (int z = selectStart; z <= selectEnd; z++) {
1452 TextLine::Ptr textLine = getTextLine(z); 1457 TextLine::Ptr textLine = getTextLine(z);
1453 textLine->selectEol(false,0); 1458 textLine->selectEol(false,0);
1454 } 1459 }
1455 selectStart = 0xffffff; 1460 selectStart = 0xffffff;
1456 selectEnd = 0; 1461 selectEnd = 0;
1457 emit selectionChanged(); 1462 emit selectionChanged();
1458} 1463}
1459 1464
1460void KateDocument::invertSelection() { 1465void KateDocument::invertSelection() {
1461 TextLine::Ptr textLine; 1466 TextLine::Ptr textLine;
1462 1467
1463 select.x = -1; 1468 select.x = -1;
1464 1469
1465// if (selectStart != 0 || selectEnd != lastLine()) recordReset(); 1470// if (selectStart != 0 || selectEnd != lastLine()) recordReset();
1466 1471
1467 selectStart = 0; 1472 selectStart = 0;
1468 selectEnd = lastLine(); 1473 selectEnd = lastLine();
1469 1474
1470 tagLines(selectStart,selectEnd); 1475 tagLines(selectStart,selectEnd);
1471 1476
1472 for (int z = selectStart; z < selectEnd; z++) { 1477 for (int z = selectStart; z < selectEnd; z++) {
1473 textLine = getTextLine(z); 1478 textLine = getTextLine(z);
1474 textLine->toggleSelectEol(0); 1479 textLine->toggleSelectEol(0);
1475 } 1480 }
1476 textLine = getTextLine(selectEnd); 1481 textLine = getTextLine(selectEnd);
1477 textLine->toggleSelect(0,textLine->length()); 1482 textLine->toggleSelect(0,textLine->length());
1478 optimizeSelection(); 1483 optimizeSelection();
1479 emit selectionChanged(); 1484 emit selectionChanged();
1480} 1485}
1481 1486
1482void KateDocument::selectWord(PointStruc &cursor, int flags) { 1487void KateDocument::selectWord(PointStruc &cursor, int flags) {
1483 int start, end, len; 1488 int start, end, len;
1484 1489
1485 TextLine::Ptr textLine = getTextLine(cursor.y); 1490 TextLine::Ptr textLine = getTextLine(cursor.y);
1486 len = textLine->length(); 1491 len = textLine->length();
1487 start = end = cursor.x; 1492 start = end = cursor.x;
1488 while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--; 1493 while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
1489 while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++; 1494 while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++;
1490 if (end <= start) return; 1495 if (end <= start) return;
1491 if (!(flags & KateView::cfKeepSelection)) deselectAll(); 1496 if (!(flags & KateView::cfKeepSelection)) deselectAll();
1492// else recordReset(); 1497// else recordReset();
1493 1498
1494 textLine->select(true, start, end); 1499 textLine->select(true, start, end);
1495 1500
1496 anchor.x = start; 1501 anchor.x = start;
1497 select.x = end; 1502 select.x = end;
1498 anchor.y = select.y = cursor.y; 1503 anchor.y = select.y = cursor.y;
1499 tagLines(cursor.y, cursor.y); 1504 tagLines(cursor.y, cursor.y);
1500 if (cursor.y < selectStart) selectStart = cursor.y; 1505 if (cursor.y < selectStart) selectStart = cursor.y;
1501 if (cursor.y > selectEnd) selectEnd = cursor.y; 1506 if (cursor.y > selectEnd) selectEnd = cursor.y;
1502 emit selectionChanged(); 1507 emit selectionChanged();
1503} 1508}
1504 1509
1505void KateDocument::selectLength(PointStruc &cursor, int length, int flags) { 1510void KateDocument::selectLength(PointStruc &cursor, int length, int flags) {
1506 int start, end; 1511 int start, end;
1507 1512
1508 TextLine::Ptr textLine = getTextLine(cursor.y); 1513 TextLine::Ptr textLine = getTextLine(cursor.y);
1509 start = cursor.x; 1514 start = cursor.x;
1510 end = start + length; 1515 end = start + length;
1511 if (end <= start) return; 1516 if (end <= start) return;
1512 if (!(flags & KateView::cfKeepSelection)) deselectAll(); 1517 if (!(flags & KateView::cfKeepSelection)) deselectAll();
1513 1518
1514 textLine->select(true, start, end); 1519 textLine->select(true, start, end);
1515 1520
1516 anchor.x = start; 1521 anchor.x = start;
1517 select.x = end; 1522 select.x = end;
1518 anchor.y = select.y = cursor.y; 1523 anchor.y = select.y = cursor.y;
1519 tagLines(cursor.y, cursor.y); 1524 tagLines(cursor.y, cursor.y);
1520 if (cursor.y < selectStart) selectStart = cursor.y; 1525 if (cursor.y < selectStart) selectStart = cursor.y;
1521 if (cursor.y > selectEnd) selectEnd = cursor.y; 1526 if (cursor.y > selectEnd) selectEnd = cursor.y;
1522 emit selectionChanged(); 1527 emit selectionChanged();
1523} 1528}
1524 1529
1525void KateDocument::doIndent(VConfig &c, int change) { 1530void KateDocument::doIndent(VConfig &c, int change) {
1526 1531
1527 c.cursor.x = 0; 1532 c.cursor.x = 0;
1528 1533
1529 recordStart(c, (change < 0) ? KateActionGroup::ugUnindent 1534 recordStart(c, (change < 0) ? KateActionGroup::ugUnindent
1530 : KateActionGroup::ugIndent); 1535 : KateActionGroup::ugIndent);
1531 1536
1532 if (selectEnd < selectStart) { 1537 if (selectEnd < selectStart) {
1533 // single line 1538 // single line
1534 optimizeLeadingSpace(c.cursor.y, c.flags, change); 1539 optimizeLeadingSpace(c.cursor.y, c.flags, change);
1535 } else { 1540 } else {
1536 // entire selection 1541 // entire selection
1537 TextLine::Ptr textLine; 1542 TextLine::Ptr textLine;
1538 int line, z; 1543 int line, z;
1539 QChar ch; 1544 QChar ch;
1540 1545
1541 if (c.flags & KateView::cfKeepIndentProfile && change < 0) { 1546 if (c.flags & KateView::cfKeepIndentProfile && change < 0) {
1542 // unindent so that the existing indent profile doesn´t get screwed 1547 // unindent so that the existing indent profile doesn´t get screwed
1543 // if any line we may unindent is already full left, don't do anything 1548 // if any line we may unindent is already full left, don't do anything
1544 for (line = selectStart; line <= selectEnd; line++) { 1549 for (line = selectStart; line <= selectEnd; line++) {
1545 textLine = getTextLine(line); 1550 textLine = getTextLine(line);
1546 if (textLine->isSelected() || textLine->numSelected()) { 1551 if (textLine->isSelected() || textLine->numSelected()) {
1547 for (z = 0; z < tabChars; z++) { 1552 for (z = 0; z < tabChars; z++) {
1548 ch = textLine->getChar(z); 1553 ch = textLine->getChar(z);
1549 if (ch == '\t') break; 1554 if (ch == '\t') break;
1550 if (ch != ' ') { 1555 if (ch != ' ') {
1551 change = 0; 1556 change = 0;
1552 goto jumpOut; 1557 goto jumpOut;
1553 } 1558 }
1554 } 1559 }
1555 } 1560 }
1556 } 1561 }
1557 jumpOut:; 1562 jumpOut:;
1558 } 1563 }
1559 1564
1560 for (line = selectStart; line <= selectEnd; line++) { 1565 for (line = selectStart; line <= selectEnd; line++) {
1561 textLine = getTextLine(line); 1566 textLine = getTextLine(line);
1562 if (textLine->isSelected() || textLine->numSelected()) { 1567 if (textLine->isSelected() || textLine->numSelected()) {
1563 optimizeLeadingSpace(line, c.flags, change); 1568 optimizeLeadingSpace(line, c.flags, change);
1564 } 1569 }
1565 } 1570 }
1566 } 1571 }
1567 // recordEnd now removes empty undo records 1572 // recordEnd now removes empty undo records
1568 recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent); 1573 recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent);
1569} 1574}
1570 1575
1571/* 1576/*
1572 Optimize the leading whitespace for a single line. 1577 Optimize the leading whitespace for a single line.
1573 If change is > 0, it adds indentation units (tabChars) 1578 If change is > 0, it adds indentation units (tabChars)
1574 if change is == 0, it only optimizes 1579 if change is == 0, it only optimizes
1575 If change is < 0, it removes indentation units 1580 If change is < 0, it removes indentation units
1576 This will be used to indent, unindent, and optimal-fill a line. 1581 This will be used to indent, unindent, and optimal-fill a line.
1577 If excess space is removed depends on the flag cfKeepExtraSpaces 1582 If excess space is removed depends on the flag cfKeepExtraSpaces
1578 which has to be set by the user 1583 which has to be set by the user
1579*/ 1584*/
1580void KateDocument::optimizeLeadingSpace(int line, int flags, int change) { 1585void KateDocument::optimizeLeadingSpace(int line, int flags, int change) {
1581 int len; 1586 int len;
1582 int chars, space, okLen; 1587 int chars, space, okLen;
1583 QChar ch; 1588 QChar ch;
1584 int extra; 1589 int extra;
1585 QString s; 1590 QString s;
1586 PointStruc cursor; 1591 PointStruc cursor;
1587 1592
1588 TextLine::Ptr textLine = getTextLine(line); 1593 TextLine::Ptr textLine = getTextLine(line);
1589 len = textLine->length(); 1594 len = textLine->length();
1590 space = 0; // length of space at the beginning of the textline 1595 space = 0; // length of space at the beginning of the textline
1591 okLen = 0; // length of space which does not have to be replaced 1596 okLen = 0; // length of space which does not have to be replaced
1592 for (chars = 0; chars < len; chars++) { 1597 for (chars = 0; chars < len; chars++) {
1593 ch = textLine->getChar(chars); 1598 ch = textLine->getChar(chars);
1594 if (ch == ' ') { 1599 if (ch == ' ') {
1595 space++; 1600 space++;
1596 if (flags & KateView::cfSpaceIndent && okLen == chars) okLen++; 1601 if (flags & KateView::cfSpaceIndent && okLen == chars) okLen++;
1597 } else if (ch == '\t') { 1602 } else if (ch == '\t') {
1598 space += tabChars - space % tabChars; 1603 space += tabChars - space % tabChars;
1599 if (!(flags & KateView::cfSpaceIndent) && okLen == chars) okLen++; 1604 if (!(flags & KateView::cfSpaceIndent) && okLen == chars) okLen++;
1600 } else break; 1605 } else break;
1601 } 1606 }
1602 1607
1603 space += change*tabChars; // modify space width 1608 space += change*tabChars; // modify space width
1604 // if line contains only spaces it will be cleared 1609 // if line contains only spaces it will be cleared
1605 if (space < 0 || chars == len) space = 0; 1610 if (space < 0 || chars == len) space = 0;
1606 1611
1607 extra = space % tabChars; // extra spaces which don´t fit the indentation pattern 1612 extra = space % tabChars; // extra spaces which don´t fit the indentation pattern
1608 if (flags & KateView::cfKeepExtraSpaces) chars -= extra; 1613 if (flags & KateView::cfKeepExtraSpaces) chars -= extra;
1609 1614
1610 if (flags & KateView::cfSpaceIndent) { 1615 if (flags & KateView::cfSpaceIndent) {
1611 space -= extra; 1616 space -= extra;
1612 ch = ' '; 1617 ch = ' ';
1613 } else { 1618 } else {
1614 space /= tabChars; 1619 space /= tabChars;
1615 ch = '\t'; 1620 ch = '\t';
1616 } 1621 }
1617 1622
1618 // don´t replace chars which are already ok 1623 // don´t replace chars which are already ok
1619 cursor.x = QMIN(okLen, QMIN(chars, space)); 1624 cursor.x = QMIN(okLen, QMIN(chars, space));
1620 chars -= cursor.x; 1625 chars -= cursor.x;
1621 space -= cursor.x; 1626 space -= cursor.x;
1622 if (chars == 0 && space == 0) return; //nothing to do 1627 if (chars == 0 && space == 0) return; //nothing to do
1623 1628
1624 s.fill(ch, space); 1629 s.fill(ch, space);
1625 1630
1626//printf("chars %d insert %d cursor.x %d\n", chars, insert, cursor.x); 1631//printf("chars %d insert %d cursor.x %d\n", chars, insert, cursor.x);
1627 cursor.y = line; 1632 cursor.y = line;
1628 recordReplace(cursor, chars, s); 1633 recordReplace(cursor, chars, s);
1629} 1634}
1630 1635
1631void KateDocument::doComment(VConfig &c, int change) 1636void KateDocument::doComment(VConfig &c, int change)
1632{ 1637{
1633 c.flags |=KateView:: cfPersistent; 1638 c.flags |=KateView:: cfPersistent;
1634 1639
1635 recordStart(c, (change < 0) ? KateActionGroup::ugUncomment 1640 recordStart(c, (change < 0) ? KateActionGroup::ugUncomment
1636 : KateActionGroup::ugComment); 1641 : KateActionGroup::ugComment);
1637 1642
1638 QString startComment = m_highlight->getCommentStart(); 1643 QString startComment = m_highlight->getCommentStart();
1639 QString startLineComment = m_highlight->getCommentSingleLineStart(); 1644 QString startLineComment = m_highlight->getCommentSingleLineStart();
1640 QString endComment = m_highlight->getCommentEnd(); 1645 QString endComment = m_highlight->getCommentEnd();
1641 1646
1642 int startCommentLen = startComment.length(); 1647 int startCommentLen = startComment.length();
1643 int startLineCommentLen = startLineComment.length(); 1648 int startLineCommentLen = startLineComment.length();
1644 int endCommentLen = endComment.length(); 1649 int endCommentLen = endComment.length();
1645 1650
1646 if (change > 0) 1651 if (change > 0)
1647 { 1652 {
1648 if ( !hasMarkedText() ) 1653 if ( !hasMarkedText() )
1649 { 1654 {
1650 if (startLineComment != "") 1655 if (startLineComment != "")
1651 { 1656 {
1652 // Add a start comment mark 1657 // Add a start comment mark
1653 c.cursor.x = 0; 1658 c.cursor.x = 0;
1654 recordReplace(c.cursor, 0, startLineComment); 1659 recordReplace(c.cursor, 0, startLineComment);
1655 } 1660 }
1656 else if ((startComment != "") && (endComment != "")) 1661 else if ((startComment != "") && (endComment != ""))
1657 { 1662 {
1658 // Add a start comment mark 1663 // Add a start comment mark
1659 c.cursor.x = 0; 1664 c.cursor.x = 0;
1660 recordReplace(c.cursor, 0, startComment); 1665 recordReplace(c.cursor, 0, startComment);
1661 1666
1662 // Add an end comment mark 1667 // Add an end comment mark
1663 TextLine* textline = getTextLine(c.cursor.y); 1668 TextLine* textline = getTextLine(c.cursor.y);
1664 c.cursor.x = textline->length(); 1669 c.cursor.x = textline->length();
1665 recordReplace(c.cursor, 0, endComment); 1670 recordReplace(c.cursor, 0, endComment);
1666 c.cursor.x = 0; 1671 c.cursor.x = 0;
1667 } 1672 }
1668 } 1673 }
1669 else if ((startComment != "") && (endComment != "")) 1674 else if ((startComment != "") && (endComment != ""))
1670 { 1675 {
1671 QString marked (c.view->markedText ()); 1676 QString marked (c.view->markedText ());
1672 int preDeleteLine = -1, preDeleteCol = -1; 1677 int preDeleteLine = -1, preDeleteCol = -1;
1673 c.view->getCursorPosition (&preDeleteLine, &preDeleteCol); 1678 c.view->getCursorPosition (&preDeleteLine, &preDeleteCol);
1674 1679
1675 if (marked.length() > 0) 1680 if (marked.length() > 0)
1676 c.view->keyDelete (); 1681 c.view->keyDelete ();
1677 1682
1678 int line = -1, col = -1; 1683 int line = -1, col = -1;
1679 c.view->getCursorPosition (&line, &col); 1684 c.view->getCursorPosition (&line, &col);
1680 1685
1681 c.view->insertText (startComment + marked + endComment); 1686 c.view->insertText (startComment + marked + endComment);
1682 } 1687 }
1683 } 1688 }
1684 else 1689 else
1685 { 1690 {
1686 if ( !hasMarkedText() ) 1691 if ( !hasMarkedText() )
1687 { 1692 {
1688 TextLine* textline = getTextLine(c.cursor.y); 1693 TextLine* textline = getTextLine(c.cursor.y);
1689 1694
1690 if(textline->startingWith(startLineComment)) 1695 if(textline->startingWith(startLineComment))
1691 { 1696 {
1692 // Remove start comment mark 1697 // Remove start comment mark
1693 c.cursor.x = 0; 1698 c.cursor.x = 0;
1694 recordReplace(c.cursor, startLineCommentLen, ""); 1699 recordReplace(c.cursor, startLineCommentLen, "");
1695 } 1700 }
1696 else if (textline->startingWith(startComment) && textline->endingWith(endComment)) 1701 else if (textline->startingWith(startComment) && textline->endingWith(endComment))
1697 { 1702 {
1698 // Remove start comment mark 1703 // Remove start comment mark
1699 c.cursor.x = 0; 1704 c.cursor.x = 0;
1700 recordReplace(c.cursor, startCommentLen, ""); 1705 recordReplace(c.cursor, startCommentLen, "");
1701 1706
1702 // Remove end comment mark 1707 // Remove end comment mark
1703 if(endComment != "") 1708 if(endComment != "")
1704 { 1709 {
1705 c.cursor.x = textline->length() - endCommentLen; 1710 c.cursor.x = textline->length() - endCommentLen;
1706 recordReplace(c.cursor, endCommentLen, ""); 1711 recordReplace(c.cursor, endCommentLen, "");
1707 c.cursor.x = 0; 1712 c.cursor.x = 0;
1708 } 1713 }
1709 } 1714 }
1710 } 1715 }
1711 else 1716 else
1712 { 1717 {
1713 QString marked (c.view->markedText ()); 1718 QString marked (c.view->markedText ());
1714 int preDeleteLine = -1, preDeleteCol = -1; 1719 int preDeleteLine = -1, preDeleteCol = -1;
1715 c.view->getCursorPosition (&preDeleteLine, &preDeleteCol); 1720 c.view->getCursorPosition (&preDeleteLine, &preDeleteCol);
1716 1721
1717 int start = marked.find (startComment); 1722 int start = marked.find (startComment);
1718 int end = marked.findRev (endComment); 1723 int end = marked.findRev (endComment);
1719 1724
1720 if ((start > -1) && (end > -1)) 1725 if ((start > -1) && (end > -1))
1721 { 1726 {
1722 marked.remove (start, startCommentLen); 1727 marked.remove (start, startCommentLen);
1723 marked.remove (end-startCommentLen, endCommentLen); 1728 marked.remove (end-startCommentLen, endCommentLen);
1724 1729
1725 c.view->keyDelete (); 1730 c.view->keyDelete ();
1726 1731
1727 int line = -1, col = -1; 1732 int line = -1, col = -1;
1728 c.view->getCursorPosition (&line, &col); 1733 c.view->getCursorPosition (&line, &col);
1729 c.view->insertText (marked); 1734 c.view->insertText (marked);
1730 } 1735 }
1731 } 1736 }
1732 } 1737 }
1733 1738
1734 recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent); 1739 recordEnd(c.view, c.cursor, c.flags | KateView::cfPersistent);
1735} 1740}
1736 1741
1737 1742
1738QString KateDocument::text() const 1743QString KateDocument::text() const
1739{ 1744{
1740 QString s; 1745 QString s;
1741 1746
1742 for (int i=0; i < buffer->count(); i++) 1747 for (int i=0; i < buffer->count(); i++)
1743 { 1748 {
1744 TextLine::Ptr textLine = buffer->line(i); 1749 TextLine::Ptr textLine = buffer->line(i);
1745 s.insert(s.length(), textLine->getText(), textLine->length()); 1750 s.insert(s.length(), textLine->getText(), textLine->length());
1746 if ( (i < (buffer->count()-1)) ) 1751 if ( (i < (buffer->count()-1)) )
1747 s.append('\n'); 1752 s.append('\n');
1748 } 1753 }
1749 1754
1750 return s; 1755 return s;
1751} 1756}
1752 1757
1753QString KateDocument::getWord(PointStruc &cursor) { 1758QString KateDocument::getWord(PointStruc &cursor) {
1754 int start, end, len; 1759 int start, end, len;
1755 1760
1756 TextLine::Ptr textLine = getTextLine(cursor.y); 1761 TextLine::Ptr textLine = getTextLine(cursor.y);
1757 len = textLine->length(); 1762 len = textLine->length();
1758 start = end = cursor.x; 1763 start = end = cursor.x;
1759 while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--; 1764 while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
1760 while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++; 1765 while (end < len && m_highlight->isInWord(textLine->getChar(end))) end++;
1761 len = end - start; 1766 len = end - start;
1762 return QString(&textLine->getText()[start], len); 1767 return QString(&textLine->getText()[start], len);
1763} 1768}
1764 1769
1765void KateDocument::setText(const QString &s) { 1770void KateDocument::setText(const QString &s) {
1766 int pos; 1771 int pos;
1767 QChar ch; 1772 QChar ch;
1768 1773
1769 clear(); 1774 clear();
1770 1775
1771 int line=1; 1776 int line=1;
1772 1777
1773 TextLine::Ptr textLine = buffer->line(0); 1778 TextLine::Ptr textLine = buffer->line(0);
1774 for (pos = 0; pos <= (int) s.length(); pos++) { 1779 for (pos = 0; pos <= (int) s.length(); pos++) {
1775 ch = s[pos]; 1780 ch = s[pos];
1776 if (ch.isPrint() || ch == '\t') { 1781 if (ch.isPrint() || ch == '\t') {
1777 textLine->append(&ch, 1); 1782 textLine->append(&ch, 1);
1778 } else if (ch == '\n') 1783 } else if (ch == '\n')
1779 { 1784 {
1780 textLine = new TextLine(); 1785 textLine = new TextLine();
1781 buffer->insertLine (line, textLine); 1786 buffer->insertLine (line, textLine);
1782 line++; 1787 line++;
1783 } 1788 }
1784 } 1789 }
1785 updateLines(); 1790 updateLines();
1786} 1791}
1787 1792
1788 1793
1789QString KateDocument::markedText(int flags) { 1794QString KateDocument::markedText(int flags) {
1790 TextLine::Ptr textLine; 1795 TextLine::Ptr textLine;
1791 int len, z, start, end, i; 1796 int len, z, start, end, i;
1792 1797
1793 len = 1; 1798 len = 1;
1794 if (!(flags & KateView::cfVerticalSelect)) { 1799 if (!(flags & KateView::cfVerticalSelect)) {
1795 for (z = selectStart; z <= selectEnd; z++) { 1800 for (z = selectStart; z <= selectEnd; z++) {
1796 textLine = getTextLine(z); 1801 textLine = getTextLine(z);
1797 len += textLine->numSelected(); 1802 len += textLine->numSelected();
1798 if (textLine->isSelected()) len++; 1803 if (textLine->isSelected()) len++;
1799 } 1804 }
1800 QString s; 1805 QString s;
1801 len = 0; 1806 len = 0;
1802 for (z = selectStart; z <= selectEnd; z++) { 1807 for (z = selectStart; z <= selectEnd; z++) {
1803 textLine = getTextLine(z); 1808 textLine = getTextLine(z);
1804 end = 0; 1809 end = 0;
1805 do { 1810 do {
1806 start = textLine->findUnselected(end); 1811 start = textLine->findUnselected(end);
1807 end = textLine->findSelected(start); 1812 end = textLine->findSelected(start);
1808 for (i = start; i < end; i++) { 1813 for (i = start; i < end; i++) {
1809 s[len] = textLine->getChar(i); 1814 s[len] = textLine->getChar(i);
1810 len++; 1815 len++;
1811 } 1816 }
1812 } while (start < end); 1817 } while (start < end);
1813 if (textLine->isSelected()) { 1818 if (textLine->isSelected()) {
1814 s[len] = '\n'; 1819 s[len] = '\n';
1815 len++; 1820 len++;
1816 } 1821 }
1817 } 1822 }
1818// s[len] = '\0'; 1823// s[len] = '\0';
1819 return s; 1824 return s;
1820 } else { 1825 } else {
1821 for (z = selectStart; z <= selectEnd; z++) { 1826 for (z = selectStart; z <= selectEnd; z++) {
1822 textLine = getTextLine(z); 1827 textLine = getTextLine(z);
1823 len += textLine->numSelected() + 1; 1828 len += textLine->numSelected() + 1;
1824 } 1829 }
1825 QString s; 1830 QString s;
1826 len = 0; 1831 len = 0;
1827 for (z = selectStart; z <= selectEnd; z++) { 1832 for (z = selectStart; z <= selectEnd; z++) {
1828 textLine = getTextLine(z); 1833 textLine = getTextLine(z);
1829 end = 0; 1834 end = 0;
1830 do { 1835 do {
1831 start = textLine->findUnselected(end); 1836 start = textLine->findUnselected(end);
1832 end = textLine->findSelected(start); 1837 end = textLine->findSelected(start);
1833 for (i = start; i < end; i++) { 1838 for (i = start; i < end; i++) {
1834 s[len] = textLine->getChar(i); 1839 s[len] = textLine->getChar(i);
1835 len++; 1840 len++;
1836 } 1841 }
1837 } while (start < end); 1842 } while (start < end);
1838 s[len] = '\n'; 1843 s[len] = '\n';
1839 len++; 1844 len++;
1840 } 1845 }
1841// s[len] = '\0'; // the final \0 is not counted in length() 1846// s[len] = '\0'; // the final \0 is not counted in length()
1842 return s; 1847 return s;
1843 } 1848 }
1844} 1849}
1845 1850
1846void KateDocument::delMarkedText(VConfig &c/*, bool undo*/) { 1851void KateDocument::delMarkedText(VConfig &c/*, bool undo*/) {
1847 int end = 0; 1852 int end = 0;
1848 1853
1849 if (selectEnd < selectStart) return; 1854 if (selectEnd < selectStart) return;
1850 1855
1851 // the caller may have already started an undo record for the current action 1856 // the caller may have already started an undo record for the current action
1852// if (undo) 1857// if (undo)
1853 1858
1854 //auto deletion of the marked text occurs not very often and can therefore 1859 //auto deletion of the marked text occurs not very often and can therefore
1855 // be recorded separately 1860 // be recorded separately
1856 recordStart(c, KateActionGroup::ugDelBlock); 1861 recordStart(c, KateActionGroup::ugDelBlock);
1857 1862
1858 for (c.cursor.y = selectEnd; c.cursor.y >= selectStart; c.cursor.y--) { 1863 for (c.cursor.y = selectEnd; c.cursor.y >= selectStart; c.cursor.y--) {
1859 TextLine::Ptr textLine = getTextLine(c.cursor.y); 1864 TextLine::Ptr textLine = getTextLine(c.cursor.y);
1860 1865
1861 c.cursor.x = textLine->length(); 1866 c.cursor.x = textLine->length();
1862 do { 1867 do {
1863 end = textLine->findRevUnselected(c.cursor.x); 1868 end = textLine->findRevUnselected(c.cursor.x);
1864 if (end == 0) break; 1869 if (end == 0) break;
1865 c.cursor.x = textLine->findRevSelected(end); 1870 c.cursor.x = textLine->findRevSelected(end);
1866 recordDelete(c.cursor, end - c.cursor.x); 1871 recordDelete(c.cursor, end - c.cursor.x);
1867 } while (true); 1872 } while (true);
1868 end = c.cursor.x; 1873 end = c.cursor.x;
1869 c.cursor.x = textLine->length(); 1874 c.cursor.x = textLine->length();
1870 if (textLine->isSelected()) recordAction(KateAction::delLine,c.cursor); 1875 if (textLine->isSelected()) recordAction(KateAction::delLine,c.cursor);
1871 } 1876 }
1872 c.cursor.y++; 1877 c.cursor.y++;
1873 /*if (end < c.cursor.x)*/ c.cursor.x = end; 1878 /*if (end < c.cursor.x)*/ c.cursor.x = end;
1874 1879
1875 selectEnd = -1; 1880 selectEnd = -1;
1876 select.x = -1; 1881 select.x = -1;
1877 1882
1878 /*if (undo)*/ recordEnd(c); 1883 /*if (undo)*/ recordEnd(c);
1879} 1884}
1880 1885
1881void KateDocument::tagLineRange(int line, int x1, int x2) { 1886void KateDocument::tagLineRange(int line, int x1, int x2) {
1882 int z; 1887 int z;
1883 1888
1884 for (z = 0; z < (int) views.count(); z++) { 1889 for (z = 0; z < (int) views.count(); z++) {
1885 views.at(z)->tagLines(line, line, x1, x2); 1890 views.at(z)->tagLines(line, line, x1, x2);
1886 } 1891 }
1887} 1892}
1888 1893
1889void KateDocument::tagLines(int start, int end) { 1894void KateDocument::tagLines(int start, int end) {
1890 int z; 1895 int z;
1891 1896
1892 for (z = 0; z < (int) views.count(); z++) { 1897 for (z = 0; z < (int) views.count(); z++) {
1893 views.at(z)->tagLines(start, end, 0, 0xffffff); 1898 views.at(z)->tagLines(start, end, 0, 0xffffff);
1894 } 1899 }
1895} 1900}
1896 1901
1897void KateDocument::tagAll() { 1902void KateDocument::tagAll() {
1898 int z; 1903 int z;
1899 1904
1900 for (z = 0; z < (int) views.count(); z++) { 1905 for (z = 0; z < (int) views.count(); z++) {
1901 views.at(z)->tagAll(); 1906 views.at(z)->tagAll();
1902 } 1907 }
1903} 1908}
1904 1909