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 #ifndef __KCHATBASE_H__
0010 #define __KCHATBASE_H__
0011 
0012 // own
0013 #include "kdegamesprivate_export.h"
0014 // KF
0015 #include <KCompletion>
0016 // Qt
0017 #include <QFrame>
0018 // Std
0019 #include <memory>
0020 
0021 class KConfig;
0022 
0023 class KChatBasePrivate;
0024 class KChatBaseModel;
0025 class KChatBaseItemDelegate;
0026 class QModelIndex;
0027 class QPoint;
0028 
0029 /**
0030  * \class KChatBase kchatbase.h <KChatBase>
0031  *
0032  * @short The base class for chat widgets
0033  *
0034  * This is the base class for both KChat and KGameChat. KGameChat is the class
0035  * you want to use if you write a KGame based game as it will do most things for
0036  * you. KChat is more or less the same but not KGame dependent
0037  *
0038  * KChatBase provides a complete chat widget, featuring different sending means
0039  * (e.g. "send to all", "send to player1", "send to group2" and so on - see
0040  * addSendingEntry). It also provides full auto-completion capabilities (see
0041  * KCompletion and KLineEdit) which defaults to disabled. The user can
0042  * change this by right-clicking on the KLineEdit widget and selecting the
0043  * desired behaviour. You can also change this manually by calling
0044  * setCompletionMode.
0045  *
0046  * To make KhatBase useful you have to overwrite at least returnPressed.
0047  * Here you should send the message to all of your clients (or just some of
0048  * them, depending on sendingEntry).
0049  *
0050  * To add a message just call addMessage with the nickname of the player
0051  * who sent the message and the message itself.
0052  *
0053  * You probably don't want to use the abstract class KChatBase directly but use
0054  * one of the derived classes KChat or KGameChat. The latter is the
0055  * widget of choice if you develop a KGame application as you don't have to
0056  * do anything but providing a KGame object. If you want to change the kind of
0057  * elements displayed (using pixmaps for example), then you will also have to
0058  * derive the KChatBaseModel and KChatBaseItemDelegate classes.
0059  *
0060  * @author Andreas Beckermann <b_mann@gmx.de>
0061  * @author Gael de Chalendar (aka Kleag) <kleag@free.fr> for the port to Model/View
0062  */
0063 class KDEGAMESPRIVATE_EXPORT KChatBase : public QFrame
0064 {
0065     Q_OBJECT
0066 
0067 public:
0068     /**
0069      * @param parent The parent widget for this widget.
0070      * @param model
0071      * @param delegate
0072      * @param noComboBox If true then the combo box where the player can
0073      * choose where to send messages to (either globally or just to some
0074      * players) will not be added.
0075      */
0076     explicit KChatBase(QWidget *parent, KChatBaseModel *model = nullptr, KChatBaseItemDelegate *delegate = nullptr, bool noComboBox = false);
0077 
0078     /**
0079      * Destruct the KChatBase object
0080      *
0081      * Also calls saveConfig
0082      */
0083     ~KChatBase() override;
0084 
0085     enum SendingIds { SendToAll = 0 };
0086 
0087     /**
0088      * @return The name that will be shown for messages from this widget. Either the
0089      * string that was set by setFromName or the name of the player
0090      * that was set by setFromPlayer
0091      */
0092     virtual QString fromName() const = 0;
0093 
0094     /**
0095      * Adds a new entry in the combo box. The default is "send to all
0096      * players" only. This function is provided for convenience. You can
0097      * also call insertSendingEntry with index = -1.
0098      * See also nextId!
0099      * @param text The text of the new entry
0100      * @param id An ID for this entry. This must be unique for this
0101      * entry. It has nothing to do with the position of the entry in the
0102      * combo box. See nextId
0103      * @return True if successful, otherwise false (e.g. if the id is already used)
0104      */
0105     bool addSendingEntry(const QString &text, int id);
0106 
0107     /**
0108      * Inserts a new entry in the combo box.
0109      * @param text The entry
0110      * @param id An ID for this entry. This must be unique for this
0111      * entry. It has nothing to do with the position of the entry in the
0112      * combo box!
0113      * @see nextId
0114      * @param index The position of the entry. If -1 the entry will be added
0115      * at the bottom
0116      * @return True if successful, otherwise false (e.g. if the id is already used)
0117      */
0118     bool insertSendingEntry(const QString &text, int id, int index = -1);
0119 
0120     /**
0121      * This changes a combo box entry.
0122      * @param text The new text of the entry
0123      * @param id The ID of the item to be changed
0124      */
0125     void changeSendingEntry(const QString &text, int id);
0126 
0127     /**
0128      * This selects a combo box entry.
0129      * @param id The ID of the item to be selected
0130      */
0131     void setSendingEntry(int id);
0132 
0133     /**
0134      * Removes the entry with the ID id from the combo box. Note that id is
0135      * _not_ the index of the entry!
0136      * @see addSendingEntry
0137      * @param id The unique id of the entry
0138      */
0139     void removeSendingEntry(int id);
0140 
0141     /**
0142      * @return The _unique ID_ of the sending entry that has been selected.
0143      * @see addSendingEntry
0144      *
0145      * Note that the entry "send to all" _always_ uses
0146      * KChatBase::SendToAll, i.e. 0 as id!
0147      */
0148     int sendingEntry() const;
0149 
0150     /**
0151      * @return The index of the combo box entry with the given id
0152      */
0153     int findIndex(int id) const;
0154 
0155     /**
0156      * @return An ID that has not yet been used in the combo box.
0157      * @see addSendingEntry
0158      */
0159     int nextId() const;
0160 
0161     /**
0162      * @return True if this widget is able to send messages (see
0163      * returnPressed) and false if not. The default implementation returns
0164      * the value which has been set by setAcceptMessage (true by
0165      * default)
0166      */
0167     virtual bool acceptMessage() const;
0168 
0169     /**
0170      * See KLineEdit::setCompletionMode
0171      */
0172     void setCompletionMode(KCompletion::CompletionMode mode);
0173 
0174     /**
0175      * Set the font that is used for the name part of a message. See also
0176      * nameFont and setBothFont
0177      */
0178     void setNameFont(const QFont &font);
0179 
0180     /**
0181      * Set the font that is used for the message part of a message.
0182      * @see messageFont, setBothFont
0183      */
0184     void setMessageFont(const QFont &font);
0185 
0186     /**
0187      * This sets both - nameFont and messageFont to font. You
0188      * probably want to use this if you don't wish to distinguish between
0189      * these parts of a message.
0190      * @param font A font used for both nameFont and messageFont
0191      */
0192     void setBothFont(const QFont &font);
0193 
0194     /**
0195      * Same as setNameFont but applies only to system messages.
0196      * @see layoutSystemMessage
0197      */
0198     void setSystemNameFont(const QFont &font);
0199 
0200     /**
0201      * Same as setMessageFont but applies only to system messages.
0202      * @see layoutSystemMessage
0203      */
0204     void setSystemMessageFont(const QFont &font);
0205 
0206     /**
0207      * Same as setBothFont but applies only to system messages.
0208      * @see layoutSystemMessage
0209      */
0210     void setSystemBothFont(const QFont &font);
0211 
0212     /**
0213      * This font should be used for the name (the "from: " part) of a
0214      * message. layoutMessage uses this to set the font using
0215      * KChatBaseItemDelegate::setNameFont but if you want to overwrite
0216      * layoutMessage you should do this yourself.
0217      * @return The font that is used for the name part of the message.
0218      */
0219     QFont nameFont() const;
0220 
0221     /**
0222      * This font should be used for a message. layoutMessage sets the
0223      * font of a message using KChatBaseItemDelegate::setMessageFont but if you
0224      * replace layoutMessage with your own function you should use
0225      * messageFont() yourself.
0226      * @return The font that is used for a message
0227      */
0228     QFont messageFont() const;
0229 
0230     /**
0231      * Same as systemNameFont but applies only to system messages.
0232      * @see layoutSystemMessage
0233      */
0234     QFont systemNameFont() const;
0235 
0236     /**
0237      * Same as systemMessageFont but applies only to system messages.
0238      * @see layoutSystemMessage
0239      */
0240     QFont systemMessageFont() const;
0241 
0242     /**
0243      * Save the configuration of the dialog to a KConfig object. If
0244      * the supplied KConfig pointer is NULL then KGlobal::config() is used
0245      * instead (and the group is changed to "KChatBase") butr the current
0246      * group is restored at the end.
0247      * @param conf A pointer to the KConfig object to save the config
0248      * to. If you use 0 then KGlobal::config() is used and the group is changed
0249      * to "KChatBase" (the current group is restored at the end).
0250      */
0251     virtual void saveConfig(KConfig *conf = nullptr);
0252 
0253     /**
0254      * Read the configuration from a KConfig object. If the pointer is
0255      * NULL KGlobal::config() is used and the group is changed to "KChatBase".
0256      * The current KConfig::group is restored after this call.
0257      */
0258     virtual void readConfig(KConfig *conf = nullptr);
0259 
0260     /**
0261      * Set the maximum number of items in the list. If the number of item
0262      * exceeds the maximum as many items are deleted (oldest first) as
0263      * necessary. The number of items will never exceed this value.
0264      * @param maxItems the maximum number of items. -1 (default) for
0265      * unlimited.
0266      */
0267     void setMaxItems(int maxItems);
0268 
0269     /**
0270      * Clear all messages in the list.
0271      */
0272     void clear();
0273 
0274     /**
0275      * @return The maximum number of messages in the list. -1 is unlimited. See also
0276      * setMaxItems
0277      */
0278     int maxItems() const;
0279 
0280     KChatBaseModel *model();
0281     void setModel(KChatBaseModel *m);
0282 
0283 public Q_SLOTS:
0284     /**
0285      * Add a text in the listbox. See also signalSendMessage()
0286      *
0287      * Maybe you want to replace this with a function that creates a nicer text
0288      * than "fromName: text"
0289      *
0290      * Update: the function layoutMessage is called by this now. This
0291      * means that you will get user defined outlook on the messages :-)
0292      * @param fromName The player who sent this message
0293      * @param text The text to be added
0294      */
0295     virtual void addMessage(const QString &fromName, const QString &text);
0296 
0297     /**
0298      * This works just like addMessage but adds a system message.
0299      * layoutSystemMessage is used to generate the displayed item. System
0300      * messages will have a different look than player messages.
0301      *
0302      * You may wish to  use this to display status information from your game.
0303      */
0304     virtual void addSystemMessage(const QString &fromName, const QString &text);
0305 
0306     /**
0307      * This clears all messages in the view. Note that only the messages are
0308      * cleared, not the sender names in the combo box!
0309      */
0310     void slotClear();
0311 
0312     /**
0313      * @param a If false this widget cannot send a message until
0314      * setAcceptMessage(true) is called
0315      */
0316     void setAcceptMessage(bool a);
0317 
0318 protected:
0319     /**
0320      * This is called whenever the user pushed return ie wants to send a
0321      * message.
0322      *
0323      * Note that you MUST add the message to the widget when this function
0324      * is called as it has already been added to the KCompletion object
0325      * of the KLineEdit widget!
0326      *
0327      * Must be implemented in derived classes
0328      * @param text The message to be sent
0329      */
0330     virtual void returnPressed(const QString &text) = 0;
0331 
0332     /**
0333      * Replace to customize the combo box.
0334      *
0335      * Default: i18n("Send to %1).arg(name)
0336      * @param name The name of the player
0337      * @return The string as it will be shown in the combo box
0338      */
0339     virtual QString comboBoxItem(const QString &name) const;
0340 
0341     /**
0342      * Returns the model index of the message at the viewport coordinates point
0343      * @param pos position to check index for
0344      * @return model index of message with coordinates pos
0345      */
0346     QModelIndex indexAt(QPoint pos) const;
0347 
0348 private Q_SLOTS:
0349     /**
0350      * Check if a text was entered and if acceptMessage returns true.
0351      * Then add the message to the KCompletion object of the KLineEdit
0352      * widget and call returnPressed
0353      */
0354     void slotReturnPressed(const QString &);
0355 
0356     /**
0357      * Implements custom menu which is applicable for one chat message
0358      * @param pos point where custom menu has been requested (widget coordinates)
0359      */
0360     virtual void customMenuHandler(QPoint pos);
0361 
0362 protected:
0363     KChatBase(KChatBasePrivate &dd, QWidget *parent, bool noComboBox);
0364 
0365 private:
0366     friend class KGameChat;
0367     Q_DECLARE_PRIVATE_D(d, KChatBase)
0368     std::unique_ptr<KChatBasePrivate> const d;
0369     // KF6 TODO: change private d to protected d_ptr, use normal Q_DECLARE_PRIVATE, remove subclass friend
0370 };
0371 
0372 #endif