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)) && !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