summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/MyPty.cpp8
-rw-r--r--core/apps/embeddedkonsole/TEHistory.cpp269
-rw-r--r--core/apps/embeddedkonsole/TEHistory.h42
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp18
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp110
-rw-r--r--core/apps/embeddedkonsole/TEWidget.h14
-rw-r--r--core/apps/embeddedkonsole/TEmulation.cpp1
-rw-r--r--core/apps/embeddedkonsole/commandeditdialog.cpp4
-rw-r--r--core/apps/embeddedkonsole/konsole.cpp1542
-rw-r--r--core/apps/embeddedkonsole/konsole.h80
-rw-r--r--core/apps/embeddedkonsole/main.cpp1
-rw-r--r--core/apps/embeddedkonsole/session.cpp20
-rw-r--r--core/apps/embeddedkonsole/session.h5
13 files changed, 1505 insertions, 609 deletions
diff --git a/core/apps/embeddedkonsole/MyPty.cpp b/core/apps/embeddedkonsole/MyPty.cpp
index 7e820ad..e7d8274 100644
--- a/core/apps/embeddedkonsole/MyPty.cpp
+++ b/core/apps/embeddedkonsole/MyPty.cpp
@@ -1,284 +1,290 @@
/* -------------------------------------------------------------------------- */
/* */
/* [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>
+#undef HAVE_OPENPTY
#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 );
- if(strlen(getenv("TERM"))<=0)
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/TEHistory.cpp b/core/apps/embeddedkonsole/TEHistory.cpp
index db9d10c..504cd13 100644
--- a/core/apps/embeddedkonsole/TEHistory.cpp
+++ b/core/apps/embeddedkonsole/TEHistory.cpp
@@ -1,219 +1,230 @@
/* -------------------------------------------------------------------------- */
/* */
/* [TEHistory.C] History Buffer */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
-/* This file is part of Konsole - an X terminal for KDE */
+/* This file is part of Qkonsole - an X terminal for KDE */
/* */
/* -------------------------------------------------------------------------- */
/* */
-/* Ported Konsole to Qt/Embedded */
+/* Ported Qkonsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
#include "TEHistory.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
+#include <qpe/config.h>
+
#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
/*
An arbitrary long scroll.
One can modify the scroll only by adding either cells
or newlines, but access it randomly.
The model is that of an arbitrary wide typewriter scroll
in that the scroll is a serie of lines and each line is
a serie of cells with no overwriting permitted.
The implementation provides arbitrary length and numbers
of cells and line/column indexed read access to the scroll
at constant costs.
-FIXME: some complain about the history buffer comsuming the
- memory of their machines. This problem is critical
- since the history does not behave gracefully in cases
- where the memory is used up completely.
-
- I put in a workaround that should handle it problem
- now gracefully. I'm not satisfied with the solution.
-
-FIXME: Terminating the history is not properly indicated
- in the menu. We should throw a signal.
-
-FIXME: There is noticable decrease in speed, also. Perhaps,
- there whole feature needs to be revisited therefore.
- Disadvantage of a more elaborated, say block-oriented
- scheme with wrap around would be it's complexity.
*/
-//FIXME: tempory replacement for tmpfile
-// this is here one for debugging purpose.
-
-//#define tmpfile xTmpFile
-
-FILE* xTmpFile()
-{
- static int fid = 0;
- char fname[80];
- sprintf(fname,"TmpFile.%d",fid++);
- return fopen(fname,"w");
-}
-
-
-// History Buffer ///////////////////////////////////////////
-
-/*
- A Row(X) data type which allows adding elements to the end.
-*/
-
-HistoryBuffer::HistoryBuffer()
-{
- ion = -1;
- length = 0;
-}
-HistoryBuffer::~HistoryBuffer()
+HistoryScroll::HistoryScroll()
{
- setScroll(FALSE);
+ m_lines = NULL;
+ m_max_lines = 0;
+ m_cells = NULL;
+ m_max_cells = 0;
+ m_num_lines = 0;
+ m_first_line = 0;
+ m_last_cell = 0;
+ m_start_line = 0;
}
-void HistoryBuffer::setScroll(bool on)
-{
- if (on == hasScroll()) return;
-
- if (on)
- {
- assert( ion < 0 );
- assert( length == 0);
- FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
- ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
- fclose(tmp);
- }
- else
+HistoryScroll::~HistoryScroll()
{
- assert( ion >= 0 );
- close(ion);
- ion = -1;
- length = 0;
- }
+ setSize(0,0);
}
-bool HistoryBuffer::hasScroll()
+void HistoryScroll::setSize(int lines, int cells)
{
- return ion >= 0;
-}
-
-void HistoryBuffer::add(const unsigned char* bytes, int len)
-{ int rc;
- assert(hasScroll());
- rc = lseek( ion, length, SEEK_SET);
- if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
- rc = write( ion, bytes, len);
- if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
- length += rc;
-}
-
-void HistoryBuffer::get(unsigned char* bytes, int len, int loc) {
- int rc;
- assert(hasScroll());
-// qDebug("history get len %d, loc %d, length %d", len, loc, length);
- if (loc < 0 || len < 0 || loc + len > length)
- fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
-
- rc = lseek( ion, loc, SEEK_SET);
- if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
- rc = read( ion, bytes, len);
- if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
+ // could try to preserve the existing data...
+ // printf("setSize(%d,%d)\n", lines, cells);
+ if (m_lines) {
+ delete m_lines;
+ m_lines = NULL;
}
-
-int HistoryBuffer::len()
-{
- return length;
+ if (m_cells) {
+ delete m_cells;
+ m_cells = NULL;
}
-
-// History Scroll //////////////////////////////////////
-
-/*
- The history scroll makes a Row(Row(Cell)) from
- two history buffers. The index buffer contains
- start of line positions which refere to the cells
- buffer.
-
- Note that index[0] addresses the second line
- (line #1), while the first line (line #0) starts
- at 0 in cells.
-*/
-
-HistoryScroll::HistoryScroll()
-{
+ m_max_lines = m_max_cells = 0;
+ if (lines > 0 && cells > 0) {
+ m_max_lines = lines;
+ m_lines = new int[m_max_lines];
+ m_lines[0] = 0;
+ m_max_cells = cells;
+ m_cells = new ca[m_max_cells];
}
-
-HistoryScroll::~HistoryScroll()
-{
+ m_first_line = 0;
+ m_num_lines = 0;
+ m_last_cell = 0;
+ m_start_line = 0;
}
void HistoryScroll::setScroll(bool on)
{
- index.setScroll(on);
- cells.setScroll(on);
+ Config cfg("Qkonsole");
+ cfg.setGroup("History");
+ // printf("setScroll(%d)\n", on);
+ if (on) {
+ int lines = cfg.readNumEntry("history_lines",300);
+ int avg_line = cfg.readNumEntry("avg_line_length",60);
+ int cells = lines * avg_line;
+ setSize(lines,cells);
+ } else {
+ setSize(0,0);
+ }
}
bool HistoryScroll::hasScroll()
{
- return index.hasScroll() && cells.hasScroll();
+ return (m_max_lines > 0);
}
int HistoryScroll::getLines()
{
- if (!hasScroll()) return 0;
- return index.len() / sizeof(int);
+ return(m_num_lines);
}
int HistoryScroll::getLineLen(int lineno)
{
if (!hasScroll()) return 0;
- return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
+ if (lineno >= m_num_lines) {
+ // printf("getLineLen(%d) out of range %d\n", lineno, m_num_lines);
+ return(0);
+ }
+ int len = startOfLine(lineno+1) - startOfLine(lineno);
+ if (len < 0) {
+ len += m_max_cells;
+ }
+ // printf("getLineLen(%d) = %d\n", lineno, len);
+ return(len);
}
int HistoryScroll::startOfLine(int lineno)
{
- if (lineno <= 0) return 0;
+ // printf("startOfLine(%d) =", lineno);
if (!hasScroll()) return 0;
- if (lineno <= getLines())
- { int res;
- index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
- return res;
+ assert(lineno >= 0 && lineno <= m_num_lines);
+ if (lineno < m_num_lines) {
+ int index = lineno + m_first_line;
+ if (index >= m_max_lines)
+ index -= m_max_lines;
+ // printf("%d\n", m_lines[index]);
+ return(m_lines[index]);
+ } else {
+ // printf("last %d\n", m_last_cell);
+ return(m_last_cell);
}
- return cells.len();
}
-void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
+void HistoryScroll::getCells(int lineno, int colno, int count, ca *res)
{
+ // printf("getCells(%d,%d,%d) num_lines=%d\n", lineno, colno, count, m_num_lines);
assert(hasScroll());
-//get(unsigned char* bytes, int len, int loc)
- cells.get( (unsigned char*)res, count * sizeof(ca), startOfLine( lineno) + colno * sizeof(ca) );
+ assert(lineno >= 0 && lineno < m_num_lines);
+ int index = lineno + m_first_line;
+ if (index >= m_max_lines)
+ index -= m_max_lines;
+ assert(index >= 0 && index < m_max_lines);
+ index = m_lines[index] + colno;
+ assert(index >= 0 && index < m_max_cells);
+ while(count-- > 0) {
+ *res++ = m_cells[index];
+ if (++index >= m_max_cells) {
+ index = 0;
+ }
+ }
}
-void HistoryScroll::addCells(ca text[], int count)
+void HistoryScroll::addCells(ca *text, int count)
{
if (!hasScroll()) return;
- cells.add((unsigned char*)text,count*sizeof(ca));
+ int start_cell = m_last_cell;
+ // printf("addCells count=%d start=%d first_line=%d first_cell=%d lines=%d\n",
+ // count, start_cell, m_first_line, m_lines[m_first_line], m_num_lines);
+ if (count <= 0) {
+ return;
+ }
+ while(count-- > 0) {
+ assert (m_last_cell >= 0 && m_last_cell < m_max_cells );
+ m_cells[m_last_cell] = *text++;
+ if (++m_last_cell >= m_max_cells) {
+ m_last_cell = 0;
+ }
+ }
+ if (m_num_lines > 1) {
+ if (m_last_cell > start_cell) {
+ while(m_num_lines > 0
+ && m_lines[m_first_line] >= start_cell
+ && m_lines[m_first_line] < m_last_cell) {
+ // printf("A remove %d>%d && %d<%d first_line=%d num_lines=%d\n",
+ // m_lines[m_first_line], start_cell, m_lines[m_first_line], m_last_cell,
+ // m_first_line, m_num_lines);
+ if (++m_first_line >= m_max_lines) {
+ m_first_line = 0;
+ }
+ m_num_lines--;
+ }
+ } else {
+ while(m_num_lines > 0
+ && (m_lines[m_first_line] >= start_cell
+ || m_lines[m_first_line] < m_last_cell)) {
+ // printf("B remove %d>%d || %d<%d first_line=%d num_lines=%d\n",
+ // m_lines[m_first_line], start_cell, m_lines[m_first_line], m_last_cell,
+ // m_first_line, m_num_lines);
+ if (++m_first_line >= m_max_lines) {
+ m_first_line = 0;
+ }
+ m_num_lines--;
+ }
+ }
+ }
}
void HistoryScroll::addLine()
{
if (!hasScroll()) return;
- int locn = cells.len();
- index.add((unsigned char*)&locn,sizeof(int));
+ int index = m_first_line + m_num_lines;
+ if (index >= m_max_lines) {
+ index -= m_max_lines;
+ }
+ // printf("addLine line=%d cell=%d\n", index, m_last_cell);
+ assert(index >= 0 && index < m_max_lines);
+ m_lines[index] = m_start_line;
+ m_start_line = m_last_cell;
+ if (m_num_lines >= m_max_lines) {
+ if (++m_first_line >= m_num_lines) {
+ m_first_line = 0;
+ }
+ } else {
+ m_num_lines++;
+ }
}
diff --git a/core/apps/embeddedkonsole/TEHistory.h b/core/apps/embeddedkonsole/TEHistory.h
index 11eb150..fcf6496 100644
--- a/core/apps/embeddedkonsole/TEHistory.h
+++ b/core/apps/embeddedkonsole/TEHistory.h
@@ -1,75 +1,57 @@
/* -------------------------------------------------------------------------- */
/* */
/* [TEHistory.H] History Buffer */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
/* This file is part of Konsole - an X terminal for KDE */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Ported Konsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
#ifndef TEHISTORY_H
#define TEHISTORY_H
#include "TECommon.h"
-/*
- An extendable tmpfile(1) based buffer.
-*/
-class HistoryBuffer
-{
-public:
- HistoryBuffer();
- ~HistoryBuffer();
-
-public:
- void setScroll(bool on);
- bool hasScroll();
-
-public:
- void add(const unsigned char* bytes, int len);
- void get(unsigned char* bytes, int len, int loc);
- int len();
-
-private:
- int ion;
- int length;
-};
-
class HistoryScroll
{
public:
HistoryScroll();
~HistoryScroll();
public:
+ void setSize(int lines, int cells);
void setScroll(bool on);
bool hasScroll();
-public: // access to history
int getLines();
int getLineLen(int lineno);
- void getCells(int lineno, int colno, int count, ca res[]);
+ void getCells(int lineno, int colno, int count, ca *res);
-public: // backward compatibility (obsolete)
ca getCell(int lineno, int colno) { ca res; getCells(lineno,colno,1,&res); return res; }
-public: // adding lines.
- void addCells(ca a[], int count);
+ void addCells(ca *text, int count);
void addLine();
private:
int startOfLine(int lineno);
- HistoryBuffer index; // lines Row(int)
- HistoryBuffer cells; // text Row(ca)
+
+ int m_max_lines;
+ int *m_lines;
+ int m_max_cells;
+ ca *m_cells;
+ int m_first_line;
+ int m_last_cell;
+ int m_num_lines;
+ int m_start_line;
};
#endif // TEHISTORY_H
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
index a6cf6a1..4ebc28e 100644
--- a/core/apps/embeddedkonsole/TEScreen.cpp
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -1,1220 +1,1236 @@
/* -------------------------------------------------------------------------- */
/* */
/* [TEScreen.C] Screen Data Type */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
/* This file is part of Konsole - an X terminal for KDE */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Ported Konsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
// enhancements added by L.J. Potter <ljp@llornkcor.com>
/*! \file
*/
/*! \class TEScreen
\brief The image manipulated by the emulation.
This class implements the operations of the terminal emulation framework.
It is a complete passive device, driven by the emulation decoder
(TEmuVT102). By this it forms in fact an ADT, that defines operations
on a rectangular image.
It does neither know how to display its image nor about escape sequences.
It is further independent of the underlying toolkit. By this, one can even
use this module for an ordinary text surface.
Since the operations are called by a specific emulation decoder, one may
collect their different operations here.
The state manipulated by the operations is mainly kept in `image', though
it is a little more complex bejond this. See the header file of the class.
\sa TEWidget \sa VT102Emulation
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// #include <kdebug.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <qpe/config.h>
#include "TEScreen.h"
#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
//FIXME: see if we can get this from terminfo.
#define BS_CLEARS FALSE
#define loc(X,Y) ((Y) * columns + (X))
/*! creates a `TEScreen' of `lines' lines and `columns' columns.
*/
TEScreen::TEScreen(int lines, int columns)
{
this->lines = lines;
this->columns = columns;
// qDebug("Columns %d", columns);
image = (ca*) malloc(lines*columns*sizeof(ca));
tabstops = NULL; initTabStops();
histCursor = 0;
horzCursor = 0;
clearSelection();
reset();
}
/*! Destructor
*/
TEScreen::~TEScreen()
{
free(image);
if (tabstops) free(tabstops);
}
/* ------------------------------------------------------------------------- */
/* */
/* Normalized Screen Operations */
/* */
/* ------------------------------------------------------------------------- */
// Cursor Setting --------------------------------------------------------------
/*! \section Cursor
The `cursor' is a location within the screen that is implicitely used in
many operations. The operations within this section allow to manipulate
the cursor explicitly and to obtain it's value.
The position of the cursor is guarantied to be between (including) 0 and
`columns-1' and `lines-1'.
*/
/*!
Move the cursor up.
The cursor will not be moved beyond the top margin.
*/
void TEScreen::cursorUp(int n)
//=CUU
{
if (n == 0) n = 1; // Default
int stop = cuY < tmargin ? 0 : tmargin;
cuX = QMIN(columns-1,cuX); // nowrap!
cuY = QMAX(stop,cuY-n);
}
/*!
Move the cursor down.
The cursor will not be moved beyond the bottom margin.
*/
void TEScreen::cursorDown(int n)
//=CUD
{
if (n == 0) n = 1; // Default
int stop = cuY > bmargin ? lines-1 : bmargin;
cuX = QMIN(columns-1,cuX); // nowrap!
cuY = QMIN(stop,cuY+n);
}
/*!
Move the cursor left.
The cursor will not move beyond the first column.
*/
void TEScreen::cursorLeft(int n)
//=CUB
{
if (n == 0) n = 1; // Default
cuX = QMIN(columns-1,cuX); // nowrap!
cuX = QMAX(0,cuX-n);
}
/*!
Move the cursor left.
The cursor will not move beyond the rightmost column.
*/
void TEScreen::cursorRight(int n)
//=CUF
{
if (n == 0) n = 1; // Default
cuX = QMIN(columns-1,cuX+n);
}
/*!
Set top and bottom margin.
*/
void TEScreen::setMargins(int top, int bot)
//=STBM
{
if (top == 0) top = 1; // Default
if (bot == 0) bot = lines; // Default
top = top - 1; // Adjust to internal lineno
bot = bot - 1; // Adjust to internal lineno
if ( !( 0 <= top && top < bot && bot < lines ) )
{ fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
__FILE__,__LINE__,top,bot);
return; // Default error action: ignore
}
tmargin = top;
bmargin = bot;
cuX = 0;
cuY = getMode(MODE_Origin) ? top : 0;
}
/*!
Move the cursor down one line.
If cursor is on bottom margin, the region between the
actual top and bottom margin is scrolled up instead.
*/
void TEScreen::index()
//=IND
{
if (cuY == bmargin)
{
if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
scrollUp(tmargin,1);
}
else if (cuY < lines-1)
cuY += 1;
}
/*!
Move the cursor up one line.
If cursor is on the top margin, the region between the
actual top and bottom margin is scrolled down instead.
*/
void TEScreen::reverseIndex()
//=RI
{
if (cuY == tmargin)
scrollDown(tmargin,1);
else if (cuY > 0)
cuY -= 1;
}
/*!
Move the cursor to the begin of the next line.
If cursor is on bottom margin, the region between the
actual top and bottom margin is scrolled up.
*/
void TEScreen::NextLine()
//=NEL
{
Return(); index();
}
// Line Editing ----------------------------------------------------------------
/*! \section inserting / deleting characters
*/
/*! erase `n' characters starting from (including) the cursor position.
The line is filled in from the right with spaces.
*/
void TEScreen::eraseChars(int n)
{
if (n == 0) n = 1; // Default
int p = QMAX(0,QMIN(cuX+n-1,columns-1));
clearImage(loc(cuX,cuY),loc(p,cuY),' ');
}
/*! delete `n' characters starting from (including) the cursor position.
The line is filled in from the right with spaces.
*/
void TEScreen::deleteChars(int n)
{
if (n == 0) n = 1; // Default
int p = QMAX(0,QMIN(cuX+n,columns-1));
moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
}
/*! insert `n' spaces at the cursor position.
The cursor is not moved by the operation.
*/
void TEScreen::insertChars(int n)
{
if (n == 0) n = 1; // Default
int p = QMAX(0,QMIN(columns-1-n,columns-1));
int q = QMAX(0,QMIN(cuX+n,columns-1));
moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
}
/*! delete `n' lines starting from (including) the cursor position.
The cursor is not moved by the operation.
*/
void TEScreen::deleteLines(int n)
{
if (n == 0) n = 1; // Default
scrollUp(cuY,n);
}
/*! insert `n' lines at the cursor position.
The cursor is not moved by the operation.
*/
void TEScreen::insertLines(int n)
{
if (n == 0) n = 1; // Default
scrollDown(cuY,n);
}
// Mode Operations -----------------------------------------------------------
/*! Set a specific mode. */
void TEScreen::setMode(int m)
{
currParm.mode[m] = TRUE;
switch(m)
{
case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
}
}
/*! Reset a specific mode. */
void TEScreen::resetMode(int m)
{
currParm.mode[m] = FALSE;
switch(m)
{
case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
}
}
/*! Save a specific mode. */
void TEScreen::saveMode(int m)
{
saveParm.mode[m] = currParm.mode[m];
}
/*! Restore a specific mode. */
void TEScreen::restoreMode(int m)
{
currParm.mode[m] = saveParm.mode[m];
}
//NOTE: this is a helper function
/*! Return the setting a specific mode. */
BOOL TEScreen::getMode(int m)
{
return currParm.mode[m];
}
/*! Save the cursor position and the rendition attribute settings. */
void TEScreen::saveCursor()
{
sa_cuX = cuX;
sa_cuY = cuY;
sa_cu_re = cu_re;
sa_cu_fg = cu_fg;
sa_cu_bg = cu_bg;
}
/*! Restore the cursor position and the rendition attribute settings. */
void TEScreen::restoreCursor()
{
cuX = QMIN(sa_cuX,columns-1);
cuY = QMIN(sa_cuY,lines-1);
cu_re = sa_cu_re;
cu_fg = sa_cu_fg;
cu_bg = sa_cu_bg;
effectiveRendition();
}
/* ------------------------------------------------------------------------- */
/* */
/* Screen Operations */
/* */
/* ------------------------------------------------------------------------- */
/*! Assing a new size to the screen.
The topmost left position is maintained, while lower lines
or right hand side columns might be removed or filled with
spaces to fit the new size.
The region setting is reset to the whole screen and the
tab positions reinitialized.
*/
void TEScreen::resizeImage(int new_lines, int new_columns)
{
if (cuY > new_lines-1) {
// attempt to preserve focus and lines
bmargin = lines-1; //FIXME: margin lost
for (int i = 0; i < cuY-(new_lines-1); i++) {
addHistLine(); scrollUp(horzCursor,1);
}
}
// make new image
ca* newimg = (ca*)malloc( new_lines * new_columns * sizeof( ca));
clearSelection();
// clear new image
for (int y = 0; y < new_lines; y++)
for (int x = 0; x < new_columns; x++) {
newimg[y*new_columns+x].c = ' ';
newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
newimg[y*new_columns+x].r = DEFAULT_RENDITION;
}
int cpy_lines = QMIN(new_lines, lines);
int cpy_columns = QMIN(new_columns,columns);
// copy to new image
for (int y = 0; y < cpy_lines; y++)
for (int x = 0; x < cpy_columns; x++) {
newimg[y*new_columns+x].c = image[loc(x,y)].c;
newimg[y*new_columns+x].f = image[loc(x,y)].f;
newimg[y*new_columns+x].b = image[loc(x,y)].b;
newimg[y*new_columns+x].r = image[loc(x,y)].r;
}
free(image);
image = newimg;
lines = new_lines;
columns = new_columns;
cuX = QMIN(cuX,columns-1);
cuY = QMIN(cuY,lines-1);
// FIXME: try to keep values, evtl.
tmargin=0;
bmargin=lines-1;
initTabStops();
clearSelection();
}
/*
Clarifying rendition here and in TEWidget.
currently, TEWidget's color table is
0 1 2 .. 9 10 .. 17
dft_fg, dft_bg, dim 0..7, intensive 0..7
cu_fg, cu_bg contain values 0..8;
- 0 = default color
- 1..8 = ansi specified color
re_fg, re_bg contain values 0..17
due to the TEWidget's color table
rendition attributes are
attr widget screen
-------------- ------ ------
RE_UNDERLINE XX XX affects foreground only
RE_BLINK XX XX affects foreground only
RE_BOLD XX XX affects foreground only
RE_REVERSE -- XX
RE_TRANSPARENT XX -- affects background only
RE_INTENSIVE XX -- affects foreground only
Note that RE_BOLD is used in both widget
and screen rendition. Since xterm/vt102
is to poor to distinguish between bold
(which is a font attribute) and intensive
(which is a color attribute), we translate
this and RE_BOLD in falls eventually appart
into RE_BOLD and RE_INTENSIVE.
*/
void TEScreen::reverseRendition(ca* p)
{ UINT8 f = p->f; UINT8 b = p->b;
p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
}
void TEScreen::effectiveRendition()
// calculate rendition
{
ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
if (cu_re & RE_REVERSE)
{
ef_fg = cu_bg;
ef_bg = cu_fg;
}
else
{
ef_fg = cu_fg;
ef_bg = cu_bg;
}
if (cu_re & RE_BOLD)
{
if (ef_fg < BASE_COLORS)
ef_fg += BASE_COLORS;
else
ef_fg -= BASE_COLORS;
}
}
/*!
returns the image.
Get the size of the image by \sa getLines and \sa getColumns.
NOTE that the image returned by this function must later be
freed.
*/
ca* TEScreen::getCookedImage()
{
int x,y;
ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
+ if (histCursor > hist.getLines()) {
+ histCursor = hist.getLines();
+ }
+
for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
{
int len = QMIN(columns,hist.getLineLen(y+histCursor));
int yp = y*columns;
int yq = (y+histCursor)*columns;
hist.getCells(y+histCursor,0,len,merged+yp);
for (x = len; x < columns; x++) merged[yp+x] = dft;
for (x = 0; x < columns; x++)
{ int p=x + yp; int q=x + yq;
if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
reverseRendition(&merged[p]); // for selection
}
}
if (lines >= hist.getLines()-histCursor)
{
for (y = (hist.getLines()-histCursor); y < lines ; y++)
{
int yp = y*columns;
int yq = (y+histCursor)*columns;
int yr = (y-hist.getLines()+histCursor)*columns;
for (x = 0; x < columns; x++)
{ int p = x + yp; int q = x + yq; int r = x + yr;
merged[p] = image[r];
if ( q >= sel_TL && q <= sel_BR )
reverseRendition(&merged[p]); // for selection
}
}
}
// evtl. inverse display
if (getMode(MODE_Screen))
{ int i,n = lines*columns;
for (i = 0; i < n; i++)
reverseRendition(&merged[i]); // for reverse display
}
if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
return merged;
}
/*!
*/
void TEScreen::reset()
{
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
cfg.setGroup("ScrollBar");
if( !cfg.readBoolEntry("HorzScroll",0) )
setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
setMode(MODE_Cursor); // cursor visible
resetMode(MODE_Screen); // screen not inverse
resetMode(MODE_NewLine);
tmargin=0;
bmargin=lines-1;
setDefaultRendition();
saveCursor();
clear();
}
/*! Clear the entire screen and home the cursor.
*/
void TEScreen::clear()
{
clearEntireScreen();
home();
}
/*! Moves the cursor left one column.
*/
void TEScreen::BackSpace()
{
cuX = QMAX(0,cuX-1);
if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
}
/*!
*/
void TEScreen::Tabulate()
{
// note that TAB is a format effector (does not write ' ');
cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
}
void TEScreen::clearTabStops()
{
for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
}
void TEScreen::changeTabStop(bool set)
{
if (cuX >= columns) return;
tabstops[cuX] = set;
}
void TEScreen::initTabStops()
{
if (tabstops) free(tabstops);
tabstops = (bool*)malloc(columns*sizeof(bool));
// Arrg! The 1st tabstop has to be one longer than the other.
// i.e. the kids start counting from 0 instead of 1.
// Other programs might behave correctly. Be aware.
for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
}
/*!
This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
depending on the NewLine Mode (LNM). This mode also
affects the key sequence returned for newline ([CR]LF).
*/
void TEScreen::NewLine()
{
if (getMode(MODE_NewLine)) Return();
index();
}
/*! put `c' literally onto the screen at the current cursor position.
VT100 uses the convention to produce an automatic newline (am)
with the *first* character that would fall onto the next line (xenl).
*/
void TEScreen::checkSelection(int from, int to)
{
if (sel_begin == -1) return;
int scr_TL = loc(0, hist.getLines());
//Clear entire selection if it overlaps region [from, to]
if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
{
clearSelection();
}
}
void TEScreen::ShowCharacter(unsigned short c)
{
// Note that VT100 does wrapping BEFORE putting the character.
// This has impact on the assumption of valid cursor positions.
// We indicate the fact that a newline has to be triggered by
// putting the cursor one right to the last column of the screen.
if (cuX >= columns)
{
if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1;
// comment out for no wrap
}
if (getMode(MODE_Insert)) insertChars(1);
int i = loc( cuX, cuY);
checkSelection(i, i); // check if selection is still valid.
image[i].c = c;
image[i].f = ef_fg;
image[i].b = ef_bg;
image[i].r = ef_re;
cuX += 1;
}
// Region commands -------------------------------------------------------------
/*! scroll up `n' lines within current region.
The `n' new lines are cleared.
\sa setRegion \sa scrollDown
*/
void TEScreen::scrollUp(int from, int n)
{
if (n <= 0 || from + n > bmargin) return;
//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin));
clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' ');
}
/*! scroll down `n' lines within current region.
The `n' new lines are cleared.
\sa setRegion \sa scrollUp
*/
void TEScreen::scrollDown(int from, int n)
{
//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
if (n <= 0) return;
if (from > bmargin) return;
if (from + n > bmargin) n = bmargin - from;
moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n));
clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
}
/*! position the cursor to a specific line and column. */
void TEScreen::setCursorYX(int y, int x)
{
setCursorY(y); setCursorX(x);
}
/*! Set the cursor to x-th line. */
void TEScreen::setCursorX(int x)
{
if (x == 0) x = 1; // Default
x -= 1; // Adjust
cuX = QMAX(0,QMIN(columns-1, x));
}
/*! Set the cursor to y-th line. */
void TEScreen::setCursorY(int y)
{
if (y == 0) y = 1; // Default
y -= 1; // Adjust
cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
}
/*! set cursor to the `left upper' corner of the screen (1,1).
*/
void TEScreen::home()
{
cuX = 0;
cuY = 0;
}
/*! set cursor to the begin of the current line.
*/
void TEScreen::Return()
{
cuX = 0;
}
/*! returns the current cursor columns.
*/
int TEScreen::getCursorX()
{
return cuX;
}
/*! returns the current cursor line.
*/
int TEScreen::getCursorY()
{
return cuY;
}
// Erasing ---------------------------------------------------------------------
/*! \section Erasing
This group of operations erase parts of the screen contents by filling
it with spaces colored due to the current rendition settings.
Althought the cursor position is involved in most of these operations,
it is never modified by them.
*/
/*! fill screen between (including) `loca' and `loce' with spaces.
This is an internal helper functions. The parameter types are internal
addresses of within the screen image and make use of the way how the
screen matrix is mapped to the image vector.
*/
void TEScreen::clearImage(int loca, int loce, char c)
{ int i;
int scr_TL=loc(0,hist.getLines());
//FIXME: check positions
//Clear entire selection if it overlaps region to be moved...
if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
{
clearSelection();
}
for (i = loca; i <= loce; i++)
{
image[i].c = c;
image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
}
}
/*! move image between (including) `loca' and `loce' to 'dst'.
This is an internal helper functions. The parameter types are internal
addresses of within the screen image and make use of the way how the
screen matrix is mapped to the image vector.
*/
void TEScreen::moveImage(int dst, int loca, int loce)
{
//FIXME: check positions
if (loce < loca) {
// kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
return;
}
memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
}
/*! clear from (including) current cursor position to end of screen.
*/
void TEScreen::clearToEndOfScreen()
{
clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
}
/*! clear from begin of screen to (including) current cursor position.
*/
void TEScreen::clearToBeginOfScreen()
{
clearImage(loc(0,0),loc(cuX,cuY),' ');
}
/*! clear the entire screen.
*/
void TEScreen::clearEntireScreen()
{
clearImage(loc(0,0),loc(columns-1,lines-1),' ');
}
/*! fill screen with 'E'
This is to aid screen alignment
*/
void TEScreen::helpAlign()
{
clearImage(loc(0,0),loc(columns-1,lines-1),'E');
}
/*! clear from (including) current cursor position to end of current cursor line.
*/
void TEScreen::clearToEndOfLine()
{
clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
}
/*! clear from begin of current cursor line to (including) current cursor position.
*/
void TEScreen::clearToBeginOfLine()
{
clearImage(loc(0,cuY),loc(cuX,cuY),' ');
}
/*! clears entire current cursor line
*/
void TEScreen::clearEntireLine()
{
clearImage( loc( 0, cuY),loc( columns - 1, cuY),' ');
}
// Rendition ------------------------------------------------------------------
/*!
set rendition mode
*/
void TEScreen::setRendition(int re)
{
cu_re |= re;
effectiveRendition();
}
/*!
reset rendition mode
*/
void TEScreen::resetRendition(int re)
{
cu_re &= ~re;
effectiveRendition();
}
/*!
*/
void TEScreen::setDefaultRendition()
{
setForeColorToDefault();
setBackColorToDefault();
cu_re = DEFAULT_RENDITION;
effectiveRendition();
}
/*!
*/
void TEScreen::setForeColor(int fgcolor)
{
cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
effectiveRendition();
}
/*!
*/
void TEScreen::setBackColor(int bgcolor)
{
cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
effectiveRendition();
}
/*!
*/
void TEScreen::setBackColorToDefault()
{
cu_bg = DEFAULT_BACK_COLOR;
effectiveRendition();
}
/*!
*/
void TEScreen::setForeColorToDefault()
{
cu_fg = DEFAULT_FORE_COLOR;
effectiveRendition();
}
/* ------------------------------------------------------------------------- */
/* */
/* Marking & Selection */
/* */
/* ------------------------------------------------------------------------- */
void TEScreen::clearSelection()
{
sel_BR = -1;
sel_TL = -1;
sel_begin = -1;
}
void TEScreen::setSelBeginXY(const int x, const int y)
{
+ if (histCursor > hist.getLines()) {
+ histCursor = hist.getLines();
+ }
sel_begin = loc(x,y+histCursor) ;
sel_BR = sel_begin;
sel_TL = sel_begin;
}
void TEScreen::setSelExtentXY(const int x, const int y)
{
if (sel_begin == -1) return;
+ if (histCursor > hist.getLines()) {
+ histCursor = hist.getLines();
+ }
int l = loc(x,y + histCursor);
if (l < sel_begin)
{
sel_TL = l;
sel_BR = sel_begin;
}
else
{
/* FIXME, HACK to correct for x too far to the right... */
if (( x == columns )|| (x == 0)) l--;
sel_TL = sel_begin;
sel_BR = l;
}
}
QString TEScreen::getSelText(const BOOL preserve_line_breaks)
{
if (sel_begin == -1)
return QString::null; // Selection got clear while selecting.
int *m; // buffer to fill.
int s, d; // source index, dest. index.
int hist_BR = loc(0, hist.getLines());
int hY = sel_TL / columns;
int hX = sel_TL % columns;
int eol; // end of line
s = sel_TL; // tracks copy in source.
// allocate buffer for maximum
// possible size...
d = (sel_BR - sel_TL) / columns + 1;
m = new int[d * (columns + 1) + 2];
d = 0;
while (s <= sel_BR)
{
if (s < hist_BR)
{ // get lines from hist.history
// buffer.
eol = hist.getLineLen(hY);
if ((hY == (sel_BR / columns)) &&
(eol >= (sel_BR % columns)))
{
eol = sel_BR % columns + 1;
}
while (hX < eol)
{
m[d++] = hist.getCell(hY, hX++).c;
s++;
}
if (s <= sel_BR)
{
// The line break handling
// It's different from the screen
// image case!
if (eol % columns == 0)
{
// That's either a completely filled
// line or an empty line
if (eol == 0)
{
m[d++] = '\n';
}
else
{
// We have a full line.
// FIXME: How can we handle newlines
// at this position?!
}
}
else if ((eol + 1) % columns == 0)
{
// FIXME: We don't know if this was a
// space at the last position or a
// short line!!
m[d++] = ' ';
}
else
{
// We have a short line here. Put a
// newline or a space into the
// buffer.
m[d++] = preserve_line_breaks ? '\n' : ' ';
}
}
hY++;
hX = 0;
s = hY * columns;
}
else
{ // or from screen image.
eol = (s / columns + 1) * columns - 1;
if (eol < sel_BR)
{
while ((eol > s) &&
isspace(image[eol - hist_BR].c))
{
eol--;
}
}
else
{
eol = sel_BR;
}
while (s <= eol)
{
m[d++] = image[s++ - hist_BR].c;
}
if (eol < sel_BR)
{
// eol processing see below ...
if ((eol + 1) % columns == 0)
{
if (image[eol - hist_BR].c == ' ')
{
m[d++] = ' ';
}
}
else
{
m[d++] = ((preserve_line_breaks ||
((eol % columns) == 0)) ?
'\n' : ' ');
}
}
s = (eol / columns + 1) * columns;
}
}
QChar* qc = new QChar[d];
for (int i = 0; i < d; i++)
{
qc[i] = m[i];
}
QString res(qc, d);
delete m;
delete qc;
return res;
}
/* above ... end of line processing for selection -- psilva
cases:
1) (eol+1)%columns == 0 --> the whole line is filled.
If the last char is a space, insert (preserve) space. otherwise
leave the text alone, so that words that are broken by linewrap
are preserved.
FIXME:
* this suppresses \n for command output that is
sized to the exact column width of the screen.
2) eol%columns == 0 --> blank line.
insert a \n unconditionally.
Do it either you would because you are in preserve_line_break mode,
or because it's an ASCII paragraph delimiter, so even when
not preserving line_breaks, you want to preserve paragraph breaks.
3) else --> partially filled line
insert a \n in preserve line break mode, else a space
The space prevents concatenation of the last word of one
line with the first of the next.
*/
void TEScreen::addHistLine()
{
assert(hasScroll() || histCursor == 0);
// add to hist buffer
// we have to take care about scrolling, too...
if (hasScroll()){
ca dft;
int end = columns - 1;
while (end >= 0 && image[end] == dft)
end -= 1;
hist.addCells( image, end + 1);
hist.addLine();
// adjust history cursor
histCursor += ( hist.getLines() - 1 == histCursor);
}
if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
}
void TEScreen::setHistCursor(int cursor)
{
histCursor = cursor; //FIXME:rangecheck
+ if (histCursor > hist.getLines()) {
+ histCursor = hist.getLines();
+ }
+ if (histCursor < 0) {
+ histCursor = 0;
+ }
}
void TEScreen::setHorzCursor(int cursor)
{
horzCursor = cursor;
}
int TEScreen::getHistCursor()
{
return histCursor;
}
int TEScreen::getHorzCursor()
{
return horzCursor;
}
int TEScreen::getHistLines()
{
return hist.getLines();
}
void TEScreen::setScroll(bool on)
{
histCursor = 0;
clearSelection();
hist.setScroll(on);
}
bool TEScreen::hasScroll()
{
return hist.hasScroll();
}
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
index ec1b30c..98c3cdf 100644
--- a/core/apps/embeddedkonsole/TEWidget.cpp
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -1,1373 +1,1433 @@
/* ------------------------------------------------------------------------ */
/* */
/* [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 = max width of ASCII chars (U.B.)
- font_w = 0;
- int fw;
- for (int i = 0x20; i < 0x80; i++) {
- if (isprint(i) && font_w < (fw = fm.width(i))) {
- font_w = fw;
- }
- }
//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);
+ // hScrollbar->setMaximumHeight(16);
connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int)));
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
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();
- word_selection_mode = FALSE;
+ 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());
- if(ke->key() == Key_Escape) {
- 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
- if( ke->state() == ShiftButton && ke->key() == Key_Tab) {
- //lets hardcode this sucker
+ case 0x201b: // fn-5
+ case Key_F4:
+ emit toggleFullScreen();
+ break;
+
+ case 0x200f: // fn-1 magnify minus
+ case Key_F5:
+ emit changeFontSize(-1);
+ break;
-// qDebug("key pressed 2 is 0x%x", ke->key());
- emitText("\\"); // expose
+ case 0x2010: // fn-2 magnify plus
+ case Key_F6:
+ emit changeFontSize(1);
+ break;
+
+ default:
+ special_function = false;
}
- else if( ke->state() == ControlButton && ke->key() == Key_V) {
- pasteClipboard();
+ 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();
// }
- else
emit keyPressedSignal(ke); // expose
ke->accept();
#ifdef FAKE_CTRL_AND_ALT
if ( dele ) delete e;
#endif
return true; // stop the event
}
if ( e->type() == QEvent::Enter ) {
QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
this, SLOT(onClearSelection()) );
}
if ( e->type() == QEvent::Leave ) {
QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
this, SLOT(onClearSelection()) );
}
return QFrame::eventFilter( obj, e );
}
/* ------------------------------------------------------------------------- */
/* */
/* Frame */
/* */
/* ------------------------------------------------------------------------- */
void TEWidget::frameChanged()
{
propagateSize();
update();
}
-
/* ------------------------------------------------------------------------- */
/* */
/* Sound */
/* */
/* ------------------------------------------------------------------------- */
void TEWidget::Bell()
{
//#ifdef QT_QWS_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;
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
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/TEWidget.h b/core/apps/embeddedkonsole/TEWidget.h
index 5597f27..792b109 100644
--- a/core/apps/embeddedkonsole/TEWidget.h
+++ b/core/apps/embeddedkonsole/TEWidget.h
@@ -1,204 +1,214 @@
/* ----------------------------------------------------------------------- */
/* */
/* [te_widget.h] 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> */
/* */
/* -------------------------------------------------------------------------- */
#ifndef TE_WIDGET_H
#define TE_WIDGET_H
#include <qwidget.h>
#include <qlabel.h>
#include <qtimer.h>
#include <qcolor.h>
#include <qkeycode.h>
#include <qscrollbar.h>
#include <qpopupmenu.h>
#include "TECommon.h"
extern unsigned short vt100_graphics[32];
class TESession;
// class Konsole;
class TEWidget : public QFrame
// a widget representing attributed text
-{ Q_OBJECT
+{
+ Q_OBJECT
// friend class Konsole;
public:
TEWidget(QWidget *parent=0, const char *name=0);
virtual ~TEWidget();
public:
QColor getDefaultBackColor();
const ColorEntry* getColorTable() const;
const ColorEntry* getdefaultColorTable() const;
void setColorTable(const ColorEntry table[]);
void setScrollbarLocation(int loc);
enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 };
void setScroll(int cursor, int lines);
void doScroll(int lines);
void doHScroll(int lines);
void emitSelection();
void setWrapAt(int columns);
void setImage(const ca* const newimg, int lines, int columns);
int Lines() { return lines; }
int Columns() { return columns; }
void calcGeometry();
void propagateSize();
QSize calcSize(int cols, int lins) const;
QSize sizeHint() const;
bool useHorzScroll;
bool useBeep;
+ int color_menu_item;
void Bell();
void emitText(QString text);
void pasteClipboard();
signals:
void keyPressedSignal(QKeyEvent *e);
void mouseSignal(int cb, int cx, int cy);
void changedImageSizeSignal(int lines, int columns);
void changedHistoryCursor(int value);
void changedHorzCursor(int value);
void configureRequest( TEWidget*, int state, int x, int y );
void clearSelectionSignal();
void beginSelectionSignal( const int x, const int y );
void extendSelectionSignal( const int x, const int y );
void endSelectionSignal(const BOOL preserve_line_breaks);
+ void changeFontSize(int);
+ void toggleFullScreen();
+ void setFullScreen(bool);
+ void changeSession(int);
+ void newSession();
protected:
virtual void styleChange( QStyle& );
bool eventFilter( QObject *, QEvent * );
void drawAttrStr(QPainter &paint, QRect rect,
QString& str, ca attr, BOOL pm, BOOL clear);
void paintEvent( QPaintEvent * );
void resizeEvent(QResizeEvent*);
void fontChange(const QFont &font);
void frameChanged();
void mouseDoubleClickEvent(QMouseEvent* ev);
void mousePressEvent( QMouseEvent* );
void mouseReleaseEvent( QMouseEvent* );
void mouseMoveEvent( QMouseEvent* );
void focusInEvent( QFocusEvent * );
void focusOutEvent( QFocusEvent * );
bool focusNextPrevChild( bool next );
#ifndef QT_NO_DRAGANDDROP
// Dnd
void dragEnterEvent(QDragEnterEvent* event);
void dropEvent(QDropEvent* event);
#endif
virtual int charClass(char) const;
void clearImage();
public:
const QPixmap *backgroundPixmap();
void setSelection(const QString &t);
virtual void setFont(const QFont &);
void setVTFont(const QFont &);
QFont getVTFont();
void setMouseMarks(bool on);
public slots:
void onClearSelection();
protected slots:
void scrollChanged(int value);
void hScrollChanged(int value);
void blinkEvent();
private:
QChar (*fontMap)(QChar); // possible vt100 font extention
- bool fixed_font; // has fixed pitch
+ // bool fixed_font; // has fixed pitch
int font_h; // height
int font_w; // width
int font_a; // ascend
int blX; // actual offset (left)
int brX; // actual offset (right)
int bY; // actual offset
int lines;
int columns;
ca *image; // [lines][columns]
ColorEntry color_table[TABLE_COLORS];
BOOL resizing;
bool mouse_marks;
void makeImage();
QPoint iPntSel; // initial selection point
QPoint pntSel; // current selection point
int actSel; // selection state
BOOL word_selection_mode;
BOOL preserve_line_breaks;
QClipboard* cb;
QScrollBar* scrollbar, *hScrollbar;
int scrollLoc, hScrollLoc;
int hposition, vcolumns;
+ int mouse_down_x, mouse_down_y;
//#define SCRNONE 0
//#define SCRLEFT 1
//#define SCRRIGHT 2
BOOL blinking; // hide text in paintEvent
BOOL hasBlinker; // has characters to blink
QTimer* blinkT; // active when hasBlinker
QPopupMenu* m_drop;
QString dropText;
+
public:
// current session in this widget
TESession *currentSession;
+
private slots:
void drop_menu_activated(int item);
};
#endif // TE_WIDGET_H
diff --git a/core/apps/embeddedkonsole/TEmulation.cpp b/core/apps/embeddedkonsole/TEmulation.cpp
index c19f2a1..a539757 100644
--- a/core/apps/embeddedkonsole/TEmulation.cpp
+++ b/core/apps/embeddedkonsole/TEmulation.cpp
@@ -1,378 +1,379 @@
/* -------------------------------------------------------------------------- */
/* */
/* [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 dd35466..03cba87 100644
--- a/core/apps/embeddedkonsole/commandeditdialog.cpp
+++ b/core/apps/embeddedkonsole/commandeditdialog.cpp
@@ -1,199 +1,199 @@
//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");
+ Config cfg("Qkonsole");
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");
+ Config *cfg = new Config("Qkonsole");
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/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp
index ce8fb6b..d10b66d 100644
--- a/core/apps/embeddedkonsole/konsole.cpp
+++ b/core/apps/embeddedkonsole/konsole.cpp
@@ -1,1176 +1,1918 @@
+
/* ---------------------------------------------------------------------- */
/* */
/* [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>
//#define QT_QWS_OPIE
-#include "signal.h"
+#include <stdlib.h>
#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 <qpe/config.h>
-#include <qpe/qpeapplication.h>
+#include <qfontdatabase.h>
+#include <qfile.h>
+#include <qspinbox.h>
+#include <qlayout.h>
+#include <qvbox.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <sys/types.h>
-//#include <sys/wait.h>
+#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "konsole.h"
#include "keytrans.h"
#include "commandeditdialog.h"
#ifdef QT_QWS_OPIE
#include <opie/colorpopupmenu.h>
#endif
-#include <qfontdatabase.h> // U.B.
-#include <qstringlist.h> // U.B.
-#include <qvaluelist.h> // U.B.
-
-class EKNumTabBar : public QTabBar {
+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++) {
+ 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 ) {
+ for( QTab* t; (t=it.current()); ++it )
+ {
int tx = t->rect().x();
- if ( tx<x && tx>m ) {
+ if ( tx<x && tx>m )
+ {
x = tx;
left = t;
}
}
- if ( left ) {
+ 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 {
+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
-
-// signal (SIGSTOP, SIG_IGN);
-
-// 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();
- }
-
-// qWarning("SHELL now is %s", *shell );
-
- 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;
-
- setCaption( tr("Terminal") );
+ QStrList args;
+ init("/bin/bash",args);
+}
- konsoleInit( &shell);
-// qWarning("Using shell %s", 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");
+ Config cfg("Qkonsole");
cfg.setGroup("Commands");
- commonCombo->setInsertionPolicy(QComboBox::AtCurrent);
+ // commonCombo->setInsertionPolicy(QComboBox::AtCurrent);
commonCombo->clear();
- if (cfg.readEntry("Commands Set","FALSE") == "FALSE") {
- for (int i = 0; commonCmds[i] != NULL; i++) {
- commonCombo->insertItem(commonCmds[i],i);
+
+ 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;
}
- } else {
- for (int i = 0; i < 100; i++) {
+ 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),"")));
+ 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("Terminal") );
- setIcon( Resource::loadPixmap( "konsole" ) );
+ setCaption( "Qkonsole" );
+ setIcon( Resource::loadPixmap( "qkonsole/qkonsole" ) );
- Config cfg("Konsole");
- cfg.setGroup("Konsole");
+ Config cfg("Qkonsole");
+ cfg.setGroup("Font");
QString tmp;
- // initialize the list of allowed fonts ///////////////////////////////////
- cfont = cfg.readNumEntry("FontID", 1);
-
- QFont f = QFont("Micro", 4, QFont::Normal);
- f.setFixedPitch(TRUE);
- fonts.append(new VTFont(tr("Micro"), f));
- f = QFont("Fixed", 7, QFont::Normal);
- f.setFixedPitch(TRUE);
- fonts.append(new VTFont(tr("Small Fixed"), f));
+ // initialize the list of allowed fonts ///////////////////////////////////
- f = QFont("Fixed", 12, QFont::Normal);
- f.setFixedPitch(TRUE);
- fonts.append(new VTFont(tr("Medium Fixed"), f));
+ QString cfgFontName = cfg.readEntry("FontName","Lcfont");
+ int cfgFontSize = cfg.readNumEntry("FontSize",18);
-// NEW STUFF
+ cfont = -1;
- QStringList ignfont = cfg.readListEntry("IgnFont", ',');
- /* If there is no "IgnFont = ..." entry in "myonsole.conf",
- * put some Japanese fonts of the SL-C7x0 to "ignfont". */
+ // 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 );
- if (ignfont.isEmpty()) {
- ignfont = QStringList::split (',',"jisupasp,mmkjg1,mmkjg4,mmkjg5");
+ 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();
-// QFont
- f = QFont("Fixed", 16, QFont::Normal);
- f.setFixedPitch(true);
- fonts.append(new VTFont(tr("Default"), f));
-
- int fcount = 1;
+ QValueList<int> sizes = fontDB.pointSizes( familyNames[j] );
- f.setCharSet(QFont::AnyCharSet);
- f.setStyleHint(QFont::TypeWriter, QFont::PreferMatch);
-// f.setWeight(QFont::Normal);
+ printf("family[%d] = %s with %d sizes\n", j, familyNames[j].latin1(),
+ sizes.count());
- /*
- * Look for installed font families. If the family is not in
- * the "ignfont" list, look for available sizes.
- * If it is fixed pitch font, put the font and the size
- * to the fontlist.
- */
- QFontDatabase fdb;
- QStringList ff = fdb.families(false);
-
- for (QStringList::Iterator it = ff.begin(); it != ff.end(); ++it ) {
- QString fit = *it;
+ if (sizes.count() > 0)
+ {
+ QPopupMenu *sizeMenu;
+ QFont f;
+ int last_width = -1;
+ sizeMenu = NULL;
- if( fit != "fixed" && fit != "micro" ) {
- if ( ignfont.contains(*it) == 0) {
- QValueList<int> pt = fdb.pointSizes(*it);
+ 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;
- for (QValueList<int>::Iterator itv = pt.begin();
- itv != pt.end(); ++itv ) {
- int size = (*itv)/10;
- if(size > 0) {
- f.setFamily(*it);
- f.setPointSize(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];
+ }
+#ifndef __i386__
+ // a hack, sizes on Z seem to be points*10
+ size /= 10;
+#endif
- QFontMetrics fm(f);
-
-//qDebug("%s %d:\twidth('i')=%d, width('w')=%d", (*it).latin1(), (*itv)/10, fm.width('i'), fm.width('w'));
-
- if (fm.width('i') == fm.width('w') ) {
- qDebug((*it));
+ f = QFont(familyNames[j], size);
f.setFixedPitch(true);
- fonts.append(new VTFont(*it + ' ' + QString::number(size), f));
- fcount++;
+ 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++;
+ }
}
-// END NEW STUFF
+ }
+ 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 );
- QToolBar *menuToolBar = new QToolBar( this );
+ menuToolBar = new QToolBar( this );
menuToolBar->setHorizontalStretchable( TRUE );
QMenuBar *menuBar = new QMenuBar( menuToolBar );
- fontList = new QPopupMenu( this );
- for(uint i = 0; i < fonts.count(); i++) {
- VTFont *fnt = fonts.at(i);
- fontList->insertItem(fnt->getName(), i);
+ 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);
- fontChanged(cfont);
+ 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") {
- editCommandListMenu->insertItem( tr( "Show command list" ));
+ if( cfg.readEntry("Hidden","FALSE") == "TRUE")
+ {
+ ec_cmdlist = editCommandListMenu->insertItem( tr( "Show command list" ));
listHidden=TRUE;
- } else {
- editCommandListMenu->insertItem( tr( "Hide command list" ));
+ }
+ else
+ {
+ ec_cmdlist = editCommandListMenu->insertItem( tr( "Hide command list" ));
listHidden=FALSE;
}
cfg.setGroup("Tabs");
- tmp=cfg.readEntry("Position","Bottom");
- if(tmp=="Top") {
+
+ 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);
- configMenu->insertItem( tr( "Tabs on Bottom" ) );
- } else {
+ tab->getTabBar()->show();
+ tabPos = tm_top;
+ }
+ else if (tmp=="Bottom")
+ {
tab->setTabPosition(QTabWidget::Bottom);
- configMenu->insertItem(tr("Tabs on Top"));
- }
- configMenu->insertSeparator(2);
-
- colorMenu->insertItem(tr( "Green on Black"));
- colorMenu->insertItem(tr( "Black on White"));
- colorMenu->insertItem(tr( "White on Black"));
- colorMenu->insertItem(tr( "Black on Transparent"));
- colorMenu->insertItem(tr( "Black on Red"));
- colorMenu->insertItem(tr( "Red on Black"));
- colorMenu->insertItem(tr( "Green on Yellow"));
- colorMenu->insertItem(tr( "Blue on Magenta"));
- colorMenu->insertItem(tr( "Magenta on Blue"));
- colorMenu->insertItem(tr( "Cyan on White"));
- colorMenu->insertItem(tr( "White on Cyan"));
- colorMenu->insertItem(tr( "Blue on Black"));
- colorMenu->insertItem(tr( "Amber on Black"));
+ 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("Font"), fontList );
configMenu->insertItem(tr( "Colors") ,colorMenu);
- connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) ));
+ sessionList = new QPopupMenu(this);
+ sessionList-> insertItem ( Resource::loadPixmap ( "qkonsole/qkonsole" ), 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("Options"), configMenu );
+ menuBar->insertItem( tr("View"), configMenu );
+ menuBar->insertItem( tr("Fonts"), fontList );
+ menuBar->insertItem( tr("Sessions"), sessionList );
- QToolBar *toolbar = new QToolBar( this );
+ toolBar = new QToolBar( this );
QAction *a;
// Button Commands
- a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 );
- connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar );
+ a = new QAction( tr("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 );
+ 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 );
+ 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 );
+ 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 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolBar );
a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 );
- connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
- a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
- connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar );
-/*
- a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 );
- connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
- a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 );
- connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
+ 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);
+ // commonCombo->setMaximumWidth(236);
- editCommandListMenu->insertItem( tr( "Quick Edit" ) );
- if( listHidden) {
+ ec_quick = editCommandListMenu->insertItem( tr( "Quick Edit" ) );
+ if( listHidden)
+ {
secondToolBar->hide();
- editCommandListMenu->setItemEnabled(-23 ,FALSE);
+ editCommandListMenu->setItemEnabled(ec_quick ,FALSE);
}
- editCommandListMenu->insertItem(tr( "Edit" ) );
+ 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) ));
- scrollMenu->insertItem(tr( "None" ));
- scrollMenu->insertItem(tr( "Left" ));
- scrollMenu->insertItem(tr( "Right" ));
+ 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);
- int jut = configMenu->insertItem(tr( "Wrap" ));
+ configMenu->insertItem(tr( "History" ), this, SLOT(historyDialog()));
+
+ cm_wrap = configMenu->insertItem(tr( "Wrap" ));
cfg.setGroup("ScrollBar");
- configMenu->setItemChecked(jut, cfg.readBoolEntry("HorzScroll",0));
+ configMenu->setItemChecked(cm_wrap, cfg.readBoolEntry("HorzScroll",0));
- jut = configMenu->insertItem(tr( "Use Beep" ));
+ cm_beep = configMenu->insertItem(tr( "Use Beep" ));
cfg.setGroup("Menubar");
+ configMenu->setItemChecked(cm_beep, cfg.readBoolEntry("useBeep",0));
- configMenu->setItemChecked(jut, 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);
+ {
+ 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 ) {
+ if ( !nsessions )
+ {
newSession();
}
QMainWindow::show();
}
void Konsole::initSession(const char*, QStrList &)
{
QMainWindow::show();
}
Konsole::~Konsole()
{
- while (nsessions > 0) {
- doneSession(getTe()->currentSession, 0);
+ 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("Qkonsole");
+ 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);
+ }
}
- Config cfg("Konsole");
- cfg.setGroup("Konsole");
- cfg.writeEntry("FontID", cfont);
+int Konsole::findFont(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("Qkonsole");
+ 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++) {
+ 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) {
+ if (te != 0)
+ {
te->setVTFont(font->getFont());
}
}
}
+#endif
void Konsole::enterCommand(int c)
{
TEWidget* te = getTe();
- if (te != 0) {
- if(!commonCombo->editable()) {
+ if (te != 0)
+ {
+ if(!commonCombo->editable())
+ {
QString text = commonCombo->text(c); //commonCmds[c];
te->emitText(text);
- } else {
+ }
+ else
+ {
changeCommand( commonCombo->text(c), c);
}
}
}
void Konsole::hitEnter()
{
TEWidget* te = getTe();
- if (te != 0) {
+ if (te != 0)
+ {
te->emitText(QString("\r"));
}
}
void Konsole::hitSpace()
{
TEWidget* te = getTe();
- if (te != 0) {
+ if (te != 0)
+ {
te->emitText(QString(" "));
}
}
void Konsole::hitTab()
{
TEWidget* te = getTe();
- if (te != 0) {
+ if (te != 0)
+ {
te->emitText(QString("\t"));
}
}
void Konsole::hitPaste()
{
TEWidget* te = getTe();
- if (te != 0) {
+ if (te != 0)
+ {
te->pasteClipboard();
}
}
void Konsole::hitUp()
{
TEWidget* te = getTe();
- if (te != 0) {
+ 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) {
+ 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) {
+QSize Konsole::calcSize(int columns, int lines)
+{
TEWidget* te = getTe();
- if (te != 0) {
+ if (te != 0)
+ {
QSize size = te->calcSize(columns, lines);
return size;
- } else {
+ }
+ 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 {
+ }
+ 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
+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(TESession*, int )
+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)
{
- TEWidget *te = getTe();
- if (te != 0) {
te->currentSession->setConnect(FALSE);
tab->removeTab(te);
delete te->currentSession;
delete te;
+ sessionList->removeItem(nsessions);
nsessions--;
}
-
- if (nsessions == 0) {
+ if (nsessions == 0)
+ {
close();
}
}
-void Konsole::newSession() {
- if(nsessions < 15) { // seems to be something weird about 16 tabs on the Zaurus.... memory?
+void Konsole::changeTitle(TEWidget* te, QString newTitle )
+{
+ if (te == getTe())
+ {
+ setCaption(newTitle + " - QKonsole");
+ }
+}
+
+
+void Konsole::newSession()
+{
+ if(nsessions < 15)
+ { // seems to be something weird about 16 tabs on the Zaurus.... memory?
TEWidget* te = new TEWidget(tab);
- Config c("Konsole");
- c.setGroup("Menubar");
- te->useBeep=c.readBoolEntry("useBeep",0);
+ Config cfg("Qkonsole");
+ 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(TESession*,int)), this, SLOT(doneSession(TESession*,int)) );
+ connect( se, SIGNAL(done(TEWidget*,int)), this, SLOT(doneSession(TEWidget*,int)) );
+ connect( se, SIGNAL(changeTitle(TEWidget*,QString)), this,
+ SLOT(changeTitle(TEWidget*,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);
- tab->setCurrentPage(nsessions);
nsessions++;
+ sessionList->insertItem(QString::number(nsessions), nsessions);
+ sessionListSelected(nsessions);
doWrap();
- setColor();
+ setColor(nsessions-1);
}
}
-TEWidget* Konsole::getTe() {
- if (nsessions) {
+TEWidget* Konsole::getTe()
+{
+ if (nsessions)
+ {
return (TEWidget *) tab->currentPage();
- } else {
+ }
+ else
+ {
return 0;
}
}
-void Konsole::switchSession(QWidget* w) {
- TEWidget* te = (TEWidget *) w;
+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();
- for(uint i = 0; i < fonts.count(); i++) {
+ 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) {
+ 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() + " - QKonsole");
+ }
+ else
+ {
+ setCaption( "Qkonsole" );
+ }
+ // 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) {
+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
+{
+ // this is NOT pretty, elegant or anything else besides functional
// QString temp;
// qDebug( temp.sprintf("colormenu %d", iD));
TEWidget* te = getTe();
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
cfg.setGroup("Colors");
-// QColor foreground;
-// QColor background;
- colorMenu->setItemChecked(lastSelectedMenu,FALSE);
+
ColorEntry m_table[TABLE_COLORS];
const ColorEntry * defaultCt=te->getdefaultColorTable();
- /////////// fore back
+
int i;
- if(iD==-9) { // default default
- for (i = 0; i < TABLE_COLORS; i++) {
+
+ // 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;
- cfg.writeEntry("Schema","9");
- colorMenu->setItemChecked(-9,TRUE);
+ colorMenu->setItemChecked(cm_default,TRUE);
+ }
+ te->setColorTable(m_table);
}
- } else {
- if(iD==-6) { // green black
- foreground.setRgb(0x18,255,0x18);
+ if(iD==cm_gb)
+ { // green black
+ foreground.setRgb(100,255,100); // (0x18,255,0x18);
background.setRgb(0x00,0x00,0x00);
- cfg.writeEntry("Schema","6");
- colorMenu->setItemChecked(-6,TRUE);
+ colorMenu->setItemChecked(cm_gb,TRUE);
}
- if(iD==-7) { // black white
+ if(iD==cm_bw)
+ { // black white
foreground.setRgb(0x00,0x00,0x00);
background.setRgb(0xFF,0xFF,0xFF);
- cfg.writeEntry("Schema","7");
- colorMenu->setItemChecked(-7,TRUE);
+ colorMenu->setItemChecked(cm_bw,TRUE);
}
- if(iD==-8) { // white black
+ if(iD==cm_wb)
+ { // white black
foreground.setRgb(0xFF,0xFF,0xFF);
background.setRgb(0x00,0x00,0x00);
- cfg.writeEntry("Schema","8");
- colorMenu->setItemChecked(-8,TRUE);
+ colorMenu->setItemChecked(cm_wb,TRUE);
}
- if(iD==-10) {// Black, Red
+ if(iD==cm_br)
+ {// Black, Red
foreground.setRgb(0x00,0x00,0x00);
- background.setRgb(0xB2,0x18,0x18);
- cfg.writeEntry("Schema","10");
- colorMenu->setItemChecked(-10,TRUE);
+ background.setRgb(255,85,85); //(0xB2,0x18,0x18);
+ colorMenu->setItemChecked(cm_br,TRUE);
}
- if(iD==-11) {// Red, Black
- foreground.setRgb(230,31,31); //0xB2,0x18,0x18
+ if(iD==cm_rb)
+ {// Red, Black
+ foreground.setRgb(255,85,85);
background.setRgb(0x00,0x00,0x00);
- cfg.writeEntry("Schema","11");
- colorMenu->setItemChecked(-11,TRUE);
+ colorMenu->setItemChecked(cm_rb,TRUE);
}
- if(iD==-12) {// Green, Yellow - is ugly
+ if(iD==cm_gy)
+ {// Green, Yellow - is ugly
// foreground.setRgb(0x18,0xB2,0x18);
- foreground.setRgb(36,139,10);
+ foreground.setRgb(15,115,0);
// background.setRgb(0xB2,0x68,0x18);
background.setRgb(255,255,0);
- cfg.writeEntry("Schema","12");
- colorMenu->setItemChecked(-12,TRUE);
- }
- if(iD==-13) {// Blue, Magenta
- foreground.setRgb(0x18,0xB2,0xB2);
- background.setRgb(0x18,0x18,0xB2);
- cfg.writeEntry("Schema","13");
- colorMenu->setItemChecked(-13,TRUE);
- }
- if(iD==-14) {// Magenta, Blue
- foreground.setRgb(0x18,0x18,0xB2);
- background.setRgb(0x18,0xB2,0xB2);
- cfg.writeEntry("Schema","14");
- colorMenu->setItemChecked(-14,TRUE);
- }
- if(iD==-15) {// Cyan, White
- foreground.setRgb(0x18,0xB2,0xB2);
+ 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);
- cfg.writeEntry("Schema","15");
- colorMenu->setItemChecked(-15,TRUE);
+ colorMenu->setItemChecked(cm_cw,TRUE);
}
- if(iD==-16) {// White, Cyan
- background.setRgb(0x18,0xB2,0xB2);
+ if(iD==cm_wc)
+ {// White, Cyan
+ background.setRgb(8,91,129);
foreground.setRgb(0xFF,0xFF,0xFF);
- cfg.writeEntry("Schema","16");
- colorMenu->setItemChecked(-16,TRUE);
+ colorMenu->setItemChecked(cm_wc,TRUE);
}
- if(iD==-17) {// Black, Blue
+ if(iD==cm_bb)
+ {// Black, Blue
background.setRgb(0x00,0x00,0x00);
- foreground.setRgb(0x18,0xB2,0xB2);
- cfg.writeEntry("Schema","17");
- colorMenu->setItemChecked(-17,TRUE);
+ foreground.setRgb(127,147,225);
+ colorMenu->setItemChecked(cm_bb,TRUE);
}
- if(iD==-18) {// Black, Gold
+ if(iD==cm_ab)
+ {// Black, Gold
background.setRgb(0x00,0x00,0x00);
- foreground.setRgb(255,215,0);
- cfg.writeEntry("Schema","18");
- colorMenu->setItemChecked(-18,TRUE);
+ foreground.setRgb(255,215,105);
+ colorMenu->setItemChecked(cm_ab,TRUE);
}
#ifdef QT_QWS_OPIE
- if(iD==-19) {
+ if(iD==-19)
+ {
// Custom
qDebug("do custom");
- if(fromMenu) {
+ if(fromMenu)
+ {
OColorPopupMenu* penColorPopupMenu = new OColorPopupMenu(Qt::black, this, "foreground color");
connect(penColorPopupMenu, SIGNAL(colorSelected(const QColor&)), this,
SLOT(changeForegroundColor(const QColor&)));
penColorPopupMenu->exec();
}
- cfg.writeEntry("Schema","19");
- if(!fromMenu) {
+ if(!fromMenu)
+ {
foreground.setNamedColor(cfg.readEntry("foreground",""));
background.setNamedColor(cfg.readEntry("background",""));
}
fromMenu=FALSE;
colorMenu->setItemChecked(-19,TRUE);
}
#endif
- for (i = 0; i < TABLE_COLORS; i++) {
- if(i==0 || i == 10) {
+
+ 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 if(i==1 || i == 11)
+ {
+ m_table[i].color = background;
+ m_table[i].transparent=0;
}
else
m_table[i].color = defaultCt[i].color;
}
- }
- lastSelectedMenu = iD;
te->setColorTable(m_table);
- update();
-
}
-void Konsole::configMenuSelected(int iD)
+void Konsole::tabMenuSelected(int id)
{
-// QString temp;
-// qDebug( temp.sprintf("configmenu %d",iD));
-
- TEWidget* te = getTe();
- Config cfg("Konsole");
- cfg.setGroup("Menubar");
- int i,j;
-#ifdef QT_QWS_OPIE
- i=-29;j=-30;
-#else
- i=-28;j=-29;
-#endif
-
- if(iD == -4) {
+ Config cfg("Qkonsole");
cfg.setGroup("Tabs");
- QString tmp=cfg.readEntry("Position","Bottom");
-
- if(tmp=="Top") {
+ tabMenu->setItemChecked(tabPos, false);
+ if (id == tm_bottom)
+ {
+ printf("set bottom tab\n");
+ tab->getTabBar()->show();
tab->setTabPosition(QTabWidget::Bottom);
- configMenu->changeItem( iD, tr("Tabs on Top"));
+ tab->getTabBar()->show();
cfg.writeEntry("Position","Bottom");
- } else {
+ }
+ else if (id == tm_top)
+ {
+ printf("set top tab\n");
+ tab->getTabBar()->show();
+ tab->setTabPosition(QTabWidget::Bottom);
tab->setTabPosition(QTabWidget::Top);
- configMenu->changeItem( iD, tr("Tabs on Bottom"));
+ 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;
}
- if(iD == i) {
+
+
+void Konsole::configMenuSelected(int iD)
+{
+ // QString temp;
+ // qDebug( temp.sprintf("configmenu %d",iD));
+
+ TEWidget* te = getTe();
+ Config cfg("Qkonsole");
+ 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) {
+ if(cfg.readNumEntry("Position",2) == 0)
+ {
te->setScrollbarLocation(1);
- } else {
+ }
+ else
+ {
te->setScrollbarLocation(0);
}
te->setScrollbarLocation( cfg.readNumEntry("Position",2));
}
- if(iD == j) {
+ if(iD == cm_beep)
+ {
cfg.setGroup("Menubar");
bool b=cfg.readBoolEntry("useBeep",0);
b=!b;
cfg.writeEntry("useBeep", b );
cfg.write();
- configMenu->setItemChecked(j,b);
+ configMenu->setItemChecked(cm_beep,b);
te->useBeep=b;
}
}
void Konsole::changeCommand(const QString &text, int c)
{
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
cfg.setGroup("Commands");
- if(commonCmds[c] != text) {
+ if(commonCmds[c] != text)
+ {
cfg.writeEntry(QString::number(c),text);
commonCombo->clearEdit();
commonCombo->setCurrentItem(c);
}
}
-void Konsole::setColor()
+void Konsole::setColor(int sess)
{
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
cfg.setGroup("Colors");
- int scheme = cfg.readNumEntry("Schema",1);
- if(scheme != 1) colorMenuSelected( -scheme);
+ 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");
+ Config cfg("Qkonsole");
cfg.setGroup("ScrollBar");
- int i,j,k;
-#ifdef QT_QWS_OPIE
-i=-25;j=-26;k=-27;
-#else
-i=-24;j=-25;k=-26;
-#endif
- if(index == i) {
+ if(index == sm_none)
+ {
te->setScrollbarLocation(0);
cfg.writeEntry("Position",0);
- } else if(index == j) {
-
+ }
+ else if(index == sm_left)
+ {
te->setScrollbarLocation(1);
cfg.writeEntry("Position",1);
- } else if(index == k) {
-
+ }
+ 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");
+ Config cfg("Qkonsole");
cfg.setGroup("Menubar");
- if( iD == -3) {
- if(!secondToolBar->isHidden()) {
+ if( iD == ec_cmdlist)
+ {
+ if(!secondToolBar->isHidden())
+ {
secondToolBar->hide();
configMenu->changeItem( iD,tr( "Show Command List" ));
cfg.writeEntry("Hidden","TRUE");
- configMenu->setItemEnabled(-23 ,FALSE);
- } else {
+ 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(-23 ,TRUE);
+ configMenu->setItemEnabled(ec_edit ,TRUE);
+ configMenu->setItemEnabled(ec_quick ,TRUE);
- if(cfg.readEntry("EditEnabled","FALSE")=="TRUE") {
- configMenu->setItemChecked(-23,TRUE);
+ if(cfg.readEntry("EditEnabled","FALSE")=="TRUE")
+ {
+ configMenu->setItemChecked(ec_edit,TRUE);
commonCombo->setEditable( TRUE );
- } else {
- configMenu->setItemChecked(-23,FALSE);
+ }
+ else
+ {
+ configMenu->setItemChecked(ec_edit,FALSE);
commonCombo->setEditable( FALSE );
}
}
}
- if( iD == -23) {
+ if( iD == ec_quick)
+ {
cfg.setGroup("Commands");
// qDebug("enableCommandEdit");
- if( !configMenu->isItemChecked(iD) ) {
+ if( !configMenu->isItemChecked(iD) )
+ {
commonCombo->setEditable( TRUE );
configMenu->setItemChecked(iD,TRUE);
commonCombo->setCurrentItem(0);
cfg.writeEntry("EditEnabled","TRUE");
- } else {
+ }
+ else
+ {
commonCombo->setEditable( FALSE );
configMenu->setItemChecked(iD,FALSE);
cfg.writeEntry("EditEnabled","FALSE");
commonCombo->setFocusPolicy(QWidget::NoFocus);
te->setFocus();
}
}
- if(iD == -24) {
+ if(iD == ec_edit)
+ {
// "edit commands"
CommandEditDialog *m = new CommandEditDialog(this);
connect(m,SIGNAL(commandsEdited()),this,SLOT(initCommandList()));
- QPEApplication::showDialog( m );
+ m->showMaximized();
}
}
// $QPEDIR/bin/qcop QPE/Application/embeddedkonsole 'setDocument(QString)' 'ssh -V'
-void Konsole::setDocument( const QString &cmd) {
+void Konsole::setDocument( const QString &cmd)
+{
newSession();
TEWidget* te = getTe();
- if(cmd.find("-e", 0, TRUE) != -1) {
+ if(cmd.find("-e", 0, TRUE) != -1)
+ {
QString cmd2;
cmd2=cmd.right(cmd.length()-3)+" &";
system(cmd2.latin1());
- if(startUp <= 1 && nsessions < 2) {
- doneSession(getTe()->currentSession, 0);
+ if(startUp <= 1 && nsessions < 2)
+ {
+ doneSession(getTe(), 0);
exit(0);
- } else
- doneSession(getTe()->currentSession, 0);
- } else {
- if (te != 0) {
+ }
+ else
+ doneSession(getTe(), 0);
+ }
+ else
+ {
+ if (te != 0)
+ {
te->emitText(cmd+"\r");
}
}
startUp++;
}
-void Konsole::parseCommandLine() {
+
+// 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") {
+ for (int i=1;i< qApp->argc();i++)
+ {
+ if( QString(qApp->argv()[i]) == "-e")
+ {
i++;
- for ( int j=i;j< qApp->argc();j++) {
+ 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");
+void Konsole::changeForegroundColor(const QColor &color)
+{
+ Config cfg("Qkonsole");
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
OColorPopupMenu* penColorPopupMenu2 = new 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) {
+void Konsole::changeBackgroundColor(const QColor &color)
+{
qDebug("Change background");
- Config cfg("Konsole");
+ Config cfg("Qkonsole");
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() {
-int i;
-#ifdef QT_QWS_OPIE
-i=-29;
-#else
-i=-28;
-#endif
-
- Config cfg("Konsole");
+void Konsole::doWrap()
+{
+ Config cfg("Qkonsole");
cfg.setGroup("ScrollBar");
TEWidget* te = getTe();
- if( !cfg.readBoolEntry("HorzScroll",0)) {
+ if( !cfg.readBoolEntry("HorzScroll",0))
+ {
te->setWrapAt(0);
- configMenu->setItemChecked( i,TRUE);
- } else {
+ configMenu->setItemChecked( cm_wrap,TRUE);
+ }
+ else
+ {
// te->setWrapAt(90);
te->setWrapAt(120);
- configMenu->setItemChecked( i,FALSE);
+ configMenu->setItemChecked( cm_wrap,FALSE);
}
}
diff --git a/core/apps/embeddedkonsole/konsole.h b/core/apps/embeddedkonsole/konsole.h
index 7d5a908..37babbb 100644
--- a/core/apps/embeddedkonsole/konsole.h
+++ b/core/apps/embeddedkonsole/konsole.h
@@ -1,144 +1,206 @@
/* ----------------------------------------------------------------------- */
/* */
/* [konsole.h] Konsole */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
/* This file is part of Konsole, an X terminal. */
/* */
/* The material contained in here more or less directly orginates from */
/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Ported Konsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
#ifndef KONSOLE_H
#define KONSOLE_H
#include <qmainwindow.h>
#include <qaction.h>
#include <qpopupmenu.h>
#include <qstrlist.h>
#include <qintdict.h>
#include <qptrdict.h>
#include <qtabwidget.h>
#include <qtoolbar.h>
#include <qcombobox.h>
#include <qcolor.h>
#include "MyPty.h"
#include "TEWidget.h"
#include "TEmuVt102.h"
#include "session.h"
class EKNumTabWidget;
class Konsole : public QMainWindow
{
Q_OBJECT
public:
- static QString appName() { return QString::fromLatin1("embeddedkonsole"); }
+
+ static QString appName()
+ {
+ return QString::fromLatin1("embeddedkonsole");
+ }
Konsole(QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
+ Konsole(const char * name, const char* pgm, QStrList & _args, int histon);
~Konsole();
void setColLin(int columns, int lines);
QToolBar *secondToolBar;
void show();
- void setColor();
+ void setColor(int);
int lastSelectedMenu;
int startUp;
+
+public slots:
+ void changeFontSize(int);
+ void toggleFullScreen();
+ void setFullScreen(bool);
+ void changeSession(int);
+ void cycleZoom();
+ void newSession();
+
private slots:
void setDocument(const QString &);
- void doneSession(TESession*,int);
+ void doneSession(TEWidget*,int);
+ void changeTitle(TEWidget*,QString);
void changeColumns(int);
- void fontChanged(int);
+ void setFont(int);
+ // void fontChanged(int);
void configMenuSelected(int );
void colorMenuSelected(int);
void colorMenuIsSelected(int);
+ void tabMenuSelected(int);
+ void sessionListSelected(int);
+
void enterCommand(int);
void hitEnter();
void hitSpace();
void hitTab();
void hitPaste();
void hitUp();
void hitDown();
void switchSession(QWidget *);
- void newSession();
void changeCommand(const QString &, int);
void initCommandList();
void scrollMenuSelected(int);
void editCommandListMenuSelected(int);
void parseCommandLine();
void changeForegroundColor(const QColor &);
void changeBackgroundColor(const QColor &);
+
+ void historyDialog();
+ void fullscreenTimeout();
+
private:
void doWrap();
void init(const char* _pgm, QStrList & _args);
void initSession(const char* _pgm, QStrList & _args);
void runSession(TESession* s);
void setColorPixmaps();
void setHistory(bool);
+ void setColors(QColor foreground, QColor background);
+ int findFont(QString name, int size, bool exact = false);
QSize calcSize(int columns, int lines);
TEWidget* getTe();
QStringList commands;
QLabel * msgLabel;
QColor foreground, background;
bool fromMenu;
+
+ bool fullscreen;
+
private:
class VTFont
{
public:
- VTFont(QString name, QFont& font)
+ VTFont(QString name, QFont& font, QString family, int familyNum, int size)
{
this->name = name;
this->font = font;
+ this->family = family;
+ this->size = size;
+ this->familyNum = familyNum;
}
QFont& getFont()
{
return font;
}
-
QString getName()
{
return name;
}
+ int getSize()
+ {
+ return(size);
+ }
+ QString getFamily()
+ {
+ return(family);
+ }
+ int getFamilyNum()
+ {
+ return(familyNum);
+ }
private:
- QString name;
QFont font;
+ QString name;
+ QString family;
+ int familyNum;
+ int size;
};
EKNumTabWidget* tab;
+ int tabPos;
int nsessions;
QList<VTFont> fonts;
int cfont;
QCString se_pgm;
QStrList se_args;
- QPopupMenu *fontList,*configMenu,*colorMenu,*scrollMenu,*editCommandListMenu;
+ QToolBar *menuToolBar;
+ QToolBar *toolBar;
QComboBox *commonCombo;
+
+ QPopupMenu *fontList,*configMenu,*colorMenu,*scrollMenu,*editCommandListMenu;
+ QPopupMenu *sessionList, *tabMenu;
+
+ int sm_none, sm_left, sm_right;
+ int cm_beep, cm_wrap;
+ int cm_default;
+ int cm_bw, cm_wb, cm_gb, cm_bt, cm_br, cm_rb, cm_gy, cm_bm, cm_mb, cm_cw, cm_wc, cm_bb, cm_ab;
+ int tm_top, tm_bottom, tm_hidden;
+ int ec_edit, ec_cmdlist, ec_quick;
+
+ bool show_fullscreen_msg;
+ QTimer *fullscreen_timer;
+ QLabel *fullscreen_msg;
+
+
// history scrolling I think
bool b_scroll;
int n_keytab;
int n_scroll;
int n_render;
QString pmPath; // pixmap path
QString dropText;
QFont defaultFont;
QSize defaultSize;
};
#endif
diff --git a/core/apps/embeddedkonsole/main.cpp b/core/apps/embeddedkonsole/main.cpp
index f77fe24..a6a079c 100644
--- a/core/apps/embeddedkonsole/main.cpp
+++ b/core/apps/embeddedkonsole/main.cpp
@@ -1,38 +1,39 @@
/* ---------------------------------------------------------------------- */
/* */
/* [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> */
/* */
/* -------------------------------------------------------------------------- */
#include "konsole.h"
#include <qpe/qpeapplication.h>
#include <opie/oapplicationfactory.h>
#include <qfile.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <sys/types.h>
/* --| main |------------------------------------------------------ */
OPIE_EXPORT_APP( OApplicationFactory<Konsole> )
+
diff --git a/core/apps/embeddedkonsole/session.cpp b/core/apps/embeddedkonsole/session.cpp
index 520af86..17acb8c 100644
--- a/core/apps/embeddedkonsole/session.cpp
+++ b/core/apps/embeddedkonsole/session.cpp
@@ -1,157 +1,161 @@
/* -------------------------------------------------------------------------- */
/* */
/* 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)
+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);
- term = _term;
-
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&)),
- main,SLOT(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(this,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::setTitle(const QString& title)
+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/embeddedkonsole/session.h b/core/apps/embeddedkonsole/session.h
index 4a61569..f399e96 100644
--- a/core/apps/embeddedkonsole/session.h
+++ b/core/apps/embeddedkonsole/session.h
@@ -1,93 +1,94 @@
/* -------------------------------------------------------------------------- */
/* */
/* [session.h] Testbed for TE framework */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
/* This file is part of Konsole, an X terminal. */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Ported Konsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
#ifndef SESSION_H
#define SESSION_H
#include <qapplication.h>
#include <qmainwindow.h>
#include <qstrlist.h>
#include "MyPty.h"
#include "TEWidget.h"
#include "TEmuVt102.h"
class TESession : public QObject
{ Q_OBJECT
public:
TESession(QMainWindow* main, TEWidget* w,
const char* pgm, QStrList & _args,
const char* term);
~TESession();
public:
void setConnect(bool r);
TEmulation* getEmulation(); // to control emulation
bool isSecure();
public:
int schemaNo();
int fontNo();
const char* emuName();
const QString& Title();
bool history();
int keymap();
void setHistory(bool on);
void setSchemaNo(int sn);
void setKeymapNo(int kn);
void setFontNo(int fn);
- void setTitle(const QString& title);
void kill(int signal);
public slots:
void run();
void done(int status);
void terminate();
+ void changeTitle(int, const QString& title);
signals:
- void done(TESession*, int);
+ void done(TEWidget*, int);
+ void changeTitle(TEWidget*, QString);
private:
// TEPty* sh;
MyPty* sh;
TEWidget* te;
TEmulation* em;
//FIXME: using the indices here
// is propably very bad. We should
// use a persistent reference instead.
int schema_no;
int font_no;
int keymap_no;
QString title;
const char* pgm;
QStrList args;
QCString term;
};
#endif