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