You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/ksirc/KSTicker/ksticker.cpp

549 lines
14 KiB

#include <stdlib.h>
#include <tqpainter.h>
#include <tqframe.h>
#include <tqpaintdevice.h>
#include <tqcursor.h>
#include <tqtooltip.h>
#include <tqregexp.h>
#include <kapplication.h>
#include <kfontdialog.h>
#include <klocale.h>
#include "ksticker.h"
#include "speeddialog.h"
#include "kspainter.h"
#include "../ksopts.h"
#include "../nickColourMaker.h"
#include <kconfig.h>
#include <kwin.h>
#include <kdebug.h>
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);
KConfig *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 kwin
//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 kwin
//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;
tqrepaint(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);
tqrepaint(TRUE);
startTicker();
}
void KSTicker::mergeString(TQString str, TQColor c)
{
int num = KSPainter::colour2num(c);
if(num != -1){
str.prepend(TQString("~%1").tqarg(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").tqarg(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 = KFontDialog::getFont( ourFont, true );
if ( result == KFontDialog::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();
KConfig *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);
KConfig *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"