Logo Search packages:      
Sourcecode: qchat version File versions  Download package

chatcore.h

/***************************************************************************
 *   Copyright (C) 2007 by Anistratov Oleg                                 *
 *   ower@users.sourceforge.net                                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation;                         *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 ***************************************************************************/

#ifndef CHATCORE_H
#define CHATCORE_H

#include <QObject>
#include <QThread>
#include <QUdpSocket>
#include <QHostInfo>
#include <QByteArray>
#include <QColor>
#include <QSettings>
#include <QTimer>
#include <QHostAddress>
#include <QMap>
#include <QDir>
#include <QTextDocument>

class ChatWgt;
class NLAmarok;
class ReceiverThread;
class SenderThread;
class LargeDatagram;
class UserInfo;
class Preferences;
class QC_DatagramHeader;
class UserProfile;
class Smile;
class SingleMsgsHistory;
class Message;

struct CmdArgs
{
  int port_in;
  int port_out;

  CmdArgs() : port_in(-1), port_out(-1){}
};

/**
        @author Anistratov Oleg <ower@users.sourceforge.net>
*/
00056 class ChatCore : public QThread
{
  Q_OBJECT
  private:
    QByteArray      m_smilesParam;

    /// Main Window Geometry
00063     QByteArray      m_geometry;
    /// Main Window State
00065     QByteArray      m_state;
    QString         m_lang;
    int             m_needCheckIp;

    QMap<QString, QByteArray> m_channelsStates;

    QString         m_nowListening;
    bool            m_nlIsNew;
#if defined(Q_OS_LINUX)
    NLAmarok*       m_nlAmarok;
#endif
    ChatWgt*        m_chatWgt;
    ReceiverThread* m_receiver;
    SenderThread*   m_sender;

    UserInfo*       m_myInfo;
    Preferences*    m_prefs;
    QMap<QString, UserProfile*>
                    m_profiles;
    UserProfile*    m_currentProfile;

    QSettings*      m_settings;
    QTimer*         m_statusTimer;

    /// Hranit dannye poluchennye posle razbora paketa kak massiva baitov
    /// (imya i IP otpravitelya, soobschenie, i t.d.)
00091     QC_DatagramHeader* Hdr;
    /// Vhodnoi Buffer - suda zapisyvayutsya pakety(<= 2^16-1) posle prinyatiya
00093     char*           m_inputBuffer;
    /// Vyhodnoi Buffer - suda zapisyvayutsya dannye(<= 2^16-1) pered otpravkoi
00095     char*           m_outputBuffer;
    /// Ispol'zuetsya dlya otpravki bol'shih(> 2^16-1) paketov
    /// Hranit zagolovok paketa
00098     char*           m_header;
    /// Ispol'zuetsya dlya otpravki bol'shih(> 2^16-1) paketov
    /// Hranit dannye(soobschenie i massiv $Parametrs) paketa
00101     char*           m_data;

    QByteArray      m_parametrs;

    unsigned short  m_inputBufferSize;
    unsigned long   m_outputBufferSize;
    unsigned long   m_dataSize;
    unsigned short  m_headerSize;
    QUdpSocket      m_socketOut;

    QString m_settingsDirName;

    /// Flag pokazyvayuschi chto razmer otsylaemogo paketa > 2^16-1
00114     bool m_largeDtgrm;

    // NowListening
    QString m_nlTitle;
    QString m_nlArtist;
    QString m_nlAlbum;

    static QTimer* m_chatTimer;
    quint32 m_chatTime;

  public:
    SingleMsgsHistory* m_singleMsgsHistory;

  private:
    QString homePath(){return QDir::homePath ();}

  public:
    ChatCore(QObject *parent = 0);
    ~ChatCore();

    const QByteArray & geometry() const {return m_geometry;}
    const QByteArray & state() const {return m_state;}
    int needCheckIp() const {return m_needCheckIp;}
    QByteArray channelState(const QString & ch) const {return m_channelsStates.value(ch);}

    void setChatWgt(ChatWgt* chw){m_chatWgt = chw;}

    void run(){exec();}
    void stopThreads();

    CmdArgs* processCmdArgs(int argc, char* argv[]);

    bool initSettings();

    void slot_loadSettings();
    UserProfile* readProfile(const QString &);
    void writeProfile(const UserProfile*);

    static QByteArray getParametr(const QString & par_name, const QByteArray & pars);
    static void addParametr(const QString & par_name, const QByteArray & par, QByteArray & buf);
    static QColor getColorParametr(QByteArray*);

    inline void addParametr      (const QString & par_name, const QByteArray & par);
    inline QByteArray getParametr(const QString & par_name);
    inline void clearParametrs   ();
    void addParametr(const QString & par_name, const QString & filename);

    QStringList profiles() const;
    const QString & currentProfile() const;

    /**
     * Generiruent paket
     * @param dtgrm_type - tip paketa iz enum DataType
     * @param msg_len - dlina soobscheniya
     * @param msg - soobschenie
     * @param chnnl_id - id kanala v kotoryi posylaetsya soobschenie
     * @param dtgrm_id - id paketa(dlya fragmentirovannyh paketov)
     * @param dtgrm_num - nomer paketa(dlya fragmentirovannyh paketov)
     * @param parametrs_len - dlina massiva parametrs
     * @param parametrs - razlichnye dopolnitel'nye parametry(ne yavlyaetsya C-strokoi).
       format: [char*(C-stroka) par1_name][Ushort par1_len][char[par1_len] par1]...
               [char*(C-stroka) parN_name][Ushort parN_len][char[parN_len] parN]
     */
    void prepareDatagram(unsigned char dtgrm_type    , quint32 dest_ip           , const QString & msg  = "",
                         unsigned long  chnnl_id  = 0, unsigned long dtgrm_id = 0, unsigned long dtgrm_num = 0);

    /// otsylaet dannye nahodyaschiesya v $m_outputBuffer po addressu $addr
    void sendData       (const QHostAddress & addr);

    bool fillHeader();
    void startThreads();
    void processData();

    quint32 initSendingFile  (const QHostAddress &, const QString &, QObject*);
    void    initReceivingFile(QObject*);

    /**
     * adding all smiles in $message to $m_parametrs in reason that smiles on receiver side
     * are looking such as smiles on sender side
     * @param  message - message to process
     */
    void processSmiles(QString);
    void nextSmile(const QString &);

    ReceiverThread* receiver(){return m_receiver;}

  public slots:
    void slot_prepareAndSend    (const QString &, const QHostAddress &, uint , const QString & = "", quint32 = 0, QByteArray* = NULL);
    void slot_sendMessage       (const QString &, const QHostAddress &, quint32, QTextDocument*);
    void slot_statusAnswer      (const QString &, const QHostAddress &, quint32 ch_type = 0, bool changed = 0, bool = 0);
    void slot_infoAnswer        (const QString &, const QHostAddress &, quint32 ch_type = 0, uchar = 0);

    void slot_avatarAnswer      (const QString &, const QHostAddress &, quint32 ch_type = 0);

    void slot_privateChatRequest(const QString &, const QHostAddress &);
    void slot_infStatusChanged  (const QString & );

    void slot_singleMessage     (const QString & msg, const QHostAddress & addr, quint32 ch_type = 0);
    void slot_msgsHistoryAnswer (const QString &, const QHostAddress &, const QByteArray &, uint);
    void slot_msgsNumAnswer     (const QString &, const QHostAddress &, quint32, uint);
    void slot_requestFragments  (char*, quint32, quint32, const QHostAddress &);

    void slot_processData     (char*, quint16);
    void slot_processLargeData(LargeDatagram*);
    void slot_bindInputPort(int);
    void slot_acceptReceiving(quint16, quint64);
    void slot_saveSettings();

    void slot_setNl(const QString &, const QString &, const QString &);

    /**
     *
     * @param  reason: 0 - rejected(receiving didn't ever began)
                       1 - cancelled
     */
    void slot_rejectReceiving(quint16, quint64, int reason);
    void slot_confirmReceivingFile(quint8, quint16, const QHostAddress &);

    void slot_openSocketError(quint16);

    /**
     * setting the profile with name $name(if it exists) to be current profile
     * @param  name name of profile to load
     */
    void slot_loadProfile  (const QString & name);
    void slot_renameProfile(const QString &, const QString &);
    void slot_deleteProfile(const QString &);
    void slot_updateChatTime(){m_chatTime += 1;}

    void setChannelState(const QString & ch, const QByteArray & ba) {m_channelsStates.insert(ch, ba);}

  public:
    void setLang(const QString & value){m_lang = value;}
    const QString & lang() const {return m_lang;}

  signals:
    void closed             ();
    void singleMessageIn    (Message*);
    void privateChatRequest (const QString &, const QHostAddress &);
    void profileLoaded      (const QString &);
    void chatDataReceived   (QC_DatagramHeader*);
    void wantSendLargeData  (char*, quint16, char* , quint32, const QHostAddress &, quint32);
    void wantSendFile       (char*, quint16, const QString &, const QHostAddress &, quint32);
    void wantChangeInputPort(quint16);
};

#endif

Generated by  Doxygen 1.6.0   Back to index