//=============================================================================
//
// File : DccCanvasWindow.cpp
// Creation date : Sun Jul 29 07 2001 20:23:13 by Szymon Stefanek
//
// This file is part of the KVIrc IRC client distribution
// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net)
//
// This program is FREE software. You can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// 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.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#define QT_MODULE_CANVAS
#include "DccCanvasWindow.h"
#ifdef COMPILE_DCC_CANVAS
#include "DccDialog.h"
#include "DccMarshal.h"
#include "canvaswidget.h"
#define _KVI_DEBUG_CHECK_RANGE_
#include "kvi_debug.h"
#include "KviOptions.h"
#include "KviInput.h"
#include "KviIrcView.h"
#include "KviIconManager.h"
#include "KviLocale.h"
#include "KviError.h"
#include "kvi_out.h"
#include "KviNetUtils.h"
#include "KviConsoleWindow.h"
#include "KviMainWindow.h"
#include "KviMemory.h"
#include "KviThread.h"
#include "KviIrcSocket.h"
#include "kvi_settings.h"
#include "KviIrcConnection.h"
#include <QSplitter>
extern DccBroker * g_pDccBroker;
DccCanvasWindow::DccCanvasWindow(DccDescriptor * dcc, const char * name)
: DccWindow(KVI_WINDOW_TYPE_DCCCANVAS, name, dcc)
{
m_pSplitter = new QSplitter(QSplitter::Vertical, this, "splitter");
m_pCanvas = new DccCanvasWidget(m_pSplitter);
m_pIrcView = new KviIrcView(m_pSplitter, this);
m_pInput = new KviInput(this);
// setFocusHandler(m_pInput,this);
m_pMarshal = new DccMarshal(this);
connect(m_pMarshal, SIGNAL(error(int)), this, SLOT(handleMarshalError(int)));
connect(m_pMarshal, SIGNAL(connected()), this, SLOT(connected()));
if(!(m_pDescriptor->bActive))
{
// PASSIVE CONNECTION
output(KVI_OUT_DCCMSG, __tr2qs_ctx("Attempting a passive DCC CANVAS connection", "dcc"));
int ret = m_pMarshal->dccListen(dcc->szListenIp, dcc->szListenPort, m_pDescriptor->bDoTimeout);
if(ret != KviError_success)
handleMarshalError(ret);
else
{
output(KVI_OUT_DCCMSG, __tr2qs_ctx("Listening on interface %Q port %Q", "dcc"),
&(m_pMarshal->localIp()), &(m_pMarshal->localPort()));
if(dcc->bSendRequest)
{
QString ip = !dcc->szFakeIp.isEmpty() ? dcc->szFakeIp : dcc->szListenIp;
QString port = !dcc->szFakePort.isEmpty() ? dcc->szFakePort.toUtf8().data() : m_pMarshal->localPort();
//#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned number)"
struct in_addr a;
if(kvi_stringIpToBinaryIp(ip.toUtf8().data(), &a))
ip.setNum(htonl(a.s_addr));
dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC CANVAS chat %Q %Q%c",
dcc->console()->connection()->encodeText(dcc->szNick.toUtf8().data()).data(),
0x01, &ip,
&port,
0x01);
output(KVI_OUT_DCCMSG, __tr2qs_ctx("Sent DCC CANVAS request to %Q, waiting for the remote client to connect...", "dcc"),
&(dcc->szNick));
}
else
outputNoFmt(KVI_OUT_DCCMSG, __tr2qs_ctx("DCC CANVAS request not sent: awaiting manual connections", "dcc"));
}
}
else
{
// ACTIVE CONNECTION
outputNoFmt(KVI_OUT_DCCMSG, __tr2qs_ctx("Attempting an active DCC CANVAS connection", "dcc"));
int ret = m_pMarshal->dccConnect(dcc->szIp.toUtf8().data(), dcc->szPort.toUtf8().data(), m_pDescriptor->bDoTimeout);
if(ret != KviError_success)
handleMarshalError(ret);
else
output(KVI_OUT_DCCMSG, __tr2qs_ctx("Contacting host %Q on port %Q", "dcc"), &(dcc->szIp), &(dcc->szPort));
}
// m_pSlaveThread = nullptr;
}
DccCanvasWindow::~DccCanvasWindow()
{
g_pDccBroker->unregisterDccWindow(this);
// if(m_pSlaveThread)
// {
// m_pSlaveThread->terminate();
// delete m_pSlaveThread;
// m_pSlaveThread = nullptr;
// }
KviThreadManager::killPendingEvents(this);
// delete m_pDescriptor;
// delete m_pMarshal;
}
const QString & DccCanvasWindow::target()
{
// This may change on the fly...
m_szTarget = QString::asprintf("%s@%s:%s",
m_pDescriptor->szNick.toUtf8().data(), m_pDescriptor->szIp.toUtf8().data(), m_pDescriptor->szPort.toUtf8().data());
return m_szTarget;
}
void DccCanvasWindow::fillCaptionBuffers()
{
KviCString tmp(KviCString::Format, "DCC Canvas %s@%s:%s",
m_pDescriptor->szNick.toUtf8().data(), m_pDescriptor->szIp.toUtf8().data(), m_pDescriptor->szPort.toUtf8().data());
m_szPlainTextCaption = tmp;
m_szHtmlActiveCaption.sprintf("<font color=\"%s\"><b>%s</b></font>",
KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(), tmp.ptr());
m_szHtmlInactiveCaption.sprintf("<font color=\"%s\"><b>%s</b></font>",
KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(), tmp.ptr());
}
QPixmap * DccCanvasWindow::myIconPtr()
{
return g_pIconManager->getSmallIcon(KviIconManager::Canvas);
}
void DccCanvasWindow::getBaseLogFileName(KviCString & buffer)
{
buffer.sprintf("%s_%s_%s", m_pDescriptor->szNick.toUtf8().data(), m_pDescriptor->szIp.toUtf8().data(), m_pDescriptor->szPort.toUtf8().data());
}
void DccCanvasWindow::ownMessage(const QString & text, bool bUserFeedback)
{
KviCString buf(KviCString::Format, "%s\r\n", text);
// m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
if(bUserFeedback)
m_pFrm->firstConsole()->outputPrivmsg(this, KVI_OUT_OWNPRIVMSG,
m_pDescriptor->szLocalNick.toUtf8().data(), m_pDescriptor->szLocalUser.toUtf8().data(),
m_pDescriptor->szLocalHost.toUtf8().data(), text);
}
void DccCanvasWindow::ownAction(const QString & text)
{
KviCString buf(KviCString::Format, "%cACTION %s%c\r\n", text);
// m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
output(KVI_OUT_OWNACTION, "%Q %s", &(m_pDescriptor->szLocalNick), text);
}
bool DccCanvasWindow::event(QEvent * e)
{
// if(e->type() == KVI_THREAD_EVENT)
// {
// switch(((KviThreadEvent *)e)->id())
// {
// case KVI_DCC_THREAD_EVENT_ERROR:
// {
// int * err = ((KviThreadDataEvent<int> *)e)->getData();
// output(KVI_OUT_DCCERROR,__tr("ERROR: %s"),kvi_getErrorString(*err));
// delete err;
// return true;
// }
// break;
// case KVI_DCC_THREAD_EVENT_DATA:
// {
// KviCString * d = ((KviThreadDataEvent<KviCString> *)e)->getData();
// if(d->firstCharIs(0x01))
// {
// d->cutLeft(1);
// if(d->lastCharIs(0x01))d->cutRight(1);
// if(kvi_strEqualCIN("ACTION",d->ptr(),6))d->cutLeft(6);
// d->stripLeftWhiteSpace();
// output(KVI_OUT_ACTION,"%s %s",m_pDescriptor->szNick.ptr(),d->ptr());
// } else {
//
//#ifdef COMPILE_CRYPT_SUPPORT
// if(KviCryptSessionInfo * cinf = cryptSessionInfo())
// {
// if(cinf->bDoDecrypt)
// {
// if(cinf->pEngine->isCryptographicEngine() && (*(d->ptr()) == KVI_TEXT_CRYPT))
// {
// KviCString decryptedStuff;
// if(cinf->pEngine->decrypt(d->ptr() + 1,decryptedStuff))
// {
// m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSGCRYPTED,
// m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
// m_pDescriptor->szHost.ptr(),decryptedStuff.ptr());
// } else {
// output(KVI_OUT_SYSTEMERROR,
// __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"),
// cinf->pEngine->lastError());
// m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG,
// m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
// m_pDescriptor->szHost.ptr(),d->ptr() + 1);
// }
// delete d;
// return true;
// } else {
// if(!(cinf->pEngine->isCryptographicEngine()))
// {
// KviCString decryptedStuff;
// if(cinf->pEngine->decrypt(d->ptr(),decryptedStuff))
// {
// m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG,
// m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
// m_pDescriptor->szHost.ptr(),decryptedStuff.ptr());
// delete d;
// return true;
// } else {
// output(KVI_OUT_SYSTEMERROR,
// __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"),
// cinf->pEngine->lastError());
// }
// }
// }
// }
// }
//#endif
// m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG,
// m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
// m_pDescriptor->szHost.ptr(),d->ptr());
// }
// delete d;
// return true;
// }
// break;
// }
// }
return KviWindow::event(e);
}
void DccCanvasWindow::resizeEvent(QResizeEvent * e)
{
int hght = m_pInput->heightHint();
// int hght2 = m_pTopSplitter->sizeHint().height();
// m_pTopSplitter->setGeometry(0,0,width(),hght2);
m_pSplitter->setGeometry(0, 0, width(), height() - hght);
m_pInput->setGeometry(0, height() - hght, width(), hght);
}
QSize DccCanvasWindow::sizeHint() const
{
QSize ret(m_pIrcView->sizeHint().width(),
m_pIrcView->sizeHint().height() + m_pInput->heightHint());
return ret;
}
void DccCanvasWindow::handleMarshalError(int err)
{
QString sss = KviError::getDescription(err);
output(KVI_OUT_DCCERROR, __tr2qs_ctx("DCC failed: %Q", "dcc"), &sss);
}
void DccCanvasWindow::connected()
{
output(KVI_OUT_DCCMSG, __tr2qs_ctx("Connected to %Q:%Q", "dcc"),
&(m_pMarshal->remoteIp()), &(m_pMarshal->remotePort()));
output(KVI_OUT_DCCMSG, __tr2qs_ctx("Local end is %Q:%Q", "dcc"),
&(m_pMarshal->localIp()), &(m_pMarshal->localPort()));
if(!(m_pDescriptor->bActive))
{
// PASSIVE CONNECTION...Find out the remote end
m_pDescriptor->szIp = m_pMarshal->remoteIp();
m_pDescriptor->szPort = m_pMarshal->remotePort();
m_pDescriptor->szHost = m_pMarshal->remoteIp();
}
updateCaption();
// m_pSlaveThread = new KviDccCanvasThread(this,m_pMarshal->releaseSocket());
// m_pSlaveThread->start();
}
#endif