From bcb704366cb5e333a626c18c308c7e0448a8e69f Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- ksirc/ahistlineedit.cpp | 437 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 437 insertions(+) create mode 100644 ksirc/ahistlineedit.cpp (limited to 'ksirc/ahistlineedit.cpp') diff --git a/ksirc/ahistlineedit.cpp b/ksirc/ahistlineedit.cpp new file mode 100644 index 00000000..72e6da35 --- /dev/null +++ b/ksirc/ahistlineedit.cpp @@ -0,0 +1,437 @@ +/************************************************************************ + + AHistLineEdit + + $$Id$$ + + An extended KLineEdit with history scroll back and focus controls. + + Function: + + Each time a line is saved, to a max of 256, when the user hits enter. + The arrow keys are used to scroll through the history list, rolling + around at the end. + + When focus is gained or lost it emits the appropriate signals. This + is so the toplevel can track who has focus. + + signals: + gotFocus: duh! + + lostFocus: no shit sherlock + + Implementation: + + protected: + + keyPressEvent: Filter key presses looking for up arrow, down + arrow or enter. UpArrow saves the current line at the end then + scroll. No more processing. DownArrow does the opposite. Enter + saves the line, but then passes on the event for normal + processing. + + focusInEvent: emits needed signal + focusOutEvent: ditto + + Variables: + QStrList: current list of history items. + current: what I think is the current list item. + +*************************************************************************/ + + +#include "ahistlineedit.h" +#include "colorpicker.h" +#include "ksopts.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +aHistLineEdit::aHistLineEdit(QWidget *parent, const char *name) + : QTextEdit(parent, name) +{ + + m_drawrect = false; + m_height = 0; + current = hist.append(QString::null); // Set the current as blank + setWrapPolicy(QTextEdit::AtWordOrDocumentBoundary); + setVScrollBarMode( AlwaysOff ); + setHScrollBarMode( AlwaysOff ); + +// connect( this, SIGNAL( returnPressed () ), this, SLOT( slotReturn() ) ); + connect( this, SIGNAL( textChanged () ), this, SLOT( slotMaybeResize() ) ); + + setTabChangesFocus(true); + setTextFormat(PlainText); + + slotMaybeResize(); // setup initial size. + + setLineWidth(2); + +} + +void aHistLineEdit::setCursorPosition ( int index ) +{ + QTextEdit::setCursorPosition(0, index); +} + +int aHistLineEdit::cursorPosition() const +{ + int par, index; + QTextEdit::getCursorPosition(&par, &index); + return index; +} + +void aHistLineEdit::slotMaybeResize() +{ +/* + if(QTextEdit::text().contains("\n")){ + setText(text()); + setCursorPosition(text().length()); + } +*/ + + if(text().length() > IRC_SAFE_MAX_LINE){ + if(m_drawrect == false){ + m_drawrect = true; + repaint(); + } + } + else { + if(m_drawrect == true){ + m_drawrect = false; + repaint(); + } + } + + QFontMetrics metrics( currentFont() ); + // int h = metrics.height() * lines(); + int h = metrics.lineSpacing() * lines()+8; + // only grow if we are less than 1/4 the size of the toplevel + if(h > (topLevelWidget()->height() >> 2)) { + if(this != topLevelWidget()) { + h = topLevelWidget()->height() >> 2; + setVScrollBarMode( Auto ); + } + } + else { + setVScrollBarMode( AlwaysOff ); + } + if(h != m_height){ + m_height = h; + QSize s = size(); + s.setHeight(h); + resize(s); + setFixedHeight( h ); + QLayout *l = topLevelWidget()->layout(); + if(l){ + l->invalidate(); + l->activate(); + } + emit resized(); + } +} + +void aHistLineEdit::keyPressEvent( QKeyEvent *e ) +{ + bool accept = true; + bool ignore = false; + bool callKeyPressEvent = false; + +// kdDebug(5008) << "Got key: " << e->text() << "/" << e->key() << "-" << e->state() << endl; + + if ( ! (e->key() == Key_Tab || e->key() == Key_Shift || e->state() == ShiftButton || e->key() == 0)) { +// kdDebug(5008) << "Sending notTab() " << e->text() << endl; + emit notTab(); + } + + // those keycodes correspond to the ones in ksirc.pl in sub hook_fixcolours + if ( e->state() == ControlButton ) { + QString s = text(); + int curPos = cursorPosition(); + switch ( e->key() ) { + case Key_K: + if ( ksopts->colorPicker ) + ColourPickerPopUp(); + else + { + s.insert( cursorPosition(), 0x03 ); + setText(s); + setCursorPosition(curPos + 1); + } + break; + case Key_I: + s.insert( cursorPosition(), "~i"); + setText(s); + setCursorPosition(curPos + 2); + break; + case Key_Return: + case Key_Enter: + doEnterKey(); + callKeyPressEvent = false; + break; + default: + accept = false; + ignore = false; + callKeyPressEvent = true; + } + } + else if(e->state() == 0){ + switch(e->key()){ + case Key_Return: + case Key_Enter: + doEnterKey(); + callKeyPressEvent = false; + break; + case Key_Up: + if(ksopts->oneLineEntry){ + if ((*current) != text()) { // change in hist <-> text() then save text + *current = text(); + } + if (current == hist.begin()) { // if at begin of list then wrap around + current = hist.fromLast(); + } else --current; // previous entry + setText(*current); + setCursorPosition((*current).length()); + break; + } + case Key_Down: + if(ksopts->oneLineEntry){ + if ((*current) != text()) { // change in hist <-> text() then save text + *current = text(); + } + if (current == hist.fromLast()) { // if at end of list then wrap around + current = hist.begin(); + } else ++current; // next entry + setText(*current); + setCursorPosition((*current).length()); + break; + } + default: + accept = false; + ignore = false; + callKeyPressEvent = true; + } + } + // QLineEdit falsely converts Alt+C to the character 'c', so to work around + // this, we just don't pass any Alt+? key on to the keyPressEvent() method. + else if (e->state() == AltButton) { + switch(e->key()){ + case Key_Return: + case Key_Enter: + doEnterKey(); + callKeyPressEvent = false; + break; + case Key_Up: + if ((*current) != text()) { // change in hist <-> text() then save text + *current = text(); + } + if (current == hist.begin()) { // if at begin of list then wrap around + current = hist.fromLast(); + } else --current; // previous entry + setText(*current); + setCursorPosition((*current).length()); + break; + case Key_Down: + if ((*current) != text()) { // change in hist <-> text() then save text + *current = text(); + } + if (current == hist.fromLast()) { // if at end of list then wrap around + current = hist.begin(); + } else ++current; // next entry + setText(*current); + setCursorPosition((*current).length()); + break; + default: + accept = false; + callKeyPressEvent = true; + } + } + else if (e->state() == ShiftButton){ + switch(e->key()){ + case Key_Return: + case Key_Enter: + doEnterKey(); + callKeyPressEvent = false; + break; + default: + accept = false; + ignore = false; + callKeyPressEvent = true; + } + } + else { + switch(e->key()){ + case Key_Return: + case Key_Enter: + doEnterKey(); + callKeyPressEvent = false; + break; + default: + accept = false; + ignore = false; + callKeyPressEvent = true; + + } + } + +// kdDebug(5008) << "Accept: " << accept << " Ignore: " << ignore << " callKPE: " << callKeyPressEvent << endl; + if ( accept ) { + e->accept(); + } + else { + if ( ignore ) { + e->ignore(); + } + else { + if ( callKeyPressEvent ) { + QTextEdit::keyPressEvent(e); + } + } + } +} + +bool aHistLineEdit::processKeyEvent( QKeyEvent *e ) +{ + /* + * Only put key sequences in here you + * want us to ignore and to pass upto + * parent widgets for handling + */ + + bool eat = false; + +// kdDebug(5008) << "Key: " << KShortcut( KKey( e ) ).toString() << " StdAccel: " << KStdAccel::paste().toString() << endl; + + if ( KStdAccel::paste().contains(KKey( e ))) { + e->ignore(); + eat = true; + } + + return eat; +} + +void aHistLineEdit::ColourPickerPopUp() +{ + ColorPicker picker( this ); + if ( picker.exec() == QDialog::Accepted ) + { + QString s = text(); + // int curPos = cursorPosition(); + int curPos, p; + getCursorPosition(&p, &curPos); + QString colString = picker.colorString(); + colString.prepend( 0x03 ); + s.insert( curPos, colString ); + setText( s ); + setCursorPosition( curPos + colString.length() ); + } +} + +void aHistLineEdit::focusInEvent(QFocusEvent *e) +{ + QTextEdit::focusInEvent(e); + emit gotFocus(); +} + +void aHistLineEdit::focusOutEvent(QFocusEvent *e) +{ + QTextEdit::focusOutEvent(e); + emit lostFocus(); +} +#if 0 +void aHistLineEdit::mousePressEvent ( QMouseEvent *e ) +{ + if(e->button() == MidButton){ + /* + * emit pasteText(QApplication::clipboard()->text(QClipboard::Selection)); + */ + } + else{ + QTextEdit::mousePressEvent(e); + } +} +#endif +bool aHistLineEdit::eventFilter( QObject *o, QEvent *e ) +{ + if ( o == this && e->type() == QEvent::AccelOverride ) + if(processKeyEvent( static_cast( e ) ) == true) + return true; + + return QTextEdit::eventFilter( o, e ); +} + +QString aHistLineEdit::text() const +{ + QString s = QTextEdit::text(); + s.remove("\n"); + return s; +} + +// Called upon MMB on the lineedit +void aHistLineEdit::paste() +{ + /* we let the top level take it */ + if(ksopts->oneLineEntry) { + emit pasteText(QApplication::clipboard()->text(QClipboard::Selection)); + } + else { + QString paste = QApplication::clipboard()->text(QClipboard::Selection); + paste.replace("\n", " ~ "); + insert(paste); + } +} + +void aHistLineEdit::paintEvent ( QPaintEvent *p ) +{ + QTextEdit::paintEvent(p); + + if(m_drawrect == true){ + QPainter paint(this); + QPen pen = paint.pen(); + pen.setWidth(5); + pen.setStyle(Qt::SolidLine); + pen.setColor(palette().active().highlight()); + paint.setPen(pen); + QRect r = frameRect(); + paint.drawRect(r); + } + +} + +void aHistLineEdit::doEnterKey() +{ + // strategy: always append an empty line to the end + if ((*current).isEmpty()) { // current is empty + if (!text().isEmpty()) { + // text() has something -> store it in current and add a new empty one + *current = text(); + hist.append(QString::null); // always add empty line at end + if (hist.count() >= 256) { // if appended check if it will go beyond the max number of entries + hist.remove(hist.begin()); // if so then delete the first entry + } + } + } else { // current has content + if (!text().isEmpty()) { + // both !isEmpty() and != -> append at end + current = hist.fromLast(); // goto last entry which is empty + *current = text(); // change content to text() + hist.append(QString::null); // always add empty line at end + if (hist.count() >= 256) { // if appended check if it will go beyond the max number of entries + hist.remove(hist.begin()); // if so then delete the first entry + } + } + } + current = hist.fromLast(); // set current history item back to the last item in the list + emit gotReturnPressed(); +} + +#include "ahistlineedit.moc" -- cgit v1.2.1