00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00076 d->mName =
QString(
"%1: ").arg(n);
00077 setText(
QString(
"%1: %2").arg(
name()).arg(
message()));
00078 }
00079
00080 void KChatBaseText::setMessage(
const QString& m)
00081 {
00082 d->mMessage = m;
00083 setText(
QString(
"%1: %2").arg(
name()).arg(
message()));
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
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
00147
if (
QFontMetrics(
nameFont()).lineSpacing() >
QFontMetrics(
messageFont()).lineSpacing()) {
00148 h +=
QFontMetrics(
nameFont()).lineSpacing();
00149 }
else {
00150 h +=
QFontMetrics(
messageFont()).lineSpacing();
00151 }
00152 }
00153
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
00193
saveConfig();
00194
delete d;
00195 }
00196
00197
void KChatBase::init(
bool noComboBox)
00198 {
00199
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
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();
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);
00233 }
00234
00235 d->mAcceptMessage =
true;
00236
setMaxItems(-1);
00237
00238
if (kapp) {
00239
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
00253
00254
00255
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);
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
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
00363
QListBoxItem* message;
00364
if (text.startsWith(
"/me ")) {
00365
00366
QPixmap pix;
00367 pix.load(locate(
"data", QString::fromLatin1(
"kdegames/pics/star.png")));
00368
00369
00370
00371 message = (
QListBoxItem*)
new QListBoxPixmap(pix, i18n(
"%1 %2").arg(fromName).arg(text.mid(3)));
00372 }
else {
00373
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
00385
00386
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
00397
return;
00398 }
else if (!
acceptMessage()) {
00399
return;
00400 }
00401 d->mEdit->completionObject()->addItem(text);
00402
00403 d->mEdit->clear();
00404
returnPressed(text);
00405 }
00406
00407 QString KChatBase::comboBoxItem(
const QString& name)
const
00408
{
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
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"