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