00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "TEWidget.h"
00052 #include "session.h"
00053 #include <qpe/config.h>
00054
00055
00056 #if !(QT_NO_COP)
00057 #include <qpe/qcopenvelope_qws.h>
00058 #endif
00059
00060 #include <qclipboard.h>
00061
00062 #ifndef QT_NO_DRAGANDDROP
00063 #include <qdragobject.h>
00064 #include <qfile.h>
00065 #endif
00066
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <unistd.h>
00070 #include <ctype.h>
00071 #include <sys/stat.h>
00072 #include <sys/types.h>
00073 #include <signal.h>
00074
00075 #include <assert.h>
00076
00077
00078
00079
00080
00081
00082
00083
00084 #define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
00085 #define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
00086
00087 #define loc(X,Y) ((Y)*columns+(X))
00088
00089
00090 #define rimX 0 // left/right rim width
00091 #define rimY 0 // top/bottom rim high
00092
00093 #define SCRWIDTH 16 // width of the scrollbar
00094
00095 #define yMouseScroll 1
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 static const ColorEntry base_color_table[TABLE_COLORS] =
00107
00108
00109
00110 {
00111
00112
00113 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ),
00114 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ),
00115 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ),
00116 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
00117 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ),
00118
00119 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
00120 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
00121 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
00122 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
00123 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
00124 };
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 QColor TEWidget::getDefaultBackColor()
00135 {
00136 return color_table[DEFAULT_BACK_COLOR].color;
00137 }
00138
00139 const ColorEntry* TEWidget::getColorTable() const
00140 {
00141 return color_table;
00142 }
00143
00144 const ColorEntry* TEWidget::getdefaultColorTable() const
00145 {
00146 return base_color_table;
00147 }
00148
00149
00150 const QPixmap *TEWidget::backgroundPixmap()
00151 {
00152 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
00153 const QPixmap *pm = bg;
00154 return pm;
00155 }
00156
00157 void TEWidget::setColorTable(const ColorEntry table[])
00158 {
00159 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
00160
00161 const QPixmap* pm = backgroundPixmap();
00162 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
00163 update();
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 unsigned short vt100_graphics[32] =
00189 {
00190 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
00191 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
00192 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
00193 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
00194 };
00195
00196 static QChar vt100extended(QChar c)
00197 {
00198 switch (c.unicode())
00199 {
00200 case 0x25c6 : return 1;
00201 case 0x2592 : return 2;
00202 case 0x2409 : return 3;
00203 case 0x240c : return 4;
00204 case 0x240d : return 5;
00205 case 0x240a : return 6;
00206 case 0x00b0 : return 7;
00207 case 0x00b1 : return 8;
00208 case 0x2424 : return 9;
00209 case 0x240b : return 10;
00210 case 0x2518 : return 11;
00211 case 0x2510 : return 12;
00212 case 0x250c : return 13;
00213 case 0x2514 : return 14;
00214 case 0x253c : return 15;
00215 case 0xf800 : return 16;
00216 case 0xf801 : return 17;
00217 case 0x2500 : return 18;
00218 case 0xf803 : return 19;
00219 case 0xf804 : return 20;
00220 case 0x251c : return 21;
00221 case 0x2524 : return 22;
00222 case 0x2534 : return 23;
00223 case 0x252c : return 24;
00224 case 0x2502 : return 25;
00225 case 0x2264 : return 26;
00226 case 0x2265 : return 27;
00227 case 0x03c0 : return 28;
00228 case 0x2260 : return 29;
00229 case 0x00a3 : return 30;
00230 case 0x00b7 : return 31;
00231 }
00232 return c;
00233 }
00234
00235 static QChar identicalMap(QChar c)
00236 {
00237 return c;
00238 }
00239
00240 void TEWidget::fontChange(const QFont &)
00241 {
00242 QFontMetrics fm(font());
00243 font_h = fm.height();
00244
00245 font_w = fm.width("m");
00246 font_a = fm.ascent();
00247 printf("font h=%d max_width=%d width_m=%d assent=%d\n", font_h,
00248 fm.maxWidth(), font_w, font_a);
00249
00250
00251
00252
00253
00254
00255 fontMap =
00256 #if QT_VERSION < 0x030000
00257 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
00258 ? vt100extended
00259 :
00260 #endif
00261 identicalMap;
00262 propagateSize();
00263 update();
00264 }
00265
00266 void TEWidget::setVTFont(const QFont& f)
00267 {
00268 QFrame::setFont(f);
00269 }
00270
00271 QFont TEWidget::getVTFont() {
00272 return font();
00273 }
00274
00275 void TEWidget::setFont(const QFont &)
00276 {
00277
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
00287 {
00288 #ifndef QT_NO_CLIPBOARD
00289 cb = QApplication::clipboard();
00290 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
00291 this, SLOT(onClearSelection()) );
00292 #endif
00293
00294 scrollbar = new QScrollBar(this);
00295 scrollbar->setCursor( arrowCursor );
00296 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
00297
00298 hScrollbar = new QScrollBar(this);
00299 hScrollbar->setCursor( arrowCursor );
00300 hScrollbar->setOrientation(QScrollBar::Horizontal);
00301
00302
00303 connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int)));
00304
00305 Config cfg( "Konsole" );
00306 cfg.setGroup("ScrollBar");
00307 switch( cfg.readNumEntry("Position",2)){
00308 case 0:
00309 scrollLoc = SCRNONE;
00310 break;
00311 case 1:
00312 scrollLoc = SCRLEFT;
00313 break;
00314 case 2:
00315 scrollLoc = SCRRIGHT;
00316 break;
00317 };
00318
00319 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
00320
00321 blinkT = new QTimer(this);
00322 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
00323
00324 blinking = TRUE;
00325
00326 resizing = FALSE;
00327 actSel = 0;
00328 image = 0;
00329 lines = 1;
00330 columns = 1;
00331 font_w = 1;
00332 font_h = 1;
00333 font_a = 1;
00334 word_selection_mode = FALSE;
00335 hposition = 0;
00336 vcolumns = 0;
00337 useBeep = true;
00338
00339 setMouseMarks(TRUE);
00340 setVTFont( QFont("fixed") );
00341 setColorTable(base_color_table);
00342
00343 qApp->installEventFilter( this );
00344
00345
00346
00347 currentSession = NULL;
00348
00349
00350
00351
00352
00353
00354
00355 setFocus();
00356 setFocusPolicy( WheelFocus );
00357 }
00358
00359
00360
00361 TEWidget::~TEWidget()
00362 {
00363 qApp->removeEventFilter( this );
00364 if (image) free(image);
00365 }
00366
00367
00368
00369
00370
00371
00372
00377 void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
00378 QString& str, ca attr, BOOL pm, BOOL clear)
00379 {
00380 if (pm && color_table[attr.b].transparent)
00381 {
00382 paint.setBackgroundMode( TransparentMode );
00383 if (clear) erase(rect);
00384 }
00385 else
00386 {
00387 if (blinking)
00388 paint.fillRect(rect, color_table[attr.b].color);
00389 else
00390 {
00391 paint.setBackgroundMode( OpaqueMode );
00392 paint.setBackgroundColor( color_table[attr.b].color );
00393 }
00394 }
00395
00396 if (color_table[attr.f].bold)
00397 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
00398 else
00399 paint.setPen(color_table[attr.f].color);
00400
00401 paint.drawText(rect.x(),rect.y()+font_a, str);
00402
00403 if (attr.r & RE_UNDERLINE)
00404 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
00405 }
00406
00413 void TEWidget::setImage(const ca* const newimg, int lines, int columns)
00414 { int y,x,len;
00415 const QPixmap* pm = backgroundPixmap();
00416 QPainter paint;
00417 setUpdatesEnabled(FALSE);
00418 paint.begin( this );
00419 HCNT("setImage");
00420
00421 QPoint tL = contentsRect().topLeft();
00422 int tLx = tL.x();
00423 int tLy = tL.y();
00424 hasBlinker = FALSE;
00425
00426 int cf = -1;
00427 int cb = -1;
00428 int cr = -1;
00429
00430 int lins = QMIN(this->lines, QMAX(0,lines ));
00431 int cols = QMIN(this->columns,QMAX(0,columns));
00432 QChar *disstrU = new QChar[cols];
00433 for (y = 0; y < lins; y++) {
00434 const ca* lcl = &image[y*this->columns];
00435 const ca* const ext = &newimg[y*columns];
00436 if (!resizing)
00437 for (x = 0; x < cols; x++)
00438 {
00439 hasBlinker |= (ext[x].r & RE_BLINK);
00440 if (ext[x] != lcl[x])
00441 {
00442 cr = ext[x].r;
00443 cb = ext[x].b;
00444 if (ext[x].f != cf) cf = ext[x].f;
00445 int lln = cols - x;
00446 disstrU[0] = fontMap(ext[x+0].c);
00447 for (len = 1; len < lln; len++)
00448 {
00449 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
00450 ext[x+len] == lcl[x+len] )
00451 break;
00452 disstrU[len] = fontMap(ext[x+len].c);
00453 }
00454 QString unistr(disstrU,len);
00455 drawAttrStr(paint,
00456 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
00457 unistr, ext[x], pm != NULL, true);
00458 x += len - 1;
00459 }
00460 }
00461
00462 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
00463 }
00464 drawFrame( &paint );
00465 paint.end();
00466 setUpdatesEnabled(TRUE);
00467 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000);
00468 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
00469 delete [] disstrU;
00470 }
00471
00472
00473
00481 void TEWidget::paintEvent( QPaintEvent* pe )
00482 {
00483
00484
00485 const QPixmap* pm = backgroundPixmap();
00486 QPainter paint;
00487 setUpdatesEnabled(FALSE);
00488 paint.begin( this );
00489 paint.setBackgroundMode( TransparentMode );
00490 HCNT("paintEvent");
00491
00492
00493
00494
00495
00496
00497
00498 QRect rect = pe->rect().intersect(contentsRect());
00499
00500 QPoint tL = contentsRect().topLeft();
00501 int tLx = tL.x();
00502 int tLy = tL.y();
00503
00504 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
00505 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
00506 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
00507 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 QChar *disstrU = new QChar[columns];
00519 for (int y = luy; y <= rly; y++)
00520 for (int x = lux; x <= rlx; x++)
00521 {
00522 int len = 1;
00523 disstrU[0] = fontMap(image[loc(x,y)].c);
00524 int cf = image[loc(x,y)].f;
00525 int cb = image[loc(x,y)].b;
00526 int cr = image[loc(x,y)].r;
00527 while (x+len <= rlx &&
00528 image[loc(x+len,y)].f == cf &&
00529 image[loc(x+len,y)].b == cb &&
00530 image[loc(x+len,y)].r == cr )
00531 {
00532 disstrU[len] = fontMap(image[loc(x+len,y)].c);
00533 len += 1;
00534 }
00535 QString unistr(disstrU,len);
00536 drawAttrStr(paint,
00537 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
00538 unistr, image[loc(x,y)], pm != NULL, false);
00539 x += len - 1;
00540 }
00541 delete [] disstrU;
00542 drawFrame( &paint );
00543 paint.end();
00544 setUpdatesEnabled(TRUE);
00545 }
00546
00547 void TEWidget::blinkEvent()
00548 {
00549 blinking = !blinking;
00550 repaint(FALSE);
00551 }
00552
00553
00554
00555
00556
00557
00558
00559 void TEWidget::resizeEvent(QResizeEvent* ev)
00560 {
00561
00562
00563
00564
00565 HCNT("resizeEvent");
00566
00567
00568
00569 assert(ev->size().width() == width());
00570 assert(ev->size().height() == height());
00571
00572 propagateSize();
00573 }
00574
00575 void TEWidget::propagateSize()
00576 {
00577 ca* oldimg = image;
00578 int oldlin = lines;
00579 int oldcol = columns;
00580 makeImage();
00581
00582 int lins = QMIN(oldlin,lines);
00583 int cols = QMIN(oldcol,columns);
00584 if (oldimg)
00585 {
00586 for (int lin = 0; lin < lins; lin++)
00587 memcpy((void*)&image[columns*lin],
00588 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
00589 free(oldimg);
00590 }
00591 else
00592 clearImage();
00593
00594
00595
00596
00597 resizing = TRUE;
00598 emit changedImageSizeSignal(lines, columns);
00599 resizing = FALSE;
00600 }
00601
00602
00603
00604
00605
00606
00607
00608 void TEWidget::scrollChanged(int) {
00609 emit changedHistoryCursor(scrollbar->value());
00610 }
00611
00612 void TEWidget::hScrollChanged(int loc) {
00613 hposition = loc;
00614 propagateSize();
00615 update();
00616
00617
00618 }
00619
00620 void TEWidget::setScroll(int cursor, int slines)
00621 {
00622 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
00623 scrollbar->setRange(0,slines);
00624 scrollbar->setSteps(1,lines);
00625 scrollbar->setValue(cursor);
00626 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
00627 }
00628
00629 void TEWidget::setScrollbarLocation(int loc)
00630 {
00631 if (scrollLoc == loc) return;
00632 scrollLoc = loc;
00633 propagateSize();
00634 update();
00635 }
00636
00637
00638
00639
00640
00641
00642
00670 void TEWidget::mousePressEvent(QMouseEvent* ev)
00671 {
00672
00673 if ( !contentsRect().contains(ev->pos()) ) return;
00674 QPoint tL = contentsRect().topLeft();
00675 int tLx = tL.x();
00676 int tLy = tL.y();
00677
00678 mouse_down_x = ev->x();
00679 mouse_down_y = ev->y();
00680
00681
00682 if ( ev->button() == LeftButton)
00683 {
00684 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
00685
00686 word_selection_mode = (ev->state() & ShiftButton);
00687
00688 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
00689
00690 if (mouse_marks || (ev->state() & ShiftButton))
00691 {
00692 emit clearSelectionSignal();
00693 iPntSel = pntSel = pos;
00694 actSel = 1;
00695 grabMouse( );
00696 }
00697 else
00698 {
00699 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 );
00700 }
00701 }
00702 if ( ev->button() == MidButton )
00703 {
00704 emitSelection();
00705 }
00706 if ( ev->button() == RightButton )
00707 {
00708 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
00709 }
00710 }
00711
00712 void TEWidget::mouseMoveEvent(QMouseEvent* ev)
00713 {
00714
00715 if (ev->state() == NoButton ) return;
00716
00717 if (actSel == 0) return;
00718
00719
00720 if (ev->state() & MidButton) return;
00721
00722
00723 QPoint tL = contentsRect().topLeft();
00724 int tLx = tL.x();
00725 int tLy = tL.y();
00726 int scroll = scrollbar->value();
00727
00728
00729
00730
00731
00732
00733
00734 QPoint pos = ev->pos();
00735 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
00736 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
00737 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
00738 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
00739
00740 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
00741
00742 if ( pos.y() == tLy+bY+lines*font_h-1 )
00743 {
00744 scrollbar->setValue(scrollbar->value()+yMouseScroll);
00745 }
00746 if ( pos.y() == tLy+bY )
00747 {
00748 scrollbar->setValue(scrollbar->value()-yMouseScroll);
00749 }
00750
00751 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
00752 QPoint ohere;
00753 bool swapping = FALSE;
00754
00755 if ( word_selection_mode )
00756 {
00757
00758 int i;
00759 int selClass;
00760
00761 bool left_not_right = ( here.y() < iPntSel.y() ||
00762 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
00763 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
00764 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
00765 swapping = left_not_right != old_left_not_right;
00766
00767
00768 QPoint left = left_not_right ? here : iPntSel;
00769 i = loc(left.x(),left.y());
00770 selClass = charClass(image[i].c);
00771 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
00772 { i--; left.rx()--; }
00773
00774
00775 QPoint right = left_not_right ? iPntSel : here;
00776 i = loc(right.x(),right.y());
00777 selClass = charClass(image[i].c);
00778 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
00779 { i++; right.rx()++; }
00780
00781
00782 if ( left_not_right )
00783 {
00784 here = left; ohere = right;
00785 }
00786 else
00787 {
00788 here = right; ohere = left;
00789 }
00790 }
00791
00792 if (here == pntSel && scroll == scrollbar->value()) return;
00793
00794 if ( word_selection_mode ) {
00795 if ( actSel < 2 || swapping ) {
00796 emit beginSelectionSignal( ohere.x(), ohere.y() );
00797 }
00798 } else if ( actSel < 2 ) {
00799 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
00800 }
00801
00802 actSel = 2;
00803 pntSel = here;
00804 emit extendSelectionSignal( here.x(), here.y() );
00805 }
00806
00807 void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
00808 {
00809
00810 if ( ev->button() == LeftButton)
00811 {
00812 if (QABS(ev->x() - mouse_down_x) < 3
00813 && QABS(ev->y() - mouse_down_y) < 3
00814 && ev->y() < qApp->desktop()->height()/8) {
00815 emit setFullScreen(false);
00816 }
00817
00818 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
00819 preserve_line_breaks = TRUE;
00820 actSel = 0;
00821
00822
00823
00824
00825
00826 QPoint tL = contentsRect().topLeft();
00827 int tLx = tL.x();
00828 int tLy = tL.y();
00829
00830 if (!mouse_marks && !(ev->state() & ShiftButton))
00831 emit mouseSignal( 3,
00832 (ev->x()-tLx-blX)/font_w + 1,
00833 (ev->y()-tLy-bY)/font_h + 1 );
00834 releaseMouse();
00835 }
00836 }
00837
00838 void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
00839 {
00840 if ( ev->button() != LeftButton) return;
00841
00842 QPoint tL = contentsRect().topLeft();
00843 int tLx = tL.x();
00844 int tLy = tL.y();
00845 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
00846
00847
00848 if (!mouse_marks && !(ev->state() & ShiftButton))
00849 {
00850 emit mouseSignal( 0, pos.x()+1, pos.y()+1 );
00851 emit mouseSignal( 3, pos.x()+1, pos.y()+1 );
00852 emit mouseSignal( 0, pos.x()+1, pos.y()+1 );
00853 return;
00854 }
00855
00856
00857 emit clearSelectionSignal();
00858 QPoint bgnSel = pos;
00859 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
00860 int i = loc(bgnSel.x(),bgnSel.y());
00861 iPntSel = bgnSel;
00862
00863 word_selection_mode = TRUE;
00864
00865
00866 int selClass = charClass(image[i].c);
00867 {
00868
00869 int x = bgnSel.x();
00870 while ( x > 0 && charClass(image[i-1].c) == selClass )
00871 { i--; x--; }
00872 bgnSel.setX(x);
00873 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
00874
00875
00876 i = loc( endSel.x(), endSel.y() );
00877 x = endSel.x();
00878 while( x < columns-1 && charClass(image[i+1].c) == selClass )
00879 { i++; x++ ; }
00880 endSel.setX(x);
00881 actSel = 2;
00882 emit extendSelectionSignal( endSel.x(), endSel.y() );
00883 emit endSelectionSignal(preserve_line_breaks);
00884 preserve_line_breaks = TRUE;
00885 }
00886 }
00887
00888 void TEWidget::focusInEvent( QFocusEvent * )
00889 {
00890
00891
00892 }
00893
00894
00895 void TEWidget::focusOutEvent( QFocusEvent * )
00896 {
00897
00898 }
00899
00900 bool TEWidget::focusNextPrevChild( bool next )
00901 {
00902 if (next)
00903 return false;
00904
00905 return QFrame::focusNextPrevChild( next );
00906 }
00907
00908
00909 int TEWidget::charClass(char ch) const
00910 {
00911
00912
00913
00914
00915 if ( isspace(ch) ) return ' ';
00916
00917 static const char *word_characters = ":@-./_~";
00918 if ( isalnum(ch) || strchr(word_characters, ch) )
00919 return 'a';
00920
00921
00922 return 1;
00923 }
00924
00925 void TEWidget::setMouseMarks(bool on)
00926 {
00927 mouse_marks = on;
00928 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
00929 }
00930
00931
00932
00933
00934
00935
00936
00937 #undef KeyPress
00938
00939 void TEWidget::emitSelection()
00940
00941 {
00942 #ifndef QT_NO_CLIPBOARD
00943 QString text = QApplication::clipboard()->text();
00944
00945 if ( ! text.isNull())
00946 {
00947 text.replace(QRegExp("\n"), "\r");
00948 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
00949 emit keyPressedSignal(&e);
00950 emit clearSelectionSignal();
00951 }
00952 #endif
00953 }
00954
00955 void TEWidget::emitText(QString text)
00956 {
00957 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
00958 emit keyPressedSignal(&e);
00959 }
00960
00961 void TEWidget::pasteClipboard( )
00962 {
00963 emitSelection();
00964 }
00965
00966 void TEWidget::setSelection(const QString& t)
00967 {
00968 #ifndef QT_NO_CLIPBOARD
00969
00970 QObject *cb = QApplication::clipboard();
00971 QObject::disconnect( cb, SIGNAL(dataChanged()),
00972 this, SLOT(onClearSelection()) );
00973
00974 QApplication::clipboard()->setText(t);
00975
00976 QObject::connect( cb, SIGNAL(dataChanged()),
00977 this, SLOT(onClearSelection()) );
00978 #endif
00979 }
00980
00981 void TEWidget::onClearSelection()
00982 {
00983 emit clearSelectionSignal();
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 void TEWidget::doScroll(int lines)
01007 {
01008 scrollbar->setValue(scrollbar->value()+lines);
01009 }
01010
01011 void TEWidget::doHScroll(int lines) {
01012 hScrollbar->setValue( hScrollbar->value()+lines);
01013 }
01014
01015 bool TEWidget::eventFilter( QObject *obj, QEvent *e )
01016 {
01017 if ( (e->type() == QEvent::Accel ||
01018 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) {
01019 static_cast<QKeyEvent *>( e )->ignore();
01020 return true;
01021 }
01022 if ( obj != this && obj != parent() )
01023 return FALSE;
01024 if ( e->type() == QEvent::Wheel) {
01025 QApplication::sendEvent(scrollbar, e);
01026 }
01027
01028 #ifdef FAKE_CTRL_AND_ALT
01029 static bool control = FALSE;
01030 static bool alt = FALSE;
01031
01032 bool dele=FALSE;
01033 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
01034 QKeyEvent* ke = (QKeyEvent*)e;
01035 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
01036 switch (ke->key()) {
01037 case Key_F9:
01038 control = keydown;
01039 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
01040 dele=TRUE;
01041 break;
01042 case Key_F13:
01043 alt = keydown;
01044 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
01045 dele=TRUE;
01046 break;
01047 default:
01048 if ( control ) {
01049 int a = toupper(ke->ascii())-64;
01050 if ( a >= 0 && a < ' ' ) {
01051 e = new QKeyEvent(e->type(), ke->key(),
01052 a, ke->state()|ControlButton, QChar(a,0));
01053 dele=TRUE;
01054 }
01055 }
01056 if ( alt ) {
01057 e = new QKeyEvent(e->type(), ke->key(),
01058 ke->ascii(), ke->state()|AltButton, ke->text());
01059 dele=TRUE;
01060 }
01061 }
01062 }
01063 #endif
01064
01065 if ( e->type() == QEvent::KeyPress ) {
01066 QKeyEvent* ke = (QKeyEvent*)e;
01067 actSel=0;
01068
01069
01070
01071
01072 bool special_function = true;
01073 switch(ke->key()) {
01074
01075
01076
01077
01078
01079
01080 case 0x2016:
01081 case Key_F2:
01082 pasteClipboard();
01083 break;
01084
01085 case 0x2018:
01086 case Key_F3:
01087 emit changeSession(1);
01088 break;
01089
01090 case 0x2019:
01091 emit newSession();
01092 break;
01093
01094 case Qt::Key_Tab:
01095 if (ke->state() == ControlButton) {
01096 emit changeSession(1);
01097 } else {
01098 special_function = false;
01099 }
01100 break;
01101
01102 #if 0
01103 case Qt::Key_Left:
01104 if (vcolumns == 0) {
01105 emit changeSession(-1);
01106 } else {
01107 special_function = false;
01108 }
01109 break;
01110
01111 case Qt::Key_Right:
01112 if (vcolumns == 0) {
01113 emit changeSession(1);
01114 } else {
01115 special_function = false;
01116 }
01117 break;
01118 #endif
01119
01120 case 0x201b:
01121 case Key_F4:
01122 emit toggleFullScreen();
01123 break;
01124
01125 case 0x200f:
01126 case Key_F5:
01127 emit changeFontSize(-1);
01128 break;
01129
01130 case 0x2010:
01131 case Key_F6:
01132 emit changeFontSize(1);
01133 break;
01134
01135 default:
01136 special_function = false;
01137 }
01138 if (special_function) {
01139 return true;
01140 }
01141
01142
01143
01144
01145
01146
01147 emit keyPressedSignal(ke);
01148 ke->accept();
01149 #ifdef FAKE_CTRL_AND_ALT
01150 if ( dele ) delete e;
01151 #endif
01152 return true;
01153 }
01154 if ( e->type() == QEvent::Enter ) {
01155 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
01156 this, SLOT(onClearSelection()) );
01157 }
01158 if ( e->type() == QEvent::Leave ) {
01159 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
01160 this, SLOT(onClearSelection()) );
01161 }
01162 return QFrame::eventFilter( obj, e );
01163 }
01164
01165
01166
01167
01168
01169
01170
01171 void TEWidget::frameChanged()
01172 {
01173 propagateSize();
01174 update();
01175 }
01176
01177
01178
01179
01180
01181
01182 void TEWidget::Bell()
01183 {
01184
01185
01186 if(useBeep)
01187 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 }
01198
01199
01200
01201
01202
01203
01204
01205 void TEWidget::clearImage()
01206
01207
01208 {
01209 for (int y = 0; y < lines; y++)
01210 for (int x = 0; x < columns; x++)
01211 {
01212 image[loc(x,y)].c = 0xff;
01213 image[loc(x,y)].f = 0xff;
01214 image[loc(x,y)].b = 0xff;
01215 image[loc(x,y)].r = 0xff;
01216 }
01217 }
01218
01219
01220
01221 void TEWidget::calcGeometry()
01222 {
01223 int showhscrollbar = 1;
01224 int hwidth = 0;
01225 int dcolumns = 0;
01226 Config cfg( "Konsole" );
01227 cfg.setGroup("ScrollBar");
01228 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
01229
01230 if(vcolumns == 0) showhscrollbar = 0;
01231 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width();
01232
01233 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
01234 contentsRect().height() - hwidth);
01235
01236 switch(scrollLoc) {
01237 case SCRNONE :
01238 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
01239 dcolumns = columns;
01240 if(vcolumns) columns = vcolumns;
01241 blX = (contentsRect().width() - (columns*font_w) ) / 2;
01242 if(showhscrollbar)
01243 blX = -hposition * font_w;
01244 brX = blX;
01245 scrollbar->hide();
01246 break;
01247 case SCRLEFT :
01248 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
01249 dcolumns = columns;
01250 if(vcolumns) columns = vcolumns;
01251 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
01252 if(showhscrollbar)
01253 brX = -hposition * font_w;
01254 blX = brX + scrollbar->width();
01255 scrollbar->move(contentsRect().topLeft());
01256 scrollbar->show();
01257 break;
01258 case SCRRIGHT:
01259 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
01260 dcolumns = columns;
01261 if(vcolumns) columns = vcolumns;
01262 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
01263 if(showhscrollbar)
01264 blX = -hposition * font_w;
01265 brX = blX;
01266 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
01267 scrollbar->show();
01268 break;
01269 }
01270
01271 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
01272 bY = (contentsRect().height() - (lines *font_h)) / 2;
01273
01274 if(showhscrollbar == 1) {
01275 hScrollbar->resize(contentsRect().width() - hwidth, hwidth);
01276 hScrollbar->setRange(0, vcolumns - dcolumns);
01277
01278 QPoint p = contentsRect().bottomLeft();
01279 if(scrollLoc == SCRLEFT)
01280 hScrollbar->move(QPoint(p.x()+hwidth, p.y() - hwidth));
01281 else
01282 hScrollbar->move(QPoint(p.x(), p.y() - hwidth));
01283
01284 hScrollbar->show();
01285 }
01286 else hScrollbar->hide();
01287
01288 if(showhscrollbar == 1) {
01289 lines = lines - (hwidth / font_h) - 1;
01290 if(lines < 1) lines = 1;
01291 }
01292
01293 }
01294
01295 void TEWidget::makeImage()
01296
01297 {
01298 calcGeometry();
01299 image = (ca*) malloc(lines*columns*sizeof(ca));
01300 clearImage();
01301 }
01302
01303
01304 QSize TEWidget::calcSize(int cols, int lins) const
01305 {
01306 int frw = width() - contentsRect().width();
01307 int frh = height() - contentsRect().height();
01308 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
01309 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
01310 }
01311
01312 QSize TEWidget::sizeHint() const
01313 {
01314 return size();
01315 }
01316
01317 void TEWidget::styleChange(QStyle &)
01318 {
01319 propagateSize();
01320 }
01321
01322 #ifndef QT_NO_DRAGANDDROP
01323
01324
01325
01326
01327
01328
01329
01330
01331 void TEWidget::dragEnterEvent(QDragEnterEvent* e)
01332 {
01333 e->accept(QTextDrag::canDecode(e) ||
01334 QUriDrag::canDecode(e));
01335 }
01336
01337 void TEWidget::dropEvent(QDropEvent* event)
01338 {
01339
01340
01341
01342
01343 QStrList strlist;
01344 int file_count = 0;
01345 dropText = "";
01346 bool bPopup = true;
01347
01348 if(QUriDrag::decode(event, strlist)) {
01349 if (strlist.count()) {
01350 for(const char* p = strlist.first(); p; p = strlist.next()) {
01351 if(file_count++ > 0) {
01352 dropText += " ";
01353 bPopup = false;
01354 }
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 }
01368
01369 if (bPopup)
01370
01371 m_drop->popup(mapToGlobal(event->pos()));
01372 else
01373 {
01374 if (currentSession) {
01375 currentSession->getEmulation()->sendString(dropText.local8Bit());
01376 }
01377
01378 }
01379 }
01380 }
01381 else if(QTextDrag::decode(event, dropText)) {
01382
01383 if (currentSession) {
01384 currentSession->getEmulation()->sendString(dropText.local8Bit());
01385 }
01386
01387 }
01388 }
01389 #endif
01390
01391
01392 void TEWidget::drop_menu_activated(int item)
01393 {
01394 #ifndef QT_NO_DRAGANDDROP
01395 switch (item)
01396 {
01397 case 0:
01398 currentSession->getEmulation()->sendString(dropText.local8Bit());
01399
01400 break;
01401 case 1:
01402 currentSession->getEmulation()->sendString("cd ");
01403 struct stat statbuf;
01404 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
01405 {
01406 if ( !S_ISDIR(statbuf.st_mode) )
01407 {
01408
01409
01410
01411
01412
01413 }
01414 }
01415 dropText.replace(QRegExp(" "), "\\ ");
01416 currentSession->getEmulation()->sendString(dropText.local8Bit());
01417 currentSession->getEmulation()->sendString("\n");
01418
01419 break;
01420 }
01421 #else
01422 Q_UNUSED(item);
01423 #endif
01424 }
01425
01426 void TEWidget::setWrapAt(int columns)
01427 {
01428 vcolumns = columns;
01429 propagateSize();
01430 update();
01431 }