summaryrefslogtreecommitdiff
authoribotty <ibotty>2002-10-11 17:43:18 (UTC)
committer ibotty <ibotty>2002-10-11 17:43:18 (UTC)
commit01f26248efccbd764e7c82b74372f33a4bbae303 (patch) (side-by-side diff)
treea13712dabfa9aaeb7d9ad9353e434b8976234836
parent00005567e4841af1f0efe090160881b286574493 (diff)
downloadopie-01f26248efccbd764e7c82b74372f33a4bbae303.zip
opie-01f26248efccbd764e7c82b74372f33a4bbae303.tar.gz
opie-01f26248efccbd764e7c82b74372f33a4bbae303.tar.bz2
changed references to widget into references to widgetLayer or EmulationWidget.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/metafactory.cpp2
-rw-r--r--noncore/apps/opie-console/metafactory.h6
-rw-r--r--noncore/apps/opie-console/profilemanager.cpp5
-rw-r--r--noncore/apps/opie-console/session.cpp6
-rw-r--r--noncore/apps/opie-console/session.h8
-rw-r--r--noncore/apps/opie-console/widget.cpp12
-rw-r--r--noncore/apps/opie-console/widget_layer.h3
7 files changed, 23 insertions, 19 deletions
diff --git a/noncore/apps/opie-console/metafactory.cpp b/noncore/apps/opie-console/metafactory.cpp
index 02a9f9b..2b672cf 100644
--- a/noncore/apps/opie-console/metafactory.cpp
+++ b/noncore/apps/opie-console/metafactory.cpp
@@ -1,139 +1,139 @@
#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::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::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::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;
qWarning("new terminalPlugin %s %l", str.latin1(), parent );
QMap<QString, configWidget>::Iterator it;
it = m_termFact.find( str );
if ( it != m_termFact.end() ) {
wid = (*(it.data() ) )(str,parent);
}
return wid;
}
-EmulationLayer* MetaFactory::newEmulationLayer( const QString& str, Widget* 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;
}
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 71c35a2..d05ece4 100644
--- a/noncore/apps/opie-console/metafactory.h
+++ b/noncore/apps/opie-console/metafactory.h
@@ -1,106 +1,106 @@
#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 "profile.h"
#include "profiledialogwidget.h"
#include "emulation_layer.h"
-class Widget;
+class WidgetLayer;
class MetaFactory {
public:
typedef ProfileDialogWidget* (*configWidget)(const QString&, QWidget* parent);
typedef IOLayer* (*iolayer)(const Profile& );
typedef FileTransferLayer* (*filelayer)(IOLayer*);
- typedef EmulationLayer* (*emulationLayer)(Widget* );
+ 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 );
/**
* adds an IOLayer factory
*/
void addIOLayerFactory( const QCString&,
const QString&,
iolayer );
/**
* adds a FileTransfer Layer
*/
void addFileTransferLayer( const QCString& name,
const QString&,
filelayer );
/**
* 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 emulationLayers()const;
/**
* the generation...
*/
IOLayer* newIOLayer( const QString&,const Profile& );
ProfileDialogWidget *newConnectionPlugin ( const QString&, QWidget* );
ProfileDialogWidget* newTerminalPlugin( const QString&, QWidget* );
- EmulationLayer* newEmulationLayer(const QString&, Widget* );
+ EmulationLayer* newEmulationLayer(const QString&, WidgetLayer* );
/*
* 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, iolayer> m_layerFact;
QMap<QString, filelayer> m_fileFact;
QMap<QString, emulationLayer> m_emu;
};
#endif
diff --git a/noncore/apps/opie-console/profilemanager.cpp b/noncore/apps/opie-console/profilemanager.cpp
index dcf3cbd..78751e7 100644
--- a/noncore/apps/opie-console/profilemanager.cpp
+++ b/noncore/apps/opie-console/profilemanager.cpp
@@ -1,126 +1,127 @@
#include <stdio.h>
#include <stdlib.h>
#include <qfile.h>
#include <qlayout.h>
#include <qwidgetstack.h>
#include <qpe/config.h>
-#include "widget.h"
+#include "widget_layer.h"
+#include "emulation_widget.h"
#include "metafactory.h"
#include "profileconfig.h"
#include "profilemanager.h"
ProfileManager::ProfileManager( MetaFactory* fact )
: m_fact( fact )
{
}
ProfileManager::~ProfileManager() {
}
void ProfileManager::load() {
m_list.clear();
qWarning("load");
ProfileConfig conf("opie-console-profiles");
QStringList groups = conf.groups();
QStringList::Iterator it;
/*
* for each profile
*/
for ( it = groups.begin(); it != groups.end(); ++it ) {
qWarning("group " + (*it) );
conf.setGroup( (*it) );
Profile prof;
prof.setName( conf.readEntry("name") );
prof.setIOLayer( conf.readEntry("iolayer").utf8() );
prof.setTerminalName( conf.readEntry("term").utf8() );
qWarning(" %s %s", conf.readEntry("iolayer").latin1(), prof.ioLayerName().data() );
prof.setBackground( conf.readNumEntry("back") );
prof.setForeground( conf.readNumEntry("fore") );
prof.setTerminal( conf.readNumEntry("terminal") );
prof.setConf( conf.items( (*it) ) );
/* now add it */
m_list.append( prof );
}
}
void ProfileManager::clear() {
m_list.clear();
}
Profile::ValueList ProfileManager::all()const {
return m_list;
}
/*
* Our goal is to create a Session
* We will load the the IOLayer and EmulationLayer
* from the factory
* we will generate a QWidgetStack
* add a dummy widget with layout
* add "Widget" to the layout
* add the dummy to the stack
* raise the dummy
* call session->connect(=
* this way we only need to reparent
* in TabWidget
*/
Session* ProfileManager::fromProfile( const Profile& prof, QWidget* parent) {
Session* session = new Session();
session->setName( prof.name() );
/* translate the internal name to the external */
session->setIOLayer(m_fact->newIOLayer( m_fact->external(prof.ioLayerName()) ,
prof) );
QWidgetStack *stack = new QWidgetStack(parent);
session->setWidgetStack( stack );
QWidget* dummy = new QWidget(stack );
QHBoxLayout* lay = new QHBoxLayout(dummy );
stack->addWidget( dummy, 0 );
stack->raiseWidget( 0 );
- Widget* wid = new Widget(dummy );
+ WidgetLayer* wid = new EmulationWidget( prof, dummy );
lay->addWidget( wid );
session->setEmulationWidget( wid );
session->setEmulationLayer( m_fact->newEmulationLayer( m_fact->external( prof.terminalName() ),
wid ) );
session->connect();
return session;
}
void ProfileManager::save( ) {
QFile::remove( (QString(getenv("HOME") )+ "/Settings/opie-console-profiles.conf" ) );
ProfileConfig conf("opie-console-profiles");
Profile::ValueList::Iterator it;
for (it = m_list.begin(); it != m_list.end(); ++it ) {
conf.setGroup( (*it).name() );
conf.writeEntry( "name", (*it).name() );
conf.writeEntry( "iolayer", QString::fromUtf8( (*it).ioLayerName() ) );
conf.writeEntry( "term", QString::fromUtf8( (*it).terminalName() ) );
conf.writeEntry( "back", (*it).background() );
conf.writeEntry( "fore", (*it).foreground() );
conf.writeEntry( "terminal", (*it).terminal() );
/* now the config stuff */
QMap<QString, QString> map = (*it).conf();
QMap<QString, QString>::Iterator it;
for ( it = map.begin(); it != map.end(); ++it ) {
conf.writeEntry( it.key(), it.data() );
}
}
}
void ProfileManager::setProfiles( const Profile::ValueList& list ) {
m_list = list;
};
Profile ProfileManager::profile( const QString& name )const {
Profile prof;
Profile::ValueList::ConstIterator it;
for ( it = m_list.begin(); it != m_list.end(); ++it ) {
if ( name == (*it).name() ) {
prof = (*it);
break;
}
}
return prof;
}
diff --git a/noncore/apps/opie-console/session.cpp b/noncore/apps/opie-console/session.cpp
index 42b0583..ff2c3e2 100644
--- a/noncore/apps/opie-console/session.cpp
+++ b/noncore/apps/opie-console/session.cpp
@@ -1,81 +1,81 @@
#include "io_layer.h"
#include "file_layer.h"
-#include "widget.h"
+#include "widget_layer.h"
#include "emulation_layer.h"
#include "session.h"
Session::Session() {
m_widget = 0l;
m_layer = 0l;
m_widLay = 0l;
m_emLay = 0l;
}
Session::Session( const QString& na, QWidgetStack* widget, IOLayer* lay)
: m_name( na ), m_widget( widget ), m_layer( lay )
{
m_widLay = 0l;
m_emLay = 0l;
}
Session::~Session() {
delete m_layer;
delete m_emLay;
delete m_widget;
/* the widget layer should be deleted by the m_widget */
}
QString Session::name()const {
return m_name;
}
QWidgetStack* Session::widgetStack() {
return m_widget;
}
IOLayer* Session::layer() {
return m_layer;
}
EmulationLayer* Session::emulationLayer() {
return m_emLay;
}
-Widget* Session::emulationWidget() {
+WidgetLayer* Session::emulationWidget() {
return m_widLay;
}
void Session::connect() {
if ( !m_layer || !m_emLay )
return;
QObject::connect(m_layer, SIGNAL(received(const QByteArray&) ),
m_emLay, SLOT(onRcvBlock(const QByteArray&) ) );
QObject::connect(m_emLay, SIGNAL(sndBlock(const QByteArray&) ),
m_layer, SLOT(send(const QByteArray&) ) );
}
void Session::disconnect() {
if ( !m_layer || !m_emLay )
return;
QObject::disconnect(m_layer, SIGNAL(received(const QByteArray&) ),
m_emLay, SLOT(onRcvBlock(const QByteArray&) ) );
QObject::disconnect(m_emLay, SIGNAL(sndBlock(const QByteArray&) ),
m_layer, SLOT(send(const QByteArray&) ) );
}
void Session::setName( const QString& na){
m_name = na;
}
void Session::setWidgetStack( QWidgetStack* wid ) {
delete m_widget;
/* the EmulationLayer was destroyed... */
delete m_emLay;
m_widget = wid;
}
void Session::setIOLayer( IOLayer* lay ) {
delete m_layer;
m_layer = lay;
}
void Session::setEmulationLayer( EmulationLayer* lay ) {
delete m_emLay;
m_emLay = lay;
}
-void Session::setEmulationWidget( Widget* lay ) {
+void Session::setEmulationWidget( WidgetLayer* lay ) {
delete m_widLay;
m_widLay = lay;
}
diff --git a/noncore/apps/opie-console/session.h b/noncore/apps/opie-console/session.h
index c3673fc..64c2cdb 100644
--- a/noncore/apps/opie-console/session.h
+++ b/noncore/apps/opie-console/session.h
@@ -1,74 +1,74 @@
#ifndef OPIE_SESSION_H
#define OPIE_SESSION_H
#include <qwidgetstack.h>
class IOLayer;
class EmulationLayer;
-class Widget;
+class WidgetLayer;
/**
* This is a Session. A session contains
* a QWidget pointer and a IOLayer
* Imagine a session like a collection of what
* is needed to show your widget in a tab ;)
*/
class Session {
public:
/**
* c'tor with widget and layer
* ownership get's transfered
*/
Session();
Session( const QString&, QWidgetStack* widget, IOLayer* );
~Session();
/**
* return the name of the session
*/
QString name()const;
/**
* return the widgetstack
* this is used to be semi modal
* for FileTransfer
*
* semi modal == SessionModal
*/
QWidgetStack* widgetStack();
/**
* return the layer
*/
IOLayer* layer();
EmulationLayer* emulationLayer();
- Widget* emulationWidget();
+ WidgetLayer* emulationWidget();
/*
* connects the data flow from
* the IOLayer to the EmulationLayer
*/
void connect();
/*
* disconnect the dataflow
* this will be done for ft
*/
void disconnect();
void setWidgetStack( QWidgetStack* widget );
void setEmulationLayer( EmulationLayer* lay );
- void setEmulationWidget( Widget* lay );
+ void setEmulationWidget( WidgetLayer* lay );
void setIOLayer( IOLayer* );
void setName( const QString& );
private:
QString m_name;
QWidgetStack* m_widget;
IOLayer* m_layer;
EmulationLayer* m_emLay;
- Widget* m_widLay;
+ WidgetLayer* m_widLay;
};
#endif
diff --git a/noncore/apps/opie-console/widget.cpp b/noncore/apps/opie-console/widget.cpp
index b8f2906..d948179 100644
--- a/noncore/apps/opie-console/widget.cpp
+++ b/noncore/apps/opie-console/widget.cpp
@@ -1,1291 +1,1293 @@
/* ------------------------------------------------------------------------ */
/* */
/* [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> */
/* */
/* -------------------------------------------------------------------------- */
/* ibot:
i changed
"currentSession->getEmulation()->sendString()" to
"currentSession->layer()->send()"
# this is not right! EmulationLayer should send it...
+ i changed all those to use emulationLayer()->send() instead
i had to create a QByteArray before...
TODO:
alter Widget to use only QByteArray, where applicable.
*/
/*! \class Widget
\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 "widget.h"
#include "session.h"
#include <qpe/config.h>
#include <qapplication.h>
#include <qcursor.h>
#include <qregexp.h>
#include <qpainter.h>
#include <qclipboard.h>
#include <qstyle.h>
#include <qfile.h>
#include <qdragobject.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <assert.h>
// #include "widget.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 Widget::getDefaultBackColor()
{
return color_table[DEFAULT_BACK_COLOR].color;
}
const ColorEntry* Widget::getColorTable() const
{
return color_table;
}
const ColorEntry* Widget::getdefaultColorTable() const
{
return base_color_table;
}
const QPixmap *Widget::backgroundPixmap()
{
static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
const QPixmap *pm = bg;
return pm;
}
void Widget::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 Widget::fontChange(const QFont &)
{
QFontMetrics fm(font());
font_h = fm.height();
font_w = fm.maxWidth();
font_a = fm.ascent();
//printf("font_h: %d\n",font_h);
//printf("font_w: %d\n",font_w);
//printf("font_a: %d\n",font_a);
//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
//printf("rawname: %s\n",font().rawName().ascii());
fontMap =
#if QT_VERSION < 300
strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
? vt100extended
:
#endif
identicalMap;
propagateSize();
update();
}
void Widget::setVTFont(const QFont& f)
{
QFrame::setFont(f);
}
QFont Widget::getVTFont() {
return font();
}
void Widget::setFont(const QFont &)
{
// ignore font change request if not coming from konsole itself
}
/* ------------------------------------------------------------------------- */
/* */
/* Constructor / Destructor */
/* */
/* ------------------------------------------------------------------------- */
Widget::Widget(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)));
Config cfg("Konsole");
cfg.setGroup("ScrollBar");
switch( cfg.readNumEntry("Position",2)){
case 0:
scrollLoc = SCRNONE;
break;
case 1:
scrollLoc = SCRLEFT;
break;
case 2:
scrollLoc = SCRRIGHT;
break;
};
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;
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)
Widget::~Widget()
{
qApp->removeEventFilter( this );
if (image) free(image);
}
/* ------------------------------------------------------------------------- */
/* */
/* Display Operations */
/* */
/* ------------------------------------------------------------------------- */
/*!
attributed string draw primitive
*/
void Widget::drawAttrStr(QPainter &paint, QRect rect,
QString& str, Character 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 Widget::setImage(const Character* 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];
//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
for (y = 0; y < lins; y++)
{
const Character* lcl = &image[y*this->columns];
const Character* 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(Character));
}
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 Widget::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 Widget::blinkEvent()
{
blinking = !blinking;
repaint(FALSE);
}
/* ------------------------------------------------------------------------- */
/* */
/* Resizing */
/* */
/* ------------------------------------------------------------------------- */
void Widget::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 Widget::propagateSize()
{
Character* 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(Character));
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 Widget::scrollChanged(int)
{
emit changedHistoryCursor(scrollbar->value()); //expose
}
void Widget::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 Widget::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 Widget.
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 Widget 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 Widget::mousePressEvent(QMouseEvent* ev)
{
//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
if ( !contentsRect().contains(ev->pos()) ) return;
QPoint tL = contentsRect().topLeft();
int tLx = tL.x();
int tLy = tL.y();
word_selection_mode = FALSE;
//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
if ( ev->button() == LeftButton)
{
QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
if (mouse_marks || (ev->state() & ShiftButton))
{
emit clearSelectionSignal();
iPntSel = pntSel = pos;
actSel = 1; // left mouse button pressed but nothing selected yet.
grabMouse( /*crossCursor*/ ); // handle with care!
}
else
{
emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
}
}
if ( ev->button() == MidButton )
{
emitSelection();
}
if ( ev->button() == RightButton ) // Configure
{
emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
}
}
void Widget::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();
// 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 Widget::mouseReleaseEvent(QMouseEvent* ev)
{
//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
if ( ev->button() == LeftButton)
{
if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
preserve_line_breaks = TRUE;
actSel = 0;
//FIXME: emits a release event even if the mouse is
// outside the range. The procedure used in `mouseMoveEvent'
// applies here, too.
QPoint tL = contentsRect().topLeft();
int tLx = tL.x();
int tLy = tL.y();
if (!mouse_marks && !(ev->state() & ShiftButton))
emit mouseSignal( 3, // release
(ev->x()-tLx-blX)/font_w + 1,
(ev->y()-tLy-bY)/font_h + 1 );
releaseMouse();
}
}
void Widget::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 Widget::focusInEvent( QFocusEvent * )
{
// do nothing, to prevent repainting
}
void Widget::focusOutEvent( QFocusEvent * )
{
// do nothing, to prevent repainting
}
bool Widget::focusNextPrevChild( bool next )
{
if (next)
return false; // This disables changing the active part in konqueror
// when pressing Tab
return QFrame::focusNextPrevChild( next );
}
int Widget::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 Widget::setMouseMarks(bool on)
{
mouse_marks = on;
setCursor( mouse_marks ? ibeamCursor : arrowCursor );
}
/* ------------------------------------------------------------------------- */
/* */
/* Clipboard */
/* */
/* ------------------------------------------------------------------------- */
#undef KeyPress
void Widget::emitSelection()
// Paste Clipboard by simulating keypress events
{
#ifndef QT_NO_CLIPBOARD
QString text = QApplication::clipboard()->text();
if ( ! text.isNull() )
{
text.replace(QRegExp("\n"), "\r");
QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
emit keyPressedSignal(&e); // expose as a big fat keypress event
emit clearSelectionSignal();
}
#endif
}
void Widget::emitText(QString text)
{
QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
emit keyPressedSignal(&e); // expose as a big fat keypress event
}
void Widget::pasteClipboard( )
{
emitSelection();
}
void Widget::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 Widget::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 Widget::doScroll(int lines)
{
scrollbar->setValue(scrollbar->value()+lines);
}
bool Widget::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 Widget won't
// know where the current selection is.
// qDebug("key pressed is 0x%x",ke->key());
if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker
// qDebug("key pressed 2 is 0x%x",ke->key());
emitText("\\"); // expose
} 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 Widget::frameChanged()
{
propagateSize();
update();
}
/* ------------------------------------------------------------------------- */
/* */
/* Sound */
/* */
/* ------------------------------------------------------------------------- */
void Widget::Bell()
{
QApplication::beep();
}
/* ------------------------------------------------------------------------- */
/* */
/* Auxiluary */
/* */
/* ------------------------------------------------------------------------- */
void Widget::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 Widget::calcGeometry()
{
//FIXME: set rimX == rimY == 0 when running in full screen mode.
scrollbar->resize(QApplication::style().scrollBarExtent().width(),
contentsRect().height());
switch(scrollLoc)
{
case SCRNONE :
columns = ( contentsRect().width() - 2 * rimX ) / font_w;
blX = (contentsRect().width() - (columns*font_w) ) / 2;
brX = blX;
scrollbar->hide();
break;
case SCRLEFT :
columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
blX = brX + scrollbar->width();
scrollbar->move(contentsRect().topLeft());
scrollbar->show();
break;
case SCRRIGHT:
columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
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;
}
void Widget::makeImage()
//FIXME: rename 'calcGeometry?
{
calcGeometry();
image = (Character*) malloc(lines*columns*sizeof(Character));
clearImage();
}
// calculate the needed size
QSize Widget::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 Widget::sizeHint() const
{
return size();
}
void Widget::styleChange(QStyle &)
{
propagateSize();
}
#ifndef QT_NO_DRAGANDDROP
/* --------------------------------------------------------------------- */
/* */
/* Drag & Drop */
/* */
/* --------------------------------------------------------------------- */
void Widget::dragEnterEvent(QDragEnterEvent* e)
{
e->accept(QTextDrag::canDecode(e) ||
QUriDrag::canDecode(e));
}
void Widget::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());
QByteArray tmp;
// ibot: this should be pretty wrong...
- currentSession->layer()->send( tmp.setRawData( dropText.local8Bit()));
+ // now it sends to the right layer
+ currentSession-> emulationLayer()->send( tmp.setRawData( 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());
QByteArray tmp;
- currentSession->layer()->send( tmp.setRawData( dropText.local8Bit()));
+ currentSession->emulationLayer()->send( tmp.setRawData( dropText.local8Bit()));
}
// Paste it
}
}
#endif
void Widget::drop_menu_activated(int item)
{
#ifndef QT_NO_DRAGANDDROP
QByteArray tmp;
switch (item)
{
case 0: // paste
//currentSession->getEmulation()->sendString(dropText.local8Bit());
- currentSession->layer()->send( tmp.setRawData( dropText.local8Bit()));
+ currentSession->emulationLayer()->send( tmp.setRawData( dropText.local8Bit()));
// KWM::activate((Window)this->winId());
break;
case 1: // cd ...
//currentSession->getEmulation()->sendString("cd ");
tmp.setRawData( "cd " );
- currentSession->layer()->send( tmp );
+ currentSession->emulationLayer()->send( tmp );
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
QByteArray tmp2;
tmp.setRawDate( dropText.local8Bit() + "\n" );
//currentSession->getEmulation()->sendString(dropText.local8Bit());
//currentSession->getEmulation()->sendString("\n");
- currentSession->layer()->send( tmp );
+ currentSession->emulationLayer()->send( tmp );
// KWM::activate((Window)this->winId());
break;
}
#endif
}
diff --git a/noncore/apps/opie-console/widget_layer.h b/noncore/apps/opie-console/widget_layer.h
index 5bd2ef9..01a4614 100644
--- a/noncore/apps/opie-console/widget_layer.h
+++ b/noncore/apps/opie-console/widget_layer.h
@@ -1,254 +1,255 @@
/* -------------------------------------------------------------------------- */
/* */
/* [widget_layer.h] Widget Layer */
/* */
/* -------------------------------------------------------------------------- */
// proposal of a widget Layer in opie-console
//
// fellow devels:
// just mail me (ibotty@web.de), what you additionally need from the main widget
// (or say in chat)
#ifndef WIDGET_LAYER_H
#define WIDGET_LAYER_H
// qt includes
#include <qapplication.h>
#include <qframe.h>
#include <qarray.h>
#include <qtimer.h>
#include <qkeycode.h>
#include <qclipboard.h>
// opie-console includes
#include "session.h"
#include "common.h"
#include "profile.h"
/*
* given a pseudo location ( column, line ),
* returns the actual index, in the QArray<Character>
*/
#define loc(X,Y) ((Y)*m_columns+(X))
class WidgetLayer : public QFrame
{ Q_OBJECT
public:
/**
* constructor
* @param const Profile &config, the configuration for this widget
* @param QWidget *parent, the parent widget
* @param const char *name, the name of the widget, defaults to ""
*/
WidgetLayer( const Profile& config, QWidget *parent=0, const char *name=0 );
/**
* destructor
*/
virtual ~WidgetLayer();
public:
/**
* sets the image
* @param QArray<Character> const newimg, the new image
* @param int lines, lines count of newimg
* @param int columns, columns count of newimg
*/
virtual void setImage( QArray<Character> const newimg, int lines, int colums ) = 0;
/**
* annoy the user
*/
void bell();
/**
* @return int m_lines, the lines count
*/
int lines() { return m_lines; }
/**
* @return int m_columns, the columns count
*/
int columns() { return m_columns; }
/**
* insert current selection (currently this is only the clipboard)
*/
void insertSelection();
/**
* insert text
* @param QString text, the text to be inserted
*/
void insertText( QString text );
/**
* set selection (clipboard) to text
* @param const QString &text, the text to be selected
*/
void setSelection( const QString &text );
/**
* paste content of clipboard
*/
void pasteClipboard();
/**
* reload configuration
+ * @param const Profile& config, the config to be used (may be the same as in constructor)
*/
- virtual void reloadConfig() = 0;
+ virtual void reloadConfig( const Profile& config ) = 0;
/**
* sets the scrollbar (if implemented by successor of this class)
*/
virtual void setScroll( int cursor, int slines );
/**
* scrolls (if implemented, by successor of this class)
* @param int value, how much the widget should scroll up (positive value) or down (negative value)
*/
virtual void scroll( int value );
signals:
/**
* key was pressed
*/
void keyPressed( QKeyEvent *e );
/**
* whenever Mouse selects something
* @param int button, the button that us pressed :
* 0 left Button
* 3 Button released
* @param int x, x position
* @param int y, y position
*
* // numbering due to layout in old TEWidget
*/
void mousePressed( int button, int x, int y );
/**
* size of image changed
* @param int lines, line count of new size
* @param int columns, column count of new size
*/
void imageSizeChanged( int lines, int columns );
/**
* cursor in history changed
* @param int value, value of history cursor
*/
void historyCursorChanged( int value );
/**
* selection should be cleared
*/
void selectionCleared();
/**
* selection begin
* @param const int x, x position
* @param const int y, y position
*/
void selectionBegin( const int x, const int y );
/**
* selection extended
* (from begin (s.a.) to x, y)
* @param const int x, x position
* @param const int y, y position
*/
void selectionExtended( const int x, const int y );
/**
* selection end
* @param const bool lineBreakPreserve, preserve line breaks in selection
*/
void selectionEnd( const bool lineBreakPreserve );
// protected methods
protected:
// image operations
/**
* changes image, to suit new size
* TODO: find meaningful name!
*/
void propagateSize();
/**
*determines count of lines and columns
*/
virtual void calcGeometry() = 0;
/**
* makes an empty image
*/
void makeImage();
/**
* clears the image
*/
void clearImage();
protected slots:
/**
* clear selection
*/
void onClearSelection();
// protected vars
protected:
/**
* current Session
*/
Session *m_session;
/**
* current character image
*
* a Character at loc( column, line )
* has the actual index:
* ix = line * m_columns + column;
*
* use loc( x, y ) macro to access.
*/
QArray<Character> m_image;
/**
* lines count
*/
int m_lines;
/**
* columns count
*/
int m_columns;
/**
* clipboard
*/
QClipboard* m_clipboard;
/**
* whether widget is resizing
*/
bool m_resizing;
};
#endif // WIDGET_LAYER_H