Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TEWidget.cpp

Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------ */
00002 /*                                                                          */
00003 /* [TEWidget.C]            Terminal Emulation Widget                        */
00004 /*                                                                          */
00005 /* ------------------------------------------------------------------------ */
00006 /*                                                                          */
00007 /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>          */
00008 /*                                                                          */
00009 /* This file is part of Konsole - an X terminal for KDE                     */
00010 /*                                                                          */
00011 /* ------------------------------------------------------------------------ */
00012 /*                        */
00013 /* Ported Konsole to Qt/Embedded                                              */
00014 /*                        */
00015 /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com>                  */
00016 /*                        */
00017 /* -------------------------------------------------------------------------- */
00039 /* FIXME:
00040    - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
00041    - 'font_a' not used in mouse events
00042    - add destructor
00043 */
00044 
00045 /* TODO
00046    - evtl. be sensitive to `paletteChange' while using default colors.
00047    - set different 'rounding' styles? I.e. have a mode to show clipped chars?
00048 */
00049 
00050 // #include "config.h"
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 // #include "TEWidget.moc"
00070 //#include <kapp.h>
00071 //#include <kcursor.h>
00072 //#include <kurl.h>
00073 //#include <kdebug.h>
00074 //#include <klocale.h>
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 //FIXME: the rim should normally be 1, 0 only when running in full screen mode.
00082 #define rimX 0      // left/right rim width
00083 #define rimY 0      // top/bottom rim high
00084 
00085 #define yMouseScroll 1
00086 // scroll increment used when dragging selection at top/bottom of window.
00087 
00088 /* Button XPM */
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 /*                                Colors                                     */
00116 /*                                                                           */
00117 /* ------------------------------------------------------------------------- */
00118 
00119 //FIXME: the default color table is in session.C now.
00120 //       We need a way to get rid of this one, here.
00121 static const ColorEntry base_color_table[TABLE_COLORS] =
00122 // The following are almost IBM standard color codes, with some slight
00123 // gamma correction for the dim colors to compensate for bright X screens.
00124 // It contains the 8 ansiterm/xterm colors in 2 intensities.
00125 {
00126   // Fixme: could add faint colors here, also.
00127   // normal
00128   ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
00129   ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
00130   ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
00131   ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue,  Magenta
00132   ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan,  White
00133   // intensiv
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 /* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
00142 
00143    Code        0       1       2       3       4       5       6       7
00144    ----------- ------- ------- ------- ------- ------- ------- ------- -------
00145    ANSI  (bgr) Black   Red     Green   Yellow  Blue    Magenta Cyan    White
00146    IBMPC (rgb) Black   Blue    Green   Cyan    Red     Magenta Yellow  White
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 //FIXME: add backgroundPixmapChanged.
00182 
00183 /* ------------------------------------------------------------------------- */
00184 /*                                                                           */
00185 /*                                   Font                                    */
00186 /*                                                                           */
00187 /* ------------------------------------------------------------------------- */
00188 
00189 /*
00190    The VT100 has 32 special graphical characters. The usual vt100 extended
00191    xterm fonts have these at 0x00..0x1f.
00192 
00193    QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
00194    come in here as proper unicode characters.
00195 
00196    We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
00197    from unicode to 0x00..0x1f. The remaining translation is then left to the
00198    QCodec.
00199 */
00200 
00201 // assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
00202 
00203 unsigned short vt100_graphics[32] =
00204 { // 0/8     1/9    2/10    3/11    4/12    5/13    6/14    7/15
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 //printf("font_h: %d\n",font_h);
00262 //printf("font_w: %d\n",font_w);
00263 //printf("font_a: %d\n",font_a);
00264 //printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
00265 //printf("rawname: %s\n",font().rawName().ascii());
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   // ignore font change request if not coming from konsole itself
00289 }
00290 
00291 /* ------------------------------------------------------------------------- */
00292 /*                                                                           */
00293 /*                         Constructor / Destructor                          */
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   // bugfix for #1647
00327   // if user set 'show scrollbar on left' then let it be on left
00328   // but only if it is not set in opie-console itself
00329   if(scrollLoc == -1)
00330   {
00331       Config qpecfg ("qpe");
00332       qpecfg.setGroup("Appearance");
00333       scrollLoc = qpecfg.readNumEntry("LeftHand", SCRRIGHT);
00334       if(scrollLoc == 0)    // user set LeftHand in past and switched it off later
00335       {
00336           scrollLoc = SCRRIGHT;
00337       }
00338   };
00339 
00340   blinkT   = new QTimer(this);
00341   connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
00342   // blinking = FALSE;
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); // init color table
00360 
00361   qApp->installEventFilter( this ); //FIXME: see below
00362 //  KCursor::setAutoHideCursor( this, true );
00363 
00364   // Init DnD ////////////////////////////////////////////////////////////////
00365   currentSession = NULL;
00366 //  setAcceptDrops(true); // attempt
00367 //  m_drop = new QPopupMenu(this);
00368 //  m_drop->insertItem( QString("Paste"), 0);
00369 //  m_drop->insertItem( QString("cd"),    1);
00370 //  connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
00371 
00372   // we need focus so that the auto-hide cursor feature works
00373   setFocus();
00374   setFocusPolicy( WheelFocus );
00375 }
00376 
00377 //FIXME: make proper destructor
00378 // Here's a start (David)
00379 TEWidget::~TEWidget()
00380 {
00381   qApp->removeEventFilter( this );
00382   if (image) free(image);
00383 }
00384 
00385 /* ------------------------------------------------------------------------- */
00386 /*                                                                           */
00387 /*                             Display Operations                            */
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; // undefined
00445   int cb  = -1; // undefined
00446   int cr  = -1; // undefined
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 //{ static int cnt = 0; printf("setImage %d\n",cnt++); }
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) // not while resizing, we're expecting a paintEvent
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     // finally, make `image' become `newimg'.
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); // 1000 ms
00489   if (!hasBlinker &&  blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
00490   delete [] disstrU;
00491 }
00492 
00493 // paint Event ////////////////////////////////////////////////////
00494 
00502 void TEWidget::paintEvent( QPaintEvent* pe )
00503 {
00504 
00505 //{ static int cnt = 0; printf("paint %d\n",cnt++); }
00506   const QPixmap* pm = backgroundPixmap();
00507   QPainter paint;
00508   setUpdatesEnabled(FALSE);
00509   paint.begin( this );
00510   paint.setBackgroundMode( TransparentMode );
00511 HCNT("paintEvent");
00512 
00513   // Note that the actual widget size can be slightly larger
00514   // that the image (the size is truncated towards the smaller
00515   // number of characters in `resizeEvent'. The paint rectangle
00516   // can thus be larger than the image, but less then the size
00517   // of one character.
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  printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
00532   rect.left(), rect.right(), rect.top(), rect.bottom());
00533   */
00534 
00535   //  if (pm != NULL && color_table[image->b].transparent)
00536   //  erase(rect);
00537   // BL: I have no idea why we need this, and it breaks the refresh.
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 /*                                  Resizing                                 */
00577 /*                                                                           */
00578 /* ------------------------------------------------------------------------- */
00579 
00580 void TEWidget::resizeEvent(QResizeEvent* ev)
00581 {
00582 //  printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
00583   //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
00584   //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
00585   //printf("curren: %d,%d\n",width(),height());
00586 HCNT("resizeEvent");
00587 
00588   // see comment in `paintEvent' concerning the rounding.
00589   //FIXME: could make a routine here; check width(),height()
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   // we copy the old image to reduce flicker
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); //FIXME: try new,delete
00611   }
00612   else
00613     clearImage();
00614 
00615   //NOTE: control flows from the back through the chest right into the eye.
00616   //      `emu' will call back via `setImage'.
00617 
00618   resizing = TRUE;
00619   emit changedImageSizeSignal(lines, columns); // expose resizeEvent
00620   resizing = FALSE;
00621 }
00622 
00623 /* ------------------------------------------------------------------------- */
00624 /*                                                                           */
00625 /*                                Scrollbar                                  */
00626 /*                                                                           */
00627 /* ------------------------------------------------------------------------- */
00628 
00629 void TEWidget::scrollChanged(int)
00630 {
00631   emit changedHistoryCursor(scrollbar->value()); //expose
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; // quickly
00653   scrollLoc = loc;
00654   propagateSize();
00655   update();
00656 }
00657 
00658 /* ------------------------------------------------------------------------- */
00659 /*                                                                           */
00660 /*                                   Mouse                                   */
00661 /*                                                                           */
00662 /* ------------------------------------------------------------------------- */
00663 
00691 void TEWidget::mousePressEvent(QMouseEvent* ev)
00692 {
00693 //printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
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 //printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
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; // left mouse button pressed but nothing selected yet.
00713       grabMouse(   /*crossCursor*/  ); // handle with care!
00714     }
00715     else
00716     {
00717       emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
00718     }
00719   }
00720   if ( ev->button() == MidButton )
00721   {
00722     emitSelection();
00723   }
00724   if ( ev->button() == RightButton ) // Configure
00725   {
00726     emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
00727   }
00728 }
00729 
00730 void TEWidget::mouseMoveEvent(QMouseEvent* ev)
00731 {
00732   // for auto-hiding the cursor, we need mouseTracking
00733   if (ev->state() == NoButton ) return;
00734 
00735   if (actSel == 0) return;
00736 
00737  // don't extend selection while pasting
00738   if (ev->state() & MidButton) return;
00739 
00740   //if ( !contentsRect().contains(ev->pos()) ) return;
00741   QPoint tL  = contentsRect().topLeft();
00742   int    tLx = tL.x();
00743   int    tLy = tL.y();
00744   int    scroll = scrollbar->value();
00745 
00746   // we're in the process of moving the mouse with the left button pressed
00747   // the mouse cursor will kept catched within the bounds of the text in
00748   // this widget.
00749 
00750   // Adjust position within text area bounds. See FIXME above.
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   // check if we produce a mouse move event by this
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); // scrollforward
00762   }
00763   if ( pos.y() == tLy+bY )
00764   {
00765     scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
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     // Extend to word boundaries
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     // Find left (left_not_right ? from here : from start)
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     // Find left (left_not_right ? from start : from here)
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     // Pick which is start (ohere) and which is extension (here)
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; // not moved
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; // within selection
00820   pntSel = here;
00821   emit extendSelectionSignal( here.x(), here.y() );
00822 }
00823 
00824 void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
00825 {
00826 //printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
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     //FIXME: emits a release event even if the mouse is
00834     //       outside the range. The procedure used in `mouseMoveEvent'
00835     //       applies here, too.
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, // release
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   // pass on double click as two clicks.
00859   if (!mouse_marks && !(ev->state() & ShiftButton))
00860   {
00861     emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
00862     emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
00863     emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
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   // find word boundaries...
00877   int selClass = charClass(image[i].c);
00878   {
00879     // set the start...
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      // set the end...
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; // within selection
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     // do nothing, to prevent repainting
00903 }
00904 
00905 
00906 void TEWidget::focusOutEvent( QFocusEvent * )
00907 {
00908     // do nothing, to prevent repainting
00909 }
00910 
00911 bool TEWidget::focusNextPrevChild( bool next )
00912 {
00913   if (next)
00914     return false; // This disables changing the active part in konqueror
00915                   // when pressing Tab
00916   return QFrame::focusNextPrevChild( next );
00917 }
00918 
00919 
00920 int TEWidget::charClass(char ch) const
00921 {
00922     // This might seem like overkill, but imagine if ch was a Unicode
00923     // character (Qt 2.0 QChar) - it might then be sensible to separate
00924     // the different language ranges, etc.
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     // Everything else is weird
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 /*                               Clipboard                                   */
00945 /*                                                                           */
00946 /* ------------------------------------------------------------------------- */
00947 
00948 #undef KeyPress
00949 
00950 void TEWidget::emitSelection()
00951 // Paste Clipboard by simulating keypress events
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); // expose as a big fat keypress event
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); // expose as a big fat keypress event
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   // Disconnect signal while WE set the clipboard
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 /*                                Keyboard                                   */
00999 /*                                                                           */
01000 /* ------------------------------------------------------------------------- */
01001 
01002 //FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
01003 //       due to a bug in `QT' or the ignorance of the author to prevent
01004 //       repaint events being emitted to the screen whenever one leaves
01005 //       or reenters the screen to/from another application.
01006 //
01007 //   Troll says one needs to change focusInEvent() and focusOutEvent(),
01008 //   which would also let you have an in-focus cursor and an out-focus
01009 //   cursor like xterm does.
01010 
01011 // for the auto-hide cursor feature, I added empty focusInEvent() and
01012 // focusOutEvent() so that update() isn't called.
01013 // For auto-hide, we need to get keypress-events, but we only get them when
01014 // we have focus.
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 /* when embedded */ && obj != parent() /* when standalone */ )
01029         return FALSE; // not us
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: // let this be "Control"
01043               control = keydown;
01044               e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
01045               dele=TRUE;
01046               break;
01047           case Key_F13: // let this be "Alt"
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; // Key stroke implies a screen update, so TEWidget won't
01073           // know where the current selection is.
01074 
01075 
01076         if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker
01077             emitText("\\"); // expose
01078         } else
01079             emit keyPressedSignal(ke); // expose
01080         ke->accept();
01081 #ifdef FAKE_CTRL_AND_ALT
01082         if ( dele ) delete e;
01083 #endif
01084         return true;               // stop the event
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 /*                                  Frame                                    */
01100 /*                                                                           */
01101 /* ------------------------------------------------------------------------- */
01102 
01103 void TEWidget::frameChanged()
01104 {
01105   propagateSize();
01106   update();
01107 }
01108 
01109 /* ------------------------------------------------------------------------- */
01110 /*                                                                           */
01111 /*                                   Sound                                   */
01112 /*                                                                           */
01113 /* ------------------------------------------------------------------------- */
01114 
01115 void TEWidget::Bell()
01116 {
01117   QApplication::beep();
01118 }
01119 
01120 /* ------------------------------------------------------------------------- */
01121 /*                                                                           */
01122 /*                                 Auxiluary                                 */
01123 /*                                                                           */
01124 /* ------------------------------------------------------------------------- */
01125 
01126 void TEWidget::clearImage()
01127 // initialize the image
01128 // for internal use only
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; //DEFAULT_FORE_COLOR;
01135     image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
01136     image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
01137   }
01138 }
01139 
01140 // Create Image ///////////////////////////////////////////////////////
01141 
01142 void TEWidget::calcGeometry()
01143 {
01144   //FIXME: set rimX == rimY == 0 when running in full screen mode.
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   //FIXME: support 'rounding' styles
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 //FIXME: rename 'calcGeometry?
01219 {
01220   calcGeometry();
01221   image = (ca*) malloc(lines*columns*sizeof(ca));
01222   clearImage();
01223 }
01224 
01225 // calculate the needed size
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 /* Drag & Drop                                                           */
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     // The current behaviour when url(s) are dropped is
01262     // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
01263     // * in all other cases, just paste
01264     //   (for non-local ones, or for a list of URLs, 'cd' is nonsense)
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; // more than one file, don't popup
01276         }
01277 
01278 /*
01279         KURL url(p);
01280         if (url.isLocalFile()) {
01281           dropText += url.path(); // local URL : remove protocol
01282         }
01283         else {
01284           dropText += url.prettyURL();
01285           bPopup = false; // a non-local file, don't popup
01286         }
01287 */
01288 
01289       }
01290 
01291       if (bPopup)
01292         // m_drop->popup(pos() + event->pos());
01293   m_drop->popup(mapToGlobal(event->pos()));
01294       else
01295   {
01296     if (currentSession) {
01297       currentSession->getEmulation()->sendString(dropText.local8Bit());
01298     }
01299 //    kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
01300   }
01301     }
01302   }
01303   else if(QTextDrag::decode(event, dropText)) {
01304 //    kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
01305     if (currentSession) {
01306       currentSession->getEmulation()->sendString(dropText.local8Bit());
01307     }
01308     // Paste it
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: // paste
01320       currentSession->getEmulation()->sendString(dropText.local8Bit());
01321 //    KWM::activate((Window)this->winId());
01322       break;
01323     case 1: // cd ...
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           KURL url;
01332           url.setPath( dropText );
01333           dropText = url.directory( true, false ); // remove filename
01334 */
01335         }
01336       }
01337       dropText.replace(QRegExp(" "), "\\ "); // escape spaces
01338       currentSession->getEmulation()->sendString(dropText.local8Bit());
01339       currentSession->getEmulation()->sendString("\n");
01340 //    KWM::activate((Window)this->winId());
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 

Generated on Sat Nov 5 16:15:28 2005 for OPIE by  doxygen 1.4.2