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