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