-rw-r--r-- | core/apps/embeddedkonsole/TEWidget.cpp | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp index a989e10..8214e7d 100644 --- a/core/apps/embeddedkonsole/TEWidget.cpp +++ b/core/apps/embeddedkonsole/TEWidget.cpp @@ -205,229 +205,229 @@ static QChar vt100extended(QChar c) 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))); hScrollbar = new QScrollBar(this); hScrollbar->setCursor( arrowCursor ); hScrollbar->setOrientation(QScrollBar::Horizontal); hScrollbar->setMaximumHeight(16); - + connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int))); Config cfg("Konsole"); cfg.setGroup("ScrollBar"); switch( cfg.readNumEntry("Position",2)){ case 0: scrollLoc = SCRNONE; break; case 1: scrollLoc = SCRLEFT; break; case 2: scrollLoc = SCRRIGHT; break; }; useHorzScroll=cfg.readBoolEntry("HorzScroll",0); blinkT = new QTimer(this); connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent())); // blinking = FALSE; blinking = TRUE; resizing = FALSE; actSel = 0; image = 0; lines = 1; columns = 1; font_w = 1; font_h = 1; font_a = 1; word_selection_mode = FALSE; hposition = 0; vcolumns = 0; useBeep = true; - + setMouseMarks(TRUE); setVTFont( QFont("fixed") ); setColorTable(base_color_table); // init color table qApp->installEventFilter( this ); //FIXME: see below // KCursor::setAutoHideCursor( this, true ); // Init DnD //////////////////////////////////////////////////////////////// currentSession = NULL; // setAcceptDrops(true); // attempt // m_drop = new QPopupMenu(this); // m_drop->insertItem( QString("Paste"), 0); // m_drop->insertItem( QString("cd"), 1); // connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); // we need focus so that the auto-hide cursor feature works setFocus(); setFocusPolicy( WheelFocus ); } //FIXME: make proper destructor // Here's a start (David) TEWidget::~TEWidget() { qApp->removeEventFilter( this ); if (image) free(image); } /* ------------------------------------------------------------------------- */ /* */ /* Display Operations */ /* */ /* ------------------------------------------------------------------------- */ /*! attributed string draw primitive */ void TEWidget::drawAttrStr(QPainter &paint, QRect rect, QString& str, ca attr, BOOL pm, BOOL clear) { if (pm && color_table[attr.b].transparent) { paint.setBackgroundMode( TransparentMode ); if (clear) erase(rect); } else { if (blinking) paint.fillRect(rect, color_table[attr.b].color); else { paint.setBackgroundMode( OpaqueMode ); paint.setBackgroundColor( color_table[attr.b].color ); } } if (color_table[attr.f].bold) paint.setPen(QColor( 0x8F, 0x00, 0x00 )); else paint.setPen(color_table[attr.f].color); paint.drawText(rect.x(),rect.y()+font_a, str); if (attr.r & RE_UNDERLINE) paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); } /*! The image can only be set completely. The size of the new image may or may not match the size of the widget. */ void TEWidget::setImage(const ca* const newimg, int lines, int columns) { int y,x,len; const QPixmap* pm = backgroundPixmap(); QPainter paint; setUpdatesEnabled(FALSE); paint.begin( this ); HCNT("setImage"); QPoint tL = contentsRect().topLeft(); int tLx = tL.x(); int tLy = tL.y(); hasBlinker = FALSE; int cf = -1; // undefined int cb = -1; // undefined int cr = -1; // undefined int lins = QMIN(this->lines, QMAX(0,lines )); int cols = QMIN(this->columns,QMAX(0,columns)); QChar *disstrU = new QChar[cols]; for (y = 0; y < lins; y++) { const ca* lcl = &image[y*this->columns]; @@ -784,525 +784,525 @@ void TEWidget::mouseMoveEvent(QMouseEvent* ev) 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(); // qDebug(text); if ( ! text.isNull()) { text.replace(QRegExp("\n"), "\r"); QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); emit keyPressedSignal(&e); // expose as a big fat keypress event emit clearSelectionSignal(); } #endif } void TEWidget::emitText(QString text) { QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); emit keyPressedSignal(&e); // expose as a big fat keypress event } void TEWidget::pasteClipboard( ) { emitSelection(); } void TEWidget::setSelection(const QString& t) { #ifndef QT_NO_CLIPBOARD // Disconnect signal while WE set the clipboard QObject *cb = QApplication::clipboard(); QObject::disconnect( cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); QApplication::clipboard()->setText(t); QObject::connect( cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); #endif } void TEWidget::onClearSelection() { emit clearSelectionSignal(); } /* ------------------------------------------------------------------------- */ /* */ /* Keyboard */ /* */ /* ------------------------------------------------------------------------- */ //FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' // due to a bug in `QT' or the ignorance of the author to prevent // repaint events being emitted to the screen whenever one leaves // or reenters the screen to/from another application. // // Troll says one needs to change focusInEvent() and focusOutEvent(), // which would also let you have an in-focus cursor and an out-focus // cursor like xterm does. // for the auto-hide cursor feature, I added empty focusInEvent() and // focusOutEvent() so that update() isn't called. // For auto-hide, we need to get keypress-events, but we only get them when // we have focus. void TEWidget::doScroll(int lines) { scrollbar->setValue(scrollbar->value()+lines); } void TEWidget::doHScroll(int lines) { hScrollbar->setValue( hScrollbar->value()+lines); } bool TEWidget::eventFilter( QObject *obj, QEvent *e ) { if ( (e->type() == QEvent::Accel || e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { static_cast<QKeyEvent *>( e )->ignore(); return true; } if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) return FALSE; // not us if ( e->type() == QEvent::Wheel) { QApplication::sendEvent(scrollbar, e); } #ifdef FAKE_CTRL_AND_ALT static bool control = FALSE; static bool alt = FALSE; // qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); bool dele=FALSE; if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { QKeyEvent* ke = (QKeyEvent*)e; bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); switch (ke->key()) { case Key_F9: // let this be "Control" control = keydown; e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); dele=TRUE; break; case Key_F13: // let this be "Alt" alt = keydown; e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); dele=TRUE; break; default: if ( control ) { int a = toupper(ke->ascii())-64; if ( a >= 0 && a < ' ' ) { e = new QKeyEvent(e->type(), ke->key(), a, ke->state()|ControlButton, QChar(a,0)); dele=TRUE; } } if ( alt ) { e = new QKeyEvent(e->type(), ke->key(), ke->ascii(), ke->state()|AltButton, ke->text()); dele=TRUE; } } } #endif if ( e->type() == QEvent::KeyPress ) { QKeyEvent* ke = (QKeyEvent*)e; actSel=0; // Key stroke implies a screen update, so TEWidget won't // know where the current selection is. // qDebug("key pressed is 0x%x, ascii is 0x%x, state %d", ke->key(), ke->ascii(), ke->state()); if( ke->state() == ShiftButton && ke->key() == Key_Tab) { //lets hardcode this sucker // qDebug("key pressed 2 is 0x%x", ke->key()); emitText("\\"); // expose } else if( ke->state() == ControlButton && ke->key() == Key_V) { pasteClipboard(); } - else if( ke->state() == ControlButton && ke->key() == Key_C) { +// else if( ke->state() == ControlButton && ke->key() == Key_C) { // pasteClipboard(); - } +// } else emit keyPressedSignal(ke); // expose ke->accept(); #ifdef FAKE_CTRL_AND_ALT if ( dele ) delete e; #endif return true; // stop the event } if ( e->type() == QEvent::Enter ) { QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); } if ( e->type() == QEvent::Leave ) { QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), this, SLOT(onClearSelection()) ); } return QFrame::eventFilter( obj, e ); } /* ------------------------------------------------------------------------- */ /* */ /* Frame */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::frameChanged() { propagateSize(); update(); } /* ------------------------------------------------------------------------- */ /* */ /* Sound */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::Bell() { //#ifdef QT_QWS_SHARP //# ifndef QT_NO_COP - if(useBeep) + if(useBeep) QCopEnvelope( "QPE/TaskBar", "soundAlarm()" ); - + //# endif //#else //# ifndef QT_NO_SOUND // QSound::play(Resource::findSound("alarm")); //# endif -//#endif +//#endif // QApplication::beep(); } /* ------------------------------------------------------------------------- */ /* */ /* Auxiluary */ /* */ /* ------------------------------------------------------------------------- */ void TEWidget::clearImage() // initialize the image // for internal use only { for (int y = 0; y < lines; y++) for (int x = 0; x < columns; x++) { image[loc(x,y)].c = 0xff; //' '; image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; } } // Create Image /////////////////////////////////////////////////////// void TEWidget::calcGeometry() { int showhscrollbar = 1; int hwidth = 0; int dcolumns; Config cfg("Konsole"); cfg.setGroup("ScrollBar"); useHorzScroll=cfg.readBoolEntry("HorzScroll",0); if(vcolumns == 0) showhscrollbar = 0; if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width(); scrollbar->resize(QApplication::style().scrollBarExtent().width(), contentsRect().height() - hwidth); switch(scrollLoc) { case SCRNONE : columns = ( contentsRect().width() - 2 * rimX ) / font_w; dcolumns = columns; if(vcolumns) columns = vcolumns; blX = (contentsRect().width() - (columns*font_w) ) / 2; if(showhscrollbar) blX = -hposition * font_w; brX = blX; scrollbar->hide(); break; case SCRLEFT : columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; dcolumns = columns; if(vcolumns) columns = vcolumns; brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; if(showhscrollbar) brX = -hposition * font_w; blX = brX + scrollbar->width(); scrollbar->move(contentsRect().topLeft()); scrollbar->show(); break; case SCRRIGHT: columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; dcolumns = columns; if(vcolumns) columns = vcolumns; blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; if(showhscrollbar) blX = -hposition * font_w; brX = blX; scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); scrollbar->show(); break; } //FIXME: support 'rounding' styles lines = ( contentsRect().height() - 2 * rimY ) / font_h; bY = (contentsRect().height() - (lines *font_h)) / 2; if(showhscrollbar == 1) { hScrollbar->resize(contentsRect().width() - hwidth, hwidth); hScrollbar->setRange(0, vcolumns - dcolumns); QPoint p = contentsRect().bottomLeft(); if(scrollLoc == SCRLEFT) hScrollbar->move(QPoint(p.x()+hwidth, p.y() - hwidth)); else hScrollbar->move(QPoint(p.x(), p.y() - hwidth)); - + hScrollbar->show(); } else hScrollbar->hide(); if(showhscrollbar == 1) { lines = lines - (hwidth / font_h) - 1; if(lines < 1) lines = 1; } //FIXME: support 'rounding' styles } void TEWidget::makeImage() //FIXME: rename 'calcGeometry? { calcGeometry(); image = (ca*) malloc(lines*columns*sizeof(ca)); clearImage(); } // calculate the needed size QSize TEWidget::calcSize(int cols, int lins) const { int frw = width() - contentsRect().width(); int frh = height() - contentsRect().height(); int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); } QSize TEWidget::sizeHint() const { return size(); } void TEWidget::styleChange(QStyle &) { propagateSize(); } #ifndef QT_NO_DRAGANDDROP /* --------------------------------------------------------------------- */ /* */ /* Drag & Drop */ /* */ /* --------------------------------------------------------------------- */ void TEWidget::dragEnterEvent(QDragEnterEvent* e) { e->accept(QTextDrag::canDecode(e) || QUriDrag::canDecode(e)); } void TEWidget::dropEvent(QDropEvent* event) { // The current behaviour when url(s) are dropped is // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd // * in all other cases, just paste // (for non-local ones, or for a list of URLs, 'cd' is nonsense) QStrList strlist; int file_count = 0; dropText = ""; bool bPopup = true; if(QUriDrag::decode(event, strlist)) { if (strlist.count()) { for(const char* p = strlist.first(); p; p = strlist.next()) { if(file_count++ > 0) { dropText += " "; bPopup = false; // more than one file, don't popup } /* KURL url(p); if (url.isLocalFile()) { dropText += url.path(); // local URL : remove protocol } else { dropText += url.prettyURL(); bPopup = false; // a non-local file, don't popup } */ } if (bPopup) // m_drop->popup(pos() + event->pos()); m_drop->popup(mapToGlobal(event->pos())); else { if (currentSession) { currentSession->getEmulation()->sendString(dropText.local8Bit()); } // kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; } } |