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

channelwgt.cpp

/***************************************************************************
 *   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.                          *
 *                                                                         *
 ***************************************************************************/
#include "channelwgt.h"

#include <QList>
#include <QProcess>
#include <QColor>
#include <QCoreApplication>
#include <QIcon>
#include <QScrollBar>
#include <QPainter>
#include <QCryptographicHash>
#include <QBitmap>
#include <QDir>

#include <assert.h>

#include "chatwgt.h"
#include "chatcore.h"
#include "msghistory.h"
#include "userslist.h"
#include "userslistwgt.h"
#include "message.h"
#include "statuseditwgt.h"
#include "chattextwgt.h"
#include "inputtextwgt.h"
#include "userwgt.h"
#include "userinfo.h"
#include "usersstatisticswgt.h"
#include "usersstatisticsmodel.h"
#include "userstatistics.h"

ChannelWgt::ChannelWgt(QString name_, QWidget *parent, quint32 type, QHostAddress dest_ip)
 : QWidget(parent),
  m_type            (type),
  m_destIp          (dest_ip),
  m_name            (name_),
  m_usersNum        (0),
  m_passwordSize    (0),
  m_messageSize     (0),
  m_displayInfoMsgs (true),
  m_soundOnMessageIn(true),
  m_requestsRest    (0)
{
  m_parent = (ChatWgt*)parentWidget();

  QSplitter* lv_split;
  QSplitter* rv_split;
  QSplitter* h_split;

  m_smilesFromSender   = new QList<Smile>;

  m_chatMsgs           = new MsgHistory;
  m_users              = new UsersList;

  m_statusWgt          = new StatusEditWgt(this);
  m_file               = new QFile();
  mw_grid              = new QGridLayout(this);
  mw_chatTextStack     = new QStackedWidget(this);
  mw_usersStack        = new QStackedWidget(this);
  lv_split             = new QSplitter(Qt::Vertical);
  rv_split             = new QSplitter(Qt::Vertical);
  h_split              = new QSplitter(Qt::Horizontal);
  mw_chatText          = new ChatTextWgt(this);
  mw_clearChatText     = new ChatTextWgt(this);
  mw_inputText         = new InputTextWgt(this);
  mw_usersList         = new UsersListWgt(this);
  mw_usersStatistics   = new UsersStatisticsWgt(this);
  m_sendBtn            = new QPushButton(this);
  m_refreshUlBtn       = new QPushButton(this);
  m_sysMessagesChbx    = new QCheckBox(this);
  m_refreshTimer       = new QTimer(this);
  m_statusChangedTimer = new QTimer(this);
  m_initTimer          = new QTimer(this);
  m_usersModel         = new UsersStatisticsModel(this);

  m_splitters.append(lv_split);
  m_splitters.append(rv_split);
  m_splitters.append(h_split);

  m_usersModel->setUsers(m_users);
  mw_usersStatistics->setModel(m_usersModel);
  mw_usersStatistics->setSortingEnabled(true);

  mw_clearChatText->setSmilesFromSender(m_smilesFromSender);
  mw_chatText     ->setSmilesFromSender(m_smilesFromSender);

  m_myStatus           = m_statusWgt->status();
  m_oldStatus          = m_statusWgt->status();
  m_statusDescription  = m_statusWgt->description();

  mw_clearChatText->hide();

  mw_chatTextStack->addWidget(mw_chatText);
  mw_chatTextStack->addWidget(mw_clearChatText);

  mw_usersStack->addWidget(mw_usersList);
  mw_usersStack->addWidget(mw_usersStatistics);

  mw_grid->setMargin(1);

  lv_split->addWidget(m_sysMessagesChbx);
  lv_split->addWidget(mw_chatTextStack);
  lv_split->addWidget(mw_inputText);
  lv_split->addWidget(m_sendBtn);

  rv_split->addWidget(m_statusWgt);
  rv_split->addWidget(mw_usersStack);
  rv_split->addWidget(m_refreshUlBtn);

  h_split ->addWidget(lv_split);
  h_split ->addWidget(rv_split);

  resize(800, 370);

  QList<int> tmplst;
  tmplst.append(590);
  tmplst.append(210);

  h_split ->setSizes(tmplst);

  tmplst.clear();
  tmplst.append(25);
  tmplst.append(300);
  tmplst.append(70);
  tmplst.append(25);

  lv_split->setSizes(tmplst);

  tmplst.clear();
  tmplst.append(25);
  tmplst.append(370);
  tmplst.append(25);

  rv_split->setSizes(tmplst);

  mw_grid->addWidget(h_split    , 0, 0);

  m_refreshUlBtn   ->setMaximumHeight(25);
  m_sendBtn        ->setMaximumHeight(25);
  m_sysMessagesChbx->setMaximumHeight(24);
  mw_inputText     ->setMinimumHeight(30);


  connect(m_statusChangedTimer, SIGNAL(timeout()), this        , SLOT(slot_statusChanged()));
  connect(m_refreshTimer      , SIGNAL(timeout()), this        , SLOT(slot_statusRequest()));
  connect(m_sendBtn           , SIGNAL(clicked()), mw_inputText, SLOT(sendMsg()));
  connect(m_sendBtn           , SIGNAL(clicked()), mw_inputText, SLOT(setFocus()));
  connect(m_refreshUlBtn      , SIGNAL(clicked()), this        , SLOT(slot_refreshUL()));
  connect(m_sysMessagesChbx   , SIGNAL(clicked()), this        , SLOT(slot_chbxInfChgd()));
  connect(mw_inputText        , SIGNAL(wantSend()), this, SLOT(slot_msgOut   ()));

  connect(mw_usersList        , SIGNAL(itemDoubleClicked(UserWgt*)),
          m_parent            , SLOT  (slot_showUserInfo(UserWgt*)));

  connect(mw_usersList        , SIGNAL(itemDoubleClicked(UserWgt*)),
          this                , SLOT  (slot_infoRequest (UserWgt*)));

  connect(m_statusWgt         , SIGNAL(statusChanged()),
          this                , SLOT  (slot_startStatusChangedTimer()));

  connect(m_statusWgt         , SIGNAL(editing()),  m_statusChangedTimer, SLOT(stop()));

  connect(h_split, SIGNAL(splitterMoved(int, int)),this, SLOT(slot_controlSplitter(int, int)));

  connect((QObject*)mw_usersStatistics->horizontalHeader(), SIGNAL(sectionClicked(int)),
          mw_usersStatistics                    , SLOT(sortByColumn(int)));

  connect(mw_usersStatistics, SIGNAL(sorted()),
          this              , SLOT  (updateUsersView()));

  if(m_parent)
  {
    connect(mw_usersList  , SIGNAL(singleMessage   (const QString &, const QHostAddress &)),
            m_parent      , SIGNAL(singleMessage   (const QString &, const QHostAddress &)));
    connect(mw_usersList  , SIGNAL(wantPrivateChat (const QString &, const QHostAddress &)),
            m_parent      , SLOT  (slot_privateChat(const QString &, const QHostAddress &)));
    connect(mw_usersList  , SIGNAL(wantSendFile    (const QHostAddress &)),
            m_parent      , SLOT  (slot_sendFile   (const QHostAddress &)));
  }

  mw_clearChatText->text()->verticalScrollBar()->setValue(mw_clearChatText->text()->verticalScrollBar()->maximum());
  mw_chatText     ->text()->verticalScrollBar()->setValue(mw_chatText     ->text()->verticalScrollBar()->maximum());

  m_refreshTimer->start(Globals::prefs()->usersListRefreshInterval() * 1000);

  retranslate();
}
//\*****************************************************************************
ChannelWgt::~ChannelWgt()
{
  emit wantSaveState(m_name, saveState());
  slot_disconnected();

  qDebug("[~ChannelWgt '%s']", m_name.toLocal8Bit().data());
}
//\*****************************************************************************
UserWgt* ChannelWgt::findUser(quint64 Ip) const
{
  return m_users->findByIp(Ip);
}
//\*****************************************************************************
void ChannelWgt::setFocus2InputText()
{
  mw_inputText->setFocus();
}
//\*****************************************************************************
void ChannelWgt::processData(QC_DatagramHeader* Hdr)
{
  qDebug("[ChannelWgt::processData]");

  if(Hdr->src_ip == 0)
    return;

  switch(Hdr->type)
  {
    case (quint8)Globals::MESSAGE        :
      qDebug("[ChannelWgt::processData]: Message");
      emit wantActivate();
      getSmilesFromData(Hdr);
      addMsg(Hdr);
      break;

    case (quint8)Globals::STATUS_REQUEST :
      qDebug("[ChannelWgt::processData]: StatusRequest");
      sendStatusAnswer(m_name, QHostAddress(Hdr->src_ip), Hdr->programVersion < 14);
      break;

    case (quint8)Globals::STATUS_ANSWER  :
      qDebug("[ChannelWgt::processData]: StatusAnswer");
      addUser(Hdr);
      break;

    case (quint8)Globals::CONNECTED  :
      qDebug("[ChannelWgt::processData]: Connected");
      addUser(Hdr);
      addInfoMsg(Hdr);
      break;

    case (quint8)Globals::DISCONNECTED  :
      qDebug("[ChannelWgt::processData]: Disconnected");
      addInfoMsg(Hdr);
      hideUser(Hdr);
      break;

    case (quint8)Globals::INF_STATUS_CHNGD :
      qDebug("[ChannelWgt::processData]: StatusChanged");
      addUser(Hdr);
      addInfoMsg(Hdr);
      break;

    case (quint8)Globals::INFO_REQUEST  :
      qDebug("[ChannelWgt::processData]: UserInfoRequest");
      sendInfoAnswer(Hdr);
      break;

    case (quint8)Globals::INFO_ANSWER  :
      qDebug("[ChannelWgt::processData]: UserInfoAnswer");
      addUserInfo(Hdr);
      addUser(Hdr);
      break;

    case Globals::MSGS_HISTORY_REQUEST :
      qDebug("[ChannelWgt::processData]: Msgs Request");
      qDebug("[ChannelWgt::processData]: par.size = %d", ChatCore::getParametr("MaxMsgsHistorySize", Hdr->parametrs).size());

      sendMsgsHistory(m_name, QHostAddress(Hdr->src_ip), m_chatMsgs->toByteArray(ChatCore::getParametr("MaxMsgsHistorySize", Hdr->parametrs).toLongLong()), m_type);
      break;

    case Globals::MSGS_HISTORY_ANSWER :
    {
      qDebug("[ChannelWgt::processData]: Msgs Answer");

      int diff_time = time(NULL) - Hdr->tm;
      m_chatMsgs->fromByteArray(ChatCore::getParametr("MsgsHistory", Hdr->parametrs));

      for(uint i = 0; i < m_chatMsgs->size(); i++)
        m_chatMsgs->msg(i)->setReceiveTime(m_chatMsgs->msg(i)->receiveTime() + diff_time);

      rebuildChatText();
      break;
    }
    case Globals::MSGS_NUM_REQUEST :
      qDebug("[ChannelWgt::processData]: Msgs Num Request");
      emit sendMsgsNum(m_name, QHostAddress(Hdr->src_ip), m_chatMsgs->size(), m_type);
      break;

    case Globals::MSGS_NUM_ANSWER :
      qDebug("[ChannelWgt::processData]: Msgs Num Answer");
      msgsNumAnswer(Hdr);
      break;

    case Globals::AVATAR_REQUEST :
    {
      qDebug("[ChannelWgt::processData]: Avatar Request");
      QByteArray ba = ChatCore::getParametr("IconHash", Hdr->parametrs);

      if(ba.isEmpty() || Globals::info()->avatarHash() != ba)
        emit avatarAnswer(m_name, QHostAddress(Hdr->src_ip), m_type);
      break;
    }

    case Globals::AVATAR_ANSWER :
      qDebug("[ChannelWgt::processData]: Avatar Answer");
      addAvatar(Hdr);
      break;
  }
}
//\*****************************************************************************
void ChannelWgt::slot_msgOut()
{
  if(!mw_inputText->toPlainText().isEmpty())
  {
    if(m_type == 1)
    {
      emit sendMessage(m_name, m_destIp, m_type, mw_inputText->document()->clone());
      emit sendMessage(m_name, QHostAddress("127.0.0.1"), m_type, mw_inputText->document()->clone());
    }
    else
      emit sendMessage(m_name, Globals::prefs()->broadcast(), m_type, mw_inputText->document()->clone());

    mw_inputText->clear();
  }
}
//\*****************************************************************************
void ChannelWgt::addInfoMsg(QC_DatagramHeader* Hdr)
{
  Message* msg = new Message(Hdr);

  m_chatMsgs->addMsg(msg);
  mw_chatText->addMsg(msg);
}
//\*****************************************************************************
void ChannelWgt::addMsg(QC_DatagramHeader* Hdr)
{
  if(Globals::prefs()->isExecuteCommandOnIncomingMsg() && !Globals::prefs()->executeCommandOnIncomingMsg().isEmpty())
  {
    QProcess pr;
    pr.startDetached(Globals::prefs()->executeCommandOnIncomingMsg());
  }

  Message* msg = new Message(Hdr);
  m_chatMsgs->addMsg(msg);

  mw_chatText->addMsg(msg);
  mw_clearChatText->addMsg(msg);
}
//\*****************************************************************************
void ChannelWgt::addMsg2Chat(Message* msg)
{
  if(msg)
  {
    printf("[ChannelWgt::addMsg2Chat]: adding: %s\n", msg->msg().toLocal8Bit().data());
    mw_chatText->addMsg(msg);
    if(!isSystemMsg(msg->type()))
      mw_clearChatText->addMsg(msg);
  }
}
//\*****************************************************************************
void ChannelWgt::addUser(QC_DatagramHeader* Hdr)
{
  UserWgt*   usr;
  UserInfo*  info;
  UserStatistics* stats;
  QPixmap*   icon, *tmp;
  QByteArray buf;
  QCryptographicHash md5_hash(QCryptographicHash::Md5);
  bool need_avatar = true;

  qDebug("[ChannelWgt::addUser]: ip = %s", QHostAddress(Hdr->src_ip).toString().toAscii().data());

  if(!(usr = m_users->enableIfExists(Hdr->src_ip)))
  {
    info = new UserInfo();
    if(!info) return;

    stats = new UserStatistics;
    if(!stats) return;

    usr  = new UserWgt();
    if(!usr) return;

    usr->setInfo(info);
    usr->setStats(stats);
    usr->info()->setIP(Hdr->src_ip);

    m_users->addUser(usr);
  }
  else
    info = usr->info();

  usr->info()->setGender(QString().fromUtf8(ChatCore::getParametr("Gender", Hdr->parametrs)).toInt());

  buf = ChatCore::getParametr("OS", Hdr->parametrs);
  if(!buf.isNull())
    usr->stats()->setOs(QString().fromUtf8(buf));

  buf = ChatCore::getParametr("Uptime", Hdr->parametrs);
  if(!buf.isNull())
    usr->stats()->setUptime((QString().fromUtf8(buf)).toLong());

  buf = ChatCore::getParametr("ChatTime", Hdr->parametrs);
  if(!buf.isNull())
    usr->stats()->setChatTime((QString().fromUtf8(buf)).toLong());

  buf = ChatCore::getParametr("FirstName", Hdr->parametrs);
  if(!buf.isNull())
    usr->info()->setFirstName((QString().fromUtf8(buf)));

  buf = ChatCore::getParametr("Icon", Hdr->parametrs);
  if(!buf.isNull())
  {
    md5_hash.addData(buf);
    info->setAvatarHash(md5_hash.result());

    icon = new QPixmap();
    icon->loadFromData(buf);

    need_avatar = false;
  }
  else
    icon = usr->info()->avatar();

  usr->info()->setProgramVerName(Hdr->versionName);
  usr->info()->setIP            (Hdr->src_ip);
  usr->info()->setNickname      (Hdr->name);
  usr->info()->setCompName      (Hdr->comp_name);
  usr->info()->setStatus        (Hdr->status);
  usr->info()->setStatusDescription(QString().fromUtf8(ChatCore::getParametr("StatusDescription", Hdr->parametrs)));

  tmp = drawUsersIcon(icon, info);
  usr->setIcon(QIcon(*tmp));

  delete tmp;
  if(!need_avatar)
    delete icon;

  usr->setData(Qt::StatusTipRole,
               usr->info()->nickname() + tr(" on ") + usr->info()->compName() + "[" +
               QHostAddress(usr->info()->ip()).toString() + "]" + tr(" running QChat ver. ") +
               usr->info()->programVerName()
              );

  usr->setData(Qt::ToolTipRole, usr->info()->statusDescription());

  mw_usersList->addUser(usr);

  m_usersModel->resort();
  updateUsersView();

  if(need_avatar)
  {
    ChatCore::addParametr("IconHash", usr->info()->avatarHash(), m_parametrs);
    emitSomeData(Globals::AVATAR_REQUEST, "", QHostAddress(Hdr->src_ip));
  }
}
//\*****************************************************************************
void ChannelWgt::hideUser(QC_DatagramHeader* Hdr)
{
  UserWgt* user;

  if(m_users->exists(Hdr->src_ip))
  {
    user = m_users->findByIp(Hdr->src_ip);
    if(user)
    {
      mw_usersList->hideUser(user);
      user->info()->setEnabled(false);
    }
  }

  m_usersModel->resort();
  updateUsersView();
}
//\*****************************************************************************
void ChannelWgt::addUserInfo(QC_DatagramHeader* Hdr)
{
  UserWgt*   usr = m_users->findByIp(Hdr->src_ip);
  QByteArray buf;

  if(NULL == usr)
  {
    usr = new UserWgt();
    usr->setInfo(new UserInfo());
    m_users->addUser(usr);
  }

  if(!(buf = ChatCore::getParametr("LastName"   , Hdr->parametrs)).isNull())
    usr->info()->setLastName   (QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("FirstName"  , Hdr->parametrs)).isNull())
    usr->info()->setFirstName  (QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("SecondName" , Hdr->parametrs)).isNull())
    usr->info()->setSecondName (QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("DateOfBorn"    , Hdr->parametrs)).isNull())
    usr->info()->setDateOfBorn(QDate().fromString(QString().fromUtf8(buf)));

  if(!(buf = ChatCore::getParametr("Address"    , Hdr->parametrs)).isNull())
    usr->info()->setAddress(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("HomePhone"  , Hdr->parametrs)).isNull())
    usr->info()->setHomePhone(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("MobilePhone", Hdr->parametrs)).isNull())
    usr->info()->setMobilePhone(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("WorkPhone"  , Hdr->parametrs)).isNull())
    usr->info()->setWorkPhone(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("e-mail"     , Hdr->parametrs)).isNull())
    usr->info()->setE_mail(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("ICQ"        , Hdr->parametrs)).isNull())
    usr->info()->setICQ(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("Homepage"   , Hdr->parametrs)).isNull())
    usr->info()->setHomepage(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("AboutInfo"  , Hdr->parametrs)).isNull())
    usr->info()->setAboutInfo(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("StatusDescription", Hdr->parametrs)).isNull())
    usr->info()->setStatusDescription(QString().fromUtf8(buf));

  if(!(buf = ChatCore::getParametr("Gender", Hdr->parametrs)).isNull())
    usr->info()->setGender(QString().fromUtf8(buf).toInt());

  usr->info()->setStatus     (Hdr->status);

  buf = ChatCore::getParametr("PhotoOk", Hdr->parametrs);
  if(buf.isNull())
  {
    buf = ChatCore::getParametr("Photo", Hdr->parametrs);

    if(!buf.isNull())
      usr->info()->setPhoto(buf);

    buf = ChatCore::getParametr("PhotoHash", Hdr->parametrs);
    usr->info()->setPhotoHash(buf);
  }

  buf = ChatCore::getParametr("PictureOk", Hdr->parametrs);
  if(buf.isNull())
  {
    buf = ChatCore::getParametr("Picture", Hdr->parametrs);

    if(!buf.isNull())
      usr->info()->setPicture(buf);

    buf = ChatCore::getParametr("PictureHash", Hdr->parametrs);
    usr->info()->setPictureHash(buf);
  }

}
//\*****************************************************************************
void ChannelWgt::slot_refreshUL()
{
  qDebug("\n[ChannelWgt::slot_refreshUL]\n");

  mw_usersList->clear();
  m_users->disableAll();
//   slot_statusRequest();
  slot_deepRefreshUL();
}
//\*****************************************************************************
void ChannelWgt::slot_chbxInfChgd()
{
  if(m_sysMessagesChbx->checkState() == Qt::Checked)
  {
    mw_chatTextStack->setCurrentIndex(1);
    m_displayInfoMsgs = false;
  }
  if(m_sysMessagesChbx->checkState() == Qt::Unchecked)
  {
    m_displayInfoMsgs = true;
    mw_chatTextStack->setCurrentIndex(0);
  }
}
//\*****************************************************************************
void ChannelWgt::sendInfoAnswer(QC_DatagramHeader* Hdr)
{
  uchar photo_ok = 0;
  uchar pic_ok   = 0;
  QByteArray ba;

  if(m_myStatus != Globals::INVISIBLE)
  {
    Globals::info()->setStatus(m_myStatus);

    ba = ChatCore::getParametr("PhotoHash"  , Hdr->parametrs);
    if(!ba.isEmpty())
      photo_ok = Globals::info()->photoHash() == ba;

    ba = ChatCore::getParametr("PictureHash", Hdr->parametrs);
    if(!ba.isEmpty())
      pic_ok = Globals::info()->pictureHash() == ba;

    emit infoAnswer(m_name, QHostAddress(Hdr->src_ip), m_type, pic_ok | (2 * photo_ok));
  }
}
//\*****************************************************************************
void ChannelWgt::sendStatusAnswer(const QString & name, const QHostAddress & addr, bool send_icon)
{
  if(m_myStatus != Globals::INVISIBLE)
  {
    Globals::info()->setStatus(m_myStatus);
    Globals::info()->setStatusDescription(m_statusDescription);
    emit statusAnswer(name, addr, m_type, 0, send_icon);
  }
}
//\*****************************************************************************
void ChannelWgt::slot_infoRequest(UserWgt* user)
{
  m_parametrs.clear();

  if(QFile::exists(user->info()->pictureFilename()))
    ChatCore::addParametr("PictureHash", user->info()->pictureHash(), m_parametrs);

  if(QFile::exists(user->info()->photoFilename()))
    ChatCore::addParametr("PhotoHash"  , user->info()->photoHash()  , m_parametrs);

  emit sendSomeData(m_name, QHostAddress(user->info()->ip()), Globals::INFO_REQUEST, "", m_type, &m_parametrs);
}
//\*****************************************************************************
void ChannelWgt::slot_statusChanged()
{
  m_statusDescription = m_statusWgt->description();
  Globals::info()->setStatusDescription(m_statusDescription);

  if(m_oldStatus != m_statusWgt->status())
  {
    m_myStatus          = m_statusWgt->status();
    m_oldStatus         = m_myStatus;
    Globals::info()->setStatus(m_myStatus);

     qDebug("[ChannelWgt::slot_statusChanged]");

    if(m_type == 1)
    {
      emit statusAnswer(m_name, m_destIp, m_type, 1);
      emit statusAnswer(m_name, QHostAddress("127.0.0.1"), m_type, 1);
    }
    else
      emit statusAnswer(m_name, Globals::prefs()->broadcast(), m_type, 1);
  }
  else
  {
    if(m_type == 1)
    {
      emit statusAnswer(m_name, m_destIp, m_type, 0);
      emit statusAnswer(m_name, QHostAddress("127.0.0.1"), m_type, 0);
    }
    else
      emit statusAnswer(m_name, Globals::prefs()->broadcast(), m_type, 0);
 }
}
//\*****************************************************************************
void ChannelWgt::slot_startStatusChangedTimer()
{
  m_statusChangedTimer->setInterval(1 * 1000);
  m_statusChangedTimer->setSingleShot(true);
  m_statusChangedTimer->start();
}

void ChannelWgt::getSmilesFromData(QC_DatagramHeader * Hdr) // TODO rewrite
{
  m_smilesFromSender->clear();

  QFile file;

  QString fname;
  QString str;

  QByteArray barr_hash;
  QByteArray barr1;
  QByteArray barr = ChatCore::getParametr("Smiles", Hdr->parametrs);
  QByteArray sm_ba;

  QCryptographicHash md5_hash(QCryptographicHash::Md5);
  int len;

  qDebug("[ChannelWgt::getSmilesFromData]: Smiles = %s", QString().fromUtf8(barr).toLocal8Bit().data());

  for(int i = 0; i < barr.size(); i++)
  {
    sm_ba.clear();
    for(; barr.at(i) != 0 && i < barr.size(); i++)
      sm_ba.append(barr.at(i));

    str = QString().fromUtf8(sm_ba);

    qDebug("[ChannelWgt::getSmilesFromData]: str = %s", str.toLocal8Bit().data());

    barr1 = ChatCore::getParametr("Smile" + str, Hdr->parametrs);
    md5_hash.addData(barr1);

    barr_hash = md5_hash.result();
    md5_hash.reset();
    fname = QDir::tempPath() + "/smile";

    fname.append('_');

    len = barr_hash.size();

    for(int i = 0; i < len; i++)
      fname.append(QString::number((uchar)barr_hash.at(i), 16));

    file.setFileName(fname);
    if(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered))
      file.write(barr1);
    else
      qWarning("[ChannelWgt::getSmilesFromData]: couldn't open file %s for writing", fname.toLocal8Bit().data());
    file.close();

    m_smilesFromSender->append(Smile(QStringList(str), fname));
  }
}

void ChannelWgt::initChannel()
{
  emit sendSomeData(m_name, Globals::prefs()->broadcast(), Globals::MSGS_NUM_REQUEST, "", m_type, NULL);

  m_msgsReqSent     = QTime::currentTime();
  m_msgsReqReceived = m_msgsReqSent;

  connect(m_initTimer, SIGNAL(timeout()), this, SLOT(slot_finMsgsHistoryReq()));

  m_msgsReqNum = 0;

  m_initTimer->setSingleShot(true);
  m_initTimer->start(Globals::prefs()->historyReqTimeout());

  slot_statusRequest();
  slot_connected();
}

void ChannelWgt::rebuildChatText()
{
  mw_chatText     ->clear();
  mw_clearChatText->clear();

  for(uint i = 0; i < m_chatMsgs->size(); i++)
    addMsg2Chat(m_chatMsgs->msg(i));
}

void ChannelWgt::slot_finMsgsHistoryReq()
{
  qDebug("\n[ChannelWgt::slot_finMsgsHistoryReq]: num = %d\n", m_msgsReqNum);

  ChatCore::addParametr("MaxMsgsHistorySize", QString().setNum(Globals::prefs()->nHistoryMsgs()).toUtf8(), m_parametrs);

  if(m_msgsReqNum > 0)
    emit sendSomeData(m_name, m_msgsReqAddr, Globals::MSGS_HISTORY_REQUEST, "", m_type, &m_parametrs);
}

void ChannelWgt::msgsNumAnswer(QC_DatagramHeader* Hdr)
{
  uint num = QString(ChatCore::getParametr("MsgsNum", Hdr->parametrs)).toULongLong();

  if(num > m_msgsReqNum && (Globals::prefs()->nHistoryMsgs() < 0 || (int)m_msgsReqNum < Globals::prefs()->nHistoryMsgs()))
  {
    m_msgsReqNum      = num;
    m_msgsReqAddr     = QHostAddress(Hdr->src_ip);
    m_msgsReqReceived = QTime::currentTime();
  }
}

void ChannelWgt::retranslate()
{
  m_sendBtn            ->setText(tr("&Send(CTRL+Space or CTRL+Enter)"));
  m_refreshUlBtn       ->setText(tr("&Refresh"));
  m_sysMessagesChbx    ->setText(tr("Hide System Messages"));
}

void ChannelWgt::emitSomeData(uint data_type, const QString & msg, QHostAddress addr) const
{
  if(m_type == 1)
  {
    emit sendSomeData (m_name, m_destIp, data_type, msg, m_type, &m_parametrs);
    emit sendSomeData (m_name, QHostAddress("127.0.0.1"), data_type, msg, m_type, &m_parametrs);
  }
  else if(addr == QHostAddress("0.0.0.0"))
    emit sendSomeData (m_name, Globals::prefs()->broadcast(), data_type, msg, m_type, &m_parametrs);
  else
    emit sendSomeData (m_name, addr, data_type, msg, m_type, &m_parametrs);
}

void ChannelWgt::slot_changeUlRefreshInterval(uint erval)
{
  if(erval == 0)
    m_refreshTimer->stop();
  else
    m_refreshTimer->start(erval * 1000);
}

void ChannelWgt::slot_changeUlDeepRefreshInterval(uint /*erval*/)
{

}

void ChannelWgt::slot_controlSplitter(int idx, int /*pos*/)
{
  if((double)idx / (double)width() <= 0.5)
  {
    mw_usersStack->setCurrentIndex(1);
    m_usersModel->resort();
    updateUsersView();
  }
  else
    mw_usersStack->setCurrentIndex(0);
}

void ChannelWgt::updateUsersView()
{
  m_usersModel->resetModel();
  mw_usersStatistics->reset();
  mw_usersStatistics->setModel(m_usersModel);
}

void ChannelWgt::slot_deepRefreshUL()
{
  if(!m_requestsRest)
  {
    QTimer* t = new QTimer;

    m_requestsRest = 3;

    connect(t, SIGNAL(timeout()), this, SLOT(nextStatusRequest()));

    t->start(1000);

    slot_statusRequest();
  }
  else
    slot_statusRequest();
}

QByteArray ChannelWgt::saveState() const
{
  // Format:
  // 2 bytes - splittersStatesSize
  // 3x:
  // 2 bytes - splitter[i] State Size(SSS)
  // SSS bytes - splitter[i] state , i = (1, 3)
  //
  // from splittersStatesSize to state.size(); - usersstatisticswgt state

  QByteArray state, tmp;
  char sz[2];

  for(int i = 0; i < m_splitters.size(); i++)
  {
    tmp = m_splitters[i]->saveState();
    catUS2str(sz, tmp.size());

    state.append(sz[0]);
    state.append(sz[1]);
    state.append(tmp);
  }

  catUS2str(sz, state.size());
  state.prepend(sz[1]);
  state.prepend(sz[0]);

  state.append(mw_usersStatistics->saveState());

  return state;
}

void ChannelWgt::restoreState(const QByteArray & state)
{
  QByteArray tmp;
  char sz2[2];
  uint sz;
  uint state_sz;

  if(state.size() < 2)
    return;

  sz2[0] = state.at(0);
  sz2[1] = state.at(1);

  state_sz = str2US(sz2) + 2;

  if((uint)state.size() < state_sz)
    return;

  for(uint i = 0, j = 2; i < (uint)m_splitters.size(); i++)
  {
    if(j + 2 > state_sz)
      break;

    sz2[0] = state.at(j++);
    sz2[1] = state.at(j++);
    sz     = str2US(sz2);

    if(j + sz > state_sz)
      break;

    tmp = state.mid(j, sz);
    m_splitters[i]->restoreState(tmp);

    j += sz;
  }

  mw_usersStatistics->restoreState(state.mid(state_sz, state.size() - state_sz));

  if((double)m_splitters[2]->sizes()[1] / (double)width() >= 0.5)
  {
    mw_usersStack->setCurrentIndex(1);
    m_usersModel->resort();
    updateUsersView();
  }
  else
    mw_usersStack->setCurrentIndex(0);

  updateUsersView();
}

void ChannelWgt::nextStatusRequest()
{
  slot_statusRequest();
  m_requestsRest--;

  if(!m_requestsRest)
    if(qobject_cast<QTimer*>(sender()))
      delete sender();
}

void ChannelWgt::addAvatar(QC_DatagramHeader * Hdr)
{
  UserWgt*   usr;
  QByteArray buf;
  QPixmap* icon, *tmp;

  usr = m_users->findByIp(Hdr->src_ip);
  if(!usr)
    m_users->findHidden(Hdr->src_ip);

  if(!usr)
    return;

  buf = ChatCore::getParametr("Icon", Hdr->parametrs);

  if(!buf.isNull())
  {
    icon = new QPixmap();

    if(!buf.isEmpty())
      icon->loadFromData(buf);

    tmp = drawUsersIcon(icon, usr->info());

    usr->setIcon(QIcon(*tmp));

    delete usr->info()->avatar();
    usr->info()->setAvatar(icon);

    delete tmp;
  }

  buf = ChatCore::getParametr("IconHash", Hdr->parametrs);
  usr->info()->setAvatarHash(buf);

  updateUsersView();
}

QPixmap * ChannelWgt::drawUsersIcon(const QPixmap* icon, UserInfo* info)
{
  QPixmap  status_pix;
  QPixmap* gender_pix;
  QPixmap* result_pix;
  QPixmap  tmp_icon;
  QPainter painter;
  bool disabled = true;

  assert(NULL != info);

  switch(info->status())
  {
    case Globals::READY4CHAT :
      status_pix.load(":/images/status/status-ffc.png");
      disabled = false;
      break;

    case Globals::FREE :
      status_pix.load(":/images/status/status-online.png");
      disabled = false;
      break;

    case Globals::BUSY :
      status_pix.load(":/images/status/status-occupied.png");
      break;

    case Globals::DND :
      status_pix.load(":/images/status/status-dnd.png");
      break;

    case Globals::INACTIVE :
      status_pix.load(":/images/status/status-away.png");
      break;

    case Globals::AWAY :
      status_pix.load(":/images/status/status-na.png");
      break;
  }

  if(icon)
  {
    if(disabled)
      tmp_icon = QIcon(*icon).pixmap(32, 32, QIcon::Disabled);
    else
      tmp_icon = *icon;
  }

  switch(info->gender())
  {
    case 'm' : gender_pix = new QPixmap(":/images/user-male.svg"); break;
    case 'f' : gender_pix = new QPixmap(":/images/user-female.svg"); break;
    default  : gender_pix = new QPixmap(":/images/unknown.png");
  }

  *gender_pix = gender_pix->scaled(16, 16, Qt::KeepAspectRatio, Qt::SmoothTransformation);

  int wd = status_pix.width() + gender_pix->width() + 32;
  int he = 32;

  result_pix = new QPixmap(wd, he);

  QPixmap tmp(wd, he);

  tmp.fill(Qt::black);
  result_pix->setAlphaChannel(tmp);

  painter.begin(result_pix);

  painter.drawPixmap(0, 7, *gender_pix);
  painter.drawPixmap(32, (32 - tmp_icon.height()) / 2, tmp_icon);
  painter.drawPixmap(16, 7, status_pix);

  painter.end();

  return result_pix;
}

Generated by  Doxygen 1.6.0   Back to index