-rw-r--r-- | noncore/apps/opie-console/emulation_layer.cpp~ | 373 | ||||
-rw-r--r-- | noncore/apps/opie-console/widget.cpp~ | 1291 |
2 files changed, 0 insertions, 1664 deletions
diff --git a/noncore/apps/opie-console/emulation_layer.cpp~ b/noncore/apps/opie-console/emulation_layer.cpp~ deleted file mode 100644 index e65fd4b..0000000 --- a/noncore/apps/opie-console/emulation_layer.cpp~ +++ b/dev/null @@ -1,373 +0,0 @@ -/* -------------------------------------------------------------------------- */ -/* */ -/* [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> */ -/* */ -/* -------------------------------------------------------------------------- */ -/* ------------------------------------------------------------------------- */ -/* */ -/* Modified to suit opie-console */ -/* */ -/* Copyright (C) 2002 by opie developers <opie@handhelds.org> */ -/* */ -/* ------------------------------------------------------------------------- */ - -/*! \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 "emulation_layer.h" -#include "widget.h" -#include "TEScreen.h" -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <qkeycode.h> - - -/* ------------------------------------------------------------------------- */ -/* */ -/* EmulationLayer */ -/* */ -/* ------------------------------------------------------------------------- */ - -#define CNTL(c) ((c)-'@') - -/*! -*/ - -EmulationLayer::EmulationLayer(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()) ); -} - -/*! -*/ - -EmulationLayer::~EmulationLayer() -{ - delete screen[0]; - delete screen[1]; - bulk_timer.stop(); -} - -/*! change between primary and alternate screen -*/ - -void EmulationLayer::setScreen(int n) -{ - scr = screen[n&1]; -} - -void EmulationLayer::setHistory(bool on) -{ - screen[0]->setScroll(on); - if (!connected) return; - showBulk(); -} - -bool EmulationLayer::history() -{ - return screen[0]->hasScroll(); -} - -void EmulationLayer::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 EmulationLayer::setKeytrans(int no) -{ - keytrans = KeyTrans::find(no); -} - -void EmulationLayer::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 EmulationLayer::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 EmulationLayer::onKeyPress( QKeyEvent* ev ) -{ - if (!connected) return; // someone else gets the keys - if (scr->getHistCursor() != scr->getHistLines()); - scr->setHistCursor(scr->getHistLines()); - if (!ev->text().isEmpty()) - { // A block of text - // Note that the text is proper unicode. - // We should do a conversion here, but since this - // routine will never be used, we simply emit plain ascii. - sendString( ev->text().ascii() ); //,ev->text().length()); - } - else if (ev->ascii()>0) - { - QByteArray c = QByteArray( 1 ); - c.at( 0 ) = ev->ascii(); - // ibot: qbytearray is emited not char* - emit sndBlock( (QByteArray) c ); - } -} - -// Unblocking, Byte to Unicode translation --------------------------------- -- - -/* - We are doing code conversion from locale to unicode first. -*/ - -void EmulationLayer::onRcvBlock(const QByteArray &s ) -{ - bulkStart(); - bulk_incnt += 1; - for (int i = 0; i < s.size(); i++) - { - //TODO: ibot: maybe decoding qbytearray to unicode in io_layer? - 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 EmulationLayer::onSelectionBegin(const int x, const int y) { - if (!connected) return; - scr->setSelBeginXY(x,y); - showBulk(); -} - -void EmulationLayer::onSelectionExtend(const int x, const int y) { - if (!connected) return; - scr->setSelExtentXY(x,y); - showBulk(); -} - -void EmulationLayer::setSelection(const BOOL preserve_line_breaks) { - if (!connected) return; - QString t = scr->getSelText(preserve_line_breaks); - if (!t.isNull()) gui->setSelection(t); -} - -void EmulationLayer::clearSelection() { - if (!connected) return; - scr->clearSelection(); - showBulk(); -} - -// Refreshing -------------------------------------------------------------- -- - -#define BULK_TIMEOUT 20 - -/*! - called when \n comes in. Evtl. triggers showBulk at endBulk -*/ - -void EmulationLayer::bulkNewline() -{ - bulk_nlcnt += 1; - bulk_incnt = 0; // reset bulk counter since `nl' rule applies -} - -/*! -*/ - -void EmulationLayer::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 EmulationLayer::bulkStart() -{ - if (bulk_timer.isActive()) bulk_timer.stop(); -} - -void EmulationLayer::bulkEnd() -{ - if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 ) - showBulk(); // resets bulk_??cnt to 0, too. - else - bulk_timer.start(BULK_TIMEOUT,TRUE); -} - -void EmulationLayer::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 EmulationLayer::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 EmulationLayer::onHistoryCursorChange(int cursor) -{ - if (!connected) return; - scr->setHistCursor(cursor); - showBulk(); -} - -void EmulationLayer::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/widget.cpp~ b/noncore/apps/opie-console/widget.cpp~ deleted file mode 100644 index e403015..0000000 --- a/noncore/apps/opie-console/widget.cpp~ +++ b/dev/null @@ -1,1291 +0,0 @@ -/* ------------------------------------------------------------------------ */ -/* */ -/* [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 had to create a QByteArray before... - -TODO: -alter TEWidget to use only QByteArray, where applicable. -*/ - - - -/*! \class TEWidget - - \brief Visible screen contents - - This class is responsible to map the `image' of a terminal emulation to the - display. All the dependency of the emulation to a specific GUI or toolkit is - localized here. Further, this widget has no knowledge about being part of an - emulation, it simply work within the terminal emulation framework by exposing - size and key events and by being ordered to show a new image. - - <ul> - <li> The internal image has the size of the widget (evtl. rounded up) - <li> The external image used in setImage can have any size. - <li> (internally) the external image is simply copied to the internal - when a setImage happens. During a resizeEvent no painting is done - a paintEvent is expected to follow anyway. - </ul> - - \sa TEScreen \sa Emulation -*/ - -/* FIXME: - - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent - - 'font_a' not used in mouse events - - add destructor -*/ - -/* TODO - - evtl. be sensitive to `paletteChange' while using default colors. - - set different 'rounding' styles? I.e. have a mode to show clipped chars? -*/ - -// #include "config.h" -#include "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 TEWidget::getDefaultBackColor() -{ - return color_table[DEFAULT_BACK_COLOR].color; -} - -const ColorEntry* TEWidget::getColorTable() const -{ - return color_table; -} - -const ColorEntry* TEWidget::getdefaultColorTable() const -{ - return base_color_table; -} - - -const QPixmap *TEWidget::backgroundPixmap() -{ - static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm"); - const QPixmap *pm = bg; - return pm; -} - -void TEWidget::setColorTable(const ColorEntry table[]) -{ - for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i]; - - const QPixmap* pm = backgroundPixmap(); - if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color); - update(); -} - -//FIXME: add backgroundPixmapChanged. - -/* ------------------------------------------------------------------------- */ -/* */ -/* Font */ -/* */ -/* ------------------------------------------------------------------------- */ - -/* - The VT100 has 32 special graphical characters. The usual vt100 extended - xterm fonts have these at 0x00..0x1f. - - QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals - come in here as proper unicode characters. - - We treat non-iso10646 fonts as VT100 extended and do the requiered mapping - from unicode to 0x00..0x1f. The remaining translation is then left to the - QCodec. -*/ - -// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i. - -unsigned short vt100_graphics[32] = -{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15 - 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, - 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, - 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534, - 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7 -}; - -static QChar vt100extended(QChar c) -{ - switch (c.unicode()) - { - case 0x25c6 : return 1; - case 0x2592 : return 2; - case 0x2409 : return 3; - case 0x240c : return 4; - case 0x240d : return 5; - case 0x240a : return 6; - case 0x00b0 : return 7; - case 0x00b1 : return 8; - case 0x2424 : return 9; - case 0x240b : return 10; - case 0x2518 : return 11; - case 0x2510 : return 12; - case 0x250c : return 13; - case 0x2514 : return 14; - case 0x253c : return 15; - case 0xf800 : return 16; - case 0xf801 : return 17; - case 0x2500 : return 18; - case 0xf803 : return 19; - case 0xf804 : return 20; - case 0x251c : return 21; - case 0x2524 : return 22; - case 0x2534 : return 23; - case 0x252c : return 24; - case 0x2502 : return 25; - case 0x2264 : return 26; - case 0x2265 : return 27; - case 0x03c0 : return 28; - case 0x2260 : return 29; - case 0x00a3 : return 30; - case 0x00b7 : return 31; - } - return c; -} - -static QChar identicalMap(QChar c) -{ - return c; -} - -void TEWidget::fontChange(const QFont &) -{ - QFontMetrics fm(font()); - font_h = fm.height(); - font_w = fm.maxWidth(); - font_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 TEWidget::setVTFont(const QFont& f) -{ - QFrame::setFont(f); -} - -QFont TEWidget::getVTFont() { - return font(); -} - -void TEWidget::setFont(const QFont &) -{ - // ignore font change request if not coming from konsole itself -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Constructor / Destructor */ -/* */ -/* ------------------------------------------------------------------------- */ - -TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) -{ -#ifndef QT_NO_CLIPBOARD - cb = QApplication::clipboard(); - QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), - this, SLOT(onClearSelection()) ); -#endif - - scrollbar = new QScrollBar(this); - scrollbar->setCursor( arrowCursor ); - connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); - - 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) -TEWidget::~TEWidget() -{ - qApp->removeEventFilter( this ); - if (image) free(image); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Display Operations */ -/* */ -/* ------------------------------------------------------------------------- */ - -/*! - attributed string draw primitive -*/ - -void TEWidget::drawAttrStr(QPainter &paint, QRect rect, - QString& str, ca attr, BOOL pm, BOOL clear) -{ - if (pm && color_table[attr.b].transparent) - { - paint.setBackgroundMode( TransparentMode ); - if (clear) erase(rect); - } - else - { - if (blinking) - paint.fillRect(rect, color_table[attr.b].color); - else - { - paint.setBackgroundMode( OpaqueMode ); - paint.setBackgroundColor( color_table[attr.b].color ); - } - } - - if (color_table[attr.f].bold) - paint.setPen(QColor( 0x8F, 0x00, 0x00 )); - else - paint.setPen(color_table[attr.f].color); - - paint.drawText(rect.x(),rect.y()+font_a, str); - - if (attr.r & RE_UNDERLINE) - paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); -} - -/*! - The image can only be set completely. - - The size of the new image may or may not match the size of the widget. -*/ - -void TEWidget::setImage(const ca* const newimg, int lines, int columns) -{ int y,x,len; - const QPixmap* pm = backgroundPixmap(); - QPainter paint; - setUpdatesEnabled(FALSE); - paint.begin( this ); -HCNT("setImage"); - - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - hasBlinker = FALSE; - - int cf = -1; // undefined - int cb = -1; // undefined - int cr = -1; // undefined - - int lins = QMIN(this->lines, QMAX(0,lines )); - int cols = QMIN(this->columns,QMAX(0,columns)); - QChar *disstrU = new QChar[cols]; - -//{ static int cnt = 0; printf("setImage %d\n",cnt++); } - for (y = 0; y < lins; y++) - { - const ca* lcl = &image[y*this->columns]; - const ca* const ext = &newimg[y*columns]; - if (!resizing) // not while resizing, we're expecting a paintEvent - for (x = 0; x < cols; x++) - { - hasBlinker |= (ext[x].r & RE_BLINK); - if (ext[x] != lcl[x]) - { - cr = ext[x].r; - cb = ext[x].b; - if (ext[x].f != cf) cf = ext[x].f; - int lln = cols - x; - disstrU[0] = fontMap(ext[x+0].c); - for (len = 1; len < lln; len++) - { - if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || - ext[x+len] == lcl[x+len] ) - break; - disstrU[len] = fontMap(ext[x+len].c); - } - QString unistr(disstrU,len); - drawAttrStr(paint, - QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), - unistr, ext[x], pm != NULL, true); - x += len - 1; - } - } - // finally, make `image' become `newimg'. - memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); - } - drawFrame( &paint ); - paint.end(); - setUpdatesEnabled(TRUE); - if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms - if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } - delete [] disstrU; -} - -// paint Event //////////////////////////////////////////////////// - -/*! - The difference of this routine vs. the `setImage' is, - that the drawing does not include a difference analysis - between the old and the new image. Instead, the internal - image is used and the painting bound by the PaintEvent box. -*/ - -void TEWidget::paintEvent( QPaintEvent* pe ) -{ - -//{ static int cnt = 0; printf("paint %d\n",cnt++); } - const QPixmap* pm = backgroundPixmap(); - QPainter paint; - setUpdatesEnabled(FALSE); - paint.begin( this ); - paint.setBackgroundMode( TransparentMode ); -HCNT("paintEvent"); - - // Note that the actual widget size can be slightly larger - // that the image (the size is truncated towards the smaller - // number of characters in `resizeEvent'. The paint rectangle - // can thus be larger than the image, but less then the size - // of one character. - - QRect rect = pe->rect().intersect(contentsRect()); - - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - - int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w)); - int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h)); - int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w)); - int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h)); - - /* - printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly, - rect.left(), rect.right(), rect.top(), rect.bottom()); - */ - - // if (pm != NULL && color_table[image->b].transparent) - // erase(rect); - // BL: I have no idea why we need this, and it breaks the refresh. - - QChar *disstrU = new QChar[columns]; - for (int y = luy; y <= rly; y++) - for (int x = lux; x <= rlx; x++) - { - int len = 1; - disstrU[0] = fontMap(image[loc(x,y)].c); - int cf = image[loc(x,y)].f; - int cb = image[loc(x,y)].b; - int cr = image[loc(x,y)].r; - while (x+len <= rlx && - image[loc(x+len,y)].f == cf && - image[loc(x+len,y)].b == cb && - image[loc(x+len,y)].r == cr ) - { - disstrU[len] = fontMap(image[loc(x+len,y)].c); - len += 1; - } - QString unistr(disstrU,len); - drawAttrStr(paint, - QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), - unistr, image[loc(x,y)], pm != NULL, false); - x += len - 1; - } - delete [] disstrU; - drawFrame( &paint ); - paint.end(); - setUpdatesEnabled(TRUE); -} - -void TEWidget::blinkEvent() -{ - blinking = !blinking; - repaint(FALSE); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Resizing */ -/* */ -/* ------------------------------------------------------------------------- */ - -void TEWidget::resizeEvent(QResizeEvent* ev) -{ -// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); - //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); - //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); - //printf("curren: %d,%d\n",width(),height()); -HCNT("resizeEvent"); - - // see comment in `paintEvent' concerning the rounding. - //FIXME: could make a routine here; check width(),height() - assert(ev->size().width() == width()); - assert(ev->size().height() == height()); - - propagateSize(); -} - -void TEWidget::propagateSize() -{ - ca* oldimg = image; - int oldlin = lines; - int oldcol = columns; - makeImage(); - // we copy the old image to reduce flicker - int lins = QMIN(oldlin,lines); - int cols = QMIN(oldcol,columns); - if (oldimg) - { - for (int lin = 0; lin < lins; lin++) - memcpy((void*)&image[columns*lin], - (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); - free(oldimg); //FIXME: try new,delete - } - else - clearImage(); - - //NOTE: control flows from the back through the chest right into the eye. - // `emu' will call back via `setImage'. - - resizing = TRUE; - emit changedImageSizeSignal(lines, columns); // expose resizeEvent - resizing = FALSE; -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Scrollbar */ -/* */ -/* ------------------------------------------------------------------------- */ - -void TEWidget::scrollChanged(int) -{ - emit changedHistoryCursor(scrollbar->value()); //expose -} - -void TEWidget::setScroll(int cursor, int slines) -{ - disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); - scrollbar->setRange(0,slines); - scrollbar->setSteps(1,lines); - scrollbar->setValue(cursor); - connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); -} - -void TEWidget::setScrollbarLocation(int loc) -{ - if (scrollLoc == loc) return; // quickly - scrollLoc = loc; - propagateSize(); - update(); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Mouse */ -/* */ -/* ------------------------------------------------------------------------- */ - -/*! - Three different operations can be performed using the mouse, and the - routines in this section serve all of them: - - 1) The press/release events are exposed to the application - 2) Marking (press and move left button) and Pasting (press middle button) - 3) The right mouse button is used from the configuration menu - - NOTE: During the marking process we attempt to keep the cursor within - the bounds of the text as being displayed by setting the mouse position - whenever the mouse has left the text area. - - Two reasons to do so: - 1) QT does not allow the `grabMouse' to confine-to the TEWidget. - Thus a `XGrapPointer' would have to be used instead. - 2) Even if so, this would not help too much, since the text area - of the TEWidget is normally not identical with it's bounds. - - The disadvantage of the current handling is, that the mouse can visibly - leave the bounds of the widget and is then moved back. Because of the - current construction, and the reasons mentioned above, we cannot do better - without changing the overall construction. -*/ - -/*! -*/ - -void TEWidget::mousePressEvent(QMouseEvent* ev) -{ -//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); - if ( !contentsRect().contains(ev->pos()) ) return; - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - - word_selection_mode = FALSE; - -//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 TEWidget::mouseMoveEvent(QMouseEvent* ev) -{ - // for auto-hiding the cursor, we need mouseTracking - if (ev->state() == NoButton ) return; - - if (actSel == 0) return; - - // don't extend selection while pasting - if (ev->state() & MidButton) return; - - //if ( !contentsRect().contains(ev->pos()) ) return; - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - int scroll = scrollbar->value(); - - // we're in the process of moving the mouse with the left button pressed - // the mouse cursor will kept catched within the bounds of the text in - // this widget. - - // Adjust position within text area bounds. See FIXME above. - QPoint pos = ev->pos(); - if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); - if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); - if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); - if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); - // check if we produce a mouse move event by this - if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); - - if ( pos.y() == tLy+bY+lines*font_h-1 ) - { - scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward - } - if ( pos.y() == tLy+bY ) - { - scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback - } - - QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); - QPoint ohere; - bool swapping = FALSE; - - if ( word_selection_mode ) - { - // Extend to word boundaries - int i; - int selClass; - - bool left_not_right = ( here.y() < iPntSel.y() || - here.y() == iPntSel.y() && here.x() < iPntSel.x() ); - bool old_left_not_right = ( pntSel.y() < iPntSel.y() || - pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); - swapping = left_not_right != old_left_not_right; - - // Find left (left_not_right ? from here : from start) - QPoint left = left_not_right ? here : iPntSel; - i = loc(left.x(),left.y()); - selClass = charClass(image[i].c); - while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) - { i--; left.rx()--; } - - // Find left (left_not_right ? from start : from here) - QPoint right = left_not_right ? iPntSel : here; - i = loc(right.x(),right.y()); - selClass = charClass(image[i].c); - while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) - { i++; right.rx()++; } - - // Pick which is start (ohere) and which is extension (here) - if ( left_not_right ) - { - here = left; ohere = right; - } - else - { - here = right; ohere = left; - } - } - - if (here == pntSel && scroll == scrollbar->value()) return; // not moved - - if ( word_selection_mode ) { - if ( actSel < 2 || swapping ) { - emit beginSelectionSignal( ohere.x(), ohere.y() ); - } - } else if ( actSel < 2 ) { - emit beginSelectionSignal( pntSel.x(), pntSel.y() ); - } - - actSel = 2; // within selection - pntSel = here; - emit extendSelectionSignal( here.x(), here.y() ); -} - -void TEWidget::mouseReleaseEvent(QMouseEvent* ev) -{ -//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); - if ( ev->button() == LeftButton) - { - if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks); - preserve_line_breaks = TRUE; - actSel = 0; - - //FIXME: emits a release event even if the mouse is - // outside the range. The procedure used in `mouseMoveEvent' - // applies here, too. - - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - - if (!mouse_marks && !(ev->state() & ShiftButton)) - emit mouseSignal( 3, // release - (ev->x()-tLx-blX)/font_w + 1, - (ev->y()-tLy-bY)/font_h + 1 ); - releaseMouse(); - } -} - -void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev) -{ - if ( ev->button() != LeftButton) return; - - QPoint tL = contentsRect().topLeft(); - int tLx = tL.x(); - int tLy = tL.y(); - QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); - - // pass on double click as two clicks. - if (!mouse_marks && !(ev->state() & ShiftButton)) - { - emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button - emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release - emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button - return; - } - - - emit clearSelectionSignal(); - QPoint bgnSel = pos; - QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); - int i = loc(bgnSel.x(),bgnSel.y()); - iPntSel = bgnSel; - - word_selection_mode = TRUE; - - // find word boundaries... - int selClass = charClass(image[i].c); - { - // set the start... - int x = bgnSel.x(); - while ( x > 0 && charClass(image[i-1].c) == selClass ) - { i--; x--; } - bgnSel.setX(x); - emit beginSelectionSignal( bgnSel.x(), bgnSel.y() ); - - // set the end... - i = loc( endSel.x(), endSel.y() ); - x = endSel.x(); - while( x < columns-1 && charClass(image[i+1].c) == selClass ) - { i++; x++ ; } - endSel.setX(x); - actSel = 2; // within selection - emit extendSelectionSignal( endSel.x(), endSel.y() ); - emit endSelectionSignal(preserve_line_breaks); - preserve_line_breaks = TRUE; - } -} - -void TEWidget::focusInEvent( QFocusEvent * ) -{ - - // do nothing, to prevent repainting -} - - -void TEWidget::focusOutEvent( QFocusEvent * ) -{ - // do nothing, to prevent repainting -} - -bool TEWidget::focusNextPrevChild( bool next ) -{ - if (next) - return false; // This disables changing the active part in konqueror - // when pressing Tab - return QFrame::focusNextPrevChild( next ); -} - - -int TEWidget::charClass(char ch) const -{ - // This might seem like overkill, but imagine if ch was a Unicode - // character (Qt 2.0 QChar) - it might then be sensible to separate - // the different language ranges, etc. - - if ( isspace(ch) ) return ' '; - - static const char *word_characters = ":@-./_~"; - if ( isalnum(ch) || strchr(word_characters, ch) ) - return 'a'; - - // Everything else is weird - return 1; -} - -void TEWidget::setMouseMarks(bool on) -{ - mouse_marks = on; - setCursor( mouse_marks ? ibeamCursor : arrowCursor ); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Clipboard */ -/* */ -/* ------------------------------------------------------------------------- */ - -#undef KeyPress - -void TEWidget::emitSelection() -// Paste Clipboard by simulating keypress events -{ -#ifndef QT_NO_CLIPBOARD - QString text = QApplication::clipboard()->text(); - if ( ! text.isNull() ) - { - text.replace(QRegExp("\n"), "\r"); - QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); - emit keyPressedSignal(&e); // expose as a big fat keypress event - emit clearSelectionSignal(); - } -#endif -} - -void TEWidget::emitText(QString text) -{ - QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); - emit keyPressedSignal(&e); // expose as a big fat keypress event -} - -void TEWidget::pasteClipboard( ) -{ - emitSelection(); -} - -void TEWidget::setSelection(const QString& t) -{ -#ifndef QT_NO_CLIPBOARD - // Disconnect signal while WE set the clipboard - QObject *cb = QApplication::clipboard(); - QObject::disconnect( cb, SIGNAL(dataChanged()), - this, SLOT(onClearSelection()) ); - - QApplication::clipboard()->setText(t); - - QObject::connect( cb, SIGNAL(dataChanged()), - this, SLOT(onClearSelection()) ); -#endif -} - -void TEWidget::onClearSelection() -{ - emit clearSelectionSignal(); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Keyboard */ -/* */ -/* ------------------------------------------------------------------------- */ - -//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' -// due to a bug in `QT' or the ignorance of the author to prevent -// repaint events being emitted to the screen whenever one leaves -// or reenters the screen to/from another application. -// -// Troll says one needs to change focusInEvent() and focusOutEvent(), -// which would also let you have an in-focus cursor and an out-focus -// cursor like xterm does. - -// for the auto-hide cursor feature, I added empty focusInEvent() and -// focusOutEvent() so that update() isn't called. -// For auto-hide, we need to get keypress-events, but we only get them when -// we have focus. - -void TEWidget::doScroll(int lines) -{ - scrollbar->setValue(scrollbar->value()+lines); -} - -bool TEWidget::eventFilter( QObject *obj, QEvent *e ) -{ - if ( (e->type() == QEvent::Accel || - e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { - static_cast<QKeyEvent *>( e )->ignore(); - return true; - } - if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) - return FALSE; // not us - if ( e->type() == QEvent::Wheel) { - QApplication::sendEvent(scrollbar, e); - } - -#ifdef FAKE_CTRL_AND_ALT - static bool control = FALSE; - static bool alt = FALSE; -// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); - bool dele=FALSE; - if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { - QKeyEvent* ke = (QKeyEvent*)e; - bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); - switch (ke->key()) { - case Key_F9: // let this be "Control" - control = keydown; - e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); - dele=TRUE; - break; - case Key_F13: // let this be "Alt" - alt = keydown; - e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); - dele=TRUE; - break; - default: - if ( control ) { - int a = toupper(ke->ascii())-64; - if ( a >= 0 && a < ' ' ) { - e = new QKeyEvent(e->type(), ke->key(), - a, ke->state()|ControlButton, QChar(a,0)); - dele=TRUE; - } - } - if ( alt ) { - e = new QKeyEvent(e->type(), ke->key(), - ke->ascii(), ke->state()|AltButton, ke->text()); - dele=TRUE; - } - } - } -#endif - - if ( e->type() == QEvent::KeyPress ) { - QKeyEvent* ke = (QKeyEvent*)e; - actSel=0; // Key stroke implies a screen update, so TEWidget won't - // know where the current selection is. - -// qDebug("key pressed is 0x%x",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 TEWidget::frameChanged() -{ - propagateSize(); - update(); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Sound */ -/* */ -/* ------------------------------------------------------------------------- */ - -void TEWidget::Bell() -{ - QApplication::beep(); -} - -/* ------------------------------------------------------------------------- */ -/* */ -/* Auxiluary */ -/* */ -/* ------------------------------------------------------------------------- */ - -void TEWidget::clearImage() -// initialize the image -// for internal use only -{ - for (int y = 0; y < lines; y++) - for (int x = 0; x < columns; x++) - { - image[loc(x,y)].c = 0xff; //' '; - image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; - image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; - image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; - } -} - -// Create Image /////////////////////////////////////////////////////// - -void TEWidget::calcGeometry() -{ - //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 TEWidget::makeImage() -//FIXME: rename 'calcGeometry? -{ - calcGeometry(); - image = (ca*) malloc(lines*columns*sizeof(ca)); - clearImage(); -} - -// calculate the needed size -QSize TEWidget::calcSize(int cols, int lins) const -{ - int frw = width() - contentsRect().width(); - int frh = height() - contentsRect().height(); - int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); - return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); -} - -QSize TEWidget::sizeHint() const -{ - return size(); -} - -void TEWidget::styleChange(QStyle &) -{ - propagateSize(); -} - -#ifndef QT_NO_DRAGANDDROP - -/* --------------------------------------------------------------------- */ -/* */ -/* Drag & Drop */ -/* */ -/* --------------------------------------------------------------------- */ - - -void TEWidget::dragEnterEvent(QDragEnterEvent* e) -{ - e->accept(QTextDrag::canDecode(e) || - QUriDrag::canDecode(e)); -} - -void TEWidget::dropEvent(QDropEvent* event) -{ - // The current behaviour when url(s) are dropped is - // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd - // * in all other cases, just paste - // (for non-local ones, or for a list of URLs, 'cd' is nonsense) - QStrList strlist; - int file_count = 0; - dropText = ""; - bool bPopup = true; - - if(QUriDrag::decode(event, strlist)) { - if (strlist.count()) { - for(const char* p = strlist.first(); p; p = strlist.next()) { - if(file_count++ > 0) { - dropText += " "; - bPopup = false; // more than one file, don't popup - } - -/* - KURL url(p); - if (url.isLocalFile()) { - dropText += url.path(); // local URL : remove protocol - } - else { - dropText += url.prettyURL(); - bPopup = false; // a non-local file, don't popup - } -*/ - - } - - if (bPopup) - // m_drop->popup(pos() + event->pos()); - m_drop->popup(mapToGlobal(event->pos())); - else - { - if (currentSession) { - //currentSession->getEmulation()->sendString(dropText.local8Bit()); - QByteArray tmp; - // ibot: this should be pretty wrong... - currentSession->layer()->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())); - } - // Paste it - } -} -#endif - - -void TEWidget::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())); - -// KWM::activate((Window)this->winId()); - break; - case 1: // cd ... - //currentSession->getEmulation()->sendString("cd "); - tmp.setRawData( "cd " ); - currentSession->layer()->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 ); -// KWM::activate((Window)this->winId()); - break; - } -#endif -} - |