From 00348d25b54085cde1f8038f282db2c6afb83d68 Mon Sep 17 00:00:00 2001 From: Lars Doelle Date: Sun, 31 Jan 1999 04:48:44 +0000 Subject: [PATCH] applied warwick's patches. see ChangeLog. svn path=/trunk/kdebase/konsole/; revision=16213 --- CONTRIBUTORS | 1 + ChangeLog | 6 +++ include/TEWidget.h | 4 +- src/TEWidget.C | 112 +++++++++++++++++++++++++++++++++++---------- src/TEmuVt102.C | 2 +- 5 files changed, 98 insertions(+), 27 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ff86739f..bd2c44ec 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -4,6 +4,7 @@ CONTRIBUTORS - 16 color SGR codes (xterm-83) - schema files seeked also in ~/.kde/share/apps/konsole - vim.schema + - improved/fixed selections - Matthias Ettrich - most of main.C donated via kvt. - rework of the session management diff --git a/ChangeLog b/ChangeLog index 6ba14b75..afea4465 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +30 Jan 1998 Warwick Allison +- character classes (removing word_characters code) +- "word" selection based on character classes +- "word" selection during selection Extend (double-click-and-drag) +- fixed bug to so that selection stays highlighted +- fixed another, more obscure selection bug 05 Jan 1998 - improved handling of atypical or moved installations (Martin,Sven,Lars) - a QString::printf issue resolved (Sven,Lars) diff --git a/include/TEWidget.h b/include/TEWidget.h index 75ff12a3..51b4c44c 100644 --- a/include/TEWidget.h +++ b/include/TEWidget.h @@ -88,6 +88,7 @@ protected: void mouseMoveEvent( QMouseEvent* ); void emitSelection(); + virtual int charClass(char) const; public: @@ -102,7 +103,6 @@ public: public slots: void onClearSelection(); - void setWordClass(char* s); protected slots: @@ -131,9 +131,9 @@ private: void makeImage(); + QPoint iPntSel; // initial selection point QPoint pntSel; // current selection point int actSel; // selection state - char *word_characters; // word class characters. BOOL word_selection_mode; BOOL preserve_line_breaks; diff --git a/src/TEWidget.C b/src/TEWidget.C index 25f97858..103228f2 100644 --- a/src/TEWidget.C +++ b/src/TEWidget.C @@ -171,10 +171,6 @@ TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) setMouseMarks(TRUE); setVTFont( QFont("fixed") ); - //make an empty string as default to avoid having to test for NULL - word_characters = NULL; - setWordClass(""); - setColorTable(base_color_table); // init color table if ( parent ) parent->installEventFilter( this ); //FIXME: see below @@ -488,6 +484,8 @@ void TEWidget::mousePressEvent(QMouseEvent* ev) int tLx = tL.x(); int tLy = tL.y(); + word_selection_mode = FALSE; + // printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); if ( ev->button() == LeftButton) { @@ -498,7 +496,7 @@ void TEWidget::mousePressEvent(QMouseEvent* ev) if (mouse_marks || (ev->state() & ShiftButton)) { emit clearSelectionSignal(); - pntSel = pos; + iPntSel = pntSel = pos; actSel = 1; // left mouse button pressed but nothing selected yet. grabMouse( /*crossCursor*/ ); // handle with care! } @@ -549,11 +547,55 @@ void TEWidget::mouseMoveEvent(QMouseEvent* ev) } QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); + QPoint ohere; + bool swapping = FALSE; + + if ( word_selection_mode ) { + // Extend to word boundaries + int i; + int selClass; + + bool left_not_right = ( here.y() < iPntSel.y() || + here.y() == iPntSel.y() && here.x() < iPntSel.x() ); + bool old_left_not_right = ( pntSel.y() < iPntSel.y() || + pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); + swapping = left_not_right != old_left_not_right; + + // Find left (left_not_right ? from here : from start) + QPoint left = left_not_right ? here : iPntSel; + i = loc(left.x(),left.y()); + selClass = charClass(image[i].c); + while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) + { i--; left.rx()--; } + + // Find left (left_not_right ? from start : from here) + QPoint right = left_not_right ? iPntSel : here; + i = loc(right.x(),right.y()); + selClass = charClass(image[i].c); + while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) + { i++; right.rx()++; } + + // Pick which is start (ohere) and which is extension (here) + if ( left_not_right ) + { + here = left; + ohere = right; + } else { + here = right; + ohere = left; + } + } if (here == pntSel && scroll == scrollbar->value()) return; // not moved - if (actSel < 2) emit beginSelectionSignal( pntSel.x(), pntSel.y() ); - + if ( word_selection_mode ) { + if ( actSel < 2 || swapping ) { + emit beginSelectionSignal( ohere.x(), ohere.y() ); + } + } else if ( actSel < 2 ) { + emit beginSelectionSignal( pntSel.x(), pntSel.y() ); + } + actSel = 2; // within selection pntSel = here; emit extendSelectionSignal( here.x(), here.y() ); @@ -583,13 +625,6 @@ void TEWidget::mouseReleaseEvent(QMouseEvent* ev) } } -void TEWidget::setWordClass(char* s) { - if (s) { - if (word_characters) free(word_characters); - word_characters = strdup(s); - } -} - void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) { if ( ev->button() != LeftButton) return; @@ -613,32 +648,48 @@ void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) QPoint bgnSel = pos; QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); int i = loc(bgnSel.x(),bgnSel.y()); + iPntSel = bgnSel; + + word_selection_mode = TRUE; // find word boundaries... - if (!isspace(image[i].c)) + int selClass = charClass(image[i].c); { // set the start... int x = bgnSel.x(); - while((isalnum(image[i].c)||ispunct(image[i].c)) && (x > 0)) { i--; x--; } - if ( x > 0 ) x++; + while ( x > 0 && charClass(image[i-1].c) == selClass ) + { i--; x--; } bgnSel.setX(x); emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); // set the end... i = loc( endSel.x(), endSel.y() ); x = endSel.x(); - while((isalnum(image[i].c)||ispunct(image[i].c)||strchr(word_characters,image[i].c)) - && (x < (columns-1))) - { i++; x++ ; } - if (x < (columns-1)) x--; + while( x < columns-1 && charClass(image[i+1].c) == selClass ) + { i++; x++ ; } endSel.setX(x); emit extendSelectionSignal( endSel.x(), endSel.y() ); emit endSelectionSignal(preserve_line_breaks); preserve_line_breaks = TRUE; - } } +int TEWidget::charClass(char ch) const +{ + // This might seem like overkill, but imagine if ch was a Unicode + // character (Qt 2.0 QChar) - it might then be sensible to separate + // the different language ranges, etc. + + if ( isspace(ch) ) return ' '; + + static char *word_characters = "@-./_~"; + if ( isalnum(ch) || strchr(word_characters, ch) ) + return 'a'; + + // Everything else is weird + return 1; +} + void TEWidget::setMouseMarks(bool on) { mouse_marks = on; @@ -662,8 +713,16 @@ void TEWidget::emitSelection() void TEWidget::setSelection(const char *t) { - QApplication::clipboard()->setText(t); - return; + // Disconnect signal while WE set the clipboard + QObject *cb = QApplication::clipboard(); + QObject::disconnect( cb, SIGNAL(dataChanged()), + this, SLOT(onClearSelection()) ); + + QApplication::clipboard()->setText(t); + + QObject::connect( cb, SIGNAL(dataChanged()), + this, SLOT(onClearSelection()) ); + return; } void TEWidget::onClearSelection() @@ -702,6 +761,11 @@ bool TEWidget::eventFilter( QObject *, QEvent *e ) case ShiftButton|(Key_PageDown << 8) : scrollbar->setValue(scrollbar->value()+lines/2); break; +#if 0 + case (Key_Insert << 8) : // Some progs use this. + emitSelection(); + break; +#endif default : emit keyPressedSignal(ke); // expose break; diff --git a/src/TEmuVt102.C b/src/TEmuVt102.C index 6aed5cfa..bc3d5e28 100644 --- a/src/TEmuVt102.C +++ b/src/TEmuVt102.C @@ -59,7 +59,7 @@ /*! */ -int maxHistLines = 100; +int maxHistLines = 2000; //#define MAXHISTLINES 100 // natural constant for now. VT102Emulation::VT102Emulation(TEWidget* gui, const char* term) : Emulation(gui)