summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/TEScreen.cpp17
-rw-r--r--noncore/apps/opie-console/TEScreen.h2
-rw-r--r--noncore/apps/opie-console/TEmulation.cpp4
-rw-r--r--noncore/apps/opie-console/TEmulation.h7
-rw-r--r--noncore/apps/opie-console/emulation_handler.cpp3
-rw-r--r--noncore/apps/opie-console/emulation_handler.h1
-rw-r--r--noncore/apps/opie-console/mainwindow.cpp35
-rw-r--r--noncore/apps/opie-console/mainwindow.h1
-rw-r--r--noncore/apps/opie-console/metafactory.cpp25
-rw-r--r--noncore/apps/opie-console/metafactory.h11
10 files changed, 64 insertions, 42 deletions
diff --git a/noncore/apps/opie-console/TEScreen.cpp b/noncore/apps/opie-console/TEScreen.cpp
index a3d115d..2675d31 100644
--- a/noncore/apps/opie-console/TEScreen.cpp
+++ b/noncore/apps/opie-console/TEScreen.cpp
@@ -220,978 +220,989 @@ void TEScreen::reverseIndex()
/*!
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(0,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);
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()
{
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;
}
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)
{
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;
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)
+ 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;
}
+QString TEScreen::getHistory() {
+ sel_begin = 0;
+ sel_BR = sel_begin;
+ sel_TL = sel_begin;
+ setSelExtentXY(columns-1,lines-1);
+ QString tmp=getSelText(true);
+ while (tmp.at(tmp.length()-2).unicode()==10 && tmp.at(tmp.length()-1).unicode()==10)
+ tmp.truncate(tmp.length()-1);
+
+ return tmp;
+}
/* 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
}
int TEScreen::getHistCursor()
{
return histCursor;
}
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/noncore/apps/opie-console/TEScreen.h b/noncore/apps/opie-console/TEScreen.h
index 473ce79..a840b44 100644
--- a/noncore/apps/opie-console/TEScreen.h
+++ b/noncore/apps/opie-console/TEScreen.h
@@ -1,259 +1,261 @@
/* -------------------------------------------------------------------------- */
/* */
/* [te_screen.h] Screen Data Type */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
/* This file is part of Konsole - an X terminal for KDE */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Ported Konsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
#ifndef TESCREEN_H
#define TESCREEN_H
/*! \file
*/
#include "TECommon.h"
#include "TEHistory.h"
#define MODE_Origin 0
#define MODE_Wrap 1
#define MODE_Insert 2
#define MODE_Screen 3
#define MODE_Cursor 4
#define MODE_NewLine 5
#define MODES_SCREEN 6
/*!
*/
struct ScreenParm
{
int mode[MODES_SCREEN];
};
class TEScreen
{
public:
TEScreen(int lines, int columns);
~TEScreen();
public: // these are all `Screen' operations
//
// VT100/2 Operations ------------------
//
// Cursor Movement
//
void cursorUp (int n);
void cursorDown (int n);
void cursorLeft (int n);
void cursorRight (int n);
void setCursorY (int y);
void setCursorX (int x);
void setCursorYX (int y, int x);
void setMargins (int t, int b);
//
// Cursor Movement with Scrolling
//
void NewLine ();
void NextLine ();
void index ();
void reverseIndex();
//
void Return ();
void BackSpace ();
void Tabulate ();
//
// Editing
//
void eraseChars (int n);
void deleteChars (int n);
void insertChars (int n);
void deleteLines (int n);
void insertLines (int n);
//
// -------------------------------------
//
void clearTabStops();
void changeTabStop(bool set);
//
void resetMode (int n);
void setMode (int n);
void saveMode (int n);
void restoreMode (int n);
//
void saveCursor ();
void restoreCursor();
//
// -------------------------------------
//
void clearEntireScreen();
void clearToEndOfScreen();
void clearToBeginOfScreen();
//
void clearEntireLine();
void clearToEndOfLine();
void clearToBeginOfLine();
//
void helpAlign ();
//
// -------------------------------------
//
void setRendition (int rendition);
void resetRendition(int rendition);
void setForeColor (int fgcolor);
void setBackColor (int bgcolor);
//
void setDefaultRendition();
void setForeColorToDefault();
void setBackColorToDefault();
//
// -------------------------------------
//
BOOL getMode (int n);
//
// only for report cursor position
//
int getCursorX();
int getCursorY();
//
// -------------------------------------
//
void clear();
void home();
void reset();
//
void ShowCharacter(unsigned short c);
//
void resizeImage(int new_lines, int new_columns);
//
ca* getCookedImage();
/*! return the number of lines. */
int getLines() { return lines; }
/*! return the number of columns. */
int getColumns() { return columns; }
/*! set the position of the history cursor. */
void setHistCursor(int cursor);
/*! return the position of the history cursor. */
int getHistCursor();
int getHistLines ();
void setScroll(bool on);
bool hasScroll();
//
// Selection
//
void setSelBeginXY(const int x, const int y);
void setSelExtentXY(const int x, const int y);
void clearSelection();
QString getSelText(const BOOL preserve_line_breaks);
void checkSelection(int from, int to);
+ QString getHistory();
+
private: // helper
void clearImage(int loca, int loce, char c);
void moveImage(int dst, int loca, int loce);
void scrollUp(int from, int i);
void scrollDown(int from, int i);
void addHistLine();
void initTabStops();
void effectiveRendition();
void reverseRendition(ca* p);
private:
/*
The state of the screen is more complex as one would
expect first. The screem does really do part of the
emulation providing state informations in form of modes,
margins, tabulators, cursor etc.
Even more unexpected are variables to save and restore
parts of the state.
*/
// screen image ----------------
int lines;
int columns;
ca *image; // [lines][columns]
// history buffer ---------------
int histCursor; // display position relative to start of the history buffer
HistoryScroll hist;
// cursor location
int cuX;
int cuY;
// cursor color and rendition info
UINT8 cu_fg; // foreground
UINT8 cu_bg; // background
UINT8 cu_re; // rendition
// margins ----------------
int tmargin; // top margin
int bmargin; // bottom margin
// states ----------------
ScreenParm currParm;
// ----------------------------
bool* tabstops;
// selection -------------------
int sel_begin; // The first location selected.
int sel_TL; // TopLeft Location.
int sel_BR; // Bottom Right Location.
// effective colors and rendition ------------
UINT8 ef_fg; // These are derived from
UINT8 ef_bg; // the cu_* variables above
UINT8 ef_re; // to speed up operation
//
// save cursor, rendition & states ------------
//
// cursor location
int sa_cuX;
int sa_cuY;
// rendition info
UINT8 sa_cu_re;
UINT8 sa_cu_fg;
UINT8 sa_cu_bg;
// modes
ScreenParm saveParm;
};
#endif // TESCREEN_H
diff --git a/noncore/apps/opie-console/TEmulation.cpp b/noncore/apps/opie-console/TEmulation.cpp
index 7a0c624..3b1b9e1 100644
--- a/noncore/apps/opie-console/TEmulation.cpp
+++ b/noncore/apps/opie-console/TEmulation.cpp
@@ -1,364 +1,366 @@
/* -------------------------------------------------------------------------- */
/* */
/* [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(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 )
{
qWarning("onKeyPress,....");
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();
}
-
+void TEmulation::streamHistory(QTextStream* stream) {
+ *stream << scr->getHistory();
+}
// 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::setColumns(int columns)
{
//FIXME: this goes strange ways.
// Can we put this straight or explain it at least?
emit changeColumns(columns);
}
diff --git a/noncore/apps/opie-console/TEmulation.h b/noncore/apps/opie-console/TEmulation.h
index ec15e7a..d7b3d6d 100644
--- a/noncore/apps/opie-console/TEmulation.h
+++ b/noncore/apps/opie-console/TEmulation.h
@@ -1,117 +1,122 @@
/* -------------------------------------------------------------------------- */
/* */
/* [emulation.h] Fundamental Terminal Emulation */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
/* */
/* This file is part of Konsole - an X terminal for KDE */
/* */
/* -------------------------------------------------------------------------- */
/* */
/* Ported Konsole to Qt/Embedded */
/* */
/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
/* */
/* -------------------------------------------------------------------------- */
#ifndef EMULATION_H
#define EMULATION_H
#include "TEWidget.h"
#include "TEScreen.h"
#include <qtimer.h>
#include <stdio.h>
#include <qtextcodec.h>
+#include <qtextstream.h>
+
#include "keytrans.h"
class TEmulation : public QObject
{ Q_OBJECT
public:
TEmulation(TEWidget* gui);
~TEmulation();
public:
virtual void setHistory(bool on);
virtual bool history();
+ virtual void streamHistory( QTextStream* );
public slots: // signals incoming from TEWidget
virtual void onImageSizeChange(int lines, int columns);
virtual void onHistoryCursorChange(int cursor);
virtual void onKeyPress(QKeyEvent*);
-
+
virtual void clearSelection();
virtual void onSelectionBegin(const int x, const int y);
virtual void onSelectionExtend(const int x, const int y);
virtual void setSelection(const BOOL preserve_line_breaks);
public slots: // signals incoming from data source
void onRcvBlock(const char* txt,int len);
signals:
void sndBlock(const char* txt,int len);
void ImageSizeChanged(int lines, int columns);
void changeColumns(int columns);
void changeTitle(int arg, const char* str);
public:
virtual void onRcvChar(int);
virtual void setMode (int) = 0;
virtual void resetMode(int) = 0;
virtual void sendString(const char*) = 0;
virtual void setConnect(bool r);
void setColumns(int columns);
void setKeytrans(int no);
void setKeytrans(const char * no);
+
+
protected:
TEWidget* gui;
TEScreen* scr; // referes to one `screen'
TEScreen* screen[2]; // 0 = primary, 1 = alternate
void setScreen(int n); // set `scr' to `screen[n]'
bool connected; // communicate with widget
void setCodec(int c); // codec number, 0 = locale, 1=utf8
QTextCodec* codec;
QTextCodec* localeCodec;
QTextDecoder* decoder;
KeyTrans* keytrans;
// refreshing related material.
// this is localized in the class.
private slots: // triggered by timer
void showBulk();
private:
void bulkNewline();
void bulkStart();
void bulkEnd();
private:
QTimer bulk_timer;
int bulk_nlcnt; // bulk newline counter
char* SelectedText;
int bulk_incnt; // bulk counter
};
#endif // ifndef EMULATION_H
diff --git a/noncore/apps/opie-console/emulation_handler.cpp b/noncore/apps/opie-console/emulation_handler.cpp
index 7924568..235facb 100644
--- a/noncore/apps/opie-console/emulation_handler.cpp
+++ b/noncore/apps/opie-console/emulation_handler.cpp
@@ -1,206 +1,209 @@
#include <qwidget.h>
#include <qpushbutton.h>
#include "TEWidget.h"
#include "TEmuVt102.h"
#include "profile.h"
#include "emulation_handler.h"
#include "script.h"
EmulationHandler::EmulationHandler( const Profile& prof, QWidget* parent,const char* name )
: QObject(0, name )
{
m_teWid = new TEWidget( parent, "TerminalMain");
// use setWrapAt(0) for classic behaviour (wrap at screen width, no scrollbar)
// use setWrapAt(80) for normal console with scrollbar
setWrap(prof.readNumEntry("Wrap", 0) ? 0 : 80);
m_teWid->setMinimumSize(150, 70 );
m_script = 0;
parent->resize( m_teWid->calcSize(80, 24 ) );
m_teEmu = new TEmuVt102(m_teWid );
connect(m_teEmu,SIGNAL(ImageSizeChanged(int, int) ),
this, SIGNAL(changeSize(int, int) ) );
connect(m_teEmu, SIGNAL(sndBlock(const char*, int) ),
this, SLOT(recvEmulation(const char*, int) ) );
m_teEmu->setConnect( true );
m_teEmu->setHistory( TRUE );
load( prof );
}
+TEmulation* EmulationHandler::emulation() {
+ return m_teEmu;
+}
EmulationHandler::~EmulationHandler() {
if (isRecording())
clearScript();
delete m_teEmu;
delete m_teWid;
}
void EmulationHandler::load( const Profile& prof) {
m_teWid->setVTFont( font( prof.readNumEntry("Font") ) );
int num = prof.readNumEntry("Color");
setColor( foreColor(num), backColor(num) );
m_teWid->setBackgroundColor(backColor(num) );
int term = prof.readNumEntry("Terminal", 0) ;
switch(term) {
default:
case Profile::VT102:
case Profile::VT100:
m_teEmu->setKeytrans("vt100.keytab");
break;
case Profile::Linux:
m_teEmu->setKeytrans("linux.keytab");
break;
case Profile::XTerm:
m_teEmu->setKeytrans("default.Keytab");
break;
}
}
void EmulationHandler::recv( const QByteArray& ar) {
m_teEmu->onRcvBlock(ar.data(), ar.count() );
}
void EmulationHandler::recvEmulation(const char* src, int len ) {
QByteArray ar(len);
memcpy(ar.data(), src, sizeof(char) * len );
if (isRecording())
m_script->append(ar);
emit send(ar);
}
QWidget* EmulationHandler::widget() {
return m_teWid;
}
/*
* allocate a new table of colors
*/
void EmulationHandler::setColor( const QColor& fore, const QColor& back ) {
ColorEntry table[TABLE_COLORS];
const ColorEntry *defaultCt = m_teWid->getdefaultColorTable();
for (int i = 0; i < TABLE_COLORS; i++ ) {
if ( i == 0 || i == 10 ) {
table[i].color = fore;
}else if ( i == 1 || i == 11 ) {
table[i].color = back;
table[i].transparent = 0;
}else {
table[i].color = defaultCt[i].color;
}
}
m_teWid->setColorTable(table );
m_teWid->update();
}
QFont EmulationHandler::font( int id ) {
QString name;
int size = 0;
switch(id ) {
default: // fall through
case 0:
name = QString::fromLatin1("Micro");
size = 4;
break;
case 1:
name = QString::fromLatin1("Fixed");
size = 7;
break;
case 2:
name = QString::fromLatin1("Fixed");
size = 12;
break;
}
QFont font(name, size, QFont::Normal );
font.setFixedPitch(TRUE );
return font;
}
QColor EmulationHandler::foreColor(int col) {
QColor co;
/* we need to switch it */
switch( col ) {
default:
case Profile::White:
/* color is black */
co = Qt::white;
break;
case Profile::Black:
co = Qt::black;
break;
case Profile::Green:
qWarning("Foreground green");
co = Qt::green;
break;
case Profile::Orange:
qWarning("Foreground orange");
co.setRgb( 231, 184, 98 );
break;
}
return co;
}
QColor EmulationHandler::backColor(int col ) {
QColor co;
/* we need to switch it */
switch( col ) {
default:
case Profile::White:
/* color is white */
co = Qt::black;
break;
case Profile::Black:
co = Qt::white;
break;
case Profile::Green:
qWarning("Background black");
co = Qt::black;
break;
case Profile::Orange:
qWarning("Background black");
co = Qt::black;
break;
}
return co;
}
QPushButton* EmulationHandler::cornerButton() {
return m_teWid->cornerButton();
}
Script *EmulationHandler::script() {
return m_script;
}
bool EmulationHandler::isRecording() {
return (m_script != 0);
}
void EmulationHandler::startRecording() {
if (!isRecording())
m_script = new Script();
}
void EmulationHandler::clearScript() {
if (isRecording()) {
delete m_script;
m_script = 0;
}
}
void EmulationHandler::runScript(const Script *script) {
emit send(script->script());
}
void EmulationHandler::copy() {
m_teWid->emitSelection();
}
void EmulationHandler::paste() {
m_teWid->pasteClipboard();
}
void EmulationHandler::setWrap(int columns) {
m_teWid->setWrapAt(columns);
}
diff --git a/noncore/apps/opie-console/emulation_handler.h b/noncore/apps/opie-console/emulation_handler.h
index 7bc6f16..1338525 100644
--- a/noncore/apps/opie-console/emulation_handler.h
+++ b/noncore/apps/opie-console/emulation_handler.h
@@ -1,94 +1,95 @@
#ifndef OPIE_EMULATION_HANDLER_H
#define OPIE_EMULATION_HANDLER_H
#include <qobject.h>
#include <qcolor.h>
#include <qcstring.h>
/*
* Badly ibotty lacks the time to finish
* his widget in time..
* Never the less we've to have an EmulationWidget
* This is why I'm taking the inferior not cleaned
* up TE* KDE STUFF
*/
/**
* This is the layer above the IOLayer*
* This nice QObject here will get stuff from
* got a slot and a signal
* the signal for data
* the slot for receiving
* it'll set up the widget internally
* and manage the communication between
* the pre QByteArray world!
*/
class Profile;
class QWidget;
class QPushButton;
class TEWidget;
class TEmulation;
class QFont;
class Script;
class EmulationHandler : public QObject {
Q_OBJECT
public:
/**
* simple c'tor the parent of the TEWdiget
* and a name
* and a Profile
*/
EmulationHandler( const Profile&, QWidget* parent, const char* name = 0l );
/**
* delete all components
*/
~EmulationHandler();
void load( const Profile& );
QWidget* widget();
+ TEmulation *emulation();
void setColor( const QColor& fore, const QColor& back );
QPushButton* cornerButton();
/* Scripts */
/* Create a new script and record all typed characters */
void startRecording();
/* Return whether we are currently recording a script */
bool isRecording();
/* Return the current script (or NULL) */
Script *script();
/* Stop recording and remove the current script from memory */
void clearScript();
/* Run a script by forwarding its keys to the EmulationLayer */
void runScript(const Script *);
/* Propagate change to widget */
void setWrap(int columns);
signals:
void send( const QByteArray& );
void changeSize(int rows, int cols );
public slots:
void recv( const QByteArray& );
void paste();
void copy();
private slots:
void recvEmulation( const char*, int len );
private:
QFont font( int );
QColor foreColor(int );
QColor backColor(int );
private:
TEWidget* m_teWid;
TEmulation* m_teEmu;
Script * m_script;
};
#endif
diff --git a/noncore/apps/opie-console/mainwindow.cpp b/noncore/apps/opie-console/mainwindow.cpp
index d221715..01468ca 100644
--- a/noncore/apps/opie-console/mainwindow.cpp
+++ b/noncore/apps/opie-console/mainwindow.cpp
@@ -1,770 +1,803 @@
#include <assert.h>
#include <qaction.h>
#include <qmenubar.h>
#include <qlabel.h>
#include <qpopupmenu.h>
#include <qtoolbar.h>
#include <qmessagebox.h>
#include <qpushbutton.h>
#include <qwhatsthis.h>
#include <qfileinfo.h>
+#include <qtextstream.h>
#include <qpe/resource.h>
#include <qpe/qpeapplication.h>
#include <qpe/filemanager.h>
#include <qpe/mimetype.h>
#include <opie/ofiledialog.h>
+#include "TEmulation.h"
#include "keytrans.h"
#include "profileeditordialog.h"
#include "configdialog.h"
#include "default.h"
#include "metafactory.h"
#include "profile.h"
#include "profilemanager.h"
#include "mainwindow.h"
#include "tabwidget.h"
#include "transferdialog.h"
#include "function_keyboard.h"
#include "emulation_handler.h"
#include "script.h"
static char * filesave_xpm[] = {
"16 16 78 1",
" c None",
". c #343434",
"+ c #A0A0A0",
"@ c #565656",
"# c #9E9E9E",
"$ c #525252",
"% c #929292",
"& c #676767",
"* c #848484",
"= c #666666",
"- c #D8D8D8",
"; c #FFFFFF",
"> c #DBDBDB",
", c #636363",
"' c #989898",
") c #2D2D2D",
"! c #909090",
"~ c #AEAEAE",
"{ c #EAEAEA",
"] c #575757",
"^ c #585858",
"/ c #8A8A8A",
"( c #828282",
"_ c #6F6F6F",
": c #C9C9C9",
"< c #050505",
"[ c #292929",
"} c #777777",
"| c #616161",
"1 c #3A3A3A",
"2 c #BEBEBE",
"3 c #2C2C2C",
"4 c #7C7C7C",
"5 c #F6F6F6",
"6 c #FCFCFC",
"7 c #6B6B6B",
"8 c #959595",
"9 c #4F4F4F",
"0 c #808080",
"a c #767676",
"b c #818181",
"c c #B8B8B8",
"d c #FBFBFB",
"e c #F9F9F9",
"f c #CCCCCC",
"g c #030303",
"h c #737373",
"i c #7A7A7A",
"j c #7E7E7E",
"k c #6A6A6A",
"l c #FAFAFA",
"m c #505050",
"n c #9D9D9D",
"o c #333333",
"p c #7B7B7B",
"q c #787878",
"r c #696969",
"s c #494949",
"t c #555555",
"u c #949494",
"v c #E6E6E6",
"w c #424242",
"x c #515151",
"y c #535353",
"z c #3E3E3E",
"A c #D4D4D4",
"B c #0C0C0C",
"C c #353535",
"D c #474747",
"E c #ECECEC",
"F c #919191",
"G c #7D7D7D",
"H c #000000",
"I c #404040",
"J c #858585",
"K c #323232",
"L c #D0D0D0",
"M c #1C1C1C",
" ...+ ",
" @#$%&..+ ",
" .*=-;;>,..+ ",
" ')!~;;;;;;{]..",
" ^/(-;;;;;;;_:<",
" [}|;;;;;;;{12$",
" #34-55;;;;678$+",
" 90ab=c;dd;e1fg ",
" [ahij((kbl0mn$ ",
" op^q^^7r&]s/$+ ",
"@btu;vbwxy]zAB ",
"CzDEvEv;;DssF$ ",
"G.H{E{E{IxsJ$+ ",
" +...vEKxzLM ",
" +...z]n$ ",
" +... "};
MainWindow::MainWindow(QWidget *parent, const char *name, WFlags) : QMainWindow(parent, name, WStyle_ContextHelp) {
KeyTrans::loadAll();
for (int i = 0; i < KeyTrans::count(); i++ ) {
KeyTrans* s = KeyTrans::find(i );
assert( s );
}
m_factory = new MetaFactory();
Default def(m_factory);
m_sessions.setAutoDelete( TRUE );
m_curSession = 0;
m_manager = new ProfileManager( m_factory );
m_manager->load();
m_scriptsData.setAutoDelete(TRUE);
initUI();
populateProfiles();
populateScripts();
}
void MainWindow::initUI() {
setToolBarsMovable( FALSE );
/* tool bar for the menu */
m_tool = new QToolBar( this );
m_tool->setHorizontalStretchable( TRUE );
m_bar = new QMenuBar( m_tool );
m_console = new QPopupMenu( this );
m_scripts = new QPopupMenu( this );
m_sessionsPop= new QPopupMenu( this );
m_scriptsPop = new QPopupMenu( this );
/* add a toolbar for icons */
m_icons = new QToolBar(this);
/*
* the settings action
*/
m_setProfiles = new QAction(tr("Configure Profiles"),
Resource::loadPixmap( "SettingsIcon" ),
QString::null, 0, this, 0);
m_setProfiles->addTo( m_console );
connect( m_setProfiles, SIGNAL(activated() ),
this, SLOT(slotConfigure() ) );
m_console->insertSeparator();
/*
* new Action for new sessions
*/
QAction* newCon = new QAction(tr("New Connection"),
Resource::loadPixmap( "new" ),
QString::null, 0, this, 0);
newCon->addTo( m_console );
connect( newCon, SIGNAL(activated() ),
this, SLOT(slotNew() ) );
m_console->insertSeparator();
QAction *saveCon = new QAction(tr("Save Connection"),
QPixmap( ( const char** ) filesave_xpm ) , QString::null,
0, this, 0 );
saveCon->addTo( m_console );
connect( saveCon, SIGNAL(activated() ),
this, SLOT(slotSaveSession() ) );
m_console->insertSeparator();
/*
* connect action
*/
m_connect = new QAction( tr("Connect"), Resource::loadPixmap("console/connected"),
QString::null, 0, this, 0 );
m_connect->addTo( m_console );
connect(m_connect, SIGNAL(activated() ),
this, SLOT(slotConnect() ) );
/*
* disconnect action
*/
m_disconnect = new QAction( tr("Disconnect"), Resource::loadPixmap("console/notconnected"),
QString::null, 0, this, 0 );
m_disconnect->addTo( m_console );
connect(m_disconnect, SIGNAL(activated() ),
this, SLOT(slotDisconnect() ) );
m_console->insertSeparator();
m_transfer = new QAction( tr("Transfer file..."), Resource::loadPixmap("pass") , QString::null,
0, this, 0 );
m_transfer->addTo( m_console );
connect(m_transfer, SIGNAL(activated() ),
this, SLOT(slotTransfer() ) );
/*
* immediate change of line wrap policy
*/
m_isWrapped = false;
m_wrap = new QAction( tr("Line wrap"), Resource::loadPixmap( "linewrap" ), QString::null, 0, this, 0 );
m_wrap->addTo( m_console );
connect( m_wrap, SIGNAL( activated() ), SLOT( slotWrap() ) );
/*
* fullscreen
*/
m_isFullscreen = false;
m_fullscreen = new QAction( tr("Full screen"), Resource::loadPixmap( "fullscreen" )
, QString::null, 0, this, 0);
m_fullscreen->addTo( m_console );
connect( m_fullscreen, SIGNAL( activated() ),
this, SLOT( slotFullscreen() ) );
m_console->insertSeparator();
+
+ QAction *a = new QAction();
+ a->setText( tr("Save history") );
+ a->addTo( m_console );
+ connect(a, SIGNAL(activated() ),
+ this, SLOT(slotSaveHistory() ) );
/*
* terminate action
*/
m_terminate = new QAction();
m_terminate->setText( tr("Terminate") );
m_terminate->addTo( m_console );
connect(m_terminate, SIGNAL(activated() ),
this, SLOT(slotTerminate() ) );
m_closewindow = new QAction();
m_closewindow->setText( tr("Close Window") );
m_closewindow->addTo( m_console );
connect( m_closewindow, SIGNAL(activated() ),
this, SLOT(slotClose() ) );
/*
* script actions
*/
m_runScript_id = m_scripts->insertItem(tr("Run Script"), m_scriptsPop, -1, 0);
connect(m_scriptsPop, SIGNAL(activated(int)), this, SLOT(slotRunScript(int)));
m_recordScript = new QAction(tr("Record Script"), QString::null, 0, this, 0);
m_recordScript->addTo(m_scripts);
connect(m_recordScript, SIGNAL(activated()), this, SLOT(slotRecordScript()));
m_saveScript = new QAction(tr("Save Script"), QString::null, 0, this, 0);
m_saveScript->addTo(m_scripts);
connect(m_saveScript, SIGNAL(activated()), this, SLOT(slotSaveScript()));
/*
* action that open/closes the keyboard
*/
m_openKeys = new QAction (tr("Open Keyboard..."),
Resource::loadPixmap( "console/keys/keyboard_icon" ),
QString::null, 0, this, 0);
m_openKeys->setToggleAction(true);
connect (m_openKeys, SIGNAL(toggled(bool)), this, SLOT(slotOpenKeb(bool)));
/* insert the submenu */
m_console->insertItem(tr("New from Profile"), m_sessionsPop,
-1, 0);
/* insert the connection menu */
m_bar->insertItem( tr("Connection"), m_console );
/* the scripts menu */
m_bar->insertItem( tr("Scripts"), m_scripts );
/* and the keyboard */
m_keyBar = new QToolBar(this);
addToolBar( m_keyBar, "Keyboard", QMainWindow::Top, TRUE );
m_keyBar->setHorizontalStretchable( TRUE );
m_keyBar->hide();
m_kb = new FunctionKeyboard(m_keyBar);
connect(m_kb, SIGNAL(keyPressed(FKey, ushort, ushort, bool)),
this, SLOT(slotKeyReceived(FKey, ushort, ushort, bool)));
- QAction *a = new QAction(tr("Copy"),
+ a = new QAction(tr("Copy"),
Resource::loadPixmap("copy"), QString::null,
0, this, 0 );
//a->addTo( m_icons );
connect( a, SIGNAL(activated() ),
this, SLOT(slotCopy() ) );
QAction *paste = new QAction(tr("Paste"),
Resource::loadPixmap("paste"), QString::null,
0, this, 0 );
connect( paste, SIGNAL(activated() ),
this, SLOT(slotPaste() ) );
newCon->addTo( m_icons );
m_setProfiles->addTo( m_icons );
paste->addTo( m_icons );
m_openKeys->addTo(m_icons);
m_fullscreen->addTo( m_icons );
m_connect->setEnabled( false );
m_disconnect->setEnabled( false );
m_terminate->setEnabled( false );
m_transfer->setEnabled( false );
m_scripts->setItemEnabled(m_runScript_id, false);
m_recordScript->setEnabled( false );
m_saveScript->setEnabled( false );
m_fullscreen->setEnabled( false );
m_closewindow->setEnabled( false );
m_wrap->setEnabled( false );
/*
* connect to the menu activation
*/
connect( m_sessionsPop, SIGNAL(activated( int ) ),
this, SLOT(slotProfile( int ) ) );
m_consoleWindow = new TabWidget( this, "blah");
connect(m_consoleWindow, SIGNAL(activated(Session*) ),
this, SLOT(slotSessionChanged(Session*) ) );
setCentralWidget( m_consoleWindow );
}
ProfileManager* MainWindow::manager() {
return m_manager;
}
TabWidget* MainWindow::tabWidget() {
return m_consoleWindow;
}
void MainWindow::populateProfiles() {
m_sessionsPop->clear();
Profile::ValueList list = manager()->all();
for (Profile::ValueList::Iterator it = list.begin(); it != list.end(); ++it ) {
m_sessionsPop->insertItem( (*it).name() );
}
}
void MainWindow::populateScripts() {
m_scriptsPop->clear();
m_scriptsData.clear();
DocLnkSet files(QPEApplication::documentDir(), "text/plain");
QListIterator<DocLnk> dit(files.children());
for (; dit.current(); ++dit) {
if (*dit && (*dit)->name().length()>0) {
QFileInfo info((*dit)->file());
if (info.extension(false) == "script") {
m_scriptsData.append(new DocLnk(**dit));
m_scriptsPop->insertItem((*dit)->name());
}
}
}
}
MainWindow::~MainWindow() {
delete m_factory;
manager()->save();
}
MetaFactory* MainWindow::factory() {
return m_factory;
}
Session* MainWindow::currentSession() {
return m_curSession;
}
QList<Session> MainWindow::sessions() {
return m_sessions;
}
void MainWindow::slotNew() {
ProfileEditorDialog dlg(factory() );
dlg.showMaximized();
dlg.setCaption( tr("New Connection") );
int ret = dlg.exec();
if ( ret == QDialog::Accepted ) {
create( dlg.profile() );
}
}
void MainWindow::slotRecordScript() {
if (currentSession()) {
currentSession()->emulationHandler()->startRecording();
m_saveScript->setEnabled(true);
m_recordScript->setEnabled(false);
}
}
void MainWindow::slotSaveScript() {
if (currentSession() && currentSession()->emulationHandler()->isRecording()) {
QMap<QString, QStringList> map;
QStringList text;
text << "text/plain";
map.insert(tr("Script"), text );
QString filename = OFileDialog::getSaveFileName(2, QPEApplication::documentDir(), QString::null, map);
if (!filename.isEmpty()) {
QFileInfo info(filename);
if (info.extension(FALSE) != "script")
filename += ".script";
DocLnk nf;
nf.setType("text/plain");
nf.setFile(filename);
nf.setName(info.fileName());
FileManager fm;
fm.saveFile(nf, currentSession()->emulationHandler()->script()->script());
currentSession()->emulationHandler()->clearScript();
m_saveScript->setEnabled(false);
m_recordScript->setEnabled(true);
populateScripts();
}
}
}
void MainWindow::slotRunScript(int id) {
if (currentSession()) {
int index = m_scriptsPop->indexOf(id);
DocLnk *lnk = m_scriptsData.at(index);
QString filePath = lnk->file();
Script script(filePath);
currentSession()->emulationHandler()->runScript(&script);
}
}
void MainWindow::slotConnect() {
if ( currentSession() ) {
bool ret = currentSession()->layer()->open();
if(!ret) QMessageBox::warning(currentSession()->widgetStack(),
QObject::tr("Failed"),
QObject::tr("Connecting failed for this session."));
else {
m_connect->setEnabled( false );
m_disconnect->setEnabled( true );
// if it does not support file transfer, disable the menu entry
if ( ( m_curSession->layer() )->supports()[1] == 0 ) {
m_transfer->setEnabled( false );
} else {
m_transfer->setEnabled( true );
}
m_recordScript->setEnabled( true );
m_scripts->setItemEnabled(m_runScript_id, true);
}
}
}
void MainWindow::slotDisconnect() {
if ( currentSession() ) {
currentSession()->layer()->close();
m_connect->setEnabled( true );
m_disconnect->setEnabled( false );
m_transfer->setEnabled( false );
m_recordScript->setEnabled( false);
m_saveScript->setEnabled( false );
m_scripts->setItemEnabled(m_runScript_id, false);
}
}
void MainWindow::slotTerminate() {
if ( currentSession() )
currentSession()->layer()->close();
slotClose();
/* FIXME move to the next session */
}
void MainWindow::slotConfigure() {
ConfigDialog conf( manager()->all(), factory() );
conf.showMaximized();
int ret = conf.exec();
if ( QDialog::Accepted == ret ) {
manager()->setProfiles( conf.list() );
manager()->save();
populateProfiles();
}
}
/*
* we will remove
* this window from the tabwidget
* remove it from the list
* delete it
* and set the currentSession()
*/
void MainWindow::slotClose() {
if (!currentSession() )
return;
Session* ses = currentSession();
qWarning("removing! currentSession %s", currentSession()->name().latin1() );
/* set to NULL to be safe, if its needed slotSessionChanged resets it automatically */
m_curSession = NULL;
tabWidget()->remove( /*currentSession()*/ses );
/*it's autodelete */
m_sessions.remove( ses );
qWarning("after remove!!");
if (!currentSession() ) {
m_connect->setEnabled( false );
m_disconnect->setEnabled( false );
m_terminate->setEnabled( false );
m_transfer->setEnabled( false );
m_recordScript->setEnabled( false );
m_saveScript->setEnabled( false );
m_scripts->setItemEnabled(m_runScript_id, false);
m_fullscreen->setEnabled( false );
m_wrap->setEnabled( false );
m_closewindow->setEnabled( false );
}
m_kb->loadDefaults();
}
/*
* We will get the name
* Then the profile
* and then we will make a profile
*/
void MainWindow::slotProfile( int id) {
Profile prof = manager()->profile( m_sessionsPop->text( id) );
create( prof );
}
void MainWindow::create( const Profile& prof ) {
if(m_curSession)
if(m_curSession->transferDialog()) m_curSession->transferDialog()->hide();
Session *ses = manager()->fromProfile( prof, tabWidget() );
if((!ses) || (!ses->layer()) || (!ses->widgetStack()))
{
QMessageBox::warning(this,
QObject::tr("Session failed"),
QObject::tr("<qt>Cannot open session: Not all components were found.</qt>"));
//if(ses) delete ses;
return;
}
m_sessions.append( ses );
tabWidget()->add( ses );
tabWidget()->repaint();
m_curSession = ses;
// dicide if its a local term ( then no connction and no tranfer), maybe make a wrapper method out of it
m_connect->setEnabled( true );
m_disconnect->setEnabled( false );
m_terminate->setEnabled( true );
m_fullscreen->setEnabled( true );
m_wrap->setEnabled( true );
m_closewindow->setEnabled( true );
m_transfer->setEnabled( false );
m_recordScript->setEnabled( false );
m_saveScript->setEnabled( false );
m_scripts->setItemEnabled(m_runScript_id, false);
// is io_layer wants direct connection, then autoconnect
//if ( ( m_curSession->layer() )->supports()[0] == 1 ) {
if (prof.autoConnect()) {
slotConnect();
}
QWidget *w = currentSession()->widget();
if(w) w->setFocus();
if(currentSession()->profile().readNumEntry("Wrap", 80)){
m_isWrapped = true;
} else {
m_isWrapped = false;
}
m_kb->load(currentSession()->profile());
}
void MainWindow::slotTransfer()
{
if ( currentSession() ) {
Session *mysession = currentSession();
TransferDialog dlg(/*mysession->widgetStack()*/this, this);
mysession->setTransferDialog(&dlg);
//dlg.reparent(mysession->widgetStack(), QPoint(0, 0));
//dlg.showMaximized();
currentSession()->widgetStack()->addWidget(&dlg, -1);
dlg.show();
//dlg.exec();
while(dlg.isRunning()) qApp->processEvents();
mysession->setTransferDialog(0l);
}
}
void MainWindow::slotOpenKeb(bool state) {
if (state) m_keyBar->show();
else m_keyBar->hide();
}
void MainWindow::slotOpenButtons( bool state ) {
if ( state ) {
m_buttonBar->show();
} else {
m_buttonBar->hide();
}
}
void MainWindow::slotSessionChanged( Session* ses ) {
qWarning("changed!");
if(m_curSession)
if(m_curSession->transferDialog()) m_curSession->transferDialog()->hide();
if(ses)
if(ses->transferDialog()) ses->transferDialog()->show();
if ( ses ) {
m_curSession = ses;
qDebug(QString("is connected : %1").arg( m_curSession->layer()->isConnected() ) );
if ( m_curSession->layer()->isConnected() ) {
m_connect->setEnabled( false );
m_disconnect->setEnabled( true );
m_recordScript->setEnabled(!m_curSession->emulationHandler()->isRecording());
m_saveScript->setEnabled(m_curSession->emulationHandler()->isRecording());
m_scripts->setItemEnabled(m_runScript_id, true);
} else {
m_connect->setEnabled( true );
m_disconnect->setEnabled( false );
m_recordScript->setEnabled( false );
m_saveScript->setEnabled( false );
m_scripts->setItemEnabled(m_runScript_id, false);
}
if ( ( m_curSession->layer() )->supports()[1] == 0 ) {
m_transfer->setEnabled( false );
} else {
m_transfer->setEnabled( true );
}
QWidget *w = m_curSession->widget();
if(w) w->setFocus();
if(currentSession()->profile().readNumEntry("Wrap", 80)){
m_isWrapped = true;
} else {
m_isWrapped = false;
}
m_kb->load(currentSession()->profile());
}
}
void MainWindow::slotWrap()
{
if(m_curSession)
{
EmulationHandler *e = m_curSession->emulationHandler();
if(e)
{
if(m_isWrapped)
{
e->setWrap(80);
m_isWrapped = false;
}
else
{
e->setWrap(0);
m_isWrapped = true;
}
}
}
}
void MainWindow::slotFullscreen() {
if ( m_isFullscreen ) {
( m_curSession->widgetStack() )->reparent( savedParentFullscreen, 0, QPoint(0,0), true );
( m_curSession->widgetStack() )->resize( savedParentFullscreen->width(), savedParentFullscreen->height() );
( m_curSession->emulationHandler() )->cornerButton()->hide();
disconnect( ( m_curSession->emulationHandler() )->cornerButton(), SIGNAL( pressed() ), this, SLOT( slotFullscreen() ) );
} else {
savedParentFullscreen = ( m_curSession->widgetStack() )->parentWidget();
( m_curSession->widgetStack() )->setFrameStyle( QFrame::NoFrame );
( m_curSession->widgetStack() )->reparent( 0, WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop
, QPoint(0,0), false );
( m_curSession->widgetStack() )->resize( qApp->desktop()->width(), qApp->desktop()->height() );
( m_curSession->widgetStack() )->setFocus();
( m_curSession->widgetStack() )->show();
( ( m_curSession->emulationHandler() )->cornerButton() )->show();
connect( ( m_curSession->emulationHandler() )->cornerButton(), SIGNAL( pressed() ), this, SLOT( slotFullscreen() ) );
}
m_isFullscreen = !m_isFullscreen;
}
void MainWindow::slotKeyReceived(FKey k, ushort, ushort, bool pressed) {
if ( m_curSession ) {
QEvent::Type state;
if (pressed) state = QEvent::KeyPress;
else state = QEvent::KeyRelease;
QKeyEvent ke(state, k.qcode, k.unicode, 0, QString(QChar(k.unicode)));
// is this the best way to do this? cant figure out any other way to work
QApplication::sendEvent((QObject *)m_curSession->widget(), &ke);
ke.ignore();
}
}
void MainWindow::slotCopy() {
if (!currentSession() ) return;
currentSession()->emulationHandler()->copy();
}
void MainWindow::slotPaste() {
if (!currentSession() ) return;
currentSession()->emulationHandler()->paste();
}
/*
* Save the session
*/
void MainWindow::slotSaveSession() {
if (!currentSession() ) {
QMessageBox::information(this, tr("Save Connection"),
tr("<qt>There is no Connection.</qt>"), 1 );
return;
}
manager()->add( currentSession()->profile() );
manager()->save();
populateProfiles();
}
+void MainWindow::slotSaveHistory() {
+ QMap<QString, QStringList> map;
+ QStringList text;
+ text << "text/plain";
+ map.insert(tr("History"), text );
+ QString filename = OFileDialog::getSaveFileName(2, QPEApplication::documentDir(), QString::null, map);
+ if (filename.isEmpty() ) return;
+
+ QFileInfo info(filename);
+
+ DocLnk nf;
+ nf.setType("text/plain");
+ nf.setFile(filename);
+ nf.setName(info.fileName());
+
+
+ QFile file(filename);
+ file.open(IO_WriteOnly );
+ QTextStream str(&file );
+ if ( currentSession() )
+ currentSession()->emulationHandler()->emulation()->streamHistory(&str);
+
+ file.close();
+ nf.writeLink();
+}
diff --git a/noncore/apps/opie-console/mainwindow.h b/noncore/apps/opie-console/mainwindow.h
index 37219c5..0fac38b 100644
--- a/noncore/apps/opie-console/mainwindow.h
+++ b/noncore/apps/opie-console/mainwindow.h
@@ -1,135 +1,136 @@
#ifndef OPIE_MAIN_WINDOW_H
#define OPIE_MAIN_WINDOW_H
#include <qmainwindow.h>
#include <qlist.h>
#include "session.h"
/**
* this is the MainWindow of the new opie console
* it's also the dispatcher between the different
* actions supported by the gui
*/
class QToolBar;
class QToolButton;
class QMenuBar;
class QAction;
class MetaFactory;
class TabWidget;
class ProfileManager;
class Profile;
class FunctionKeyboard;
class FKey;
class DocLnk;
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow( QWidget *parent = 0, const char *name = 0, WFlags fl = 0 );
~MainWindow();
/**
* our factory to generate IOLayer and so on
*
*/
MetaFactory* factory();
/**
* A session contains a QWidget*,
* an IOLayer* and some infos for us
*/
Session* currentSession();
/**
* the session list
*/
QList<Session> sessions();
/**
*
*/
ProfileManager* manager();
TabWidget* tabWidget();
private slots:
void slotNew();
void slotConnect();
void slotDisconnect();
void slotTerminate();
void slotConfigure();
void slotClose();
void slotProfile(int);
void slotTransfer();
void slotOpenKeb(bool);
void slotOpenButtons(bool);
void slotRecordScript();
void slotSaveScript();
void slotRunScript(int);
void slotFullscreen();
void slotWrap();
void slotSessionChanged( Session* );
void slotKeyReceived(FKey, ushort, ushort, bool);
+ void slotSaveHistory();
/* what could these both slot do? */
void slotCopy();
void slotPaste();
/* save the currentSession() to Profiles */
void slotSaveSession();
private:
void initUI();
void populateProfiles();
void populateScripts();
void create( const Profile& );
/**
* the current session
*/
Session* m_curSession;
/**
* the session list
*/
QList<Session> m_sessions;
QList<DocLnk> m_scriptsData;
/**
* the metafactory
*/
MetaFactory* m_factory;
ProfileManager* m_manager;
TabWidget* m_consoleWindow;
QToolBar* m_tool;
QToolBar* m_icons;
QToolBar* m_keyBar;
QToolBar* m_buttonBar;
QMenuBar* m_bar;
QPopupMenu* m_console;
QPopupMenu* m_sessionsPop;
QPopupMenu* m_scriptsPop;
QPopupMenu* m_scripts;
QAction* m_connect;
QAction* m_disconnect;
QAction* m_terminate;
QAction* m_transfer;
QAction* m_setProfiles;
QAction* m_openKeys;
QAction* m_openButtons;
QAction* m_recordScript;
QAction* m_saveScript;
QAction* m_fullscreen;
QAction* m_wrap;
QAction* m_closewindow;
FunctionKeyboard *m_kb;
int m_runScript_id;
bool m_isFullscreen;
bool m_isWrapped;
QWidget* savedParentFullscreen;
};
#endif
diff --git a/noncore/apps/opie-console/metafactory.cpp b/noncore/apps/opie-console/metafactory.cpp
index 0b43e17..24928e7 100644
--- a/noncore/apps/opie-console/metafactory.cpp
+++ b/noncore/apps/opie-console/metafactory.cpp
@@ -1,190 +1,165 @@
#include <qpe/config.h>
#include "metafactory.h"
MetaFactory::MetaFactory() {
}
MetaFactory::~MetaFactory() {
}
void MetaFactory::addConnectionWidgetFactory( const QCString& name,
const QString& str,
configWidget wid) {
m_strings.insert( str, name );
m_conFact.insert( str, wid );
}
void MetaFactory::addTerminalWidgetFactory( const QCString& name,
const QString& str,
configWidget wid ) {
m_strings.insert( str, name );
m_termFact.insert( str, wid );
}
void MetaFactory::addKeyboardWidgetFactory( const QCString& name,
const QString & str,
configWidget wid) {
m_strings.insert( str, name );
m_keyFact.insert( str, wid );
}
void MetaFactory::addIOLayerFactory( const QCString& name,
const QString& str,
iolayer lay) {
m_strings.insert( str, name );
m_layerFact.insert( str, lay );
}
void MetaFactory::addFileTransferLayer( const QCString& name,
const QString& str,
filelayer lay) {
m_strings.insert(str, name );
m_fileFact.insert( str, lay );
}
void MetaFactory::addReceiveLayer( const QCString& name,
const QString& str,
receivelayer lay) {
m_strings.insert(str, name );
m_receiveFact.insert( str, lay );
}
-void MetaFactory::addEmulationLayer( const QCString& name,
- const QString& str,
- emulationLayer em) {
- m_strings.insert(str, name );
- m_emu.insert( str, em );
-}
QStringList MetaFactory::ioLayers()const {
QStringList list;
QMap<QString, iolayer>::ConstIterator it;
for (it = m_layerFact.begin(); it != m_layerFact.end(); ++it ) {
list << it.key();
}
return list;
}
QStringList MetaFactory::connectionWidgets()const {
QStringList list;
QMap<QString, configWidget>::ConstIterator it;
for ( it = m_conFact.begin(); it != m_conFact.end(); ++it ) {
list << it.key();
}
return list;
}
QStringList MetaFactory::terminalWidgets()const {
QStringList list;
QMap<QString, configWidget>::ConstIterator it;
for ( it = m_termFact.begin(); it != m_termFact.end(); ++it ) {
list << it.key();
}
return list;
}
QStringList MetaFactory::fileTransferLayers()const {
QStringList list;
QMap<QString, filelayer>::ConstIterator it;
for ( it = m_fileFact.begin(); it != m_fileFact.end(); ++it ) {
list << it.key();
}
return list;
}
QStringList MetaFactory::receiveLayers()const {
QStringList list;
QMap<QString, receivelayer>::ConstIterator it;
for ( it = m_receiveFact.begin(); it != m_receiveFact.end(); ++it ) {
list << it.key();
}
return list;
}
-QStringList MetaFactory::emulationLayers()const {
- QStringList list;
- QMap<QString, emulationLayer>::ConstIterator it;
- for ( it = m_emu.begin(); it != m_emu.end(); ++it ) {
- list << it.key();
- }
- return list;
-}
IOLayer* MetaFactory::newIOLayer( const QString& str,const Profile& prof ) {
IOLayer* lay = 0l;
QMap<QString, iolayer>::Iterator it;
it = m_layerFact.find( str );
if ( it != m_layerFact.end() ) {
lay = (*(it.data()))(prof);
/*
iolayer laye = it.data();
lay = (*laye )(conf);*/
}
return lay;
}
ProfileDialogWidget *MetaFactory::newConnectionPlugin ( const QString& str, QWidget *parent) {
ProfileDialogWidget* wid = 0l;
QMap<QString, configWidget>::Iterator it;
it = m_conFact.find( str );
if ( it != m_conFact.end() ) {
wid = (*(it.data() ) )(str,parent);
}
return wid;
}
ProfileDialogWidget *MetaFactory::newTerminalPlugin( const QString& str, QWidget *parent) {
if (str.isEmpty() )
return 0l;
ProfileDialogWidget* wid = 0l;
QMap<QString, configWidget>::Iterator it;
it = m_termFact.find( str );
if ( it != m_termFact.end() ) {
wid = (*(it.data() ) )(str,parent);
}
return wid;
}
ProfileDialogWidget *MetaFactory::newKeyboardPlugin( const QString& str, QWidget *parent) {
if (str.isEmpty() )
return 0l;
ProfileDialogWidget* wid = 0l;
QMap<QString, configWidget>::Iterator it;
it = m_keyFact.find( str );
if ( it != m_keyFact.end() ) {
wid = (*(it.data() ) )(str,parent);
}
return wid;
}
-EmulationLayer* MetaFactory::newEmulationLayer( const QString& str, WidgetLayer* wid) {
- EmulationLayer* lay = 0l;
-
- QMap<QString, emulationLayer>::Iterator it;
- it = m_emu.find( str );
- if ( it != m_emu.end() ) {
- lay = (*(it.data() ) )(wid);
- }
-
- return lay;
-}
FileTransferLayer* MetaFactory::newFileTransfer(const QString& str, IOLayer* lay ) {
FileTransferLayer* file = 0l;
QMap<QString, filelayer>::Iterator it;
it = m_fileFact.find( str );
if ( it != m_fileFact.end() ) {
file = (*(it.data() ) )(lay);
}
return file;
}
ReceiveLayer* MetaFactory::newReceive(const QString& str, IOLayer* lay ) {
ReceiveLayer* file = 0l;
QMap<QString, receivelayer>::Iterator it;
it = m_receiveFact.find( str );
if ( it != m_receiveFact.end() ) {
file = (*(it.data() ) )(lay);
}
return file;
}
QCString MetaFactory::internal( const QString& str )const {
return m_strings[str];
}
QString MetaFactory::external( const QCString& str )const {
QMap<QString, QCString>::ConstIterator it;
for ( it = m_strings.begin(); it != m_strings.end(); ++it ) {
if ( it.data() == str )
return it.key();
}
return QString::null;
}
diff --git a/noncore/apps/opie-console/metafactory.h b/noncore/apps/opie-console/metafactory.h
index f89136c..bcc40db 100644
--- a/noncore/apps/opie-console/metafactory.h
+++ b/noncore/apps/opie-console/metafactory.h
@@ -1,120 +1,109 @@
#ifndef OPIE_META_FACTORY_H
#define OPIE_META_FACTORY_H
/**
* The MetaFactory is used to keep track of all IOLayers, FileTransferLayers and ConfigWidgets
* and to instantiate these implementations on demand
*/
#include <qwidget.h>
#include <qmap.h>
#include <qpe/config.h>
#include "io_layer.h"
#include "file_layer.h"
#include "receive_layer.h"
#include "profile.h"
#include "profiledialogwidget.h"
-#include "emulation_layer.h"
class WidgetLayer;
class MetaFactory {
public:
typedef ProfileDialogWidget* (*configWidget)(const QString&, QWidget* parent);
typedef IOLayer* (*iolayer)(const Profile& );
typedef FileTransferLayer* (*filelayer)(IOLayer*);
typedef ReceiveLayer* (*receivelayer)(IOLayer*);
- typedef EmulationLayer* (*emulationLayer)(WidgetLayer* );
MetaFactory();
~MetaFactory();
/**
* add a ProfileDialogWidget to the factory
* name is the name shown to the user
*/
void addConnectionWidgetFactory( const QCString& internalName,
const QString& uiString,
configWidget );
void addTerminalWidgetFactory ( const QCString& internalName,
const QString& name,
configWidget );
void addKeyboardWidgetFactory ( const QCString& internalName,
const QString& name,
configWidget );
/**
* adds an IOLayer factory
*/
void addIOLayerFactory( const QCString&,
const QString&,
iolayer );
/**
* adds a FileTransfer Layer
*/
void addFileTransferLayer( const QCString& name,
const QString&,
filelayer );
void addReceiveLayer( const QCString& name,
const QString&,
receivelayer);
- /**
- * adds a Factory for Emulation to the Layer..
- */
- void addEmulationLayer ( const QCString& name,
- const QString& uiString,
- emulationLayer );
/* translated UI Strings */
QStringList ioLayers()const;
QStringList connectionWidgets()const;
/**
* Terminal Configuration widgets
*/
QStringList terminalWidgets()const;
QStringList fileTransferLayers()const;
QStringList receiveLayers()const;
- QStringList emulationLayers()const;
/**
* the generation...
*/
IOLayer* newIOLayer( const QString&,const Profile& );
ProfileDialogWidget *newConnectionPlugin ( const QString&, QWidget* );
ProfileDialogWidget* newTerminalPlugin( const QString&, QWidget* );
ProfileDialogWidget* newKeyboardPlugin( const QString&, QWidget* );
- EmulationLayer* newEmulationLayer(const QString&, WidgetLayer* );
FileTransferLayer* newFileTransfer(const QString&, IOLayer* );
ReceiveLayer* newReceive(const QString&, IOLayer* );
/*
* internal takes the maybe translated
* public QString and maps it to the internal
* not translatable QCString
*/
QCString internal( const QString& )const;
/*
* external takes the internal name
* it returns a translated name
*/
QString external( const QCString& )const;
private:
QMap<QString, QCString> m_strings;
QMap<QString, configWidget> m_conFact;
QMap<QString, configWidget> m_termFact;
QMap<QString, configWidget> m_keyFact;
QMap<QString, iolayer> m_layerFact;
QMap<QString, filelayer> m_fileFact;
QMap<QString, receivelayer> m_receiveFact;
- QMap<QString, emulationLayer> m_emu;
};
#endif