1 //=============================================================================
2 //
3 // File : DccCanvasWindow.cpp
4 // Creation date : Sun Jul 29 07 2001 20:23:13 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #define QT_MODULE_CANVAS
26
27 #include "DccCanvasWindow.h"
28
29 #ifdef COMPILE_DCC_CANVAS
30
31 #include "DccDialog.h"
32 #include "DccMarshal.h"
33 #include "canvaswidget.h"
34
35 #define _KVI_DEBUG_CHECK_RANGE_
36 #include "kvi_debug.h"
37 #include "KviOptions.h"
38 #include "KviInput.h"
39 #include "KviIrcView.h"
40 #include "KviIconManager.h"
41 #include "KviLocale.h"
42 #include "KviError.h"
43 #include "kvi_out.h"
44 #include "KviNetUtils.h"
45 #include "KviConsoleWindow.h"
46 #include "KviMainWindow.h"
47 #include "KviMemory.h"
48 #include "KviThread.h"
49 #include "KviIrcSocket.h"
50 #include "kvi_settings.h"
51 #include "KviIrcConnection.h"
52
53 #include <QSplitter>
54
55 extern DccBroker * g_pDccBroker;
56
DccCanvasWindow(DccDescriptor * dcc,const char * name)57 DccCanvasWindow::DccCanvasWindow(DccDescriptor * dcc, const char * name)
58 : DccWindow(KVI_WINDOW_TYPE_DCCCANVAS, name, dcc)
59 {
60 m_pSplitter = new QSplitter(QSplitter::Vertical, this, "splitter");
61
62 m_pCanvas = new DccCanvasWidget(m_pSplitter);
63
64 m_pIrcView = new KviIrcView(m_pSplitter, this);
65 m_pInput = new KviInput(this);
66
67 // setFocusHandler(m_pInput,this);
68
69 m_pMarshal = new DccMarshal(this);
70 connect(m_pMarshal, SIGNAL(error(int)), this, SLOT(handleMarshalError(int)));
71 connect(m_pMarshal, SIGNAL(connected()), this, SLOT(connected()));
72
73 if(!(m_pDescriptor->bActive))
74 {
75 // PASSIVE CONNECTION
76 output(KVI_OUT_DCCMSG, __tr2qs_ctx("Attempting a passive DCC CANVAS connection", "dcc"));
77 int ret = m_pMarshal->dccListen(dcc->szListenIp, dcc->szListenPort, m_pDescriptor->bDoTimeout);
78 if(ret != KviError_success)
79 handleMarshalError(ret);
80 else
81 {
82
83 output(KVI_OUT_DCCMSG, __tr2qs_ctx("Listening on interface %Q port %Q", "dcc"),
84 &(m_pMarshal->localIp()), &(m_pMarshal->localPort()));
85
86 if(dcc->bSendRequest)
87 {
88 QString ip = !dcc->szFakeIp.isEmpty() ? dcc->szFakeIp : dcc->szListenIp;
89 QString port = !dcc->szFakePort.isEmpty() ? dcc->szFakePort.toUtf8().data() : m_pMarshal->localPort();
90 //#warning "OPTION FOR SENDING 127.0.0.1 and so on (not an unsigned number)"
91 struct in_addr a;
92 if(kvi_stringIpToBinaryIp(ip.toUtf8().data(), &a))
93 ip.setNum(htonl(a.s_addr));
94 dcc->console()->connection()->sendFmtData("PRIVMSG %s :%cDCC CANVAS chat %Q %Q%c",
95 dcc->console()->connection()->encodeText(dcc->szNick.toUtf8().data()).data(),
96 0x01, &ip,
97 &port,
98 0x01);
99 output(KVI_OUT_DCCMSG, __tr2qs_ctx("Sent DCC CANVAS request to %Q, waiting for the remote client to connect...", "dcc"),
100 &(dcc->szNick));
101 }
102 else
103 outputNoFmt(KVI_OUT_DCCMSG, __tr2qs_ctx("DCC CANVAS request not sent: awaiting manual connections", "dcc"));
104 }
105 }
106 else
107 {
108 // ACTIVE CONNECTION
109 outputNoFmt(KVI_OUT_DCCMSG, __tr2qs_ctx("Attempting an active DCC CANVAS connection", "dcc"));
110 int ret = m_pMarshal->dccConnect(dcc->szIp.toUtf8().data(), dcc->szPort.toUtf8().data(), m_pDescriptor->bDoTimeout);
111 if(ret != KviError_success)
112 handleMarshalError(ret);
113 else
114 output(KVI_OUT_DCCMSG, __tr2qs_ctx("Contacting host %Q on port %Q", "dcc"), &(dcc->szIp), &(dcc->szPort));
115 }
116
117 // m_pSlaveThread = nullptr;
118 }
119
~DccCanvasWindow()120 DccCanvasWindow::~DccCanvasWindow()
121 {
122 g_pDccBroker->unregisterDccWindow(this);
123 // if(m_pSlaveThread)
124 // {
125 // m_pSlaveThread->terminate();
126 // delete m_pSlaveThread;
127 // m_pSlaveThread = nullptr;
128 // }
129 KviThreadManager::killPendingEvents(this);
130 // delete m_pDescriptor;
131 // delete m_pMarshal;
132 }
133
target()134 const QString & DccCanvasWindow::target()
135 {
136 // This may change on the fly...
137 m_szTarget.sprintf("%s@%s:%s",
138 m_pDescriptor->szNick.toUtf8().data(), m_pDescriptor->szIp.toUtf8().data(), m_pDescriptor->szPort.toUtf8().data());
139 return m_szTarget;
140 }
141
fillCaptionBuffers()142 void DccCanvasWindow::fillCaptionBuffers()
143 {
144 KviCString tmp(KviCString::Format, "DCC Canvas %s@%s:%s",
145 m_pDescriptor->szNick.toUtf8().data(), m_pDescriptor->szIp.toUtf8().data(), m_pDescriptor->szPort.toUtf8().data());
146
147 m_szPlainTextCaption = tmp;
148
149 m_szHtmlActiveCaption.sprintf("<font color=\"%s\"><b>%s</b></font>",
150 KVI_OPTION_COLOR(KviOption_colorCaptionTextActive).name().ascii(), tmp.ptr());
151 m_szHtmlInactiveCaption.sprintf("<font color=\"%s\"><b>%s</b></font>",
152 KVI_OPTION_COLOR(KviOption_colorCaptionTextInactive).name().ascii(), tmp.ptr());
153 }
154
myIconPtr()155 QPixmap * DccCanvasWindow::myIconPtr()
156 {
157 return g_pIconManager->getSmallIcon(KviIconManager::Canvas);
158 }
159
getBaseLogFileName(KviCString & buffer)160 void DccCanvasWindow::getBaseLogFileName(KviCString & buffer)
161 {
162 buffer.sprintf("%s_%s_%s", m_pDescriptor->szNick.toUtf8().data(), m_pDescriptor->szIp.toUtf8().data(), m_pDescriptor->szPort.toUtf8().data());
163 }
164
ownMessage(const QString & text,bool bUserFeedback)165 void DccCanvasWindow::ownMessage(const QString & text, bool bUserFeedback)
166 {
167 KviCString buf(KviCString::Format, "%s\r\n", text);
168 // m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
169
170 if(bUserFeedback)
171 m_pFrm->firstConsole()->outputPrivmsg(this, KVI_OUT_OWNPRIVMSG,
172 m_pDescriptor->szLocalNick.toUtf8().data(), m_pDescriptor->szLocalUser.toUtf8().data(),
173 m_pDescriptor->szLocalHost.toUtf8().data(), text);
174 }
175
ownAction(const QString & text)176 void DccCanvasWindow::ownAction(const QString & text)
177 {
178 KviCString buf(KviCString::Format, "%cACTION %s%c\r\n", text);
179 // m_pSlaveThread->sendRawData(buf.ptr(),buf.len());
180 output(KVI_OUT_OWNACTION, "%Q %s", &(m_pDescriptor->szLocalNick), text);
181 }
182
event(QEvent * e)183 bool DccCanvasWindow::event(QEvent * e)
184 {
185 // if(e->type() == KVI_THREAD_EVENT)
186 // {
187 // switch(((KviThreadEvent *)e)->id())
188 // {
189 // case KVI_DCC_THREAD_EVENT_ERROR:
190 // {
191 // int * err = ((KviThreadDataEvent<int> *)e)->getData();
192 // output(KVI_OUT_DCCERROR,__tr("ERROR: %s"),kvi_getErrorString(*err));
193 // delete err;
194 // return true;
195 // }
196 // break;
197 // case KVI_DCC_THREAD_EVENT_DATA:
198 // {
199 // KviCString * d = ((KviThreadDataEvent<KviCString> *)e)->getData();
200 // if(d->firstCharIs(0x01))
201 // {
202 // d->cutLeft(1);
203 // if(d->lastCharIs(0x01))d->cutRight(1);
204 // if(kvi_strEqualCIN("ACTION",d->ptr(),6))d->cutLeft(6);
205 // d->stripLeftWhiteSpace();
206 // output(KVI_OUT_ACTION,"%s %s",m_pDescriptor->szNick.ptr(),d->ptr());
207 // } else {
208 //
209 //#ifdef COMPILE_CRYPT_SUPPORT
210 // if(KviCryptSessionInfo * cinf = cryptSessionInfo())
211 // {
212 // if(cinf->bDoDecrypt)
213 // {
214 // if(cinf->pEngine->isCryptographicEngine() && (*(d->ptr()) == KVI_TEXT_CRYPT))
215 // {
216 // KviCString decryptedStuff;
217 // if(cinf->pEngine->decrypt(d->ptr() + 1,decryptedStuff))
218 // {
219 // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSGCRYPTED,
220 // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
221 // m_pDescriptor->szHost.ptr(),decryptedStuff.ptr());
222 // } else {
223 // output(KVI_OUT_SYSTEMERROR,
224 // __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"),
225 // cinf->pEngine->lastError());
226 // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG,
227 // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
228 // m_pDescriptor->szHost.ptr(),d->ptr() + 1);
229 // }
230 // delete d;
231 // return true;
232 // } else {
233 // if(!(cinf->pEngine->isCryptographicEngine()))
234 // {
235 // KviCString decryptedStuff;
236 // if(cinf->pEngine->decrypt(d->ptr(),decryptedStuff))
237 // {
238 // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG,
239 // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
240 // m_pDescriptor->szHost.ptr(),decryptedStuff.ptr());
241 // delete d;
242 // return true;
243 // } else {
244 // output(KVI_OUT_SYSTEMERROR,
245 // __tr("The following message looks like an encrypted one, but the crypting engine failed to decode it: %s"),
246 // cinf->pEngine->lastError());
247 // }
248 // }
249 // }
250 // }
251 // }
252 //#endif
253 // m_pFrm->firstConsole()->outputPrivmsg(this,KVI_OUT_DCCCHATMSG,
254 // m_pDescriptor->szNick.ptr(),m_pDescriptor->szUser.ptr(),
255 // m_pDescriptor->szHost.ptr(),d->ptr());
256 // }
257 // delete d;
258 // return true;
259 // }
260 // break;
261 // }
262 // }
263 return KviWindow::event(e);
264 }
265
resizeEvent(QResizeEvent * e)266 void DccCanvasWindow::resizeEvent(QResizeEvent * e)
267 {
268 int hght = m_pInput->heightHint();
269 // int hght2 = m_pTopSplitter->sizeHint().height();
270 // m_pTopSplitter->setGeometry(0,0,width(),hght2);
271 m_pSplitter->setGeometry(0, 0, width(), height() - hght);
272 m_pInput->setGeometry(0, height() - hght, width(), hght);
273 }
274
sizeHint() const275 QSize DccCanvasWindow::sizeHint() const
276 {
277 QSize ret(m_pIrcView->sizeHint().width(),
278 m_pIrcView->sizeHint().height() + m_pInput->heightHint());
279 return ret;
280 }
281
handleMarshalError(int err)282 void DccCanvasWindow::handleMarshalError(int err)
283 {
284 QString sss = KviError::getDescription(err);
285 output(KVI_OUT_DCCERROR, __tr2qs_ctx("DCC failed: %Q", "dcc"), &sss);
286 }
287
connected()288 void DccCanvasWindow::connected()
289 {
290 output(KVI_OUT_DCCMSG, __tr2qs_ctx("Connected to %Q:%Q", "dcc"),
291 &(m_pMarshal->remoteIp()), &(m_pMarshal->remotePort()));
292 output(KVI_OUT_DCCMSG, __tr2qs_ctx("Local end is %Q:%Q", "dcc"),
293 &(m_pMarshal->localIp()), &(m_pMarshal->localPort()));
294 if(!(m_pDescriptor->bActive))
295 {
296 // PASSIVE CONNECTION...Find out the remote end
297 m_pDescriptor->szIp = m_pMarshal->remoteIp();
298 m_pDescriptor->szPort = m_pMarshal->remotePort();
299 m_pDescriptor->szHost = m_pMarshal->remoteIp();
300 }
301 updateCaption();
302 // m_pSlaveThread = new KviDccCanvasThread(this,m_pMarshal->releaseSocket());
303 // m_pSlaveThread->start();
304 }
305
306 #endif
307