#include #include #include #include #include #include #include #include #include #include #include "ksticker.h" #include "speeddialog.h" #include "kspainter.h" #include "../ksopts.h" #include "../nickColourMaker.h" #include #include #include KSTicker::KSTicker(TQWidget * parent, const char * name, WFlags f) : TQFrame(parent, name, f) { pHeight = 1; pic = new TQPixmap(); // create pic map here, resize it later though. // pic->setBackgroundMode(TransparentMode); TDEConfig *conf = kapp->config(); conf->setGroup("KSTicker"); bScrollConstantly = conf->readNumEntry("ScollConst", FALSE); bAtEnd = FALSE; setFont(conf->readFontEntry("Font", &ksopts->defaultFont)); ourFont = font(); //TQFont("Courier"); setFont(ourFont); setMinimumSize(100, 10); setFixedHeight((fontMetrics().height()+fontMetrics().descent()*2)*pHeight); descent = fontMetrics().descent(); onechar = fontMetrics().width("X"); pic->resize(width() + onechar, height()); pic->fill(backgroundColor()); tickStep = 2; cOffset = 0; tickRate = 30; currentChar = 0; chars = this->width() / onechar; popup = new TQPopupMenu(); popup->insertItem(i18n( "Font..." ), this, TQT_SLOT(fontSelector())); popup->insertItem(i18n( "Scroll Rate..." ), this, TQT_SLOT(scrollRate())); iScrollItem = popup->insertItem(i18n( "Scroll Constantly" ), this, TQT_SLOT(scrollConstantly())); popup->setItemChecked(iScrollItem, bScrollConstantly); popup->insertSeparator(); popup->insertItem(i18n( "Return to Normal Mode" ), this, TQT_SIGNAL(doubleClick())); currentStr = ""; /* * Tell KWM to use only minimum decurations */ // ### FIXME: port to twin //KWM::setDecoration(winId(), KWM::tinyDecoration); // KWin::setType(winId(), NET::Override); /* * Setup basic colours and background status info for ticker. */ KSPainter::initOptColours(); bold = FALSE; underline = FALSE; italics = FALSE; defbg = ksopts->backgroundColor; deffg = ksopts->textColor; setBackgroundColor(defbg); bg = ksopts->backgroundColor; fg = ksopts->textColor; } KSTicker::~KSTicker() { TQT_TQOBJECT(this)->killTimers(); delete pic; } void KSTicker::show() { /* * Tell KWM to use only minimum decurations */ // ### FIXME: port to twin //KWM::setDecoration(winId(), KWM::tinyDecoration); TQSize size = this->size(); size.setHeight(TQFontMetrics(font()).height()+10); setFixedHeight(TQFontMetrics(font()).height()+10); resize(size); TQFrame::show(); if(currentStr.length() != 0) startTicker(); currentChar = 0; repaint(TRUE); } void KSTicker::hide() { TQT_TQOBJECT(this)->killTimers(); TQFrame::hide(); } void KSTicker::iconify() { TQFrame::showMinimized(); TQT_TQOBJECT(this)->killTimers(); } void KSTicker::setString(TQString str) { strlist.clear(); strlist.append(str); repaint(TRUE); startTicker(); } void KSTicker::mergeString(TQString str, TQColor c) { int num = KSPainter::colour2num(c); if(num != -1){ str.prepend(TQString("~%1").arg(num)); } mergeString(str); } void KSTicker::mergeString(TQString str) { TQRegExp rx("~n(\\S+)~n"); if(rx.search(str) >= 0){ int value = nickColourMaker::colourMaker()->findIdx(rx.cap(1)); if(value >= 0){ TQString newText = TQString("~%1\\1~c").arg(value); str.replace(rx, newText); } } str.append("~C "); strlist.append(str); if(strlist.count() > 5){ int found = 0; TQStringList::Iterator it = strlist.begin(); for(; it != strlist.end(); it++){ if(((*it).find(ksopts->server["global"].nick, 0, FALSE) == -1) && ((*it).find(ksopts->server["global"].altNick, 0, FALSE) == -1)){ strlist.remove(it); found = 1; break; } else { } } if(found == 0){ strlist.pop_front(); } } if(bScrollConstantly == FALSE) startTicker(); TQStringList sep = TQStringList::split(" ", stripCols(str)); int len = 0; TQString brok; TQStringList::Iterator it = sep.begin(); for(; it != sep.end(); ++it) { brok += *it + " "; len += (*it).length(); if(len >= 50){ brok += "\n"; len = 0; } } if(brok.endsWith("\n")) brok.truncate(brok.length()-1); tipbuffer.append(brok); while(tipbuffer.count() > 10) tipbuffer.pop_front(); TQString tip = tipbuffer.join("\n"); // TQToolTip::remove(this); TQToolTip::add(this, tip); } void KSTicker::timerEvent(TQTimerEvent *) { if((uint)currentChar >= currentStr.length()){ if(strlist.isEmpty()){ if(bScrollConstantly == TRUE){ currentStr = strbuffer.first(); strbuffer.append(strbuffer.first()); strbuffer.pop_front(); currentChar = 0; } else{ stopTicker(); return; } } else { currentStr = strlist.first(); strlist.pop_front(); strbuffer.append(currentStr); while(strbuffer.count() > 10) strbuffer.pop_front(); currentChar = 0; } } bAtEnd = FALSE; static Qt::BGMode bgmode = Qt::TransparentMode; bitBlt(pic, -tickStep, 0, pic); TQPainter p(pic); cOffset += tickStep; if(cOffset >= onechar){ int step = 1; // Used to check if we did anything, and hence // catch ~c~c type things. Set to 1 to start loop while(((currentStr[currentChar] == '~') || (currentStr[currentChar] == 0x03)) && (step > 0)){ step = 1; // reset in case it's our second, or more loop. TQString text = currentStr.mid(currentChar); TQString buf = ""; if((text[step] >= '0') && (text[step] <= '9')) { buf += text[step]; step++; if((text[step] >= '0') && (text[step] <= '9')) { buf += text[step]; step++; } int col = buf.toInt(); if((col >= 0) || (col <= KSPainter::maxcolour)){ fg = KSPainter::num2colour[col]; } bg = defbg; buf = ""; if(text[step] == ','){ step++; if((text[step] >= '0') && (text[step] <= '9')) { buf += text[step]; step++; if((text[step] >= '0') && (text[step] <= '9')) { buf += text[step]; step++; } int col = buf.toInt(); if((col >= 0) || (col <= KSPainter::maxcolour)){ bg = KSPainter::num2colour[col]; bgmode = Qt::OpaqueMode; } } } else{ bgmode = Qt::TransparentMode; } } else { switch(text[step].latin1()){ case 'c': fg = deffg; bg = defbg; step++; break; case 'C': fg = deffg; bg = defbg; bold = FALSE; underline = FALSE; italics = FALSE; step++; break; case '#': fg.setNamedColor(text.mid(step, 7)); step += 7; break; case 'b': bold == TRUE ? bold = FALSE : bold = TRUE; step++; break; case 'u': underline == TRUE ? underline = FALSE : underline = TRUE; step++; break; case 'i': italics == TRUE ? italics = FALSE : italics = TRUE; step++; break; case 'n': fg = ksopts->nickForeground; bg = ksopts->nickBackground; step++; break; case 'o': fg = ksopts->msgContainNick; step++; break; case '~': currentChar++; // Move ahead 1, but... step = 0; // Don't loop on next ~. break; default: if(currentStr[currentChar] == 0x03){ fg = deffg; bg = defbg; } else step = 0; } } currentChar += step; } if((uint)currentChar >= currentStr.length()){ // Bail out if we're // at the end of the string. return; } TQFont fnt = font(); fnt.setBold(bold); fnt.setUnderline(underline); fnt.setItalic(italics); p.setFont(fnt); p.setPen(fg); p.setBackgroundColor(bg); p.setBackgroundMode(Qt::OpaqueMode); p.drawText(this->width() - cOffset + onechar, // remove -onechar. this->height() / 4 + p.fontMetrics().height() / 2, currentStr.mid(currentChar, 1), 1); currentChar++; // Move ahead to next character. cOffset -= onechar; // Set offset back one. } p.end(); bitBlt(this, 0, descent, pic); } void KSTicker::paintEvent( TQPaintEvent *) { if(isVisible() == FALSE) return; bitBlt(this, 0, descent, pic); } void KSTicker::resizeEvent( TQResizeEvent *e) { TQFrame::resizeEvent(e); onechar = fontMetrics().width("X"); chars = this->width() / onechar; TQT_TQOBJECT(this)->killTimers(); TQPixmap *new_pic = new TQPixmap(width() + onechar, height()); new_pic->fill(backgroundColor()); bitBlt(TQT_TQPAINTDEVICE(new_pic), new_pic->width() - pic->width(), 0, TQT_TQPAINTDEVICE(pic), 0, 0, pic->width(), pic->height(), CopyROP, TRUE); delete pic; pic = new_pic; // if(ring.length() > (uint) chars) startTicker(); } void KSTicker::closeEvent( TQCloseEvent *) { emit closing(); TQT_TQOBJECT(this)->killTimers(); // delete this; } void KSTicker::startTicker() { TQT_TQOBJECT(this)->killTimers(); startTimer(tickRate); } void KSTicker::stopTicker() { TQT_TQOBJECT(this)->killTimers(); } void KSTicker::mouseDoubleClickEvent( TQMouseEvent * ) { emit doubleClick(); } void KSTicker::mousePressEvent( TQMouseEvent *e) { if(e->button() == Qt::RightButton){ popup->popup(this->cursor().pos()); } else{ TQFrame::mousePressEvent(e); } } void KSTicker::fontSelector() { int result = TDEFontDialog::getFont( ourFont, true ); if ( result == TDEFontDialog::Accepted ) { updateFont(ourFont); } } void KSTicker::scrollRate() { SpeedDialog *sd = new SpeedDialog(tickRate, tickStep); sd->setLimit(5, 200, 1, onechar); connect(sd, TQT_SIGNAL(stateChange(int, int)), this, TQT_SLOT(setSpeed(int, int))); sd->show(); } void KSTicker::scrollConstantly() { bScrollConstantly = !bScrollConstantly; popup->setItemChecked(iScrollItem, bScrollConstantly); if(bScrollConstantly == TRUE) startTicker(); TDEConfig *conf = kapp->config(); conf->setGroup("KSTicker"); conf->writeEntry("ScollConst", bScrollConstantly); conf->sync(); } void KSTicker::updateFont(const TQFont &font){ setFont(font); setFixedHeight((fontMetrics().height()+fontMetrics().descent()*2)*pHeight); resize(fontMetrics().width("X")*chars, (fontMetrics().height()+fontMetrics().descent())*pHeight); TDEConfig *conf = kapp->config(); conf->setGroup("KSTicker"); conf->writeEntry("Font", font); conf->sync(); } void KSTicker::setSpeed(int _tickRate, int _tickStep){ tickRate = _tickRate; tickStep = _tickStep; startTicker(); } void KSTicker::speed(int *_tickRate, int *_tickStep){ *_tickRate = tickRate; *_tickStep = tickStep; } void KSTicker::setBackgroundColor ( const TQColor &c ) { TQFrame::setBackgroundColor(c); pic->fill(c); bitBlt(this, 0,0, pic); defbg = backgroundColor(); bg = backgroundColor(); } void KSTicker::setPalette ( const TQPalette & p ) { TQFrame::setPalette(p); pic->fill(backgroundColor()); bitBlt(this, 0,0, pic); defbg = backgroundColor(); bg = backgroundColor(); deffg = backgroundColor(); fg = foregroundColor(); } TQString KSTicker::stripCols( TQString str ) { uint i = 0; TQString ret; for(i = 0; i < str.length(); i++){ if(((str[i] == '~') || (str[i] == 0x03))){ if((str[i+1] >= '0') && (str[i+1] <= '9')) { i+=1; if((str[i+1] >= '0') && (str[i+1] <= '9')) { i+=1; } if(str[i+1] == ','){ i+=1; if((str[i+1] >= '0') && (str[i+1] <= '9')) { i+=1; if((str[i+1] >= '0') && (str[i+1] <= '9')) { i+=1; } } } } else { switch(str[i+1].latin1()){ case 'c': case 'C': case 'b': case 'u': case 'i': case 'n': case 'o': i+= 1; break; case '~': i+= 0; break; default: ret.append(str[i]); } } } else { ret.append(str[i]); } } return ret; } #include "ksticker.moc"