summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/MyPty.cpp1
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp9
-rw-r--r--core/apps/embeddedkonsole/TEmuVt102.cpp5
-rw-r--r--core/apps/embeddedkonsole/TEmulation.cpp3
-rw-r--r--core/apps/embeddedkonsole/commandeditdialog.cpp8
-rw-r--r--core/apps/embeddedkonsole/commandeditwidget.cpp4
-rw-r--r--core/apps/embeddedkonsole/keytrans.cpp3
-rw-r--r--core/apps/embeddedkonsole/konsole.cpp21
-rw-r--r--core/apps/embeddedkonsole/playlistselection.cpp7
-rw-r--r--core/apps/embeddedkonsole/session.cpp1
-rw-r--r--core/apps/helpbrowser/helpbrowser.cpp24
-rw-r--r--core/apps/helpbrowser/magictextbrowser.cpp2
-rw-r--r--core/apps/oapp/oappplugin.cpp3
-rw-r--r--core/apps/qcop/main.cpp2
-rw-r--r--core/apps/taboapp/main.cpp1
-rw-r--r--core/apps/textedit/filePermissions.cpp4
-rw-r--r--core/apps/textedit/textedit.cpp18
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,1433 +1,1424 @@
/* ------------------------------------------------------------------------ */
/* */
/* [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;
case 0x2019: // fn-n
emit newSession();
break;
case Qt::Key_Tab:
if (ke->state() == ControlButton) {
emit changeSession(1);
} else {
special_function = false;
}
break;
#if 0
case Qt::Key_Left:
if (vcolumns == 0) {
emit changeSession(-1);
} else {
special_function = false;
}
break;
case Qt::Key_Right:
if (vcolumns == 0) {
emit changeSession(1);
} else {
special_function = false;
}
break;
#endif
case 0x201b: // fn-5
case Key_F4:
emit toggleFullScreen();
break;
case 0x200f: // fn-1 magnify minus
case Key_F5:
emit changeFontSize(-1);
break;
case 0x2010: // fn-2 magnify plus
case Key_F6:
emit changeFontSize(1);
break;
default:
special_function = false;
}
if (special_function) {
return true;
}
// else if( ke->state() == ControlButton && ke->key() == Key_V) {
// pasteClipboard();
// }
// else if( ke->state() == ControlButton && ke->key() == Key_C) {
// pasteClipboard();
// }
emit keyPressedSignal(ke); // expose
ke->accept();
#ifdef FAKE_CTRL_AND_ALT
if ( dele ) delete e;
#endif
return true; // stop the event
}
if ( e->type() == QEvent::Enter ) {
QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
this, SLOT(onClearSelection()) );
}
if ( e->type() == QEvent::Leave ) {
QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
this, SLOT(onClearSelection()) );
}
return QFrame::eventFilter( obj, e );
}
/* ------------------------------------------------------------------------- */
/* */
/* Frame */
/* */
/* ------------------------------------------------------------------------- */
void TEWidget::frameChanged()
{
propagateSize();
update();
}
/* ------------------------------------------------------------------------- */
/* */
/* Sound */
/* */
/* ------------------------------------------------------------------------- */
void TEWidget::Bell()
{
//#ifdef QT_QWS_SL5XXX
//# ifndef QT_NO_COP
if(useBeep)
QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
//# endif
//#else
//# ifndef QT_NO_SOUND
// QSound::play(Resource::findSound("alarm"));
//# endif
//#endif
// QApplication::beep();
}
/* ------------------------------------------------------------------------- */
/* */
/* Auxiluary */
/* */
/* ------------------------------------------------------------------------- */
void TEWidget::clearImage()
// initialize the image
// for internal use only
{
for (int y = 0; y < lines; y++)
for (int x = 0; x < columns; x++)
{
image[loc(x,y)].c = 0xff; //' ';
image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
}
}
// Create Image ///////////////////////////////////////////////////////
void TEWidget::calcGeometry()
{
int showhscrollbar = 1;
int hwidth = 0;
int dcolumns = 0;
Config cfg( "Konsole" );
cfg.setGroup("ScrollBar");
useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
if(vcolumns == 0) showhscrollbar = 0;
if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width();
scrollbar->resize(QApplication::style().scrollBarExtent().width(),
contentsRect().height() - hwidth);
switch(scrollLoc) {
case SCRNONE :
columns = ( contentsRect().width() - 2 * rimX ) / font_w;
dcolumns = columns;
if(vcolumns) columns = vcolumns;
blX = (contentsRect().width() - (columns*font_w) ) / 2;
if(showhscrollbar)
blX = -hposition * font_w;
brX = blX;
scrollbar->hide();
break;
case SCRLEFT :
columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
dcolumns = columns;
if(vcolumns) columns = vcolumns;
brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
if(showhscrollbar)
brX = -hposition * font_w;
blX = brX + scrollbar->width();
scrollbar->move(contentsRect().topLeft());
scrollbar->show();
break;
case SCRRIGHT:
columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
dcolumns = columns;
if(vcolumns) columns = vcolumns;
blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
if(showhscrollbar)
blX = -hposition * font_w;
brX = blX;
scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
scrollbar->show();
break;
}
//FIXME: support 'rounding' styles
lines = ( contentsRect().height() - 2 * rimY ) / font_h;
bY = (contentsRect().height() - (lines *font_h)) / 2;
if(showhscrollbar == 1) {
hScrollbar->resize(contentsRect().width() - hwidth, hwidth);
hScrollbar->setRange(0, vcolumns - dcolumns);
QPoint p = contentsRect().bottomLeft();
if(scrollLoc == SCRLEFT)
hScrollbar->move(QPoint(p.x()+hwidth, p.y() - hwidth));
else
hScrollbar->move(QPoint(p.x(), p.y() - hwidth));
hScrollbar->show();
}
else hScrollbar->hide();
if(showhscrollbar == 1) {
lines = lines - (hwidth / font_h) - 1;
if(lines < 1) lines = 1;
}
//FIXME: support 'rounding' styles
}
void TEWidget::makeImage()
//FIXME: rename 'calcGeometry?
{
calcGeometry();
image = (ca*) malloc(lines*columns*sizeof(ca));
clearImage();
}
// calculate the needed size
QSize TEWidget::calcSize(int cols, int lins) const
{
int frw = width() - contentsRect().width();
int frh = height() - contentsRect().height();
int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
}
QSize TEWidget::sizeHint() const
{
return size();
}
void TEWidget::styleChange(QStyle &)
{
propagateSize();
}
#ifndef QT_NO_DRAGANDDROP
/* --------------------------------------------------------------------- */
/* */
/* Drag & Drop */
/* */
/* --------------------------------------------------------------------- */
void TEWidget::dragEnterEvent(QDragEnterEvent* e)
{
e->accept(QTextDrag::canDecode(e) ||
QUriDrag::canDecode(e));
}
void TEWidget::dropEvent(QDropEvent* event)
{
// The current behaviour when url(s) are dropped is
// * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
// * in all other cases, just paste
// (for non-local ones, or for a list of URLs, 'cd' is nonsense)
QStrList strlist;
int file_count = 0;
dropText = "";
bool bPopup = true;
if(QUriDrag::decode(event, strlist)) {
if (strlist.count()) {
for(const char* p = strlist.first(); p; p = strlist.next()) {
if(file_count++ > 0) {
dropText += " ";
bPopup = false; // more than one file, don't popup
}
/*
KURL url(p);
if (url.isLocalFile()) {
dropText += url.path(); // local URL : remove protocol
}
else {
dropText += url.prettyURL();
bPopup = false; // a non-local file, don't popup
}
*/
}
if (bPopup)
// m_drop->popup(pos() + event->pos());
m_drop->popup(mapToGlobal(event->pos()));
else
{
if (currentSession) {
currentSession->getEmulation()->sendString(dropText.local8Bit());
}
// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
}
}
}
else if(QTextDrag::decode(event, dropText)) {
// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
if (currentSession) {
currentSession->getEmulation()->sendString(dropText.local8Bit());
}
// Paste it
}
}
#endif
void TEWidget::drop_menu_activated(int item)
{
#ifndef QT_NO_DRAGANDDROP
switch (item)
{
case 0: // paste
currentSession->getEmulation()->sendString(dropText.local8Bit());
// KWM::activate((Window)this->winId());
break;
case 1: // cd ...
currentSession->getEmulation()->sendString("cd ");
struct stat statbuf;
if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
{
if ( !S_ISDIR(statbuf.st_mode) )
{
/*
KURL url;
url.setPath( dropText );
dropText = url.directory( true, false ); // remove filename
*/
}
}
dropText.replace(QRegExp(" "), "\\ "); // escape spaces
currentSession->getEmulation()->sendString(dropText.local8Bit());
currentSession->getEmulation()->sendString("\n");
// KWM::activate((Window)this->winId());
break;
}
#endif
}
void TEWidget::setWrapAt(int columns)
{
vcolumns = columns;
propagateSize();
update();
}
diff --git a/core/apps/embeddedkonsole/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,1955 +1,1934 @@
/* ---------------------------------------------------------------------- */
/* */
/* [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;
}
}
/**
sets application window to a size based on columns X lines of the te
guest widget. Call with (0,0) for setting default size.
*/
void Konsole::setColLin(int columns, int lines)
{
qDebug("konsole::setColLin:: Columns %d", columns);
if ((columns==0) || (lines==0))
{
if (defaultSize.isEmpty()) // not in config file : set default value
{
defaultSize = calcSize(80,24);
// notifySize(24,80); // set menu items (strange arg order !)
}
resize(defaultSize);
}
else
{
resize(calcSize(columns, lines));
// notifySize(lines,columns); // set menu items (strange arg order !)
}
}
/*
void Konsole::setFont(int fontno)
{
QFont f;
if (fontno == 0)
f = defaultFont = QFont( "Helvetica", 12 );
else
if (fonts[fontno][0] == '-')
f.setRawName( fonts[fontno] );
else
{
f.setFamily(fonts[fontno]);
f.setRawMode( TRUE );
}
if ( !f.exactMatch() && fontno != 0)
{
QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]);
QMessageBox(this, msg);
return;
}
if (se) se->setFontNo(fontno);
te->setVTFont(f);
n_font = fontno;
}
*/
// --| color selection |-------------------------------------------------------
void Konsole::changeColumns(int /*columns*/)
{ //FIXME this seems to cause silliness when reset command is executed
// qDebug("change columns");
// TEWidget* te = getTe();
// if (te != 0) {
// setColLin(columns,te->Lines());
// te->update();
// }
}
//FIXME: If a child dies during session swap,
// this routine might be called before
// session swap is completed.
void Konsole::doneSession(TEWidget* te, int )
{
// TEWidget *te = NULL;
// if (sess->currentSession == tab->currentPage()) {
// printf("done current session\n");
// te = getTe();
// } else {
// int currentPage = tab->currentPageIndex();
// printf("done not current session\n");
// for(int i = 0; i < nsessions; i++) {
// tab->setCurrentPage(i);
// printf("find session %d tab page %x session %x\n",
// i, tab->currentPage(), sess->currentSession);
// if (tab->currentPage() == sess->currentSession) {
// printf("found session %d\n", i);
// te = tab->currentPage();
// break;
// }
// }
// tab->setCurrentPage(currentPage);
// }
if (te != 0)
{
te->currentSession->setConnect(FALSE);
tab->removeTab(te);
delete te->currentSession;
delete te;
sessionList->removeItem(nsessions);
nsessions--;
}
if (nsessions == 0)
{
close();
}
}
void Konsole::changeTitle(TEWidget* te, const QString& newTitle )
{
if (te == getTe())
{
setCaption( newTitle + " - " + tr( "Konsole " ) );
}
}
void Konsole::newSession()
{
if(nsessions < 15)
{ // seems to be something weird about 16 tabs on the Zaurus.... memory?
TEWidget* te = new TEWidget(tab);
Config cfg( "Konsole" );
cfg.setGroup("Menubar");
// FIXME use more defaults from config file
te->useBeep=cfg.readBoolEntry("useBeep",0);
// te->setBackgroundMode(PaletteBase); //we want transparent!!
cfg.setGroup("Font");
QString sn = "Session" + QString::number(nsessions+1);
printf("read font session %s\n", sn.latin1());
QString fontName = cfg.readEntry("FontName"+sn,
cfg.readEntry("FontName",
fonts.at(cfont)->getFamily()));
int fontSize = cfg.readNumEntry("FontSize"+sn,
cfg.readNumEntry("FontSize",
fonts.at(cfont)->getSize()));
cfont = findFont(fontName, fontSize, false);
printf("lookup font %s size %d got %d\n", fontName.latin1(), fontSize, cfont);
if (cfont < 0)
cfont = 0;
te->setVTFont(fonts.at(cfont)->getFont());
tab->addTab(te);
TESession* se = new TESession(this, te, se_pgm, se_args, "xterm");
te->currentSession = se;
connect( se, SIGNAL(done(TEWidget*,int)), this, SLOT(doneSession(TEWidget*,int)) );
connect( se, SIGNAL(changeTitle(TEWidget*,const QString&)), this,
SLOT(changeTitle(TEWidget*,const QString&)) );
connect(te, SIGNAL(changeFontSize(int)), this, SLOT(changeFontSize(int)));
connect(te, SIGNAL(changeSession(int)), this, SLOT(changeSession(int)));
connect(te, SIGNAL(newSession()), this, SLOT(newSession()));
connect(te, SIGNAL(toggleFullScreen()), this, SLOT(toggleFullScreen()));
connect(te, SIGNAL(setFullScreen(bool)), this, SLOT(setFullScreen(bool)));
se->run();
se->setConnect(TRUE);
se->setHistory(b_scroll);
nsessions++;
sessionList->insertItem(QString::number(nsessions), nsessions);
sessionListSelected(nsessions);
doWrap();
setColor(nsessions-1);
}
}
TEWidget* Konsole::getTe()
{
if (nsessions)
{
return (TEWidget *) tab->currentPage();
}
else
{
return 0;
}
}
void Konsole::sessionListSelected(int id)
{
if (id < 0)
{
return;
}
QString selected = sessionList->text(id);
EKNumTabBar *tabBar = tab->getTabBar();
int n = 0;
for(int i = 0; n < tabBar->count(); i++)
{
if (tabBar->tab(i))
{
// printf("selected = %s tab %d = %s\n", selected.latin1(),
// i, tabBar->tab(i)->text().latin1());
if (tabBar->tab(i)->text() == selected)
{
tab->setCurrentPage(i);
break;
}
n++;
}
}
}
void Konsole::changeSession(int delta)
{
printf("delta session %d\n", delta);
QTabBar *tabBar = tab->getTabBar();
int i = tabBar->tab(tabBar->currentTab())->text().toInt() - 1;
i += delta;
if (i < 0)
i += tabBar->count();
if (i >= tabBar->count())
i -= tabBar->count();
QString selected = QString::number(i+1);
int n = 0;
for(int i = 0; n < tabBar->count(); i++)
{
if (tabBar->tab(i))
{
printf("selected = %s tab %d = %s\n", selected.latin1(),
i, tabBar->tab(i)->text().latin1());
if (tabBar->tab(i)->text() == selected)
{
tab->setCurrentPage(i);
break;
}
n++;
}
}
}
void Konsole::switchSession(QWidget* w)
{
TEWidget* te = (TEWidget *) w;
QFont teFnt = te->getVTFont();
int familyNum = -1;
for(uint i = 0; i < fonts.count(); i++)
{
VTFont *fnt = fonts.at(i);
bool cf = fnt->getFont() == teFnt;
fontList->setItemChecked(i, cf);
if (cf)
{
cfont = i;
familyNum = fnt->getFamilyNum();
}
}
for(int i = 0; i < (int)fontList->count(); i++)
{
fontList->setItemChecked(i + 1000, i == familyNum);
}
if (! te->currentSession->Title().isEmpty() )
{
setCaption( te->currentSession->Title() + " - " + tr( "Konsole" ) );
}
else
{
setCaption( tr( "Konsole" ) );
}
// colorMenuSelected(te->color_menu_item);
}
void Konsole::toggleFullScreen()
{
setFullScreen(! fullscreen);
}
void Konsole::setFullScreen ( bool b )
{
static QSize normalsize;
static bool listHidden;
if (b == fullscreen)
{
return;
}
fullscreen = b;
if ( b )
{
if ( !normalsize. isValid ( ))
{
normalsize = size ( );
}
setFixedSize ( qApp-> desktop ( )-> size ( ));
showNormal ( );
reparent ( 0, WStyle_Customize | WStyle_NoBorder,
QPoint ( 0, 0 ));
showFullScreen ( );
menuToolBar->hide();
toolBar->hide();
listHidden = secondToolBar->isHidden();
secondToolBar->hide();
// commonCombo->hide();
tab->getTabBar()->hide();
tab->setMargin(tab->margin());
if (show_fullscreen_msg)
{
fullscreen_msg-> move(tab->x() + tab->width()/2 - fullscreen_msg->width()/2,
qApp->desktop()->height()/16 - fullscreen_msg->height()/2);
fullscreen_msg->show();
fullscreen_timer->start(3000, true);
show_fullscreen_msg = false;
}
}
else
{
showNormal ( );
reparent ( 0, WStyle_Customize, QPoint ( 0, 0 ));
resize ( normalsize );
showMaximized ( );
normalsize = QSize ( );
menuToolBar->show();
toolBar->show();
if(! listHidden)
{
secondToolBar->show();
}
// commonCombo->show();
menuToolBar->show();
if (tabPos != tm_hidden)
{
tab->getTabBar()->show();
}
}
tab->setMargin(tab->margin()); // cause setup to run
}
void Konsole::fullscreenTimeout()
{
fullscreen_msg->hide();
}
void Konsole::colorMenuIsSelected(int iD)
{
fromMenu = TRUE;
colorMenuSelected(iD);
}
/// ------------------------------- some new stuff by L.J. Potter
void Konsole::colorMenuSelected(int iD)
{
// this is NOT pretty, elegant or anything else besides functional
// QString temp;
// qDebug( temp.sprintf("colormenu %d", iD));
TEWidget* te = getTe();
Config cfg( "Konsole" );
cfg.setGroup("Colors");
ColorEntry m_table[TABLE_COLORS];
const ColorEntry * defaultCt=te->getdefaultColorTable();
int i;
// te->color_menu_item = iD;
colorMenu->setItemChecked(cm_ab,FALSE);
colorMenu->setItemChecked(cm_bb,FALSE);
colorMenu->setItemChecked(cm_wc,FALSE);
colorMenu->setItemChecked(cm_cw,FALSE);
colorMenu->setItemChecked(cm_mb,FALSE);
colorMenu->setItemChecked(cm_bm,FALSE);
colorMenu->setItemChecked(cm_gy,FALSE);
colorMenu->setItemChecked(cm_rb,FALSE);
colorMenu->setItemChecked(cm_br,FALSE);
colorMenu->setItemChecked(cm_wb,FALSE);
colorMenu->setItemChecked(cm_bw,FALSE);
colorMenu->setItemChecked(cm_gb,FALSE);
if(iD==cm_default)
{ // default default
printf("default colors\n");
for (i = 0; i < TABLE_COLORS; i++)
{
m_table[i].color = defaultCt[i].color;
if(i==1 || i == 11)
m_table[i].transparent=1;
colorMenu->setItemChecked(cm_default,TRUE);
}
te->setColorTable(m_table);
}
if(iD==cm_gb)
{ // green black
foreground.setRgb(100,255,100); // (0x18,255,0x18);
background.setRgb(0x00,0x00,0x00);
colorMenu->setItemChecked(cm_gb,TRUE);
}
if(iD==cm_bw)
{ // black white
foreground.setRgb(0x00,0x00,0x00);
background.setRgb(0xFF,0xFF,0xFF);
colorMenu->setItemChecked(cm_bw,TRUE);
}
if(iD==cm_wb)
{ // white black
foreground.setRgb(0xFF,0xFF,0xFF);
background.setRgb(0x00,0x00,0x00);
colorMenu->setItemChecked(cm_wb,TRUE);
}
if(iD==cm_br)
{// Black, Red
foreground.setRgb(0x00,0x00,0x00);
background.setRgb(255,85,85); //(0xB2,0x18,0x18);
colorMenu->setItemChecked(cm_br,TRUE);
}
if(iD==cm_rb)
{// Red, Black
foreground.setRgb(255,85,85);
background.setRgb(0x00,0x00,0x00);
colorMenu->setItemChecked(cm_rb,TRUE);
}
if(iD==cm_gy)
{// Green, Yellow - is ugly
// foreground.setRgb(0x18,0xB2,0x18);
foreground.setRgb(15,115,0);
// background.setRgb(0xB2,0x68,0x18);
background.setRgb(255,255,0);
colorMenu->setItemChecked(cm_gy,TRUE);
}
if(iD==cm_bm)
{// Blue, Magenta
foreground.setRgb(3,24,132);
background.setRgb(225,2,255);
colorMenu->setItemChecked(cm_bm,TRUE);
}
if(iD==cm_mb)
{// Magenta, Blue
foreground.setRgb(225,2,255);
background.setRgb(3,24,132);
colorMenu->setItemChecked(cm_mb,TRUE);
}
if(iD==cm_cw)
{// Cyan, White
foreground.setRgb(8,91,129);
background.setRgb(0xFF,0xFF,0xFF);
colorMenu->setItemChecked(cm_cw,TRUE);
}
if(iD==cm_wc)
{// White, Cyan
background.setRgb(8,91,129);
foreground.setRgb(0xFF,0xFF,0xFF);
colorMenu->setItemChecked(cm_wc,TRUE);
}
if(iD==cm_bb)
{// Black, Blue
background.setRgb(0x00,0x00,0x00);
foreground.setRgb(127,147,225);
colorMenu->setItemChecked(cm_bb,TRUE);
}
if(iD==cm_ab)
{// Black, Gold
background.setRgb(0x00,0x00,0x00);
foreground.setRgb(255,215,105);
colorMenu->setItemChecked(cm_ab,TRUE);
}
#ifdef QT_QWS_OPIE
if(iD==-19)
{
// Custom
qDebug("do custom");
if(fromMenu)
{
Opie::OColorPopupMenu* penColorPopupMenu = new Opie::OColorPopupMenu(Qt::black, this, "foreground color");
connect(penColorPopupMenu, SIGNAL(colorSelected(const QColor&)), this,
SLOT(changeForegroundColor(const QColor&)));
penColorPopupMenu->exec();
}
if(!fromMenu)
{
foreground.setNamedColor(cfg.readEntry("foreground",""));
background.setNamedColor(cfg.readEntry("background",""));
}
fromMenu=FALSE;
colorMenu->setItemChecked(-19,TRUE);
}
#endif
lastSelectedMenu = iD;
setColors(foreground, background);
QTabBar *tabBar = tab->getTabBar();
QString ss = QString("Session%1").arg(tabBar->currentTab());
// printf("current tab = %d\n", tabBar->currentTab());
if (tabBar->currentTab() == 0)
{
cfg.writeEntry("foregroundRed",QString::number(foreground.red()));
cfg.writeEntry("foregroundGreen",QString::number(foreground.green()));
cfg.writeEntry("foregroundBlue",QString::number(foreground.blue()));
cfg.writeEntry("backgroundRed",QString::number(background.red()));
cfg.writeEntry("backgroundGreen",QString::number(background.green()));
cfg.writeEntry("backgroundBlue",QString::number(background.blue()));
}
cfg.writeEntry("foregroundRed"+ss,QString::number(foreground.red()));
cfg.writeEntry("foregroundGreen"+ss,QString::number(foreground.green()));
cfg.writeEntry("foregroundBlue"+ss,QString::number(foreground.blue()));
cfg.writeEntry("backgroundRed"+ss,QString::number(background.red()));
cfg.writeEntry("backgroundGreen"+ss,QString::number(background.green()));
cfg.writeEntry("backgroundBlue"+ss,QString::number(background.blue()));
update();
}
void Konsole::setColors(QColor foreground, QColor background)
{
int i;
ColorEntry m_table[TABLE_COLORS];
TEWidget* te = getTe();
const ColorEntry * defaultCt=te->getdefaultColorTable();
for (i = 0; i < TABLE_COLORS; i++)
{
if(i==0 || i == 10)
{
m_table[i].color = foreground;
}
else if(i==1 || i == 11)
{
m_table[i].color = background;
m_table[i].transparent=0;
}
else
m_table[i].color = defaultCt[i].color;
}
te->setColorTable(m_table);
}
void Konsole::tabMenuSelected(int id)
{
Config cfg( "Konsole" );
cfg.setGroup("Tabs");
tabMenu->setItemChecked(tabPos, false);
if (id == tm_bottom)
{
printf("set bottom tab\n");
tab->getTabBar()->show();
tab->setTabPosition(QTabWidget::Bottom);
tab->getTabBar()->show();
cfg.writeEntry("Position","Bottom");
}
else if (id == tm_top)
{
printf("set top tab\n");
tab->getTabBar()->show();
tab->setTabPosition(QTabWidget::Bottom);
tab->setTabPosition(QTabWidget::Top);
tab->getTabBar()->show();
cfg.writeEntry("Position","Top");
}
else if (id == tm_hidden)
{
tab->getTabBar()->hide();
tab->setMargin(tab->margin());
cfg.writeEntry("Position","Hidden");
}
tabMenu->setItemChecked(id, true);
tabPos = id;
}
void Konsole::configMenuSelected(int iD)
{
// QString temp;
// qDebug( temp.sprintf("configmenu %d",iD));
TEWidget* te = getTe();
Config cfg( "Konsole" );
cfg.setGroup("Menubar");
if(iD == cm_wrap)
{
cfg.setGroup("ScrollBar");
bool b=cfg.readBoolEntry("HorzScroll",0);
b=!b;
cfg.writeEntry("HorzScroll", b );
cfg.write();
doWrap();
if(cfg.readNumEntry("Position",2) == 0)
{
te->setScrollbarLocation(1);
}
else
{
te->setScrollbarLocation(0);
}
te->setScrollbarLocation( cfg.readNumEntry("Position",2));
}
if(iD == cm_beep)
{
cfg.setGroup("Menubar");
bool b=cfg.readBoolEntry("useBeep",0);
b=!b;
cfg.writeEntry("useBeep", b );
cfg.write();
configMenu->setItemChecked(cm_beep,b);
te->useBeep=b;
}
}
void Konsole::changeCommand(const QString &text, int c)
{
Config cfg( "Konsole" );
cfg.setGroup("Commands");
if(commonCmds[c] != text)
{
cfg.writeEntry(QString::number(c),text);
commonCombo->clearEdit();
commonCombo->setCurrentItem(c);
}
}
void Konsole::setColor(int sess)
{
Config cfg( "Konsole" );
cfg.setGroup("Colors");
QColor foreground, background;
QString ss = QString("Session") + QString::number(sess);
foreground.setRgb(cfg.readNumEntry("foregroundRed"+ss,
cfg.readNumEntry("foregroundRed",0xff)),
cfg.readNumEntry("foregroundGreen"+ss,
cfg.readNumEntry("foregroundGreen",0xff)),
cfg.readNumEntry("foregroundBlue"+ss,
cfg.readNumEntry("foregroundBlue",0xff)));
background.setRgb(cfg.readNumEntry("backgroundRed"+ss,
cfg.readNumEntry("backgroundRed",0)),
cfg.readNumEntry("backgroundGreen"+ss,
cfg.readNumEntry("backgroundGreen",0)),
cfg.readNumEntry("backgroundBlue"+ss,
cfg.readNumEntry("backgroundBlue",0)));
setColors(foreground, background);
}
void Konsole::scrollMenuSelected(int index)
{
// qDebug( "scrollbar menu %d",index);
TEWidget* te = getTe();
Config cfg( "Konsole" );
cfg.setGroup("ScrollBar");
if(index == sm_none)
{
te->setScrollbarLocation(0);
cfg.writeEntry("Position",0);
}
else if(index == sm_left)
{
te->setScrollbarLocation(1);
cfg.writeEntry("Position",1);
}
else if(index == sm_right)
{
te->setScrollbarLocation(2);
cfg.writeEntry("Position",2);
}
scrollMenu->setItemChecked(sm_none, index == sm_none);
scrollMenu->setItemChecked(sm_left, index == sm_left);
scrollMenu->setItemChecked(sm_right, index == sm_right);
}
// case -29: {
// bool b=cfg.readBoolEntry("HorzScroll",0);
// cfg.writeEntry("HorzScroll", !b );
// cfg.write();
// if(cfg.readNumEntry("Position",2) == 0) {
// te->setScrollbarLocation(1);
// te->setWrapAt(0);
// } else {
// te->setScrollbarLocation(0);
// te->setWrapAt(120);
// }
// te->setScrollbarLocation( cfg.readNumEntry("Position",2));
// }
// break;
void Konsole::editCommandListMenuSelected(int iD)
{
// QString temp;
// qDebug( temp.sprintf("edit command list %d",iD));
// FIXME: more cleanup needed here
TEWidget* te = getTe();
Config cfg( "Konsole" );
cfg.setGroup("Menubar");
if( iD == ec_cmdlist)
{
if(!secondToolBar->isHidden())
{
secondToolBar->hide();
configMenu->changeItem( iD,tr( "Show Command List" ));
cfg.writeEntry("Hidden","TRUE");
configMenu->setItemEnabled(ec_edit ,FALSE);
configMenu->setItemEnabled(ec_quick ,FALSE);
}
else
{
secondToolBar->show();
configMenu->changeItem( iD,tr( "Hide Command List" ));
cfg.writeEntry("Hidden","FALSE");
configMenu->setItemEnabled(ec_edit ,TRUE);
configMenu->setItemEnabled(ec_quick ,TRUE);
if(cfg.readEntry("EditEnabled","FALSE")=="TRUE")
{
configMenu->setItemChecked(ec_edit,TRUE);
commonCombo->setEditable( TRUE );
}
else
{
configMenu->setItemChecked(ec_edit,FALSE);
commonCombo->setEditable( FALSE );
}
}
}
if( iD == ec_quick)
{
cfg.setGroup("Commands");
// qDebug("enableCommandEdit");
if( !configMenu->isItemChecked(iD) )
{
commonCombo->setEditable( TRUE );
configMenu->setItemChecked(iD,TRUE);
commonCombo->setCurrentItem(0);
cfg.writeEntry("EditEnabled","TRUE");
}
else
{
commonCombo->setEditable( FALSE );
configMenu->setItemChecked(iD,FALSE);
cfg.writeEntry("EditEnabled","FALSE");
commonCombo->setFocusPolicy(QWidget::NoFocus);
te->setFocus();
}
}
if(iD == ec_edit)
{
// "edit commands"
CommandEditDialog *m = new CommandEditDialog(this);
connect(m,SIGNAL(commandsEdited()),this,SLOT(initCommandList()));
m->showMaximized();
}
}
// $QPEDIR/bin/qcop QPE/Application/embeddedkonsole 'setDocument(QString)' 'ssh -V'
void Konsole::setDocument( const QString &cmd)
{
newSession();
TEWidget* te = getTe();
if(cmd.find("-e", 0, TRUE) != -1)
{
QString cmd2;
cmd2=cmd.right(cmd.length()-3)+" &";
system(cmd2.latin1());
if(startUp <= 1 && nsessions < 2)
{
doneSession(getTe(), 0);
exit(0);
}
else
doneSession(getTe(), 0);
}
else
{
if (te != 0)
{
te->emitText(cmd+"\r");
}
}
startUp++;
}
// what is the point of this when you can just
// run commands by using the shell directly??
void Konsole::parseCommandLine()
{
QString cmd;
// newSession();
for (int i=1;i< qApp->argc();i++)
{
if( QString(qApp->argv()[i]) == "-e")
{
i++;
for ( int j=i;j< qApp->argc();j++)
{
cmd+=QString(qApp->argv()[j])+" ";
}
cmd.stripWhiteSpace();
system(cmd.latin1());
exit(0);//close();
} // end -e switch
}
startUp++;
}
void Konsole::changeForegroundColor(const QColor &color)
{
Config cfg( "Konsole" );
cfg.setGroup("Colors");
int r, g, b;
color.rgb(&r,&g,&b);
foreground.setRgb(r,g,b);
cfg.writeEntry("foreground",color.name());
qDebug("foreground "+color.name());
cfg.write();
qDebug("do other dialog");
#ifdef QT_QWS_OPIE
Opie::OColorPopupMenu* penColorPopupMenu2 = new Opie::OColorPopupMenu(Qt::black, this,"background color");
connect(penColorPopupMenu2, SIGNAL(colorSelected(const QColor&)), this,
SLOT(changeBackgroundColor(const QColor&)));
penColorPopupMenu2->exec();
#endif
}
void Konsole::changeBackgroundColor(const QColor &color)
{
qDebug("Change background");
Config cfg( "Konsole" );
cfg.setGroup("Colors");
int r, g, b;
color.rgb(&r,&g,&b);
background.setRgb(r,g,b);
cfg.writeEntry("background",color.name());
qDebug("background "+color.name());
cfg.write();
}
void Konsole::doWrap()
{
Config cfg( "Konsole" );
cfg.setGroup("ScrollBar");
TEWidget* te = getTe();
if( !cfg.readBoolEntry("HorzScroll",0))
{
te->setWrapAt(0);
configMenu->setItemChecked( cm_wrap,TRUE);
}
else
{
// te->setWrapAt(90);
te->setWrapAt(120);
configMenu->setItemChecked( cm_wrap,FALSE);
}
}
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,1215 +1,1197 @@
/**********************************************************************
// 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>"
"2000 Trolltech AS, and<BR>"
"2002 by <B>L. J. Potter <BR>llornkcor@handhelds.org</B><BR>"
"and is licensed under the GPL"));
}
void TextEdit::doPrompt(bool b) {
promptExit=b;
Config cfg("TextEdit");
cfg.setGroup ( "View" );
cfg.writeEntry ( "PromptExit", b);
}
void TextEdit::doDesktop(bool b) {
openDesktop=b;
Config cfg("TextEdit");
cfg.setGroup ( "View" );
cfg.writeEntry ( "OpenDesktop", b);
}
void TextEdit::doFilePerms(bool b) {
filePerms=b;
Config cfg("TextEdit");
cfg.setGroup ( "View" );
cfg.writeEntry ( "FilePermissions", b);
}
void TextEdit::editPasteTimeDate() {
#ifndef QT_NO_CLIPBOARD
QClipboard *cb = QApplication::clipboard();
QDateTime dt = QDateTime::currentDateTime();
cb->setText( dt.toString());
editor->paste();
#endif
}
int TextEdit::savePrompt()
{
switch( QMessageBox::information( 0, (tr("Textedit")),
(tr("Textedit detected\n"
"you have unsaved changes\n"
"Go ahead and save?\n")),
(tr("Save")), (tr("Don't Save")), (tr("&Cancel")), 2, 2 ) )
{
case 0:
{
return 1;
}
break;
case 1:
{
return 2;
}
break;
case 2:
{
return -1;
}
break;
};
return 0;
}
void TextEdit::timerCrank()
{
if(featureAutoSave && edited1)
{
if(currentFileName.isEmpty())
{
currentFileName = QDir::homeDirPath()+"/textedit.tmp";
saveAs();
}
else
{
// qDebug("autosave");
save();
}
setTimer();
}
}
void TextEdit::doTimer(bool b)
{
Config cfg("TextEdit");
cfg.setGroup ( "View" );
cfg.writeEntry ( "autosave", b);
featureAutoSave = b;
nAutoSave->setOn(b);
if(b)
{
// qDebug("doTimer true");
setTimer();
}
// else
// qDebug("doTimer false");
}
void TextEdit::setTimer()
{
if(featureAutoSave)
{
// qDebug("setting autosave");
QTimer *timer = new QTimer(this );
connect( timer, SIGNAL(timeout()), this, SLOT(timerCrank()) );
timer->start( 300000, true); //5 minutes
}
}
void TextEdit::gotoLine() {
if( editor->length() < 1)
return;
QWidget *d = QApplication::desktop();
gotoEdit = new QLineEdit( 0, "Goto line");
gotoEdit->move( (d->width()/2) - ( gotoEdit->width()/2) , (d->height()/2) - (gotoEdit->height()/2));
gotoEdit->setFrame(true);
gotoEdit->show();
connect (gotoEdit,SIGNAL(returnPressed()), this, SLOT(doGoto()));
}
void TextEdit::doGoto() {
QString number = gotoEdit->text();
gotoEdit->hide();
if(gotoEdit) {
delete gotoEdit;
gotoEdit = 0;
}
bool ok;
int lineNumber = number.toInt(&ok, 10);
if( editor->numLines() < lineNumber)
QMessageBox::message(tr("Text Edit"),tr("Not enough lines"));
else
{
editor->setCursorPosition(lineNumber, 0, false);
}
}