File indexing completed on 2024-05-12 04:06:09
0001 /* 0002 This file is part of the KDE games library 0003 SPDX-FileCopyrightText: 2001 Andreas Beckermann <b_mann@gmx.de> 0004 SPDX-FileCopyrightText: 2007 Gael de Chalendar (aka Kleag) <kleag@free.fr> 0005 0006 SPDX-License-Identifier: LGPL-2.0-only 0007 */ 0008 0009 #include "kchatbase.h" 0010 #include "kchatbase_p.h" 0011 0012 // own 0013 #include "kchatbaseitemdelegate.h" 0014 #include "kchatbasemodel.h" 0015 #include <kdegamesprivate_kgame_logging.h> 0016 #include <kdegamesprivate_logging.h> 0017 // KF 0018 #include <KConfig> 0019 #include <KLineEdit> 0020 #include <KLocalizedString> 0021 // Qt 0022 #include <QComboBox> 0023 #include <QHBoxLayout> 0024 #include <QList> 0025 #include <QListView> 0026 #include <QVBoxLayout> 0027 0028 KChatBasePrivate::KChatBasePrivate(KChatBaseModel *model, KChatBaseItemDelegate *delegate, QWidget *parent) 0029 { 0030 if (!model) { 0031 model = new KChatBaseModel(parent); 0032 } 0033 if (!delegate) { 0034 delegate = new KChatBaseItemDelegate(parent); 0035 } 0036 0037 mModel = model; 0038 mDelegate = delegate; 0039 } 0040 0041 void KChatBase::setModel(KChatBaseModel *m) 0042 { 0043 Q_D(KChatBase); 0044 0045 // delete d->mModel; 0046 d->mModel = m; 0047 } 0048 0049 KChatBaseModel *KChatBase::model() 0050 { 0051 Q_D(KChatBase); 0052 0053 return d->mModel; 0054 } 0055 0056 KChatBase::KChatBase(QWidget *parent, KChatBaseModel *model, KChatBaseItemDelegate *delegate, bool noComboBox) 0057 : KChatBase(*new KChatBasePrivate(model, delegate, parent), parent, noComboBox) 0058 { 0059 } 0060 0061 KChatBase::KChatBase(KChatBasePrivate &dd, QWidget *parent, bool noComboBox) 0062 : QFrame(parent) 0063 , d(&dd) 0064 { 0065 setMinimumWidth(100); 0066 setMinimumHeight(150); 0067 0068 QVBoxLayout *l = new QVBoxLayout(this); 0069 0070 d->mBox = new QListView(); 0071 d->mBox->setModel(d->mModel); 0072 d->mBox->setItemDelegate(d->mDelegate); 0073 l->addWidget(d->mBox); 0074 0075 connect(d->mModel, &QAbstractItemModel::rowsInserted, d->mBox, &QAbstractItemView::scrollToBottom); 0076 0077 connect(d->mBox, &QListView::customContextMenuRequested, this, &KChatBase::customMenuHandler); 0078 0079 d->mBox->setContextMenuPolicy(Qt::CustomContextMenu); 0080 d->mBox->setFocusPolicy(Qt::NoFocus); 0081 d->mBox->setSelectionMode(QAbstractItemView::SingleSelection); 0082 0083 l->addSpacing(5); 0084 0085 QHBoxLayout *h = new QHBoxLayout; 0086 l->addLayout(h); 0087 d->mEdit = new KLineEdit(this); 0088 d->mEdit->setHandleSignals(false); 0089 d->mEdit->setTrapReturnKey(true); 0090 d->mEdit->completionObject(); // add the completion object 0091 d->mEdit->setCompletionMode(KCompletion::CompletionNone); 0092 connect(d->mEdit, &KLineEdit::returnKeyPressed, this, &KChatBase::slotReturnPressed); 0093 h->addWidget(d->mEdit); 0094 0095 if (!noComboBox) { 0096 d->mCombo = new QComboBox(this); 0097 h->addWidget(d->mCombo); 0098 addSendingEntry(i18n("Send to All Players"), SendToAll); // FIXME: where to put the id? 0099 } 0100 0101 d->mAcceptMessage = true; // by default 0102 setMaxItems(-1); // unlimited 0103 0104 readConfig(); 0105 } 0106 0107 QModelIndex KChatBase::indexAt(QPoint pos) const 0108 { 0109 Q_D(const KChatBase); 0110 0111 return d->mBox->indexAt(pos); 0112 } 0113 0114 void KChatBase::customMenuHandler(QPoint pos) 0115 { 0116 qCDebug(KDEGAMESPRIVATE_LOG) << "custom menu has been requested at position=" << pos << ". Implement handler at subclass if you need it."; 0117 } 0118 0119 KChatBase::~KChatBase() 0120 { 0121 // qCDebug(KDEGAMESPRIVATE_LOG) << "KChatBase: DESTRUCT (" << this << ")"; 0122 saveConfig(); 0123 } 0124 0125 bool KChatBase::acceptMessage() const 0126 { 0127 Q_D(const KChatBase); 0128 0129 return d->mAcceptMessage; 0130 } 0131 0132 void KChatBase::setAcceptMessage(bool a) 0133 { 0134 Q_D(KChatBase); 0135 0136 d->mAcceptMessage = a; 0137 } 0138 0139 bool KChatBase::addSendingEntry(const QString &text, int id) 0140 { 0141 // FIXME: is ID used correctly? 0142 // do we need ID at all? 0143 // what the hell should be here? 0144 // d->mCombo->insertItem(i18n("Send to All Players"), SendToAll); 0145 return insertSendingEntry(text, id); 0146 } 0147 0148 bool KChatBase::insertSendingEntry(const QString &text, int id, int index) 0149 { 0150 Q_D(KChatBase); 0151 0152 if (!d->mCombo) { 0153 qCWarning(KDEGAMESPRIVATE_LOG) << "KChatBase: Cannot add an entry to the combo box"; 0154 return false; 0155 } 0156 if (d->mIndex2Id.indexOf(id) != -1) { 0157 qCCritical(KDEGAMESPRIVATE_LOG) << "KChatBase: Cannot add more than one entry with the same ID! "; 0158 qCCritical(KDEGAMESPRIVATE_LOG) << "KChatBase: Text=" << text; 0159 return false; 0160 } 0161 d->mCombo->insertItem(index, text); 0162 if (index < 0) { 0163 d->mIndex2Id.prepend(id); 0164 } else { 0165 d->mIndex2Id.insert(d->mIndex2Id.at(index), id); 0166 } 0167 if (d->mIndex2Id.count() != d->mCombo->count()) { 0168 qCCritical(KDEGAMESPRIVATE_LOG) << "KChatBase: internal ERROR - local IDs do not match combo box entries!"; 0169 } 0170 return true; 0171 } 0172 0173 int KChatBase::sendingEntry() const 0174 { 0175 Q_D(const KChatBase); 0176 0177 if (!d->mCombo) { 0178 qCWarning(KDEGAMESPRIVATE_KGAME_LOG) << "Cannot retrieve index from NULL combo box"; 0179 return -1; 0180 } 0181 const int index = d->mCombo->currentIndex(); 0182 if (index >= 0 && index < d->mIndex2Id.size()) 0183 return d->mIndex2Id[index]; 0184 0185 qCWarning(KDEGAMESPRIVATE_LOG) << "could not find the selected sending entry!"; 0186 return -1; 0187 } 0188 0189 void KChatBase::removeSendingEntry(int id) 0190 { 0191 Q_D(KChatBase); 0192 0193 if (!d->mCombo) { 0194 qCWarning(KDEGAMESPRIVATE_LOG) << "KChatBase: Cannot remove an entry from the combo box"; 0195 return; 0196 } 0197 int idx = findIndex(id); 0198 // Guard, passing -1 will crash qcombobox 0199 if (idx >= 0) 0200 d->mCombo->removeItem(idx); 0201 d->mIndex2Id.removeAll(id); 0202 } 0203 0204 void KChatBase::changeSendingEntry(const QString &text, int id) 0205 { 0206 Q_D(KChatBase); 0207 0208 if (!d->mCombo) { 0209 qCWarning(KDEGAMESPRIVATE_LOG) << "KChatBase: Cannot change an entry in the combo box"; 0210 return; 0211 } 0212 int index = findIndex(id); 0213 d->mCombo->setItemText(index, text); 0214 } 0215 0216 void KChatBase::setSendingEntry(int id) 0217 { 0218 Q_D(KChatBase); 0219 0220 if (!d->mCombo) { 0221 qCWarning(KDEGAMESPRIVATE_LOG) << "KChatBase: Cannot set an entry in the combo box"; 0222 return; 0223 } 0224 d->mCombo->setCurrentIndex(findIndex(id)); 0225 } 0226 0227 int KChatBase::findIndex(int id) const 0228 { 0229 Q_D(const KChatBase); 0230 0231 return d->mIndex2Id.indexOf(id); 0232 } 0233 0234 int KChatBase::nextId() const 0235 { 0236 Q_D(const KChatBase); 0237 0238 int i = SendToAll + 1; 0239 while (d->mIndex2Id.indexOf(i) != -1) { 0240 i++; 0241 } 0242 return i; 0243 } 0244 0245 void KChatBase::slotReturnPressed(const QString &text) 0246 { 0247 Q_D(KChatBase); 0248 0249 if (text.length() <= 0) { 0250 // no text entered - probably hit return by accident 0251 return; 0252 } else if (!acceptMessage()) { 0253 return; 0254 } 0255 d->mEdit->completionObject()->addItem(text); 0256 d->mEdit->clear(); 0257 returnPressed(text); 0258 } 0259 0260 QString KChatBase::comboBoxItem(const QString &name) const 0261 { // TODO: such a function for "send to all" and "send to my group" 0262 return i18n("Send to %1", name); 0263 } 0264 0265 void KChatBase::slotClear() 0266 { 0267 clear(); 0268 } 0269 0270 void KChatBase::setCompletionMode(KCompletion::CompletionMode mode) 0271 { 0272 Q_D(KChatBase); 0273 0274 d->mEdit->setCompletionMode(mode); 0275 } 0276 0277 void KChatBase::saveConfig(KConfig *conf) 0278 { 0279 Q_D(KChatBase); 0280 0281 if (conf == nullptr) { 0282 return; 0283 } 0284 d->mModel->saveConfig(conf); 0285 } 0286 0287 void KChatBase::readConfig(KConfig *conf) 0288 { 0289 Q_D(KChatBase); 0290 0291 if (conf == nullptr) { 0292 return; 0293 } 0294 d->mModel->readConfig(conf); 0295 } 0296 0297 void KChatBase::clear() 0298 { 0299 Q_D(KChatBase); 0300 0301 d->mModel->removeRows(0, d->mModel->rowCount()); 0302 } 0303 0304 void KChatBase::setMaxItems(int maxItems) 0305 { 0306 Q_D(KChatBase); 0307 0308 d->mModel->setMaxItems(maxItems); 0309 // TODO cut too many messages 0310 if (maxItems == 0) { 0311 clear(); 0312 } else if (maxItems > 0) { 0313 while (d->mModel->rowCount() > (int)maxItems) { 0314 d->mModel->removeRow(0); 0315 } 0316 } 0317 } 0318 0319 int KChatBase::maxItems() const 0320 { 0321 Q_D(const KChatBase); 0322 0323 return d->mModel->maxItems(); 0324 } 0325 0326 QFont KChatBase::nameFont() const 0327 { 0328 Q_D(const KChatBase); 0329 0330 return d->mModel->nameFont(); 0331 } 0332 0333 QFont KChatBase::messageFont() const 0334 { 0335 Q_D(const KChatBase); 0336 0337 return d->mModel->messageFont(); 0338 } 0339 0340 QFont KChatBase::systemNameFont() const 0341 { 0342 Q_D(const KChatBase); 0343 0344 return d->mModel->systemNameFont(); 0345 } 0346 0347 QFont KChatBase::systemMessageFont() const 0348 { 0349 Q_D(const KChatBase); 0350 0351 return d->mModel->systemMessageFont(); 0352 } 0353 0354 void KChatBase::setNameFont(const QFont &font) 0355 { 0356 Q_D(KChatBase); 0357 0358 d->mModel->setNameFont(font); 0359 } 0360 0361 void KChatBase::setMessageFont(const QFont &font) 0362 { 0363 Q_D(KChatBase); 0364 0365 d->mModel->setMessageFont(font); 0366 } 0367 0368 void KChatBase::setBothFont(const QFont &font) 0369 { 0370 Q_D(KChatBase); 0371 0372 d->mModel->setBothFont(font); 0373 } 0374 0375 void KChatBase::setSystemNameFont(const QFont &font) 0376 { 0377 Q_D(KChatBase); 0378 0379 d->mModel->setSystemNameFont(font); 0380 } 0381 0382 void KChatBase::setSystemMessageFont(const QFont &font) 0383 { 0384 Q_D(KChatBase); 0385 0386 d->mModel->setSystemMessageFont(font); 0387 } 0388 0389 void KChatBase::setSystemBothFont(const QFont &font) 0390 { 0391 Q_D(KChatBase); 0392 0393 d->mModel->setSystemBothFont(font); 0394 } 0395 0396 void KChatBase::addMessage(const QString &fromName, const QString &text) 0397 { 0398 Q_D(KChatBase); 0399 0400 d->mModel->addMessage(fromName, text); 0401 } 0402 0403 void KChatBase::addSystemMessage(const QString &fromName, const QString &text) 0404 { 0405 Q_D(KChatBase); 0406 0407 d->mModel->addSystemMessage(fromName, text); 0408 } 0409 0410 #include "moc_kchatbase.cpp"