00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <qdragobject.h>
00023
#include <qpopupmenu.h>
00024
#include <qtextstream.h>
00025
#include <qtimer.h>
00026
00027
#include <kapplication.h>
00028
#include <kcursor.h>
00029
#include <kdebug.h>
00030
#include <kcmenumngr.h>
00031
#include <kfontdialog.h>
00032
#include <klocale.h>
00033
#include <kmessagebox.h>
00034
#include <kstdaccel.h>
00035
#include <kurldrag.h>
00036
00037
#include "keditcl.h"
00038
#include "keditcl.moc"
00039
00040
class KEdit::KEditPrivate
00041 {
00042
public:
00043
bool overwriteEnabled:1;
00044
bool posDirty:1;
00045 };
00046
00047
00048 KEdit::KEdit(
QWidget *_parent,
const char *name)
00049 :
QMultiLineEdit(_parent, name)
00050 {
00051 d =
new KEditPrivate;
00052 d->overwriteEnabled =
false;
00053 d->posDirty =
true;
00054
00055 parent = _parent;
00056
00057
00058
00059 line_pos = col_pos = 0;
00060
00061 srchdialog = NULL;
00062 replace_dialog= NULL;
00063 gotodialog = NULL;
00064
00065 setAcceptDrops(
true);
00066
KCursor::setAutoHideCursor(
this,
true );
00067
00068 connect(
this, SIGNAL(cursorPositionChanged(
int,
int)),
00069
this, SLOT(slotCursorPositionChanged()));
00070 }
00071
00072
00073 KEdit::~KEdit()
00074 {
00075
delete d;
00076 }
00077
00078
void
00079 KEdit::insertText(
QTextStream *stream)
00080 {
00081
00082
int line, col;
00083 getCursorPosition(&line, &col);
00084
int saveline = line;
00085
int savecol = col;
00086
QString textLine;
00087
00088
00089
00090
00091
00092
00093
00094
int oldUndoDepth = undoDepth();
00095 setUndoDepth( 0 );
00096
00097
00098
00099
QIODevice *dev=stream->
device();
00100
if (dev && dev->
size()>(1024*1024)) {
00101
while(1) {
00102
int i;
00103 textLine=
"";
00104
for (i=0; i<5000; i++) {
00105
QString line=stream->
readLine();
00106
if (line.
isNull())
break;
00107 textLine+=line+
'\n';
00108 }
00109
insertAt(textLine, line, col);
00110 line+=i; col=0;
00111
if (i!=5000)
break;
00112 }
00113 }
00114
else {
00115 textLine = stream->
read();
00116
insertAt( textLine, line, col);
00117 }
00118 setUndoDepth( oldUndoDepth );
00119
00120
setCursorPosition(saveline, savecol);
00121
00122
00123
00124
00125 setModified(
true);
00126 setFocus();
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 }
00138
00139
void
00140 KEdit::cleanWhiteSpace()
00141 {
00142 setAutoUpdate(
false);
00143
if (!
hasMarkedText())
00144 selectAll();
00145
QString oldText =
markedText();
00146
QString newText;
00147
QStringList lines =
QStringList::split(
'\n', oldText,
true);
00148
bool addSpace =
false;
00149
bool firstLine =
true;
00150
QChar lastChar = oldText[oldText.length()-1];
00151
QChar firstChar = oldText[0];
00152
for(QStringList::Iterator it = lines.begin();
00153 it != lines.end();)
00154 {
00155
QString line = (*it).simplifyWhiteSpace();
00156
if (line.
isEmpty())
00157 {
00158
if (addSpace)
00159 newText +=
QString::fromLatin1(
"\n\n");
00160
if (firstLine)
00161 {
00162
if (firstChar.
isSpace())
00163 newText +=
'\n';
00164 firstLine =
false;
00165 }
00166 addSpace =
false;
00167 }
00168
else
00169 {
00170
if (addSpace)
00171 newText +=
' ';
00172
if (firstLine)
00173 {
00174
if (firstChar.
isSpace())
00175 newText +=
' ';
00176 firstLine =
false;
00177 }
00178 newText += line;
00179 addSpace =
true;
00180 }
00181 it = lines.remove(it);
00182 }
00183
if (addSpace)
00184 {
00185
if (lastChar ==
'\n')
00186 newText +=
'\n';
00187
else if (lastChar.
isSpace())
00188 newText +=
' ';
00189 }
00190
00191
if (oldText == newText)
00192 {
00193 deselect();
00194 setAutoUpdate(
true);
00195 repaint();
00196
return;
00197 }
00198
if (wordWrap() == NoWrap)
00199 {
00200
00201
00202
00203
QMultiLineEdit *we =
new QMultiLineEdit();
00204 we->setWordWrap(FixedColumnWidth);
00205 we->setWrapColumnOrWidth(78);
00206 we->setText(newText);
00207 newText = QString::null;
00208
for(
int i = 0; i < we->
numLines(); i++)
00209 {
00210
QString line = we->
textLine(i);
00211
if (line.
right(1) !=
"\n")
00212 line +=
'\n';
00213 newText += line;
00214 }
00215
delete we;
00216 }
00217
00218 insert(newText);
00219 setAutoUpdate(
true);
00220 repaint();
00221
00222 setModified(
true);
00223 setFocus();
00224 }
00225
00226
00227
void
00228
KEdit::saveText(
QTextStream *stream)
00229 {
00230
saveText(stream,
false);
00231 }
00232
00233
void
00234 KEdit::saveText(
QTextStream *stream,
bool softWrap)
00235 {
00236
int line_count =
numLines()-1;
00237
if (line_count < 0)
00238
return;
00239
00240
if (softWrap || (wordWrap() == NoWrap))
00241 {
00242
for(
int i = 0; i < line_count; i++)
00243 {
00244 (*stream) <<
textLine(i) <<
'\n';
00245 }
00246 (*stream) <<
textLine(line_count);
00247 }
00248
else
00249 {
00250
for(
int i = 0; i <= line_count; i++)
00251 {
00252
int lines_in_parag = linesOfParagraph(i);
00253
if (lines_in_parag == 1)
00254 {
00255 (*stream) <<
textLine(i);
00256 }
00257
else
00258 {
00259
QString parag_text =
textLine(i);
00260
int pos = 0;
00261
int first_pos = 0;
00262
int current_line = 0;
00263
while(
true) {
00264
while(lineOfChar(i, pos) == current_line) pos++;
00265 (*stream) << parag_text.
mid(first_pos, pos - first_pos - 1) <<
'\n';
00266 current_line++;
00267 first_pos = pos;
00268
if (current_line+1 == lines_in_parag)
00269 {
00270
00271 (*stream) << parag_text.
mid(pos);
00272
break;
00273 }
00274 }
00275 }
00276
if (i < line_count)
00277 (*stream) <<
'\n';
00278 }
00279 }
00280 }
00281
00282 int KEdit::currentLine(){
00283
00284 computePosition();
00285
return line_pos;
00286
00287 }
00288
00289 int KEdit::currentColumn(){
00290
00291 computePosition();
00292
return col_pos;
00293 }
00294
00295
void KEdit::slotCursorPositionChanged()
00296 {
00297 d->posDirty =
true;
00298 emit
CursorPositionChanged();
00299 }
00300
00301
void KEdit::computePosition()
00302 {
00303
if (!d->posDirty)
return;
00304 d->posDirty =
false;
00305
00306
int line, col;
00307
00308 getCursorPosition(&line,&col);
00309
00310
00311 line_pos = 0;
00312
if (wordWrap() == NoWrap)
00313 {
00314 line_pos = line;
00315 }
00316
else
00317 {
00318
for(
int i = 0; i < line; i++)
00319 line_pos += linesOfParagraph(i);
00320 }
00321
00322
int line_offset = lineOfChar(line, col);
00323 line_pos += line_offset;
00324
00325
00326
QString linetext =
textLine(line);
00327
int start_of_line = 0;
00328
if (line_offset > 0)
00329 {
00330 start_of_line = col;
00331
while(lineOfChar(line, --start_of_line) == line_offset);
00332 start_of_line++;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
int coltemp = col-start_of_line;
00344
int pos = 0;
00345
int find = 0;
00346
int mem = 0;
00347
bool found_one =
false;
00348
00349
00350
00351
00352
00353
while(
find >=0 &&
find <= coltemp- 1 ){
00354
find = linetext.
find(
'\t', find+start_of_line,
true )-start_of_line;
00355
if(
find >=0 &&
find <= coltemp - 1 ){
00356 found_one =
true;
00357 pos = pos +
find - mem;
00358 pos = pos + 8 - pos % 8;
00359 mem =
find;
00360
find ++;
00361 }
00362 }
00363
00364 pos = pos + coltemp - mem;
00365
00366
00367
if (found_one){
00368 pos = pos - 1;
00369 }
00370
00371 col_pos = pos;
00372 }
00373
00374
00375
void KEdit::keyPressEvent (
QKeyEvent *e)
00376 {
00377
00378
if ( e->
key() == Key_Return && e->
state() == ControlButton ) {
00379 e->
ignore();
00380
return;
00381 }
00382
00383
KKey key(e);
00384
int keyQt =
key.keyCodeQt();
00385
00386
if ( keyQt == CTRL+Key_K ){
00387
00388
int line = 0;
00389
int col = 0;
00390
QString killstring;
00391
00392
if(!killing){
00393 killbufferstring =
"";
00394 killtrue =
false;
00395 lastwasanewline =
false;
00396 }
00397
00398
if(!
atEnd()){
00399
00400 getCursorPosition(&line,&col);
00401 killstring =
textLine(line);
00402 killstring = killstring.
mid(col,killstring.
length());
00403
00404
00405
if(!killbufferstring.
isEmpty() && !killtrue && !lastwasanewline){
00406 killbufferstring +=
'\n';
00407 }
00408
00409
if( (killstring.
length() == 0) && !killtrue){
00410 killbufferstring +=
'\n';
00411 lastwasanewline =
true;
00412 }
00413
00414
if(killstring.
length() > 0){
00415
00416 killbufferstring += killstring;
00417 lastwasanewline =
false;
00418 killtrue =
true;
00419
00420 }
else{
00421
00422 lastwasanewline =
false;
00423 killtrue = !killtrue;
00424
00425 }
00426
00427 }
else{
00428
00429
if(killbufferstring.
isEmpty() && !killtrue && !lastwasanewline){
00430 killtrue =
true;
00431 }
00432
00433 }
00434
00435 killing =
true;
00436
00437 QMultiLineEdit::keyPressEvent(e);
00438 setModified(
true);
00439
return;
00440 }
00441
else if ( keyQt == CTRL+Key_Y ){
00442
00443
int line = 0;
00444
int col = 0;
00445
00446 getCursorPosition(&line,&col);
00447
00448
QString tmpstring = killbufferstring;
00449
if(!killtrue)
00450 tmpstring +=
'\n';
00451
00452
insertAt(tmpstring,line,col);
00453
00454 killing =
false;
00455 setModified(
true);
00456
return;
00457 }
00458
00459 killing =
false;
00460
00461
if (
KStdAccel::copy().
contains( key ) )
00462
copy();
00463
else if ( isReadOnly() )
00464 QMultiLineEdit::keyPressEvent( e );
00465
00466
else if ( (
key.keyCodeQt() & (CTRL | ALT)) == 0 && !e->
text().isEmpty() && e->
text().unicode()->isPrint() )
00467 QMultiLineEdit::keyPressEvent( e );
00468
else if (
KStdAccel::paste().
contains( key ) ) {
00469
paste();
00470 setModified(
true);
00471 slotCursorPositionChanged();
00472 }
00473
else if (
KStdAccel::cut().
contains( key ) ) {
00474
cut();
00475 setModified(
true);
00476 slotCursorPositionChanged();
00477 }
00478
else if (
KStdAccel::undo().
contains( key ) ) {
00479
undo();
00480 setModified(
true);
00481 slotCursorPositionChanged();
00482 }
00483
else if (
KStdAccel::redo().
contains( key ) ) {
00484
redo();
00485 setModified(
true);
00486 slotCursorPositionChanged();
00487 }
00488
else if (
KStdAccel::deleteWordBack().
contains( key ) ) {
00489 moveCursor(MoveWordBackward,
true);
00490
if (hasSelectedText())
00491
del();
00492 setModified(
true);
00493 slotCursorPositionChanged();
00494 }
00495
else if (
KStdAccel::deleteWordForward().
contains( key ) ) {
00496 moveCursor(MoveWordForward,
true);
00497
if (hasSelectedText())
00498
del();
00499 setModified(
true);
00500 slotCursorPositionChanged();
00501 }
00502
else if (
key == Key_Insert ) {
00503
if (d->overwriteEnabled)
00504 {
00505 this->setOverwriteMode(!this->isOverwriteMode());
00506 emit
toggle_overwrite_signal();
00507 }
00508 }
00509
else
00510 QMultiLineEdit::keyPressEvent(e);
00511 }
00512
00513 void KEdit::installRBPopup(
QPopupMenu *p) {
00514
KContextMenuManager::insert(
this, p );
00515 }
00516
00517 void KEdit::selectFont(){
00518
00519
QFont font = this->font();
00520
KFontDialog::getFont(font);
00521 this->setFont(font);
00522
00523 }
00524
00525 void KEdit::doGotoLine() {
00526
00527
if( !gotodialog )
00528 gotodialog =
new KEdGotoLine( parent,
"gotodialog" );
00529
00530 this->clearFocus();
00531
00532 gotodialog->exec();
00533
00534
00535
if( gotodialog->result() != KEdGotoLine::Accepted)
00536
return;
00537
int target_line = gotodialog->getLineNumber()-1;
00538
if (wordWrap() == NoWrap)
00539 {
00540
setCursorPosition( target_line, 0 );
00541 setFocus();
00542
return;
00543 }
00544
00545
int max_parag = paragraphs();
00546
00547
int line = 0;
00548
int parag = -1;
00549
int lines_in_parag = 0;
00550
while ((++parag < max_parag) && (line + lines_in_parag < target_line))
00551 {
00552 line += lines_in_parag;
00553 lines_in_parag = linesOfParagraph(parag);
00554 }
00555
00556
int col = 0;
00557
if (parag >= max_parag)
00558 {
00559 target_line = line + lines_in_parag - 1;
00560 parag = max_parag-1;
00561 }
00562
00563
while(1+line+lineOfChar(parag,col) < target_line) col++;
00564
setCursorPosition( parag, col );
00565 setFocus();
00566 }
00567
00568
00569
void KEdit::dragMoveEvent(
QDragMoveEvent* e) {
00570
00571
if(
KURLDrag::canDecode(e))
00572 e->
accept();
00573
else if(
QTextDrag::canDecode(e))
00574 QMultiLineEdit::dragMoveEvent(e);
00575 }
00576
00577
void KEdit::contentsDragMoveEvent(
QDragMoveEvent* e) {
00578
00579
if(
KURLDrag::canDecode(e))
00580 e->
accept();
00581
else if(
QTextDrag::canDecode(e))
00582 QMultiLineEdit::contentsDragMoveEvent(e);
00583 }
00584
00585
void KEdit::dragEnterEvent(
QDragEnterEvent* e) {
00586
00587
kdDebug() <<
"KEdit::dragEnterEvent()" <<
endl;
00588 e->accept(KURLDrag::canDecode(e) || QTextDrag::canDecode(e));
00589 }
00590
00591
void KEdit::contentsDragEnterEvent(
QDragEnterEvent* e) {
00592
00593
kdDebug() <<
"KEdit::contentsDragEnterEvent()" <<
endl;
00594 e->accept(KURLDrag::canDecode(e) || QTextDrag::canDecode(e));
00595 }
00596
00597
00598
void KEdit::dropEvent(
QDropEvent* e) {
00599
00600
kdDebug() <<
"KEdit::dropEvent()" <<
endl;
00601
00602
if(
KURLDrag::canDecode(e)) {
00603 emit
gotUrlDrop(e);
00604 }
00605
else if(
QTextDrag::canDecode(e))
00606 QMultiLineEdit::dropEvent(e);
00607 }
00608
00609
void KEdit::contentsDropEvent(
QDropEvent* e) {
00610
00611
kdDebug() <<
"KEdit::contentsDropEvent()" <<
endl;
00612
00613
if(
KURLDrag::canDecode(e)) {
00614 emit
gotUrlDrop(e);
00615 }
00616
else if(
QTextDrag::canDecode(e))
00617 QMultiLineEdit::contentsDropEvent(e);
00618 }
00619
00620 void KEdit::setOverwriteEnabled(
bool b)
00621 {
00622 d->overwriteEnabled = b;
00623 }
00624
00625
00626 void KEdit::create( WId
id,
bool initializeWindow,
bool destroyOldWindow )
00627 {
00628 QMultiLineEdit::create(
id, initializeWindow, destroyOldWindow );
00629
KCursor::setAutoHideCursor(
this,
true );
00630 }
00631
00632
00633
void KEdGotoLine::virtual_hook(
int id,
void* data )
00634 { KDialogBase::virtual_hook(
id, data ); }
00635
00636
void KEdFind::virtual_hook(
int id,
void* data )
00637 { KDialogBase::virtual_hook(
id, data ); }
00638
00639
void KEdReplace::virtual_hook(
int id,
void* data )
00640 { KDialogBase::virtual_hook(
id, data ); }
00641
00642
void KEdit::virtual_hook(
int,
void* )
00643 { }
00644