author | chicken <chicken> | 2004-03-01 16:53:58 (UTC) |
---|---|---|
committer | chicken <chicken> | 2004-03-01 16:53:58 (UTC) |
commit | 8de0eea414192d758746a5f3950b9765e9709bf9 (patch) (side-by-side diff) | |
tree | 75f7c619ba161f395c058691af152226992d20a7 | |
parent | 49615014f281a58bd9bde5543692ffddab052755 (diff) | |
download | opie-8de0eea414192d758746a5f3950b9765e9709bf9.zip opie-8de0eea414192d758746a5f3950b9765e9709bf9.tar.gz opie-8de0eea414192d758746a5f3950b9765e9709bf9.tar.bz2 |
fix includes
-rw-r--r-- | core/apps/embeddedkonsole/MyPty.cpp | 1 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/TEWidget.cpp | 9 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/TEmuVt102.cpp | 5 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/TEmulation.cpp | 3 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/commandeditdialog.cpp | 8 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/commandeditwidget.cpp | 4 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/keytrans.cpp | 3 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/konsole.cpp | 21 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/playlistselection.cpp | 7 | ||||
-rw-r--r-- | core/apps/embeddedkonsole/session.cpp | 1 | ||||
-rw-r--r-- | core/apps/helpbrowser/helpbrowser.cpp | 24 | ||||
-rw-r--r-- | core/apps/helpbrowser/magictextbrowser.cpp | 2 | ||||
-rw-r--r-- | core/apps/oapp/oappplugin.cpp | 3 | ||||
-rw-r--r-- | core/apps/qcop/main.cpp | 2 | ||||
-rw-r--r-- | core/apps/taboapp/main.cpp | 1 | ||||
-rw-r--r-- | core/apps/textedit/filePermissions.cpp | 4 | ||||
-rw-r--r-- | core/apps/textedit/textedit.cpp | 18 |
17 files changed, 2 insertions, 114 deletions
diff --git a/core/apps/embeddedkonsole/MyPty.cpp b/core/apps/embeddedkonsole/MyPty.cpp index 5a8519a..d05e31e 100644 --- a/core/apps/embeddedkonsole/MyPty.cpp +++ b/core/apps/embeddedkonsole/MyPty.cpp @@ -1,289 +1,288 @@ /* -------------------------------------------------------------------------- */ /* */ /* [MyPty.C] Pseudo Terminal Device */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* 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> */ /* */ /* -------------------------------------------------------------------------- */ /* If you're compiling konsole on non-Linux platforms and find problems that you can track down to this file, please have a look into ../README.ports, too. */ /*! \file */ /*! \class TEPty \brief Ptys provide a pseudo terminal connection to a program. Although closely related to pipes, these pseudo terminal connections have some ability, that makes it nessesary to uses them. Most importent, they know about changing screen sizes and UNIX job control. Within the terminal emulation framework, this class represents the host side of the terminal together with the connecting serial line. One can create many instances of this class within a program. As a side effect of using this class, a signal(2) handler is installed on SIGCHLD. \par FIXME [NOTE: much of the technical stuff below will be replaced by forkpty.] publish the SIGCHLD signal if not related to an instance. clearify TEPty::done vs. TEPty::~TEPty semantics. check if pty is restartable via run after done. \par Pseudo terminals Pseudo terminals are a unique feature of UNIX, and always come in form of pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each other by the operating system. One may think of them as two serial devices linked by a null-modem cable. Being based on devices the number of simultanous instances of this class is (globally) limited by the number of those device pairs, which is 256. Another technic are UNIX 98 PTY's. These are supported also, and prefered over the (obsolete) predecessor. There's a sinister ioctl(2), signal(2) and job control stuff nessesary to make everything work as it should. */ #include <qfileinfo.h> #include <qapplication.h> #include <qsocketnotifier.h> -#include <qstring.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/wait.h> #ifdef HAVE_OPENPTY #include <pty.h> #endif #include "MyPty.h" #undef VERBOSE_DEBUG /* -------------------------------------------------------------------------- */ /*! Informs the client program about the actual size of the window. */ void MyPty::setSize(int lines, int columns) { struct winsize wsize; wsize.ws_row = (unsigned short)lines; wsize.ws_col = (unsigned short)columns; if(fd < 0) return; ioctl(fd,TIOCSWINSZ,(char *)&wsize); } void MyPty::donePty() { // This is code from the Qt DumbTerminal example int status = 0; ::close(fd); if (cpid) { kill(cpid, SIGHUP); waitpid(cpid, &status, 0); } emit done(status); } const char* MyPty::deviceName() { return ttynam; } void MyPty::error() { // This is code from the Qt DumbTerminal example donePty(); } /*! start the client program. */ int MyPty::run(const char* cmd, QStrList &, const char*, int) { // This is code from the Qt DumbTerminal example cpid = fork(); if ( !cpid ) { // child - exec shell on tty for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); // attempt to keep apm driver from killing us on power on/off signal(SIGSTOP, SIG_IGN); signal(SIGCONT, SIG_IGN); signal(SIGTSTP, SIG_IGN); int ttyfd = open(ttynam, O_RDWR); dup2(ttyfd, STDIN_FILENO); dup2(ttyfd, STDOUT_FILENO); dup2(ttyfd, STDERR_FILENO); // should be done with tty, so close it close(ttyfd); static struct termios ttmode; if ( setsid() < 0 ) perror( "failed to set process group" ); #if defined (TIOCSCTTY) // grabbed from APUE by Stevens ioctl(STDIN_FILENO, TIOCSCTTY, 0); #endif tcgetattr( STDIN_FILENO, &ttmode ); ttmode.c_cc[VINTR] = 3; ttmode.c_cc[VERASE] = 8; tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); setenv("TERM","vt100",1); setenv("COLORTERM","0",1); if (getuid() == 0) { char msg[] = "WARNING: You are running this shell as root!\n"; write(ttyfd, msg, sizeof(msg)); } QString ccmd = "-"+QFileInfo(cmd).fileName(); //creates a login shell execl(cmd, ccmd.latin1(), 0); donePty(); exit(-1); } // parent - continue as a widget QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this); QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this); connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); connect(sn_e,SIGNAL(activated(int)),this,SLOT(error())); return 0; } int MyPty::openPty() { // This is code from the Qt DumbTerminal example int ptyfd = -1; #ifdef HAVE_OPENPTY int ttyfd; if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) ptyfd = -1; else close(ttyfd); // we open the ttynam ourselves. #else for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { sprintf(ptynam,"/dev/pty%c%c",*c0,*c1); sprintf(ttynam,"/dev/tty%c%c",*c0,*c1); if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) { if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) { ::close(ptyfd); ptyfd = -1; } } } } #endif if ( ptyfd < 0 ) { qApp->exit(1); return -1; } return ptyfd; } /*! Create an instance. */ MyPty::MyPty() : cpid(0) { fd = openPty(); } /*! Destructor. Note that the related client program is not killed (yet) when a instance is deleted. */ MyPty::~MyPty() { donePty(); } /*! sends len bytes through the line */ void MyPty::send_bytes(const char* s, int len) { #ifdef VERBOSE_DEBUG // verbose debug printf("sending bytes:\n"); for (int i = 0; i < len; i++) printf("%c", s[i]); printf("\n"); #endif ::write(fd, s, len); } /*! indicates that a block of data is received */ void MyPty::readPty() { char buf[4096]; int len = ::read( fd, buf, 4096 ); if (len == -1) donePty(); if (len < 0) return; emit block_in(buf,len); #ifdef VERBOSE_DEBUG // verbose debug printf("read bytes:\n"); for (int i = 0; i < len; i++) printf("%c", buf[i]); printf("\n"); #endif } diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp index de5e585..8206e4b 100644 --- a/core/apps/embeddedkonsole/TEWidget.cpp +++ b/core/apps/embeddedkonsole/TEWidget.cpp @@ -1,1093 +1,1084 @@ /* ------------------------------------------------------------------------ */ /* */ /* [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> #if !(QT_NO_COP) #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 <qnamespace.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_w = fm.width("m"); font_a = fm.ascent(); printf("font h=%d max_width=%d width_m=%d assent=%d\n", font_h, fm.maxWidth(), font_w, font_a); //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; useBeep = true; 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(); mouse_down_x = ev->x(); mouse_down_y = ev->y(); //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); word_selection_mode = (ev->state() & ShiftButton); 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 (QABS(ev->x() - mouse_down_x) < 3 && QABS(ev->y() - mouse_down_y) < 3 && ev->y() < qApp->desktop()->height()/8) { emit setFullScreen(false); } 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(); // qDebug(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, ascii is 0x%x, state %d", ke->key(), ke->ascii(), ke->state()); bool special_function = true; switch(ke->key()) { // case 0x201b: // fn-5 // case Key_F1: // switch sessions (?) // emitText("\\"); // expose (??) // break; case 0x2016: // fn-p case Key_F2: pasteClipboard(); break; case 0x2018: // fn-S case Key_F3: emit changeSession(1); break; diff --git a/core/apps/embeddedkonsole/TEmuVt102.cpp b/core/apps/embeddedkonsole/TEmuVt102.cpp index 275c18d..0d6aef5 100644 --- a/core/apps/embeddedkonsole/TEmuVt102.cpp +++ b/core/apps/embeddedkonsole/TEmuVt102.cpp @@ -1,1020 +1,1015 @@ /* ------------------------------------------------------------------------- */ /* */ /* [TEmuVt102.C] VT102 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> */ /* */ /* -------------------------------------------------------------------------- */ /*! \class TEmuVt102 \brief Actual Emulation for Konsole \sa TEWidget \sa TEScreen */ #include "TEmuVt102.h" -#include "TEWidget.h" -#include "TEScreen.h" -#include "keytrans.h" #include <stdio.h> #include <unistd.h> -#include <qkeycode.h> -#include <qtextcodec.h> /* VT102 Terminal Emulation This class puts together the screens, the pty and the widget to a complete terminal emulation. Beside combining it's componentes, it handles the emulations's protocol. This module consists of the following sections: - Constructor/Destructor - Incoming Bytes Event pipeline - Outgoing Bytes - Mouse Events - Keyboard Events - Modes and Charset State - Diagnostics */ /* ------------------------------------------------------------------------- */ /* */ /* Constructor / Destructor */ /* */ /* ------------------------------------------------------------------------- */ /* Nothing really intesting happens here. */ /*! */ TEmuVt102::TEmuVt102(TEWidget* gui) : TEmulation(gui) { QObject::connect(gui,SIGNAL(mouseSignal(int,int,int)), this,SLOT(onMouse(int,int,int))); initTokenizer(); reset(); } /*! */ TEmuVt102::~TEmuVt102() { } /*! */ void TEmuVt102::reset() { resetToken(); resetModes(); resetCharset(0); screen[0]->reset(); resetCharset(1); screen[0]->reset(); setCodec(0); setKeytrans("linux.keytab"); } /* ------------------------------------------------------------------------- */ /* */ /* Processing the incoming byte stream */ /* */ /* ------------------------------------------------------------------------- */ /* Incoming Bytes Event pipeline This section deals with decoding the incoming character stream. Decoding means here, that the stream is first seperated into `tokens' which are then mapped to a `meaning' provided as operations by the `TEScreen' class or by the emulation class itself. The pipeline proceeds as follows: - Tokenizing the ESC codes (onRcvChar) - VT100 code page translation of plain characters (applyCharset) - Interpretation of ESC codes (tau) The escape codes and their meaning are described in the technical reference of this program. */ // Tokens ------------------------------------------------------------------ -- /* Since the tokens are the central notion if this section, we've put them in front. They provide the syntactical elements used to represent the terminals operations as byte sequences. They are encodes here into a single machine word, so that we can later switch over them easily. Depending on the token itself, additional argument variables are filled with parameter values. The tokens are defined below: - CHR - Printable characters (32..255 but DEL (=127)) - CTL - Control characters (0..31 but ESC (= 27), DEL) - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'> - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C - VT52 - VT52 escape codes - <ESC><Chr> - <ESC>'Y'{Pc}{Pc} - XTE_HA - Xterm hacks <ESC>`]' {Pn} `;' {Text} <BEL> note that this is handled differently The last two forms allow list of arguments. Since the elements of the lists are treated individually the same way, they are passed as individual tokens to the interpretation. Further, because the meaning of the parameters are names (althought represented as numbers), they are includes within the token ('N'). */ #define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) ) #define TY_CHR___( ) TY_CONSTR(0,0,0) #define TY_CTL___(A ) TY_CONSTR(1,A,0) #define TY_ESC___(A ) TY_CONSTR(2,A,0) #define TY_ESC_CS(A,B) TY_CONSTR(3,A,B) #define TY_ESC_DE(A ) TY_CONSTR(4,A,0) #define TY_CSI_PS(A,N) TY_CONSTR(5,A,N) #define TY_CSI_PN(A ) TY_CONSTR(6,A,0) #define TY_CSI_PR(A,N) TY_CONSTR(7,A,N) #define TY_VT52__(A ) TY_CONSTR(8,A,0) // Tokenizer --------------------------------------------------------------- -- /* The tokenizers state The state is represented by the buffer (pbuf, ppos), and accompanied by decoded arguments kept in (argv,argc). Note that they are kept internal in the tokenizer. */ void TEmuVt102::resetToken() { ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0; } void TEmuVt102::addDigit(int dig) { argv[argc] = 10*argv[argc] + dig; } void TEmuVt102::addArgument() { argc = QMIN(argc+1,MAXARGS-1); argv[argc] = 0; } void TEmuVt102::pushToToken(int cc) { pbuf[ppos] = cc; ppos = QMIN(ppos+1,MAXPBUF-1); } // Character Classes used while decoding #define CTL 1 #define CHR 2 #define CPN 4 #define DIG 8 #define SCS 16 #define GRP 32 void TEmuVt102::initTokenizer() { int i; UINT8* s; for(i = 0; i < 256; i++) tbl[ i] = 0; for(i = 0; i < 32; i++) tbl[ i] |= CTL; for(i = 32; i < 256; i++) tbl[ i] |= CHR; for(s = (UINT8*)"@ABCDGHLMPXcdfry"; *s; s++) tbl[*s] |= CPN; for(s = (UINT8*)"0123456789" ; *s; s++) tbl[*s] |= DIG; for(s = (UINT8*)"()+*%" ; *s; s++) tbl[*s] |= SCS; for(s = (UINT8*)"()+*#[]%" ; *s; s++) tbl[*s] |= GRP; resetToken(); } /* Ok, here comes the nasty part of the decoder. Instead of keeping an explicit state, we deduce it from the token scanned so far. It is then immediately combined with the current character to form a scanning decision. This is done by the following defines. - P is the length of the token scanned so far. - L (often P-1) is the position on which contents we base a decision. - C is a character or a group of characters (taken from 'tbl'). Note that they need to applied in proper order. */ #define lec(P,L,C) (p == (P) && s[(L)] == (C)) #define lun( ) (p == 1 && cc >= 32 ) #define les(P,L,C) (p == (P) && s[L] < 256 && (tbl[s[(L)]] & (C)) == (C)) #define eec(C) (p >= 3 && cc == (C)) #define ees(C) (p >= 3 && cc < 256 && (tbl[ cc ] & (C)) == (C)) #define eps(C) (p >= 3 && s[2] != '?' && cc < 256 && (tbl[ cc ] & (C)) == (C)) #define epp( ) (p >= 3 && s[2] == '?' ) #define egt( ) (p == 3 && s[2] == '>' ) #define Xpe (ppos>=2 && pbuf[1] == ']' ) #define Xte (Xpe && cc == 7 ) #define ces(C) ( cc < 256 && (tbl[ cc ] & (C)) == (C) && !Xte) #define ESC 27 #define CNTL(c) ((c)-'@') // process an incoming unicode character void TEmuVt102::onRcvChar(int cc) { int i; if (cc == 127) return; //VT100: ignore. if (ces( CTL)) { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100 // This means, they do neither a resetToken nor a pushToToken. Some of them, do // of course. Guess this originates from a weakly layered handling of the X-on // X-off protocol, which comes really below this level. if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB if (cc != ESC) { tau( TY_CTL___(cc+'@' ), 0, 0); return; } } pushToToken(cc); // advance the state int* s = pbuf; int p = ppos; if (getMode(MODE_Ansi)) // decide on proper action { if (lec(1,0,ESC)) { return; } if (les(2,1,GRP)) { return; } if (Xte ) { XtermHack(); resetToken(); return; } if (Xpe ) { return; } if (lec(3,2,'?')) { return; } if (lec(3,2,'>')) { return; } if (lun( )) { tau( TY_CHR___(), applyCharset(cc), 0); resetToken(); return; } if (lec(2,0,ESC)) { tau( TY_ESC___(s[1]), 0, 0); resetToken(); return; } if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]), 0, 0); resetToken(); return; } if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]), 0, 0); resetToken(); return; } // if (egt( )) { tau( TY_CSI_PG(cc ), '>', 0); resetToken(); return; } if (eps( CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]); resetToken(); return; } if (ees( DIG)) { addDigit(cc-'0'); return; } if (eec( ';')) { addArgument(); return; } for (i=0;i<=argc;i++) if (epp( )) tau( TY_CSI_PR(cc,argv[i]), 0, 0); else tau( TY_CSI_PS(cc,argv[i]), 0, 0); resetToken(); } else // mode VT52 { if (lec(1,0,ESC)) return; if (les(1,0,CHR)) { tau( TY_CHR___( ), s[0], 0); resetToken(); return; } if (lec(2,1,'Y')) return; if (lec(3,1,'Y')) return; if (p < 4) { tau( TY_VT52__(s[1] ), 0, 0); resetToken(); return; } tau( TY_VT52__(s[1] ), s[2],s[3]); resetToken(); return; } } void TEmuVt102::XtermHack() { int i,arg = 0; for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++) arg = 10*arg + (pbuf[i]-'0'); if (pbuf[i] != ';') { ReportErrorToken(); return; } QChar *str = new QChar[ppos-i-2]; for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j]; QString unistr(str,ppos-i-2); // arg == 1 doesn't change the title. In XTerm it only changes the icon name // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title if (arg == 0 || arg == 2) emit changeTitle(arg,unistr); delete [] str; } // Interpreting Codes --------------------------------------------------------- /* Now that the incoming character stream is properly tokenized, meaning is assigned to them. These are either operations of the current screen, or of the emulation class itself. The token to be interpreteted comes in as a machine word possibly accompanied by two parameters. Likewise, the operations assigned to, come with up to two arguments. One could consider to make up a proper table from the function below. The technical reference manual provides more informations about this mapping. */ void TEmuVt102::tau( int token, int p, int q ) { //scan_buffer_report(); //if (token == TY_CHR___()) printf("%c",p); else //printf("tau(%d,%d,%d, %d,%d)\n",(token>>0)&0xff,(token>>8)&0xff,(token>>16)&0xffff,p,q); switch (token) { case TY_CHR___( ) : scr->ShowCharacter (p ); break; //UTF16 // 127 DEL : ignored on input case TY_CTL___('@' ) : /* NUL: ignored */ break; case TY_CTL___('A' ) : /* SOH: ignored */ break; case TY_CTL___('B' ) : /* STX: ignored */ break; case TY_CTL___('C' ) : /* ETX: ignored */ break; case TY_CTL___('D' ) : /* EOT: ignored */ break; case TY_CTL___('E' ) : reportAnswerBack ( ); break; //VT100 case TY_CTL___('F' ) : /* ACK: ignored */ break; case TY_CTL___('G' ) : gui->Bell ( ); break; //VT100 case TY_CTL___('H' ) : scr->BackSpace ( ); break; //VT100 case TY_CTL___('I' ) : scr->Tabulate ( ); break; //VT100 case TY_CTL___('J' ) : scr->NewLine ( ); break; //VT100 case TY_CTL___('K' ) : scr->NewLine ( ); break; //VT100 case TY_CTL___('L' ) : scr->NewLine ( ); break; //VT100 case TY_CTL___('M' ) : scr->Return ( ); break; //VT100 case TY_CTL___('N' ) : useCharset ( 1); break; //VT100 case TY_CTL___('O' ) : useCharset ( 0); break; //VT100 case TY_CTL___('P' ) : /* DLE: ignored */ break; case TY_CTL___('Q' ) : /* DC1: XON continue */ break; //VT100 case TY_CTL___('R' ) : /* DC2: ignored */ break; case TY_CTL___('S' ) : /* DC3: XOFF halt */ break; //VT100 case TY_CTL___('T' ) : /* DC4: ignored */ break; case TY_CTL___('U' ) : /* NAK: ignored */ break; case TY_CTL___('V' ) : /* SYN: ignored */ break; case TY_CTL___('W' ) : /* ETB: ignored */ break; case TY_CTL___('X' ) : scr->ShowCharacter ( 0x2592); break; //VT100 case TY_CTL___('Y' ) : /* EM : ignored */ break; case TY_CTL___('Z' ) : scr->ShowCharacter ( 0x2592); break; //VT100 case TY_CTL___('[' ) : /* ESC: cannot be seen here. */ break; case TY_CTL___('\\' ) : /* FS : ignored */ break; case TY_CTL___(']' ) : /* GS : ignored */ break; case TY_CTL___('^' ) : /* RS : ignored */ break; case TY_CTL___('_' ) : /* US : ignored */ break; case TY_ESC___('D' ) : scr->index ( ); break; //VT100 case TY_ESC___('E' ) : scr->NextLine ( ); break; //VT100 case TY_ESC___('H' ) : scr->changeTabStop (TRUE ); break; //VT100 case TY_ESC___('M' ) : scr->reverseIndex ( ); break; //VT100 case TY_ESC___('Z' ) : reportTerminalType ( ); break; case TY_ESC___('c' ) : reset ( ); break; case TY_ESC___('n' ) : useCharset ( 2); break; case TY_ESC___('o' ) : useCharset ( 3); break; case TY_ESC___('7' ) : saveCursor ( ); break; case TY_ESC___('8' ) : restoreCursor ( ); break; case TY_ESC___('=' ) : setMode (MODE_AppKeyPad); break; case TY_ESC___('>' ) : resetMode (MODE_AppKeyPad); break; case TY_ESC___('<' ) : setMode (MODE_Ansi ); break; //VT100 case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100 case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100 case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100 case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100 case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100 case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100 case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100 case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100 case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100 case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100 case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100 case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100 case TY_ESC_CS('%', 'G') : setCodec (1 ); break; //LINUX case TY_ESC_CS('%', '@') : setCodec (0 ); break; //LINUX case TY_ESC_DE('3' ) : /* IGNORED: double high, top half */ break; case TY_ESC_DE('4' ) : /* IGNORED: double high, bottom half */ break; case TY_ESC_DE('5' ) : /* IGNORED: single width, single high*/ break; case TY_ESC_DE('6' ) : /* IGNORED: double width, single high*/ break; case TY_ESC_DE('8' ) : scr->helpAlign ( ); break; case TY_CSI_PS('K', 0) : scr->clearToEndOfLine ( ); break; case TY_CSI_PS('K', 1) : scr->clearToBeginOfLine ( ); break; case TY_CSI_PS('K', 2) : scr->clearEntireLine ( ); break; case TY_CSI_PS('J', 0) : scr->clearToEndOfScreen ( ); break; case TY_CSI_PS('J', 1) : scr->clearToBeginOfScreen ( ); break; case TY_CSI_PS('J', 2) : scr->clearEntireScreen ( ); break; case TY_CSI_PS('g', 0) : scr->changeTabStop (FALSE ); break; //VT100 case TY_CSI_PS('g', 3) : scr->clearTabStops ( ); break; //VT100 case TY_CSI_PS('h', 4) : scr-> setMode (MODE_Insert ); break; case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break; case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100 case TY_CSI_PS('l', 4) : scr-> resetMode (MODE_Insert ); break; case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break; case TY_CSI_PS('m', 0) : scr->setDefaultRendition ( ); break; case TY_CSI_PS('m', 1) : scr-> setRendition (RE_BOLD ); break; //VT100 case TY_CSI_PS('m', 4) : scr-> setRendition (RE_UNDERLINE); break; //VT100 case TY_CSI_PS('m', 5) : scr-> setRendition (RE_BLINK ); break; //VT100 case TY_CSI_PS('m', 7) : scr-> setRendition (RE_REVERSE ); break; case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX case TY_CSI_PS('m', 22) : scr->resetRendition (RE_BOLD ); break; case TY_CSI_PS('m', 24) : scr->resetRendition (RE_UNDERLINE); break; case TY_CSI_PS('m', 25) : scr->resetRendition (RE_BLINK ); break; case TY_CSI_PS('m', 27) : scr->resetRendition (RE_REVERSE ); break; case TY_CSI_PS('m', 30) : scr->setForeColor ( 0); break; case TY_CSI_PS('m', 31) : scr->setForeColor ( 1); break; case TY_CSI_PS('m', 32) : scr->setForeColor ( 2); break; case TY_CSI_PS('m', 33) : scr->setForeColor ( 3); break; case TY_CSI_PS('m', 34) : scr->setForeColor ( 4); break; case TY_CSI_PS('m', 35) : scr->setForeColor ( 5); break; case TY_CSI_PS('m', 36) : scr->setForeColor ( 6); break; case TY_CSI_PS('m', 37) : scr->setForeColor ( 7); break; case TY_CSI_PS('m', 39) : scr->setForeColorToDefault( ); break; case TY_CSI_PS('m', 40) : scr->setBackColor ( 0); break; case TY_CSI_PS('m', 41) : scr->setBackColor ( 1); break; case TY_CSI_PS('m', 42) : scr->setBackColor ( 2); break; case TY_CSI_PS('m', 43) : scr->setBackColor ( 3); break; case TY_CSI_PS('m', 44) : scr->setBackColor ( 4); break; case TY_CSI_PS('m', 45) : scr->setBackColor ( 5); break; case TY_CSI_PS('m', 46) : scr->setBackColor ( 6); break; case TY_CSI_PS('m', 47) : scr->setBackColor ( 7); break; case TY_CSI_PS('m', 49) : scr->setBackColorToDefault( ); break; case TY_CSI_PS('m', 90) : scr->setForeColor ( 8); break; case TY_CSI_PS('m', 91) : scr->setForeColor ( 9); break; case TY_CSI_PS('m', 92) : scr->setForeColor ( 10); break; case TY_CSI_PS('m', 93) : scr->setForeColor ( 11); break; case TY_CSI_PS('m', 94) : scr->setForeColor ( 12); break; case TY_CSI_PS('m', 95) : scr->setForeColor ( 13); break; case TY_CSI_PS('m', 96) : scr->setForeColor ( 14); break; case TY_CSI_PS('m', 97) : scr->setForeColor ( 15); break; case TY_CSI_PS('m', 100) : scr->setBackColor ( 8); break; case TY_CSI_PS('m', 101) : scr->setBackColor ( 9); break; case TY_CSI_PS('m', 102) : scr->setBackColor ( 10); break; case TY_CSI_PS('m', 103) : scr->setBackColor ( 11); break; case TY_CSI_PS('m', 104) : scr->setBackColor ( 12); break; case TY_CSI_PS('m', 105) : scr->setBackColor ( 13); break; case TY_CSI_PS('m', 106) : scr->setBackColor ( 14); break; case TY_CSI_PS('m', 107) : scr->setBackColor ( 15); break; case TY_CSI_PS('n', 5) : reportStatus ( ); break; case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break; case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100 case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100 case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100 case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100 case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100 case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100 case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100 case TY_CSI_PN('@' ) : scr->insertChars (p ); break; case TY_CSI_PN('A' ) : scr->cursorUp (p ); break; //VT100 case TY_CSI_PN('B' ) : scr->cursorDown (p ); break; //VT100 case TY_CSI_PN('C' ) : scr->cursorRight (p ); break; //VT100 case TY_CSI_PN('D' ) : scr->cursorLeft (p ); break; //VT100 case TY_CSI_PN('G' ) : scr->setCursorX (p ); break; //LINUX case TY_CSI_PN('H' ) : scr->setCursorYX (p, q); break; //VT100 case TY_CSI_PN('L' ) : scr->insertLines (p ); break; case TY_CSI_PN('M' ) : scr->deleteLines (p ); break; case TY_CSI_PN('P' ) : scr->deleteChars (p ); break; case TY_CSI_PN('X' ) : scr->eraseChars (p ); break; case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100 case TY_CSI_PN('d' ) : scr->setCursorY (p ); break; //LINUX case TY_CSI_PN('f' ) : scr->setCursorYX (p, q); break; //VT100 case TY_CSI_PN('r' ) : scr->setMargins (p, q); break; //VT100 case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100 case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100 case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100 case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100 case TY_CSI_PR('h', 3) : setColumns ( 132); break; //VT100 case TY_CSI_PR('l', 3) : setColumns ( 80); break; //VT100 case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100 case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100 case TY_CSI_PR('h', 5) : scr-> setMode (MODE_Screen ); break; //VT100 case TY_CSI_PR('l', 5) : scr-> resetMode (MODE_Screen ); break; //VT100 case TY_CSI_PR('h', 6) : scr-> setMode (MODE_Origin ); break; //VT100 case TY_CSI_PR('l', 6) : scr-> resetMode (MODE_Origin ); break; //VT100 case TY_CSI_PR('s', 6) : scr-> saveMode (MODE_Origin ); break; //FIXME case TY_CSI_PR('r', 6) : scr->restoreMode (MODE_Origin ); break; //FIXME case TY_CSI_PR('h', 7) : scr-> setMode (MODE_Wrap ); break; //VT100 case TY_CSI_PR('l', 7) : scr-> resetMode (MODE_Wrap ); break; //VT100 case TY_CSI_PR('s', 7) : scr-> saveMode (MODE_Wrap ); break; //FIXME case TY_CSI_PR('r', 7) : scr->restoreMode (MODE_Wrap ); break; //FIXME case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100 case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100 case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100 case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100 case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100 case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100 case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100 case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100 case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM case TY_CSI_PR('l', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM case TY_CSI_PR('l', 1047) : resetMode (MODE_AppScreen); break; //XTERM //FIXME: Unitoken: save translations case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM //FIXME: every once new sequences like this pop up in xterm. // Here's a guess of what they could mean. case TY_CSI_PR('h', 1049) : setMode (MODE_AppScreen); break; //XTERM case TY_CSI_PR('l', 1049) : resetMode (MODE_AppScreen); break; //XTERM //FIXME: when changing between vt52 and ansi mode evtl do some resetting. case TY_VT52__('A' ) : scr->cursorUp ( 1); break; //VT52 case TY_VT52__('B' ) : scr->cursorDown ( 1); break; //VT52 case TY_VT52__('C' ) : scr->cursorRight ( 1); break; //VT52 case TY_VT52__('D' ) : scr->cursorLeft ( 1); break; //VT52 case TY_VT52__('F' ) : setAndUseCharset (0, '0'); break; //VT52 case TY_VT52__('G' ) : setAndUseCharset (0, 'B'); break; //VT52 case TY_VT52__('H' ) : scr->setCursorYX (1,1 ); break; //VT52 case TY_VT52__('I' ) : scr->reverseIndex ( ); break; //VT52 case TY_VT52__('J' ) : scr->clearToEndOfScreen ( ); break; //VT52 case TY_VT52__('K' ) : scr->clearToEndOfLine ( ); break; //VT52 case TY_VT52__('Y' ) : scr->setCursorYX (p-31,q-31 ); break; //VT52 case TY_VT52__('Z' ) : reportTerminalType ( ); break; //VT52 case TY_VT52__('<' ) : setMode (MODE_Ansi ); break; //VT52 case TY_VT52__('=' ) : setMode (MODE_AppKeyPad); break; //VT52 case TY_VT52__('>' ) : resetMode (MODE_AppKeyPad); break; //VT52 default : ReportErrorToken(); break; }; } /* ------------------------------------------------------------------------- */ /* */ /* Terminal to Host protocol */ /* */ /* ------------------------------------------------------------------------- */ /* Outgoing bytes originate from several sources: - Replies to Enquieries. - Mouse Events - Keyboard Events */ /*! */ void TEmuVt102::sendString(const char* s) { emit sndBlock(s,strlen(s)); } // Replies ----------------------------------------------------------------- -- // This section copes with replies send as response to an enquiery control code. /*! */ void TEmuVt102::reportCursorPosition() { char tmp[20]; sprintf(tmp,"\033[%d;%dR",scr->getCursorY()+1,scr->getCursorX()+1); sendString(tmp); } /* What follows here is rather obsolete and faked stuff. The correspondent enquieries are neverthenless issued. */ /*! */ void TEmuVt102::reportTerminalType() { //FIXME: should change? if (getMode(MODE_Ansi)) // sendString("\033[?1;2c"); // I'm a VT100 with AP0 //FIXME: send only in response to ^[[0c sendString("\033[>0;115;0c"); // I'm a VT220 //FIXME: send only in response to ^[[>c else sendString("\033/Z"); // I'm a VT52 } void TEmuVt102::reportTerminalParms(int p) // DECREPTPARM { char tmp[100]; sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true. sendString(tmp); } /*! */ void TEmuVt102::reportStatus() { sendString("\033[0n"); //VT100. Device status report. 0 = Ready. } /*! */ #define ANSWER_BACK "" // This is really obsolete VT100 stuff. void TEmuVt102::reportAnswerBack() { sendString(ANSWER_BACK); } // Mouse Handling ---------------------------------------------------------- -- /*! Mouse clicks are possibly reported to the client application if it has issued interest in them. They are normally consumed by the widget for copy and paste, but may be propagated from the widget when gui->setMouseMarks is set via setMode(MODE_Mouse1000). `x',`y' are 1-based. `ev' (event) indicates the button pressed (0-2) or a general mouse release (3). */ void TEmuVt102::onMouse( int cb, int cx, int cy ) { char tmp[20]; if (!connected) return; sprintf(tmp,"\033[M%c%c%c",cb+040,cx+040,cy+040); sendString(tmp); } // Keyboard Handling ------------------------------------------------------- -- #define encodeMode(M,B) BITS(B,getMode(M)) #define encodeStat(M,B) BITS(B,((ev->state() & (M)) == (M))) /* Keyboard event handling has been simplified somewhat by pushing the complications towards a configuration file [see KeyTrans class]. */ void TEmuVt102::onKeyPress( QKeyEvent* ev ) { if (!connected) return; // someone else gets the keys //printf("State/Key: 0x%04x 0x%04x (%d,%d)\n",ev->state(),ev->key(),ev->text().length(),ev->text().length()?ev->text().ascii()[0]:0); // revert to non-history when typing if (scr->getHistCursor() != scr->getHistLines()); scr->setHistCursor(scr->getHistLines()); // lookup in keyboard translation table ... int cmd; const char* txt; int len; if (keytrans->findEntry(ev->key(), encodeMode(MODE_NewLine , BITS_NewLine ) + // OLD, encodeMode(MODE_Ansi , BITS_Ansi ) + // OBSOLETE, encodeMode(MODE_AppCuKeys, BITS_AppCuKeys ) + // VT100 stuff encodeStat(ControlButton , BITS_Control ) + encodeStat(ShiftButton , BITS_Shift ) + encodeStat(AltButton , BITS_Alt ), &cmd, &txt, &len )) //printf("cmd: %d, %s, %d\n",cmd,txt,len); switch(cmd) // ... and execute if found. { case CMD_emitSelection : gui->emitSelection(); return; case CMD_scrollPageUp : gui->doScroll(-gui->Lines()/2); return; case CMD_scrollPageDown : gui->doScroll(+gui->Lines()/2); return; case CMD_scrollLineUp : gui->doScroll(-1 ); return; case CMD_scrollLineDown : gui->doScroll(+1 ); return; case CMD_send : emit sndBlock(txt,len); return; case CMD_prevSession : emit prevSession(); return; case CMD_nextSession : emit nextSession(); return; } // fall back handling if (!ev->text().isEmpty()) { if (ev->state() & AltButton) sendString("\033"); // ESC, this is the ALT prefix /// very hacky if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='A')) sendString("\01"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='B')) sendString("\02"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='C')) sendString("\03"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='D')) sendString("\04"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='E')) sendString("\05"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='F')) sendString("\06"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='G')) sendString("\07"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='H')) sendString("\010"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='I')) sendString("\011"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='J')) sendString("\012"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='K')) sendString("\013"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='L')) sendString("\014"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='M')) sendString("\015"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='N')) sendString("\016"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='O')) sendString("\017"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='P')) sendString("\020"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='Q')) sendString("\021"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='R')) sendString("\022"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='S')) sendString("\023"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='T')) sendString("\024"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='U')) sendString("\025"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='V')) sendString("\026"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='W')) sendString("\027"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='X')) sendString("\030"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='Y')) sendString("\031"); else if ((ev->state() & ControlButton) && (ev->text().upper().ascii()[0]=='Z')) sendString("\032"); else { QCString s = codec->fromUnicode(ev->text()); // encode for application emit sndBlock(s.data(),s.length()); // we may well have s.length() > 1 } return; } } /* ------------------------------------------------------------------------- */ /* */ /* VT100 Charsets */ /* */ /* ------------------------------------------------------------------------- */ // Character Set Conversion ------------------------------------------------ -- /* The processing contains a VT100 specific code translation layer. It's still in use and mainly responsible for the line drawing graphics. These and some other glyphs are assigned to codes (0x5f-0xfe) normally occupied by the latin letters. Since this codes also appear within control sequences, the extra code conversion does not permute with the tokenizer and is placed behind it in the pipeline. It only applies to tokens, which represent plain characters. This conversion it eventually continued in TEWidget.C, since it might involve VT100 enhanced fonts, which have these particular glyphs allocated in (0x00-0x1f) in their code page. */ #define CHARSET charset[scr==screen[1]] // Apply current character map. unsigned short TEmuVt102::applyCharset(unsigned short c) { if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f]; if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete return c; } /* "Charset" related part of the emulation state. This configures the VT100 charset filter. While most operation work on the current screen, the following two are different. */ void TEmuVt102::resetCharset(int scrno) { charset[scrno].cu_cs = 0; strncpy(charset[scrno].charset,"BBBB",4); charset[scrno].sa_graphic = FALSE; charset[scrno].sa_pound = FALSE; charset[scrno].graphic = FALSE; charset[scrno].pound = FALSE; } /*! */ void TEmuVt102::setCharset(int n, int cs) // on both screens. { charset[0].charset[n&3] = cs; useCharset(charset[0].cu_cs); charset[1].charset[n&3] = cs; useCharset(charset[1].cu_cs); } /*! */ void TEmuVt102::setAndUseCharset(int n, int cs) { CHARSET.charset[n&3] = cs; useCharset(n&3); } /*! */ void TEmuVt102::useCharset(int n) { CHARSET.cu_cs = n&3; CHARSET.graphic = (CHARSET.charset[n&3] == '0'); CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete } /*! Save the cursor position and the rendition attribute settings. */ void TEmuVt102::saveCursor() { CHARSET.sa_graphic = CHARSET.graphic; CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete // we are not clear about these //sa_charset = charsets[cScreen->charset]; //sa_charset_num = cScreen->charset; scr->saveCursor(); } /*! Restore the cursor position and the rendition attribute settings. */ void TEmuVt102::restoreCursor() { CHARSET.graphic = CHARSET.sa_graphic; CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete scr->restoreCursor(); } /* ------------------------------------------------------------------------- */ /* */ /* Mode Operations */ /* */ /* ------------------------------------------------------------------------- */ /* Some of the emulations state is either added to the state of the screens. This causes some scoping problems, since different emulations choose to located the mode either to the current screen or to both. For strange reasons, the extend of the rendition attributes ranges over all screens and not over the actual screen. We decided on the precise precise extend, somehow. */ // "Mode" related part of the state. These are all booleans. void TEmuVt102::resetModes() { resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000); resetMode(MODE_AppScreen); saveMode(MODE_AppScreen); // here come obsolete modes resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys); resetMode(MODE_NewLine ); setMode(MODE_Ansi ); } void TEmuVt102::setMode(int m) { currParm.mode[m] = TRUE; switch (m) { case MODE_Mouse1000 : gui->setMouseMarks(FALSE); break; case MODE_AppScreen : screen[1]->clearSelection(); screen[1]->clearEntireScreen(); setScreen(1); break; } if (m < MODES_SCREEN || m == MODE_NewLine) { screen[0]->setMode(m); screen[1]->setMode(m); } } void TEmuVt102::resetMode(int m) { currParm.mode[m] = FALSE; switch (m) { case MODE_Mouse1000 : gui->setMouseMarks(TRUE); break; case MODE_AppScreen : screen[0]->clearSelection(); setScreen(0); break; } if (m < MODES_SCREEN || m == MODE_NewLine) { screen[0]->resetMode(m); screen[1]->resetMode(m); } } void TEmuVt102::saveMode(int m) { saveParm.mode[m] = currParm.mode[m]; } void TEmuVt102::restoreMode(int m) { if(saveParm.mode[m]) setMode(m); else resetMode(m); } BOOL TEmuVt102::getMode(int m) { return currParm.mode[m]; } void TEmuVt102::setConnect(bool c) { TEmulation::setConnect(c); if (c) { // refresh mouse mode if (getMode(MODE_Mouse1000)) setMode(MODE_Mouse1000); else resetMode(MODE_Mouse1000); } } /* ------------------------------------------------------------------------- */ /* */ /* Diagnostic */ /* */ /* ------------------------------------------------------------------------- */ /*! shows the contents of the scan buffer. This functions is used for diagnostics. It is called by \e ReportErrorToken to inform about strings that cannot be decoded or handled by the emulation. \sa ReportErrorToken */ /*! */ static void hexdump(int* s, int len) { int i; for (i = 0; i < len; i++) { if (s[i] == '\\') printf("\\\\"); else if ((s[i]) > 32 && s[i] < 127) printf("%c",s[i]); else printf("\\%04x(hex)",s[i]); } } void TEmuVt102::scan_buffer_report() { if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return; printf("token: "); hexdump(pbuf,ppos); printf("\n"); } /*! */ void TEmuVt102::ReportErrorToken() { printf("undecodable "); scan_buffer_report(); } diff --git a/core/apps/embeddedkonsole/TEmulation.cpp b/core/apps/embeddedkonsole/TEmulation.cpp index a539757..54f408e 100644 --- a/core/apps/embeddedkonsole/TEmulation.cpp +++ b/core/apps/embeddedkonsole/TEmulation.cpp @@ -1,379 +1,376 @@ /* -------------------------------------------------------------------------- */ /* */ /* [TEmulation.cpp] Terminal Emulation Decoder */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* 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 TEmulation \brief Mediator between TEWidget and TEScreen. This class is responsible to scan the escapes sequences of the terminal emulation and to map it to their corresponding semantic complements. Thus this module knows mainly about decoding escapes sequences and is a stateless device w.r.t. the semantics. It is also responsible to refresh the TEWidget by certain rules. \sa TEWidget \sa TEScreen \par A note on refreshing Although the modifications to the current screen image could immediately be propagated via `TEWidget' to the graphical surface, we have chosen another way here. The reason for doing so is twofold. First, experiments show that directly displaying the operation results in slowing down the overall performance of emulations. Displaying individual characters using X11 creates a lot of overhead. Second, by using the following refreshing method, the screen operations can be completely separated from the displaying. This greatly simplifies the programmer's task of coding and maintaining the screen operations, since one need not worry about differential modifications on the display affecting the operation of concern. We use a refreshing algorithm here that has been adoped from rxvt/kvt. By this, refreshing is driven by a timer, which is (re)started whenever a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'. As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger refresh. This rule suits both bulk display operation as done by curses as well as individual characters typed. (BULK_TIMEOUT < 1000 / max characters received from keyboard per second). Additionally, we trigger refreshing by newlines comming in to make visual snapshots of lists as produced by `cat', `ls' and likely programs, thereby producing the illusion of a permanent and immediate display operation. As a sort of catch-all needed for cases where none of the above conditions catch, the screen refresh is also triggered by a count of incoming bulks (`bulk_incnt'). */ /* FIXME - evtl. the bulk operations could be made more transparent. */ #include "TEmulation.h" -#include "TEWidget.h" -#include "TEScreen.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <qkeycode.h> /* ------------------------------------------------------------------------- */ /* */ /* TEmulation */ /* */ /* ------------------------------------------------------------------------- */ #define CNTL(c) ((c)-'@') /*! */ TEmulation::TEmulation(TEWidget* gui) : decoder((QTextDecoder*)NULL) { this->gui = gui; screen[0] = new TEScreen(gui->Lines(),gui->Columns()); screen[1] = new TEScreen(gui->Lines(),gui->Columns()); scr = screen[0]; bulk_nlcnt = 0; // reset bulk newline counter bulk_incnt = 0; // reset bulk counter connected = FALSE; QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) ); QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)), this,SLOT(onImageSizeChange(int,int))); QObject::connect(gui,SIGNAL(changedHistoryCursor(int)), this,SLOT(onHistoryCursorChange(int))); QObject::connect(gui,SIGNAL(changedHorzCursor(int)), this,SLOT(onHorzCursorChange(int))); QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)), this,SLOT(onKeyPress(QKeyEvent*))); QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)), this,SLOT(onSelectionBegin(const int,const int)) ); QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)), this,SLOT(onSelectionExtend(const int,const int)) ); QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)), this,SLOT(setSelection(const BOOL)) ); QObject::connect(gui,SIGNAL(clearSelectionSignal()), this,SLOT(clearSelection()) ); } /*! */ TEmulation::~TEmulation() { delete screen[0]; delete screen[1]; bulk_timer.stop(); } /*! change between primary and alternate screen */ void TEmulation::setScreen(int n) { scr = screen[n&1]; } void TEmulation::setHistory(bool on) { screen[0]->setScroll(on); if (!connected) return; showBulk(); } bool TEmulation::history() { return screen[0]->hasScroll(); } void TEmulation::setCodec(int c) { //FIXME: check whether we have to free codec codec = c ? QTextCodec::codecForName("utf8") : QTextCodec::codecForLocale(); if (decoder) delete decoder; decoder = codec->makeDecoder(); } void TEmulation::setKeytrans(int no) { keytrans = KeyTrans::find(no); } void TEmulation::setKeytrans(const char * no) { keytrans = KeyTrans::find(no); } // Interpreting Codes --------------------------------------------------------- /* This section deals with decoding the incoming character stream. Decoding means here, that the stream is first seperated into `tokens' which are then mapped to a `meaning' provided as operations by the `Screen' class. */ /*! */ void TEmulation::onRcvChar(int c) // process application unicode input to terminal // this is a trivial scanner { c &= 0xff; switch (c) { case '\b' : scr->BackSpace(); break; case '\t' : scr->Tabulate(); break; case '\n' : scr->NewLine(); break; case '\r' : scr->Return(); break; case 0x07 : gui->Bell(); break; default : scr->ShowCharacter(c); break; }; } /* ------------------------------------------------------------------------- */ /* */ /* Keyboard Handling */ /* */ /* ------------------------------------------------------------------------- */ /*! */ void TEmulation::onKeyPress( QKeyEvent* ev ) { if (!connected) return; // someone else gets the keys if (scr->getHistCursor() != scr->getHistLines()); scr->setHistCursor(scr->getHistLines()); if (!ev->text().isEmpty()) { // A block of text // Note that the text is proper unicode. // We should do a conversion here, but since this // routine will never be used, we simply emit plain ascii. emit sndBlock(ev->text().ascii(),ev->text().length()); } else if (ev->ascii()>0) { unsigned char c[1]; c[0] = ev->ascii(); emit sndBlock((char*)c,1); } } // Unblocking, Byte to Unicode translation --------------------------------- -- /* We are doing code conversion from locale to unicode first. */ void TEmulation::onRcvBlock(const char *s, int len) { bulkStart(); bulk_incnt += 1; for (int i = 0; i < len; i++) { QString result = decoder->toUnicode(&s[i],1); int reslen = result.length(); for (int j = 0; j < reslen; j++) onRcvChar(result[j].unicode()); if (s[i] == '\n') bulkNewline(); } bulkEnd(); } // Selection --------------------------------------------------------------- -- void TEmulation::onSelectionBegin(const int x, const int y) { if (!connected) return; scr->setSelBeginXY(x,y); showBulk(); } void TEmulation::onSelectionExtend(const int x, const int y) { if (!connected) return; scr->setSelExtentXY(x,y); showBulk(); } void TEmulation::setSelection(const BOOL preserve_line_breaks) { if (!connected) return; QString t = scr->getSelText(preserve_line_breaks); if (!t.isNull()) gui->setSelection(t); } void TEmulation::clearSelection() { if (!connected) return; scr->clearSelection(); showBulk(); } // Refreshing -------------------------------------------------------------- -- #define BULK_TIMEOUT 20 /*! called when \n comes in. Evtl. triggers showBulk at endBulk */ void TEmulation::bulkNewline() { bulk_nlcnt += 1; bulk_incnt = 0; // reset bulk counter since `nl' rule applies } /*! */ void TEmulation::showBulk() { bulk_nlcnt = 0; // reset bulk newline counter bulk_incnt = 0; // reset bulk counter if (connected) { ca* image = scr->getCookedImage(); // get the image gui->setImage(image, scr->getLines(), scr->getColumns()); // actual refresh free(image); //FIXME: check that we do not trigger other draw event here. gui->setScroll(scr->getHistCursor(),scr->getHistLines()); } } void TEmulation::bulkStart() { if (bulk_timer.isActive()) bulk_timer.stop(); } void TEmulation::bulkEnd() { if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 ) showBulk(); // resets bulk_??cnt to 0, too. else bulk_timer.start(BULK_TIMEOUT,TRUE); } void TEmulation::setConnect(bool c) { connected = c; if ( connected) { onImageSizeChange(gui->Lines(), gui->Columns()); showBulk(); } else { scr->clearSelection(); } } // --------------------------------------------------------------------------- /*! triggered by image size change of the TEWidget `gui'. This event is simply propagated to the attached screens and to the related serial line. */ void TEmulation::onImageSizeChange(int lines, int columns) { if (!connected) return; screen[0]->resizeImage(lines,columns); screen[1]->resizeImage(lines,columns); showBulk(); emit ImageSizeChanged(lines,columns); // propagate event to serial line } void TEmulation::onHistoryCursorChange(int cursor) { if (!connected) return; scr->setHistCursor(cursor); showBulk(); } void TEmulation::onHorzCursorChange(int cursor) { if (!connected) return; scr->setHorzCursor(cursor); showBulk(); } void TEmulation::setColumns(int columns) { //FIXME: this goes strange ways. // Can we put this straight or explain it at least? emit changeColumns(columns); } diff --git a/core/apps/embeddedkonsole/commandeditdialog.cpp b/core/apps/embeddedkonsole/commandeditdialog.cpp index e4255f3..c0066d8 100644 --- a/core/apps/embeddedkonsole/commandeditdialog.cpp +++ b/core/apps/embeddedkonsole/commandeditdialog.cpp @@ -1,199 +1,191 @@ //comandeditdialog.cpp #include "commandeditdialog.h" #include "playlistselection.h" -#include <qstring.h> #include <qpe/config.h> -#include <qtoolbar.h> -#include <qwidget.h> -#include <qmenubar.h> #include <qpe/resource.h> -#include <qlist.h> #include <qtoolbutton.h> -#include <qvbox.h> -#include <qlistview.h> #include <qlineedit.h> #include <qheader.h> #include <qlabel.h> -#include <qmessagebox.h> #include "smallcommandeditdialogbase.h" CommandEditDialog::CommandEditDialog(QWidget *parent, const char* name, WFlags fl ) : CommandEditDialogBase(parent, name, TRUE, fl) { m_SuggestedCommandList->addColumn( tr("Command Selection") ); m_SuggestedCommandList->header()->hide(); m_SuggestedCommandList->setSorting(-1,FALSE); m_SuggestedCommandList->clearSelection(); m_SuggestedCommandList->setSorting(0,TRUE); QListViewItem *item; item = new QListViewItem( m_SuggestedCommandList,"export "); item = new QListViewItem( m_SuggestedCommandList,"ifconfig "); item = new QListViewItem( m_SuggestedCommandList,"ipkg "); item = new QListViewItem( m_SuggestedCommandList,"gzip "); item = new QListViewItem( m_SuggestedCommandList,"gunzip "); item = new QListViewItem( m_SuggestedCommandList,"chgrp "); item = new QListViewItem( m_SuggestedCommandList,"chown "); item = new QListViewItem( m_SuggestedCommandList,"date "); item = new QListViewItem( m_SuggestedCommandList,"dd "); item = new QListViewItem( m_SuggestedCommandList,"dmesg "); item = new QListViewItem( m_SuggestedCommandList,"fuser "); item = new QListViewItem( m_SuggestedCommandList,"hostname "); item = new QListViewItem( m_SuggestedCommandList,"kill "); item = new QListViewItem( m_SuggestedCommandList,"killall "); item = new QListViewItem( m_SuggestedCommandList,"ln "); item = new QListViewItem( m_SuggestedCommandList,"ln -s "); item = new QListViewItem( m_SuggestedCommandList,"lsmod"); item = new QListViewItem( m_SuggestedCommandList,"depmod -a"); item = new QListViewItem( m_SuggestedCommandList,"modprobe "); item = new QListViewItem( m_SuggestedCommandList,"mount "); item = new QListViewItem( m_SuggestedCommandList,"more "); item = new QListViewItem( m_SuggestedCommandList,"sort "); item = new QListViewItem( m_SuggestedCommandList,"touch "); item = new QListViewItem( m_SuggestedCommandList,"umount "); item = new QListViewItem( m_SuggestedCommandList,"mknod "); item = new QListViewItem( m_SuggestedCommandList,"netstat "); item = new QListViewItem( m_SuggestedCommandList,"route "); item = new QListViewItem( m_SuggestedCommandList,"cardctl eject "); m_SuggestedCommandList->setSelected(m_SuggestedCommandList->firstChild(),TRUE); m_SuggestedCommandList->sort(); connect( m_SuggestedCommandList, SIGNAL( clicked( QListViewItem * ) ), m_PlayListSelection, SLOT( addToSelection( QListViewItem *) ) ); ToolButton1->setTextLabel("new"); ToolButton1->setPixmap(Resource::loadPixmap("new")); ToolButton1->setAutoRaise(TRUE); ToolButton1->setFocusPolicy(QWidget::NoFocus); connect(ToolButton1,SIGNAL(clicked()),this,SLOT(showAddDialog())); ToolButton2->setTextLabel("edit"); ToolButton2->setPixmap(Resource::loadPixmap("edit")); ToolButton2->setAutoRaise(TRUE); ToolButton2->setFocusPolicy(QWidget::NoFocus); connect(ToolButton2,SIGNAL(clicked()),this,SLOT(showEditDialog())); ToolButton3->setTextLabel("delete"); ToolButton3->setPixmap(Resource::loadPixmap("editdelete")); ToolButton3->setAutoRaise(TRUE); ToolButton3->setFocusPolicy(QWidget::NoFocus); connect(ToolButton3,SIGNAL(clicked()),m_PlayListSelection,SLOT(removeSelected())); ToolButton4->setTextLabel("up"); ToolButton4->setPixmap(Resource::loadPixmap("up")); ToolButton4->setAutoRaise(TRUE); ToolButton4->setFocusPolicy(QWidget::NoFocus); connect(ToolButton4,SIGNAL(clicked()),m_PlayListSelection,SLOT(moveSelectedUp())); ToolButton5->setTextLabel("down"); ToolButton5->setPixmap(Resource::loadPixmap("down")); ToolButton5->setAutoRaise(TRUE); ToolButton5->setFocusPolicy(QWidget::NoFocus); connect(ToolButton5,SIGNAL(clicked()),m_PlayListSelection,SLOT(moveSelectedDown())); QListViewItem *current = m_SuggestedCommandList->selectedItem(); if ( current ) item->moveItem( current ); m_SuggestedCommandList->setSelected( item, TRUE ); m_SuggestedCommandList->ensureItemVisible( m_SuggestedCommandList->selectedItem() ); Config cfg( "Konsole" ); cfg.setGroup("Commands"); if (cfg.readEntry("Commands Set","FALSE") == "TRUE") { for (int i = 0; i < 100; i++) { QString tmp; tmp = cfg.readEntry( QString::number(i),""); if (!tmp.isEmpty()) m_PlayListSelection->addStringToSelection(tmp); } } else { m_PlayListSelection->addStringToSelection("ls "); m_PlayListSelection->addStringToSelection("cardctl eject"); m_PlayListSelection->addStringToSelection("cat "); m_PlayListSelection->addStringToSelection("cd "); m_PlayListSelection->addStringToSelection("chmod "); m_PlayListSelection->addStringToSelection("cp "); m_PlayListSelection->addStringToSelection("dc "); m_PlayListSelection->addStringToSelection("df "); m_PlayListSelection->addStringToSelection("dmesg"); m_PlayListSelection->addStringToSelection("echo "); m_PlayListSelection->addStringToSelection("env"); m_PlayListSelection->addStringToSelection("find "); m_PlayListSelection->addStringToSelection("free"); m_PlayListSelection->addStringToSelection("grep "); m_PlayListSelection->addStringToSelection("ifconfig "); m_PlayListSelection->addStringToSelection("ipkg "); m_PlayListSelection->addStringToSelection("mkdir "); m_PlayListSelection->addStringToSelection("mv "); m_PlayListSelection->addStringToSelection("nc localhost 7776"); m_PlayListSelection->addStringToSelection("nc localhost 7777"); m_PlayListSelection->addStringToSelection("nslookup "); m_PlayListSelection->addStringToSelection("ping "); m_PlayListSelection->addStringToSelection("ps aux"); m_PlayListSelection->addStringToSelection("pwd "); m_PlayListSelection->addStringToSelection("rm "); m_PlayListSelection->addStringToSelection("rmdir "); m_PlayListSelection->addStringToSelection("route "); m_PlayListSelection->addStringToSelection("set "); m_PlayListSelection->addStringToSelection("traceroute"); } } CommandEditDialog::~CommandEditDialog() { } void CommandEditDialog::accept() { int i = 0; Config *cfg = new Config("Konsole"); cfg->setGroup("Commands"); cfg->clearGroup(); QListViewItemIterator it( m_PlayListSelection ); for ( ; it.current(); ++it ) { // qDebug(it.current()->text(0)); cfg->writeEntry(QString::number(i),it.current()->text(0)); i++; } cfg->writeEntry("Commands Set","TRUE"); // qDebug("CommandEditDialog::accept() - written"); delete cfg; emit commandsEdited(); close(); } void CommandEditDialog::showEditDialog() { editCommandBase *d = new editCommandBase(this,"smalleditdialog", TRUE); d->setCaption("Edit command"); d->TextLabel->setText("Edit command:"); d->commandEdit->setText(m_PlayListSelection->currentItem()->text(0)); int i = d->exec(); if ((i==1) && (!(d->commandEdit->text()).isEmpty())) m_PlayListSelection->currentItem()->setText(0,(d->commandEdit->text())); } void CommandEditDialog::showAddDialog() { editCommandBase *d = new editCommandBase(this,"smalleditdialog", TRUE); int i = d->exec(); if ((i==1) && (!(d->commandEdit->text()).isEmpty())) m_PlayListSelection->addStringToSelection(d->commandEdit->text()); } diff --git a/core/apps/embeddedkonsole/commandeditwidget.cpp b/core/apps/embeddedkonsole/commandeditwidget.cpp index 6a2c482..ed8dade 100644 --- a/core/apps/embeddedkonsole/commandeditwidget.cpp +++ b/core/apps/embeddedkonsole/commandeditwidget.cpp @@ -1,64 +1,60 @@ /* This file is part of the Opie Project Copyright (c) 2002 L. Potter <ljp@llornkcor.com> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "commandeditwidget.h" -#include <qpushbutton.h> #include "playlistselection.h" #include <qlayout.h> -#include <qvariant.h> -#include <qtooltip.h> -#include <qwhatsthis.h> /* * Constructs a Form1 which is a child of 'parent', with the * name 'name' and widget flags set to 'f' */ Form1::Form1( QWidget* parent, const char* name, WFlags fl ) : QWidget( parent, name, fl ) { if ( !name ) resize( 596, 480 ); Form1Layout = new QGridLayout( this ); Form1Layout->setSpacing( 6 ); Form1Layout->setMargin( 11 ); MyCustomWidget1 = new PlayListSelection( this, "MyCustomWidget1" ); Form1Layout->addWidget( MyCustomWidget1, 0, 0 ); } /* * Destroys the object and frees any allocated resources */ Form1::~Form1() { // no need to delete child widgets, Qt does it all for us } diff --git a/core/apps/embeddedkonsole/keytrans.cpp b/core/apps/embeddedkonsole/keytrans.cpp index d569ae0..45a7960 100644 --- a/core/apps/embeddedkonsole/keytrans.cpp +++ b/core/apps/embeddedkonsole/keytrans.cpp @@ -1,706 +1,705 @@ /* -------------------------------------------------------------------------- */ /* */ /* [keytrans.C] Keyboard Translation */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* 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> */ /* */ /* -------------------------------------------------------------------------- */ /* The keyboard translation table allows to configure konsoles behavior on key strokes. FIXME: some bug crept in, disallowing '\0' to be emitted. */ #include "keytrans.h" #include <qpe/qpeapplication.h> #include <qnamespace.h> #include <qbuffer.h> #include <qobject.h> #include <qdict.h> #include <qintdict.h> #include <qfile.h> #include <qglobal.h> #include <qdir.h> //#include <kstddirs.h> //nclude <klocale.h> #include <stdio.h> #undef USE_APPDATA_DIR #define HERE printf("%s(%d): here\n",__FILE__,__LINE__) /* KeyEntry instances represent the individual assignments */ KeyTrans::KeyEntry::KeyEntry(int _ref, int _key, int _bits, int _mask, int _cmd, QString _txt) : ref(_ref), key(_key), bits(_bits), mask(_mask), cmd(_cmd), txt(_txt) { } KeyTrans::KeyEntry::~KeyEntry() { } bool KeyTrans::KeyEntry::matches(int _key, int _bits, int _mask) { int m = mask & _mask; return _key == key && (bits & m) == (_bits & m); } QString KeyTrans::KeyEntry::text() { return txt; } /* KeyTrans combines the individual assignments to a proper map Takes part in a collection themself. */ KeyTrans::KeyTrans() { path = ""; numb = 0; } KeyTrans::~KeyTrans() { } KeyTrans::KeyEntry* KeyTrans::addEntry(int ref, int key, int bits, int mask, int cmd, QString txt) // returns conflicting entry { for (QListIterator<KeyEntry> it(table); it.current(); ++it) { if (it.current()->matches(key,bits,mask)) { return it.current(); } } table.append(new KeyEntry(ref,key,bits,mask,cmd,txt)); return (KeyEntry*)NULL; } bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len) { for (QListIterator<KeyEntry> it(table); it.current(); ++it) if (it.current()->matches(key,bits,0xffff)) { *cmd = it.current()->cmd; *txt = it.current()->txt.ascii(); *len = it.current()->txt.length(); return TRUE; } return FALSE; } /* ------------------------------------------------------------------------- */ /* */ /* Scanner for keyboard configuration */ /* */ /* ------------------------------------------------------------------------- */ // regular tokenizer /* Tokens - Spaces - Name (A-Za-z0-9)+ - String - Opr on of +-: */ #define SYMName 0 #define SYMString 1 #define SYMEol 2 #define SYMEof 3 #define SYMOpr 4 #define SYMError 5 #define inRange(L,X,H) ((L <= X) && (X <= H)) #define isNibble(X) (inRange('A',X,'F')||inRange('a',X,'f')||inRange('0',X,'9')) #define convNibble(X) (inRange('0',X,'9')?X-'0':X+10-(inRange('A',X,'F')?'A':'a')) class KeytabReader { public: KeytabReader(QString p, QIODevice &d); public: void getCc(); void getSymbol(); void parseTo(KeyTrans* kt); void ReportError(const char* msg); void ReportToken(); // diagnostic private: int sym; QString res; int len; int slinno; int scolno; private: int cc; int linno; int colno; QIODevice* buf; QString path; }; KeytabReader::KeytabReader(QString p, QIODevice &d) { path = p; buf = &d; cc = 0; } void KeytabReader::getCc() { if (cc == '\n') { linno += 1; colno = 0; } if (cc < 0) return; cc = buf->getch(); colno += 1; } void KeytabReader::getSymbol() { res = ""; len = 0; sym = SYMError; while (cc == ' ') getCc(); // skip spaces if (cc == '#') // skip comment { while (cc != '\n' && cc > 0) getCc(); } slinno = linno; scolno = colno; if (cc <= 0) { sym = SYMEof; return; // eos } if (cc == '\n') { getCc(); sym = SYMEol; return; // eol } if (inRange('A',cc,'Z')||inRange('a',cc,'z')||inRange('0',cc,'9')) { while (inRange('A',cc,'Z') || inRange('a',cc,'z') || inRange('0',cc,'9')) { res = res + (char)cc; getCc(); } sym = SYMName; return; } if (strchr("+-:",cc)) { res = ""; res = res + (char)cc; getCc(); sym = SYMOpr; return; } if (cc == '"') { getCc(); while (cc >= ' ' && cc != '"') { int sc; if (cc == '\\') // handle quotation { getCc(); switch (cc) { case 'E' : sc = 27; getCc(); break; case 'b' : sc = 8; getCc(); break; case 'f' : sc = 12; getCc(); break; case 't' : sc = 9; getCc(); break; case 'r' : sc = 13; getCc(); break; case 'n' : sc = 10; getCc(); break; case '\\' : // fall thru case '"' : sc = cc; getCc(); break; case 'x' : getCc(); sc = 0; if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc(); if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc(); break; default : return; } } else { // regular char sc = cc; getCc(); } res = res + (char)sc; len = len + 1; } if (cc != '"') return; getCc(); sym = SYMString; return; } } void KeytabReader::ReportToken() // diagnostic { printf("sym(%d): ",slinno); switch(sym) { case SYMEol : printf("End of line"); break; case SYMEof : printf("End of file"); break; case SYMName : printf("Name: %s",res.latin1()); break; case SYMOpr : printf("Opr : %s",res.latin1()); break; case SYMString : printf("String len %d,%d ",res.length(),len); for (unsigned i = 0; i < res.length(); i++) printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?'); break; } printf("\n"); } void KeytabReader::ReportError(const char* msg) // diagnostic { fprintf(stderr,"%s(%d,%d):error: %s.\n",path.ascii(),slinno,scolno,msg); } // local symbol tables --------------------------------------------------------------------- class KeyTransSymbols { public: KeyTransSymbols(); protected: void defOprSyms(); void defModSyms(); void defKeySyms(); void defKeySym(const char* key, int val); void defOprSym(const char* key, int val); void defModSym(const char* key, int val); public: QDict<QObject> keysyms; QDict<QObject> modsyms; QDict<QObject> oprsyms; }; static KeyTransSymbols * syms = 0L; // parser ---------------------------------------------------------------------------------- /* Syntax - Line :: [KeyName { ("+" | "-") ModeName } ":" (String|CommandName)] "\n" - Comment :: '#' (any but \n)* */ KeyTrans* KeyTrans::fromDevice(QString path, QIODevice &buf) { KeyTrans* kt = new KeyTrans; kt->path = path; KeytabReader ktr(path,buf); ktr.parseTo(kt); return kt; } #define assertSyntax(Cond,Message) if (!(Cond)) { ReportError(Message); goto ERROR; } void KeytabReader::parseTo(KeyTrans* kt) { // Opening sequence buf->open(IO_ReadOnly); getCc(); linno = 1; colno = 1; getSymbol(); Loop: // syntax: ["key" KeyName { ("+" | "-") ModeName } ":" String/CommandName] ["#" Comment] if (sym == SYMName && !strcmp(res.latin1(),"keyboard")) { getSymbol(); assertSyntax(sym == SYMString, "Header expected") kt->hdr = res.latin1(); getSymbol(); assertSyntax(sym == SYMEol, "Text unexpected") getSymbol(); // eoln goto Loop; } if (sym == SYMName && !strcmp(res.latin1(),"key")) { //printf("line %3d: ",startofsym); getSymbol(); assertSyntax(sym == SYMName, "Name expected") assertSyntax(syms->keysyms[res], "Unknown key name") int key = (int)syms->keysyms[res]-1; //printf(" key %s (%04x)",res.latin1(),(int)syms->keysyms[res]-1); getSymbol(); // + - : int mode = 0; int mask = 0; while (sym == SYMOpr && (!strcmp(res.latin1(),"+") || !strcmp(res.latin1(),"-"))) { bool on = !strcmp(res.latin1(),"+"); getSymbol(); // mode name assertSyntax(sym == SYMName, "Name expected") assertSyntax(syms->modsyms[res], "Unknown mode name") int bits = (int)syms->modsyms[res]-1; if (mask & (1 << bits)) { fprintf(stderr,"%s(%d,%d): mode name used multible times.\n",path.ascii(),slinno,scolno); } else { mode |= (on << bits); mask |= (1 << bits); } //printf(", mode %s(%d) %s",res.latin1(),(int)syms->modsyms[res]-1,on?"on":"off"); getSymbol(); } assertSyntax(sym == SYMOpr && !strcmp(res.latin1(),":"), "':' expected") getSymbol(); // string or command assertSyntax(sym == SYMName || sym == SYMString,"Command or string expected") int cmd = 0; if (sym == SYMName) { assertSyntax(syms->oprsyms[res], "Unknown operator name") cmd = (int)syms->oprsyms[res]-1; //printf(": do %s(%d)",res.latin1(),(int)syms->oprsyms[res]-1); } if (sym == SYMString) { cmd = CMD_send; //printf(": send"); //for (unsigned i = 0; i < res.length(); i++) //printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?'); } //printf(". summary %04x,%02x,%02x,%d\n",key,mode,mask,cmd); KeyTrans::KeyEntry* ke = kt->addEntry(slinno,key,mode,mask,cmd,res); if (ke) { fprintf(stderr,"%s(%d): keystroke already assigned in line %d.\n",path.ascii(),slinno,ke->ref); } getSymbol(); assertSyntax(sym == SYMEol, "Unexpected text") goto Loop; } if (sym == SYMEol) { getSymbol(); goto Loop; } assertSyntax(sym == SYMEof, "Undecodable Line") buf->close(); return; ERROR: while (sym != SYMEol && sym != SYMEof) getSymbol(); // eoln goto Loop; } KeyTrans* KeyTrans::defaultKeyTrans() { QCString txt = -#include "default.keytab.h" + #include "default.keytab.h" ; QBuffer buf(txt); return fromDevice("[buildin]",buf); } KeyTrans* KeyTrans::fromFile(const char* path) { QFile file(path); return fromDevice(path,file); } // local symbol tables --------------------------------------------------------------------- // material needed for parsing the config file. // This is incomplete work. void KeyTransSymbols::defKeySym(const char* key, int val) { keysyms.insert(key,(QObject*)(val+1)); } void KeyTransSymbols::defOprSym(const char* key, int val) { oprsyms.insert(key,(QObject*)(val+1)); } void KeyTransSymbols::defModSym(const char* key, int val) { modsyms.insert(key,(QObject*)(val+1)); } void KeyTransSymbols::defOprSyms() { // Modifier defOprSym("scrollLineUp", CMD_scrollLineUp ); defOprSym("scrollLineDown",CMD_scrollLineDown); defOprSym("scrollPageUp", CMD_scrollPageUp ); defOprSym("scrollPageDown",CMD_scrollPageDown); defOprSym("emitSelection", CMD_emitSelection ); defOprSym("prevSession", CMD_prevSession ); defOprSym("nextSession", CMD_nextSession ); } void KeyTransSymbols::defModSyms() { // Modifier defModSym("Shift", BITS_Shift ); defModSym("Control", BITS_Control ); defModSym("Alt", BITS_Alt ); // Modes defModSym("BsHack", BITS_BsHack ); // deprecated defModSym("Ansi", BITS_Ansi ); defModSym("NewLine", BITS_NewLine ); defModSym("AppCuKeys", BITS_AppCuKeys ); } void KeyTransSymbols::defKeySyms() { // Grey keys defKeySym("Escape", Qt::Key_Escape ); defKeySym("Tab", Qt::Key_Tab ); defKeySym("Backtab", Qt::Key_Backtab ); defKeySym("Backspace", Qt::Key_Backspace ); defKeySym("Return", Qt::Key_Return ); defKeySym("Enter", Qt::Key_Enter ); defKeySym("Insert", Qt::Key_Insert ); defKeySym("Delete", Qt::Key_Delete ); defKeySym("Pause", Qt::Key_Pause ); defKeySym("Print", Qt::Key_Print ); defKeySym("SysReq", Qt::Key_SysReq ); defKeySym("Home", Qt::Key_Home ); defKeySym("End", Qt::Key_End ); defKeySym("Left", Qt::Key_Left ); defKeySym("Up", Qt::Key_Up ); defKeySym("Right", Qt::Key_Right ); defKeySym("Down", Qt::Key_Down ); defKeySym("Prior", Qt::Key_Prior ); defKeySym("Next", Qt::Key_Next ); defKeySym("Shift", Qt::Key_Shift ); defKeySym("Control", Qt::Key_Control ); defKeySym("Meta", Qt::Key_Meta ); defKeySym("Alt", Qt::Key_Alt ); defKeySym("CapsLock", Qt::Key_CapsLock ); defKeySym("NumLock", Qt::Key_NumLock ); defKeySym("ScrollLock", Qt::Key_ScrollLock ); defKeySym("F1", Qt::Key_F1 ); defKeySym("F2", Qt::Key_F2 ); defKeySym("F3", Qt::Key_F3 ); defKeySym("F4", Qt::Key_F4 ); defKeySym("F5", Qt::Key_F5 ); defKeySym("F6", Qt::Key_F6 ); defKeySym("F7", Qt::Key_F7 ); defKeySym("F8", Qt::Key_F8 ); defKeySym("F9", Qt::Key_F9 ); defKeySym("F10", Qt::Key_F10 ); defKeySym("F11", Qt::Key_F11 ); defKeySym("F12", Qt::Key_F12 ); defKeySym("F13", Qt::Key_F13 ); defKeySym("F14", Qt::Key_F14 ); defKeySym("F15", Qt::Key_F15 ); defKeySym("F16", Qt::Key_F16 ); defKeySym("F17", Qt::Key_F17 ); defKeySym("F18", Qt::Key_F18 ); defKeySym("F19", Qt::Key_F19 ); defKeySym("F20", Qt::Key_F20 ); defKeySym("F21", Qt::Key_F21 ); defKeySym("F22", Qt::Key_F22 ); defKeySym("F23", Qt::Key_F23 ); defKeySym("F24", Qt::Key_F24 ); defKeySym("F25", Qt::Key_F25 ); defKeySym("F26", Qt::Key_F26 ); defKeySym("F27", Qt::Key_F27 ); defKeySym("F28", Qt::Key_F28 ); defKeySym("F29", Qt::Key_F29 ); defKeySym("F30", Qt::Key_F30 ); defKeySym("F31", Qt::Key_F31 ); defKeySym("F32", Qt::Key_F32 ); defKeySym("F33", Qt::Key_F33 ); defKeySym("F34", Qt::Key_F34 ); defKeySym("F35", Qt::Key_F35 ); defKeySym("Super_L", Qt::Key_Super_L ); defKeySym("Super_R", Qt::Key_Super_R ); defKeySym("Menu", Qt::Key_Menu ); defKeySym("Hyper_L", Qt::Key_Hyper_L ); defKeySym("Hyper_R", Qt::Key_Hyper_R ); // Regular keys defKeySym("Space", Qt::Key_Space ); defKeySym("Exclam", Qt::Key_Exclam ); defKeySym("QuoteDbl", Qt::Key_QuoteDbl ); defKeySym("NumberSign", Qt::Key_NumberSign ); defKeySym("Dollar", Qt::Key_Dollar ); defKeySym("Percent", Qt::Key_Percent ); defKeySym("Ampersand", Qt::Key_Ampersand ); defKeySym("Apostrophe", Qt::Key_Apostrophe ); defKeySym("ParenLeft", Qt::Key_ParenLeft ); defKeySym("ParenRight", Qt::Key_ParenRight ); defKeySym("Asterisk", Qt::Key_Asterisk ); defKeySym("Plus", Qt::Key_Plus ); defKeySym("Comma", Qt::Key_Comma ); defKeySym("Minus", Qt::Key_Minus ); defKeySym("Period", Qt::Key_Period ); defKeySym("Slash", Qt::Key_Slash ); defKeySym("0", Qt::Key_0 ); defKeySym("1", Qt::Key_1 ); defKeySym("2", Qt::Key_2 ); defKeySym("3", Qt::Key_3 ); defKeySym("4", Qt::Key_4 ); defKeySym("5", Qt::Key_5 ); defKeySym("6", Qt::Key_6 ); defKeySym("7", Qt::Key_7 ); defKeySym("8", Qt::Key_8 ); defKeySym("9", Qt::Key_9 ); defKeySym("Colon", Qt::Key_Colon ); defKeySym("Semicolon", Qt::Key_Semicolon ); defKeySym("Less", Qt::Key_Less ); defKeySym("Equal", Qt::Key_Equal ); defKeySym("Greater", Qt::Key_Greater ); defKeySym("Question", Qt::Key_Question ); defKeySym("At", Qt::Key_At ); defKeySym("A", Qt::Key_A ); defKeySym("B", Qt::Key_B ); defKeySym("C", Qt::Key_C ); defKeySym("D", Qt::Key_D ); defKeySym("E", Qt::Key_E ); defKeySym("F", Qt::Key_F ); defKeySym("G", Qt::Key_G ); defKeySym("H", Qt::Key_H ); defKeySym("I", Qt::Key_I ); defKeySym("J", Qt::Key_J ); defKeySym("K", Qt::Key_K ); defKeySym("L", Qt::Key_L ); defKeySym("M", Qt::Key_M ); defKeySym("N", Qt::Key_N ); defKeySym("O", Qt::Key_O ); defKeySym("P", Qt::Key_P ); defKeySym("Q", Qt::Key_Q ); defKeySym("R", Qt::Key_R ); defKeySym("S", Qt::Key_S ); defKeySym("T", Qt::Key_T ); defKeySym("U", Qt::Key_U ); defKeySym("V", Qt::Key_V ); defKeySym("W", Qt::Key_W ); defKeySym("X", Qt::Key_X ); defKeySym("Y", Qt::Key_Y ); defKeySym("Z", Qt::Key_Z ); defKeySym("BracketLeft", Qt::Key_BracketLeft ); defKeySym("Backslash", Qt::Key_Backslash ); defKeySym("BracketRight", Qt::Key_BracketRight); defKeySym("AsciiCircum", Qt::Key_AsciiCircum ); defKeySym("Underscore", Qt::Key_Underscore ); defKeySym("QuoteLeft", Qt::Key_QuoteLeft ); defKeySym("BraceLeft", Qt::Key_BraceLeft ); defKeySym("Bar", Qt::Key_Bar ); defKeySym("BraceRight", Qt::Key_BraceRight ); defKeySym("AsciiTilde", Qt::Key_AsciiTilde ); } KeyTransSymbols::KeyTransSymbols() { defModSyms(); defOprSyms(); defKeySyms(); } // Global material ----------------------------------------------------------- static int keytab_serial = 0; //FIXME: remove,localize static QIntDict<KeyTrans> * numb2keymap = 0L; static QDict<KeyTrans> * path2keymap = 0L; KeyTrans* KeyTrans::find(int numb) { KeyTrans* res = numb2keymap->find(numb); return res ? res : numb2keymap->find(0); } KeyTrans* KeyTrans::find(const char* path) { KeyTrans* res = path2keymap->find(path); return res ? res : numb2keymap->find(0); } int KeyTrans::count() { return numb2keymap->count(); } void KeyTrans::addKeyTrans() { this->numb = keytab_serial ++; numb2keymap->insert(numb,this); path2keymap->insert(path,this); } void KeyTrans::loadAll() { if (!numb2keymap) numb2keymap = new QIntDict<KeyTrans>; if (!path2keymap) path2keymap = new QDict<KeyTrans>; if (!syms) syms = new KeyTransSymbols; defaultKeyTrans()->addKeyTrans(); QString path = QPEApplication::qpeDir() + "etc/keytabs"; QDir dir(path); QStringList lst = dir.entryList("*.keytab"); for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { QFile file(path + "/" + *it); KeyTrans* sc = KeyTrans::fromDevice(*it, file); if (sc) { sc->addKeyTrans(); } } } // Debugging material ----------------------------------------------------------- /* void TestTokenizer(QBuffer &buf) { // opening sequence buf.open(IO_ReadOnly); cc = buf.getch(); lineno = 1; // Test tokenizer while (getSymbol(buf)) ReportToken(); buf.close(); } void test() { // Opening sequence QCString txt = -#include "default.keytab.h" ; QBuffer buf(txt); if (0) TestTokenizer(buf); if (1) { KeyTrans kt; kt.scanTable(buf); } } */ diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp index 084c39d..281835e 100644 --- a/core/apps/embeddedkonsole/konsole.cpp +++ b/core/apps/embeddedkonsole/konsole.cpp @@ -1,1094 +1,1073 @@ /* ---------------------------------------------------------------------- */ /* */ /* [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> // enhancements added by Phillip Kuhn #include <stdlib.h> #include <sys/types.h> #include <pwd.h> #include <unistd.h> #ifdef QT_QWS_OPIE #include <opie2/ocolorpopupmenu.h> #endif #include <qpe/resource.h> -#include <qdir.h> -#include <qevent.h> -#include <qdragobject.h> -#include <qobjectlist.h> -#include <qtoolbutton.h> -#include <qtoolbar.h> -#include <qpushbutton.h> -#include <qfontdialog.h> -#include <qglobal.h> -#include <qpainter.h> #include <qmenubar.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 <qfontdatabase.h> #include <qfile.h> #include <qspinbox.h> #include <qlayout.h> -#include <qvbox.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "konsole.h" -#include "keytrans.h" #include "commandeditdialog.h" class EKNumTabBar : public QTabBar { public: EKNumTabBar(QWidget *parent = 0, const char *name = 0) : QTabBar(parent, name) {} // QList<QTab> *getTabList() { return(tabList()); } 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(); } } } virtual QSize sizeHint() const { if (isHidden()) { return(QSize(0,0)); } else { QSize size = QTabBar::sizeHint(); int shrink = 5; if (qApp->desktop()->width() > 600 || qApp->desktop()->height() > 600) { shrink = 10; } size.setHeight(size.height() - shrink); return(size); } } }; class EKNumTabWidget : public QTabWidget { public: EKNumTabWidget(QWidget* parent) : QTabWidget(parent) { setTabBar(new EKNumTabBar(parent,"EKTabBar")); setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); } EKNumTabBar *getTabBar() const { return ((EKNumTabBar*)tabBar()); } 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 }; static void konsoleInit(const char** shell) { if(setuid(getuid()) !=0) qDebug("setuid failed"); if(setgid(getgid()) != 0) qDebug("setgid failed"); // drop privileges // QPEApplication::grabKeyboard(); // for CTRL and ALT qDebug("keyboard grabbed"); #ifdef FAKE_CTRL_AND_ALT qDebug("Fake Ctrl and Alt defined"); QPEApplication::grabKeyboard(); // for CTRL and ALT #endif *shell = getenv("SHELL"); qWarning("SHell initially is %s", *shell ); if (shell == NULL || *shell == '\0') { struct passwd *ent = 0; uid_t me = getuid(); *shell = "/bin/sh"; while ( (ent = getpwent()) != 0 ) { if (ent->pw_uid == me) { if (ent->pw_shell != "") *shell = ent->pw_shell; break; } } endpwent(); } if( putenv((char*)"COLORTERM=") !=0) qDebug("putenv failed"); // to trigger mc's color detection } Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) : QMainWindow(parent, name, fl) { QStrList tmp; const char* shell; konsoleInit( &shell); init(shell,tmp); } Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int) : QMainWindow(0, name) { init(_pgm,_args); } struct HistoryItem { HistoryItem(int c, const QString &l) { count = c; line = l; } int count; QString line; }; class HistoryList : public QList<HistoryItem> { virtual int compareItems( QCollection::Item item1, QCollection::Item item2) { int c1 = ((HistoryItem*)item1)->count; int c2 = ((HistoryItem*)item2)->count; if (c1 > c2) return(1); if (c1 < c2) return(-1); return(0); } }; void Konsole::initCommandList() { // qDebug("Konsole::initCommandList"); Config cfg( "Konsole" ); cfg.setGroup("Commands"); // commonCombo->setInsertionPolicy(QComboBox::AtCurrent); commonCombo->clear(); if (cfg.readEntry("ShellHistory","TRUE") == "TRUE") { QString histfilename = QString(getenv("HOME")) + "/.bash_history"; histfilename = cfg.readEntry("ShellHistoryPath",histfilename); QFile histfile(histfilename); // note: compiler barfed on: // QFile histfile(QString(getenv("HOME")) + "/.bash_history"); if (histfile.open( IO_ReadOnly )) { QString line; uint i; HistoryList items; int lineno = 0; while(!histfile.atEnd()) { if (histfile.readLine(line, 200) < 0) { break; } line = line.left(line.length()-1); lineno++; for(i=0; i<items.count(); i++) { if (line == items.at(i)->line) { // weight recent commands & repeated commands more // by adding up the index of each command items.at(i)->count += lineno; break; } } if (i >= items.count()) { items.append(new HistoryItem(lineno, line)); } } items.sort(); int n = items.count(); if (n > 40) { n = 40; } for(int i=0; i<n; i++) { // should insert start of command, but keep whole thing if (items.at(items.count()-i-1)->line.length() < 30) { commonCombo->insertItem(items.at(items.count()-i-1)->line); } } histfile.close(); } } if (cfg.readEntry("Commands Set","FALSE") == "FALSE") { for (int i = 0; commonCmds[i] != NULL; i++) { commonCombo->insertItem(commonCmds[i]); } } else { for (int i = 0; i < 100; i++) { if (!(cfg.readEntry( QString::number(i),"")).isEmpty()) commonCombo->insertItem(cfg.readEntry( QString::number(i),"")); } } } static void sig_handler(int x) { printf("got signal %d\n",x); } void Konsole::init(const char* _pgm, QStrList & _args) { #if 0 for(int i=1; i<=31; i++) { if (i != SIGPIPE && i != SIGPROF && i != SIGSEGV && i != SIGINT && i != SIGILL && i != SIGTERM && i != SIGBUS) signal(i,sig_handler); } #endif signal(SIGSTOP, sig_handler); signal(SIGCONT, sig_handler); signal(SIGTSTP, sig_handler); b_scroll = TRUE; // histon; n_keytab = 0; n_render = 0; startUp=0; fromMenu = FALSE; fullscreen = false; setCaption( tr( "Konsole" ) ); setIcon( Resource::loadPixmap( "konsole/Terminal" ) ); Config cfg( "Konsole" ); cfg.setGroup("Font"); QString tmp; // initialize the list of allowed fonts /////////////////////////////////// QString cfgFontName = cfg.readEntry("FontName","Lcfont"); int cfgFontSize = cfg.readNumEntry("FontSize",18); cfont = -1; // this code causes repeated access to all the font files // which does slow down startup QFontDatabase fontDB; QStringList familyNames; familyNames = fontDB.families( FALSE ); QString s; int fontIndex = 0; int familyNum = 0; fontList = new QPopupMenu( this ); for(uint j = 0; j < (uint)familyNames.count(); j++) { s = familyNames[j]; if ( s.contains('-') ) { int i = s.find('-'); s = s.right( s.length() - i - 1 ) + " [" + s.left( i ) + "]"; } s[0] = s[0].upper(); QValueList<int> sizes = fontDB.pointSizes( familyNames[j] ); printf("family[%d] = %s with %d sizes\n", j, familyNames[j].latin1(), sizes.count()); if (sizes.count() > 0) { QPopupMenu *sizeMenu; QFont f; int last_width = -1; sizeMenu = NULL; for(uint i = 0; i < (uint)sizes.count() + 4; i++) { // printf("family %s size %d ", familyNames[j].latin1(), sizes[i]); // need to divide by 10 on the Z, but not otherwise int size; if (i >= (uint)sizes.count()) { // try for expandable fonts size = sizes[sizes.count()-1] + 2 * (i - sizes.count() + 1); } else { printf("sizes[%d] = %d\n", i, sizes[i]); size = sizes[i]; } f = QFont(familyNames[j], size); f.setFixedPitch(true); QFontMetrics fm(f); // don't trust f.fixedPitch() or f.exactMatch(), they lie!! if (fm.width("l") == fm.width("m") && (i < (uint)sizes.count() || fm.width("m") > last_width)) { if (i < (uint)sizes.count()) { last_width = fm.width("m"); } if (sizeMenu == NULL) { sizeMenu = new QPopupMenu(); } int id = sizeMenu->insertItem(QString("%1").arg(size), fontIndex); sizeMenu->setItemParameter(id, fontIndex); sizeMenu->connectItem(id, this, SLOT(setFont(int))); QString name = s + " " + QString::number(size); fonts.append(new VTFont(name, f, familyNames[j], familyNum, size)); if (familyNames[j] == cfgFontName && size == cfgFontSize) { cfont = fontIndex; } printf("FOUND: %s family %s size %d\n", name.latin1(), familyNames[j].latin1(), size); fontIndex++; } } if (sizeMenu) { fontList->insertItem(s, sizeMenu, familyNum + 1000); familyNum++; } } } if (cfont < 0 || cfont >= (int)fonts.count()) { cfont = 0; } // create terminal emulation framework //////////////////////////////////// nsessions = 0; tab = new EKNumTabWidget(this); // tab->setMargin(tab->margin()-5); connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*))); // create terminal toolbar //////////////////////////////////////////////// setToolBarsMovable( FALSE ); menuToolBar = new QToolBar( this ); menuToolBar->setHorizontalStretchable( TRUE ); QMenuBar *menuBar = new QMenuBar( menuToolBar ); bool c7xx = false; if (qApp->desktop()->width() > 600 || qApp->desktop()->height() > 600) { c7xx = true; } QFont menuFont; menuFont.setPointSize(c7xx? 18 : 10); qApp->setFont(menuFont, true); setFont(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") { ec_cmdlist = editCommandListMenu->insertItem( tr( "Show command list" )); listHidden=TRUE; } else { ec_cmdlist = editCommandListMenu->insertItem( tr( "Hide command list" )); listHidden=FALSE; } cfg.setGroup("Tabs"); tabMenu = new QPopupMenu(this); tm_bottom = tabMenu->insertItem(tr("Bottom" )); tm_top = tabMenu->insertItem(tr("Top")); tm_hidden = tabMenu->insertItem(tr("Hidden")); configMenu->insertItem(tr("Tabs"), tabMenu); tmp=cfg.readEntry("Position","Top"); if(tmp=="Top") { tab->setTabPosition(QTabWidget::Top); tab->getTabBar()->show(); tabPos = tm_top; } else if (tmp=="Bottom") { tab->setTabPosition(QTabWidget::Bottom); tab->getTabBar()->show(); tabPos = tm_bottom; } else { tab->getTabBar()->hide(); tab->setMargin(tab->margin()); tabPos = tm_hidden; } cm_bw = colorMenu->insertItem(tr( "Black on White")); cm_wb = colorMenu->insertItem(tr( "White on Black")); cm_gb = colorMenu->insertItem(tr( "Green on Black")); // cm_bt = colorMenu->insertItem(tr( "Black on Transparent")); cm_br = colorMenu->insertItem(tr( "Black on Pink")); cm_rb = colorMenu->insertItem(tr( "Pink on Black")); cm_gy = colorMenu->insertItem(tr( "Green on Yellow")); cm_bm = colorMenu->insertItem(tr( "Blue on Magenta")); cm_mb = colorMenu->insertItem(tr( "Magenta on Blue")); cm_cw = colorMenu->insertItem(tr( "Cyan on White")); cm_wc = colorMenu->insertItem(tr( "White on Cyan")); cm_bb = colorMenu->insertItem(tr( "Blue on Black")); cm_ab = colorMenu->insertItem(tr( "Amber on Black")); cm_default = colorMenu->insertItem(tr("default")); #ifdef QT_QWS_OPIE colorMenu->insertItem(tr( "Custom")); #endif configMenu->insertItem(tr( "Colors") ,colorMenu); sessionList = new QPopupMenu(this); sessionList-> insertItem ( Resource::loadPixmap ( "konsole/Terminal" ), tr( "new session" ), this, SLOT(newSession()) ); // 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( tabMenu, SIGNAL( activated(int) ), this, SLOT( tabMenuSelected(int) )); connect( scrollMenu, SIGNAL(activated(int)),this,SLOT(scrollMenuSelected(int))); connect( editCommandListMenu,SIGNAL(activated(int)),this,SLOT(editCommandListMenuSelected(int))); connect( sessionList, SIGNAL(activated(int)), this, SLOT( sessionListSelected(int) ) ); menuBar->insertItem( tr("View"), configMenu ); menuBar->insertItem( tr("Fonts"), fontList ); menuBar->insertItem( tr("Sessions"), sessionList ); toolBar = new QToolBar( this ); QAction *a; // Button Commands a = new QAction( tr("New"), Resource::loadPixmap( "konsole/Terminal" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolBar ); a = new QAction( tr("Full Screen"), Resource::loadPixmap( "fullscreen" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( toggleFullScreen() ) ); a->addTo( toolBar ); a = new QAction( tr("Zoom"), Resource::loadPixmap( "zoom" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( cycleZoom() ) ); 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 ); secondToolBar = new QToolBar( this ); secondToolBar->setHorizontalStretchable( TRUE ); commonCombo = new QComboBox( secondToolBar ); // commonCombo->setMaximumWidth(236); ec_quick = editCommandListMenu->insertItem( tr( "Quick Edit" ) ); if( listHidden) { secondToolBar->hide(); editCommandListMenu->setItemEnabled(ec_quick ,FALSE); } ec_edit = 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) )); sm_none = scrollMenu->insertItem(tr( "None" )); sm_left = scrollMenu->insertItem(tr( "Left" )); sm_right = scrollMenu->insertItem(tr( "Right" )); // scrollMenu->insertSeparator(4); // scrollMenu->insertItem(tr( "Horizontal" )); configMenu->insertItem(tr( "ScrollBar" ),scrollMenu); configMenu->insertItem(tr( "History..." ), this, SLOT(historyDialog())); cm_wrap = configMenu->insertItem(tr( "Wrap" )); cfg.setGroup("ScrollBar"); configMenu->setItemChecked(cm_wrap, cfg.readBoolEntry("HorzScroll",0)); cm_beep = configMenu->insertItem(tr( "Use Beep" )); cfg.setGroup("Menubar"); configMenu->setItemChecked(cm_beep, cfg.readBoolEntry("useBeep",0)); fullscreen_msg = new QLabel(this); fullscreen_msg-> setAlignment ( AlignCenter | SingleLine ); fullscreen_msg-> hide(); fullscreen_msg-> setSizePolicy ( QSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding )); fullscreen_msg-> setAutoResize(true); fullscreen_msg-> setFrameStyle(QFrame::PopupPanel | QFrame::Raised); fullscreen_msg-> setText(tr("To exit fullscreen, tap here.")); fullscreen_timer = new QTimer(this); connect(fullscreen_timer, SIGNAL(timeout()), this, SLOT(fullscreenTimeout())); show_fullscreen_msg = true; //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; cfg.setGroup("CommandLine"); if (cfg.hasKey("shell_args")) { QStringList se_args_list = cfg.readListEntry("shell_args",'|'); for(uint i = 0; i < se_args_list.count(); i++) { se_args.prepend(se_args_list[se_args_list.count() - i - 1].latin1()); } } else { se_args.prepend("--login"); } se_pgm = cfg.readEntry("shell_bin", QString(se_pgm)); // this is the "documentation" for those who know to look if (! cfg.hasKey("shell_args")) { cfg.writeEntry("shell_args",QStringList::fromStrList(se_args),'|'); } if (! cfg.hasKey("shell_bin")) { cfg.writeEntry("shell_bin",QString(se_pgm)); } parseCommandLine(); // read and apply default values /////////////////////////////////////////// resize(321, 321); // Dummy. QSize currentSize = size(); if (currentSize != size()) defaultSize = size(); /* allows us to catch cancel/escape */ reparent ( 0, WStyle_Customize | WStyle_NoBorder, QPoint ( 0, 0 )); } void Konsole::show() { if ( !nsessions ) { newSession(); } QMainWindow::show(); } void Konsole::initSession(const char*, QStrList &) { QMainWindow::show(); } Konsole::~Konsole() { while (nsessions > 0) { doneSession(getTe(), 0); } } void Konsole::historyDialog() { QDialog *d = new QDialog ( this, "histdlg", true ); // d-> setCaption ( tr( "History" )); QBoxLayout *lay = new QVBoxLayout ( d, 4, 4 ); QLabel *l = new QLabel ( tr( "History Lines:" ), d ); lay-> addWidget ( l ); Config cfg( "Konsole" ); cfg.setGroup("History"); int hist = cfg.readNumEntry("history_lines",300); int avg_line = cfg.readNumEntry("avg_line_length",60); QSpinBox *spin = new QSpinBox ( 1, 100000, 20, d ); spin-> setValue ( hist ); spin-> setWrapping ( true ); spin-> setButtonSymbols ( QSpinBox::PlusMinus ); lay-> addWidget ( spin ); if ( d-> exec ( ) == QDialog::Accepted ) { cfg.writeEntry("history_lines", spin->value()); cfg.writeEntry("avg_line_length", avg_line); if (getTe() != NULL) { getTe()->currentSession->setHistory(true); } } delete d; } void Konsole::cycleZoom() { TEWidget* te = getTe(); QFont font = te->getVTFont(); int size = font.pointSize(); changeFontSize(1); font = te->getVTFont(); if (font.pointSize() <= size) { do { font = te->getVTFont(); size = font.pointSize(); changeFontSize(-1); font = te->getVTFont(); } while (font.pointSize() < size); } } void Konsole::changeFontSize(int delta) { // printf("delta font size %d\n", delta); TEWidget* te = getTe(); QFont font = te->getVTFont(); int size = font.pointSize(); int closest = delta > 0? 10000 : -10000; int closest_font = -1; for(uint i = 0; i < fonts.count(); i++) { if (fonts.at(i)->getFont() == font) { if (delta > 0) { if (i+1 < fonts.count() && fonts.at(i+1)->getFamilyNum() == fonts.at(i)->getFamilyNum()) { setFont(i+1); printf("font %d\n", i+1); return; } } else if (delta < 0) { if (i > 0 && fonts.at(i-1)->getFamilyNum() == fonts.at(i)->getFamilyNum()) { setFont(i-1); printf("font %d\n", i-1); return; } } } int fsize = fonts.at(i)->getSize(); printf("%d size=%d fsize=%d closest=%d\n", i, size, fsize, closest); if ((delta > 0 && fsize > size && fsize < closest) || (delta < 0 && fsize < size && fsize > closest)) { closest = fsize; closest_font = i; } } if (closest_font >= 0) { printf("font closest %d (%d)\n", closest_font, closest); setFont(closest_font); } } int Konsole::findFont(const QString& name, int size, bool exactMatch) { for(uint i = 0; i < fonts.count(); i++) { if (fonts.at(i)->getName() == name && fonts.at(i)->getSize() == size) { return(i); } } if (exactMatch) { return(-1); } for(uint i = 0; i < fonts.count(); i++) { if (fonts.at(i)->getSize() == size) { return(i); } } return(-1); } void Konsole::setFont(int f) { VTFont* font = fonts.at(f); if (font) { TEWidget* te = getTe(); if (te != 0) { te->setVTFont(font->getFont()); } cfont = f; int familyNum = font->getFamilyNum(); int size = font->getSize(); printf("familyNum = %d size = %d count=%d\n", familyNum, size, fontList->count()); for(int i = 0; i < (int)fontList->count(); i++) { fontList->setItemChecked(i + 1000, i == familyNum); } for(int i = 0; i < (int)fonts.count(); i++) { fontList->setItemChecked(i, fonts.at(i)->getFamilyNum() == familyNum && fonts.at(i)->getSize() == size); } Config cfg( "Konsole" ); cfg.setGroup("Font"); QString ss = "Session"+ QString::number(tab->currentPageIndex()+1); if (tab->currentPageIndex() == 0) { cfg.writeEntry("FontName", fonts.at(cfont)->getFamily()); cfg.writeEntry("FontSize", fonts.at(cfont)->getSize()); } cfg.writeEntry("FontName"+ss, fonts.at(cfont)->getFamily()); cfg.writeEntry("FontSize"+ss, fonts.at(cfont)->getSize()); } } #if 0 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()); } } } #endif 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; } } diff --git a/core/apps/embeddedkonsole/playlistselection.cpp b/core/apps/embeddedkonsole/playlistselection.cpp index 4dd3126..fc5330f 100644 --- a/core/apps/embeddedkonsole/playlistselection.cpp +++ b/core/apps/embeddedkonsole/playlistselection.cpp @@ -1,161 +1,154 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#include <qpe/applnk.h> -#include <qpe/resource.h> -#include <qpainter.h> -#include <qimage.h> #include <qheader.h> -#include <qlistview.h> -#include <qlist.h> -#include <qpixmap.h> #include "playlistselection.h" #include <stdlib.h> PlayListSelection::PlayListSelection( QWidget *parent, const char *name ) : QListView( parent, name ) { setAllColumnsShowFocus( TRUE ); addColumn( tr( "Command Selection" ) ); header()->hide(); setSorting( -1, FALSE ); } PlayListSelection::~PlayListSelection() { } void PlayListSelection::contentsMouseMoveEvent( QMouseEvent *event ) { if ( event->state() == QMouseEvent::LeftButton ) { QListViewItem *currentItem = selectedItem(); QListViewItem *itemUnder = itemAt( QPoint( event->pos().x(), event->pos().y() - contentsY() ) ); if ( currentItem && currentItem->itemAbove() == itemUnder ) moveSelectedUp(); else if ( currentItem && currentItem->itemBelow() == itemUnder ) moveSelectedDown(); } } const QString *PlayListSelection::current() { PlayListSelectionItem *item = (PlayListSelectionItem *)selectedItem(); if ( item ) return item->file(); return NULL; } void PlayListSelection::addToSelection( QListViewItem *lnk ) { PlayListSelectionItem *item = new PlayListSelectionItem( this, new QString( lnk->text(0) ) ); QListViewItem *current = selectedItem(); if ( current ) item->moveItem( current ); setSelected( item, TRUE ); ensureItemVisible( selectedItem() ); } void PlayListSelection::addStringToSelection (const QString & lnk) { PlayListSelectionItem *item = new PlayListSelectionItem( this, new QString( lnk ) ); QListViewItem *current = selectedItem(); if ( current ) item->moveItem( current ); setSelected( item, TRUE ); ensureItemVisible( selectedItem() ); } void PlayListSelection::removeSelected() { qDebug("removeSelected()"); QListViewItem *item = selectedItem(); if ( item ) delete item; setSelected( currentItem(), TRUE ); ensureItemVisible( selectedItem() ); } void PlayListSelection::moveSelectedUp() { QListViewItem *item = selectedItem(); if ( item && item->itemAbove() ) item->itemAbove()->moveItem( item ); ensureItemVisible( selectedItem() ); } void PlayListSelection::moveSelectedDown() { QListViewItem *item = selectedItem(); if ( item && item->itemBelow() ) item->moveItem( item->itemBelow() ); ensureItemVisible( selectedItem() ); } bool PlayListSelection::prev() { QListViewItem *item = selectedItem(); if ( item && item->itemAbove() ) setSelected( item->itemAbove(), TRUE ); else return FALSE; ensureItemVisible( selectedItem() ); return TRUE; } bool PlayListSelection::next() { QListViewItem *item = selectedItem(); if ( item && item->itemBelow() ) setSelected( item->itemBelow(), TRUE ); else return FALSE; ensureItemVisible( selectedItem() ); return TRUE; } bool PlayListSelection::first() { QListViewItem *item = firstChild(); if ( item ) setSelected( item, TRUE ); else return FALSE; ensureItemVisible( selectedItem() ); return TRUE; } bool PlayListSelection::last() { QListViewItem *prevItem = NULL; QListViewItem *item = firstChild(); while ( ( item = item->nextSibling() ) ) prevItem = item; if ( prevItem ) setSelected( prevItem, TRUE ); else return FALSE; ensureItemVisible( selectedItem() ); return TRUE; } diff --git a/core/apps/embeddedkonsole/session.cpp b/core/apps/embeddedkonsole/session.cpp index 17acb8c..043b8db 100644 --- a/core/apps/embeddedkonsole/session.cpp +++ b/core/apps/embeddedkonsole/session.cpp @@ -1,161 +1,160 @@ /* -------------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ #include "session.h" -#include <qpushbutton.h> // #include <kdebug.h> #include <stdlib.h> #define HERE fprintf(stderr,"%s(%d): here\n",__FILE__,__LINE__) /*! \class TESession Sessions are combinations of TEPTy and Emulations. The stuff in here does not belong to the terminal emulation framework, but to main.C. It serves it's duty by providing a single reference to TEPTy/Emulation pairs. In fact, it is only there to demonstrate one of the abilities of the framework - multible sessions. */ TESession::TESession(QMainWindow* main, TEWidget* _te, const char* _pgm, QStrList & _args, const char *_term) : schema_no(0), font_no(3), pgm(_pgm), args(_args) { te = _te; term = _term; // sh = new TEPty(); sh = new MyPty(); em = new TEmuVt102(te); sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary QObject::connect( sh,SIGNAL(block_in(const char*,int)), em,SLOT(onRcvBlock(const char*,int)) ); QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)), sh,SLOT(setSize(int,int))); // 'main' should do those connects itself, somehow. // These aren't KTMW's slots, but konsole's.(David) /* QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)), main,SLOT(notifySize(int,int))); */ QObject::connect( em,SIGNAL(sndBlock(const char*,int)), sh,SLOT(send_bytes(const char*,int)) ); QObject::connect( em,SIGNAL(changeColumns(int)), main,SLOT(changeColumns(int)) ); QObject::connect( em,SIGNAL(changeTitle(int, const QString&)), this,SLOT(changeTitle(int, const QString&)) ); QObject::connect( sh,SIGNAL(done(int)), this,SLOT(done(int)) ); } void TESession::run() { //kdDebug() << "Running the session!" << pgm << "\n"; sh->run(pgm,args,term.data(),FALSE); } void TESession::kill(int ) // signal) { // sh->kill(signal); } TESession::~TESession() { QObject::disconnect( sh, SIGNAL( done( int ) ), this, SLOT( done( int ) ) ); delete em; delete sh; } void TESession::setConnect(bool c) { em->setConnect(c); } void TESession::done(int status) { emit done(te,status); } void TESession::terminate() { delete this; } TEmulation* TESession::getEmulation() { return em; } // following interfaces might be misplaced /// int TESession::schemaNo() { return schema_no; } int TESession::keymap() { return keymap_no; } int TESession::fontNo() { return font_no; } const char* TESession::emuName() { return term.data(); } void TESession::setSchemaNo(int sn) { schema_no = sn; } void TESession::setKeymapNo(int kn) { keymap_no = kn; em->setKeytrans(kn); } void TESession::setFontNo(int fn) { font_no = fn; } void TESession::changeTitle(int, const QString& title) { this->title = title; emit changeTitle(te, title); } const QString& TESession::Title() { return title; } void TESession::setHistory(bool on) { em->setHistory( on ); } bool TESession::history() { return em->history(); } // #include "session.moc" diff --git a/core/apps/helpbrowser/helpbrowser.cpp b/core/apps/helpbrowser/helpbrowser.cpp index 6f84ae2..8fb0161 100644 --- a/core/apps/helpbrowser/helpbrowser.cpp +++ b/core/apps/helpbrowser/helpbrowser.cpp @@ -1,250 +1,228 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of the Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #define QTOPIA_INTERNAL_LANGLIST #include "helpbrowser.h" #include <qpe/qpeapplication.h> #include <qpe/resource.h> -#include <qpe/mimetype.h> -#include <qpe/applnk.h> -#include <qpe/global.h> - -#include <qstatusbar.h> -#include <qdragobject.h> -#include <qpixmap.h> -#include <qpopupmenu.h> + #include <qmenubar.h> #include <qtoolbar.h> #include <qpe/qcopenvelope_qws.h> -#include <qtoolbutton.h> -#include <qiconset.h> -#include <qfile.h> -#include <qtextstream.h> -#include <qstylesheet.h> -#include <qmessagebox.h> -#include <qfiledialog.h> -#include <qevent.h> -#include <qlineedit.h> -#include <qobjectlist.h> #include <qfileinfo.h> -#include <qfile.h> -#include <qdatastream.h> -#include <qprinter.h> -#include <qsimplerichtext.h> -#include <qpaintdevicemetrics.h> #include <qaction.h> #include <cctype> #include "magictextbrowser.h" HelpBrowser::HelpBrowser( QWidget* parent, const char *name, WFlags f ) : QMainWindow( parent, name, f ), selectedURL() { init( "index.html" ); } void HelpBrowser::init( const QString& _home ) { setIcon( Resource::loadPixmap( "HelpBrowser" ) ); setBackgroundMode( PaletteButton ); browser = new MagicTextBrowser( this ); browser->setFrameStyle( QFrame::Panel | QFrame::Sunken ); connect( browser, SIGNAL( textChanged() ), this, SLOT( textChanged() ) ); setCentralWidget( browser ); setToolBarsMovable( FALSE ); if ( !_home.isEmpty() ) browser->setSource( _home ); QToolBar* toolbar = new QToolBar( this ); toolbar->setHorizontalStretchable( TRUE ); QMenuBar *menu = new QMenuBar( toolbar ); toolbar = new QToolBar( this ); // addToolBar( toolbar, "Toolbar"); QPopupMenu* go = new QPopupMenu( this ); backAction = new QAction( tr( "Backward" ), Resource::loadIconSet( "back" ), QString::null, 0, this, 0 ); connect( backAction, SIGNAL( activated() ), browser, SLOT( backward() ) ); connect( browser, SIGNAL( backwardAvailable( bool ) ), backAction, SLOT( setEnabled( bool ) ) ); backAction->addTo( go ); backAction->addTo( toolbar ); backAction->setEnabled( FALSE ); forwardAction = new QAction( tr( "Forward" ), Resource::loadIconSet( "forward" ), QString::null, 0, this, 0 ); connect( forwardAction, SIGNAL( activated() ), browser, SLOT( forward() ) ); connect( browser, SIGNAL( forwardAvailable( bool ) ), forwardAction, SLOT( setEnabled( bool ) ) ); forwardAction->addTo( go ); forwardAction->addTo( toolbar ); forwardAction->setEnabled( FALSE ); QAction *a = new QAction( tr( "Home" ), Resource::loadIconSet( "home" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), browser, SLOT( home() ) ); a->addTo( go ); a->addTo( toolbar ); bookm = new QPopupMenu( this ); bookm->insertItem( tr( "Add Bookmark" ), this, SLOT( addBookmark() ) ); bookm->insertItem( tr( "Remove from Bookmarks" ), this, SLOT( removeBookmark() ) ); bookm->insertSeparator(); connect( bookm, SIGNAL( activated( int ) ), this, SLOT( bookmChosen( int ) ) ); readBookmarks(); menu->insertItem( tr("Go"), go ); menu->insertItem( tr( "Bookmarks" ), bookm ); resize( 240, 300 ); browser->setFocus(); browser->setFrameStyle( QFrame::NoFrame ); #if !defined(QT_NO_COP) QCopChannel *addressChannel = new QCopChannel("QPE/HelpBrowser" , this ); connect (addressChannel, SIGNAL( received(const QCString &, const QByteArray &)), this, SLOT ( appMessage(const QCString &, const QByteArray &) ) ); #endif connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)), this, SLOT(appMessage(const QCString&, const QByteArray&)) ); } void HelpBrowser::appMessage(const QCString& msg, const QByteArray& data) { qDebug("reached appMessage"); if ( msg == "showFile(QString)" ) { QDataStream ds(data,IO_ReadOnly); QString fn; ds >> fn; setDocument( fn ); QPEApplication::setKeepRunning(); showMaximized(); setActiveWindow(); raise(); } } void HelpBrowser::setDocument( const QString &doc ) { if ( !doc.isEmpty() ) browser->setSource( doc ); raise(); } void HelpBrowser::textChanged() { if ( browser->documentTitle().isNull() ) setCaption( tr("Help Browser") ); else setCaption( browser->documentTitle() ) ; selectedURL = caption(); } HelpBrowser::~HelpBrowser() { QStringList bookmarks; QMap<int, Bookmark>::Iterator it2 = mBookmarks.begin(); for ( ; it2 != mBookmarks.end(); ++it2 ) bookmarks.append( (*it2).name + "=" + (*it2).file ); QFile f2( Global::applicationFileName("helpbrowser", "bookmarks") ); if ( f2.open( IO_WriteOnly ) ) { QDataStream s2( &f2 ); s2 << bookmarks; f2.close(); } } void HelpBrowser::pathSelected( const QString &_path ) { browser->setSource( _path ); } void HelpBrowser::readBookmarks() { QString file = Global::applicationFileName("helpbrowser", "bookmarks"); if ( QFile::exists( file ) ) { QStringList bookmarks; QFile f( file ); if ( f.open( IO_ReadOnly ) ) { QDataStream s( &f ); s >> bookmarks; f.close(); } QStringList::Iterator it = bookmarks.begin(); for ( ; it != bookmarks.end(); ++it ) { Bookmark b; QString current = *it; int equal = current.find( "=" ); if ( equal < 1 || equal == (int)current.length() - 1 ) continue; b.name = current.left( equal ); b.file = current.mid( equal + 1 ); mBookmarks[ bookm->insertItem( b.name ) ] = b; } } } void HelpBrowser::bookmChosen( int i ) { if ( mBookmarks.contains( i ) ) browser->setSource( mBookmarks[ i ].file ); } void HelpBrowser::addBookmark() { Bookmark b; b.name = browser->documentTitle(); b.file = browser->source(); if (b.name.isEmpty() ) { b.name = b.file.left( b.file.length() - 5 ); // remove .html } QMap<int, Bookmark>::Iterator it; for( it = mBookmarks.begin(); it != mBookmarks.end(); ++it ) if ( (*it).file == b.file ) return; mBookmarks[ bookm->insertItem( b.name ) ] = b; } void HelpBrowser::removeBookmark() { QString file = browser->source(); QMap<int, Bookmark>::Iterator it = mBookmarks.begin(); for( ; it != mBookmarks.end(); ++it ) if ( (*it).file == file ) { bookm->removeItem( it.key() ); mBookmarks.remove( it ); break; } } diff --git a/core/apps/helpbrowser/magictextbrowser.cpp b/core/apps/helpbrowser/magictextbrowser.cpp index 8ce0325..80495c9 100644 --- a/core/apps/helpbrowser/magictextbrowser.cpp +++ b/core/apps/helpbrowser/magictextbrowser.cpp @@ -1,99 +1,97 @@ #include <qfile.h> -#include <qstring.h> #include <qdragobject.h> -#include <qregexp.h> /* need to get Global::helpPath() */ #define QTOPIA_INTERNAL_LANGLIST #include <qtopia/global.h> #include <qtopia/mimetype.h> #include <qtopia/applnk.h> #include "magictextbrowser.h" MagicTextBrowser::MagicTextBrowser(QWidget* parent) : QTextBrowser(parent){ } void MagicTextBrowser::setSource( const QString& source ) { QTextBrowser::setSource(source); if ( magicQpe(source,"applications") || magicQpe(source,"games") || magicQpe(source,"settings") || magicQpe(source, "1Pim") ) // No tr return; if ( magicOpe(source, "applets") || magicOpe(source, "input") ) return; // Just those are magic (for now). Could do CGI here, // or in Qtopia's mime source factory. } bool MagicTextBrowser::magicQpe(const QString& source, const QString& name) { if ( name+".html" == source || "help/"+name+".html" == source) { QString fn = mimeSourceFactory()->makeAbsolute( source, context() ); const QMimeSource* m = mimeSourceFactory()->data( fn, context() ); if ( m ) { QString txt; if ( QTextDrag::decode(m,txt) ) { QRegExp re("<qtopia-"+name+">.*</qtopia-"+name+">"); int start,len; if ( (start=re.match(txt,0,&len))>=0 ) { QString generated = generateQpe(name); txt.replace(start,len,generated); setText(txt); return true; } } } } return false; } bool MagicTextBrowser::magicOpe( const QString& source, const QString& name ) { if ( name+".html" != source && "help/"+name+".html" != source) return false; QString fn = mimeSourceFactory()->makeAbsolute( source, context() ); const QMimeSource* m = mimeSourceFactory()->data(fn, context() ); if (!m) return false; QString txt; if ( !QTextDrag::decode(m, txt ) ) return false; QRegExp re("<opie-"+name+">.*</opie-"+name+">"); int start,len; if ( (start=re.match(txt,0,&len))>=0 ) { QString generated = generateOpe(name); txt.replace(start,len,generated); setText(txt); return true; } return false; } QString MagicTextBrowser::generateOpe(const QString& name)const { if ( name == QString::fromLatin1("applets") ) { return QString::fromLatin1("<h3>No Applets found</h3>"); }else if ( name == QString::fromLatin1("input") ) { return QString::fromLatin1("<h3>No input methods available</h3>"); }else return QString::null; } QString MagicTextBrowser::generateQpe(const QString& name) const { QString dir = MimeType::appsFolderName()+"/"+name[0].upper()+name.mid(1); AppLnkSet lnkset(dir); AppLnk* lnk; QString r; for (QListIterator<AppLnk> it(lnkset.children()); (lnk=it.current()); ++it) { QString name = lnk->name(); QString icon = lnk->icon(); QString helpFile = lnk->exec()+".html"; QStringList helpPath = Global::helpPath(); bool helpExists = FALSE; for (QStringList::ConstIterator it=helpPath.begin(); it!=helpPath.end() && !helpExists; ++it) helpExists = QFile::exists( *it + "/" + helpFile ); if ( helpExists ) { r += "<h3><a href="+helpFile+"><img src="+icon+">"+name+"</a></h3>\n"; } } return r; } diff --git a/core/apps/oapp/oappplugin.cpp b/core/apps/oapp/oappplugin.cpp index 934594f..82cc59b 100644 --- a/core/apps/oapp/oappplugin.cpp +++ b/core/apps/oapp/oappplugin.cpp @@ -1,43 +1,40 @@ -#include "oappinterface.h" #include "oappplugin.h" -#include <qlist.h> #include <qwidget.h> -#include <qpe/quuid.h> OAppPlugin::OAppPlugin(OAppPos pos) { m_position = pos; }; OAppPlugin::OAppPlugin(QWidget *widget, OAppPos pos) { m_widgets.append( widget ); m_position = pos; }; OAppPlugin::~OAppPlugin() { }; QList<QWidget> OAppPlugin::widgets() { return m_widgets; }; OAppPos OAppPlugin::position() const { return m_position; } QRESULT OAppPlugin::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) { *iface = 0; if ( uuid == IID_QUnknown ) *iface = this; else if ( uuid == IID_OAppInterface ) *iface = this; if ( *iface ) (*iface)->addRef(); return QS_OK; } diff --git a/core/apps/qcop/main.cpp b/core/apps/qcop/main.cpp index 73db0f6..9306cbf 100644 --- a/core/apps/qcop/main.cpp +++ b/core/apps/qcop/main.cpp @@ -1,85 +1,83 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qtopia Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include <qpe/qcopenvelope_qws.h> #include <qapplication.h> -#include <qstringlist.h> -#include <qdatastream.h> #include <qtimer.h> #include <stdlib.h> #include <stdio.h> static void usage() { fprintf( stderr, "Usage: qcop channel command [parameters]\n" ); } static void syntax( const QString &where, const QString &what ) { fprintf( stderr, "Syntax error in %s: %s\n", where.latin1(), what.latin1() ); exit(1); } int main( int argc, char *argv[] ) { QApplication app( argc, argv ); if ( argc < 3 ) { usage(); exit(1); } QString channel = argv[1]; QString command = argv[2]; command.stripWhiteSpace(); int paren = command.find( "(" ); if ( paren <= 0 ) syntax( "command", command ); QString params = command.mid( paren + 1 ); if ( params[params.length()-1] != ')' ) syntax( "command", command ); params.truncate( params.length()-1 ); QCopEnvelope env(channel.latin1(), command.latin1()); int argIdx = 3; QStringList paramList = QStringList::split( ",", params ); QStringList::Iterator it; for ( it = paramList.begin(); it != paramList.end(); ++it ) { QString arg = argv[argIdx]; if ( *it == "QString" ) { env << arg; } else if ( *it == "int" ) { env << arg.toInt(); } else { syntax( "paramter type", *it ); } argIdx++; } QTimer::singleShot( 0, &app, SLOT(quit()) ); return app.exec(); } diff --git a/core/apps/taboapp/main.cpp b/core/apps/taboapp/main.cpp index 4b9451e..b2703ff 100644 --- a/core/apps/taboapp/main.cpp +++ b/core/apps/taboapp/main.cpp @@ -1,54 +1,53 @@ #include <qdir.h> -#include <qpe/global.h> #include <qpe/qpeapplication.h> #include <qpe/qlibrary.h> #include <oappinterface.h> #include <oappplugin.h> #include <opie2/otabwidget.h> int main( int argc, char **argv ) { QPEApplication a( argc, argv ); OTabWidget *tabwidget = new OTabWidget(0, "tab widget"); QString path = QPEApplication::qpeDir() + "/plugins/app"; QDir dir( path, "lib*.so" ); QStringList list = dir.entryList(); QStringList::Iterator it; QInterfacePtr<OAppInterface> iface; for ( it = list.begin(); it != list.end(); ++it ) { QLibrary *lib = new QLibrary( path + "/" + *it ); qDebug( "querying: %s", QString( path + "/" + *it ).latin1() ); if ( lib->queryInterface( IID_OAppInterface, (QUnknownInterface**)&iface ) == QS_OK ) { qDebug( "accepted: %s", QString( path + "/" + *it ).latin1() ); QList<QWidget> list = iface->widgets(); QWidget *widget; for ( widget = list.first(); widget != 0; widget = list.next() ) tabwidget->addTab(widget, QString(*it), QString(*it)); QString lang = getenv( "LANG" ); if (lang.isNull()) lang = "en"; QTranslator *trans = new QTranslator(qApp); QString type = (*it).left( (*it).find(".") ); if (type.left(3) == "lib") type = type.mid(3); type = type.right( type.find("lib") ); QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm"; if ( trans->load( tfn )) qApp->installTranslator( trans ); else delete trans; } } a.showMainDocumentWidget(tabwidget); return a.exec(); } diff --git a/core/apps/textedit/filePermissions.cpp b/core/apps/textedit/filePermissions.cpp index f1c78a1..db353a9 100644 --- a/core/apps/textedit/filePermissions.cpp +++ b/core/apps/textedit/filePermissions.cpp @@ -1,274 +1,270 @@ /**************************************************************************** ** copyright 2002 ljp ljp@llornkcor.com ** Created: Sat Feb 23 19:44:40 2002 L.J. Potter ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include "filePermissions.h" -#include <qfile.h> #include <qfileinfo.h> #include <qcheckbox.h> #include <qlabel.h> #include <qlineedit.h> -#include <qlayout.h> -#include <qvariant.h> -#include <qtooltip.h> #include <qmessagebox.h> #include <unistd.h> #include <sys/stat.h> #include <stdlib.h> #include <sys/types.h> #include <pwd.h> #include <grp.h> filePermissions::filePermissions( QWidget* parent, const char* name, bool modal, WFlags fl, const QString &fileName ) : QDialog( parent, name, modal, fl ) { if ( !name ) setName( tr("File Permissions") ); // qDebug("FilePermissions "+fileName); resize( 236, 210 ); setMaximumSize( QSize( 236, 210 ) ); setCaption( tr( "Set File Permissions" ) ); TextLabel1 = new QLabel( this, "TextLabel1" ); TextLabel1->setGeometry( QRect( 25, 5, 175, 20 ) ); TextLabel1->setText( tr( "Set file permissions for:" ) ); LineEdit1 = new QLineEdit( this, "LineEdit1" ); LineEdit1->setGeometry( QRect( 10, 25, 218, 22 ) ); LineEdit1->setReadOnly(true); TextLabel4 = new QLabel( this, "TextLabel4" ); TextLabel4->setGeometry( QRect( 5, 85, 50, 15 ) ); TextLabel4->setText( tr( "owner" ) ); TextLabel4_2 = new QLabel( this, "TextLabel4_2" ); TextLabel4_2->setGeometry( QRect( 5, 105, 50, 15 ) ); TextLabel4_2->setText( tr( "group" ) ); TextLabel4_3 = new QLabel( this, "TextLabel4_3" ); TextLabel4_3->setGeometry( QRect( 5, 125, 50, 15 ) ); TextLabel4_3->setText( tr( "others" ) ); CheckBox1 = new QCheckBox( this, "CheckBox1" ); CheckBox1->setGeometry( QRect( 75, 85, 20, 16 ) ); connect(CheckBox1, SIGNAL(released()),this,SLOT(ownReadCheck())); CheckBox1_2 = new QCheckBox( this, "CheckBox1_2" ); CheckBox1_2->setGeometry( QRect( 135, 85, 20, 16 ) ); connect(CheckBox1_2, SIGNAL(released()),this,SLOT(ownWriteCheck())); CheckBox1_3 = new QCheckBox( this, "CheckBox1_3" ); CheckBox1_3->setGeometry( QRect( 195, 85, 20, 16 ) ); connect(CheckBox1_3, SIGNAL(released()),this,SLOT(ownExeCheck())); CheckBox1_4 = new QCheckBox( this, "CheckBox1_4" ); CheckBox1_4->setGeometry( QRect( 75, 105, 20, 16 ) ); connect(CheckBox1_4, SIGNAL(released()),this,SLOT(grpReadCheck())); CheckBox1_5 = new QCheckBox( this, "CheckBox1_5" ); CheckBox1_5->setGeometry( QRect( 135, 105, 20, 16 ) ); connect(CheckBox1_5, SIGNAL(released()),this,SLOT(grpWriteCheck())); CheckBox1_6 = new QCheckBox( this, "CheckBox1_6" ); CheckBox1_6->setGeometry( QRect( 195, 105, 20, 16 ) ); connect(CheckBox1_6, SIGNAL(released()),this,SLOT(grpExeCheck())); CheckBox1_7 = new QCheckBox( this, "CheckBox1_7" ); CheckBox1_7->setGeometry( QRect( 75, 125, 16, 16 ) ); connect(CheckBox1_7, SIGNAL(released()),this,SLOT(wrldReadCheck())); CheckBox1_8 = new QCheckBox( this, "CheckBox1_8" ); CheckBox1_8->setGeometry( QRect( 135, 125, 20, 16 ) ); connect(CheckBox1_8, SIGNAL(released()),this,SLOT(wrldWriteCheck())); CheckBox1_8_2 = new QCheckBox( this, "CheckBox1_8_2" ); CheckBox1_8_2->setGeometry( QRect( 195, 125, 20, 16 ) ); connect(CheckBox1_8_2, SIGNAL(released()),this,SLOT(wrldExeCheck())); GroupLineEdit = new QLineEdit( this, "GroupLineEdit" ); GroupLineEdit->setGeometry( QRect( 125, 155, 106, 22 ) ); OwnerLineEdit = new QLineEdit( this, "OwnerLineEdit" ); OwnerLineEdit->setGeometry( QRect( 10, 155, 106, 22 ) ); TextLabel5 = new QLabel( this, "TextLabel5" ); TextLabel5->setGeometry( QRect( 45, 180, 40, 16 ) ); TextLabel5->setText( tr( "Owner" ) ); TextLabel5_2 = new QLabel( this, "TextLabel5_2" ); TextLabel5_2->setGeometry( QRect( 155, 180, 40, 16 ) ); TextLabel5_2->setText( tr( "Group" ) ); ModeLine = new QLineEdit( this, "TextLabelMode" ); ModeLine->setGeometry( QRect( 10, 60, 40, 15 ) ); TextLabel3_2 = new QLabel( this, "TextLabel3_2" ); TextLabel3_2->setGeometry( QRect( 60, 55, 50, 20 ) ); TextLabel3_2->setText( tr( "read" ) ); TextLabel3_2->setAlignment( int( QLabel::AlignBottom | QLabel::AlignHCenter ) ); TextLabel3_2_2 = new QLabel( this, "TextLabel3_2_2" ); TextLabel3_2_2->setGeometry( QRect( 120, 55, 50, 20 ) ); TextLabel3_2_2->setText( tr( "write" ) ); TextLabel3_2_2->setAlignment( int( QLabel::AlignBottom | QLabel::AlignHCenter ) ); TextLabel3 = new QLabel( this, "TextLabel3" ); TextLabel3->setGeometry( QRect( 180, 55, 50, 20 ) ); TextLabel3->setText( tr( "execute" ) ); TextLabel3->setAlignment( int( QLabel::AlignBottom | QLabel::AlignHCenter ) ); struct stat buf; mode_t mode; file = fileName; QFileInfo fi(file); LineEdit1->setText( file); OwnerLineEdit->setText( fi.owner()); GroupLineEdit->setText( fi.group()); if( fi.permission( QFileInfo::ReadUser)) { CheckBox1->setChecked(true); } if( fi.permission( QFileInfo::WriteUser)) { CheckBox1_2->setChecked(true); } if( fi.permission( QFileInfo::ExeUser)) { CheckBox1_3->setChecked(true); } if( fi.permission( QFileInfo::ReadGroup)) { CheckBox1_4->setChecked(true); } if( fi.permission( QFileInfo::WriteGroup)) { CheckBox1_5->setChecked(true); } if( fi.permission( QFileInfo::ExeGroup)) { CheckBox1_6->setChecked(true); } if( fi.permission( QFileInfo::ReadOther)) { CheckBox1_7->setChecked(true); } if( fi.permission( QFileInfo::WriteOther)) { CheckBox1_8->setChecked(true); } if( fi.permission( QFileInfo::ExeOther)) { CheckBox1_8_2->setChecked(true); } stat(file.latin1(), &buf); mode = buf.st_mode; modeStr.sprintf("%#o", buf.st_mode & ~(S_IFMT) ); ModeLine->setText(modeStr); bool ok; i_mode = modeStr.toInt(&ok,10); } /* * Destroys the object and frees any allocated resources */ filePermissions::~filePermissions() { } // might this be better as a callback routine??? void filePermissions::ownReadCheck() { if(CheckBox1->isChecked()) { i_mode +=400; } else i_mode -=400; modeStr.sprintf("0%d",i_mode); ModeLine->setText( modeStr); // 0400 } void filePermissions::ownWriteCheck() { if(CheckBox1_2->isChecked()) { i_mode +=200; } else i_mode -=200; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0200 } void filePermissions::ownExeCheck() { if(CheckBox1_3->isChecked()) { i_mode +=100; } else i_mode -=100; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0100 } void filePermissions::grpReadCheck() { if(CheckBox1_4->isChecked()) { i_mode +=40; } else i_mode -=40; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0040 } void filePermissions::grpWriteCheck() { if(CheckBox1_5->isChecked()) { i_mode +=20; } else i_mode -=20; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0020 } void filePermissions::grpExeCheck() { if(CheckBox1_6->isChecked()) { i_mode +=10; } else i_mode -=10; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0010 } void filePermissions::wrldReadCheck() { if(CheckBox1_7->isChecked()) { i_mode +=4; } else i_mode -=4; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0004 } void filePermissions::wrldWriteCheck() { if(CheckBox1_8->isChecked()) { i_mode +=2; } else i_mode -=2; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0002 } void filePermissions::wrldExeCheck() { if(CheckBox1_8_2->isChecked()) { i_mode +=1; } else i_mode -=1; modeStr.sprintf("0%d",i_mode); ModeLine->setText(modeStr); // 0001 } void filePermissions::accept() { QFileInfo fi(file); struct passwd *pwd=0; struct group *grp=0; pwd = getpwnam(OwnerLineEdit->text().latin1() ); if(pwd == NULL) { perror("getpwnam"); QMessageBox::warning(this,tr("Warning"),tr("Error- no user")); return; } else { grp = getgrnam(GroupLineEdit->text().latin1()); if(grp==NULL) { perror("getgrnam"); QMessageBox::warning(this,tr("Warning"),tr("Error- no group")); return; } if( chown( file.latin1(), pwd->pw_uid, grp->gr_gid) <0) { perror("chown"); QMessageBox::warning(this,tr("Warning"),tr("Error setting ownership or group")); return; } bool ok; uint moder = modeStr.toUInt(&ok,8); if( chmod( file.latin1(), moder) < 0) { perror("chmod"); QMessageBox::warning(this,tr("Warning"),tr("Error setting mode")); return; } } close(); } diff --git a/core/apps/textedit/textedit.cpp b/core/apps/textedit/textedit.cpp index 8e106bf..55725cc 100644 --- a/core/apps/textedit/textedit.cpp +++ b/core/apps/textedit/textedit.cpp @@ -1,1075 +1,1057 @@ /********************************************************************** // textedit.cpp ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Opie Environment. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** **********************************************************************/ // changes added by L. J. Potter Sun 02-17-2002 21:31:31 #include "textedit.h" #include "filePermissions.h" #include <opie2/ofileselector.h> #include <opie2/ofiledialog.h> #include <opie2/ofontselector.h> -#include <qpe/fontdatabase.h> -#include <qpe/global.h> -#include <qpe/fileselector.h> -#include <qpe/applnk.h> #include <qpe/resource.h> #include <qpe/config.h> #include <qpe/qpeapplication.h> #include <qmenubar.h> #include <qtoolbar.h> -#include <qpe/qcopenvelope_qws.h> -#include <qpoint.h> #include <qtextstream.h> -#include <qdatetime.h> #include <qclipboard.h> -#include <qstringlist.h> #include <qaction.h> -#include <qcolordialog.h> -#include <qfileinfo.h> #include <qlineedit.h> #include <qmessagebox.h> -#include <qobjectlist.h> -#include <qpopupmenu.h> -#include <qspinbox.h> -#include <qtoolbutton.h> -#include <qwidgetstack.h> -#include <qcheckbox.h> -#include <qcombo.h> #include <qlayout.h> -#include <qapplication.h> #include <qtimer.h> #include <qdir.h> #include <unistd.h> #include <sys/stat.h> #include <stdlib.h> //getenv using Opie::OFileDialog; using Opie::OFileSelector; using Opie::OFontSelector; #if QT_VERSION < 300 class QpeEditor : public QMultiLineEdit { public: QpeEditor( QWidget *parent, const char * name = 0 ) : QMultiLineEdit( parent, name ) { clearTableFlags(); setTableFlags( Tbl_vScrollBar | Tbl_autoHScrollBar ); } void find( const QString &txt, bool caseSensitive, bool backwards ); protected: bool markIt; int line1, line2, col1, col2; void mousePressEvent( QMouseEvent * ); void mouseReleaseEvent( QMouseEvent * ); //public slots: /* signals: void notFound(); void searchWrapped(); */ private: }; void QpeEditor::mousePressEvent( QMouseEvent *e ) { switch(e->button()) { case RightButton: { //rediculous workaround for qt popup menu //and the hold right click mechanism this->setSelection( line1, col1, line2, col2); QMultiLineEdit::mousePressEvent( e ); markIt = false; } break; default: { if(!markIt) { int line, col; this->getCursorPosition(&line, &col); line1=line2=line; col1=col2=col; } QMultiLineEdit::mousePressEvent( e ); } break; }; } void QpeEditor::mouseReleaseEvent( QMouseEvent * ) { if(this->hasMarkedText()) { markIt = true; this->getMarkedRegion( &line1, &col1, &line2, & col2 ); } else { markIt = false; } } void QpeEditor::find ( const QString &txt, bool caseSensitive, bool backwards ) { static bool wrap = false; int line, col; if ( wrap ) { if ( !backwards ) line = col = 0; wrap = false; // emit searchWrapped(); } else { getCursorPosition( &line, &col ); } //ignore backwards for now.... if ( !backwards ) { for ( ; ; ) { if ( line >= numLines() ) { wrap = true; //emit notFound(); break; } int findCol = getString( line )->find( txt, col, caseSensitive ); if ( findCol >= 0 ) { setCursorPosition( line, findCol, false ); col = findCol + txt.length(); setCursorPosition( line, col, true ); //found = true; break; } line++; col = 0; } } } #else #error "Must make a QpeEditor that inherits QTextEdit" #endif static const int nfontsizes = 6; static const int fontsize[nfontsizes] = {8,10,12,14,18,24}; TextEdit::TextEdit( QWidget *parent, const char *name, WFlags f ) : QMainWindow( parent, name, f ), bFromDocView( false ) { doc = 0; edited=false; fromSetDocument=false; setToolBarsMovable( false ); connect( qApp,SIGNAL( aboutToQuit()),SLOT( cleanUp()) ); channel = new QCopChannel( "QPE/Application/textedit", this ); connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), this, SLOT(receive(const QCString&, const QByteArray&)) ); setIcon( Resource::loadPixmap( "TextEditor" ) ); QToolBar *bar = new QToolBar( this ); bar->setHorizontalStretchable( true ); menu = bar; QMenuBar *mb = new QMenuBar( bar ); QPopupMenu *file = new QPopupMenu( this ); QPopupMenu *edit = new QPopupMenu( this ); QPopupMenu *advancedMenu = new QPopupMenu(this); font = new QPopupMenu( this ); bar = new QToolBar( this ); editBar = bar; QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) ); // a->addTo( bar ); a->addTo( file ); a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) ); a->addTo( bar ); a->addTo( file ); a = new QAction( tr( "Save" ), Resource::loadPixmap("save") , QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( save() ) ); file->insertSeparator(); a->addTo( bar ); a->addTo( file ); a = new QAction( tr( "Save As" ), Resource::loadPixmap("save") , QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( saveAs() ) ); a->addTo( file ); a = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) ); a->addTo( editBar ); a->addTo( edit ); a = new QAction( tr( "Copy" ), Resource::loadPixmap( "copy" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) ); a->addTo( editBar ); a->addTo( edit ); a = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) ); a->addTo( editBar ); a->addTo( edit ); #ifndef QT_NO_CLIPBOARD a = new QAction( tr( "Insert Time and Date" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( editPasteTimeDate() ) ); a->addTo( edit ); #endif a = new QAction( tr( "Goto Line..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( gotoLine() ) ); edit->insertSeparator(); a->addTo( edit ); a = new QAction( tr( "Find..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( editFind() ) ); a->addTo( bar ); a->addTo( edit ); zin = new QAction( tr("Zoom in"), QString::null, 0, this, 0 ); connect( zin, SIGNAL( activated() ), this, SLOT( zoomIn() ) ); zin->addTo( font ); zout = new QAction( tr("Zoom out"), QString::null, 0, this, 0 ); connect( zout, SIGNAL( activated() ), this, SLOT( zoomOut() ) ); zout->addTo( font ); font->insertSeparator(); font->insertItem(tr("Font"), this, SLOT(changeFont()) ); font->insertSeparator(); font->insertItem(tr("Advanced Features"), advancedMenu); QAction *wa = new QAction( tr("Wrap lines"), QString::null, 0, this, 0 ); connect( wa, SIGNAL( toggled(bool) ), this, SLOT( setWordWrap(bool) ) ); wa->setToggleAction(true); wa->addTo( advancedMenu); nStart = new QAction( tr("Start with new file"), QString::null, 0, this, 0 ); connect( nStart, SIGNAL( toggled(bool) ), this, SLOT( changeStartConfig(bool) ) ); nStart->setToggleAction(true); nStart->addTo( advancedMenu ); nStart->setEnabled(false); nAdvanced = new QAction( tr("Prompt on Exit"), QString::null, 0, this, 0 ); connect( nAdvanced, SIGNAL( toggled(bool) ), this, SLOT( doPrompt(bool) ) ); nAdvanced->setToggleAction(true); nAdvanced->addTo( advancedMenu ); desktopAction = new QAction( tr("Always open linked file"), QString::null, 0, this, 0 ); connect( desktopAction, SIGNAL( toggled(bool) ), this, SLOT( doDesktop(bool) ) ); desktopAction->setToggleAction(true); desktopAction->addTo( advancedMenu); filePermAction = new QAction( tr("File Permissions"), QString::null, 0, this, 0 ); connect( filePermAction, SIGNAL( toggled(bool) ), this, SLOT( doFilePerms(bool) ) ); filePermAction->setToggleAction(true); filePermAction->addTo( advancedMenu); searchBarAction = new QAction( tr("Search Bar Open"), QString::null, 0, this, 0 ); connect( searchBarAction, SIGNAL( toggled(bool) ), this, SLOT( setSearchBar(bool) ) ); searchBarAction->setToggleAction(true); searchBarAction->addTo( advancedMenu); nAutoSave = new QAction( tr("Auto Save 5 min."), QString::null, 0, this, 0 ); connect( nAutoSave, SIGNAL( toggled(bool) ), this, SLOT( doTimer(bool) ) ); nAutoSave->setToggleAction(true); nAutoSave->addTo( advancedMenu); //font->insertSeparator(); //font->insertItem(tr("About"), this, SLOT( doAbout()) ); mb->insertItem( tr( "File" ), file ); mb->insertItem( tr( "Edit" ), edit ); mb->insertItem( tr( "View" ), font ); searchBar = new QToolBar(this); addToolBar( searchBar, "Search", QMainWindow::Top, true ); searchBar->setHorizontalStretchable( true ); searchEdit = new QLineEdit( searchBar, "searchEdit" ); searchBar->setStretchableWidget( searchEdit ); connect( searchEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( search() ) ); a = new QAction( tr( "Find Next" ), Resource::loadPixmap( "next" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( findNext() ) ); a->addTo( searchBar ); a->addTo( edit ); a = new QAction( tr( "Close Find" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( findClose() ) ); a->addTo( searchBar ); edit->insertSeparator(); a = new QAction( tr( "Delete" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( editDelete() ) ); a->addTo( edit ); searchBar->hide(); editor = new QpeEditor( this ); setCentralWidget( editor ); editor->setFrameStyle( QFrame::Panel | QFrame::Sunken ); connect( editor, SIGNAL( textChanged() ), this, SLOT( editorChanged() ) ); QPEApplication::setStylusOperation( editor, QPEApplication::RightOnHold); Config cfg("TextEdit"); cfg. setGroup ( "Font" ); QFont defaultFont = editor-> font ( ); QString family = cfg. readEntry ( "Family", defaultFont. family ( )); int size = cfg. readNumEntry ( "Size", defaultFont. pointSize ( )); int weight = cfg. readNumEntry ( "Weight", defaultFont. weight ( )); bool italic = cfg. readBoolEntry ( "Italic", defaultFont. italic ( )); defaultFont = QFont ( family, size, weight, italic ); editor-> setFont ( defaultFont ); // updateCaption(); cfg.setGroup ( "View" ); promptExit = cfg.readBoolEntry ( "PromptExit", false ); openDesktop = cfg.readBoolEntry ( "OpenDesktop", true ); filePerms = cfg.readBoolEntry ( "FilePermissions", false ); useSearchBar = cfg.readBoolEntry ( "SearchBar", false ); startWithNew = cfg.readBoolEntry ( "startNew", true); featureAutoSave = cfg.readBoolEntry( "autosave", false); if(useSearchBar) searchBarAction->setOn(true); if(promptExit) nAdvanced->setOn( true ); if(openDesktop) desktopAction->setOn( true ); if(filePerms) filePermAction->setOn( true ); if(startWithNew) nStart->setOn( true ); if(featureAutoSave) nAutoSave->setOn(true); // { // doTimer(true); // } bool wrap = cfg. readBoolEntry ( "Wrap", true ); wa-> setOn ( wrap ); setWordWrap ( wrap ); ///////////////// if( qApp->argc() > 1) { currentFileName=qApp->argv()[1]; QFileInfo fi(currentFileName); if(fi.baseName().left(1) == "") { openDotFile(currentFileName); } else { openFile(currentFileName); } } else { edited1=false; openDotFile(""); } viewSelection = cfg.readNumEntry( "FileView", 0 ); } TextEdit::~TextEdit() { qWarning("textedit d'tor"); delete editor; } void TextEdit::closeEvent(QCloseEvent *) { if( edited1 && promptExit) { switch( savePrompt() ) { case 1: { saveAs(); qApp->quit(); } break; case 2: { qApp->quit(); } break; case -1: break; }; } else qApp->quit(); } void TextEdit::cleanUp() { Config cfg ( "TextEdit" ); cfg. setGroup ( "Font" ); QFont f = editor->font(); cfg.writeEntry ( "Family", f. family ( )); cfg.writeEntry ( "Size", f. pointSize ( )); cfg.writeEntry ( "Weight", f. weight ( )); cfg.writeEntry ( "Italic", f. italic ( )); cfg.setGroup ( "View" ); cfg.writeEntry ( "Wrap", editor->wordWrap() == QMultiLineEdit::WidgetWidth ); cfg.writeEntry ( "FileView", viewSelection ); cfg.writeEntry ( "PromptExit", promptExit ); cfg.writeEntry ( "OpenDesktop", openDesktop ); cfg.writeEntry ( "FilePermissions", filePerms ); cfg.writeEntry ( "SearchBar", useSearchBar ); cfg.writeEntry ( "startNew", startWithNew ); } void TextEdit::accept() { if( edited1) saveAs(); qApp->quit(); } void TextEdit::zoomIn() { setFontSize(editor->font().pointSize()+1,false); } void TextEdit::zoomOut() { setFontSize(editor->font().pointSize()-1,true); } void TextEdit::setFontSize(int sz, bool round_down_not_up) { int s=10; for (int i=0; i<nfontsizes; i++) { if ( fontsize[i] == sz ) { s = sz; break; } else if ( round_down_not_up ) { if ( fontsize[i] < sz ) s = fontsize[i]; } else { if ( fontsize[i] > sz ) { s = fontsize[i]; break; } } } QFont f = editor->font(); f.setPointSize(s); editor->setFont(f); zin->setEnabled(s != fontsize[nfontsizes-1]); zout->setEnabled(s != fontsize[0]); } void TextEdit::setBold(bool y) { QFont f = editor->font(); f.setBold(y); editor->setFont(f); } void TextEdit::setItalic(bool y) { QFont f = editor->font(); f.setItalic(y); editor->setFont(f); } void TextEdit::setWordWrap(bool y) { bool state = editor->edited(); QString captionStr = caption(); bool b1 = edited1; bool b2 = edited; editor->setWordWrap(y ? QMultiLineEdit::WidgetWidth : QMultiLineEdit::NoWrap ); editor->setEdited( state ); edited1=b1; edited=b2; setCaption(captionStr); } void TextEdit::setSearchBar(bool b) { useSearchBar=b; Config cfg("TextEdit"); cfg.setGroup("View"); cfg.writeEntry ( "SearchBar", b ); searchBarAction->setOn(b); if(b) searchBar->show(); else searchBar->hide(); editor->setFocus(); } void TextEdit::fileNew() { // if( !bFromDocView ) { // saveAs(); // } newFile(DocLnk()); } void TextEdit::fileOpen() { Config cfg("TextEdit"); cfg. setGroup ( "View" ); QMap<QString, QStringList> map; map.insert(tr("All"), QStringList() ); QStringList text; text << "text/*"; map.insert(tr("Text"), text ); text << "*"; map.insert(tr("All"), text ); QString str = OFileDialog::getOpenFileName( 2, QString::null , QString::null, map); if( !str.isEmpty() && QFile(str).exists() && !QFileInfo(str).isDir() ) { openFile( str ); } else updateCaption(); } void TextEdit::doSearchBar() { if(!useSearchBar) searchBar->hide(); else searchBar->show(); } #if 0 void TextEdit::slotFind() { FindDialog frmFind( tr("Text Editor"), this ); connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)), editor, SLOT(slotDoFind( const QString&,bool,bool))); //case sensitive, backwards, [category] connect( editor, SIGNAL(notFound()), &frmFind, SLOT(slotNotFound()) ); connect( editor, SIGNAL(searchWrapped()), &frmFind, SLOT(slotWrapAround()) ); frmFind.exec(); } #endif void TextEdit::fileRevert() { clear(); fileOpen(); } void TextEdit::editCut() { #ifndef QT_NO_CLIPBOARD editor->cut(); #endif } void TextEdit::editCopy() { #ifndef QT_NO_CLIPBOARD editor->copy(); #endif } void TextEdit::editPaste() { #ifndef QT_NO_CLIPBOARD editor->paste(); #endif } void TextEdit::editFind() { searchBar->show(); searchEdit->setFocus(); } void TextEdit::findNext() { editor->find( searchEdit->text(), false, false ); } void TextEdit::findClose() { searchBar->hide(); } void TextEdit::search() { editor->find( searchEdit->text(), false, false ); } void TextEdit::newFile( const DocLnk &f ) { DocLnk nf = f; nf.setType("text/plain"); clear(); setWState (WState_Reserved1 ); editor->setFocus(); doc = new DocLnk(nf); currentFileName = "Unnamed"; qDebug("newFile "+currentFileName); updateCaption( currentFileName); // editor->setEdited( false); } void TextEdit::openDotFile( const QString &f ) { if(!currentFileName.isEmpty()) { currentFileName=f; qDebug("openFile dotfile " + currentFileName); QString txt; QFile file(f); file.open(IO_ReadWrite); QTextStream t(&file); while ( !t.atEnd()) { txt+=t.readLine()+"\n"; } editor->setText(txt); editor->setEdited( false); edited1=false; edited=false; } updateCaption( currentFileName); } void TextEdit::openFile( const QString &f ) { qDebug("filename is "+ f); QString filer; QFileInfo fi( f); // bFromDocView = true; if(f.find(".desktop",0,true) != -1 && !openDesktop ) { switch ( QMessageBox::warning(this,tr("Text Editor"),tr("Text Editor has detected<BR>you selected a <B>.desktop</B>file.<BR>Open<B>.desktop</B> file or <B>linked</B> file?"),tr(".desktop File"),tr("Linked Document"),0,1,1) ) { case 0: //desktop filer = f; break; case 1: //linked DocLnk sf(f); filer = sf.file(); break; }; } else if(fi.baseName().left(1) == "") { qDebug("opening dotfile"); currentFileName=f; openDotFile(currentFileName); return; } /* * The problem is a file where Config(f).isValid() and it does not * end with .desktop will be treated as desktop file */ else if (f.find(".desktop",0,true) != -1 ) { DocLnk sf(f); filer = sf.file(); if(filer.right(1) == "/") filer = f; } else filer = f; DocLnk nf; nf.setType("text/plain"); nf.setFile(filer); currentFileName=filer; nf.setName(fi.baseName()); openFile(nf); qDebug("openFile string "+currentFileName); showEditTools(); // Show filename in caption QString name = filer; int sep = name.findRev( '/' ); if ( sep > 0 ) name = name.mid( sep+1 ); updateCaption( name ); } void TextEdit::openFile( const DocLnk &f ) { // clear(); // bFromDocView = true; FileManager fm; QString txt; currentFileName=f.file(); qDebug("openFile doclnk " + currentFileName); if ( !fm.loadFile( f, txt ) ) { // ####### could be a new file qDebug( "Cannot open file" ); } // fileNew(); if ( doc ) delete doc; doc = new DocLnk(f); editor->setText(txt); editor->setEdited( false); edited1=false; edited=false; doc->setName(currentFileName); updateCaption(); setTimer(); } void TextEdit::showEditTools() { menu->show(); editBar->show(); if(!useSearchBar) searchBar->hide(); else searchBar->show(); setWState (WState_Reserved1 ); } /*! unprompted save */ bool TextEdit::save() { qDebug("saveAsFile " + currentFileName); if(currentFileName.isEmpty()) { saveAs(); return false; } QString file = doc->file(); qDebug("saver file "+file); QString name= doc->name(); qDebug("File named "+name); QString rt = editor->text(); if( !rt.isEmpty() ) { if(name.isEmpty()) { saveAs(); } else { currentFileName= name ; qDebug("saveFile "+currentFileName); struct stat buf; mode_t mode; stat(file.latin1(), &buf); mode = buf.st_mode; if(!fileIs) { doc->setName( name); FileManager fm; if ( !fm.saveFile( *doc, rt ) ) { QMessageBox::message(tr("Text Edit"),tr("Save Failed")); return false; } } else { qDebug("regular save file"); QFile f(file); if( f.open(IO_WriteOnly)) { QCString crt = rt.utf8(); f.writeBlock(crt,crt.length()); } else { QMessageBox::message(tr("Text Edit"),tr("Write Failed")); return false; } } editor->setEdited( false); edited1=false; edited=false; if(caption().left(1)=="*") setCaption(caption().right(caption().length()-1)); chmod( file.latin1(), mode); } return true; } return false; } /*! prompted save */ bool TextEdit::saveAs() { if(caption() == tr("Text Editor")) return false; qDebug("saveAsFile " + currentFileName); // case of nothing to save... // if ( !doc && !currentFileName.isEmpty()) { // //|| !bFromDocView) // qDebug("no doc"); // return true; // } // if ( !editor->edited() ) { // delete doc; // doc = 0; // return true; // } QString rt = editor->text(); qDebug(currentFileName); if( currentFileName.isEmpty() || currentFileName == tr("Unnamed") || currentFileName == tr("Text Editor")) { qDebug("do silly TT filename thing"); // if ( doc && doc->name().isEmpty() ) { QString pt = rt.simplifyWhiteSpace(); int i = pt.find( ' ' ); QString docname = pt; if ( i > 0 ) docname = pt.left( i ); // remove "." at the beginning while( docname.startsWith( "." ) ) docname = docname.mid( 1 ); docname.replace( QRegExp("/"), "_" ); // cut the length. filenames longer than that //don't make sense and something goes wrong when they get too long. if ( docname.length() > 40 ) docname = docname.left(40); if ( docname.isEmpty() ) docname = tr("Unnamed"); if(doc) doc->setName(docname); currentFileName=docname; // } // else // qDebug("hmmmmmm"); } QMap<QString, QStringList> map; map.insert(tr("All"), QStringList() ); QStringList text; text << "text/*"; map.insert(tr("Text"), text ); text << "*"; map.insert(tr("All"), text ); QFileInfo cuFi( currentFileName); QString filee = cuFi.fileName(); QString dire = cuFi.dirPath(); if(dire==".") dire = QPEApplication::documentDir(); QString str; if( !featureAutoSave) { str = OFileDialog::getSaveFileName( 2, dire, filee, map); } else str=currentFileName; if(!str.isEmpty()) { QString fileNm=str; qDebug("saving filename "+fileNm); QFileInfo fi(fileNm); currentFileName=fi.fileName(); if(doc) // QString file = doc->file(); // doc->removeFiles(); delete doc; DocLnk nf; nf.setType("text/plain"); nf.setFile( fileNm); doc = new DocLnk(nf); // editor->setText(rt); qDebug("Saving file as "+currentFileName); doc->setName( currentFileName); updateCaption( currentFileName); FileManager fm; if ( !fm.saveFile( *doc, rt ) ) { QMessageBox::message(tr("Text Edit"),tr("Save Failed")); return false; } if( filePerms ) { filePermissions *filePerm; filePerm = new filePermissions(this, tr("Permissions"),true, 0,(const QString &)fileNm); QPEApplication::execDialog( filePerm ); if( filePerm) delete filePerm; } // } editor->setEdited( false); edited1 = false; edited = false; if(caption().left(1)=="*") setCaption(caption().right(caption().length()-1)); return true; } qDebug("returning false"); return false; } //end saveAs void TextEdit::clear() { delete doc; doc = 0; editor->clear(); } void TextEdit::updateCaption( const QString &name ) { if ( name.isEmpty() ) setCaption( tr("Text Editor") ); else { QString s = name; if ( s.isNull() ) s = doc->name(); if ( s.isEmpty() ) { s = tr( "Unnamed" ); currentFileName=s; } // if(s.left(1) == "/") // s = s.right(s.length()-1); setCaption( tr("%1 - Text Editor").arg( s ) ); } } void TextEdit::setDocument(const QString& fileref) { if(fileref != "Unnamed") { currentFileName=fileref; qDebug("setDocument"); QFileInfo fi(currentFileName); qDebug("basename:"+fi.baseName()+": current filenmame "+currentFileName); if( (fi.baseName().left(1)).isEmpty() ) { openDotFile(currentFileName); } else { qDebug("setDoc open"); bFromDocView = true; openFile(fileref); editor->setEdited(true); edited1=false; edited=true; // fromSetDocument=false; // doSearchBar(); } } updateCaption( currentFileName); } void TextEdit::changeFont() { QDialog *d = new QDialog ( this, "FontDialog", true ); d-> setCaption ( tr( "Choose font" )); QBoxLayout *lay = new QVBoxLayout ( d ); OFontSelector *ofs = new OFontSelector ( true, d ); lay-> addWidget ( ofs ); ofs-> setSelectedFont ( editor-> font ( )); if ( QPEApplication::execDialog( d ) == QDialog::Accepted ) editor-> setFont ( ofs-> selectedFont ( )); delete d; } void TextEdit::editDelete() { switch ( QMessageBox::warning(this,tr("Text Editor"), tr("Do you really want<BR>to <B>delete</B> " "the current file\nfrom the disk?<BR>This is " "<B>irreversable!</B>"), tr("Yes"),tr("No"),0,0,1) ) { case 0: if(doc) { doc->removeFiles(); clear(); setCaption( tr("Text Editor") ); } break; case 1: // exit break; }; } void TextEdit::changeStartConfig( bool b ) { startWithNew=b; Config cfg("TextEdit"); cfg.setGroup("View"); cfg.writeEntry("startNew",b); update(); } void TextEdit::editorChanged() { // qDebug("editor changed"); if( /*editor->edited() &&*/ /*edited && */!edited1) { setCaption( "*"+caption()); edited1=true; } edited=true; } void TextEdit::receive(const QCString&msg, const QByteArray &) { qDebug("QCop "+msg); if ( msg == "setDocument(QString)" ) { qDebug("bugger all"); } } void TextEdit::doAbout() { QMessageBox::about(0,tr("Text Edit"),tr("Text Edit is copyright<BR>" |