-rw-r--r-- | core/apps/embeddedkonsole/TEHistory.h | 6 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/TEScreen.h | 14 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/TEWidget.cpp | 5 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/TEmulation.h | 7 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/konsole.cpp | 90 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/konsole.h | 1 |
6 files changed, 83 insertions, 40 deletions
diff --git a/core/apps/embeddedkonsole/TEHistory.h b/core/apps/embeddedkonsole/TEHistory.h index 8339ec6..11eb150 100644 --- a/core/apps/embeddedkonsole/TEHistory.h +++ b/core/apps/embeddedkonsole/TEHistory.h @@ -1,75 +1,75 @@ /* -------------------------------------------------------------------------- */ /* */ /* [TEHistory.H] History Buffer */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole - an X terminal for KDE */ /* */ /* -------------------------------------------------------------------------- */ -/* */ +/* */ /* Ported Konsole to Qt/Embedded */ -/* */ +/* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ -/* */ +/* */ /* -------------------------------------------------------------------------- */ #ifndef TEHISTORY_H #define TEHISTORY_H #include "TECommon.h" /* An extendable tmpfile(1) based buffer. */ class HistoryBuffer { public: HistoryBuffer(); ~HistoryBuffer(); public: void setScroll(bool on); bool hasScroll(); public: void add(const unsigned char* bytes, int len); void get(unsigned char* bytes, int len, int loc); int len(); private: int ion; int length; }; class HistoryScroll { public: HistoryScroll(); ~HistoryScroll(); public: void setScroll(bool on); bool hasScroll(); public: // access to history int getLines(); int getLineLen(int lineno); void getCells(int lineno, int colno, int count, ca res[]); public: // backward compatibility (obsolete) ca getCell(int lineno, int colno) { ca res; getCells(lineno,colno,1,&res); return res; } public: // adding lines. void addCells(ca a[], int count); void addLine(); private: int startOfLine(int lineno); HistoryBuffer index; // lines Row(int) HistoryBuffer cells; // text Row(ca) }; #endif // TEHISTORY_H diff --git a/core/apps/embeddedkonsole/TEScreen.h b/core/apps/embeddedkonsole/TEScreen.h index ba47ee5..a28f7c5 100644 --- a/core/apps/embeddedkonsole/TEScreen.h +++ b/core/apps/embeddedkonsole/TEScreen.h @@ -1,259 +1,267 @@ /* -------------------------------------------------------------------------- */ /* */ /* [te_screen.h] Screen Data Type */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole - an X terminal for KDE */ /* */ /* -------------------------------------------------------------------------- */ -/* */ +/* */ /* Ported Konsole to Qt/Embedded */ -/* */ +/* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ -/* */ +/* */ /* -------------------------------------------------------------------------- */ #ifndef TESCREEN_H #define TESCREEN_H /*! \file */ #include "TECommon.h" #include "TEHistory.h" #define MODE_Origin 0 #define MODE_Wrap 1 #define MODE_Insert 2 #define MODE_Screen 3 #define MODE_Cursor 4 #define MODE_NewLine 5 #define MODES_SCREEN 6 /*! */ struct ScreenParm { int mode[MODES_SCREEN]; }; class TEScreen { public: TEScreen(int lines, int columns); ~TEScreen(); public: // these are all `Screen' operations // // VT100/2 Operations ------------------ // // Cursor Movement // void cursorUp (int n); void cursorDown (int n); void cursorLeft (int n); void cursorRight (int n); void setCursorY (int y); void setCursorX (int x); void setCursorYX (int y, int x); void setMargins (int t, int b); // // Cursor Movement with Scrolling // void NewLine (); void NextLine (); void index (); void reverseIndex(); // void Return (); void BackSpace (); void Tabulate (); // // Editing // void eraseChars (int n); void deleteChars (int n); void insertChars (int n); void deleteLines (int n); void insertLines (int n); // // ------------------------------------- // void clearTabStops(); void changeTabStop(bool set); // void resetMode (int n); void setMode (int n); void saveMode (int n); void restoreMode (int n); // void saveCursor (); void restoreCursor(); // // ------------------------------------- // void clearEntireScreen(); void clearToEndOfScreen(); void clearToBeginOfScreen(); // void clearEntireLine(); void clearToEndOfLine(); void clearToBeginOfLine(); // void helpAlign (); // // ------------------------------------- // void setRendition (int rendition); void resetRendition(int rendition); void setForeColor (int fgcolor); void setBackColor (int bgcolor); // void setDefaultRendition(); void setForeColorToDefault(); void setBackColorToDefault(); // // ------------------------------------- // BOOL getMode (int n); // // only for report cursor position // int getCursorX(); int getCursorY(); // // ------------------------------------- // void clear(); void home(); void reset(); // void ShowCharacter(unsigned short c); // void resizeImage(int new_lines, int new_columns); // ca* getCookedImage(); /*! return the number of lines. */ int getLines() { return lines; } + /*! return the number of columns. */ int getColumns() { return columns; } /*! set the position of the history cursor. */ void setHistCursor(int cursor); /*! return the position of the history cursor. */ int getHistCursor(); + /*! set the position of the horizontal cursor. */ + void setHorzCursor(int cursor); + /*! return the position of the horizontal cursor. */ + int getHorzCursor(); + int getHistLines (); void setScroll(bool on); bool hasScroll(); // // Selection // void setSelBeginXY(const int x, const int y); void setSelExtentXY(const int x, const int y); void clearSelection(); QString getSelText(const BOOL preserve_line_breaks); void checkSelection(int from, int to); private: // helper void clearImage(int loca, int loce, char c); void moveImage(int dst, int loca, int loce); void scrollUp(int from, int i); void scrollDown(int from, int i); void addHistLine(); void initTabStops(); void effectiveRendition(); void reverseRendition(ca* p); private: /* The state of the screen is more complex as one would expect first. The screem does really do part of the emulation providing state informations in form of modes, margins, tabulators, cursor etc. Even more unexpected are variables to save and restore parts of the state. */ // screen image ---------------- int lines; int columns; ca *image; // [lines][columns] // history buffer --------------- int histCursor; // display position relative to start of the history buffer HistoryScroll hist; + + int horzCursor; // cursor location int cuX; int cuY; // cursor color and rendition info UINT8 cu_fg; // foreground UINT8 cu_bg; // background UINT8 cu_re; // rendition // margins ---------------- int tmargin; // top margin int bmargin; // bottom margin // states ---------------- ScreenParm currParm; // ---------------------------- bool* tabstops; // selection ------------------- int sel_begin; // The first location selected. int sel_TL; // TopLeft Location. int sel_BR; // Bottom Right Location. // effective colors and rendition ------------ UINT8 ef_fg; // These are derived from UINT8 ef_bg; // the cu_* variables above UINT8 ef_re; // to speed up operation // // save cursor, rendition & states ------------ // // cursor location int sa_cuX; int sa_cuY; // rendition info UINT8 sa_cu_re; UINT8 sa_cu_fg; UINT8 sa_cu_bg; // modes ScreenParm saveParm; }; #endif // TESCREEN_H diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp index c10c7a8..60021f4 100644 --- a/core/apps/embeddedkonsole/TEWidget.cpp +++ b/core/apps/embeddedkonsole/TEWidget.cpp @@ -1,1407 +1,1406 @@ /* ------------------------------------------------------------------------ */ /* */ /* [TEWidget.C] Terminal Emulation Widget */ /* */ /* ------------------------------------------------------------------------ */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole - an X terminal for KDE */ /* */ /* ------------------------------------------------------------------------ */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ /*! \class TEWidget \brief Visible screen contents This class is responsible to map the `image' of a terminal emulation to the display. All the dependency of the emulation to a specific GUI or toolkit is localized here. Further, this widget has no knowledge about being part of an emulation, it simply work within the terminal emulation framework by exposing size and key events and by being ordered to show a new image. <ul> <li> The internal image has the size of the widget (evtl. rounded up) <li> The external image used in setImage can have any size. <li> (internally) the external image is simply copied to the internal when a setImage happens. During a resizeEvent no painting is done a paintEvent is expected to follow anyway. </ul> \sa TEScreen \sa Emulation */ /* FIXME: - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent - 'font_a' not used in mouse events - add destructor */ /* TODO - evtl. be sensitive to `paletteChange' while using default colors. - set different 'rounding' styles? I.e. have a mode to show clipped chars? */ // #include "config.h" #include "TEWidget.h" #include "session.h" #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/sound.h> #ifdef QWS #include <qpe/qcopenvelope_qws.h> #endif #include <qcursor.h> #include <qregexp.h> #include <qpainter.h> #include <qclipboard.h> #include <qstyle.h> #include <qfile.h> #include <qdragobject.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <ctype.h> #include <sys/stat.h> #include <sys/types.h> #include <signal.h> #include <assert.h> // #include "TEWidget.moc" //#include <kapp.h> //#include <kcursor.h> //#include <kurl.h> //#include <kdebug.h> //#include <klocale.h> #define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__) #define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); } #define loc(X,Y) ((Y)*columns+(X)) //FIXME: the rim should normally be 1, 0 only when running in full screen mode. #define rimX 0 // left/right rim width #define rimY 0 // top/bottom rim high #define SCRWIDTH 16 // width of the scrollbar #define yMouseScroll 1 // scroll increment used when dragging selection at top/bottom of window. /* ------------------------------------------------------------------------- */ /* */ /* Colors */ /* */ /* ------------------------------------------------------------------------- */ //FIXME: the default color table is in session.C now. // We need a way to get rid of this one, here. static const ColorEntry base_color_table[TABLE_COLORS] = // The following are almost IBM standard color codes, with some slight // gamma correction for the dim colors to compensate for bright X screens. // It contains the 8 ansiterm/xterm colors in 2 intensities. { // Fixme: could add faint colors here, also. // normal ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White // intensiv ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ), ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ), ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 ) }; /* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb) Code 0 1 2 3 4 5 6 7 ----------- ------- ------- ------- ------- ------- ------- ------- ------- ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White */ QColor TEWidget::getDefaultBackColor() { return color_table[DEFAULT_BACK_COLOR].color; } const ColorEntry* TEWidget::getColorTable() const { return color_table; } const ColorEntry* TEWidget::getdefaultColorTable() const { return base_color_table; } const QPixmap *TEWidget::backgroundPixmap() { static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm"); const QPixmap *pm = bg; return pm; } void TEWidget::setColorTable(const ColorEntry table[]) { for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i]; const QPixmap* pm = backgroundPixmap(); if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color); update(); } //FIXME: add backgroundPixmapChanged. /* ------------------------------------------------------------------------- */ /* */ /* Font */ /* */ /* ------------------------------------------------------------------------- */ /* The VT100 has 32 special graphical characters. The usual vt100 extended xterm fonts have these at 0x00..0x1f. QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals come in here as proper unicode characters. We treat non-iso10646 fonts as VT100 extended and do the requiered mapping from unicode to 0x00..0x1f. The remaining translation is then left to the QCodec. */ // assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. unsigned short vt100_graphics[32] = { // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 }; static QChar vt100extended(QChar c) { switch (c.unicode()) { case 0x25c6 : return 1; case 0x2592 : return 2; case 0x2409 : return 3; case 0x240c : return 4; case 0x240d : return 5; case 0x240a : return 6; case 0x00b0 : return 7; case 0x00b1 : return 8; case 0x2424 : return 9; case 0x240b : return 10; case 0x2518 : return 11; case 0x2510 : return 12; case 0x250c : return 13; case 0x2514 : return 14; case 0x253c : return 15; case 0xf800 : return 16; case 0xf801 : return 17; case 0x2500 : return 18; case 0xf803 : return 19; case 0xf804 : return 20; case 0x251c : return 21; case 0x2524 : return 22; case 0x2534 : return 23; case 0x252c : return 24; case 0x2502 : return 25; case 0x2264 : return 26; case 0x2265 : return 27; case 0x03c0 : return 28; case 0x2260 : return 29; case 0x00a3 : return 30; case 0x00b7 : return 31; } return c; } static QChar identicalMap(QChar c) { return c; } void TEWidget::fontChange(const QFont &) { QFontMetrics fm(font()); font_h = fm.height(); font_w = fm.maxWidth(); font_a = fm.ascent(); //printf("font_h: %d\n",font_h); //printf("font_w: %d\n",font_w); //printf("font_a: %d\n",font_a); //printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii()); //printf("rawname: %s\n",font().rawName().ascii()); fontMap = #if QT_VERSION < 300 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646") ? vt100extended : #endif identicalMap; propagateSize(); update(); } void TEWidget::setVTFont(const QFont& f) { QFrame::setFont(f); } QFont TEWidget::getVTFont() { return font(); } void TEWidget::setFont(const QFont &) { // ignore font change request if not coming from konsole itself } /* ------------------------------------------------------------------------- */ /* */ /* Constructor / Destructor */ /* */ /* ------------------------------------------------------------------------- */ TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) { #ifndef QT_NO_CLIPBOARD cb = QApplication::clipboard(); QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); #endif scrollbar = new QScrollBar(this); scrollbar->setCursor( arrowCursor ); connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); hScrollbar = new QScrollBar(this); hScrollbar->setCursor( arrowCursor ); hScrollbar->setOrientation(QScrollBar::Horizontal); hScrollbar->setMaximumHeight(16); connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int))); Config cfg("Konsole"); cfg.setGroup("ScrollBar"); switch( cfg.readNumEntry("Position",2)){ case 0: scrollLoc = SCRNONE; break; case 1: scrollLoc = SCRLEFT; break; case 2: scrollLoc = SCRRIGHT; break; }; useHorzScroll=cfg.readBoolEntry("HorzScroll",0); blinkT = new QTimer(this); connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent())); // blinking = FALSE; blinking = TRUE; resizing = FALSE; actSel = 0; image = 0; lines = 1; columns = 1; font_w = 1; font_h = 1; font_a = 1; word_selection_mode = FALSE; hposition = 0; - +vcolumns = 0; + setMouseMarks(TRUE); setVTFont( QFont("fixed") ); setColorTable(base_color_table); // init color table qApp->installEventFilter( this ); //FIXME: see below // KCursor::setAutoHideCursor( this, true ); // Init DnD //////////////////////////////////////////////////////////////// currentSession = NULL; // setAcceptDrops(true); // attempt // m_drop = new QPopupMenu(this); // m_drop->insertItem( QString("Paste"), 0); // m_drop->insertItem( QString("cd"), 1); // connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); // we need focus so that the auto-hide cursor feature works setFocus(); setFocusPolicy( WheelFocus ); } //FIXME: make proper destructor // Here's a start (David) TEWidget::~TEWidget() { qApp->removeEventFilter( this ); if (image) free(image); } /* ------------------------------------------------------------------------- */ /* */ /* Display Operations */ /* */ /* ------------------------------------------------------------------------- */ /*! attributed string draw primitive */ void TEWidget::drawAttrStr(QPainter &paint, QRect rect, QString& str, ca attr, BOOL pm, BOOL clear) { if (pm && color_table[attr.b].transparent) { paint.setBackgroundMode( TransparentMode ); if (clear) erase(rect); } else { if (blinking) paint.fillRect(rect, color_table[attr.b].color); else { paint.setBackgroundMode( OpaqueMode ); paint.setBackgroundColor( color_table[attr.b].color ); } } if (color_table[attr.f].bold) paint.setPen(QColor( 0x8F, 0x00, 0x00 )); else paint.setPen(color_table[attr.f].color); paint.drawText(rect.x(),rect.y()+font_a, str); if (attr.r & RE_UNDERLINE) paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); } /*! The image can only be set completely. The size of the new image may or may not match the size of the widget. */ void TEWidget::setImage(const ca* const newimg, int lines, int columns) { int y,x,len; const QPixmap* pm = backgroundPixmap(); QPainter paint; setUpdatesEnabled(FALSE); paint.begin( this ); HCNT("setImage"); QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); hasBlinker = FALSE; int cf = -1; // undefined int cb = -1; // undefined int cr = -1; // undefined int lins = QMIN(this->lines, QMAX(0,lines )); int cols = QMIN(this->columns,QMAX(0,columns)); QChar *disstrU = new QChar[cols]; for (y = 0; y < lins; y++) { const ca* lcl = &image[y*this->columns]; const ca* const ext = &newimg[y*columns]; if (!resizing) // not while resizing, we're expecting a paintEvent for (x = 0; x < cols; x++) { hasBlinker |= (ext[x].r & RE_BLINK); if (ext[x] != lcl[x]) { cr = ext[x].r; cb = ext[x].b; if (ext[x].f != cf) cf = ext[x].f; int lln = cols - x; disstrU[0] = fontMap(ext[x+0].c); for (len = 1; len < lln; len++) { if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || ext[x+len] == lcl[x+len] ) break; disstrU[len] = fontMap(ext[x+len].c); } QString unistr(disstrU,len); drawAttrStr(paint, QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), unistr, ext[x], pm != NULL, true); x += len - 1; } } // finally, make `image' become `newimg'. memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); } drawFrame( &paint ); paint.end(); setUpdatesEnabled(TRUE); if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } delete [] disstrU; } // paint Event //////////////////////////////////////////////////// /*! The difference of this routine vs. the `setImage' is, that the drawing does not include a difference analysis between the old and the new image. Instead, the internal image is used and the painting bound by the PaintEvent box. */ void TEWidget::paintEvent( QPaintEvent* pe ) { //{ static int cnt = 0; printf("paint %d\n",cnt++); } const QPixmap* pm = backgroundPixmap(); QPainter paint; setUpdatesEnabled(FALSE); paint.begin( this ); paint.setBackgroundMode( TransparentMode ); HCNT("paintEvent"); // Note that the actual widget size can be slightly larger // that the image (the size is truncated towards the smaller // number of characters in `resizeEvent'. The paint rectangle // can thus be larger than the image, but less then the size // of one character. QRect rect = pe->rect().intersect(contentsRect()); QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); /* printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, rect.left(), rect.right(), rect.top(), rect.bottom()); */ // if (pm != NULL && color_table[image->b].transparent) // erase(rect); // BL: I have no idea why we need this, and it breaks the refresh. QChar *disstrU = new QChar[columns]; for (int y = luy; y <= rly; y++) for (int x = lux; x <= rlx; x++) { int len = 1; disstrU[0] = fontMap(image[loc(x,y)].c); int cf = image[loc(x,y)].f; int cb = image[loc(x,y)].b; int cr = image[loc(x,y)].r; while (x+len <= rlx && image[loc(x+len,y)].f == cf && image[loc(x+len,y)].b == cb && image[loc(x+len,y)].r == cr ) { disstrU[len] = fontMap(image[loc(x+len,y)].c); len += 1; } QString unistr(disstrU,len); drawAttrStr(paint, QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), unistr, image[loc(x,y)], pm != NULL, false); x += len - 1; } delete [] disstrU; drawFrame( &paint ); paint.end(); setUpdatesEnabled(TRUE); } void TEWidget::blinkEvent() { blinking = !blinking; repaint(FALSE); } /* ------------------------------------------------------------------------- */ /* */ /* Resizing */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::resizeEvent(QResizeEvent* ev) { // printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); //printf("curren: %d,%d\n",width(),height()); HCNT("resizeEvent"); // see comment in `paintEvent' concerning the rounding. //FIXME: could make a routine here; check width(),height() assert(ev->size().width() == width()); assert(ev->size().height() == height()); propagateSize(); } void TEWidget::propagateSize() { ca* oldimg = image; int oldlin = lines; int oldcol = columns; makeImage(); // we copy the old image to reduce flicker int lins = QMIN(oldlin,lines); int cols = QMIN(oldcol,columns); if (oldimg) { for (int lin = 0; lin < lins; lin++) memcpy((void*)&image[columns*lin], (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); free(oldimg); //FIXME: try new,delete } else clearImage(); //NOTE: control flows from the back through the chest right into the eye. // `emu' will call back via `setImage'. resizing = TRUE; emit changedImageSizeSignal(lines, columns); // expose resizeEvent resizing = FALSE; } /* ------------------------------------------------------------------------- */ /* */ /* Scrollbar */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::scrollChanged(int) { emit changedHistoryCursor(scrollbar->value()); //expose } void TEWidget::hScrollChanged(int loc) { hposition = loc; propagateSize(); update(); // emit changedHorzCursor( hScrollbar->value()); //expose } void TEWidget::setScroll(int cursor, int slines) { disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); scrollbar->setRange(0,slines); scrollbar->setSteps(1,lines); scrollbar->setValue(cursor); connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); } void TEWidget::setScrollbarLocation(int loc) { if (scrollLoc == loc) return; // quickly scrollLoc = loc; propagateSize(); update(); } /* ------------------------------------------------------------------------- */ /* */ /* Mouse */ /* */ /* ------------------------------------------------------------------------- */ /*! Three different operations can be performed using the mouse, and the routines in this section serve all of them: 1) The press/release events are exposed to the application 2) Marking (press and move left button) and Pasting (press middle button) 3) The right mouse button is used from the configuration menu NOTE: During the marking process we attempt to keep the cursor within the bounds of the text as being displayed by setting the mouse position whenever the mouse has left the text area. Two reasons to do so: 1) QT does not allow the `grabMouse' to confine-to the TEWidget. Thus a `XGrapPointer' would have to be used instead. 2) Even if so, this would not help too much, since the text area of the TEWidget is normally not identical with it's bounds. The disadvantage of the current handling is, that the mouse can visibly leave the bounds of the widget and is then moved back. Because of the current construction, and the reasons mentioned above, we cannot do better without changing the overall construction. */ /*! */ void TEWidget::mousePressEvent(QMouseEvent* ev) { //printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); if ( !contentsRect().contains(ev->pos()) ) return; QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); word_selection_mode = FALSE; //printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); if ( ev->button() == LeftButton) { QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; if (mouse_marks || (ev->state() & ShiftButton)) { emit clearSelectionSignal(); iPntSel = pntSel = pos; actSel = 1; // left mouse button pressed but nothing selected yet. grabMouse( /*crossCursor*/ ); // handle with care! } else { emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button } } if ( ev->button() == MidButton ) { emitSelection(); } if ( ev->button() == RightButton ) // Configure { emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); } } void TEWidget::mouseMoveEvent(QMouseEvent* ev) { // for auto-hiding the cursor, we need mouseTracking if (ev->state() == NoButton ) return; if (actSel == 0) return; // don't extend selection while pasting if (ev->state() & MidButton) return; //if ( !contentsRect().contains(ev->pos()) ) return; QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); int scroll = scrollbar->value(); // int hScroll = hScrollbar->value(); // we're in the process of moving the mouse with the left button pressed // the mouse cursor will kept catched within the bounds of the text in // this widget. // Adjust position within text area bounds. See FIXME above. QPoint pos = ev->pos(); if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); // check if we produce a mouse move event by this if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); if ( pos.y() == tLy+bY+lines*font_h-1 ) { scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward } if ( pos.y() == tLy+bY ) { scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback } QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); QPoint ohere; bool swapping = FALSE; if ( word_selection_mode ) { // Extend to word boundaries int i; int selClass; bool left_not_right = ( here.y() < iPntSel.y() || here.y() == iPntSel.y() && here.x() < iPntSel.x() ); bool old_left_not_right = ( pntSel.y() < iPntSel.y() || pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); swapping = left_not_right != old_left_not_right; // Find left (left_not_right ? from here : from start) QPoint left = left_not_right ? here : iPntSel; i = loc(left.x(),left.y()); selClass = charClass(image[i].c); while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) { i--; left.rx()--; } // Find left (left_not_right ? from start : from here) QPoint right = left_not_right ? iPntSel : here; i = loc(right.x(),right.y()); selClass = charClass(image[i].c); while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) { i++; right.rx()++; } // Pick which is start (ohere) and which is extension (here) if ( left_not_right ) { here = left; ohere = right; } else { here = right; ohere = left; } } if (here == pntSel && scroll == scrollbar->value()) return; // not moved if ( word_selection_mode ) { if ( actSel < 2 || swapping ) { emit beginSelectionSignal( ohere.x(), ohere.y() ); } } else if ( actSel < 2 ) { emit beginSelectionSignal( pntSel.x(), pntSel.y() ); } actSel = 2; // within selection pntSel = here; emit extendSelectionSignal( here.x(), here.y() ); } void TEWidget::mouseReleaseEvent(QMouseEvent* ev) { //printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); if ( ev->button() == LeftButton) { if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); preserve_line_breaks = TRUE; actSel = 0; //FIXME: emits a release event even if the mouse is // outside the range. The procedure used in `mouseMoveEvent' // applies here, too. QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); if (!mouse_marks && !(ev->state() & ShiftButton)) emit mouseSignal( 3, // release (ev->x()-tLx-blX)/font_w + 1, (ev->y()-tLy-bY)/font_h + 1 ); releaseMouse(); } } void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) { if ( ev->button() != LeftButton) return; QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); // pass on double click as two clicks. if (!mouse_marks && !(ev->state() & ShiftButton)) { emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button return; } emit clearSelectionSignal(); QPoint bgnSel = pos; QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); int i = loc(bgnSel.x(),bgnSel.y()); iPntSel = bgnSel; word_selection_mode = TRUE; // find word boundaries... int selClass = charClass(image[i].c); { // set the start... int x = bgnSel.x(); while ( x > 0 && charClass(image[i-1].c) == selClass ) { i--; x--; } bgnSel.setX(x); emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); // set the end... i = loc( endSel.x(), endSel.y() ); x = endSel.x(); while( x < columns-1 && charClass(image[i+1].c) == selClass ) { i++; x++ ; } endSel.setX(x); actSel = 2; // within selection emit extendSelectionSignal( endSel.x(), endSel.y() ); emit endSelectionSignal(preserve_line_breaks); preserve_line_breaks = TRUE; } } void TEWidget::focusInEvent( QFocusEvent * ) { // do nothing, to prevent repainting } void TEWidget::focusOutEvent( QFocusEvent * ) { // do nothing, to prevent repainting } bool TEWidget::focusNextPrevChild( bool next ) { if (next) return false; // This disables changing the active part in konqueror // when pressing Tab return QFrame::focusNextPrevChild( next ); } int TEWidget::charClass(char ch) const { // This might seem like overkill, but imagine if ch was a Unicode // character (Qt 2.0 QChar) - it might then be sensible to separate // the different language ranges, etc. if ( isspace(ch) ) return ' '; static const char *word_characters = ":@-./_~"; if ( isalnum(ch) || strchr(word_characters, ch) ) return 'a'; // Everything else is weird return 1; } void TEWidget::setMouseMarks(bool on) { mouse_marks = on; setCursor( mouse_marks ? ibeamCursor : arrowCursor ); } /* ------------------------------------------------------------------------- */ /* */ /* Clipboard */ /* */ /* ------------------------------------------------------------------------- */ #undef KeyPress void TEWidget::emitSelection() // Paste Clipboard by simulating keypress events { #ifndef QT_NO_CLIPBOARD QString text = QApplication::clipboard()->text(); if ( ! text.isNull() ) { text.replace(QRegExp("\n"), "\r"); QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); emit keyPressedSignal(&e); // expose as a big fat keypress event emit clearSelectionSignal(); } #endif } void TEWidget::emitText(QString text) { QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); emit keyPressedSignal(&e); // expose as a big fat keypress event } void TEWidget::pasteClipboard( ) { emitSelection(); } void TEWidget::setSelection(const QString& t) { #ifndef QT_NO_CLIPBOARD // Disconnect signal while WE set the clipboard QObject *cb = QApplication::clipboard(); QObject::disconnect( cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); QApplication::clipboard()->setText(t); QObject::connect( cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); #endif } void TEWidget::onClearSelection() { emit clearSelectionSignal(); } /* ------------------------------------------------------------------------- */ /* */ /* Keyboard */ /* */ /* ------------------------------------------------------------------------- */ //FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' // due to a bug in `QT' or the ignorance of the author to prevent // repaint events being emitted to the screen whenever one leaves // or reenters the screen to/from another application. // // Troll says one needs to change focusInEvent() and focusOutEvent(), // which would also let you have an in-focus cursor and an out-focus // cursor like xterm does. // for the auto-hide cursor feature, I added empty focusInEvent() and // focusOutEvent() so that update() isn't called. // For auto-hide, we need to get keypress-events, but we only get them when // we have focus. void TEWidget::doScroll(int lines) { scrollbar->setValue(scrollbar->value()+lines); } void TEWidget::doHScroll(int lines) { hScrollbar->setValue( hScrollbar->value()+lines); } bool TEWidget::eventFilter( QObject *obj, QEvent *e ) { if ( (e->type() == QEvent::Accel || e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { static_cast<QKeyEvent *>( e )->ignore(); return true; } if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) return FALSE; // not us if ( e->type() == QEvent::Wheel) { QApplication::sendEvent(scrollbar, e); } #ifdef FAKE_CTRL_AND_ALT static bool control = FALSE; static bool alt = FALSE; // qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); bool dele=FALSE; if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { QKeyEvent* ke = (QKeyEvent*)e; bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); switch (ke->key()) { case Key_F9: // let this be "Control" control = keydown; e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); dele=TRUE; break; case Key_F13: // let this be "Alt" alt = keydown; e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); dele=TRUE; break; default: if ( control ) { int a = toupper(ke->ascii())-64; if ( a >= 0 && a < ' ' ) { e = new QKeyEvent(e->type(), ke->key(), a, ke->state()|ControlButton, QChar(a,0)); dele=TRUE; } } if ( alt ) { e = new QKeyEvent(e->type(), ke->key(), ke->ascii(), ke->state()|AltButton, ke->text()); dele=TRUE; } } } #endif if ( e->type() == QEvent::KeyPress ) { QKeyEvent* ke = (QKeyEvent*)e; actSel=0; // Key stroke implies a screen update, so TEWidget won't // know where the current selection is. // qDebug("key pressed is 0x%x, state %d",ke->key(), ke->state()); if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker // qDebug("key pressed 2 is 0x%x",ke->key()); emitText("\\"); // expose } else if( ke->state() == ControlButton && ke->key() == Key_V) { pasteClipboard(); } else emit keyPressedSignal(ke); // expose ke->accept(); #ifdef FAKE_CTRL_AND_ALT if ( dele ) delete e; #endif return true; // stop the event } if ( e->type() == QEvent::Enter ) { QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); } if ( e->type() == QEvent::Leave ) { QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); } return QFrame::eventFilter( obj, e ); } /* ------------------------------------------------------------------------- */ /* */ /* Frame */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::frameChanged() { propagateSize(); update(); } /* ------------------------------------------------------------------------- */ /* */ /* Sound */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::Bell() { //#ifdef QT_QWS_CUSTOM //# ifndef QT_NO_COP QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); //# endif //#else //# ifndef QT_NO_SOUND // QSound::play(Resource::findSound("alarm")); //# endif //#endif // QApplication::beep(); } /* ------------------------------------------------------------------------- */ /* */ /* Auxiluary */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::clearImage() // initialize the image // for internal use only { for (int y = 0; y < lines; y++) for (int x = 0; x < columns; x++) { image[loc(x,y)].c = 0xff; //' '; image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; } } // Create Image /////////////////////////////////////////////////////// void TEWidget::calcGeometry() { int showhscrollbar = 1; int hwidth = 0; int dcolumns; Config cfg("Konsole"); cfg.setGroup("ScrollBar"); useHorzScroll=cfg.readBoolEntry("HorzScroll",0); if(vcolumns == 0) showhscrollbar = 0; if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width(); scrollbar->resize(QApplication::style().scrollBarExtent().width(), contentsRect().height() - hwidth); switch(scrollLoc) { case SCRNONE : columns = ( contentsRect().width() - 2 * rimX ) / font_w; dcolumns = columns; if(vcolumns) columns = vcolumns; blX = (contentsRect().width() - (columns*font_w) ) / 2; if(showhscrollbar) blX = -hposition * font_w; brX = blX; scrollbar->hide(); break; case SCRLEFT : columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; dcolumns = columns; if(vcolumns) columns = vcolumns; brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; if(showhscrollbar) brX = -hposition * font_w; blX = brX + scrollbar->width(); scrollbar->move(contentsRect().topLeft()); scrollbar->show(); break; case SCRRIGHT: columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; dcolumns = columns; if(vcolumns) columns = vcolumns; blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; if(showhscrollbar) blX = -hposition * font_w; brX = blX; scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); scrollbar->show(); break; } //FIXME: support 'rounding' styles lines = ( contentsRect().height() - 2 * rimY ) / font_h; bY = (contentsRect().height() - (lines *font_h)) / 2; if(showhscrollbar == 1) { hScrollbar->resize(contentsRect().width() - hwidth, hwidth); hScrollbar->setRange(0, vcolumns - dcolumns); QPoint p = contentsRect().bottomLeft(); hScrollbar->move(QPoint(p.x(), p.y() - hwidth)); hScrollbar->show(); } else hScrollbar->hide(); if(showhscrollbar == 1) { lines = lines - (hwidth / font_h) - 1; if(lines < 1) lines = 1; } /*//FIXME: set rimX == rimY == 0 when running in full screen mode. Config cfg("Konsole"); cfg.setGroup("ScrollBar"); useHorzScroll=cfg.readBoolEntry("HorzScroll",0); scrollbar->resize( QApplication::style().scrollBarExtent().width(), contentsRect().height()); qDebug("font_w %d", font_w); switch(scrollLoc) { case SCRNONE : columns = ( contentsRect().width() - 2 * rimX ) / font_w; blX = (contentsRect().width() - (columns*font_w) ) / 2; brX = blX; scrollbar->hide(); break; case SCRLEFT : columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; if(useHorzScroll) columns = columns * (font_w/2); brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; blX = brX + scrollbar->width(); scrollbar->move(contentsRect().topLeft()); scrollbar->show(); break; case SCRRIGHT: columns = ( contentsRect().width() - 2 * rimX - scrollbar->width() ) / font_w; if(useHorzScroll) columns = columns * (font_w/2); blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; if(useHorzScroll) { brX = blX =2; } else { brX=blX; } scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0) ); scrollbar->show(); break; } if( !scrollbar->isHidden()) hScrollbar->resize( contentsRect().width()-SCRWIDTH, QApplication::style() .scrollBarExtent().height()); else hScrollbar->resize( contentsRect().width(), QApplication::style() .scrollBarExtent().height()); hScrollbar->move( 0, contentsRect().height() - SCRWIDTH); if(useHorzScroll) { hScrollbar->show(); lines = ( (contentsRect().height() - SCRWIDTH) - 2 * rimY ) / font_h; bY = ((contentsRect().height() - SCRWIDTH) - (lines *font_h)) / 2; } else { hScrollbar->hide(); lines = (contentsRect().height() - 2 * rimY ) / font_h; bY = (contentsRect().height() - (lines *font_h)) / 2; } */ //FIXME: support 'rounding' styles } void TEWidget::makeImage() //FIXME: rename 'calcGeometry? { calcGeometry(); image = (ca*) malloc(lines*columns*sizeof(ca)); clearImage(); } // calculate the needed size QSize TEWidget::calcSize(int cols, int lins) const { int frw = width() - contentsRect().width(); int frh = height() - contentsRect().height(); int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); } QSize TEWidget::sizeHint() const { return size(); } void TEWidget::styleChange(QStyle &) { propagateSize(); } #ifndef QT_NO_DRAGANDDROP /* --------------------------------------------------------------------- */ /* */ /* Drag & Drop */ /* */ /* --------------------------------------------------------------------- */ void TEWidget::dragEnterEvent(QDragEnterEvent* e) { e->accept(QTextDrag::canDecode(e) || QUriDrag::canDecode(e)); } void TEWidget::dropEvent(QDropEvent* event) { // The current behaviour when url(s) are dropped is // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd // * in all other cases, just paste // (for non-local ones, or for a list of URLs, 'cd' is nonsense) QStrList strlist; int file_count = 0; dropText = ""; bool bPopup = true; if(QUriDrag::decode(event, strlist)) { if (strlist.count()) { for(const char* p = strlist.first(); p; p = strlist.next()) { if(file_count++ > 0) { dropText += " "; bPopup = false; // more than one file, don't popup } /* KURL url(p); if (url.isLocalFile()) { dropText += url.path(); // local URL : remove protocol } else { dropText += url.prettyURL(); bPopup = false; // a non-local file, don't popup } */ } if (bPopup) // m_drop->popup(pos() + event->pos()); m_drop->popup(mapToGlobal(event->pos())); else { if (currentSession) { currentSession->getEmulation()->sendString(dropText.local8Bit()); } // kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; } } } else if(QTextDrag::decode(event, dropText)) { // kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; if (currentSession) { currentSession->getEmulation()->sendString(dropText.local8Bit()); } // Paste it } } #endif void TEWidget::drop_menu_activated(int item) { #ifndef QT_NO_DRAGANDDROP switch (item) { case 0: // paste currentSession->getEmulation()->sendString(dropText.local8Bit()); // KWM::activate((Window)this->winId()); break; case 1: // cd ... currentSession->getEmulation()->sendString("cd "); struct stat statbuf; if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) { if ( !S_ISDIR(statbuf.st_mode) ) { /* KURL url; url.setPath( dropText ); dropText = url.directory( true, false ); // remove filename */ } } dropText.replace(QRegExp(" "), "\\ "); // escape spaces currentSession->getEmulation()->sendString(dropText.local8Bit()); currentSession->getEmulation()->sendString("\n"); // KWM::activate((Window)this->winId()); break; } #endif } void TEWidget::setWrapAt(int columns) { vcolumns = columns; propagateSize(); update(); } - - diff --git a/core/apps/embeddedkonsole/TEmulation.h b/core/apps/embeddedkonsole/TEmulation.h index ec15e7a..bf43f11 100644 --- a/core/apps/embeddedkonsole/TEmulation.h +++ b/core/apps/embeddedkonsole/TEmulation.h @@ -1,117 +1,118 @@ /* -------------------------------------------------------------------------- */ /* */ /* [emulation.h] Fundamental Terminal Emulation */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole - an X terminal for KDE */ /* */ /* -------------------------------------------------------------------------- */ -/* */ +/* */ /* Ported Konsole to Qt/Embedded */ -/* */ +/* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ -/* */ +/* */ /* -------------------------------------------------------------------------- */ #ifndef EMULATION_H #define EMULATION_H #include "TEWidget.h" #include "TEScreen.h" #include <qtimer.h> #include <stdio.h> #include <qtextcodec.h> #include "keytrans.h" class TEmulation : public QObject { Q_OBJECT public: TEmulation(TEWidget* gui); ~TEmulation(); public: virtual void setHistory(bool on); virtual bool history(); public slots: // signals incoming from TEWidget virtual void onImageSizeChange(int lines, int columns); virtual void onHistoryCursorChange(int cursor); + virtual void onHorzCursorChange(int cursor); virtual void onKeyPress(QKeyEvent*); virtual void clearSelection(); virtual void onSelectionBegin(const int x, const int y); virtual void onSelectionExtend(const int x, const int y); virtual void setSelection(const BOOL preserve_line_breaks); public slots: // signals incoming from data source void onRcvBlock(const char* txt,int len); signals: void sndBlock(const char* txt,int len); void ImageSizeChanged(int lines, int columns); void changeColumns(int columns); void changeTitle(int arg, const char* str); public: virtual void onRcvChar(int); virtual void setMode (int) = 0; virtual void resetMode(int) = 0; virtual void sendString(const char*) = 0; virtual void setConnect(bool r); void setColumns(int columns); void setKeytrans(int no); void setKeytrans(const char * no); protected: TEWidget* gui; TEScreen* scr; // referes to one `screen' TEScreen* screen[2]; // 0 = primary, 1 = alternate void setScreen(int n); // set `scr' to `screen[n]' bool connected; // communicate with widget void setCodec(int c); // codec number, 0 = locale, 1=utf8 QTextCodec* codec; QTextCodec* localeCodec; QTextDecoder* decoder; KeyTrans* keytrans; // refreshing related material. // this is localized in the class. private slots: // triggered by timer void showBulk(); private: void bulkNewline(); void bulkStart(); void bulkEnd(); private: QTimer bulk_timer; int bulk_nlcnt; // bulk newline counter char* SelectedText; int bulk_incnt; // bulk counter }; #endif // ifndef EMULATION_H diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp index 3c87ad4..16db0ea 100644 --- a/core/apps/embeddedkonsole/konsole.cpp +++ b/core/apps/embeddedkonsole/konsole.cpp @@ -1,973 +1,1007 @@ /* ---------------------------------------------------------------------- */ /* */ /* [main.C] Konsole */ /* */ /* ---------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole, an X terminal. */ /* */ /* The material contained in here more or less directly orginates from */ /* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */ /* */ /* ---------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ // enhancements added by L.J. Potter <ljp@llornkcor.com> #include <qpe/resource.h> #include <qdir.h> #include <qevent.h> #include <qdragobject.h> #include <qobjectlist.h> #include <qtoolbutton.h> #include <qpe/qpetoolbar.h> #include <qpushbutton.h> #include <qfontdialog.h> #include <qglobal.h> #include <qpainter.h> #include <qpe/qpemenubar.h> #include <qmessagebox.h> #include <qaction.h> #include <qapplication.h> #include <qfontmetrics.h> #include <qcombobox.h> #include <qevent.h> #include <qtabwidget.h> #include <qtabbar.h> #include <qpe/config.h> #include <qstringlist.h> #include <qpalette.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "konsole.h" #include "keytrans.h" #include "commandeditdialog.h" #include <opie/colorpopupmenu.h> class EKNumTabBar : public QTabBar { public: void numberTabs() { // Yes, it really is this messy. QTabWidget needs functions // that provide acces to tabs in a sequential way. int m=INT_MIN; for (int i=0; i<count(); i++) { QTab* left=0; QListIterator<QTab> it(*tabList()); int x=INT_MAX; for( QTab* t; (t=it.current()); ++it ) { int tx = t->rect().x(); if ( tx<x && tx>m ) { x = tx; left = t; } } if ( left ) { left->setText(QString::number(i+1)); m = left->rect().x(); } } } }; class EKNumTabWidget : public QTabWidget { public: EKNumTabWidget(QWidget* parent) : QTabWidget(parent) { } void addTab(QWidget* w) { QTab* t = new QTab(QString::number(tabBar()->count()+1)); QTabWidget::addTab(w,t); } void removeTab(QWidget* w) { removePage(w); ((EKNumTabBar*)tabBar())->numberTabs(); } }; // This could be configurable or dynamicly generated from the bash history // file of the user static const char *commonCmds[] = { "ls ", // I left this here, cause it looks better than the first alpha "cardctl eject", "cat ", "cd ", "chmod ", "clear", "cp ", "dc ", "df ", "dmesg", "echo ", "env", "find ", "free", "grep ", "ifconfig ", "ipkg ", "mkdir ", "mv ", "nc localhost 7776", "nc localhost 7777", "netstat ", "nslookup ", "ping ", "ps aux", "pwd ", "qcop QPE/System 'linkChanged(QString)' ''", "qcop QPE/System 'restart()'", "qcop QPE/System 'quit()'", "rm ", "rmdir ", "route ", "set ", "traceroute", /* "gzip", "gunzip", "chgrp", "chown", "date", "dd", "df", "dmesg", "fuser", "hostname", "kill", "killall", "ln", "ping", "mount", "more", "sort", "touch", "umount", "mknod", "netstat", */ "exit", NULL }; Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) : QMainWindow(parent, name, fl) { QStrList args; init("/bin/sh",args); } Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int) : QMainWindow(0, name) { init(_pgm,_args); } void Konsole::initCommandList() { // qDebug("Konsole::initCommandList"); Config cfg("Konsole"); cfg.setGroup("Commands"); commonCombo->setInsertionPolicy(QComboBox::AtCurrent); commonCombo->clear(); if (cfg.readEntry("Commands Set","FALSE") == "FALSE") { for (int i = 0; commonCmds[i] != NULL; i++) { commonCombo->insertItem(commonCmds[i],i); } } else { for (int i = 0; i < 100; i++) { if (!(cfg.readEntry( QString::number(i),"")).isEmpty()) commonCombo->insertItem((cfg.readEntry( QString::number(i),""))); } } } void Konsole::init(const char* _pgm, QStrList & _args) { b_scroll = TRUE; // histon; n_keytab = 0; n_render = 0; startUp=0; fromMenu = FALSE; setCaption( tr("Terminal") ); setIcon( Resource::loadPixmap( "konsole" ) ); Config cfg("Konsole"); cfg.setGroup("Konsole"); QString tmp; // initialize the list of allowed fonts /////////////////////////////////// cfont = cfg.readNumEntry("FontID", 1); QFont f = QFont("Micro", 4, QFont::Normal); f.setFixedPitch(TRUE); fonts.append(new VTFont(tr("Micro"), f)); f = QFont("Fixed", 7, QFont::Normal); f.setFixedPitch(TRUE); fonts.append(new VTFont(tr("Small Fixed"), f)); f = QFont("Fixed", 12, QFont::Normal); f.setFixedPitch(TRUE); fonts.append(new VTFont(tr("Medium Fixed"), f)); // create terminal emulation framework //////////////////////////////////// nsessions = 0; tab = new EKNumTabWidget(this); connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*))); // create terminal toolbar //////////////////////////////////////////////// setToolBarsMovable( FALSE ); QPEToolBar *menuToolBar = new QPEToolBar( this ); menuToolBar->setHorizontalStretchable( TRUE ); QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar ); fontList = new QPopupMenu( this ); for(uint i = 0; i < fonts.count(); i++) { VTFont *fnt = fonts.at(i); fontList->insertItem(fnt->getName(), i); } fontChanged(cfont); configMenu = new QPopupMenu( this); colorMenu = new QPopupMenu( this); scrollMenu = new QPopupMenu( this); editCommandListMenu = new QPopupMenu( this); configMenu->insertItem(tr("Command List"), editCommandListMenu); bool listHidden; cfg.setGroup("Menubar"); if( cfg.readEntry("Hidden","FALSE") == "TRUE") { editCommandListMenu->insertItem( tr( "Show command list" )); listHidden=TRUE; } else { editCommandListMenu->insertItem( tr( "Hide command list" )); listHidden=FALSE; } cfg.setGroup("Tabs"); tmp=cfg.readEntry("Position","Bottom"); if(tmp=="Top") { tab->setTabPosition(QTabWidget::Top); configMenu->insertItem( tr( "Tabs on Bottom" ) ); } else { tab->setTabPosition(QTabWidget::Bottom); configMenu->insertItem("Tabs on Top"); } configMenu->insertSeparator(2); colorMenu->insertItem(tr( "Green on Black")); colorMenu->insertItem(tr( "Black on White")); colorMenu->insertItem(tr( "White on Black")); colorMenu->insertItem(tr( "Black on Transparent")); colorMenu->insertItem(tr( "Black on Red")); colorMenu->insertItem(tr( "Red on Black")); colorMenu->insertItem(tr( "Green on Yellow")); colorMenu->insertItem(tr( "Blue on Magenta")); colorMenu->insertItem(tr( "Magenta on Blue")); colorMenu->insertItem(tr( "Cyan on White")); colorMenu->insertItem(tr( "White on Cyan")); colorMenu->insertItem(tr( "Blue on Black")); colorMenu->insertItem(tr( "Amber on Black")); colorMenu->insertItem(tr( "Custom")); configMenu->insertItem(tr( "Colors") ,colorMenu); connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) )); connect( configMenu, SIGNAL( activated(int) ), this, SLOT( configMenuSelected(int) )); connect( colorMenu, SIGNAL( activated(int) ), this, SLOT( colorMenuIsSelected(int) )); connect( scrollMenu, SIGNAL(activated(int)),this,SLOT(scrollMenuSelected(int))); connect(editCommandListMenu,SIGNAL(activated(int)),this,SLOT(editCommandListMenuSelected(int))); menuBar->insertItem( tr("Font"), fontList ); menuBar->insertItem( tr("Options"), configMenu ); QPEToolBar *toolbar = new QPEToolBar( this ); QAction *a; // Button Commands a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar ); a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar ); a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar ); a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar ); a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar ); /* a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); */ secondToolBar = new QPEToolBar( this ); secondToolBar->setHorizontalStretchable( TRUE ); commonCombo = new QComboBox( secondToolBar ); commonCombo->setMaximumWidth(236); editCommandListMenu->insertItem( tr( "Quick Edit" ) ); if( listHidden) { secondToolBar->hide(); editCommandListMenu->setItemEnabled(-23 ,FALSE); } editCommandListMenu->insertItem(tr( "Edit" ) ); cfg.setGroup("Commands"); commonCombo->setInsertionPolicy(QComboBox::AtCurrent); initCommandList(); // for (int i = 0; commonCmds[i] != NULL; i++) { // commonCombo->insertItem( commonCmds[i], i ); // tmp = cfg.readEntry( QString::number(i),""); // if(tmp != "") // commonCombo->changeItem( tmp,i ); // } connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) )); scrollMenu->insertItem(tr( "None" )); scrollMenu->insertItem(tr( "Left" )); scrollMenu->insertItem(tr( "Right" )); - scrollMenu->insertSeparator(4); - scrollMenu->insertItem(tr( "Horizontal" )); +// scrollMenu->insertSeparator(4); +// scrollMenu->insertItem(tr( "Horizontal" )); configMenu->insertItem(tr( "ScrollBar" ),scrollMenu); + + configMenu->insertItem(tr( "Wrap" )); + //scrollMenuSelected(-29); // cfg.setGroup("ScrollBar"); // if(cfg.readBoolEntry("HorzScroll",0)) { // if(cfg.readNumEntry("Position",2) == 0) // te->setScrollbarLocation(1); // else // te->setScrollbarLocation(0); // te->setScrollbarLocation( cfg.readNumEntry("Position",2)); // te->setWrapAt(120); // } // create applications ///////////////////////////////////////////////////// setCentralWidget(tab); // load keymaps //////////////////////////////////////////////////////////// KeyTrans::loadAll(); for (int i = 0; i < KeyTrans::count(); i++) { KeyTrans* s = KeyTrans::find(i); assert( s ); } se_pgm = _pgm; se_args = _args; se_args.prepend("--login"); parseCommandLine(); // read and apply default values /////////////////////////////////////////// resize(321, 321); // Dummy. QSize currentSize = size(); if (currentSize != size()) defaultSize = size(); } void Konsole::show() { if ( !nsessions ) { newSession(); } QMainWindow::show(); + } void Konsole::initSession(const char*, QStrList &) { QMainWindow::show(); } Konsole::~Konsole() { while (nsessions > 0) { doneSession(getTe()->currentSession, 0); } Config cfg("Konsole"); cfg.setGroup("Konsole"); cfg.writeEntry("FontID", cfont); } void Konsole::fontChanged(int f) { VTFont* font = fonts.at(f); if (font != 0) { for(uint i = 0; i < fonts.count(); i++) { fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE); } cfont = f; TEWidget* te = getTe(); if (te != 0) { te->setVTFont(font->getFont()); } } } void Konsole::enterCommand(int c) { TEWidget* te = getTe(); if (te != 0) { if(!commonCombo->editable()) { QString text = commonCombo->text(c); //commonCmds[c]; te->emitText(text); } else { changeCommand( commonCombo->text(c), c); } } } void Konsole::hitEnter() { TEWidget* te = getTe(); if (te != 0) { te->emitText(QString("\r")); } } void Konsole::hitSpace() { TEWidget* te = getTe(); if (te != 0) { te->emitText(QString(" ")); } } void Konsole::hitTab() { TEWidget* te = getTe(); if (te != 0) { te->emitText(QString("\t")); } } void Konsole::hitPaste() { TEWidget* te = getTe(); if (te != 0) { te->pasteClipboard(); } } void Konsole::hitUp() { TEWidget* te = getTe(); if (te != 0) { QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0); QApplication::sendEvent( te, &ke ); } } void Konsole::hitDown() { TEWidget* te = getTe(); if (te != 0) { QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0); QApplication::sendEvent( te, &ke ); } } /** This function calculates the size of the external widget needed for the internal widget to be */ QSize Konsole::calcSize(int columns, int lines) { TEWidget* te = getTe(); if (te != 0) { QSize size = te->calcSize(columns, lines); return size; } else { QSize size; return size; } } /** sets application window to a size based on columns X lines of the te guest widget. Call with (0,0) for setting default size. */ void Konsole::setColLin(int columns, int lines) { qDebug("konsole::setColLin:: Columns %d", columns); if ((columns==0) || (lines==0)) { if (defaultSize.isEmpty()) // not in config file : set default value { defaultSize = calcSize(80,24); // notifySize(24,80); // set menu items (strange arg order !) } resize(defaultSize); } else { resize(calcSize(columns, lines)); // notifySize(lines,columns); // set menu items (strange arg order !) } } /* void Konsole::setFont(int fontno) { QFont f; if (fontno == 0) f = defaultFont = QFont( "Helvetica", 12 ); else if (fonts[fontno][0] == '-') f.setRawName( fonts[fontno] ); else { f.setFamily(fonts[fontno]); f.setRawMode( TRUE ); } if ( !f.exactMatch() && fontno != 0) { QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]); QMessageBox(this, msg); return; } if (se) se->setFontNo(fontno); te->setVTFont(f); n_font = fontno; } */ // --| color selection |------------------------------------------------------- void Konsole::changeColumns(int columns) { qDebug("change columns"); TEWidget* te = getTe(); if (te != 0) { setColLin(columns,te->Lines()); te->update(); } } //FIXME: If a child dies during session swap, // this routine might be called before // session swap is completed. void Konsole::doneSession(TESession*, int ) { TEWidget *te = getTe(); if (te != 0) { te->currentSession->setConnect(FALSE); tab->removeTab(te); delete te->currentSession; delete te; nsessions--; } if (nsessions == 0) { close(); } } void Konsole::newSession() { if(nsessions < 15) { // seems to be something weird about 16 tabs on the Zaurus.... memory? TEWidget* te = new TEWidget(tab); // te->setBackgroundMode(PaletteBase); //we want transparent!! - te->setVTFont(fonts.at(cfont)->getFont()); - tab->addTab(te); - TESession* se = new TESession(this, te, se_pgm, se_args, "xterm"); - te->currentSession = se; - connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) ); - se->run(); - se->setConnect(TRUE); - se->setHistory(b_scroll); - tab->setCurrentPage(nsessions); - nsessions++; - setColor(); + te->setVTFont(fonts.at(cfont)->getFont()); + tab->addTab(te); + TESession* se = new TESession(this, te, se_pgm, se_args, "xterm"); + te->currentSession = se; + connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) ); + se->run(); + se->setConnect(TRUE); + se->setHistory(b_scroll); + tab->setCurrentPage(nsessions); + nsessions++; + doWrap(); + setColor(); } } TEWidget* Konsole::getTe() { if (nsessions) { return (TEWidget *) tab->currentPage(); } else { return 0; } } void Konsole::switchSession(QWidget* w) { TEWidget* te = (TEWidget *) w; QFont teFnt = te->getVTFont(); for(uint i = 0; i < fonts.count(); i++) { VTFont *fnt = fonts.at(i); bool cf = fnt->getFont() == teFnt; fontList->setItemChecked(i, cf); if (cf) { cfont = i; } } } void Konsole::colorMenuIsSelected(int iD) { fromMenu = TRUE; colorMenuSelected(iD); } /// ------------------------------- some new stuff by L.J. Potter void Konsole::colorMenuSelected(int iD) { // this is NOT pretty, elegant or anything else besides functional // QString temp; // qDebug( temp.sprintf("colormenu %d", iD)); TEWidget* te = getTe(); Config cfg("Konsole"); cfg.setGroup("Colors"); // QColor foreground; // QColor background; colorMenu->setItemChecked(lastSelectedMenu,FALSE); ColorEntry m_table[TABLE_COLORS]; const ColorEntry * defaultCt=te->getdefaultColorTable(); /////////// fore back int i; if(iD==-9) { // default default for (i = 0; i < TABLE_COLORS; i++) { m_table[i].color = defaultCt[i].color; if(i==1 || i == 11) m_table[i].transparent=1; cfg.writeEntry("Schema","9"); colorMenu->setItemChecked(-9,TRUE); } } else { if(iD==-6) { // green black foreground.setRgb(0x18,255,0x18); background.setRgb(0x00,0x00,0x00); cfg.writeEntry("Schema","6"); colorMenu->setItemChecked(-6,TRUE); } if(iD==-7) { // black white foreground.setRgb(0x00,0x00,0x00); background.setRgb(0xFF,0xFF,0xFF); cfg.writeEntry("Schema","7"); colorMenu->setItemChecked(-7,TRUE); } if(iD==-8) { // white black foreground.setRgb(0xFF,0xFF,0xFF); background.setRgb(0x00,0x00,0x00); cfg.writeEntry("Schema","8"); colorMenu->setItemChecked(-8,TRUE); } if(iD==-10) {// Black, Red foreground.setRgb(0x00,0x00,0x00); background.setRgb(0xB2,0x18,0x18); cfg.writeEntry("Schema","10"); colorMenu->setItemChecked(-10,TRUE); } if(iD==-11) {// Red, Black foreground.setRgb(230,31,31); //0xB2,0x18,0x18 background.setRgb(0x00,0x00,0x00); cfg.writeEntry("Schema","11"); colorMenu->setItemChecked(-11,TRUE); } if(iD==-12) {// Green, Yellow - is ugly // foreground.setRgb(0x18,0xB2,0x18); foreground.setRgb(36,139,10); // background.setRgb(0xB2,0x68,0x18); background.setRgb(255,255,0); cfg.writeEntry("Schema","12"); colorMenu->setItemChecked(-12,TRUE); } if(iD==-13) {// Blue, Magenta foreground.setRgb(0x18,0xB2,0xB2); background.setRgb(0x18,0x18,0xB2); cfg.writeEntry("Schema","13"); colorMenu->setItemChecked(-13,TRUE); } if(iD==-14) {// Magenta, Blue foreground.setRgb(0x18,0x18,0xB2); background.setRgb(0x18,0xB2,0xB2); cfg.writeEntry("Schema","14"); colorMenu->setItemChecked(-14,TRUE); } if(iD==-15) {// Cyan, White foreground.setRgb(0x18,0xB2,0xB2); background.setRgb(0xFF,0xFF,0xFF); cfg.writeEntry("Schema","15"); colorMenu->setItemChecked(-15,TRUE); } if(iD==-16) {// White, Cyan background.setRgb(0x18,0xB2,0xB2); foreground.setRgb(0xFF,0xFF,0xFF); cfg.writeEntry("Schema","16"); colorMenu->setItemChecked(-16,TRUE); } if(iD==-17) {// Black, Blue background.setRgb(0x00,0x00,0x00); foreground.setRgb(0x18,0xB2,0xB2); cfg.writeEntry("Schema","17"); colorMenu->setItemChecked(-17,TRUE); } if(iD==-18) {// Black, Gold background.setRgb(0x00,0x00,0x00); foreground.setRgb(255,215,0); cfg.writeEntry("Schema","18"); colorMenu->setItemChecked(-18,TRUE); } if(iD==-19) {// Custom qDebug("do custom"); if(fromMenu) { ColorPopupMenu* penColorPopupMenu = new ColorPopupMenu(Qt::black, this, "foreground color"); connect(penColorPopupMenu, SIGNAL(colorSelected(const QColor&)), this, SLOT(changeForegroundColor(const QColor&))); penColorPopupMenu->exec(); } cfg.writeEntry("Schema","19"); if(!fromMenu) { foreground.setNamedColor(cfg.readEntry("foreground","")); background.setNamedColor(cfg.readEntry("background","")); } fromMenu=FALSE; colorMenu->setItemChecked(-19,TRUE); } for (i = 0; i < TABLE_COLORS; i++) { if(i==0 || i == 10) { m_table[i].color = foreground; } else if(i==1 || i == 11) { m_table[i].color = background; m_table[i].transparent=0; } else m_table[i].color = defaultCt[i].color; } } lastSelectedMenu = iD; te->setColorTable(m_table); update(); } void Konsole::configMenuSelected(int iD) { -// QString temp; -// qDebug( temp.sprintf("configmenu %d",iD)); + QString temp; + qDebug( temp.sprintf("configmenu %d",iD)); TEWidget* te = getTe(); Config cfg("Konsole"); cfg.setGroup("Menubar"); if( iD == -4) { cfg.setGroup("Tabs"); QString tmp=cfg.readEntry("Position","Bottom"); if(tmp=="Top") { tab->setTabPosition(QTabWidget::Bottom); configMenu->changeItem( iD,"Tabs on Top"); cfg.writeEntry("Position","Bottom"); } else { tab->setTabPosition(QTabWidget::Top); configMenu->changeItem( iD,"Tabs on Bottom"); cfg.writeEntry("Position","Top"); } } + if( iD == -29) { + cfg.setGroup("ScrollBar"); + bool b=cfg.readBoolEntry("HorzScroll",0); + b=!b; + cfg.writeEntry("HorzScroll", b ); + cfg.write(); + doWrap(); + if(cfg.readNumEntry("Position",2) == 0) { + te->setScrollbarLocation(1); + } else { + te->setScrollbarLocation(0); + } + te->setScrollbarLocation( cfg.readNumEntry("Position",2)); + } } void Konsole::changeCommand(const QString &text, int c) { Config cfg("Konsole"); cfg.setGroup("Commands"); if(commonCmds[c] != text) { cfg.writeEntry(QString::number(c),text); commonCombo->clearEdit(); commonCombo->setCurrentItem(c); } } void Konsole::setColor() { Config cfg("Konsole"); cfg.setGroup("Colors"); int scheme = cfg.readNumEntry("Schema",1); if(scheme != 1) colorMenuSelected( -scheme); } void Konsole::scrollMenuSelected(int index) { qDebug( "scrollbar menu %d",index); TEWidget* te = getTe(); Config cfg("Konsole"); cfg.setGroup("ScrollBar"); switch( index){ case -25: te->setScrollbarLocation(0); cfg.writeEntry("Position",0); break; case -26: te->setScrollbarLocation(1); cfg.writeEntry("Position",1); break; case -27: te->setScrollbarLocation(2); cfg.writeEntry("Position",2); break; - case -29: { - bool b=cfg.readBoolEntry("HorzScroll",0); - cfg.writeEntry("HorzScroll", !b ); - cfg.write(); - if(cfg.readNumEntry("Position",2) == 0) - te->setScrollbarLocation(1); - else - te->setScrollbarLocation(0); - te->setScrollbarLocation( cfg.readNumEntry("Position",2)); - te->setWrapAt(120); - } - break; +// case -29: { +// bool b=cfg.readBoolEntry("HorzScroll",0); +// cfg.writeEntry("HorzScroll", !b ); +// cfg.write(); +// if(cfg.readNumEntry("Position",2) == 0) { +// te->setScrollbarLocation(1); +// te->setWrapAt(0); +// } else { +// te->setScrollbarLocation(0); +// te->setWrapAt(120); +// } +// te->setScrollbarLocation( cfg.readNumEntry("Position",2)); +// } +// break; }; - } void Konsole::editCommandListMenuSelected(int iD) { // QString temp; // qDebug( temp.sprintf("edit command list %d",iD)); TEWidget* te = getTe(); Config cfg("Konsole"); cfg.setGroup("Menubar"); if( iD == -3) { if(!secondToolBar->isHidden()) { secondToolBar->hide(); configMenu->changeItem( iD,tr( "Show Command List" )); cfg.writeEntry("Hidden","TRUE"); configMenu->setItemEnabled(-23 ,FALSE); } else { secondToolBar->show(); configMenu->changeItem( iD,tr( "Hide Command List" )); cfg.writeEntry("Hidden","FALSE"); configMenu->setItemEnabled(-23 ,TRUE); if(cfg.readEntry("EditEnabled","FALSE")=="TRUE") { configMenu->setItemChecked(-23,TRUE); commonCombo->setEditable( TRUE ); } else { configMenu->setItemChecked(-23,FALSE); commonCombo->setEditable( FALSE ); } } } if( iD == -23) { cfg.setGroup("Commands"); // qDebug("enableCommandEdit"); if( !configMenu->isItemChecked(iD) ) { commonCombo->setEditable( TRUE ); configMenu->setItemChecked(iD,TRUE); commonCombo->setCurrentItem(0); cfg.writeEntry("EditEnabled","TRUE"); } else { commonCombo->setEditable( FALSE ); configMenu->setItemChecked(iD,FALSE); cfg.writeEntry("EditEnabled","FALSE"); commonCombo->setFocusPolicy(QWidget::NoFocus); te->setFocus(); } } if(iD == -24) { // "edit commands" CommandEditDialog *m = new CommandEditDialog(this); connect(m,SIGNAL(commandsEdited()),this,SLOT(initCommandList())); m->showMaximized(); } } // $QPEDIR/bin/qcop QPE/Application/embeddedkonsole 'setDocument(QString)' 'ssh -V' void Konsole::setDocument( const QString &cmd) { newSession(); TEWidget* te = getTe(); if(cmd.find("-e", 0, TRUE) != -1) { QString cmd2; cmd2=cmd.right(cmd.length()-3)+" &"; system(cmd2.latin1()); if(startUp <= 1 && nsessions < 2) { doneSession(getTe()->currentSession, 0); exit(0); } else doneSession(getTe()->currentSession, 0); } else { if (te != 0) { te->emitText(cmd+"\r"); } } startUp++; } void Konsole::parseCommandLine() { QString cmd; // newSession(); for (int i=1;i< qApp->argc();i++) { if( QString(qApp->argv()[i]) == "-e") { i++; for ( int j=i;j< qApp->argc();j++) { cmd+=QString(qApp->argv()[j])+" "; } cmd.stripWhiteSpace(); system(cmd.latin1()); exit(0);//close(); } // end -e switch } startUp++; } void Konsole::changeForegroundColor(const QColor &color) { Config cfg("Konsole"); cfg.setGroup("Colors"); int r, g, b; color.rgb(&r,&g,&b); foreground.setRgb(r,g,b); // QString colors; // colors.sprintf("%d,%d,%d"color.red,color.green,color.blue); cfg.writeEntry("foreground",color.name()); cfg.write(); qDebug("do other dialog"); ColorPopupMenu* penColorPopupMenu2 = new ColorPopupMenu(Qt::black, this,"background color"); connect(penColorPopupMenu2, SIGNAL(colorSelected(const QColor&)), this, SLOT(changeBackgroundColor(const QColor&))); penColorPopupMenu2->exec(); } void Konsole::changeBackgroundColor(const QColor &color) { qDebug("Change background"); Config cfg("Konsole"); cfg.setGroup("Colors"); int r, g, b; color.rgb(&r,&g,&b); background.setRgb(r,g,b); // QString colors; // colors.sprintf("%d,%d,%d"color.red,color.green,color.blue); cfg.writeEntry("background",color.name()); cfg.write(); } + +void Konsole::doWrap() { + Config cfg("Konsole"); + cfg.setGroup("ScrollBar"); + TEWidget* te = getTe(); + if( !cfg.readBoolEntry("HorzScroll",0)) { + te->setWrapAt(0); + configMenu->setItemChecked(-29,FALSE); + } else { + te->setWrapAt(90); +// te->setWrapAt(120); + configMenu->setItemChecked(-29,TRUE); + } +} diff --git a/core/apps/embeddedkonsole/konsole.h b/core/apps/embeddedkonsole/konsole.h index 0bf3fb3..4938159 100644 --- a/core/apps/embeddedkonsole/konsole.h +++ b/core/apps/embeddedkonsole/konsole.h @@ -1,143 +1,144 @@ /* ----------------------------------------------------------------------- */ /* */ /* [konsole.h] Konsole */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole, an X terminal. */ /* */ /* The material contained in here more or less directly orginates from */ /* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ #ifndef KONSOLE_H #define KONSOLE_H #include <qmainwindow.h> #include <qaction.h> #include <qpopupmenu.h> #include <qstrlist.h> #include <qintdict.h> #include <qptrdict.h> #include <qtabwidget.h> #include <qpe/qpetoolbar.h> #include <qcombobox.h> #include <qcolor.h> #include "MyPty.h" #include "TEWidget.h" #include "TEmuVt102.h" #include "session.h" class EKNumTabWidget; class Konsole : public QMainWindow { Q_OBJECT public: Konsole(QWidget* parent = 0, const char* name = 0, WFlags fl = 0); Konsole(const char * name, const char* pgm, QStrList & _args, int histon); ~Konsole(); void setColLin(int columns, int lines); QPEToolBar *secondToolBar; void show(); void setColor(); int lastSelectedMenu; int startUp; private slots: void setDocument(const QString &); void doneSession(TESession*,int); void changeColumns(int); void fontChanged(int); void configMenuSelected(int ); void colorMenuSelected(int); void colorMenuIsSelected(int); void enterCommand(int); void hitEnter(); void hitSpace(); void hitTab(); void hitPaste(); void hitUp(); void hitDown(); void switchSession(QWidget *); void newSession(); void changeCommand(const QString &, int); void initCommandList(); void scrollMenuSelected(int); void editCommandListMenuSelected(int); void parseCommandLine(); void changeForegroundColor(const QColor &); void changeBackgroundColor(const QColor &); private: + void doWrap(); void init(const char* _pgm, QStrList & _args); void initSession(const char* _pgm, QStrList & _args); void runSession(TESession* s); void setColorPixmaps(); void setHistory(bool); QSize calcSize(int columns, int lines); TEWidget* getTe(); QStringList commands; QLabel * msgLabel; QColor foreground, background; bool fromMenu; private: class VTFont { public: VTFont(QString name, QFont& font) { this->name = name; this->font = font; } QFont& getFont() { return font; } QString getName() { return name; } private: QString name; QFont font; }; EKNumTabWidget* tab; int nsessions; QList<VTFont> fonts; int cfont; QCString se_pgm; QStrList se_args; QPopupMenu *fontList,*configMenu,*colorMenu,*scrollMenu,*editCommandListMenu; QComboBox *commonCombo; // history scrolling I think bool b_scroll; int n_keytab; int n_scroll; int n_render; QString pmPath; // pixmap path QString dropText; QFont defaultFont; QSize defaultSize; }; #endif |