libkdegames Library API Documentation

kchatbase.cpp

00001 /* 00002 This file is part of the KDE games library 00003 Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de) 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include "kchatbase.h" 00021 00022 #include <klineedit.h> 00023 #include <klocale.h> 00024 #include <kstandarddirs.h> 00025 #include <kconfig.h> 00026 #include <kapplication.h> 00027 #include <kdebug.h> 00028 00029 #include <qlayout.h> 00030 #include <qcombobox.h> 00031 #include <qpainter.h> 00032 00033 class KChatBaseTextPrivate 00034 { 00035 public: 00036 KChatBaseTextPrivate() 00037 { 00038 mNameFont = 0; 00039 mMessageFont = 0; 00040 } 00041 00042 QString mName; 00043 QString mMessage; 00044 00045 const QFont* mNameFont; 00046 const QFont* mMessageFont; 00047 }; 00048 00049 00050 KChatBaseText::KChatBaseText(const QString& name, const QString& message) : QListBoxText() 00051 { 00052 init(); 00053 setName(name); 00054 setMessage(message); 00055 } 00056 00057 KChatBaseText::KChatBaseText(const QString& message) : QListBoxText() 00058 { 00059 init(); 00060 setMessage(message); 00061 } 00062 00063 KChatBaseText::~KChatBaseText() 00064 { 00065 delete d; 00066 } 00067 00068 void KChatBaseText::init() 00069 { 00070 d = new KChatBaseTextPrivate; 00071 } 00072 00073 void KChatBaseText::setName(const QString& n) 00074 { 00075 // d->mName = n; 00076 d->mName = QString("%1: ").arg(n); 00077 setText(QString("%1: %2").arg(name()).arg(message())); // esp. for sorting 00078 } 00079 00080 void KChatBaseText::setMessage(const QString& m) 00081 { 00082 d->mMessage = m; 00083 setText(QString("%1: %2").arg(name()).arg(message())); // esp. for sorting 00084 } 00085 00086 const QString& KChatBaseText::name() const 00087 { return d->mName; } 00088 00089 const QString& KChatBaseText::message() const 00090 { return d->mMessage; } 00091 00092 QFont KChatBaseText::nameFont() const 00093 { 00094 if (d->mNameFont) { 00095 return *d->mNameFont; 00096 } else if (listBox()) { 00097 return listBox()->font(); 00098 } else { 00099 return QFont(); 00100 } 00101 } 00102 00103 QFont KChatBaseText::messageFont() const 00104 { 00105 if (d->mMessageFont) { 00106 return *d->mMessageFont; 00107 } else if (listBox()) { 00108 return listBox()->font(); 00109 } else { 00110 return QFont(); 00111 } 00112 } 00113 00114 void KChatBaseText::setNameFont(const QFont* f) 00115 { d->mNameFont = f; } 00116 00117 void KChatBaseText::setMessageFont(const QFont* f) 00118 { d->mMessageFont = f; } 00119 00120 void KChatBaseText::paint(QPainter* painter) 00121 { 00122 QFontMetrics fm = painter->fontMetrics(); 00123 painter->setFont(nameFont()); 00124 painter->drawText(3, fm.ascent() + fm.leading()/2, name()); 00125 painter->setFont(messageFont()); 00126 painter->drawText(3 + QFontMetrics(nameFont()).width(name()), fm.ascent() + fm.leading()/2, message()); 00127 } 00128 00129 int KChatBaseText::width(QListBox* lb) const 00130 { 00131 int w = 0; 00132 if (lb) { 00133 w += 6; 00134 w += QFontMetrics(nameFont()).width(name()); 00135 w += QFontMetrics(messageFont()).width(message()); 00136 } 00137 // int w = lb ? lb->fontMetrics().width( text() ) + 6 : 0; // QT orig 00138 return QMAX(w, QApplication::globalStrut().width()); 00139 } 00140 00141 int KChatBaseText::height(QListBox* lb) const 00142 { 00143 int h = 0; 00144 if (lb) { 00145 h += 2; 00146 // AB: is lineSpacing still correct? 00147 if (QFontMetrics(nameFont()).lineSpacing() > QFontMetrics(messageFont()).lineSpacing()) { 00148 h += QFontMetrics(nameFont()).lineSpacing(); 00149 } else { 00150 h += QFontMetrics(messageFont()).lineSpacing(); 00151 } 00152 } 00153 // int h = lb ? lb->fontMetrics().lineSpacing() + 2 : 0; // QT orig 00154 return QMAX(h, QApplication::globalStrut().height()); 00155 } 00156 00157 00158 00159 class KChatBasePrivate 00160 { 00161 public: 00162 KChatBasePrivate() 00163 { 00164 mBox = 0; 00165 mEdit = 0; 00166 mCombo = 0; 00167 00168 mAcceptMessage = true; 00169 mMaxItems = -1; 00170 } 00171 QListBox* mBox; 00172 KLineEdit* mEdit; 00173 QComboBox* mCombo; 00174 bool mAcceptMessage; 00175 int mMaxItems; 00176 00177 QValueList<int> mIndex2Id; 00178 00179 QFont mNameFont; 00180 QFont mMessageFont; 00181 QFont mSystemNameFont; 00182 QFont mSystemMessageFont; 00183 }; 00184 00185 KChatBase::KChatBase(QWidget* parent, bool noComboBox) : QFrame(parent) 00186 { 00187 init(noComboBox); 00188 } 00189 00190 KChatBase::~KChatBase() 00191 { 00192 // kdDebug(11000) << "KChatBase: DESTRUCT (" << this << ")" << endl; 00193 saveConfig(); 00194 delete d; 00195 } 00196 00197 void KChatBase::init(bool noComboBox) 00198 { 00199 // kdDebug(11000) << "KChatBase: INIT (" << this << ")" << endl; 00200 00201 d = new KChatBasePrivate; 00202 00203 setMinimumWidth(100); 00204 setMinimumHeight(150); 00205 00206 QVBoxLayout* l = new QVBoxLayout(this); 00207 00208 d->mBox = new QListBox(this); 00209 connect(d->mBox, SIGNAL(rightButtonClicked(QListBoxItem*, const QPoint&)), 00210 this, SIGNAL(rightButtonClicked(QListBoxItem*, const QPoint&))); 00211 l->addWidget(d->mBox); 00212 d->mBox->setVScrollBarMode(QScrollView::AlwaysOn); 00213 d->mBox->setHScrollBarMode(QScrollView::AlwaysOff); 00214 d->mBox->setFocusPolicy(QWidget::NoFocus); 00215 // d->mBox->setSelectionMode(QListBox::NoSelection); 00216 d->mBox->setSelectionMode(QListBox::Single); 00217 00218 l->addSpacing(5); 00219 00220 QHBoxLayout* h = new QHBoxLayout(l); 00221 d->mEdit = new KLineEdit(this); 00222 d->mEdit->setHandleSignals(false); 00223 d->mEdit->setTrapReturnKey(true); 00224 d->mEdit->completionObject(); // add the completion object 00225 d->mEdit->setCompletionMode(KGlobalSettings::CompletionNone); 00226 connect(d->mEdit, SIGNAL(returnPressed(const QString&)), this, SLOT(slotReturnPressed(const QString&))); 00227 h->addWidget(d->mEdit); 00228 00229 if (!noComboBox) { 00230 d->mCombo = new QComboBox(this); 00231 h->addWidget(d->mCombo); 00232 addSendingEntry(i18n("Send to All Players"), SendToAll);//FIXME: where to put the id? 00233 } 00234 00235 d->mAcceptMessage = true; // by default 00236 setMaxItems(-1); // unlimited 00237 00238 if (kapp) { 00239 // kapp might be NULL as well - in case we are in Qt designer. 00240 readConfig(); 00241 } 00242 } 00243 00244 bool KChatBase::acceptMessage() const 00245 { return d->mAcceptMessage; } 00246 00247 void KChatBase::setAcceptMessage(bool a) 00248 { d->mAcceptMessage = a; } 00249 00250 bool KChatBase::addSendingEntry(const QString& text, int id) 00251 { 00252 //FIXME: is ID used correctly? 00253 // do we need ID at all? 00254 // what the hell should be here? 00255 // d->mCombo->insertItem(i18n("Send to All Players"), SendToAll); 00256 return insertSendingEntry(text, id); 00257 } 00258 00259 bool KChatBase::insertSendingEntry(const QString& text, int id, int index) 00260 { 00261 if (!d->mCombo) { 00262 kdWarning(11000) << "KChatBase: Cannot add an entry to the combo box" << endl; 00263 return false; 00264 } 00265 if (d->mIndex2Id.findIndex(id) != -1) { 00266 kdError(11000) << "KChatBase: Cannot add more than one entry with the same ID! " << endl; 00267 kdError(11000) << "KChatBase: Text="<<text<<endl; 00268 return false; 00269 } 00270 d->mCombo->insertItem(text, index); 00271 if (index < 0) { 00272 d->mIndex2Id.append(id); 00273 } else { 00274 d->mIndex2Id.insert(d->mIndex2Id.at(index), id); 00275 } 00276 if (d->mIndex2Id.count() != (uint)d->mCombo->count()) { 00277 kdError(11000) << "KChatBase: internal ERROR - local IDs do not match combo box entries!" << endl; 00278 } 00279 return true; 00280 } 00281 00282 int KChatBase::sendingEntry() const 00283 { 00284 if (!d->mCombo) { 00285 kdWarning(11001) << "Cannot retrieve index from NULL combo box" << endl; 00286 return -1; 00287 } 00288 int index = d->mCombo->currentItem(); 00289 if (d->mIndex2Id.at(index) == d->mIndex2Id.end()) { 00290 kdWarning(11000) << "could not find the selected sending entry!" << endl; 00291 return -1; 00292 } 00293 return d->mIndex2Id[index]; 00294 } 00295 00296 void KChatBase::removeSendingEntry(int id) 00297 { 00298 if (!d->mCombo) { 00299 kdWarning(11000) << "KChatBase: Cannot remove an entry from the combo box" << endl; 00300 return; 00301 } 00302 d->mCombo->removeItem(findIndex(id)); 00303 d->mIndex2Id.remove(id); 00304 } 00305 00306 void KChatBase::changeSendingEntry(const QString& text, int id) 00307 { 00308 if (!d->mCombo) { 00309 kdWarning(11000) << "KChatBase: Cannot change an entry in the combo box" << endl; 00310 return; 00311 } 00312 int index = findIndex(id); 00313 d->mCombo->changeItem(text, index); 00314 } 00315 00316 void KChatBase::setSendingEntry(int id) 00317 { 00318 if (!d->mCombo) { 00319 kdWarning(11000) << "KChatBase: Cannot set an entry in the combo box" << endl; 00320 return; 00321 } 00322 d->mCombo->setCurrentItem(findIndex(id)); 00323 } 00324 00325 int KChatBase::findIndex(int id) const 00326 { 00327 return d->mIndex2Id.findIndex(id); 00328 } 00329 00330 int KChatBase::nextId() const 00331 { 00332 int i = SendToAll + 1; 00333 while (d->mIndex2Id.findIndex(i) != -1) { 00334 i++; 00335 } 00336 return i; 00337 } 00338 00339 void KChatBase::addItem(const QListBoxItem* text) 00340 { 00341 d->mBox->insertItem(text); 00342 int index = d->mBox->count() -1; 00343 d->mBox->setBottomItem(index);//FIXME: don't scroll to bottom if user scrolled down manually 00344 if (maxItems() >= 0 && d->mBox->count() > (unsigned int)maxItems()) { 00345 d->mBox->removeItem(0); 00346 } 00347 } 00348 00349 void KChatBase::addMessage(const QString& fromName, const QString& text) 00350 { 00351 //maybe "%1 says: %2" or so 00352 addItem(layoutMessage(fromName, text)); 00353 } 00354 00355 void KChatBase::addSystemMessage(const QString& fromName, const QString& text) 00356 { 00357 addItem(layoutSystemMessage(fromName, text)); 00358 } 00359 00360 QListBoxItem* KChatBase::layoutMessage(const QString& fromName, const QString& text) 00361 { 00362 //TODO: KChatBaseConfigure? - e.g. color 00363 QListBoxItem* message; 00364 if (text.startsWith("/me ")) { 00365 // replace "/me" by a nice star. leave one space after the star 00366 QPixmap pix; 00367 pix.load(locate("data", QString::fromLatin1("kdegames/pics/star.png"))); 00368 00369 //TODO KChatBasePixmap? Should change the font here! 00370 00371 message = (QListBoxItem*)new QListBoxPixmap(pix, i18n("%1 %2").arg(fromName).arg(text.mid(3))); 00372 } else { 00373 // the text is not edited in any way. just return an item 00374 KChatBaseText* m = new KChatBaseText(fromName, text); 00375 m->setNameFont(&d->mNameFont); 00376 m->setMessageFont(&d->mMessageFont); 00377 message = (QListBoxItem*)m; 00378 } 00379 return message; 00380 } 00381 00382 QListBoxItem* KChatBase::layoutSystemMessage(const QString& fromName, const QString& text) 00383 { 00384 //TODO: KChatBaseConfigure? - e.g. color 00385 00386 // no need to check for /me etc. 00387 KChatBaseText* m = new KChatBaseText(i18n("--- %1").arg(fromName), text); 00388 m->setNameFont(&d->mSystemNameFont); 00389 m->setMessageFont(&d->mSystemMessageFont); 00390 return (QListBoxItem*)m; 00391 } 00392 00393 void KChatBase::slotReturnPressed(const QString& text) 00394 { 00395 if (text.length() <= 0) { 00396 // no text entered - probably hit return by accident 00397 return; 00398 } else if (!acceptMessage()) { 00399 return; 00400 } 00401 d->mEdit->completionObject()->addItem(text); 00402 // connect(d->mEdit, SIGNAL(returnPressed(const QString&)), comp, SLOT(addItem(const QString&))); 00403 d->mEdit->clear(); 00404 returnPressed(text); 00405 } 00406 00407 QString KChatBase::comboBoxItem(const QString& name) const 00408 { // TODO: such a function for "send to all" and "send to my group" 00409 return i18n("Send to %1").arg(name); 00410 } 00411 00412 void KChatBase::slotClear() 00413 { 00414 d->mBox->clear(); 00415 } 00416 00417 void KChatBase::setCompletionMode(KGlobalSettings::Completion mode) 00418 { d->mEdit->setCompletionMode(mode); } 00419 00420 void KChatBase::setNameFont(const QFont& font) 00421 { 00422 d->mNameFont = font; 00423 d->mBox->triggerUpdate(false); 00424 } 00425 00426 void KChatBase::setMessageFont(const QFont& font) 00427 { 00428 d->mMessageFont = font; 00429 d->mBox->triggerUpdate(false); 00430 } 00431 00432 void KChatBase::setBothFont(const QFont& font) 00433 { 00434 setNameFont(font); 00435 setMessageFont(font); 00436 } 00437 00438 const QFont& KChatBase::nameFont() const 00439 { return d->mNameFont; } 00440 00441 const QFont& KChatBase::messageFont() const 00442 { return d->mMessageFont; } 00443 00444 void KChatBase::setSystemNameFont(const QFont& font) 00445 { 00446 d->mSystemNameFont = font; 00447 d->mBox->triggerUpdate(false); 00448 } 00449 00450 void KChatBase::setSystemMessageFont(const QFont& font) 00451 { 00452 d->mSystemMessageFont = font; 00453 d->mBox->triggerUpdate(false); 00454 } 00455 00456 void KChatBase::setSystemBothFont(const QFont& font) 00457 { 00458 setSystemNameFont(font); 00459 setSystemMessageFont(font); 00460 } 00461 00462 const QFont& KChatBase::systemNameFont() const 00463 { return d->mSystemNameFont; } 00464 00465 const QFont& KChatBase::systemMessageFont() const 00466 { return d->mSystemMessageFont; } 00467 00468 void KChatBase::saveConfig(KConfig* conf) 00469 { 00470 QString oldGroup; 00471 if (!conf) { 00472 conf = kapp->config(); 00473 oldGroup = conf->group(); 00474 conf->setGroup("KChatBase"); 00475 } 00476 00477 conf->writeEntry("NameFont", nameFont()); 00478 conf->writeEntry("MessageFont", messageFont()); 00479 conf->writeEntry("SystemNameFont", systemNameFont()); 00480 conf->writeEntry("SystemMessageFont", systemMessageFont()); 00481 conf->writeEntry("MaxMessages", maxItems()); 00482 00483 if (!oldGroup.isNull()) { 00484 conf->setGroup(oldGroup); 00485 } 00486 } 00487 00488 void KChatBase::readConfig(KConfig* conf) 00489 { 00490 QString oldGroup; 00491 if (!conf) { 00492 conf = kapp->config(); 00493 oldGroup = conf->group(); 00494 conf->setGroup("KChatBase"); 00495 } 00496 00497 setNameFont(conf->readFontEntry("NameFont")); 00498 setMessageFont(conf->readFontEntry("MessageFont")); 00499 setSystemNameFont(conf->readFontEntry("SystemNameFont")); 00500 setSystemMessageFont(conf->readFontEntry("SystemMessageFont")); 00501 setMaxItems(conf->readNumEntry("MaxMessages", -1)); 00502 00503 if (!oldGroup.isNull()) { 00504 conf->setGroup(oldGroup); 00505 } 00506 } 00507 00508 void KChatBase::clear() 00509 { 00510 d->mBox->clear(); 00511 } 00512 00513 void KChatBase::setMaxItems(int maxItems) 00514 { 00515 d->mMaxItems = maxItems; 00516 //TODO cut too many messages 00517 if (maxItems == 0) { 00518 clear(); 00519 } else if (maxItems > 0) { 00520 while (d->mBox->count() > (unsigned int)maxItems) { 00521 d->mBox->removeItem(0); 00522 } 00523 } 00524 } 00525 00526 int KChatBase::maxItems() const 00527 { return d->mMaxItems; } 00528 00529 00530 #include "kchatbase.moc"
KDE Logo
This file is part of the documentation for libkdegames Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 14:18:45 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003