1 /*
2 * irctabitem.cpp
3 *
4 * Copyright 2008 David Vachulka <arch_dvx@users.sourceforge.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #ifdef WIN32
23 #define WIN32_LEAN_AND_MEAN
24 #include <windows.h>
25 #include <shellapi.h>
26 #endif
27 #include <string>
28 #include "irctabitem.h"
29 #include "tetristabitem.h"
30 #include "icons.h"
31 #include "config.h"
32 #include "i18n.h"
33 #include "dxirc.h"
34
35 #define ICON_SPACING 4 // Spacing between icon and label
36 #define SIDE_SPACING 6 // Left or right spacing between items
37 #define LINE_SPACING 4 // Line spacing between items
38
39 #define preferences dxirc::instance()->getPreferences()
40
41 //Get away color
makeAwayColor(FXColor clr)42 FXColor makeAwayColor(FXColor clr)
43 {
44 FXuint r,g,b;
45 r=FXREDVAL(clr);
46 g=FXGREENVAL(clr);
47 b=FXBLUEVAL(clr);
48 if(r==g && r==b && !r)
49 {
50 r=255;
51 g=255;
52 b=255;
53 }
54 r=(50*r)/100;
55 g=(50*g)/100;
56 b=(50*b)/100;
57 return FXRGB(r,g,b);
58 }
59
60 //Sort by UserMode and nick
sortNick(const FXListItem * a,const FXListItem * b)61 FXint sortNick(const FXListItem *a, const FXListItem *b)
62 {
63 return comparecase((FXchar)((NickListItem*)a)->getUserMode()+a->getText(), (FXchar)((NickListItem*)b)->getUserMode()+b->getText());
64 }
65
66 FXDEFMAP(DccSendDialog) DccSendDialogMap[] = {
67 FXMAPFUNC(SEL_COMMAND, DccSendDialog_FILE, DccSendDialog::onFile),
68 FXMAPFUNC(SEL_COMMAND, DccSendDialog_SEND, DccSendDialog::onSend),
69 FXMAPFUNC(SEL_COMMAND, DccSendDialog_CANCEL, DccSendDialog::onCancel),
70 FXMAPFUNC(SEL_CLOSE, 0, DccSendDialog::onCancel),
71 FXMAPFUNC(SEL_KEYPRESS, 0, DccSendDialog::onKeyPress)
72 };
73
FXIMPLEMENT(DccSendDialog,FXDialogBox,DccSendDialogMap,ARRAYNUMBER (DccSendDialogMap))74 FXIMPLEMENT(DccSendDialog, FXDialogBox, DccSendDialogMap, ARRAYNUMBER(DccSendDialogMap))
75
76 DccSendDialog::DccSendDialog(FXMainWindow* owner, FXString nick)
77 : FXDialogBox(owner, FXStringFormat(_("Send file to %s"), nick.text()), DECOR_RESIZE|DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0)
78 {
79 m_mainFrame = new FXVerticalFrame(this, LAYOUT_FILL_X|LAYOUT_FILL_Y);
80
81 m_fileFrame = new FXHorizontalFrame(m_mainFrame, LAYOUT_FILL_X);
82 new FXLabel(m_fileFrame, _("File:"));
83 m_fileText = new FXTextField(m_fileFrame, 25, NULL, 0, TEXTFIELD_READONLY|FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_X);
84 m_buttonFile = new dxEXButton(m_fileFrame, "...", NULL, this, DccSendDialog_FILE, FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_X, 0,0,0,0, 10,10,2,2);
85
86 m_passiveFrame = new FXHorizontalFrame(m_mainFrame, LAYOUT_FILL_X);
87 m_checkPassive = new FXCheckButton(m_passiveFrame, _("Send passive"), NULL, 0);
88
89 m_buttonFrame = new FXHorizontalFrame(m_mainFrame, LAYOUT_FILL_X|PACK_UNIFORM_WIDTH);
90 m_buttonCancel = new dxEXButton(m_buttonFrame, _("&Cancel"), NULL, this, DccSendDialog_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
91 m_buttonSend = new dxEXButton(m_buttonFrame, _("&Send file"), NULL, this, DccSendDialog_SEND, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
92 }
93
~DccSendDialog()94 DccSendDialog::~DccSendDialog()
95 {
96 }
97
execute(FXuint placement)98 FXuint DccSendDialog::execute(FXuint placement)
99 {
100 create();
101 show(placement);
102 getApp()->refresh();
103 dxEXFileDialog dialog(this, _("Select file"));
104 if(dialog.execute())
105 {
106 m_fileText->setText(dialog.getFilename());
107 }
108 return getApp()->runModalFor(this);
109 }
110
onFile(FXObject *,FXSelector,void *)111 long DccSendDialog::onFile(FXObject*, FXSelector, void*)
112 {
113 dxEXFileDialog dialog(this, _("Select file"));
114 if(dialog.execute())
115 {
116 m_fileText->setText(dialog.getFilename());
117 }
118 return 1;
119 }
120
onSend(FXObject *,FXSelector,void *)121 long DccSendDialog::onSend(FXObject*, FXSelector, void*)
122 {
123 getApp()->stopModal(this,TRUE);
124 hide();
125 return 1;
126 }
127
onCancel(FXObject *,FXSelector,void *)128 long DccSendDialog::onCancel(FXObject*, FXSelector, void*)
129 {
130 getApp()->stopModal(this,FALSE);
131 hide();
132 return 1;
133 }
134
onKeyPress(FXObject * sender,FXSelector sel,void * ptr)135 long DccSendDialog::onKeyPress(FXObject *sender, FXSelector sel, void *ptr)
136 {
137 if(FXTopWindow::onKeyPress(sender,sel,ptr)) return 1;
138 if(((FXEvent*)ptr)->code == KEY_Escape)
139 {
140 handle(this,FXSEL(SEL_COMMAND,DccSendDialog_CANCEL),NULL);
141 return 1;
142 }
143 return 0;
144 }
145
146 FXDEFMAP(NickList) NickListMap [] = {
147 FXMAPFUNC(SEL_QUERY_TIP, 0, NickList::onQueryTip)
148 };
149
FXIMPLEMENT(NickList,FXList,NickListMap,ARRAYNUMBER (NickListMap))150 FXIMPLEMENT(NickList, FXList, NickListMap, ARRAYNUMBER(NickListMap))
151
152 NickList::NickList(FXComposite* p, IrcTabItem* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h)
153 : FXList(p, tgt, sel, opts, x, y, w, h), m_parent(tgt)
154 {
155 }
156
onQueryTip(FXObject * sender,FXSelector sel,void * ptr)157 long NickList::onQueryTip(FXObject *sender, FXSelector sel, void *ptr)
158 {
159 if(FXWindow::onQueryTip(sender, sel, ptr)) return 1;
160 if((flags&FLAG_TIP) && !(options&LIST_AUTOSELECT) && (0<=cursor)) // No tip when autoselect!
161 {
162 FXString string = items[cursor]->getText();
163 string.append('\n');
164 NickInfo nick = m_parent->m_engine->getNickInfo(items[cursor]->getText());
165 string.append(FXStringFormat(_("User: %s@%s\n"), nick.user.text(), nick.host.text()));
166 string.append(FXStringFormat(_("Realname: %s"), nick.real.text()));
167 sender->handle(this, FXSEL(SEL_COMMAND,ID_SETSTRINGVALUE), (void*)&string);
168 return 1;
169 }
170 return 0;
171 }
172
173 FXIMPLEMENT(NickListItem, FXListItem, NULL, 0)
174
175 // Draw item
draw(const FXList * list,FXDC & dc,FXint xx,FXint yy,FXint ww,FXint hh)176 void NickListItem::draw(const FXList* list, FXDC& dc, FXint xx, FXint yy, FXint ww, FXint hh)
177 {
178 FXFont *font=list->getFont();
179 FXint ih=0,th=0;
180 if(icon) ih=icon->getHeight();
181 if(!label.empty()) th=font->getFontHeight();
182 dc.setForeground(list->getBackColor()); // FIXME maybe paint background in onPaint?
183 dc.fillRectangle(xx,yy,ww,hh);
184 if(isSelected())
185 {
186 dc.drawFocusRectangle(xx+1,yy+1,ww-2,hh-2);
187 }
188 xx+=SIDE_SPACING/2;
189 if(icon)
190 {
191 dc.drawIcon(icon,xx,yy+(hh-ih)/2);
192 xx+=ICON_SPACING+icon->getWidth();
193 }
194 else
195 {
196 FXString mode = "";
197 switch(m_mode){
198 case ADMIN: mode = "!";break;
199 case OWNER: mode = "*";break;
200 case OP: mode = "@";break;
201 case HALFOP: mode = "%";break;
202 case VOICE: mode= "+";break;
203 case NONE: mode = " ";break;
204 }
205 dc.setFont(font);
206 dc.setForeground(list->getTextColor());
207 dc.drawText(xx,yy+(hh-th)/2+font->getFontAscent(),mode);
208 xx+=ICON_SPACING+font->getTextWidth("@");
209 }
210 if(!label.empty())
211 {
212 dc.setFont(font);
213 if(m_away)
214 dc.setForeground(makeAwayColor(list->getTextColor()));
215 else
216 dc.setForeground(list->getTextColor());
217 dc.drawText(xx,yy+(hh-th)/2+font->getFontAscent(),label);
218 }
219 }
220
221 // Get width of item
getWidth(const FXList * list) const222 FXint NickListItem::getWidth(const FXList* list) const
223 {
224 FXFont *font=list->getFont();
225 FXint w=0;
226 if(icon)
227 {
228 w=icon->getWidth();
229 }
230 else
231 {
232 w=font->getTextWidth("@");
233 }
234 if(!label.empty())
235 {
236 if(w) w+=ICON_SPACING;
237 w+=font->getTextWidth(label.text(),label.length());
238 }
239 return SIDE_SPACING+w;
240 }
241
setUserMode(UserMode mode)242 void NickListItem::setUserMode(UserMode mode)
243 {
244 m_mode = mode;
245 m_parent->recalc();
246 if(icon)
247 {
248 switch(m_mode){
249 case ADMIN: setIcon(m_away? ICO_IRCAWAYADMIN:ICO_IRCADMIN);break;
250 case OWNER: setIcon(m_away? ICO_IRCAWAYOWNER:ICO_IRCOWNER);break;
251 case OP: setIcon(m_away? ICO_IRCAWAYOP:ICO_IRCOP);break;
252 case HALFOP: setIcon(m_away? ICO_IRCAWAYHALFOP:ICO_IRCHALFOP);break;
253 case VOICE: setIcon(m_away? ICO_IRCAWAYVOICE:ICO_IRCVOICE);break;
254 case NONE: setIcon(m_away? ICO_IRCAWAYNORMAL:ICO_IRCNORMAL);break;
255 }
256 }
257 }
258
changeAway(FXbool away)259 void NickListItem::changeAway(FXbool away)
260 {
261 if(m_away == away) return;
262 m_away = away;
263 m_parent->recalc();
264 if(icon)
265 {
266 switch(m_mode){
267 case ADMIN: setIcon(m_away? ICO_IRCAWAYADMIN:ICO_IRCADMIN);break;
268 case OWNER: setIcon(m_away? ICO_IRCAWAYOWNER:ICO_IRCOWNER);break;
269 case OP: setIcon(m_away? ICO_IRCAWAYOP:ICO_IRCOP);break;
270 case HALFOP: setIcon(m_away? ICO_IRCAWAYHALFOP:ICO_IRCHALFOP);break;
271 case VOICE: setIcon(m_away? ICO_IRCAWAYVOICE:ICO_IRCVOICE);break;
272 case NONE: setIcon(m_away? ICO_IRCAWAYNORMAL:ICO_IRCNORMAL);break;
273 }
274 }
275 }
276
277 //Clear icon, usefull for nick icon theme change
clearIcon()278 void NickListItem::clearIcon()
279 {
280 if(icon)
281 setIcon(NULL);
282 }
283
284 //Apply new theme icon, usefull for nick icon theme change
restoreIcon()285 void NickListItem::restoreIcon()
286 {
287 m_parent->recalc();
288 switch(m_mode){
289 case ADMIN: setIcon(m_away? ICO_IRCAWAYADMIN:ICO_IRCADMIN);break;
290 case OWNER: setIcon(m_away? ICO_IRCAWAYOWNER:ICO_IRCOWNER);break;
291 case OP: setIcon(m_away? ICO_IRCAWAYOP:ICO_IRCOP);break;
292 case HALFOP: setIcon(m_away? ICO_IRCAWAYHALFOP:ICO_IRCHALFOP);break;
293 case VOICE: setIcon(m_away? ICO_IRCAWAYVOICE:ICO_IRCVOICE);break;
294 case NONE: setIcon(m_away? ICO_IRCAWAYNORMAL:ICO_IRCNORMAL);break;
295 }
296 }
297
298 FXDEFMAP(IrcTabItem) IrcTabItemMap[] = {
299 FXMAPFUNC(SEL_COMMAND, IrcTabItem_COMMANDLINE, IrcTabItem::onCommandline),
300 FXMAPFUNC(SEL_KEYPRESS, IrcTabItem_COMMANDLINE, IrcTabItem::onKeyPress),
301 FXMAPFUNC(SEL_COMMAND, IrcEngine_SERVER, IrcTabItem::onIrcEvent),
302 FXMAPFUNC(SEL_TIMEOUT, IrcTabItem_PTIME, IrcTabItem::onPipeTimeout),
303 FXMAPFUNC(SEL_TIMEOUT, IrcTabItem_ETIME, IrcTabItem::onEggTimeout),
304 FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, IrcTabItem_USERS, IrcTabItem::onRightMouse),
305 FXMAPFUNC(SEL_DOUBLECLICKED, IrcTabItem_USERS, IrcTabItem::onDoubleclick),
306 FXMAPFUNC(SEL_COMMAND, IrcTabItem_NEWQUERY, IrcTabItem::onNewQuery),
307 FXMAPFUNC(SEL_COMMAND, IrcTabItem_WHOIS, IrcTabItem::onWhois),
308 FXMAPFUNC(SEL_COMMAND, IrcTabItem_DCCCHAT, IrcTabItem::onDccChat),
309 FXMAPFUNC(SEL_COMMAND, IrcTabItem_DCCSEND, IrcTabItem::onDccSend),
310 FXMAPFUNC(SEL_COMMAND, IrcTabItem_OP, IrcTabItem::onOp),
311 FXMAPFUNC(SEL_COMMAND, IrcTabItem_DEOP, IrcTabItem::onDeop),
312 FXMAPFUNC(SEL_COMMAND, IrcTabItem_VOICE, IrcTabItem::onVoice),
313 FXMAPFUNC(SEL_COMMAND, IrcTabItem_DEVOICE, IrcTabItem::onDevoice),
314 FXMAPFUNC(SEL_COMMAND, IrcTabItem_KICK, IrcTabItem::onKick),
315 FXMAPFUNC(SEL_COMMAND, IrcTabItem_BAN, IrcTabItem::onBan),
316 FXMAPFUNC(SEL_COMMAND, IrcTabItem_KICKBAN, IrcTabItem::onKickban),
317 FXMAPFUNC(SEL_COMMAND, IrcTabItem_IGNORE, IrcTabItem::onIgnore),
318 FXMAPFUNC(SEL_COMMAND, IrcTabItem_TOPIC, IrcTabItem::onTopic),
319 FXMAPFUNC(SEL_LINK, IrcTabItem_TOPIC, IrcTabItem::onTopicLink),
320 FXMAPFUNC(SEL_COMMAND, dxPipe::ID_PIPE, IrcTabItem::onPipe),
321 FXMAPFUNC(SEL_COMMAND, IrcTabItem_AWAY, IrcTabItem::onSetAway),
322 FXMAPFUNC(SEL_COMMAND, IrcTabItem_DEAWAY, IrcTabItem::onRemoveAway),
323 FXMAPFUNC(SEL_COMMAND, IrcTabItem_SPELL, IrcTabItem::onSpellLang),
324 FXMAPFUNC(SEL_COMMAND, LogThread_LIST, IrcTabItem::onListLogThread),
325 FXMAPFUNC(SEL_COMMAND, LogThread_LINES, IrcTabItem::onLinesLogThread)
326 };
327
FXIMPLEMENT(IrcTabItem,dxTabItem,IrcTabItemMap,ARRAYNUMBER (IrcTabItemMap))328 FXIMPLEMENT(IrcTabItem, dxTabItem, IrcTabItemMap, ARRAYNUMBER(IrcTabItemMap))
329
330 IrcTabItem::IrcTabItem(dxTabBook *tab, const FXString &tabtext, FXIcon *icon, FXuint opts,
331 FXint id, TYPE type, IrcEngine *socket, FXFont *font, FXbool useNickIcon)
332 : dxTabItem(tab, tabtext, icon, opts, id), m_engine(socket), m_parent(tab), m_type(type),
333 m_useNickIcon(useNickIcon), m_logstream(NULL)
334 {
335 m_currentPosition = 0;
336 m_historyMax = 25;
337 m_numberUsers = 0;
338 m_maxLen = 460;
339 m_iamOp = FALSE;
340 m_topic = _("No topic is set");
341 m_editableTopic = TRUE;
342 m_pipe = NULL;
343 m_sendPipe = FALSE;
344 m_scriptHasAll = FALSE;
345 m_scriptHasOwnMsg = FALSE;
346 m_loadLog = FALSE;
347
348 if(m_type == CHANNEL && m_engine && m_engine->getConnected())
349 {
350 m_engine->sendMode(getText());
351 }
352
353 m_mainframe = new FXVerticalFrame(m_parent, FRAME_RAISED|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
354
355 m_splitter = new FXSplitter(m_mainframe, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_REVERSED|SPLITTER_TRACKING);
356
357 m_textframe = new FXVerticalFrame(m_splitter, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y);
358 m_topicline = new dxTextField(m_textframe, 50, this, IrcTabItem_TOPIC, FRAME_SUNKEN|TEXTFIELD_ENTER_ONLY|JUSTIFY_LEFT|LAYOUT_FILL_X);
359 m_topicline->setFont(font);
360 m_topicline->setLinkColor(preferences.m_colors.link);
361 m_topicline->setText(m_topic);
362 m_topicline->setUseLink(TRUE);
363 m_topicline->setTopicline(TRUE);
364 if(m_type != CHANNEL)
365 {
366 m_topicline->hide();
367 }
368 m_text->reparent(m_textframe);
369 m_text->setFont(font);
370 m_text->setSelTextColor(getApp()->getSelforeColor());
371 m_text->setSelBackColor(getApp()->getSelbackColor());
372
373 m_usersframe = new FXVerticalFrame(m_splitter, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH);
374 m_users = new NickList(m_usersframe, this, IrcTabItem_USERS, LAYOUT_FILL_X|LAYOUT_FILL_Y);
375 m_users->setSortFunc(preferences.m_sortUserMode ? sortNick : FXList::ascendingCase);
376 m_users->setScrollStyle(HSCROLLING_OFF);
377 if(preferences.m_sameList) m_users->setFont(font);
378 if(m_type != CHANNEL || !preferences.m_usersShown)
379 {
380 m_usersframe->hide();
381 m_users->hide();
382 }
383
384 m_commandframe = new FXHorizontalFrame(m_mainframe, LAYOUT_FILL_X, 0,0,0,0, 0,0,0,0);
385 m_commandline = new dxTextField(m_commandframe, 25, this, IrcTabItem_COMMANDLINE, TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|JUSTIFY_LEFT|LAYOUT_FILL_X|LAYOUT_BOTTOM, 0, 0, 0, 0, 1, 1, 1, 1);
386 if(preferences.m_sameCmd) m_commandline->setFont(font);
387 m_spellLangs = new FXComboBox(m_commandframe, 6, this, IrcTabItem_SPELL, FRAME_SUNKEN|COMBOBOX_STATIC);
388 m_spellLangs->setTipText(_("Spellchecking language list"));
389 m_spellLangs->hide();
390 if(preferences.m_sameCmd) m_spellLangs->setFont(font);
391 if(preferences.m_useSpell && (m_type==CHANNEL || m_type==QUERY) && dxUtils.getAvailableSpellLangsNum())
392 {
393 dxStringArray langs = dxUtils.getAvailableSpellLangs();
394 FXString lang = dxUtils.getChannelLang(getText());
395 for(FXint i=0; i<langs.no(); i++)
396 {
397 m_spellLangs->appendItem(langs[i]);
398 if(langs[i]==lang) m_spellLangs->setCurrentItem(i);;
399 }
400 if(preferences.m_showSpellCombo) m_spellLangs->show();
401 m_commandline->setUseSpell(TRUE);
402 m_commandline->setLanguage(lang);
403 m_commandline->setTipText(FXStringFormat(_("Current spellchecking language: %s"),lang.text()));
404 }
405
406 dxHiliteStyle style = {preferences.m_colors.text,preferences.m_colors.back,getApp()->getSelforeColor(),getApp()->getSelbackColor(),0,FALSE};
407 for(int i=0; i<19; i++)
408 {
409 m_textStyleList.append(style);
410 }
411 //gray text - user commands
412 m_textStyleList[0].normalForeColor = preferences.m_colors.user;
413 //orange text - Actions
414 m_textStyleList[1].normalForeColor = preferences.m_colors.action;
415 //blue text - Notice
416 m_textStyleList[2].normalForeColor = preferences.m_colors.notice;
417 //red text - Errors
418 m_textStyleList[3].normalForeColor = preferences.m_colors.error;
419 //bold style
420 m_textStyleList[4].style = FXText::STYLE_BOLD;
421 //underline style
422 m_textStyleList[5].style = FXText::STYLE_UNDERLINE;
423 //bold & underline
424 m_textStyleList[6].style = FXText::STYLE_UNDERLINE;
425 m_textStyleList[6].style ^=FXText::STYLE_BOLD;
426 //highlight text
427 m_textStyleList[7].normalForeColor = preferences.m_colors.hilight;
428 //link style
429 m_textStyleList[8].normalForeColor = preferences.m_colors.link;
430 m_textStyleList[8].link = TRUE;
431 //mymsg style
432 m_textStyleList[9].normalForeColor = preferences.m_colors.mymsg;
433 //log line style
434 m_textStyleList[10].normalForeColor = preferences.m_colors.log;
435 //next styles for colored nicks
436 m_textStyleList[11].normalForeColor = FXRGB(196, 160, 0);
437 m_textStyleList[12].normalForeColor = FXRGB(206, 92, 0);
438 m_textStyleList[13].normalForeColor = FXRGB(143, 89, 2);
439 m_textStyleList[14].normalForeColor = FXRGB(78, 154, 6);
440 m_textStyleList[15].normalForeColor = FXRGB(32, 74, 135);
441 m_textStyleList[16].normalForeColor = FXRGB(117, 80, 123);
442 m_textStyleList[17].normalForeColor = FXRGB(164, 0, 0);
443 m_textStyleList[18].normalForeColor = FXRGB(85, 87, 83);
444
445 //text->setStyled(TRUE);
446 m_text->setHiliteStyles(m_textStyleList.data());
447
448 m_text->setBackColor(preferences.m_colors.back);
449 m_commandline->setBackColor(preferences.m_colors.back);
450 m_topicline->setBackColor(preferences.m_colors.back);
451 m_users->setBackColor(preferences.m_colors.back);
452 m_text->setTextColor(preferences.m_colors.text);
453 m_commandline->setTextColor(preferences.m_colors.text);
454 m_commandline->setCursorColor(preferences.m_colors.text);
455 m_topicline->setTextColor(preferences.m_colors.text);
456 m_topicline->setCursorColor(preferences.m_colors.text);
457 m_users->setTextColor(preferences.m_colors.text);
458 m_spellLangs->setBackColor(preferences.m_colors.back);
459 m_spellLangs->setTextColor(preferences.m_colors.text);
460
461 this->setIconPosition(ICON_BEFORE_TEXT);
462
463 if(m_engine) m_logThread = new LogThread(this, getApp(), preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText());
464 }
465
~IrcTabItem()466 IrcTabItem::~IrcTabItem()
467 {
468 this->stopLogging();
469 if(m_pipe) m_pipe->closePipe();
470 m_pipeStrings.clear();
471 getApp()->removeTimeout(this, IrcTabItem_PTIME);
472 }
473
createGeom()474 void IrcTabItem::createGeom()
475 {
476 m_mainframe->create();
477 loadLogLines();
478 m_commandline->setFocus();
479 }
480
clearChat()481 void IrcTabItem::clearChat()
482 {
483 m_textStyleList.no(19);
484 m_text->setHiliteStyles(m_textStyleList.data());
485 m_text->clearText();
486 }
487
488 //usefull for set tab current
makeLastRowVisible()489 void IrcTabItem::makeLastRowVisible()
490 {
491 m_text->makeLastRowVisible(TRUE);
492 }
493
getSpellLang()494 FXString IrcTabItem::getSpellLang()
495 {
496 #ifdef HAVE_ENCHANT
497 if(m_spellLangs->getNumItems()) return m_spellLangs->getItemText(m_spellLangs->getCurrentItem());
498 #endif
499 return "";
500 }
501
reparentTab()502 void IrcTabItem::reparentTab()
503 {
504 reparent(m_parent);
505 m_mainframe->reparent(m_parent);
506 recalc();
507 m_mainframe->recalc();
508 }
509
hideUsers()510 void IrcTabItem::hideUsers()
511 {
512 if(m_type == CHANNEL)
513 {
514 m_usersframe->hide();
515 m_users->hide();
516 m_splitter->setSplit(1, 0);
517 }
518 }
519
showUsers()520 void IrcTabItem::showUsers()
521 {
522 if(m_type == CHANNEL)
523 {
524 m_usersframe->show();
525 m_users->show();
526 m_splitter->recalc();
527 }
528 }
529
setType(const TYPE & typ,const FXString & tabtext)530 void IrcTabItem::setType(const TYPE &typ, const FXString &tabtext)
531 {
532 if(typ == CHANNEL)
533 {
534 if(preferences.m_usersShown) m_usersframe->show();
535 if(preferences.m_usersShown) m_users->show();
536 m_topicline->show();
537 m_topicline->setText(m_topic);
538 m_splitter->recalc();
539 setText(tabtext);
540 if(m_engine->getConnected()) m_engine->sendMode(getText());
541 m_type = typ;
542 }
543 else if(typ == SERVER || typ == QUERY)
544 {
545 m_usersframe->hide();
546 m_users->hide();
547 m_topicline->setText("");
548 m_topicline->hide();
549 m_topic = _("No topic is set");
550 setText(tabtext);
551 m_splitter->setSplit(1, 0);
552 if(m_type == CHANNEL)
553 {
554 m_users->clearItems();
555 m_numberUsers = 0;
556 }
557 m_type = typ;
558 }
559 this->stopLogging();
560 if(m_type == SERVER) this->setIcon(ICO_SERVER);
561 else if(m_type == CHANNEL) this->setIcon(ICO_CHANNEL);
562 else this->setIcon(ICO_QUERY);
563 if(m_type==CHANNEL || m_type==QUERY)
564 loadLogLines();
565 if(preferences.m_useSpell && (m_type==CHANNEL || m_type==QUERY) && dxUtils.getAvailableSpellLangsNum())
566 {
567 dxStringArray langs = dxUtils.getAvailableSpellLangs();
568 FXString lang = dxUtils.getChannelLang(getText());
569 for(FXint i=0; i<langs.no(); i++)
570 {
571 m_spellLangs->appendItem(langs[i]);
572 if(langs[i]==lang) m_spellLangs->setCurrentItem(i);
573 }
574 if(preferences.m_showSpellCombo) m_spellLangs->show();
575 m_commandline->setUseSpell(TRUE);
576 m_commandline->setLanguage(lang);
577 m_commandline->setTipText(FXStringFormat(_("Current spellchecking language: %s"),lang.text()));
578 }
579 else
580 {
581 m_commandline->setUseSpell(FALSE);
582 m_commandline->setTipText("");
583 m_spellLangs->hide();
584 }
585 m_commandframe->recalc();
586 }
587
preferencesUpdated()588 void IrcTabItem::preferencesUpdated()
589 {
590 setTextForeColor(preferences.m_colors.text);
591 setTextBackColor(preferences.m_colors.back);
592 setUserColor(preferences.m_colors.user);
593 setActionsColor(preferences.m_colors.action);
594 setNoticeColor(preferences.m_colors.notice);
595 setErrorColor(preferences.m_colors.error);
596 setHilightColor(preferences.m_colors.hilight);
597 setLinkColor(preferences.m_colors.link);
598 setMymsgColor(preferences.m_colors.mymsg);
599 setLogColor(preferences.m_colors.log);
600 stopLogging();
601 if(preferences.m_useSpell && (m_type==CHANNEL || m_type==QUERY) && dxUtils.getAvailableSpellLangsNum())
602 {
603 dxStringArray langs = dxUtils.getAvailableSpellLangs();
604 FXString lang = dxUtils.getChannelLang(getText());
605 for(FXint i=0; i<langs.no(); i++)
606 {
607 m_spellLangs->appendItem(langs[i]);
608 if(langs[i]==lang) m_spellLangs->setCurrentItem(i);;
609 }
610 if(preferences.m_showSpellCombo) m_spellLangs->show();
611 m_commandline->setUseSpell(TRUE);
612 m_commandline->setLanguage(lang);
613 m_commandline->setTipText(FXStringFormat(_("Current spellchecking language: %s"),lang.text()));
614 }
615 else
616 {
617 m_commandline->setUseSpell(FALSE);
618 m_commandline->setTipText("");
619 m_spellLangs->hide();
620 }
621 m_users->setSortFunc(preferences.m_sortUserMode ? sortNick : FXList::ascendingCase);
622 m_users->sortItems();
623 m_commandframe->recalc();
624 }
625
setTextBackColor(FXColor clr)626 void IrcTabItem::setTextBackColor(FXColor clr)
627 {
628 for(FXint i=0; i<m_textStyleList.no(); i++)
629 {
630 m_textStyleList[i].normalBackColor = clr;
631 }
632 m_text->setBackColor(clr);
633 m_commandline->setBackColor(clr);
634 m_topicline->setBackColor(clr);
635 m_users->setBackColor(clr);
636 m_spellLangs->setBackColor(clr);
637 }
638
setTextForeColor(FXColor clr)639 void IrcTabItem::setTextForeColor(FXColor clr)
640 {
641 m_textStyleList[4].normalForeColor = clr;
642 m_textStyleList[5].normalForeColor = clr;
643 m_textStyleList[6].normalForeColor = clr;
644 m_text->setTextColor(clr);
645 m_commandline->setTextColor(clr);
646 m_commandline->setCursorColor(clr);
647 m_topicline->setTextColor(clr);
648 m_topicline->setCursorColor(clr);
649 m_users->setTextColor(clr);
650 m_spellLangs->setTextColor(clr);
651 }
652
setUserColor(FXColor clr)653 void IrcTabItem::setUserColor(FXColor clr)
654 {
655 m_textStyleList[0].normalForeColor = clr;
656 }
657
setActionsColor(FXColor clr)658 void IrcTabItem::setActionsColor(FXColor clr)
659 {
660 m_textStyleList[1].normalForeColor = clr;
661 }
662
setNoticeColor(FXColor clr)663 void IrcTabItem::setNoticeColor(FXColor clr)
664 {
665 m_textStyleList[2].normalForeColor = clr;
666 }
667
setErrorColor(FXColor clr)668 void IrcTabItem::setErrorColor(FXColor clr)
669 {
670 m_textStyleList[3].normalForeColor = clr;
671 }
672
setHilightColor(FXColor clr)673 void IrcTabItem::setHilightColor(FXColor clr)
674 {
675 m_textStyleList[7].normalForeColor = clr;
676 }
677
setLinkColor(FXColor clr)678 void IrcTabItem::setLinkColor(FXColor clr)
679 {
680 m_textStyleList[8].normalForeColor = clr;
681 m_topicline->setLinkColor(clr);
682 }
683
setMymsgColor(FXColor clr)684 void IrcTabItem::setMymsgColor(FXColor clr)
685 {
686 m_textStyleList[9].normalForeColor = clr;
687 }
688
setLogColor(FXColor clr)689 void IrcTabItem::setLogColor(FXColor clr)
690 {
691 m_textStyleList[10].normalForeColor = clr;
692 }
693
setIrcFont(FXFont * fnt)694 void IrcTabItem::setIrcFont(FXFont *fnt)
695 {
696 m_text->setFont(fnt);
697 m_text->recalc();
698 m_topicline->setFont(fnt);
699 m_topicline->recalc();
700 if(preferences.m_sameCmd)
701 {
702 m_commandline->setFont(fnt);
703 m_commandline->recalc();
704 m_spellLangs->setFont(fnt);
705 m_spellLangs->recalc();
706 }
707 else
708 {
709 m_commandline->setFont(getApp()->getNormalFont());
710 m_commandline->recalc();
711 m_spellLangs->setFont(getApp()->getNormalFont());
712 m_spellLangs->recalc();
713 }
714 if(preferences.m_sameList)
715 {
716 m_users->setFont(fnt);
717 m_users->recalc();
718 }
719 else
720 {
721 m_users->setFont(getApp()->getNormalFont());
722 m_users->recalc();
723 }
724 }
725
setSmileys(FXbool smiley,dxSmileyArray nsmileys)726 void IrcTabItem::setSmileys(FXbool smiley, dxSmileyArray nsmileys)
727 {
728 m_text->setSmileys(smiley, nsmileys);
729 }
730
showSpellComboUpdated()731 void IrcTabItem::showSpellComboUpdated()
732 {
733 if(m_type == CHANNEL || m_type == QUERY)
734 {
735 if(preferences.m_showSpellCombo) m_spellLangs->show();
736 else m_spellLangs->hide();
737 m_commandframe->recalc();
738 }
739 }
740
removeSmileys()741 void IrcTabItem::removeSmileys()
742 {
743 m_text->removeSmileys();
744 }
745
746 //if highlight==TRUE, highlight tab
appendText(FXString msg,FXbool highlight,FXbool logLine)747 void IrcTabItem::appendText(FXString msg, FXbool highlight, FXbool logLine)
748 {
749 appendIrcText(msg, 0, FALSE, logLine);
750 if(highlight && preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this))
751 {
752 if(highlightNeeded(msg))
753 {
754 this->setTextColor(preferences.m_highlightColor);
755 if(m_type == CHANNEL) this->setIcon(ICO_CHANNELNEWMSG);
756 }
757 else this->setTextColor(preferences.m_unreadColor);
758 if(m_type == QUERY) this->setIcon(ICO_QUERYNEWMSG);
759 }
760 }
761
appendIrcText(FXString msg,FXTime time,FXbool disableStrip,FXbool logLine)762 void IrcTabItem::appendIrcText(FXString msg, FXTime time, FXbool disableStrip, FXbool logLine)
763 {
764 if(!time) time = FXSystem::now();
765 if(m_type != OTHER) m_text->appendText(FXSystem::time("[%H:%M:%S] ", time));
766 if(preferences.m_stripColors && !disableStrip) msg = dxutils::stripColors(msg, FALSE);
767 appendLinkText(msg, 0);
768 if(logLine) this->logLine(msg, time);
769 }
770
appendIrcNickText(FXString nick,FXString msg,FXint style,FXTime time,FXbool logLine)771 void IrcTabItem::appendIrcNickText(FXString nick, FXString msg, FXint style, FXTime time, FXbool logLine)
772 {
773 if(!time) time = FXSystem::now();
774 if(m_type != OTHER) m_text->appendText(FXSystem::time("[%H:%M:%S] ", time));
775 m_text->appendStyledText(nick+": ", style);
776 if(preferences.m_stripColors) msg = dxutils::stripColors(msg, FALSE);
777 appendLinkText(msg, 0);
778 if(logLine) this->logLine("<"+nick+"> "+msg, time);
779 }
780
appendMyMsg(FXString msg,FXTime time)781 void IrcTabItem::appendMyMsg(FXString msg, FXTime time)
782 {
783 if(!time) time = FXSystem::now();
784 m_text->appendText(FXSystem::time("[%H:%M:%S] ", time));
785 m_text->appendStyledText(getNickName()+": ", preferences.m_coloredNick?10:5);
786 if(preferences.m_stripColors) msg = dxutils::stripColors(msg, FALSE);
787 appendLinkText(msg, 10);
788 this->logLine("\01410\014<"+getNickName()+"> "+msg, time);
789 }
790
791 /* if highlight==TRUE, highlight tab
792 * disableStrip is for dxirc.Print
793 */
appendStyledText(FXString text,FXint style,FXbool highlight,FXbool disableStrip,FXbool logLine)794 void IrcTabItem::appendStyledText(FXString text, FXint style, FXbool highlight, FXbool disableStrip, FXbool logLine)
795 {
796 if(style) appendIrcStyledText(text, style, 0, disableStrip, logLine);
797 else appendIrcText(text, 0, disableStrip, logLine);
798 if(highlight && preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this))
799 {
800 if(m_type != OTHER && highlightNeeded(text))
801 {
802 this->setTextColor(preferences.m_highlightColor);
803 if(m_type == CHANNEL) this->setIcon(ICO_CHANNELNEWMSG);
804 }
805 else this->setTextColor(preferences.m_unreadColor);
806 if(m_type == QUERY) this->setIcon(ICO_QUERYNEWMSG);
807 }
808 }
809
appendIrcStyledText(FXString styled,FXint stylenum,FXTime time,FXbool disableStrip,FXbool logLine)810 void IrcTabItem::appendIrcStyledText(FXString styled, FXint stylenum, FXTime time, FXbool disableStrip, FXbool logLine)
811 {
812 if(!time) time = FXSystem::now();
813 if(m_type != OTHER) m_text->appendText(FXSystem::time("[%H:%M:%S] ", time));
814 if(preferences.m_stripColors && !disableStrip) styled = dxutils::stripColors(styled, TRUE);
815 appendLinkText(styled, stylenum);
816 if(logLine)
817 {
818 if(stylenum==8) //highlight msg
819 {
820 this->logLine("\0148\014<"+styled.before(':')+">"+styled.after(':'), time);
821 }
822 else this->logLine(FXStringFormat("\014%d\014%s", stylenum, styled.text()), time);
823 }
824 }
825
isBadchar(FXchar c)826 static FXbool isBadchar(FXchar c)
827 {
828 switch(c) {
829 case ' ':
830 case ',':
831 case '\0':
832 case '\02':
833 case '\03':
834 case '\017':
835 case '\021':
836 case '\026':
837 case '\035':
838 case '\037':
839 case '\n':
840 case '\r':
841 case '<':
842 case '>':
843 case '"':
844 case '\'':
845 return TRUE;
846 default:
847 return FALSE;
848 }
849 }
850
851 // checks is char nick/word delimiter
isDelimiter(FXchar c)852 static FXbool isDelimiter(FXchar c)
853 {
854 switch(c) {
855 case ' ':
856 case '.':
857 case ',':
858 case '/':
859 case '\\':
860 case '`':
861 case '\'':
862 case '!':
863 case '(':
864 case ')':
865 case '{':
866 case '}':
867 case '|':
868 case '[':
869 case ']':
870 case '\"':
871 case ':':
872 case ';':
873 case '<':
874 case '>':
875 case '?':
876 return TRUE;
877 default:
878 return FALSE;
879 }
880 }
881
appendLinkText(const FXString & txt,FXint stylenum)882 void IrcTabItem::appendLinkText(const FXString &txt, FXint stylenum)
883 {
884 FXint i = 0;
885 FXint linkLength = 0;
886 FXbool bold = FALSE;
887 FXbool under = FALSE;
888 FXint lastStyle = stylenum;
889 FXColor foreColor = stylenum && stylenum<=m_textStyleList.no() ? m_textStyleList[stylenum-1].normalForeColor : preferences.m_colors.text;
890 FXColor backColor = stylenum && stylenum<=m_textStyleList.no() ? m_textStyleList[stylenum-1].normalBackColor : preferences.m_colors.back;
891 FXString normalText = "";
892 FXint length = txt.length();
893 while(i<length)
894 {
895 if(txt[i]=='h' && !comparecase(txt.mid(i,7),"http://"))
896 {
897 if(!normalText.empty())
898 {
899 m_text->appendStyledText(normalText, lastStyle);
900 normalText.clear();
901 }
902 for(FXint j=i; j<length; j++)
903 {
904 if(isBadchar(txt[j]))
905 {
906 break;
907 }
908 linkLength++;
909 }
910 m_text->appendStyledText(txt.mid(i, linkLength), linkLength>7 ? 9 : stylenum);
911 i+=linkLength-1;
912 linkLength=0;
913 }
914 else if(txt[i]=='h' && !comparecase(txt.mid(i,8),"https://"))
915 {
916 if(!normalText.empty())
917 {
918 m_text->appendStyledText(normalText, lastStyle);
919 normalText.clear();
920 }
921 for(FXint j=i; j<length; j++)
922 {
923 if(isBadchar(txt[j]))
924 {
925 break;
926 }
927 linkLength++;
928 }
929 m_text->appendStyledText(txt.mid(i, linkLength), linkLength>8 ? 9 : stylenum);
930 i+=linkLength-1;
931 linkLength=0;
932 }
933 else if(txt[i]=='f' && !comparecase(txt.mid(i,6),"ftp://"))
934 {
935 if(!normalText.empty())
936 {
937 m_text->appendStyledText(normalText, lastStyle);
938 normalText.clear();
939 }
940 for(FXint j=i; j<length; j++)
941 {
942 if(isBadchar(txt[j]))
943 {
944 break;
945 }
946 linkLength++;
947 }
948 m_text->appendStyledText(txt.mid(i, linkLength), linkLength>6 ? 9 : stylenum);
949 i+=linkLength-1;
950 linkLength=0;
951 }
952 else if(txt[i]=='w' && !comparecase(txt.mid(i,4),"www."))
953 {
954 if(!normalText.empty())
955 {
956 m_text->appendStyledText(normalText, lastStyle);
957 normalText.clear();
958 }
959 for(FXint j=i; j<length; j++)
960 {
961 if(isBadchar(txt[j]))
962 {
963 break;
964 }
965 linkLength++;
966 }
967 m_text->appendStyledText(txt.mid(i, linkLength), linkLength>4 ? 9 : stylenum);
968 i+=linkLength-1;
969 linkLength=0;
970 }
971 else
972 {
973 if(txt[i] == '\002') //bold
974 {
975 if(!normalText.empty())
976 {
977 m_text->appendStyledText(normalText, lastStyle);
978 normalText.clear();
979 }
980 bold = !bold;
981 FXuint style = 0;
982 if(bold && under) style = FXText::STYLE_BOLD|FXText::STYLE_UNDERLINE;
983 else if(bold && !under) style = FXText::STYLE_BOLD;
984 else if(!bold && under) style = FXText::STYLE_UNDERLINE;
985 lastStyle = hiliteStyleExist(foreColor, backColor, style);
986 if(lastStyle == -1)
987 {
988 //dxText has available max. 255 styles
989 if(m_textStyleList.no()<256)
990 {
991 createHiliteStyle(foreColor, backColor, style);
992 lastStyle = m_textStyleList.no();
993 }
994 else lastStyle = 0;
995 }
996 }
997 else if(txt[i] == '\026') //reverse
998 {
999 if(!normalText.empty())
1000 {
1001 m_text->appendStyledText(normalText, lastStyle);
1002 normalText.clear();
1003 }
1004 FXuint style = 0;
1005 if(bold && under) style = FXText::STYLE_BOLD|FXText::STYLE_UNDERLINE;
1006 else if(bold && !under) style = FXText::STYLE_BOLD;
1007 else if(!bold && under) style = FXText::STYLE_UNDERLINE;
1008 FXColor tempColor = foreColor;
1009 foreColor = backColor;
1010 backColor = tempColor;
1011 lastStyle = hiliteStyleExist(foreColor, backColor, style);
1012 if(lastStyle == -1)
1013 {
1014 //dxText has available max. 255 styles
1015 if(m_textStyleList.no()<256)
1016 {
1017 createHiliteStyle(foreColor, backColor, style);
1018 lastStyle = m_textStyleList.no();
1019 }
1020 else lastStyle = 0;
1021 }
1022 }
1023 else if(txt[i] == '\037') //underline
1024 {
1025 if(!normalText.empty())
1026 {
1027 m_text->appendStyledText(normalText, lastStyle);
1028 normalText.clear();
1029 }
1030 under = !under;
1031 FXuint style = 0;
1032 if(bold && under) style = FXText::STYLE_BOLD|FXText::STYLE_UNDERLINE;
1033 else if(bold && !under) style = FXText::STYLE_BOLD;
1034 else if(!bold && under) style = FXText::STYLE_UNDERLINE;
1035 lastStyle = hiliteStyleExist(foreColor, backColor, style);
1036 if(lastStyle == -1)
1037 {
1038 //dxText has available max. 255 styles
1039 if(m_textStyleList.no()<256)
1040 {
1041 createHiliteStyle(foreColor, backColor, style);
1042 lastStyle = m_textStyleList.no();
1043 }
1044 else lastStyle = 0;
1045 }
1046 }
1047 else if(txt[i] == '\021') //fixed
1048 {
1049 dxutils::debugLine("Poslan fixed styl");
1050 }
1051 else if(txt[i] == '\035') //italic
1052 {
1053 dxutils::debugLine("Poslan italic styl");
1054 }
1055 else if(txt[i] == '\003') //color
1056 {
1057 if(!normalText.empty())
1058 {
1059 m_text->appendStyledText(normalText, lastStyle);
1060 normalText.clear();
1061 }
1062 FXuint style=0;
1063 if(bold && under) style = FXText::STYLE_BOLD|FXText::STYLE_UNDERLINE;
1064 else if(bold && !under) style = FXText::STYLE_BOLD;
1065 else if(!bold && under) style = FXText::STYLE_UNDERLINE;
1066 FXbool isHexColor = FALSE;
1067 FXint colorLength = 0;
1068 foreColor = preferences.m_colors.text;
1069 backColor = preferences.m_colors.back;
1070 if(i+1<length)
1071 {
1072 if(txt[i+1] == '#') isHexColor = TRUE;
1073 }
1074 if(isHexColor)
1075 {
1076 if(FXRex("^\\h\\h\\h\\h\\h\\h+$").match(txt.mid(i+2,6)))
1077 {
1078 foreColor = fxcolorfromname(txt.mid(i+1,7).text());
1079 colorLength +=7;
1080 }
1081 if(i+8 < length && txt[i+8] == ',' && FXRex("^\\h\\h\\h\\h\\h\\h+$").match(txt.mid(i+10,6)))
1082 {
1083 backColor = fxcolorfromname(txt.mid(i+9,7).text());
1084 colorLength +=8;
1085 }
1086 }
1087 else
1088 {
1089 if(i+2<length)
1090 {
1091 FXint code = -1;
1092 if(isdigit(txt[i+1]))
1093 {
1094 if(isdigit(txt[i+2]))
1095 {
1096 code = (txt[i+1]-48)*10+txt[i+2]-48;
1097 colorLength +=2;
1098 }
1099 else
1100 {
1101 code = txt[i+1]-48;
1102 colorLength ++;
1103 }
1104 }
1105 if(code!=-1)
1106 foreColor = dxutils::getIrcColor(code, true);
1107 }
1108 if(i+colorLength+1 < length && txt[i+colorLength+1] == ',')
1109 {
1110 FXint code = -1;
1111 if(isdigit(txt[i+colorLength+2]))
1112 {
1113 if(isdigit(txt[i+colorLength+3]))
1114 {
1115 code = (txt[i+colorLength+2]-48)*10+txt[i+colorLength+3]-48;
1116 colorLength +=3;
1117 }
1118 else
1119 {
1120 code = txt[i+colorLength+2]-48;
1121 colorLength +=2;
1122 }
1123 }
1124 if(code!=-1)
1125 backColor = dxutils::getIrcColor(code, false);
1126 }
1127 }
1128 lastStyle = hiliteStyleExist(foreColor, backColor, style);
1129 if(lastStyle == -1)
1130 {
1131 //dxText has available max. 255 styles
1132 if(m_textStyleList.no()<256)
1133 {
1134 createHiliteStyle(foreColor, backColor, style);
1135 lastStyle = m_textStyleList.no();
1136 }
1137 else lastStyle = 0;
1138 };
1139 i +=colorLength;
1140 }
1141 else if(txt[i] == '\004') // hex color
1142 {
1143 if(!normalText.empty())
1144 {
1145 m_text->appendStyledText(normalText, lastStyle);
1146 normalText.clear();
1147 }
1148 FXuint style=0;
1149 if(bold && under) style = FXText::STYLE_BOLD|FXText::STYLE_UNDERLINE;
1150 else if(bold && !under) style = FXText::STYLE_BOLD;
1151 else if(!bold && under) style = FXText::STYLE_UNDERLINE;
1152 FXint colorLength = 0;
1153 foreColor = preferences.m_colors.text;
1154 backColor = preferences.m_colors.back;
1155 if(FXRex("^\\h\\h\\h\\h\\h\\h+$").match(txt.mid(i+1,6)))
1156 {
1157 FXString color = "#";
1158 color.append(txt.mid(i+1,6));
1159 foreColor = fxcolorfromname(color.text());
1160 colorLength +=6;
1161 }
1162 if(i+7 < length && txt[i+7] == ',' && FXRex("^\\h\\h\\h\\h\\h\\h+$").match(txt.mid(i+8,6)))
1163 {
1164 FXString color = "#";
1165 color.append(txt.mid(i+8,6));
1166 backColor = fxcolorfromname(color.text());
1167 colorLength +=7;
1168 }
1169 lastStyle = hiliteStyleExist(foreColor, backColor, style);
1170 if(lastStyle == -1)
1171 {
1172 //dxText has available max. 255 styles
1173 if(m_textStyleList.no()<256)
1174 {
1175 createHiliteStyle(foreColor, backColor, style);
1176 lastStyle = m_textStyleList.no();
1177 }
1178 else lastStyle = 0;
1179 };
1180 i +=colorLength;
1181 }
1182 else if(txt[i] == '\017') //reset
1183 {
1184 if(!normalText.empty())
1185 {
1186 m_text->appendStyledText(normalText, lastStyle);
1187 normalText.clear();
1188 }
1189 bold = FALSE;
1190 under = FALSE;
1191 foreColor = preferences.m_colors.text;
1192 backColor = preferences.m_colors.back;
1193 lastStyle = stylenum;
1194 }
1195 else
1196 {
1197 normalText.append(txt[i]);
1198 }
1199 }
1200 i++;
1201 }
1202 if(!normalText.empty())
1203 {
1204 m_text->appendStyledText(normalText, lastStyle);
1205 }
1206 m_text->appendText("\n");
1207 }
1208
startLogging()1209 void IrcTabItem::startLogging()
1210 {
1211 if(m_logstream && FXStat::exists(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText()+PATHSEPSTRING+FXSystem::time("%Y-%m-%d", FXSystem::now())))
1212 return;
1213 if(preferences.m_logging && m_type != SERVER)
1214 {
1215 if(!FXStat::exists(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName())) FXDir::create(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName());
1216 if(!FXStat::exists(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText())) FXDir::create(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText());
1217 m_logstream = new std::ofstream(FXString(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText()+PATHSEPSTRING+FXSystem::time("%Y-%m-%d", FXSystem::now())).text(), std::ios::out|std::ios::app);
1218 }
1219 }
1220
stopLogging()1221 void IrcTabItem::stopLogging()
1222 {
1223 if(m_logstream)
1224 {
1225 m_logstream->close();
1226 delete m_logstream;
1227 m_logstream = NULL;
1228 }
1229 }
1230
logLine(const FXString & line,const FXTime & time)1231 void IrcTabItem::logLine(const FXString &line, const FXTime &time)
1232 {
1233 if(preferences.m_logging && m_type != SERVER)
1234 {
1235 this->startLogging();
1236 *m_logstream << FXSystem::time("[%H:%M:%S] ", time).text() << line.text() << std::endl;
1237 }
1238 }
1239
isChannel(const FXString & text)1240 FXbool IrcTabItem::isChannel(const FXString &text)
1241 {
1242 if(text.length()) return m_engine->getChanTypes().contains(text[0]);
1243 return FALSE;
1244 }
1245
onCommandline(FXObject *,FXSelector,void *)1246 long IrcTabItem::onCommandline(FXObject *, FXSelector, void *)
1247 {
1248 FXString commandtext = m_commandline->getText();
1249 if(commandtext.empty())
1250 return 1;
1251 m_commandsHistory.append(commandtext);
1252 if (m_commandsHistory.no() > m_historyMax)
1253 m_commandsHistory.erase(0);
1254 m_currentPosition = m_commandsHistory.no()-1;
1255 m_commandline->setText("");
1256 if(comparecase(commandtext.left(4),"/say") != 0)
1257 commandtext.substitute("^B", "\002").substitute("^C", "\003").substitute("^O", "\017").substitute("^V", "\026").substitute("^_", "\037");
1258 for(FXint i=0; i<=commandtext.contains('\n'); i++)
1259 {
1260 FXString text = commandtext.section('\n', i).before('\r');
1261 if(comparecase(text.after('/').before(' '), "quit") == 0 ||
1262 comparecase(text.after('/').before(' '), "lua") == 0)
1263 {
1264 processLine(text);
1265 return 1;
1266 }
1267 #ifdef HAVE_LUA
1268 if(text[0] != '/') m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_OWNMSG), &text);
1269 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_COMMAND), &text);
1270 if(text[0] == '/' && !m_scriptHasAll) processLine(text);
1271 else if(!m_scriptHasOwnMsg && !m_scriptHasAll) processLine(text);
1272 #else
1273 processLine(text);
1274 #endif
1275 }
1276 return 1;
1277 }
1278
processLine(const FXString & commandtext)1279 FXbool IrcTabItem::processLine(const FXString& commandtext)
1280 {
1281 FXString command = (commandtext[0] == '/' ? commandtext.before(' ') : "");
1282 if(!dxUtils.getAlias(command).empty())
1283 {
1284 FXString acommand = dxUtils.getAlias(command);
1285 if(acommand.contains("%s"))
1286 acommand.substitute("%s", commandtext.after(' '));
1287 else
1288 acommand += commandtext.after(' ');
1289 FXint num = acommand.contains("&&");
1290 if(num)
1291 {
1292 FXbool result = FALSE;
1293 for(FXint i=0; i<=acommand.contains('&'); i++)
1294 {
1295 if(!acommand.section('&',i).trim().empty()) result = processCommand(acommand.section('&',i).trim());
1296 }
1297 return result;
1298 }
1299 else
1300 {
1301 return processCommand(acommand);
1302 }
1303 }
1304 return processCommand(commandtext);
1305 }
1306
processCommand(const FXString & commandtext)1307 FXbool IrcTabItem::processCommand(const FXString& commandtext)
1308 {
1309 FXString command = (commandtext[0] == '/' ? commandtext.after('/').before(' ').lower() : "");
1310 if(m_type == OTHER)
1311 {
1312 if(dxUtils.isScriptCommand(command))
1313 {
1314 return commandScript(commandtext);
1315 }
1316 if(command == "commands")
1317 {
1318 return commandCommands();
1319 }
1320 if(command == "egg")
1321 {
1322 return commandEgg();
1323 }
1324 if(command == "help")
1325 {
1326 return commandHelp(commandtext);
1327 }
1328 if(command == "tetris")
1329 {
1330 return commandTetris();
1331 }
1332 return TRUE;
1333 }
1334 if(commandtext[0] == '/')
1335 {
1336 if(dxUtils.isScriptCommand(command))
1337 {
1338 return commandScript(commandtext);
1339 }
1340 if(command == "admin")
1341 {
1342 return commandAdmin(commandtext);
1343 }
1344 if(command == "away")
1345 {
1346 return commandAway(commandtext);
1347 }
1348 if(command == "banlist")
1349 {
1350 return commandBanlist(commandtext);
1351 }
1352 if(command == "boats")
1353 {
1354 return commandBoats(commandtext);
1355 }
1356 if(command == "connect")
1357 {
1358 return commandConnect(commandtext);
1359 }
1360 if(command == "commands")
1361 {
1362 return commandCommands();
1363 }
1364 if(command == "ctcp")
1365 {
1366 return commandCtcp(commandtext);
1367 }
1368 if(command == "cycle")
1369 {
1370 return commandCycle(commandtext);
1371 }
1372 if(command == "dcc")
1373 {
1374 return commandDcc(commandtext);
1375 }
1376 if(command == "deop")
1377 {
1378 return commandDeop(commandtext);
1379 }
1380 if(command == "devoice")
1381 {
1382 return commandDevoice(commandtext);
1383 }
1384 if(command == "disconnect")
1385 {
1386 return commandDisconnect(commandtext);
1387 }
1388 if(command == "dxirc")
1389 {
1390 return commandDxirc();
1391 }
1392 if(command == "egg")
1393 {
1394 return commandEgg();
1395 }
1396 if(command == "exec")
1397 {
1398 return commandExec(commandtext);
1399 }
1400 if(command == "help")
1401 {
1402 return commandHelp(commandtext);
1403 }
1404 if(command == "ignore")
1405 {
1406 return commandIgnore(commandtext);
1407 }
1408 if(command == "invite")
1409 {
1410 return commandInvite(commandtext);
1411 }
1412 if(command == "join")
1413 {
1414 return commandJoin(commandtext);
1415 }
1416 if(command == "kick")
1417 {
1418 return commandKick(commandtext);
1419 }
1420 if(command == "kill")
1421 {
1422 return commandKill(commandtext);
1423 }
1424 if(command == "list")
1425 {
1426 return commandList(commandtext);
1427 }
1428 if(command == "log")
1429 {
1430 return commandLog(commandtext);
1431 }
1432 if(command == "lua")
1433 {
1434 return commandLua(commandtext);
1435 }
1436 if(command == "me")
1437 {
1438 return commandMe(commandtext);
1439 }
1440 if(command == "mode")
1441 {
1442 return commandMode(commandtext);
1443 }
1444 if(command == "msg")
1445 {
1446 return commandMsg(commandtext);
1447 }
1448 if(command == "names")
1449 {
1450 return commandNames(commandtext);
1451 }
1452 if(command == "nick")
1453 {
1454 return commandNick(commandtext);
1455 }
1456 if(command == "notice")
1457 {
1458 return commandNotice(commandtext);
1459 }
1460 if(command == "op")
1461 {
1462 return commandOp(commandtext);
1463 }
1464 if(command == "oper")
1465 {
1466 return commandOper(commandtext);
1467 }
1468 if(command == "part")
1469 {
1470 return commandPart(commandtext);
1471 }
1472 if(command == "query")
1473 {
1474 return commandQuery(commandtext);
1475 }
1476 if(command == "quit")
1477 {
1478 return commandQuit();
1479 }
1480 if(command == "quote")
1481 {
1482 return commandQuote(commandtext);
1483 }
1484 if(command == "say")
1485 {
1486 return commandSay(commandtext);
1487 }
1488 if(command == "stats")
1489 {
1490 return commandStats(commandtext);
1491 }
1492 if(command == "tetris")
1493 {
1494 return commandTetris();
1495 }
1496 if(command == "time")
1497 {
1498 return commandTime();
1499 }
1500 if(command == "topic")
1501 {
1502 return commandTopic(commandtext);
1503 }
1504 if(command == "voice")
1505 {
1506 return commandVoice(commandtext);
1507 }
1508 if(command == "wallops")
1509 {
1510 return commandWallops(commandtext);
1511 }
1512 if(command == "who")
1513 {
1514 return commandWho(commandtext);
1515 }
1516 if(command == "whoami")
1517 {
1518 return commandWhoami();
1519 }
1520 if(command == "whois")
1521 {
1522 return commandWhois(commandtext);
1523 }
1524 if(command == "whowas")
1525 {
1526 return commandWhowas(commandtext);
1527 }
1528 appendIrcStyledText(FXStringFormat(_("Unknown command '%s', type /commands for available commands"), command.text()), 4, FXSystem::now(), FALSE, FALSE);
1529 return FALSE;
1530 }
1531 else
1532 {
1533 if(command.empty() && m_type != SERVER && !commandtext.empty() && m_engine->getConnected())
1534 {
1535 if(commandtext.length() > m_maxLen-10-getText().length())
1536 {
1537 dxStringArray messages = cutText(commandtext, m_maxLen-10-getText().length());
1538 FXbool result = TRUE;
1539 for(FXint i=0; i<messages.no(); i++)
1540 {
1541 appendMyMsg(messages[i], FXSystem::now());
1542 IrcEvent ev;
1543 ev.eventType = IRC_PRIVMSG;
1544 ev.param1 = getNickName();
1545 ev.param2 = getText();
1546 ev.param3 = messages[i];
1547 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
1548 result = m_engine->sendMsg(getText(), messages[i]) &result;
1549 }
1550 return result;
1551 }
1552 else
1553 {
1554 appendMyMsg(commandtext, FXSystem::now());
1555 IrcEvent ev;
1556 ev.eventType = IRC_PRIVMSG;
1557 ev.param1 = getNickName();
1558 ev.param2 = getText();
1559 ev.param3 = commandtext;
1560 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
1561 return m_engine->sendMsg(getText(), commandtext);
1562 }
1563 }
1564 if(!m_engine->getConnected())
1565 {
1566 appendIrcStyledText(_("You aren't connected"), 4, FXSystem::now(), FALSE, FALSE);
1567 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_CDIALOG), NULL);
1568 return TRUE;
1569 }
1570 return FALSE;
1571 }
1572 return FALSE;
1573 }
1574
showHelp(FXString command)1575 FXbool IrcTabItem::showHelp(FXString command)
1576 {
1577 if(dxUtils.isScriptCommand(command))
1578 {
1579 appendIrcStyledText(dxUtils.getHelpText(command), 3, FXSystem::now(), FALSE, FALSE);
1580 return TRUE;
1581 }
1582 if(command == "admin")
1583 {
1584 appendIrcStyledText(_("ADMIN [server], finds information about administrator for current server or [server]."), 3, FXSystem::now(), FALSE, FALSE);
1585 return TRUE;
1586 }
1587 if(command == "away")
1588 {
1589 appendIrcStyledText(_("AWAY [message], sets away status."), 3, FXSystem::now(), FALSE, FALSE);
1590 return TRUE;
1591 }
1592 if(command == "banlist")
1593 {
1594 appendIrcStyledText(_("BANLIST <channel>, shows banlist for channel."), 3, FXSystem::now(), FALSE, FALSE);
1595 return TRUE;
1596 }
1597 if(command == "boats")
1598 {
1599 appendIrcStyledText(_("BOATS <nick>, invites someone to a boats game."), 3, FXSystem::now(), FALSE, FALSE);
1600 return TRUE;
1601 }
1602 if(command == "commands")
1603 {
1604 appendIrcStyledText(_("COMMANDS, shows available commands"), 3, FXSystem::now(), FALSE, FALSE);
1605 return TRUE;
1606 }
1607 if(command == "connect")
1608 {
1609 appendIrcStyledText(_("CONNECT <server> [port] [nick] [password] [realname] [channels], connects for given server."), 3, FXSystem::now(), FALSE, FALSE);
1610 return TRUE;
1611 }
1612 if(command == "ctcp")
1613 {
1614 appendIrcStyledText(_("CTCP <nick> <message>, sends a CTCP message to a user."), 3, FXSystem::now(), FALSE, FALSE);
1615 return TRUE;
1616 }
1617 if(command == "cycle")
1618 {
1619 appendIrcStyledText(_("CYCLE <channel> [message], leaves and join channel."), 3, FXSystem::now(), FALSE, FALSE);
1620 return TRUE;
1621 }
1622 if(command == "dcc")
1623 {
1624 appendIrcStyledText(_("DCC chat <nick>, starts DCC chat."), 3, FXSystem::now(), FALSE, FALSE);
1625 appendIrcStyledText(_("DCC send <nick> <filename>, sends file over DCC."), 3, FXSystem::now(), FALSE, FALSE);
1626 appendIrcStyledText(_("DCC psend <nick> <filename>, sends file passive over DCC."), 3, FXSystem::now(), FALSE, FALSE);
1627 appendIrcStyledText(_("More information about passive DCC on http://en.wikipedia.org/wiki/Direct_Client-to-Client#Passive_DCC"), 3, FXSystem::now(), FALSE, FALSE);
1628 return TRUE;
1629 }
1630 if(command == "deop")
1631 {
1632 appendIrcStyledText(_("DEOP <channel> <nicks>, removes operator status from one or more nicks."), 3, FXSystem::now(), FALSE, FALSE);
1633 return TRUE;
1634 }
1635 if(command == "devoice")
1636 {
1637 appendIrcStyledText(_("DEVOICE <channel> <nicks>, removes voice from one or more nicks."), 3, FXSystem::now(), FALSE, FALSE);
1638 return TRUE;
1639 }
1640 if(command == "disconnect")
1641 {
1642 appendIrcStyledText(_("DISCONNECT [reason], leaves server."), 3, FXSystem::now(), FALSE, FALSE);
1643 return TRUE;
1644 }
1645 #ifndef WIN32
1646 if(command == "exec")
1647 {
1648 appendIrcStyledText(_("EXEC [-o|-c] <command>, executes command, -o sends output to channel/query, -c closes running command."), 3, FXSystem::now(), FALSE, FALSE);
1649 return TRUE;
1650 }
1651 #endif
1652 if(command == "help")
1653 {
1654 appendIrcStyledText(_("HELP <command>, shows help for command."), 3, FXSystem::now(), FALSE, FALSE);
1655 return TRUE;
1656 }
1657 if(command == "ignore")
1658 {
1659 appendIrcStyledText(_("IGNORE list, shows list ignored commands and users."), 3, FXSystem::now(), FALSE, FALSE);
1660 appendIrcStyledText(_("IGNORE addcmd <command>, adds command to ignored commands."), 3, FXSystem::now(), FALSE, FALSE);
1661 appendIrcStyledText(_("IGNORE rmcmd <command>, removes command from ignored commands."), 3, FXSystem::now(), FALSE, FALSE);
1662 appendIrcStyledText(_("IGNORE addusr <user> [channel] [server], adds user to ignored users."), 3, FXSystem::now(), FALSE, FALSE);
1663 appendIrcStyledText(_("IGNORE rmusr <user>, removes user from ignored users."), 3, FXSystem::now(), FALSE, FALSE);
1664 return TRUE;
1665 }
1666 if(command == "invite")
1667 {
1668 appendIrcStyledText(_("INVITE <nick> <channel>, invites someone to a channel."), 3, FXSystem::now(), FALSE, FALSE);
1669 return TRUE;
1670 }
1671 if(command == "join")
1672 {
1673 appendIrcStyledText(_("JOIN <channel>, joins a channel."), 3, FXSystem::now(), FALSE, FALSE);
1674 return TRUE;
1675 }
1676 if(command == "kick")
1677 {
1678 appendIrcStyledText(_("KICK <channel> <nick>, kicks a user from a channel."), 3, FXSystem::now(), FALSE, FALSE);
1679 return TRUE;
1680 }
1681 if(command == "kill")
1682 {
1683 appendIrcStyledText(_("KILL <user> [reason], kills a user from the network."), 3, FXSystem::now(), FALSE, FALSE);
1684 return TRUE;
1685 }
1686 if(command == "list")
1687 {
1688 appendIrcStyledText(_("LIST [channel], lists channels and their topics."), 3, FXSystem::now(), FALSE, FALSE);
1689 return TRUE;
1690 }
1691 if(command == "log")
1692 {
1693 appendIrcStyledText(_("LOG list, shows list of log files for current tab"), 3, FXSystem::now(), FALSE, FALSE);
1694 appendIrcStyledText(_("LOG show [date], shows last log file for current tab, if date is empty"), 3, FXSystem::now(), FALSE, FALSE);
1695 appendIrcStyledText(_("else file for given date"), 3, FXSystem::now(), FALSE, FALSE);
1696 appendIrcStyledText(_("date example: 2011-01-31"), 3, FXSystem::now(), FALSE, FALSE);
1697 return TRUE;
1698 }
1699 #ifdef HAVE_LUA
1700 if(command == "lua")
1701 {
1702 appendIrcStyledText(_("LUA help, shows help for lua scripting."), 3, FXSystem::now(), FALSE, FALSE);
1703 appendIrcStyledText(_("LUA load <path>, loads script."), 3, FXSystem::now(), FALSE, FALSE);
1704 appendIrcStyledText(_("Example: /lua load /home/dvx/test.lua"), 3, FXSystem::now(), FALSE, FALSE);
1705 appendIrcStyledText(_("LUA unload <name>, unloads script."), 3, FXSystem::now(), FALSE, FALSE);
1706 appendIrcStyledText(_("Example: /lua unload test"), 3, FXSystem::now(), FALSE, FALSE);
1707 appendIrcStyledText(_("LUA list, shows list of loaded scripts"), 3, FXSystem::now(), FALSE, FALSE);
1708 return TRUE;
1709 }
1710 #else
1711 if(command == "lua")
1712 {
1713 appendIrcStyledText(_("dxirc is compiled without support for Lua scripting"), 4, FXSystem::now(), FALSE, FALSE);
1714 return TRUE;
1715 }
1716 #endif
1717 if(command == "me")
1718 {
1719 appendIrcStyledText(_("ME <to> <message>, sends the action."), 3, FXSystem::now(), FALSE, FALSE);
1720 return TRUE;
1721 }
1722 if(command == "mode")
1723 {
1724 appendIrcStyledText(_("MODE <channel> <modes>, sets modes for a channel."), 3, FXSystem::now(), FALSE, FALSE);
1725 return TRUE;
1726 }
1727 if(command == "msg")
1728 {
1729 appendIrcStyledText(_("MSG <nick/channel> <message>, sends a normal message."), 3, FXSystem::now(), FALSE, FALSE);
1730 return TRUE;
1731 }
1732 if(command == "names")
1733 {
1734 appendIrcStyledText(_("NAMES <channel>, for nicks on a channel."), 3, FXSystem::now(), FALSE, FALSE);
1735 return TRUE;
1736 }
1737 if(command == "nick")
1738 {
1739 appendIrcStyledText(_("NICK <nick>, changes nick."), 3, FXSystem::now(), FALSE, FALSE);
1740 return TRUE;
1741 }
1742 if(command == "notice")
1743 {
1744 appendIrcStyledText(_("NOTICE <nick/channel> <message>, sends a notice."), 3, FXSystem::now(), FALSE, FALSE);
1745 return TRUE;
1746 }
1747 if(command == "op")
1748 {
1749 appendIrcStyledText(_("OP <channel> <nicks>, gives operator status for one or more nicks."), 3, FXSystem::now(), FALSE, FALSE);
1750 return TRUE;
1751 }
1752 if(command == "oper")
1753 {
1754 appendIrcStyledText(_("OPER <login> <password>, oper up."), 3, FXSystem::now(), FALSE, FALSE);
1755 return TRUE;
1756 }
1757 if(command == "part")
1758 {
1759 appendIrcStyledText(_("PART <channel> [reason], leaves channel."), 3, FXSystem::now(), FALSE, FALSE);
1760 return TRUE;
1761 }
1762 if(command == "query")
1763 {
1764 appendIrcStyledText(_("QUERY <nick>, opens query with nick."), 3, FXSystem::now(), FALSE, FALSE);
1765 return TRUE;
1766 }
1767 if(command == "quit")
1768 {
1769 appendIrcStyledText(_("QUIT, closes application."), 3, FXSystem::now(), FALSE, FALSE);
1770 return TRUE;
1771 }
1772 if(command == "quote")
1773 {
1774 appendIrcStyledText(_("QUOTE [text], sends text to server."), 3, FXSystem::now(), FALSE, FALSE);
1775 return TRUE;
1776 }
1777 if(command == "say")
1778 {
1779 appendIrcStyledText(_("SAY [text], sends text to current tab."), 3, FXSystem::now(), FALSE, FALSE);
1780 return TRUE;
1781 }
1782 if(command == "stats")
1783 {
1784 appendIrcStyledText(_("STATS <type>, shows some irc server usage statistics. Available types vary slightly per server; some common ones are:"), 3, FXSystem::now(), FALSE, FALSE);
1785 appendIrcStyledText(_("c - shows C and N lines for a given server. These are the names of the servers that are allowed to connect."), 3, FXSystem::now(), FALSE, FALSE);
1786 appendIrcStyledText(_("h - shows H and L lines for a given server (Hubs and Leaves)."), 3, FXSystem::now(), FALSE, FALSE);
1787 appendIrcStyledText(_("k - show K lines for a server. This shows who is not allowed to connect and possibly at what time they are not allowed to connect."), 3, FXSystem::now(), FALSE, FALSE);
1788 appendIrcStyledText(_("i - shows I lines. This is who CAN connect to a server."), 3, FXSystem::now(), FALSE, FALSE);
1789 appendIrcStyledText(_("l - shows information about amount of information passed to servers and users."), 3, FXSystem::now(), FALSE, FALSE);
1790 appendIrcStyledText(_("m - shows a count for the number of times the various commands have been used since the server was booted."), 3, FXSystem::now(), FALSE, FALSE);
1791 appendIrcStyledText(_("o - shows the list of authorized operators on the server."), 3, FXSystem::now(), FALSE, FALSE);
1792 appendIrcStyledText(_("p - shows online operators and their idle times."), 3, FXSystem::now(), FALSE, FALSE);
1793 appendIrcStyledText(_("u - shows the uptime for a server."), 3, FXSystem::now(), FALSE, FALSE);
1794 appendIrcStyledText(_("y - shows Y lines, which lists the various connection classes for a given server."), 3, FXSystem::now(), FALSE, FALSE);
1795
1796 return TRUE;
1797 }
1798 if(command == "tetris")
1799 {
1800 appendIrcStyledText(_("TETRIS, start small easteregg."), 3, FXSystem::now(), FALSE, FALSE);
1801 appendIrcStyledText(_("Keys for playing:"), 3, FXSystem::now(), FALSE, FALSE);
1802 appendIrcStyledText(_("n .. new game"), 3, FXSystem::now(), FALSE, FALSE);
1803 appendIrcStyledText(_("p .. pause game"), 3, FXSystem::now(), FALSE, FALSE);
1804 appendIrcStyledText(_("i .. rotate piece"), 3, FXSystem::now(), FALSE, FALSE);
1805 appendIrcStyledText(_("l .. move piece right"), 3, FXSystem::now(), FALSE, FALSE);
1806 appendIrcStyledText(_("k .. drop piece"), 3, FXSystem::now(), FALSE, FALSE);
1807 appendIrcStyledText(_("j .. move piece left"), 3, FXSystem::now(), FALSE, FALSE);
1808 return TRUE;
1809 }
1810 if(command == "time")
1811 {
1812 appendIrcStyledText(_("TIME, displays the time of day, local to server."), 3, FXSystem::now(), FALSE, FALSE);
1813 return TRUE;
1814 }
1815 if(command == "topic")
1816 {
1817 appendIrcStyledText(_("TOPIC [topic], sets or shows topic."), 3, FXSystem::now(), FALSE, FALSE);
1818 return TRUE;
1819 }
1820 if(command == "voice")
1821 {
1822 appendIrcStyledText(_("VOICE <channel> <nicks>, gives voice for one or more nicks."), 3, FXSystem::now(), FALSE, FALSE);
1823 return TRUE;
1824 }
1825 if(command == "wallops")
1826 {
1827 appendIrcStyledText(_("WALLOPS <message>, sends wallop message."), 3, FXSystem::now(), FALSE, FALSE);
1828 return TRUE;
1829 }
1830 if(command == "who")
1831 {
1832 appendIrcStyledText(_("WHO <mask> [o], searchs for mask on network, if o is supplied, only search for opers."), 3, FXSystem::now(), FALSE, FALSE);
1833 return TRUE;
1834 }
1835 if(command == "whoami")
1836 {
1837 appendIrcStyledText(_("WHOAMI, whois about you."), 3, FXSystem::now(), FALSE, FALSE);
1838 return TRUE;
1839 }
1840 if(command == "whois")
1841 {
1842 appendIrcStyledText(_("WHOIS <nick>, whois nick."), 3, FXSystem::now(), FALSE, FALSE);
1843 return TRUE;
1844 }
1845 if(command == "whowas")
1846 {
1847 appendIrcStyledText(_("WHOWAS <nick>, whowas nick."), 3, FXSystem::now(), FALSE, FALSE);
1848 return TRUE;
1849 }
1850 if(!dxUtils.getAlias(command[0] == '/' ? command:"/"+command).empty())
1851 {
1852 appendIrcStyledText(FXStringFormat("%s: %s", command.upper().text(), dxUtils.getAlias(command[0] == '/' ? command:"/"+command).text()), 3, FXSystem::now(), FALSE, FALSE);
1853 return TRUE;
1854 }
1855 if(command.empty()) appendIrcStyledText(_("Command is empty, type /commands for available commands"), 4, FXSystem::now(), FALSE, FALSE);
1856 else appendIrcStyledText(FXStringFormat(_("Unknown command '%s', type /commands for available commands"), command.text()), 4, FXSystem::now(), FALSE, FALSE);
1857 return FALSE;
1858 }
1859
onKeyPress(FXObject *,FXSelector,void * ptr)1860 long IrcTabItem::onKeyPress(FXObject *, FXSelector, void *ptr)
1861 {
1862 if(m_commandline->hasFocus())
1863 {
1864 FXString line = m_commandline->getText();
1865 FXString key = dxutils::getKeybinding((FXEvent*)ptr);
1866 if(comparecase(key, "Tab")==0) //tab completion
1867 {
1868 if(comparecase(line.before(' '), "/help") == 0 && !line.after(' ').empty())
1869 {
1870 completeHelpCommand();
1871 return 1;
1872 }
1873 if(line[0] == '/' && line.after(' ').empty())
1874 {
1875 for(FXint i = 0; i < dxUtils.commandsNo(); i++)
1876 {
1877 if(comparecase(line.after('/').before(' '), dxUtils.commandsAt(i)) == 0)
1878 {
1879 if((i+1) < dxUtils.commandsNo()) m_commandline->setText("/"+dxUtils.commandsAt(++i)+" ");
1880 else m_commandline->setText("/"+dxUtils.commandsAt(0)+" ");
1881 break;
1882 }
1883 else if(comparecase(line.after('/'), dxUtils.commandsAt(i).left(line.after('/').length())) == 0)
1884 {
1885 m_commandline->setText("/"+dxUtils.commandsAt(i)+" ");
1886 break;
1887 }
1888 }
1889 return 1;
1890 }
1891 if(line[0] != '/' && line.after(' ').empty() && m_type == CHANNEL)
1892 {
1893 if(line.empty())
1894 {
1895 m_commandline->setText(getNick(0)+preferences.m_nickCompletionChar+" ");
1896 return 1;
1897 }
1898 for(FXint j = 0; j < m_users->getNumItems() ; j++)
1899 {
1900 if(comparecase(line, getNick(j).left(line.length())) == 0)
1901 {
1902 m_commandline->setText(getNick(j)+preferences.m_nickCompletionChar+" ");
1903 break;
1904 }
1905 else if(comparecase(line.section(preferences.m_nickCompletionChar, 0, 1), getNick(j)) == 0)
1906 {
1907 if((j+1) < m_users->getNumItems()) m_commandline->setText(getNick(++j)+preferences.m_nickCompletionChar+" ");
1908 else m_commandline->setText(getNick(0)+preferences.m_nickCompletionChar+" ");
1909 break;
1910 }
1911 }
1912 return 1;
1913 }
1914 if(line.find(' ') != -1 && m_type == CHANNEL)
1915 {
1916 FXint curpos;
1917 line[m_commandline->getCursorPos()] == ' ' ? curpos = m_commandline->getCursorPos()-1 : curpos = m_commandline->getCursorPos();
1918 FXint pos = line.rfind(' ', curpos)+1;
1919 FXint n = line.find(' ', curpos)>0 ? line.find(' ', curpos)-pos : line.length()-pos;
1920 FXString toCompletion = line.mid(pos, n);
1921 for(FXint j = 0; j < m_users->getNumItems(); j++)
1922 {
1923 if(comparecase(toCompletion, getNick(j)) == 0)
1924 {
1925 if((j+1) < m_users->getNumItems())
1926 {
1927 m_commandline->setText(line.replace(pos, n, getNick(j+1)));
1928 m_commandline->setCursorPos(pos+getNick(j+1).length());
1929 }
1930 else
1931 {
1932 m_commandline->setText(line.replace(pos, n, getNick(0)));
1933 m_commandline->setCursorPos(pos+getNick(0).length());
1934 }
1935 break;
1936 }
1937 else if(comparecase(toCompletion, getNick(j).left(toCompletion.length())) == 0)
1938 {
1939 m_commandline->setText(line.replace(pos, n, getNick(j)));
1940 m_commandline->setCursorPos(pos+getNick(j).length());
1941 break;
1942 }
1943 }
1944 return 1;
1945 }
1946 return 1;
1947 }
1948 else if(comparecase(key, "Up")==0) //append history command backward
1949 {
1950 if(m_currentPosition!=-1 && m_currentPosition<m_commandsHistory.no())
1951 {
1952 if(!line.empty() && line!=m_commandsHistory[m_currentPosition])
1953 {
1954 m_commandsHistory.append(line);
1955 if(m_commandsHistory.no() > m_historyMax)
1956 m_commandsHistory.erase(0);
1957 m_currentPosition = m_commandsHistory.no()-1;
1958 }
1959 if(m_currentPosition > 0 && !line.empty())
1960 --m_currentPosition;
1961 m_commandline->setText(m_commandsHistory[m_currentPosition]);
1962 }
1963 return 1;
1964 }
1965 else if(comparecase(key, "Down")==0) //append history command forward
1966 {
1967 if(m_currentPosition!=-1 && m_currentPosition<m_commandsHistory.no())
1968 {
1969 if(!line.empty() && line!=m_commandsHistory[m_currentPosition])
1970 {
1971 m_commandsHistory.append(line);
1972 if(m_commandsHistory.no() > m_historyMax)
1973 m_commandsHistory.erase(0);
1974 m_currentPosition = m_commandsHistory.no()-1;
1975 }
1976 if(m_currentPosition < m_commandsHistory.no()-1)
1977 {
1978 ++m_currentPosition;
1979 m_commandline->setText(m_commandsHistory[m_currentPosition]);
1980 }
1981 else
1982 m_commandline->setText("");
1983 }
1984 return 1;
1985 }
1986 else if(comparecase(key, preferences.getBinding("colorControlChar"))==0) //color control char
1987 {
1988 FXint pos = m_commandline->getCursorPos();
1989 m_commandline->setText(line.insert(pos, "^C")); //color
1990 m_commandline->setCursorPos(pos+2);
1991 return 1;
1992 }
1993 else if(comparecase(key, preferences.getBinding("boldControlChar"))==0) //bold control char
1994 {
1995 FXint pos = m_commandline->getCursorPos();
1996 m_commandline->setText(line.insert(pos, "^B")); //bold
1997 m_commandline->setCursorPos(pos+2);
1998 return 1;
1999 }
2000 else if(comparecase(key, preferences.getBinding("underlineControlChar"))==0) //underline control char
2001 {
2002 FXint pos = m_commandline->getCursorPos();
2003 m_commandline->setText(line.insert(pos, "^_")); //underline
2004 m_commandline->setCursorPos(pos+2);
2005 return 1;
2006 }
2007 else if(comparecase(key, preferences.getBinding("reverseControlChar"))==0) //reverse control char
2008 {
2009 FXint pos = m_commandline->getCursorPos();
2010 m_commandline->setText(line.insert(pos, "^V")); //reverse
2011 m_commandline->setCursorPos(pos+2);
2012 return 1;
2013 }
2014 else if(comparecase(key, preferences.getBinding("resetControlChar"))==0) //reset control char
2015 {
2016 FXint pos = m_commandline->getCursorPos();
2017 m_commandline->setText(line.insert(m_commandline->getCursorPos(), "^O")); //reset
2018 m_commandline->setCursorPos(pos+2);
2019 return 1;
2020 }
2021 }
2022 return 0;
2023 }
2024
2025 //Check is this tab right for server message (e.g. not for IRC_SERVERREPLY)
isRightForServerMsg()2026 FXbool IrcTabItem::isRightForServerMsg()
2027 {
2028 //Check if current tab is in server targets
2029 if(m_engine->findTarget(m_parent->childAtIndex(m_parent->getCurrent()*2)))
2030 {
2031 return m_parent->indexOfChild(this) == m_parent->getCurrent()*2;
2032 }
2033 else
2034 {
2035 FXint indexOfThis = m_parent->indexOfChild(this);
2036 for(FXint i = 0; i<m_parent->numChildren(); i+=2)
2037 {
2038 if(m_engine->findTarget(m_parent->childAtIndex(i)))
2039 {
2040 if(i == indexOfThis) return TRUE;
2041 else return FALSE;
2042 }
2043 }
2044 }
2045 return FALSE;
2046 }
2047
isCommandIgnored(const FXString & command)2048 FXbool IrcTabItem::isCommandIgnored(const FXString &command)
2049 {
2050 if(preferences.m_ignoreCommandsList.contains(command)) return TRUE;
2051 return FALSE;
2052 }
2053
addUser(const FXString & user,UserMode mode)2054 void IrcTabItem::addUser(const FXString& user, UserMode mode)
2055 {
2056 if(mode == ADMIN && m_users->findItem(user) == -1)
2057 {
2058 NickListItem *item = new NickListItem(user, m_users, mode, m_useNickIcon?ICO_IRCADMIN:NULL);
2059 m_users->appendItem(item);
2060 m_numberUsers++;
2061 m_users->sortItems();
2062 return;
2063 }
2064 if(mode == OWNER && m_users->findItem(user) == -1)
2065 {
2066 NickListItem *item = new NickListItem(user, m_users, mode, m_useNickIcon?ICO_IRCOWNER:NULL);
2067 m_users->appendItem(item);
2068 m_numberUsers++;
2069 m_users->sortItems();
2070 return;
2071 }
2072 if(mode == OP && m_users->findItem(user) == -1)
2073 {
2074 NickListItem *item = new NickListItem(user, m_users, mode, m_useNickIcon?ICO_IRCOP:NULL);
2075 m_users->appendItem(item);
2076 m_numberUsers++;
2077 m_users->sortItems();
2078 return;
2079 }
2080 if(mode == VOICE && m_users->findItem(user) == -1)
2081 {
2082 NickListItem *item = new NickListItem(user, m_users, mode, m_useNickIcon?ICO_IRCVOICE:NULL);
2083 m_users->appendItem(item);
2084 m_numberUsers++;
2085 m_users->sortItems();
2086 return;
2087 }
2088 if(mode == HALFOP && m_users->findItem(user) == -1)
2089 {
2090 NickListItem *item = new NickListItem(user, m_users, mode, m_useNickIcon?ICO_IRCHALFOP:NULL);
2091 m_users->appendItem(item);
2092 m_numberUsers++;
2093 m_users->sortItems();
2094 return;
2095 }
2096 if(mode == NONE && m_users->findItem(user) == -1)
2097 {
2098 NickListItem *item = new NickListItem(user, m_users, mode, m_useNickIcon?ICO_IRCNORMAL:NULL);
2099 m_users->appendItem(item);
2100 m_numberUsers++;
2101 m_users->sortItems();
2102 return;
2103 }
2104 }
2105
removeUser(const FXString & user)2106 void IrcTabItem::removeUser(const FXString& user)
2107 {
2108 if(m_users->findItem(user) != -1)
2109 {
2110 m_users->removeItem(m_users->findItem(user));
2111 }
2112 m_numberUsers--;
2113 m_users->sortItems();
2114 }
2115
changeNickUser(const FXString & nick,const FXString & newnick)2116 void IrcTabItem::changeNickUser(const FXString& nick, const FXString& newnick)
2117 {
2118 FXint i = m_users->findItem(nick);
2119 if(i != -1)
2120 {
2121 m_users->recalc();
2122 m_users->getItem(i)->setText(newnick);
2123 m_users->sortItems();
2124 }
2125 }
2126
setUserMode(const FXString & nick,UserMode mode)2127 void IrcTabItem::setUserMode(const FXString& nick, UserMode mode)
2128 {
2129 FXint i = m_users->findItem(nick);
2130 if(i != -1)
2131 {
2132 ((NickListItem*)m_users->getItem(i))->setUserMode(mode);
2133 }
2134 }
2135
getUserMode(const FXchar mode)2136 UserMode IrcTabItem::getUserMode(const FXchar mode)
2137 {
2138 if(mode == m_engine->getAdminPrefix())
2139 return ADMIN;
2140 if(mode == m_engine->getOwnerPrefix())
2141 return OWNER;
2142 if(mode == m_engine->getOpPrefix())
2143 return OP;
2144 if(mode == m_engine->getHalfopPrefix())
2145 return HALFOP;
2146 if(mode == m_engine->getVoicePrefix())
2147 return VOICE;
2148 return NONE;
2149 }
2150
2151 //Clear theme icons, usefull for nick icon theme change
clearNickIcons()2152 void IrcTabItem::clearNickIcons()
2153 {
2154 for(FXint i=0; i<m_users->getNumItems(); i++)
2155 {
2156 ((NickListItem*)m_users->getItem(i))->clearIcon();
2157 }
2158 }
2159
2160 //Apply new theme icon, usefull for nick icon theme change
recreateNickIcons(FXbool useNickIcon)2161 void IrcTabItem::recreateNickIcons(FXbool useNickIcon)
2162 {
2163 m_useNickIcon = useNickIcon;
2164 if(m_useNickIcon)
2165 {
2166 for(FXint i=0; i<m_users->getNumItems(); i++)
2167 {
2168 ((NickListItem*)m_users->getItem(i))->restoreIcon();
2169 }
2170 }
2171 }
2172
2173 //return names
getNicks()2174 dxStringArray IrcTabItem::getNicks()
2175 {
2176 dxStringArray names;
2177 for(FXint i=0; i<m_users->getNumItems(); i++)
2178 names.append(m_users->getItemText(i));
2179 return names;
2180 }
2181
hasNick(const FXString & nick)2182 FXbool IrcTabItem::hasNick(const FXString& nick)
2183 {
2184 return m_users->findItem(nick) != -1;
2185 }
2186
onIrcEvent(FXObject *,FXSelector,void * data)2187 long IrcTabItem::onIrcEvent(FXObject *, FXSelector, void *data)
2188 {
2189 IrcEvent ev = *(IrcEvent *)data;
2190 if(m_loadLog)
2191 {
2192 m_storedEvents.append(ev);
2193 return 1;
2194 }
2195 parseIrcEvent(ev);
2196 return 1;
2197 }
2198
parseIrcEvent(IrcEvent & ev)2199 void IrcTabItem::parseIrcEvent(IrcEvent &ev)
2200 {
2201 if(ev.eventType == IRC_PRIVMSG)
2202 {
2203 onIrcPrivmsg(ev);
2204 }
2205 else if(ev.eventType == IRC_ACTION)
2206 {
2207 onIrcAction(ev);
2208 }
2209 else if(ev.eventType == IRC_CTCPREPLY)
2210 {
2211 onIrcCtpcReply(ev);
2212 }
2213 else if(ev.eventType == IRC_CTCPREQUEST)
2214 {
2215 onIrcCtcpRequest(ev);
2216 }
2217 else if(ev.eventType == IRC_JOIN)
2218 {
2219 onIrcJoin(ev);
2220 }
2221 else if(ev.eventType == IRC_QUIT)
2222 {
2223 onIrcQuit(ev);
2224 }
2225 else if(ev.eventType == IRC_PART)
2226 {
2227 onIrcPart(ev);
2228 }
2229 else if(ev.eventType == IRC_CHNOTICE)
2230 {
2231 onIrcChnotice(ev);
2232 }
2233 else if(ev.eventType == IRC_NOTICE)
2234 {
2235 onIrcNotice(ev);
2236 }
2237 else if(ev.eventType == IRC_NICK)
2238 {
2239 onIrcNick(ev);
2240 }
2241 else if(ev.eventType == IRC_TOPIC)
2242 {
2243 onIrcTopic(ev);
2244 }
2245 else if(ev.eventType == IRC_KICK)
2246 {
2247 onIrcKick(ev);
2248 }
2249 else if(ev.eventType == IRC_MODE)
2250 {
2251 onIrcMode(ev);
2252 }
2253 else if(ev.eventType == IRC_UMODE)
2254 {
2255 onIrcUmode(ev);
2256 }
2257 else if(ev.eventType == IRC_CHMODE)
2258 {
2259 onIrcChmode(ev);
2260 }
2261 else if(ev.eventType == IRC_SERVERREPLY)
2262 {
2263 onIrcServerReply(ev);
2264 }
2265 else if(ev.eventType == IRC_CONNECT)
2266 {
2267 onIrcConnect(ev);
2268 }
2269 else if(ev.eventType == IRC_ERROR)
2270 {
2271 onIrcError(ev);
2272 }
2273 else if(ev.eventType == IRC_SERVERERROR)
2274 {
2275 onIrcServerError(ev);
2276 }
2277 else if(ev.eventType == IRC_DISCONNECT)
2278 {
2279 onIrcDisconnect(ev);
2280 }
2281 else if(ev.eventType == IRC_RECONNECT)
2282 {
2283 onIrcReconnect(ev);
2284 }
2285 else if(ev.eventType == IRC_RECONNECTALL)
2286 {
2287 onIrcReconnectAll(ev);
2288 }
2289 else if(ev.eventType == IRC_UNKNOWN)
2290 {
2291 onIrcUnknown(ev);
2292 }
2293 else if(ev.eventType == IRC_301)
2294 {
2295 onIrc301(ev);
2296 }
2297 else if(ev.eventType == IRC_305)
2298 {
2299 onIrc305(ev);
2300 }
2301 else if(ev.eventType == IRC_306)
2302 {
2303 onIrc306(ev);
2304 }
2305 else if(ev.eventType == IRC_331 || ev.eventType == IRC_332 || ev.eventType == IRC_333)
2306 {
2307 onIrc331332333(ev);
2308 }
2309 else if(ev.eventType == IRC_353)
2310 {
2311 onIrc353(ev);
2312 }
2313 else if(ev.eventType == IRC_366)
2314 {
2315 onIrc366(ev);
2316 }
2317 else if(ev.eventType == IRC_372)
2318 {
2319 onIrc372(ev);
2320 }
2321 else if(ev.eventType == IRC_AWAY)
2322 {
2323 onIrcAway(ev);
2324 }
2325 else if(ev.eventType == IRC_ENDMOTD)
2326 {
2327 onIrcEndMotd();
2328 }
2329 }
2330
2331 //handle IrcEvent IRC_PRIVMSG
onIrcPrivmsg(IrcEvent & ev)2332 void IrcTabItem::onIrcPrivmsg(IrcEvent &ev)
2333 {
2334 if((comparecase(ev.param2, getText()) == 0 && m_type == CHANNEL) || (ev.param1 == getText() && m_type == QUERY && ev.param2 == getNickName()))
2335 {
2336 FXbool needHighlight = FALSE;
2337 if(ev.param3.contains(getNickName()))
2338 needHighlight = highlightNeeded(ev.param3);
2339 if(needHighlight) appendIrcStyledText(ev.param1+": "+ev.param3, 8, ev.time);
2340 else appendIrcNickText(ev.param1, ev.param3, getNickStyle(ev.param1), ev.time);
2341 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this))
2342 {
2343 if(needHighlight)
2344 {
2345 this->setTextColor(preferences.m_highlightColor);
2346 if(m_type == CHANNEL) this->setIcon(ICO_CHANNELNEWMSG);
2347 }
2348 else this->setTextColor(preferences.m_unreadColor);
2349 if(m_type == QUERY) this->setIcon(ICO_QUERYNEWMSG);
2350 }
2351 if((m_type == CHANNEL && needHighlight) || m_type == QUERY)
2352 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_NEWMSG), NULL);
2353 }
2354 }
2355
2356 //handle IrcEvent IRC_ACTION
onIrcAction(IrcEvent & ev)2357 void IrcTabItem::onIrcAction(IrcEvent &ev)
2358 {
2359 if((comparecase(ev.param2, getText()) == 0 && m_type == CHANNEL) || (ev.param1 == getText() && m_type == QUERY && ev.param2 == getNickName()))
2360 {
2361 if(!isCommandIgnored("me"))
2362 {
2363 FXbool needHighlight = FALSE;
2364 if(ev.param3.contains(getNickName()))
2365 needHighlight = highlightNeeded(ev.param3);
2366 appendIrcStyledText(ev.param1+" "+ev.param3, 2, ev.time);
2367 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this))
2368 {
2369 if(needHighlight)
2370 {
2371 this->setTextColor(preferences.m_highlightColor);
2372 if(m_type == CHANNEL) this->setIcon(ICO_CHANNELNEWMSG);
2373 }
2374 else this->setTextColor(preferences.m_unreadColor);
2375 if(m_type == QUERY) this->setIcon(ICO_QUERYNEWMSG);
2376 }
2377 if((m_type == CHANNEL && needHighlight) || m_type == QUERY)
2378 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_NEWMSG), NULL);
2379 }
2380 }
2381 }
2382
2383 //handle IrcEvent IRC_CTCPREPLY
onIrcCtpcReply(IrcEvent & ev)2384 void IrcTabItem::onIrcCtpcReply(IrcEvent &ev)
2385 {
2386 if(isRightForServerMsg())
2387 {
2388 if(!isCommandIgnored("ctcp"))
2389 {
2390 appendIrcStyledText(FXStringFormat(_("CTCP %s reply from %s: %s"), dxutils::getParam(ev.param2, 1, FALSE).text(), ev.param1.text(), dxutils::getParam(ev.param2, 2, TRUE).text()), 2, ev.time, FALSE, FALSE);
2391 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2392 }
2393 }
2394 }
2395
2396 //handle IrcEvent IRC_CTCPREQUEST
onIrcCtcpRequest(IrcEvent & ev)2397 void IrcTabItem::onIrcCtcpRequest(IrcEvent &ev)
2398 {
2399 if(isRightForServerMsg())
2400 {
2401 if(!isCommandIgnored("ctcp"))
2402 {
2403 appendIrcStyledText(FXStringFormat(_("CTCP %s request from %s"), ev.param2.text(), ev.param1.text()), 2, ev.time, FALSE, FALSE);
2404 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2405 }
2406 }
2407 }
2408
2409 //handle IrcEvent IRC_JOIN
onIrcJoin(IrcEvent & ev)2410 void IrcTabItem::onIrcJoin(IrcEvent &ev)
2411 {
2412 if(comparecase(ev.param2, getText()) == 0 && ev.param1 != getNickName())
2413 {
2414 if(!isCommandIgnored("join") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s has joined to %s"), ev.param1.text(), ev.param2.text()), 1, ev.time);
2415 addUser(ev.param1, NONE);
2416 }
2417 }
2418
2419 //handle IrcEvent IRC_QUIT
onIrcQuit(IrcEvent & ev)2420 void IrcTabItem::onIrcQuit(IrcEvent &ev)
2421 {
2422 if(m_type == CHANNEL && m_users->findItem(ev.param1) != -1)
2423 {
2424 IrcEvent pev;
2425 pev.eventType = IRC_PART;
2426 pev.param1 = ev.param1;
2427 pev.param2 = getText();
2428 pev.param3 = "";
2429 pev.param4 = "";
2430 pev.dccFile = DccFile();
2431 pev.time = FXSystem::now();
2432 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &pev);
2433 removeUser(ev.param1);
2434 if(ev.param2.empty())
2435 {
2436 if(!isCommandIgnored("quit") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s has quit"), ev.param1.text()), 1, ev.time);
2437 }
2438 else
2439 {
2440 if(!isCommandIgnored("quit") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s has quit (%s)"), ev.param1.text(), ev.param2.text()), 1, ev.time);
2441 }
2442 }
2443 else if(m_type == QUERY && getText() == ev.param1)
2444 {
2445 appendIrcStyledText(FXStringFormat(_("%s has quit"), ev.param1.text()), 1, ev.time, FALSE, FALSE);
2446 }
2447 }
2448
2449 //handle IrcEvent IRC_PART
onIrcPart(IrcEvent & ev)2450 void IrcTabItem::onIrcPart(IrcEvent &ev)
2451 {
2452 if(comparecase(ev.param2, getText()) == 0)
2453 {
2454 if(ev.param3.empty() && !isCommandIgnored("part") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s has parted %s"), ev.param1.text(), ev.param2.text()), 1, ev.time);
2455 else if(!isCommandIgnored("part") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s has parted %s (%s)"), ev.param1.text(), ev.param2.text(), ev.param3.text()), 1, ev.time);
2456 removeUser(ev.param1);
2457 }
2458 }
2459
2460 //handle IrcEvent IRC_CHNOTICE
onIrcChnotice(IrcEvent & ev)2461 void IrcTabItem::onIrcChnotice(IrcEvent &ev)
2462 {
2463 if(!isCommandIgnored("notice"))
2464 {
2465 FXbool tabExist = FALSE;
2466 for(FXint i = 0; i<m_parent->numChildren(); i+=2)
2467 {
2468 if(m_parent->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass && m_engine->findTarget(static_cast<IrcTabItem*>(m_parent->childAtIndex(i))))
2469 {
2470 if((comparecase(ev.param2, static_cast<IrcTabItem*>(m_parent->childAtIndex(i))->getText()) == 0 && static_cast<IrcTabItem*>(m_parent->childAtIndex(i))->getType() == CHANNEL)
2471 || (ev.param1 == static_cast<IrcTabItem*>(m_parent->childAtIndex(i))->getText() && static_cast<IrcTabItem*>(m_parent->childAtIndex(i))->getType() == QUERY && ev.param2 == static_cast<IrcTabItem*>(m_parent->childAtIndex(i))->getNickName()))
2472 {
2473 tabExist = TRUE;
2474 break;
2475 }
2476 }
2477 }
2478 if(tabExist)
2479 {
2480 if((comparecase(ev.param2, getText()) == 0 && m_type == CHANNEL) || (ev.param1 == getText() && m_type == QUERY && ev.param2 == getNickName()))
2481 {
2482 FXbool needHighlight = FALSE;
2483 if(ev.param3.contains(getNickName()))
2484 needHighlight = highlightNeeded(ev.param3);
2485 appendIrcStyledText(FXStringFormat(_("%s's NOTICE: %s"), ev.param1.text(), ev.param3.text()), 2, ev.time);
2486 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this))
2487 {
2488 if(needHighlight)
2489 {
2490 this->setTextColor(preferences.m_highlightColor);
2491 if(m_type == CHANNEL) this->setIcon(ICO_CHANNELNEWMSG);
2492 }
2493 else this->setTextColor(preferences.m_unreadColor);
2494 if(m_type == QUERY) this->setIcon(ICO_QUERYNEWMSG);
2495 }
2496 if((m_type == CHANNEL && needHighlight) || m_type == QUERY)
2497 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_NEWMSG), NULL);
2498 }
2499 }
2500 else
2501 {
2502 if(isRightForServerMsg())
2503 {
2504 appendIrcStyledText(FXStringFormat(_("%s's NOTICE: %s"), ev.param1.text(), ev.param3.text()), 3, ev.time);
2505 }
2506 }
2507 }
2508 }
2509
2510 //handle IrcEvent IRC_NOTICE
onIrcNotice(IrcEvent & ev)2511 void IrcTabItem::onIrcNotice(IrcEvent &ev)
2512 {
2513 if(isRightForServerMsg())
2514 {
2515 if(ev.param1 == getNickName() && !isCommandIgnored("notice"))
2516 {
2517 appendIrcStyledText(FXStringFormat(_("NOTICE for you: %s"), ev.param2.text()), 3, ev.time);
2518 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2519 }
2520 else if(!isCommandIgnored("notice"))
2521 {
2522 appendIrcStyledText(FXStringFormat(_("%s's NOTICE: %s"), ev.param1.text(), ev.param2.text()), 3, ev.time);
2523 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2524 }
2525 }
2526 }
2527
2528 //handle IrcEvent IRC_NICK
onIrcNick(IrcEvent & ev)2529 void IrcTabItem::onIrcNick(IrcEvent &ev)
2530 {
2531 if(m_users->findItem(ev.param1) != -1)
2532 {
2533 if(ev.param2 == getNickName() && !isCommandIgnored("nick")) appendIrcStyledText(FXStringFormat(_("You're now known as %s"), ev.param2.text()), 1, ev.time);
2534 else if(!isCommandIgnored("nick") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s is now known as %s"), ev.param1.text(), ev.param2.text()), 1, ev.time);
2535 changeNickUser(ev.param1, ev.param2);
2536 }
2537 if(m_type == QUERY && ev.param1 == getText())
2538 {
2539 this->setText(ev.param2);
2540 stopLogging();
2541 }
2542 }
2543
2544 //handle IrcEvent IRC_TOPIC
onIrcTopic(IrcEvent & ev)2545 void IrcTabItem::onIrcTopic(IrcEvent &ev)
2546 {
2547 if(comparecase(ev.param2, getText()) == 0)
2548 {
2549 appendIrcText(FXStringFormat(_("%s set new topic for %s: %s"), ev.param1.text(), ev.param2.text(), ev.param3.text()), ev.time);
2550 m_topic = dxutils::stripColors(ev.param3, TRUE);
2551 m_topicline->setText(m_topic);
2552 m_topicline->setCursorPos(0);
2553 m_topicline->makePositionVisible(0);
2554 }
2555 }
2556
2557 //handle IrcEvent IRC_KICK
onIrcKick(IrcEvent & ev)2558 void IrcTabItem::onIrcKick(IrcEvent &ev)
2559 {
2560 if(comparecase(ev.param3, getText()) == 0)
2561 {
2562 if(ev.param2 != getNickName())
2563 {
2564 if(ev.param4.empty()) appendIrcStyledText(FXStringFormat(_("%s was kicked from %s by %s"), ev.param2.text(), ev.param3.text(), ev.param1.text()), 1, ev.time, FALSE, FALSE);
2565 else appendIrcStyledText(FXStringFormat(_("%s was kicked from %s by %s (%s)"), ev.param2.text(), ev.param3.text(), ev.param1.text(), ev.param4.text()), 1, ev.time, FALSE, FALSE);
2566 removeUser(ev.param2);
2567 }
2568 }
2569 if(ev.param2 == getNickName() && isRightForServerMsg())
2570 {
2571 if(ev.param4.empty()) appendIrcStyledText(FXStringFormat(_("You were kicked from %s by %s"), ev.param3.text(), ev.param1.text()), 1, ev.time, FALSE, FALSE);
2572 else appendIrcStyledText(FXStringFormat(_("You were kicked from %s by %s (%s)"), ev.param3.text(), ev.param1.text(), ev.param4.text()), 1, ev.time, FALSE, FALSE);
2573 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2574 }
2575 }
2576
2577 //handle IrcEvent IRC_MODE
onIrcMode(IrcEvent & ev)2578 void IrcTabItem::onIrcMode(IrcEvent &ev)
2579 {
2580 if(isRightForServerMsg())
2581 {
2582 appendIrcStyledText(FXStringFormat(_("Mode change [%s] for %s"), ev.param1.text(), ev.param2.text()), 1, ev.time, FALSE, FALSE);
2583 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2584 }
2585 }
2586
2587 //handle IrcEvent IRC_UMODE
onIrcUmode(IrcEvent & ev)2588 void IrcTabItem::onIrcUmode(IrcEvent &ev)
2589 {
2590 FXString moderator = ev.param1;
2591 FXString channel = ev.param2;
2592 FXString modes = ev.param3;
2593 FXString args = ev.param4;
2594 if(comparecase(channel, getText()) == 0)
2595 {
2596 FXbool sign = FALSE;
2597 int argsiter = 1;
2598 for(int i =0; i < modes.count(); i++) {
2599 switch(modes[i]) {
2600 case '+':
2601 sign = TRUE;
2602 break;
2603 case '-':
2604 sign = FALSE;
2605 break;
2606 case 'a': //admin
2607 {
2608 FXString nick = dxutils::getParam(args, argsiter, FALSE);
2609 setUserMode(nick, sign?ADMIN:NONE);
2610 if(sign)
2611 {
2612 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2613 {
2614 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s gave you admin"), moderator.text()), 1, ev.time, FALSE, FALSE);
2615 else appendIrcStyledText(FXStringFormat(_("%s gave %s admin"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2616 }
2617 }
2618 else
2619 {
2620 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2621 {
2622 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s removed you admin"), moderator.text()), 1, ev.time, FALSE, FALSE);
2623 else appendIrcStyledText(FXStringFormat(_("%s removed %s admin"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2624 }
2625 }
2626 argsiter++;
2627 }break;
2628 case 'o': //op
2629 {
2630 FXString nick = dxutils::getParam(args, argsiter, FALSE);
2631 setUserMode(nick, sign?OP:NONE);
2632 if(sign)
2633 {
2634 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2635 {
2636 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s gave you op"), moderator.text()), 1, ev.time, FALSE, FALSE);
2637 else appendIrcStyledText(FXStringFormat(_("%s gave %s op"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2638 }
2639 }
2640 else
2641 {
2642 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2643 {
2644 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s removed you op"), moderator.text()), 1, ev.time, FALSE, FALSE);
2645 else appendIrcStyledText(FXStringFormat(_("%s removed %s op"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2646 }
2647 }
2648 if(getNickName() == nick) sign ? m_iamOp = TRUE : m_iamOp = FALSE;
2649 argsiter++;
2650 }break;
2651 case 'v': //voice
2652 {
2653 FXString nick = dxutils::getParam(args, argsiter, FALSE);
2654 setUserMode(nick, sign?VOICE:NONE);
2655 if(sign)
2656 {
2657 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2658 {
2659 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s gave you voice"), moderator.text()), 1, ev.time, FALSE, FALSE);
2660 else appendIrcStyledText(FXStringFormat(_("%s gave %s voice"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2661 }
2662 }
2663 else
2664 {
2665 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2666 {
2667 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s removed you voice"), moderator.text()), 1, ev.time, FALSE, FALSE);
2668 else appendIrcStyledText(FXStringFormat(_("%s removed %s voice"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2669 }
2670 }
2671 argsiter++;
2672 }break;
2673 case 'h': //halfop
2674 {
2675 FXString nick = dxutils::getParam(args, argsiter, FALSE);
2676 setUserMode(nick, sign?HALFOP:NONE);
2677 if(sign)
2678 {
2679 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2680 {
2681 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s gave you halfop"), moderator.text()), 1, ev.time, FALSE, FALSE);
2682 else appendIrcStyledText(FXStringFormat(_("%s gave %s halfop"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2683 }
2684 }
2685 else
2686 {
2687 if(!isCommandIgnored("mode") && !m_engine->isUserIgnored(nick, getText()))
2688 {
2689 if(nick == getNickName()) appendIrcStyledText(FXStringFormat(_("%s removed you halfop"), moderator.text()), 1, ev.time, FALSE, FALSE);
2690 else appendIrcStyledText(FXStringFormat(_("%s removed %s halfop"), moderator.text(), nick.text()), 1, ev.time, FALSE, FALSE);
2691 }
2692 }
2693 argsiter++;
2694 }break;
2695 case 'b': //ban
2696 {
2697 FXString banmask = dxutils::getParam(args, argsiter, FALSE);
2698 onBan(banmask, sign, moderator, ev.time);
2699 argsiter++;
2700 }break;
2701 case 't': //topic settable by channel operator
2702 {
2703 sign ? m_editableTopic = FALSE : m_editableTopic = TRUE;
2704 }break;
2705 default:
2706 {
2707 appendIrcStyledText(FXStringFormat(_("%s set Mode: %s"), moderator.text(), FXString(modes+" "+args).text()), 1, ev.time, FALSE, FALSE);
2708 }
2709 }
2710 }
2711 if(preferences.m_sortUserMode) m_users->sortItems();
2712 }
2713 }
2714
2715 //handle IrcEvent IRC_CHMODE
onIrcChmode(IrcEvent & ev)2716 void IrcTabItem::onIrcChmode(IrcEvent &ev)
2717 {
2718 FXString channel = ev.param1;
2719 FXString modes = ev.param2;
2720 if(comparecase(channel, getText()) == 0)
2721 {
2722 if(modes.contains('t')) m_editableTopic = FALSE;
2723 appendIrcStyledText(FXStringFormat(_("Mode for %s: %s"), channel.text(), modes.text()), 1, ev.time, FALSE, FALSE);
2724 }
2725 }
2726
2727 //handle IrcEvent IRC_SERVERREPLY
onIrcServerReply(IrcEvent & ev)2728 void IrcTabItem::onIrcServerReply(IrcEvent &ev)
2729 {
2730 if(m_type == SERVER)
2731 {
2732 //this->setText(server->GetRealServerName());
2733 appendIrcText(ev.param1, ev.time);
2734 if(getApp()->getForeColor() == this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2735 }
2736 else
2737 {
2738 if(isRightForServerMsg())
2739 {
2740 appendIrcText(ev.param1, ev.time, FALSE, FALSE);
2741 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2742 }
2743 }
2744 }
2745
2746 //handle IrcEvent IRC_CONNECT
onIrcConnect(IrcEvent & ev)2747 void IrcTabItem::onIrcConnect(IrcEvent &ev)
2748 {
2749 appendIrcStyledText(ev.param1, 3, ev.time, FALSE, FALSE);
2750 }
2751
2752 //handle IrcEvent IRC_ERROR
onIrcError(IrcEvent & ev)2753 void IrcTabItem::onIrcError(IrcEvent &ev)
2754 {
2755 appendIrcStyledText(ev.param1, 4, ev.time, FALSE, FALSE);
2756 }
2757
2758 //handle IrcEvent IRC_SERVERERROR
onIrcServerError(IrcEvent & ev)2759 void IrcTabItem::onIrcServerError(IrcEvent &ev)
2760 {
2761 if(isRightForServerMsg())
2762 {
2763 appendIrcStyledText(ev.param1, 4, ev.time, FALSE, FALSE);
2764 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2765 }
2766 }
2767
2768 //handle IrcEvent IRC_DISCONNECT
onIrcDisconnect(IrcEvent & ev)2769 void IrcTabItem::onIrcDisconnect(IrcEvent &ev)
2770 {
2771 appendIrcStyledText(ev.param1, 4, ev.time, FALSE, FALSE);
2772 if(isRightForServerMsg())
2773 {
2774 if(m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_highlightColor);
2775 }
2776 if(m_type == CHANNEL)
2777 {
2778 m_users->clearItems();
2779 m_iamOp = FALSE;
2780 }
2781 }
2782
2783 //handle IrcEvent IRC_RECONNECT
onIrcReconnect(IrcEvent & ev)2784 void IrcTabItem::onIrcReconnect(IrcEvent &ev)
2785 {
2786 appendIrcStyledText(ev.param1, 4, ev.time, FALSE, FALSE);
2787 if(isRightForServerMsg())
2788 {
2789 if(m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_highlightColor);
2790 }
2791 if(m_type == CHANNEL)
2792 {
2793 m_users->clearItems();
2794 m_iamOp = FALSE;
2795 }
2796 }
2797
2798 //handle IrcEvent IRC_RECONNECTALL
onIrcReconnectAll(IrcEvent & ev)2799 void IrcTabItem::onIrcReconnectAll(IrcEvent &ev)
2800 {
2801 appendIrcStyledText(ev.param1, 3, ev.time, FALSE, FALSE);
2802 if(m_type == CHANNEL)
2803 {
2804 m_users->clearItems();
2805 m_iamOp = FALSE;
2806 }
2807 }
2808
2809 //handle IrcEvent IRC_UNKNOWN
onIrcUnknown(IrcEvent & ev)2810 void IrcTabItem::onIrcUnknown(IrcEvent &ev)
2811 {
2812 if(isRightForServerMsg())
2813 {
2814 appendIrcStyledText(FXStringFormat(_("Unhandled command '%s' params: %s"), ev.param1.text(), ev.param2.text()), 4, ev.time, FALSE, FALSE);
2815 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2816 }
2817 }
2818
2819 //handle IrcEvent IRC_301
onIrc301(IrcEvent & ev)2820 void IrcTabItem::onIrc301(IrcEvent &ev)
2821 {
2822 if(m_parent->getCurrent()*2 == m_parent->indexOfChild(this) || getText() == ev.param1)
2823 {
2824 if(!isCommandIgnored("away") && !m_engine->isUserIgnored(ev.param1, getText())) appendIrcStyledText(FXStringFormat(_("%s is away: %s"),ev.param1.text(), ev.param2.text()), 1, ev.time);
2825 }
2826 }
2827
2828 //handle IrcEvent IRC_305
onIrc305(IrcEvent & ev)2829 void IrcTabItem::onIrc305(IrcEvent &ev)
2830 {
2831 FXint i = m_users->findItem(getNickName());
2832 if(i != -1)
2833 {
2834 appendIrcStyledText(ev.param1, 1, ev.time, FALSE, FALSE);
2835 ((NickListItem*)m_users->getItem(i))->changeAway(FALSE);
2836 }
2837 }
2838
2839 //handle IrcEvent IRC_306
onIrc306(IrcEvent & ev)2840 void IrcTabItem::onIrc306(IrcEvent &ev)
2841 {
2842 FXint i = m_users->findItem(getNickName());
2843 if(i != -1)
2844 {
2845 appendIrcStyledText(ev.param1, 1, ev.time, FALSE, FALSE);
2846 ((NickListItem*)m_users->getItem(i))->changeAway(TRUE);
2847 }
2848 }
2849
2850 //handle IrcEvent IRC_331, IRC_332 and IRC_333
onIrc331332333(IrcEvent & ev)2851 void IrcTabItem::onIrc331332333(IrcEvent &ev)
2852 {
2853 if(comparecase(ev.param1, getText()) == 0)
2854 {
2855 appendIrcText(ev.param2, ev.time);
2856 if(ev.eventType == IRC_331)
2857 {
2858 m_topic = dxutils::stripColors(ev.param2, TRUE);
2859 m_topicline->setText(m_topic);
2860 m_topicline->setCursorPos(0);
2861 m_topicline->makePositionVisible(0);
2862 }
2863 if(ev.eventType == IRC_332)
2864 {
2865 m_topic = dxutils::stripColors(dxutils::getParam(ev.param2, 2, TRUE, ':').after(' '), TRUE);
2866 m_topicline->setText(m_topic);
2867 m_topicline->setCursorPos(0);
2868 m_topicline->makePositionVisible(0);
2869 }
2870 }
2871 }
2872
2873 //handle IrcEvent IRC_353
onIrc353(IrcEvent & ev)2874 void IrcTabItem::onIrc353(IrcEvent &ev)
2875 {
2876 FXString channel = ev.param1;
2877 FXString usersStr = ev.param2;
2878 bool list = ev.param3=="list";
2879 FXString myNick = getNickName();
2880 if(usersStr.right(1) != " ") usersStr.append(" ");
2881 if(comparecase(channel, getText()) == 0)
2882 {
2883 if(list && !isCommandIgnored("numeric")) appendIrcText(FXStringFormat(_("Users on %s: %s"), channel.text(), usersStr.text()), ev.time, FALSE, FALSE);
2884 while(usersStr.contains(' '))
2885 {
2886 FXString nick = usersStr.before(' ');
2887 UserMode mode = getUserMode(nick[0]);
2888 if(mode != NONE) nick = nick.after(nick[0]);
2889 addUser(nick, mode);
2890 if(mode == OP && nick == myNick) m_iamOp = TRUE;
2891 usersStr = usersStr.after(' ');
2892 }
2893 }
2894 else
2895 {
2896 if(list && !isCommandIgnored("numeric"))
2897 {
2898 FXbool channelOn = FALSE;
2899 for(FXint i = 0; i<m_parent->numChildren(); i+=2)
2900 {
2901 if(m_engine->findTarget(static_cast<IrcTabItem*>(m_parent->childAtIndex(i))) && comparecase(static_cast<FXTabItem*>(m_parent->childAtIndex(i))->getText(), channel) == 0)
2902 {
2903 channelOn = TRUE;
2904 break;
2905 }
2906 }
2907 if(!channelOn)
2908 {
2909 if(m_type == SERVER)
2910 {
2911 appendIrcText(FXStringFormat(_("Users on %s: %s"), channel.text(), usersStr.text()), ev.time, FALSE, FALSE);
2912 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2913 }
2914 else
2915 {
2916 if(isRightForServerMsg())
2917 {
2918 appendIrcText(FXStringFormat(_("Users on %s: %s"), channel.text(), usersStr.text()), ev.time, FALSE, FALSE);
2919 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2920 }
2921 }
2922 }
2923 }
2924 }
2925 }
2926
2927 //handle IrcEvent IRC_366
onIrc366(IrcEvent & ev)2928 void IrcTabItem::onIrc366(IrcEvent &ev)
2929 {
2930 bool list = ev.param3=="list";
2931 if(comparecase(ev.param1, getText()) == 0)
2932 {
2933 if(list && !isCommandIgnored("numeric")) appendIrcText(FXStringFormat("%s: %s", ev.param1.text(), ev.param2.text()), ev.time, FALSE, FALSE);
2934 else m_engine->addIgnoreWho(getText());
2935 }
2936 else
2937 {
2938 if(list && !isCommandIgnored("numeric"))
2939 {
2940 FXbool channelOn = FALSE;
2941 for(FXint i = 0; i<m_parent->numChildren(); i+=2)
2942 {
2943 if(m_engine->findTarget(static_cast<IrcTabItem*>(m_parent->childAtIndex(i))) && comparecase(static_cast<FXTabItem*>(m_parent->childAtIndex(i))->getText(), ev.param1) == 0)
2944 {
2945 channelOn = TRUE;
2946 break;
2947 }
2948 }
2949 if(!channelOn)
2950 {
2951 if(m_type == SERVER)
2952 {
2953 appendIrcText(FXStringFormat("%s: %s", ev.param1.text(), ev.param2.text()), ev.time, FALSE, FALSE);
2954 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2955 }
2956 else
2957 {
2958 if(isRightForServerMsg())
2959 {
2960 appendIrcText(FXStringFormat("%s: %s", ev.param1.text(), ev.param2.text()), ev.time, FALSE, FALSE);
2961 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2962 }
2963 }
2964 }
2965 }
2966 }
2967 }
2968
2969 //handle IrcEvent IRC_372
onIrc372(IrcEvent & ev)2970 void IrcTabItem::onIrc372(IrcEvent &ev)
2971 {
2972 if(m_type == SERVER)
2973 {
2974 appendIrcText(ev.param1, ev.time);
2975 if(getApp()->getForeColor() == this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2976 }
2977 else
2978 {
2979 if(isRightForServerMsg())
2980 {
2981 appendIrcText(ev.param1, ev.time, FALSE, FALSE);
2982 if(preferences.m_highlightColor != this->getTextColor() && m_parent->getCurrent()*2 != m_parent->indexOfChild(this)) this->setTextColor(preferences.m_unreadColor);
2983 }
2984 }
2985 }
2986
2987 //handle IrcEvent IRC_AWAY
onIrcAway(IrcEvent & ev)2988 void IrcTabItem::onIrcAway(IrcEvent &ev)
2989 {
2990 if(comparecase(ev.param1, getText()) == 0)
2991 {
2992 onAway();
2993 return;
2994 }
2995 //hack for &bitlbee
2996 if(comparecase("&bitlbee", getText()) == 0 && m_users->findItem(ev.param1)!=-1)
2997 {
2998 onAway();
2999 return;
3000 }
3001 }
3002
3003 //handle IrcEvent IRC_ENDMOTD
onIrcEndMotd()3004 void IrcTabItem::onIrcEndMotd()
3005 {
3006 m_text->makeLastRowVisible(TRUE);
3007 if(m_type == SERVER && !m_engine->getNetworkName().empty())
3008 setText(m_engine->getNetworkName());
3009 }
3010
onPipe(FXObject *,FXSelector,void * ptr)3011 long IrcTabItem::onPipe(FXObject*, FXSelector, void *ptr)
3012 {
3013 FXString text = *(FXString*)ptr;
3014 if(m_sendPipe && (m_type == CHANNEL || m_type == QUERY))
3015 {
3016 if(!getApp()->hasTimeout(this, IrcTabItem_PTIME)) getApp()->addTimeout(this, IrcTabItem_PTIME);
3017 m_pipeStrings.append(text);
3018 }
3019 else appendIrcText(text, FXSystem::now(), TRUE, FALSE);
3020 return 1;
3021 }
3022
3023 //checking away in channel
checkAway()3024 void IrcTabItem::checkAway()
3025 {
3026 if(m_type == CHANNEL && m_engine->getConnected() && m_numberUsers < preferences.m_maxAway)
3027 {
3028 m_engine->addIgnoreWho(getText());
3029 }
3030 }
3031
onPipeTimeout(FXObject *,FXSelector,void *)3032 long IrcTabItem::onPipeTimeout(FXObject*, FXSelector, void*)
3033 {
3034 if(m_type == CHANNEL || m_type == QUERY)
3035 {
3036 if(m_pipeStrings.no() > 3)
3037 {
3038 if(m_pipeStrings[0].empty()) m_pipeStrings[0] = " ";
3039 if(m_pipeStrings[0].length() > m_maxLen-10-getText().length())
3040 {
3041 dxStringArray messages = cutText(m_pipeStrings[0], m_maxLen-10-getText().length());
3042 for(FXint i=0; i<messages.no(); i++)
3043 {
3044 #ifdef HAVE_LUA
3045 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_OWNMSG), &messages[i]);
3046 if(!m_scriptHasOwnMsg)
3047 {
3048 appendMyMsg(messages[i], FXSystem::now());
3049 m_engine->sendMsg(getText(), messages[i]);
3050 }
3051 #else
3052 appendMyMsg(messages[i], FXSystem::now());
3053 m_engine->sendMsg(getText(), messages[i]);
3054 #endif
3055 }
3056 }
3057 else
3058 {
3059 #ifdef HAVE_LUA
3060 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_OWNMSG), &m_pipeStrings[0]);
3061 if(!m_scriptHasOwnMsg)
3062 {
3063 appendMyMsg(m_pipeStrings[0], FXSystem::now());
3064 m_engine->sendMsg(getText(), m_pipeStrings[0]);
3065 }
3066 #else
3067 appendMyMsg(m_pipeStrings[0], FXSystem::now());
3068 m_engine->sendMsg(getText(), m_pipeStrings[0]);
3069 #endif
3070 }
3071 m_pipeStrings.erase(0);
3072 getApp()->addTimeout(this, IrcTabItem_PTIME, 3000);
3073 }
3074 else
3075 {
3076 while(m_pipeStrings.no())
3077 {
3078 if(m_pipeStrings[0].empty()) m_pipeStrings[0] = " ";
3079 if(m_pipeStrings[0].length() > m_maxLen-10-getText().length())
3080 {
3081 dxStringArray messages = cutText(m_pipeStrings[0], m_maxLen-10-getText().length());
3082 for(FXint i=0; i<messages.no(); i++)
3083 {
3084 #ifdef HAVE_LUA
3085 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_OWNMSG), &messages[i]);
3086 if(!m_scriptHasOwnMsg)
3087 {
3088 appendMyMsg(messages[i], FXSystem::now());
3089 m_engine->sendMsg(getText(), messages[i]);
3090 }
3091 #else
3092 appendMyMsg(messages[i], FXSystem::now());
3093 m_engine->sendMsg(getText(), messages[i]);
3094 #endif
3095 }
3096 }
3097 else
3098 {
3099 #ifdef HAVE_LUA
3100 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_OWNMSG), &m_pipeStrings[0]);
3101 if(!m_scriptHasOwnMsg)
3102 {
3103 appendMyMsg(m_pipeStrings[0], FXSystem::now());
3104 m_engine->sendMsg(getText(), m_pipeStrings[0]);
3105 }
3106 #else
3107 appendMyMsg(m_pipeStrings[0], FXSystem::now());
3108 m_engine->sendMsg(getText(), m_pipeStrings[0]);
3109 #endif
3110 }
3111 m_pipeStrings.erase(0);
3112 }
3113 }
3114 }
3115 return 1;
3116 }
3117
onEggTimeout(FXObject *,FXSelector,void *)3118 long IrcTabItem::onEggTimeout(FXObject*, FXSelector, void*)
3119 {
3120 if(m_pics<24)
3121 {
3122 getApp()->addTimeout(this, IrcTabItem_ETIME, 222);
3123 FXString replace = "\n";
3124 FXint max = rand()%30;
3125 for(FXint i=0; i<max; i++)
3126 replace.append(' ');
3127 FXString pic = "\n oooooooooo\n o o\no o\no o o o\no o o o\no o\no o o o\no oooooo o\n o o\n oooooooooo";
3128 pic.substitute("\n", replace);
3129 pic.append('\n');
3130 m_text->clearText();
3131 max = rand()%15;
3132 for(FXint i=0; i<max; i++)
3133 pic.prepend('\n');
3134 max = rand()%7;
3135 m_text->appendStyledText(pic, max+12);
3136 m_pics++;
3137 }
3138 return 1;
3139 }
3140
onAway()3141 void IrcTabItem::onAway()
3142 {
3143 if(m_numberUsers < preferences.m_maxAway)
3144 {
3145 for(FXint i = 0; i < m_users->getNumItems(); i++)
3146 {
3147 FXbool away = m_engine->getNickInfo(m_users->getItemText(i)).away;
3148 ((NickListItem*)m_users->getItem(i))->changeAway(away);
3149 }
3150 }
3151 else
3152 {
3153 for(FXint i = 0; i < m_users->getNumItems(); i++)
3154 {
3155 ((NickListItem*)m_users->getItem(i))->changeAway(FALSE);
3156 }
3157 }
3158 }
3159
onRightMouse(FXObject *,FXSelector,void * ptr)3160 long IrcTabItem::onRightMouse(FXObject *, FXSelector, void *ptr)
3161 {
3162 //focus();
3163 FXEvent* event = (FXEvent*)ptr;
3164 if(event->moved) return 1;
3165 FXint index = m_users->getItemAt(event->win_x,event->win_y);
3166 if(index >= 0)
3167 {
3168 UserMode mode = ((NickListItem*)m_users->getItem(index))->getUserMode();
3169 NickInfo nick = m_engine->getNickInfo(m_users->getItemText(index));
3170 m_nickOnRight = nick;
3171 FXString flagpath = DXIRC_DATADIR PATHSEPSTRING "icons" PATHSEPSTRING "flags";
3172 delete ICO_FLAG;
3173 ICO_FLAG = NULL;
3174 if(FXStat::exists(flagpath+PATHSEPSTRING+nick.host.rafter('.')+".png")) ICO_FLAG = makeIcon(getApp(), flagpath, nick.host.rafter('.')+".png", TRUE);
3175 else ICO_FLAG = makeIcon(getApp(), flagpath, "unknown.png", TRUE);
3176 FXMenuPane opmenu(this);
3177 if(mode != OP) new FXMenuCommand(&opmenu, _("Give op"), NULL, this, IrcTabItem_OP);
3178 if(mode == OP) new FXMenuCommand(&opmenu, _("Remove op"), NULL, this, IrcTabItem_DEOP);
3179 new FXMenuSeparator(&opmenu);
3180 if(mode != VOICE) new FXMenuCommand(&opmenu, _("Give voice"), NULL, this, IrcTabItem_VOICE);
3181 if(mode == VOICE) new FXMenuCommand(&opmenu, _("Remove voice"), NULL, this, IrcTabItem_DEVOICE);
3182 new FXMenuSeparator(&opmenu);
3183 new FXMenuCommand(&opmenu, _("Kick"), NULL, this, IrcTabItem_KICK);
3184 new FXMenuSeparator(&opmenu);
3185 new FXMenuCommand(&opmenu, _("Ban"), NULL, this, IrcTabItem_BAN);
3186 new FXMenuCommand(&opmenu, _("KickBan"), NULL, this, IrcTabItem_KICKBAN);
3187 FXMenuPane popup(this);
3188 new FXMenuCommand(&popup, FXStringFormat(_("User: %s@%s"), nick.user.text(), nick.host.text()), ICO_FLAG);
3189 new FXMenuCommand(&popup, FXStringFormat(_("Realname: %s"), nick.real.text()));
3190 if(nick.nick != getNickName())
3191 {
3192 new FXMenuSeparator(&popup);
3193 new FXMenuCommand(&popup, _("Query"), NULL, this, IrcTabItem_NEWQUERY);
3194 new FXMenuCommand(&popup, _("User information (WHOIS)"), NULL, this, IrcTabItem_WHOIS);
3195 new FXMenuCommand(&popup, _("DCC chat"), NULL, this, IrcTabItem_DCCCHAT);
3196 new FXMenuCommand(&popup, _("Send file"), NULL, this, IrcTabItem_DCCSEND);
3197 new FXMenuCommand(&popup, _("Ignore"), NULL, this, IrcTabItem_IGNORE);
3198 if(m_iamOp) new FXMenuCascade(&popup, _("Operator actions"), NULL, &opmenu);
3199 }
3200 else
3201 {
3202 new FXMenuSeparator(&popup);
3203 if(m_engine->isAway(getNickName())) new FXMenuCommand(&popup, _("Remove Away"), NULL, this, IrcTabItem_DEAWAY);
3204 else new FXMenuCommand(&popup, _("Set Away"), NULL, this, IrcTabItem_AWAY);
3205 }
3206 popup.create();
3207 popup.popup(NULL,event->root_x,event->root_y);
3208 getApp()->runModalWhileShown(&popup);
3209 }
3210 return 1;
3211 }
3212
onDoubleclick(FXObject *,FXSelector,void *)3213 long IrcTabItem::onDoubleclick(FXObject*, FXSelector, void*)
3214 {
3215 FXint index = m_users->getCursorItem();
3216 if(index >= 0)
3217 {
3218 if(m_users->getItemText(index) == getNickName()) return 1;
3219 IrcEvent ev;
3220 ev.eventType = IRC_QUERY;
3221 ev.param1 = m_users->getItemText(index);
3222 ev.param2 = getNickName();
3223 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
3224 }
3225 return 1;
3226 }
3227
onNewQuery(FXObject *,FXSelector,void *)3228 long IrcTabItem::onNewQuery(FXObject *, FXSelector, void *)
3229 {
3230 IrcEvent ev;
3231 ev.eventType = IRC_QUERY;
3232 ev.param1 = m_nickOnRight.nick;
3233 ev.param2 = getNickName();
3234 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
3235 return 1;
3236 }
3237
onWhois(FXObject *,FXSelector,void *)3238 long IrcTabItem::onWhois(FXObject *, FXSelector, void *)
3239 {
3240 m_engine->sendWhois(m_nickOnRight.nick);
3241 return 1;
3242 }
3243
onDccChat(FXObject *,FXSelector,void *)3244 long IrcTabItem::onDccChat(FXObject*, FXSelector, void*)
3245 {
3246 IrcEvent ev;
3247 ev.eventType = IRC_DCCSERVER;
3248 ev.param1 = m_nickOnRight.nick;
3249 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
3250 return 1;
3251 }
3252
onDccSend(FXObject *,FXSelector,void *)3253 long IrcTabItem::onDccSend(FXObject*, FXSelector, void*)
3254 {
3255 DccSendDialog dialog((FXMainWindow*)m_parent->getParent()->getParent(), m_nickOnRight.nick);
3256 if(dialog.execute())
3257 {
3258 IrcEvent ev;
3259 ev.eventType = dialog.getPassive() ? IRC_DCCPOUT: IRC_DCCOUT;
3260 ev.param1 = m_nickOnRight.nick;
3261 ev.param2 = dialog.getFilename();
3262 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
3263 }
3264 return 1;
3265 }
3266
onOp(FXObject *,FXSelector,void *)3267 long IrcTabItem::onOp(FXObject *, FXSelector, void *)
3268 {
3269 m_engine->sendMode(getText()+" +o "+m_nickOnRight.nick);
3270 return 1;
3271 }
3272
onDeop(FXObject *,FXSelector,void *)3273 long IrcTabItem::onDeop(FXObject *, FXSelector, void *)
3274 {
3275 m_engine->sendMode(getText()+" -o "+m_nickOnRight.nick);
3276 return 1;
3277 }
3278
onVoice(FXObject *,FXSelector,void *)3279 long IrcTabItem::onVoice(FXObject *, FXSelector, void *)
3280 {
3281 m_engine->sendMode(getText()+" +v "+m_nickOnRight.nick);
3282 return 1;
3283 }
3284
onDevoice(FXObject *,FXSelector,void *)3285 long IrcTabItem::onDevoice(FXObject *, FXSelector, void *)
3286 {
3287 m_engine->sendMode(getText()+" -v "+m_nickOnRight.nick);
3288 return 1;
3289 }
3290
onKick(FXObject *,FXSelector,void *)3291 long IrcTabItem::onKick(FXObject *, FXSelector, void *)
3292 {
3293 FXDialogBox kickDialog(this, _("Kick dialog"), DECOR_TITLE|DECOR_BORDER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3294 FXVerticalFrame *contents = new FXVerticalFrame(&kickDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 10, 10, 10, 10, 0, 0);
3295
3296 FXHorizontalFrame *kickframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y);
3297 new FXLabel(kickframe, _("Kick reason:"), 0, JUSTIFY_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3298 FXTextField *reasonEdit = new FXTextField(kickframe, 25, NULL, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3299
3300 FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
3301 new dxEXButton(buttonframe, _("&Cancel"), NULL, &kickDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3302 new dxEXButton(buttonframe, _("&OK"), NULL, &kickDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3303
3304 if(kickDialog.execute(PLACEMENT_CURSOR))
3305 {
3306 m_engine->sendKick(getText(), m_nickOnRight.nick, reasonEdit->getText());
3307 }
3308 return 1;
3309 }
3310
onBan(FXObject *,FXSelector,void *)3311 long IrcTabItem::onBan(FXObject *, FXSelector, void *)
3312 {
3313 FXDialogBox banDialog(this, _("Ban dialog"), DECOR_TITLE|DECOR_BORDER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3314 FXVerticalFrame *contents = new FXVerticalFrame(&banDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 10, 10, 10, 10, 0, 0);
3315
3316 FXHorizontalFrame *banframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y);
3317 new FXLabel(banframe, _("Banmask:"), 0, JUSTIFY_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3318 FXTextField *banEdit = new FXTextField(banframe, 25, NULL, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3319 banEdit->setText(m_nickOnRight.nick+"!"+m_nickOnRight.user+"@"+m_nickOnRight.host);
3320
3321 FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
3322 new dxEXButton(buttonframe, _("&Cancel"), NULL, &banDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3323 new dxEXButton(buttonframe, _("&OK"), NULL, &banDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3324
3325 if(banDialog.execute(PLACEMENT_CURSOR))
3326 {
3327 m_engine->sendMode(getText()+" +b "+banEdit->getText());
3328 }
3329 return 1;
3330 }
3331
onKickban(FXObject *,FXSelector,void *)3332 long IrcTabItem::onKickban(FXObject *, FXSelector, void *)
3333 {
3334 FXDialogBox banDialog(this, _("Kick/Ban dialog"), DECOR_TITLE|DECOR_BORDER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3335 FXVerticalFrame *contents = new FXVerticalFrame(&banDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 10, 10, 10, 10, 0, 0);
3336
3337 FXHorizontalFrame *kickframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y);
3338 new FXLabel(kickframe, _("Kick reason:"), 0, JUSTIFY_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3339 FXTextField *reasonEdit = new FXTextField(kickframe, 25, NULL, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3340
3341 FXHorizontalFrame *banframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y);
3342 new FXLabel(banframe, _("Banmask:"), 0, JUSTIFY_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3343 FXTextField *banEdit = new FXTextField(banframe, 25, NULL, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3344 banEdit->setText(m_nickOnRight.nick+"!"+m_nickOnRight.user+"@"+m_nickOnRight.host);
3345
3346 FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
3347 new dxEXButton(buttonframe, _("&Cancel"), NULL, &banDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3348 new dxEXButton(buttonframe, _("&OK"), NULL, &banDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3349
3350 if(banDialog.execute(PLACEMENT_CURSOR))
3351 {
3352 m_engine->sendKick(getText(), m_nickOnRight.nick, reasonEdit->getText());
3353 m_engine->sendMode(getText()+" +b "+banEdit->getText());
3354 }
3355 return 1;
3356 }
3357
3358 //handle popup Ignore
onIgnore(FXObject *,FXSelector,void *)3359 long IrcTabItem::onIgnore(FXObject*, FXSelector, void*)
3360 {
3361 FXDialogBox dialog(this, _("Add ignore user"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
3362 FXVerticalFrame *contents = new FXVerticalFrame(&dialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
3363 FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3364
3365 new FXLabel(matrix, _("Nick:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3366 FXTextField *nick = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3367 nick->setText(m_nickOnRight.nick+"!"+m_nickOnRight.user+"@"+m_nickOnRight.host);
3368 new FXLabel(matrix, _("Channel(s):\tChannels need to be comma separated"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3369 FXTextField *channel = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3370 channel->setText(getText());
3371 channel->setTipText(_("Channels need to be comma separated"));
3372 new FXLabel(matrix, _("Server:"), NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3373 FXTextField *server = new FXTextField(matrix, 25, NULL, 0, FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3374 server->setText(getServerName());
3375
3376 FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
3377 new dxEXButton(buttonframe, _("&Cancel"), NULL, &dialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
3378 new dxEXButton(buttonframe, _("&OK"), NULL, &dialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
3379
3380 if(dialog.execute(PLACEMENT_CURSOR))
3381 {
3382 FXString ignoretext = nick->getText()+" "+channel->getText()+" "+server->getText();
3383 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_ADDIUSER), &ignoretext);
3384 }
3385 return 1;
3386 }
3387
3388 //handle IrcTabItem_AWAY
onSetAway(FXObject *,FXSelector,void *)3389 long IrcTabItem::onSetAway(FXObject*, FXSelector, void*)
3390 {
3391 FXDialogBox awayDialog(this, _("Away dialog"), DECOR_TITLE|DECOR_BORDER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3392 FXVerticalFrame *contents = new FXVerticalFrame(&awayDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0, 0, 0, 0, 10, 10, 10, 10, 0, 0);
3393
3394 FXHorizontalFrame *msgframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y);
3395 new FXLabel(msgframe, _("Message:"), 0, JUSTIFY_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
3396 FXTextField *msgEdit = new FXTextField(msgframe, 25, NULL, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
3397 msgEdit->setText(_("away"));
3398
3399 FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents, LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
3400 new dxEXButton(buttonframe, _("&Cancel"), NULL, &awayDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3401 new dxEXButton(buttonframe, _("&OK"), NULL, &awayDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0, 0, 0, 0, 10, 10, 2, 2);
3402
3403 if(awayDialog.execute(PLACEMENT_CURSOR))
3404 {
3405 m_engine->sendAway(msgEdit->getText().empty() ? _("away"): msgEdit->getText());
3406 }
3407 return 1;
3408 }
3409
3410 //handle IrcTabItem_DEAWAY
onRemoveAway(FXObject *,FXSelector,void *)3411 long IrcTabItem::onRemoveAway(FXObject*, FXSelector, void*)
3412 {
3413 m_engine->sendAway("");
3414 return 1;
3415 }
3416
3417 //handle change in spellLang combobox
onSpellLang(FXObject *,FXSelector,void *)3418 long IrcTabItem::onSpellLang(FXObject*, FXSelector, void*)
3419 {
3420 m_commandline->setLanguage(m_spellLangs->getItemText(m_spellLangs->getCurrentItem()));
3421 m_commandline->setTipText(FXStringFormat(_("Current spellchecking language: %s"),m_spellLangs->getItemText(m_spellLangs->getCurrentItem()).text()));
3422 return 1;
3423 }
3424
3425 //handle LogThread_LIST
onListLogThread(FXObject *,FXSelector,void *)3426 long IrcTabItem::onListLogThread(FXObject*, FXSelector, void*)
3427 {
3428 dxStringArray files = m_logThread->getResult();
3429 if(!files.no())
3430 {
3431 appendIrcStyledText(FXStringFormat(_("No log files for %s-%s."), m_engine->getNetworkName().text(), getText().text()), 4, FXSystem::now(), FALSE, FALSE);
3432 return 1;
3433 }
3434 appendIrcStyledText(_("Log files:"), 7, FXSystem::now(), FALSE, FALSE);
3435 FXString lastYear = dxutils::getParam(files[0], 1, FALSE, '-');
3436 FXint lastMonth = FXIntVal(dxutils::getParam(files[0], 2, FALSE, '-'));
3437 appendIrcStyledText(FXStringFormat("%s:", lastYear.text()), 5, FXSystem::now(), FALSE, FALSE);
3438 appendIrcStyledText(FXStringFormat("%s:", dxutils::getMonth(lastMonth).text()), 5, FXSystem::now(), FALSE, FALSE);
3439 FXString list = "";
3440 for(FXint i=0; i<files.no(); i++)
3441 {
3442 if(lastYear!=dxutils::getParam(files[i], 1, FALSE, '-'))
3443 {
3444 lastYear = dxutils::getParam(files[i], 1, FALSE, '-');
3445 lastMonth = FXIntVal(dxutils::getParam(files[i], 2, FALSE, '-'));
3446 appendIrcText(list.rbefore(','), FXSystem::now(), FALSE, FALSE);
3447 appendIrcStyledText(FXStringFormat("%s:", lastYear.text()), 5, FXSystem::now(), FALSE, FALSE);
3448 appendIrcStyledText(FXStringFormat("%s:", dxutils::getMonth(lastMonth).text()), 5, FXSystem::now(), FALSE, FALSE);
3449 list.clear();
3450 list.append(dxutils::getParam(files[i], 3, FALSE, '-')+", ");
3451 }
3452 else if(lastMonth!=FXIntVal(dxutils::getParam(files[i], 2, FALSE, '-')))
3453 {
3454 lastMonth = FXIntVal(dxutils::getParam(files[i], 2, FALSE, '-'));
3455 appendIrcText(list.rbefore(','), FXSystem::now(), FALSE, FALSE);
3456 appendIrcStyledText(FXStringFormat("%s:", dxutils::getMonth(lastMonth).text()), 5, FXSystem::now(), FALSE, FALSE);
3457 list.clear();
3458 list.append(dxutils::getParam(files[i], 3, FALSE, '-')+", ");
3459 }
3460 else list.append(dxutils::getParam(files[i], 3, FALSE, '-')+", ");
3461 }
3462 if(!list.empty()) appendIrcText(list.rbefore(','), FXSystem::now(), FALSE, FALSE);
3463 return 1;
3464 }
3465
3466 //handle LogThread_LINES
onLinesLogThread(FXObject *,FXSelector,void *)3467 long IrcTabItem::onLinesLogThread(FXObject*, FXSelector, void*)
3468 {
3469 m_loadLog = FALSE;
3470 clearChat();
3471 dxStringArray lines = m_logThread->getResult();
3472 for(FXint i=0; i<lines.no(); i++)
3473 {
3474 if(lines[i].after(']')[1]=='\014') //log style mark
3475 {
3476 if(lines[i].after('\014',2)[0]=='<') //has nick
3477 {
3478 m_text->appendStyledText(lines[i].before('\014'), 11); //timestamp
3479 FXString nick = lines[i].after('<').before('>');
3480 m_text->appendStyledText(nick+":", getNickStyle(nick));
3481 appendLinkText(dxutils::stripColors(lines[i].after('>'), TRUE), 11);
3482 }
3483 else appendLinkText(dxutils::stripLogMark(dxutils::stripColors(lines[i], TRUE)), 11);
3484 }
3485 else
3486 {
3487 if(lines[i].after(']')[1]=='<') //has nick
3488 {
3489 m_text->appendStyledText(lines[i].before('<'), 11); //timestamp
3490 FXString nick = lines[i].after('<').before('>');
3491 m_text->appendStyledText(nick+":", getNickStyle(nick));
3492 appendLinkText(dxutils::stripColors(lines[i].after('>'), TRUE), 11);
3493 }
3494 else appendLinkText(dxutils::stripColors(lines[i], TRUE), 11);
3495 }
3496 }
3497 while(m_storedEvents.no())
3498 {
3499 parseIrcEvent(m_storedEvents[0]);
3500 m_storedEvents.erase(0);
3501 }
3502 return 1;
3503 }
3504
onTopic(FXObject *,FXSelector,void *)3505 long IrcTabItem::onTopic(FXObject*, FXSelector, void*)
3506 {
3507 if(m_editableTopic || m_iamOp)
3508 {
3509 if(m_topicline->getText().length() > m_engine->getTopicLen())
3510 {
3511 appendIrcStyledText(FXStringFormat(_("Warning: topic is too long. Max. topic length is %d."), m_engine->getTopicLen()), 4, FXSystem::now(), FALSE, FALSE);
3512 m_engine->sendTopic(getText(), m_topicline->getText());
3513 return 1;
3514 }
3515 m_engine->sendTopic(getText(), m_topicline->getText());
3516 }
3517 else
3518 {
3519 m_topicline->setText(m_topic);
3520 m_topicline->setCursorPos(0);
3521 m_topicline->makePositionVisible(0);
3522 }
3523 return 1;
3524 }
3525
onTopicLink(FXObject *,FXSelector,void * data)3526 long IrcTabItem::onTopicLink(FXObject*, FXSelector, void *data)
3527 {
3528 dxutils::launchLink(static_cast<FXchar*>(data));
3529 return 1;
3530 }
3531
onBan(const FXString & banmask,const FXbool & sign,const FXString & sender,const FXTime & time)3532 void IrcTabItem::onBan(const FXString &banmask, const FXbool &sign, const FXString &sender, const FXTime &time)
3533 {
3534 if(sign)
3535 {
3536 FXString nicks = m_engine->getBannedNick(banmask);
3537 FXString myNick = getNickName();
3538 while(nicks.contains(';'))
3539 {
3540 for(FXint i=m_users->getNumItems()-1; i>-1; i--)
3541 {
3542 if(nicks.before(';') == m_users->getItemText(i))
3543 {
3544 if(m_users->getItemText(i) == myNick) appendIrcStyledText(FXStringFormat(_("You was banned by %s"), sender.text()), 1, time, FALSE, FALSE);
3545 else
3546 {
3547 if(!isCommandIgnored("ban") && !m_engine->isUserIgnored(m_users->getItemText(i), getText())) appendIrcStyledText(FXStringFormat(_("%s was banned by %s"), m_users->getItemText(i).text(), sender.text()), 1, time, FALSE, FALSE);
3548 //RemoveUser(users->getItemText(i));
3549 }
3550 }
3551 }
3552 nicks = nicks.after(';');
3553 }
3554 }
3555 }
3556
getNick(FXint i)3557 FXString IrcTabItem::getNick(FXint i)
3558 {
3559 if(m_users->getNumItems()) return m_users->getItemText(i);
3560 return "";
3561 }
3562
getNickStyle(const FXString & nick)3563 FXint IrcTabItem::getNickStyle(const FXString &nick)
3564 {
3565 if(preferences.m_coloredNick) return 12+nick.hash()%8; //12 is first colored nick style
3566 return 5; //bold
3567 }
3568
hiliteStyleExist(FXColor foreColor,FXColor backColor,FXuint style)3569 FXint IrcTabItem::hiliteStyleExist(FXColor foreColor, FXColor backColor, FXuint style)
3570 {
3571 for(FXint i=0; i<m_textStyleList.no(); i++)
3572 {
3573 if(m_textStyleList[i].normalForeColor == foreColor
3574 && m_textStyleList[i].normalBackColor == backColor
3575 && m_textStyleList[i].style == style)
3576 return i+1;
3577 }
3578 return -1;
3579 }
3580
createHiliteStyle(FXColor foreColor,FXColor backColor,FXuint style)3581 void IrcTabItem::createHiliteStyle(FXColor foreColor, FXColor backColor, FXuint style)
3582 {
3583 dxHiliteStyle nstyle = {foreColor,backColor,getApp()->getSelforeColor(),getApp()->getSelbackColor(),style,FALSE};
3584 m_textStyleList.append(nstyle);
3585 m_text->setHiliteStyles(m_textStyleList.data());
3586 }
3587
cutText(FXString text,FXint len)3588 dxStringArray IrcTabItem::cutText(FXString text, FXint len)
3589 {
3590 FXint previous = 0;
3591 FXint s = -1;
3592 FXint lw = 0;
3593 dxStringArray texts;
3594 for(FXint i = 0; i<text.length(); i++)
3595 {
3596 if(text[i] == ' ') s = i;
3597 if(lw>len)
3598 {
3599 if(s!=-1)
3600 {
3601 texts.append(text.mid(previous, s));
3602 i = s+1;
3603 s = -1;
3604 previous = i;
3605 }
3606 else
3607 {
3608 texts.append(text.mid(previous, lw));
3609 previous = previous+lw;
3610 }
3611 lw = 0;
3612 }
3613 lw++;
3614 }
3615 if(previous<text.length()) texts.append(text.right(text.length()-previous));
3616 return texts;
3617 }
3618
setCommandFocus()3619 void IrcTabItem::setCommandFocus()
3620 {
3621 m_commandline->setFocus();
3622 }
3623
3624 //for "handle" checking, if script contains "all". Send from dxirc.
setHasAllCommand(FXbool hasAll)3625 void IrcTabItem::setHasAllCommand(FXbool hasAll)
3626 {
3627 m_scriptHasAll = hasAll;
3628 }
3629
3630 //for "handle" checking, if script contains "ownmsg". Send from dxirc.
setHasOwnMsg(FXbool hasOwn)3631 void IrcTabItem::setHasOwnMsg(FXbool hasOwn)
3632 {
3633 m_scriptHasOwnMsg = hasOwn;
3634 }
3635
3636 //check need of highlight in msg
highlightNeeded(const FXString & msg)3637 FXbool IrcTabItem::highlightNeeded(const FXString &msg)
3638 {
3639 FXint pos = msg.find(getNickName());
3640 if(pos==-1) return FALSE;
3641 FXbool before = TRUE;
3642 FXbool after = FALSE;
3643 if(pos) before = isDelimiter(msg[pos-1]);
3644 if(pos+getNickName().length() == msg.length()) after = TRUE;
3645 if(pos+getNickName().length() < msg.length()) after = isDelimiter(msg[pos+getNickName().length()]);
3646 return before && after;
3647 }
3648
3649 //Load lines from logs
loadLogLines()3650 void IrcTabItem::loadLogLines()
3651 {
3652 if(m_type != CHANNEL && m_type != QUERY)
3653 return;
3654 if(!m_engine)
3655 return;
3656 if(!preferences.m_loadLog)
3657 return;
3658 if(m_logThread->running())
3659 {
3660 appendStyledText(_("Thread running, try again after some seconds"), 7, false, false, false);
3661 return;
3662 }
3663 appendIrcStyledText(_("Loading log..."), 11, FXSystem::now(), FALSE, FALSE);
3664 m_loadLog = TRUE;
3665 m_logThread->setList(false);
3666 m_logThread->setDirectory(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText());
3667 m_logThread->start();
3668 }
3669
3670 //List log files for tab
listLogFiles()3671 void IrcTabItem::listLogFiles()
3672 {
3673 if(m_logThread->running())
3674 {
3675 appendStyledText(_("Thread running, try again after some seconds"), 7, false, false, false);
3676 return;
3677 }
3678 m_logThread->setList(true);
3679 m_logThread->setDirectory(preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText());
3680 m_logThread->start();
3681 }
3682
showLog(const FXString & path)3683 void IrcTabItem::showLog(const FXString& path)
3684 {
3685 if(FXStat::exists(path))
3686 {
3687 FXString name = FXPath::name(path);
3688 clearChat();
3689 appendStyledText(FXStringFormat(_("Log from %s:"), name.text()), 7, FALSE, FALSE, FALSE);
3690 std::ifstream file(path.text());
3691 std::string line;
3692 FXString fxline;
3693 while(getline(file, line))
3694 {
3695 fxline = line.c_str();
3696 if(fxline.length()>12 && fxline[11]=='\014') //log style mark
3697 {
3698 FXint style = FXIntVal(fxline.after('\014').before('\014'));
3699 m_text->appendText(fxline.before('\014'));
3700 if(fxline.after('\014',2)[0]=='<') //has nick
3701 {
3702 FXString nick = fxline.after('<').before('>');
3703 FXString msg = fxline.after('>');
3704 appendLinkText(nick+":"+msg, style);
3705 }
3706 else appendLinkText(fxline.after('\014', 2), style);
3707 }
3708 else
3709 {
3710 if(fxline.length()>12 && fxline[11]=='<') //line with nick
3711 {
3712 m_text->appendText(fxline.before('<'));
3713 FXString nick = fxline.after('<').before('>');
3714 FXString msg = fxline.after('>').trimBegin();
3715 m_text->appendStyledText(nick+": ", getNickStyle(nick));
3716 if(preferences.m_stripColors) msg = dxutils::stripColors(msg, FALSE);
3717 appendLinkText(msg, 0);
3718 }
3719 else appendIrcText(fxline, 0, FALSE, FALSE);
3720 }
3721 }
3722 file.close();
3723 }
3724 else
3725 {
3726 appendStyledText(FXStringFormat(_("'%s' path doesn't exist"), path.text()), 4, false, false, false);
3727 }
3728 }
3729
completeHelpCommand()3730 void IrcTabItem::completeHelpCommand()
3731 {
3732 FXString line = m_commandline->getText();
3733 for(FXint i = 0; i < dxUtils.commandsNo(); i++)
3734 {
3735 if(comparecase(line.after(' '), dxUtils.commandsAt(i)) == 0)
3736 {
3737 if((i+1) < dxUtils.commandsNo()) m_commandline->setText("/HELP "+dxUtils.commandsAt(++i));
3738 else m_commandline->setText("/HELP "+dxUtils.commandsAt(0));
3739 break;
3740 }
3741 else if(comparecase(line.after(' '), dxUtils.commandsAt(i).left(line.after(' ').length())) == 0)
3742 {
3743 m_commandline->setText("/HELP "+dxUtils.commandsAt(i));
3744 break;
3745 }
3746 }
3747 }
3748
commandScript(const FXString & commandtext)3749 FXbool IrcTabItem::commandScript(const FXString &commandtext)
3750 {
3751 LuaRequest lua;
3752 lua.type = LUA_COMMAND;
3753 lua.text = commandtext.after('/');
3754 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_LUA), &lua);
3755 return TRUE;
3756 }
3757
commandAdmin(const FXString & commandtext)3758 FXbool IrcTabItem::commandAdmin(const FXString &commandtext)
3759 {
3760 if(m_engine->getConnected())
3761 {
3762 return m_engine->sendAdmin(commandtext.after(' '));
3763 }
3764 else
3765 {
3766 return notConnected();
3767 }
3768 }
3769
commandAway(const FXString & commandtext)3770 FXbool IrcTabItem::commandAway(const FXString &commandtext)
3771 {
3772 if(m_engine->getConnected())
3773 {
3774 if(commandtext.after(' ').length() > m_engine->getAwayLen())
3775 {
3776 appendIrcStyledText(FXStringFormat(_("Warning: Away message is too long. Max. away message length is %d."), m_engine->getAwayLen()), 4, FXSystem::now(), FALSE, FALSE);
3777 }
3778 return m_engine->sendAway(commandtext.after(' '));
3779 }
3780 else
3781 {
3782 return notConnected();
3783 }
3784 }
3785
commandBanlist(const FXString & commandtext)3786 FXbool IrcTabItem::commandBanlist(const FXString &commandtext)
3787 {
3788 if(m_engine->getConnected())
3789 {
3790 FXString channel = commandtext.after(' ');
3791 if(channel.empty() && m_type == CHANNEL)
3792 {
3793 return m_engine->sendBanlist(getText());
3794 }
3795 else if(!isChannel(channel) && m_type != CHANNEL)
3796 {
3797 appendIrcStyledText(_("/banlist <channel>, shows banlist for channel."), 4, FXSystem::now(), FALSE, FALSE);
3798 return FALSE;
3799 }
3800 else
3801 {
3802 return m_engine->sendBanlist(channel);
3803 }
3804 }
3805 else
3806 {
3807 return notConnected();
3808 }
3809 }
3810
commandBoats(const FXString & commandtext)3811 FXbool IrcTabItem::commandBoats(const FXString &commandtext)
3812 {
3813 if(m_engine->getConnected())
3814 {
3815 FXString to = commandtext.after(' ');
3816 if(to.empty())
3817 {
3818 appendIrcStyledText(_("/boats <nick>, invites someone to a boats game."), 4, FXSystem::now(), FALSE, FALSE);
3819 return FALSE;
3820 }
3821 else
3822 {
3823 return m_engine->sendCtcp(to, "BOATS INVITE");
3824 }
3825 }
3826 else
3827 {
3828 return notConnected();
3829 }
3830 }
3831
commandConnect(const FXString & commandtext)3832 FXbool IrcTabItem::commandConnect(const FXString &commandtext)
3833 {
3834 if(commandtext.after(' ').empty())
3835 {
3836 appendIrcStyledText(_("/connect <server> [port] [nick] [password] [realname] [channels], connects for given server."), 4, FXSystem::now(), FALSE, FALSE);
3837 return FALSE;
3838 }
3839 else
3840 {
3841 ServerInfo srv;
3842 srv.hostname = commandtext.after(' ').section(' ', 0);
3843 srv.port = commandtext.after(' ').section(' ', 1).empty() ? 6667 : FXIntVal(commandtext.after(' ').section(' ', 1));
3844 srv.nick = commandtext.after(' ').section(' ', 2).empty() ? FXSystem::currentUserName() : commandtext.after(' ').section(' ', 2);
3845 srv.passwd = commandtext.after(' ').section(' ', 3).empty() ? "" : commandtext.after(' ').section(' ', 3);
3846 srv.realname = commandtext.after(' ').section(' ', 4).empty() ? FXSystem::currentUserName() : commandtext.after(' ').section(' ', 4);
3847 srv.channels = commandtext.after(' ').section(' ', 5).empty() ? "" : commandtext.after(' ').section(' ', 5);
3848 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_CSERVER), &srv);
3849 return TRUE;
3850 }
3851 }
3852
commandCommands()3853 FXbool IrcTabItem::commandCommands()
3854 {
3855 appendIrcStyledText(dxUtils.availableCommands(), 3, FXSystem::now(), FALSE, FALSE);
3856 return TRUE;
3857 }
3858
commandCtcp(const FXString & commandtext)3859 FXbool IrcTabItem::commandCtcp(const FXString &commandtext)
3860 {
3861 if(m_engine->getConnected())
3862 {
3863 FXString to = commandtext.after(' ').before(' ');
3864 FXString msg = commandtext.after(' ', 2);
3865 if(to.empty() || msg.empty())
3866 {
3867 appendIrcStyledText(_("/ctcp <nick> <message>, sends a CTCP message to a user."), 4, FXSystem::now(), FALSE, FALSE);
3868 return FALSE;
3869 }
3870 if(msg.length() > m_maxLen-12-to.length())
3871 {
3872 appendIrcStyledText(FXStringFormat(_("Warning: ctcp message is too long. Max. ctcp message length is %d."), m_maxLen-12-to.length()), 4, FXSystem::now(), FALSE, FALSE);
3873 }
3874 return m_engine->sendCtcp(to, msg);
3875 }
3876 else
3877 {
3878 return notConnected();
3879 }
3880 }
3881
commandCycle(const FXString & commandtext)3882 FXbool IrcTabItem::commandCycle(const FXString &commandtext)
3883 {
3884 if(m_engine->getConnected())
3885 {
3886 if(m_type == CHANNEL)
3887 {
3888 if(isChannel(commandtext.after(' ')))
3889 {
3890 FXString channel = commandtext.after(' ').before(' ');
3891 FXString reason = commandtext.after(' ', 2);
3892 reason.empty() ? m_engine->sendPart(channel) : m_engine->sendPart(channel, reason);
3893 return m_engine->sendJoin(channel);
3894 }
3895 else
3896 {
3897 commandtext.after(' ').empty() ? m_engine->sendPart(getText()) : m_engine->sendPart(getText(), commandtext.after(' '));
3898 return m_engine->sendJoin(getText());
3899 }
3900 }
3901 else
3902 {
3903 if(isChannel(commandtext.after(' ')))
3904 {
3905 FXString channel = commandtext.after(' ').before(' ');
3906 FXString reason = commandtext.after(' ', 2);
3907 reason.empty() ? m_engine->sendPart(channel) : m_engine->sendPart(channel, reason);
3908 return m_engine->sendJoin(channel);
3909 }
3910 else
3911 {
3912 appendIrcStyledText(_("/cycle <channel> [message], leaves and join channel."), 4, FXSystem::now(), FALSE, FALSE);
3913 return FALSE;
3914 }
3915 }
3916 }
3917 else
3918 {
3919 return notConnected();
3920 }
3921 }
3922
commandDcc(const FXString & commandtext)3923 FXbool IrcTabItem::commandDcc(const FXString &commandtext)
3924 {
3925 if(m_engine->getConnected())
3926 {
3927 FXString dccCommand = dxutils::getParam(commandtext, 2, FALSE).lower();
3928 if(dccCommand == "chat")
3929 {
3930 FXString nick = dxutils::getParam(commandtext, 3, FALSE);
3931 if(!comparecase(nick, "chat"))
3932 {
3933 appendIrcStyledText(_("Nick for chat wasn't entered."), 4, FXSystem::now(), FALSE, FALSE);
3934 return FALSE;
3935 }
3936 if(!comparecase(nick, getNickName()))
3937 {
3938 appendIrcStyledText(_("Chat with yourself isn't good idea."), 4, FXSystem::now(), FALSE, FALSE);
3939 return FALSE;
3940 }
3941 IrcEvent ev;
3942 ev.eventType = IRC_DCCSERVER;
3943 ev.param1 = nick;
3944 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
3945 return TRUE;
3946 }
3947 else if(dccCommand == "send")
3948 {
3949 FXString nick = dxutils::getParam(commandtext, 3, FALSE);
3950 FXString file = dxutils::getParam(commandtext, 4, TRUE);
3951 if(!comparecase(nick, "send"))
3952 {
3953 appendIrcStyledText(_("Nick for sending file wasn't entered."), 4, FXSystem::now(), FALSE, FALSE);
3954 return FALSE;
3955 }
3956 if(!comparecase(nick, getNickName()))
3957 {
3958 appendIrcStyledText(_("Sending to yourself isn't good idea."), 4, FXSystem::now(), FALSE, FALSE);
3959 return FALSE;
3960 }
3961 if(!comparecase(nick, file))
3962 {
3963 appendIrcStyledText(_("Filename wasn't entered"), 4, FXSystem::now(), FALSE, FALSE);
3964 return FALSE;
3965 }
3966 if(!FXStat::exists(file))
3967 {
3968 appendIrcStyledText(FXStringFormat(_("File '%s' doesn't exist"), file.text()), 4, FXSystem::now(), FALSE, FALSE);
3969 return FALSE;
3970 }
3971 IrcEvent ev;
3972 ev.eventType = IRC_DCCOUT;
3973 ev.param1 = nick;
3974 ev.param2 = file;
3975 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
3976 return TRUE;
3977 }
3978 else if(dccCommand == "psend")
3979 {
3980 FXString nick = dxutils::getParam(commandtext, 3, FALSE);
3981 FXString file = dxutils::getParam(commandtext, 4, TRUE);
3982 if(!comparecase(nick, "psend"))
3983 {
3984 appendIrcStyledText(_("Nick for sending file wasn't entered."), 4, FXSystem::now(), FALSE, FALSE);
3985 return FALSE;
3986 }
3987 if(!comparecase(nick, getNickName()))
3988 {
3989 appendIrcStyledText(_("Sending to yourself isn't good idea."), 4, FXSystem::now(), FALSE, FALSE);
3990 return FALSE;
3991 }
3992 if(!comparecase(nick, file))
3993 {
3994 appendIrcStyledText(_("Filename wasn't entered"), 4, FXSystem::now(), FALSE, FALSE);
3995 return FALSE;
3996 }
3997 if(!FXStat::exists(file))
3998 {
3999 appendIrcStyledText(FXStringFormat(_("File '%s' doesn't exist"), file.text()), 4, FXSystem::now(), FALSE, FALSE);
4000 return FALSE;
4001 }
4002 IrcEvent ev;
4003 ev.eventType = IRC_DCCPOUT;
4004 ev.param1 = nick;
4005 ev.param2 = file;
4006 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4007 return TRUE;
4008 }
4009 else
4010 {
4011 appendIrcStyledText(FXStringFormat(_("'%s' isn't dcc command <chat|send|psend>"), dccCommand.text()), 4, FXSystem::now(), FALSE, FALSE);
4012 return FALSE;
4013 }
4014 }
4015 else
4016 {
4017 return notConnected();
4018 }
4019 }
4020
commandDeop(const FXString & commandtext)4021 FXbool IrcTabItem::commandDeop(const FXString &commandtext)
4022 {
4023 if(m_engine->getConnected())
4024 {
4025 FXString params = commandtext.after(' ');
4026 if(m_type == CHANNEL)
4027 {
4028 if(params.empty())
4029 {
4030 appendIrcStyledText(_("/deop <nicks>, removes operator status from one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4031 return FALSE;
4032 }
4033 else if(isChannel(params) && params.after(' ').empty())
4034 {
4035 appendIrcStyledText(_("/deop <channel> <nicks>, removes operator status from one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4036 return FALSE;
4037 }
4038 else if(isChannel(params) && !params.after(' ').empty())
4039 {
4040 FXString channel = params.before(' ');
4041 FXString nicks = params.after(' ');
4042 FXString modeparams = dxutils::createModes('-', 'o', nicks);
4043 return m_engine->sendMode(channel+" "+modeparams);
4044 }
4045 else
4046 {
4047 FXString channel = getText();
4048 FXString nicks = params;
4049 FXString modeparams = dxutils::createModes('-', 'o', nicks);
4050 return m_engine->sendMode(channel+" "+modeparams);
4051 }
4052 }
4053 else
4054 {
4055 if(isChannel(params) && !params.after(' ').empty())
4056 {
4057 FXString channel = params.before(' ');
4058 FXString nicks = params.after(' ');
4059 FXString modeparams = dxutils::createModes('-', 'o', nicks);
4060 return m_engine->sendMode(channel+" "+modeparams);
4061 }
4062 else
4063 {
4064 appendIrcStyledText(_("/deop <channel> <nicks>, removes operator status from one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4065 return FALSE;
4066 }
4067 }
4068 }
4069 else
4070 {
4071 return notConnected();
4072 }
4073 }
4074
commandDevoice(const FXString & commandtext)4075 FXbool IrcTabItem::commandDevoice(const FXString &commandtext)
4076 {
4077 if(m_engine->getConnected())
4078 {
4079 FXString params = commandtext.after(' ');
4080 if(m_type == CHANNEL)
4081 {
4082 if(params.empty())
4083 {
4084 appendIrcStyledText(_("/devoice <nicks>, removes voice from one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4085 return FALSE;
4086 }
4087 else if(isChannel(params) && params.after(' ').empty())
4088 {
4089 appendIrcStyledText(_("/devoice <channel> <nicks>, removes voice from one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4090 return FALSE;
4091 }
4092 else if(isChannel(params) && !params.after(' ').empty())
4093 {
4094 FXString channel = params.before(' ');
4095 FXString nicks = params.after(' ');
4096 FXString modeparams = dxutils::createModes('-', 'v', nicks);
4097 return m_engine->sendMode(channel+" "+modeparams);
4098 }
4099 else
4100 {
4101 FXString channel = getText();
4102 FXString nicks = params;
4103 FXString modeparams = dxutils::createModes('-', 'v', nicks);
4104 return m_engine->sendMode(channel+" "+modeparams);
4105 }
4106 }
4107 else
4108 {
4109 if(isChannel(params) && !params.after(' ').empty())
4110 {
4111 FXString channel = params.before(' ');
4112 FXString nicks = params.after(' ');
4113 FXString modeparams = dxutils::createModes('-', 'v', nicks);
4114 return m_engine->sendMode(channel+" "+modeparams);
4115 }
4116 else
4117 {
4118 appendIrcStyledText(_("/devoice <channel> <nicks>, removes voice from one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4119 return FALSE;
4120 }
4121 }
4122 }
4123 else
4124 {
4125 return notConnected();
4126 }
4127 }
4128
commandDisconnect(const FXString & commandtext)4129 FXbool IrcTabItem::commandDisconnect(const FXString &commandtext)
4130 {
4131 if(m_engine->getConnected())
4132 {
4133 if(commandtext.after(' ').empty()) m_engine->disconnect();
4134 else m_engine->disconnect(commandtext.after(' '));
4135 return TRUE;
4136 }
4137 else
4138 {
4139 m_engine->closeConnection(TRUE);
4140 return TRUE;
4141 }
4142 }
4143
commandDxirc()4144 FXbool IrcTabItem::commandDxirc()
4145 {
4146 for(FXint i=0; i<5+rand()%5; i++)
4147 {
4148 appendIrcText("", FXSystem::now(), FALSE, FALSE);
4149 }
4150 appendIrcText(" __ __ _", FXSystem::now(), FALSE, FALSE);
4151 appendIrcText(" _/__//__/|_ | | _", FXSystem::now(), FALSE, FALSE);
4152 appendIrcText(" /_| |_| |/_/| __| |__ __|_| _ _ ___", FXSystem::now(), FALSE, FALSE);
4153 appendIrcText(" |_ _ _|/ / _ |\\ \\/ /| || '_)/ __)", FXSystem::now(), FALSE, FALSE);
4154 appendIrcText(" /_| |_| |/_/| | (_| | | | | || | | (__", FXSystem::now(), FALSE, FALSE);
4155 appendIrcText(" |_ _ _|/ \\____|/_/\\_\\|_||_| \\___)", FXSystem::now(), FALSE, FALSE);
4156 appendIrcText(" |_|/|_|/ (c) 2008~ David Vachulka", FXSystem::now(), FALSE, FALSE);
4157 appendIrcText(" http://dxirc.org", FXSystem::now(), FALSE, FALSE);
4158 for(FXint i=0; i<5+rand()%5; i++)
4159 {
4160 appendIrcText("", FXSystem::now(), FALSE, FALSE);
4161 }
4162 return TRUE;
4163 }
4164
commandEgg()4165 FXbool IrcTabItem::commandEgg()
4166 {
4167 m_text->clearText();
4168 m_text->appendStyledText(FXString("ahoj sem pan Vajíčko.\n"), 3);
4169 getApp()->addTimeout(this, IrcTabItem_ETIME, 1000);
4170 m_pics = 0;
4171 return TRUE;
4172 }
4173
commandExec(const FXString & commandtext)4174 FXbool IrcTabItem::commandExec(const FXString &commandtext)
4175 {
4176 FXString params = commandtext.after(' ');
4177 if(params.empty())
4178 {
4179 appendIrcStyledText(_("/exec [-o|-c] <command>, executes command, -o sends output to channel/query, -c closes running command."), 4, FXSystem::now(), FALSE, FALSE);
4180 return FALSE;
4181 }
4182 else
4183 {
4184 if(!m_pipe) m_pipe = new dxPipe(getApp(), this);
4185 m_pipeStrings.clear();
4186 if(params.before(' ').contains("-o"))
4187 {
4188 m_sendPipe = TRUE;
4189 m_pipe->execCmd(params.after(' '));
4190 }
4191 else if(params.before(' ').contains("-c"))
4192 {
4193 m_sendPipe = FALSE;
4194 m_pipeStrings.clear();
4195 m_pipe->stopCmd();
4196 }
4197 else
4198 {
4199 m_sendPipe = FALSE;
4200 m_pipe->execCmd(params);
4201 }
4202 return TRUE;
4203 }
4204 }
4205
commandHelp(const FXString & commandtext)4206 FXbool IrcTabItem::commandHelp(const FXString &commandtext)
4207 {
4208 return showHelp(commandtext.after(' ').lower().trim());
4209 }
4210
commandIgnore(const FXString & commandtext)4211 FXbool IrcTabItem::commandIgnore(const FXString &commandtext)
4212 {
4213 FXString ignorecommand = commandtext.after(' ').before(' ');
4214 FXString ignoretext = commandtext.after(' ').after(' ');
4215 if(ignorecommand.empty())
4216 {
4217 appendIrcStyledText(_("/ignore <list|addcmd|rmcmd|addusr|rmusr> [command|user] [channel] [server]"), 4, FXSystem::now(), FALSE, FALSE);
4218 return FALSE;
4219 }
4220 if(comparecase(ignorecommand, "list")==0)
4221 {
4222 appendIrcStyledText(_("Ignored commands:"), 7, FXSystem::now(), FALSE, FALSE);
4223 if(preferences.m_ignoreCommandsList.empty()) appendIrcText(_("No ignored commands"), FXSystem::now(), FALSE, FALSE);
4224 else appendIrcText(preferences.m_ignoreCommandsList.rbefore(';'), FXSystem::now(), FALSE, FALSE);
4225 appendIrcStyledText(_("Ignored users:"), 7, FXSystem::now(), FALSE, FALSE);
4226 if(!preferences.m_ignoreUsersList.no()) appendIrcText(_("No ignored users"), FXSystem::now(), FALSE, FALSE);
4227 else
4228 {
4229 for(FXint i=0; i<preferences.m_ignoreUsersList.no(); i++)
4230 {
4231 appendIrcText(FXStringFormat(_("%s on channel(s): %s and network: %s"), preferences.m_ignoreUsersList[i].nick.text(), preferences.m_ignoreUsersList[i].channel.text(), preferences.m_ignoreUsersList[i].network.text()), FXSystem::now(), FALSE, FALSE);
4232 }
4233 }
4234 return TRUE;
4235 }
4236 else if(comparecase(ignorecommand, "addcmd")==0)
4237 {
4238 if(ignoretext.empty())
4239 {
4240 appendIrcStyledText(_("/ignore addcmd <command>, adds command to ignored commands."), 4, FXSystem::now(), FALSE, FALSE);
4241 return FALSE;
4242 }
4243 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_ADDICOMMAND), &ignoretext);
4244 return TRUE;
4245 }
4246 else if(comparecase(ignorecommand, "rmcmd")==0)
4247 {
4248 if(ignoretext.empty())
4249 {
4250 appendIrcStyledText(_("/ignore rmcmd <command>, removes command from ignored commands."), 4, FXSystem::now(), FALSE, FALSE);
4251 return FALSE;
4252 }
4253 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_RMICOMMAND), &ignoretext);
4254 return TRUE;
4255 }
4256 else if(comparecase(ignorecommand, "addusr")==0)
4257 {
4258 if(ignoretext.empty())
4259 {
4260 appendIrcStyledText(_("/ignore addusr <user> [channel] [server], adds user to ignored users."), 4, FXSystem::now(), FALSE, FALSE);
4261 return FALSE;
4262 }
4263 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_ADDIUSER), &ignoretext);
4264 return TRUE;
4265 }
4266 else if(comparecase(ignorecommand, "rmusr")==0)
4267 {
4268 if(ignoretext.empty())
4269 {
4270 appendIrcStyledText(_("/ignore rmusr <user>, removes user from ignored users."), 4, FXSystem::now(), FALSE, FALSE);
4271 return FALSE;
4272 }
4273 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_RMIUSER), &ignoretext);
4274 return TRUE;
4275 }
4276 else
4277 {
4278 appendIrcStyledText(FXStringFormat(_("'%s' isn't <list|addcmd|rmcmd|addusr|rmusr>"), ignorecommand.text()), 4, FXSystem::now(), FALSE, FALSE);
4279 return FALSE;
4280 }
4281 }
4282
commandInvite(const FXString & commandtext)4283 FXbool IrcTabItem::commandInvite(const FXString &commandtext)
4284 {
4285 if(m_engine->getConnected())
4286 {
4287 FXString params = commandtext.after(' ');
4288 if(params.empty())
4289 {
4290 appendIrcStyledText(_("/invite <nick> <channel>, invites someone to a channel."), 4, FXSystem::now(), FALSE, FALSE);
4291 return FALSE;
4292 }
4293 else if(isChannel(params) && params.after(' ').empty())
4294 {
4295 appendIrcStyledText(_("/invite <nick> <channel>, invites someone to a channel."), 4, FXSystem::now(), FALSE, FALSE);
4296 return FALSE;
4297 }
4298 else
4299 {
4300 FXString nick = params.before(' ');
4301 FXString channel = params.after(' ');
4302 return m_engine->sendInvite(nick, channel);
4303 }
4304 }
4305 else
4306 {
4307 return notConnected();
4308 }
4309 }
4310
commandJoin(const FXString & commandtext)4311 FXbool IrcTabItem::commandJoin(const FXString &commandtext)
4312 {
4313 if(m_engine->getConnected())
4314 {
4315 FXString channel = commandtext.after(' ');
4316 if(!isChannel(channel))
4317 {
4318 appendIrcStyledText(_("/join <channel>, joins a channel."), 4, FXSystem::now(), FALSE, FALSE);
4319 appendIrcStyledText(FXStringFormat(_("'%c' isn't valid char for channel."), channel[0]), 4, FXSystem::now(), FALSE, FALSE);
4320 return FALSE;
4321 }
4322 else
4323 {
4324 return m_engine->sendJoin(channel);
4325 }
4326 }
4327 else
4328 {
4329 return notConnected();
4330 }
4331 }
4332
commandKick(const FXString & commandtext)4333 FXbool IrcTabItem::commandKick(const FXString &commandtext)
4334 {
4335 if(m_engine->getConnected())
4336 {
4337 FXString params = commandtext.after(' ');
4338 if(m_type == CHANNEL)
4339 {
4340 if(params.empty())
4341 {
4342 appendIrcStyledText(_("/kick <nick>, kicks a user from a channel."), 4, FXSystem::now(), FALSE, FALSE);
4343 return FALSE;
4344 }
4345 else if(isChannel(params) && params.after(' ').empty())
4346 {
4347 appendIrcStyledText(_("/kick <channel> <nick>, kicks a user from a channel."), 4, FXSystem::now(), FALSE, FALSE);
4348 return FALSE;
4349 }
4350 else if(isChannel(params) && !params.after(' ').empty())
4351 {
4352 FXString channel = params.before(' ');
4353 FXString nick = params.after(' ');
4354 FXString reason = params.after(' ', 2);
4355 if(reason.length() > m_engine->getKickLen())
4356 {
4357 appendIrcStyledText(FXStringFormat(_("Warning: reason of kick is too long. Max. reason length is %d."), m_engine->getKickLen()), 4, FXSystem::now(), FALSE, FALSE);
4358 return m_engine->sendKick(channel, nick, reason);
4359 }
4360 else return m_engine->sendKick(channel, nick, reason);
4361 }
4362 else
4363 {
4364 FXString channel = getText();
4365 FXString nick = params.before(' ');
4366 FXString reason = params.after(' ');
4367 if(reason.length() > m_engine->getKickLen())
4368 {
4369 appendIrcStyledText(FXStringFormat(_("Warning: reason of kick is too long. Max. reason length is %d."), m_engine->getKickLen()), 4, FXSystem::now(), FALSE, FALSE);
4370 return m_engine->sendKick(channel, nick, reason);
4371 }
4372 else return m_engine->sendKick(channel, nick, reason);
4373 }
4374 }
4375 else
4376 {
4377 if(isChannel(params) && !params.after(' ').empty())
4378 {
4379 FXString channel = params.before(' ');
4380 FXString nick = params.after(' ');
4381 FXString reason = params.after(' ', 2);
4382 if(reason.length() > m_engine->getKickLen())
4383 {
4384 appendIrcStyledText(FXStringFormat(_("Warning: reason of kick is too long. Max. reason length is %d."), m_engine->getKickLen()), 4, FXSystem::now(), FALSE, FALSE);
4385 return m_engine->sendKick(channel, nick, reason);
4386 }
4387 else return m_engine->sendKick(channel, nick, reason);
4388 }
4389 else
4390 {
4391 appendIrcStyledText(_("/kick <channel> <nick>, kicks a user from a channel."), 4, FXSystem::now(), FALSE, FALSE);
4392 return FALSE;
4393 }
4394 }
4395 }
4396 else
4397 {
4398 return notConnected();
4399 }
4400 }
4401
commandKill(const FXString & commandtext)4402 FXbool IrcTabItem::commandKill(const FXString &commandtext)
4403 {
4404 if(m_engine->getConnected())
4405 {
4406 FXString params = commandtext.after(' ');
4407 FXString nick = params.before(' ');
4408 FXString reason = params.after(' ');
4409 if(params.empty())
4410 {
4411 appendIrcStyledText(_("/kill <user> [reason], kills a user from the network."), 4, FXSystem::now(), FALSE, FALSE);
4412 return FALSE;
4413 }
4414 if(reason.length() > m_maxLen-7-nick.length())
4415 {
4416 appendIrcStyledText(FXStringFormat(_("Warning: reason of kill is too long. Max. reason length is %d."), m_maxLen-7-nick.length()), 4, FXSystem::now(), FALSE, FALSE);
4417 }
4418 return m_engine->sendKill(nick, reason);
4419 }
4420 else
4421 {
4422 return notConnected();
4423 }
4424 }
4425
commandList(const FXString & commandtext)4426 FXbool IrcTabItem::commandList(const FXString &commandtext)
4427 {
4428 if(m_engine->getConnected())
4429 {
4430 return m_engine->sendList(commandtext.after(' '));
4431 }
4432 else
4433 {
4434 return notConnected();
4435 }
4436 }
4437
commandLog(const FXString & commandtext)4438 FXbool IrcTabItem::commandLog(const FXString &commandtext)
4439 {
4440 if(m_type == SERVER)
4441 {
4442 appendIrcStyledText(_("Server tab hasn't log files"), 4, FXSystem::now(), FALSE, FALSE);
4443 return TRUE;
4444 }
4445 FXString logcommand = commandtext.after(' ').before(' ');
4446 FXString logfile = commandtext.after(' ').after(' ');
4447 if(comparecase(logcommand, "list")==0)
4448 {
4449 listLogFiles();
4450 return TRUE;
4451 }
4452 else if(comparecase(logcommand, "show")==0)
4453 {
4454 if(logfile.empty())
4455 {
4456 logfile = FXSystem::time("%Y-%m-%d", FXSystem::now());
4457 }
4458 FXString logpath = preferences.m_logPath+PATHSEPSTRING+m_engine->getNetworkName()+PATHSEPSTRING+getText()+PATHSEPSTRING+logfile;
4459 if(!FXStat::exists(logpath))
4460 {
4461 appendIrcStyledText(FXStringFormat(_("Log file %s doesn't exist"), logfile.text()), 4, FXSystem::now(), FALSE, FALSE);
4462 return FALSE;
4463 }
4464 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_SHOWLOG), &logpath);
4465 return TRUE;
4466 }
4467 else
4468 {
4469 appendIrcStyledText(FXStringFormat(_("'%s' isn't <list|show>"), logcommand.text()), 4, FXSystem::now(), FALSE, FALSE);
4470 return FALSE;
4471 }
4472 }
4473
commandLua(const FXString & commandtext)4474 FXbool IrcTabItem::commandLua(const FXString &commandtext)
4475 {
4476 #ifdef HAVE_LUA
4477 FXString luacommand = commandtext.after(' ').before(' ');
4478 FXString luatext = commandtext.after(' ').after(' ');
4479 LuaRequest lua;
4480 if(luacommand.empty())
4481 {
4482 appendIrcStyledText(_("/lua <help|load|unload|list> [scriptpath|scriptname]"), 4, FXSystem::now(), FALSE, FALSE);
4483 return FALSE;
4484 }
4485 if(comparecase(luacommand, "help")==0)
4486 {
4487 appendIrcStyledText(FXStringFormat(_("For help about Lua scripting visit: %s"), LUA_HELP_PATH), 3, FXSystem::now(), FALSE, FALSE);
4488 return TRUE;
4489 }
4490 else if(comparecase(luacommand, "load")==0)
4491 {
4492 lua.type = LUA_LOAD;
4493 }
4494 else if(comparecase(luacommand, "unload")==0)
4495 {
4496 lua.type = LUA_UNLOAD;
4497 }
4498 else if(comparecase(luacommand, "list")==0)
4499 {
4500 lua.type = LUA_LIST;
4501 }
4502 else
4503 {
4504 appendIrcStyledText(FXStringFormat(_("'%s' isn't <help|load|unload|list>"), luacommand.text()), 4, FXSystem::now(), FALSE, FALSE);
4505 return FALSE;
4506 }
4507 lua.text = luatext;
4508 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_LUA), &lua);
4509 return TRUE;
4510 #else
4511 appendIrcStyledText(_("dxirc is compiled without support for Lua scripting"), 4, FXSystem::now(), FALSE, FALSE);
4512 return FALSE;
4513 #endif
4514 }
4515
commandMe(const FXString & commandtext)4516 FXbool IrcTabItem::commandMe(const FXString &commandtext)
4517 {
4518 if(m_engine->getConnected())
4519 {
4520 FXString params = commandtext.after(' ');
4521 if(m_type == CHANNEL)
4522 {
4523 if(params.empty())
4524 {
4525 appendIrcStyledText(_("/me <message>, sends the action to the current channel."), 4, FXSystem::now(), FALSE, FALSE);
4526 return FALSE;
4527 }
4528 else if(isChannel(params) && !params.after(' ').empty())
4529 {
4530 FXString channel = params.before(' ');
4531 FXString message = params.after(' ');
4532 if(message.length() > m_maxLen-19-channel.length())
4533 {
4534 dxStringArray messages = cutText(message, m_maxLen-19-channel.length());
4535 FXbool result = TRUE;
4536 for(FXint i=0; i<messages.no(); i++)
4537 {
4538 if(channel == getText())
4539 {
4540 appendIrcStyledText(getNickName()+" "+messages[i], 2, FXSystem::now());
4541 IrcEvent ev;
4542 ev.eventType = IRC_ACTION;
4543 ev.param1 = getNickName();
4544 ev.param2 = channel;
4545 ev.param3 = messages[i];
4546 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4547 }
4548 result = m_engine->sendMe(channel, messages[i]) &result;
4549 }
4550 return result;
4551 }
4552 else
4553 {
4554 if(channel == getText())
4555 {
4556 appendIrcStyledText(getNickName()+" "+message, 2, FXSystem::now());
4557 IrcEvent ev;
4558 ev.eventType = IRC_ACTION;
4559 ev.param1 = getNickName();
4560 ev.param2 = channel;
4561 ev.param3 = message;
4562 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4563 }
4564 return m_engine->sendMe(channel, message);
4565 }
4566 }
4567 else
4568 {
4569 if(params.length() > m_maxLen-19-getText().length())
4570 {
4571 dxStringArray messages = cutText(params, m_maxLen-19-getText().length());
4572 FXbool result = TRUE;
4573 for(FXint i=0; i<messages.no(); i++)
4574 {
4575 appendIrcStyledText(getNickName()+" "+messages[i], 2, FXSystem::now());
4576 IrcEvent ev;
4577 ev.eventType = IRC_ACTION;
4578 ev.param1 = getNickName();
4579 ev.param2 = getText();
4580 ev.param3 = messages[i];
4581 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4582 result = m_engine->sendMe(getText(), messages[i]) &result;
4583 }
4584 return result;
4585 }
4586 else
4587 {
4588 appendIrcStyledText(getNickName()+" "+params, 2, FXSystem::now());
4589 IrcEvent ev;
4590 ev.eventType = IRC_ACTION;
4591 ev.param1 = getNickName();
4592 ev.param2 = getText();
4593 ev.param3 = params;
4594 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4595 return m_engine->sendMe(getText(), params);
4596 }
4597 }
4598 }
4599 else if(m_type == QUERY)
4600 {
4601 if(params.empty())
4602 {
4603 appendIrcStyledText(_("/me <message>, sends the action to the current query."), 4, FXSystem::now(), FALSE, FALSE);
4604 return FALSE;
4605 }
4606 else
4607 {
4608 if(params.length() > m_maxLen-19-getText().length())
4609 {
4610 dxStringArray messages = cutText(params, m_maxLen-19-getText().length());
4611 FXbool result = TRUE;
4612 for(FXint i=0; i<messages.no(); i++)
4613 {
4614 appendIrcStyledText(getNickName()+" "+messages[i], 2, FXSystem::now());
4615 IrcEvent ev;
4616 ev.eventType = IRC_ACTION;
4617 ev.param1 = getNickName();
4618 ev.param2 = getText();
4619 ev.param3 = messages[i];
4620 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4621 result = m_engine->sendMe(getText(), messages[i]) &result;
4622 }
4623 return result;
4624 }
4625 else
4626 {
4627 appendIrcStyledText(getNickName()+" "+params, 2, FXSystem::now());
4628 IrcEvent ev;
4629 ev.eventType = IRC_ACTION;
4630 ev.param1 = getNickName();
4631 ev.param2 = getText();
4632 ev.param3 = params;
4633 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4634 return m_engine->sendMe(getText(), params);
4635 }
4636 }
4637 }
4638 else
4639 {
4640 if(!params.after(' ').empty())
4641 {
4642 FXString to = params.before(' ');
4643 FXString message = params.after(' ');
4644 if(message.length() > m_maxLen-19-to.length())
4645 {
4646 dxStringArray messages = cutText(message, m_maxLen-19-to.length());
4647 FXbool result = TRUE;
4648 for(FXint i=0; i<messages.no(); i++)
4649 {
4650 result = m_engine->sendMe(to, messages[i]) &result;
4651 }
4652 return result;
4653 }
4654 else
4655 {
4656 return m_engine->sendMe(to, message);
4657 }
4658 }
4659 else
4660 {
4661 appendIrcStyledText(_("/me <to> <message>, sends the action."), 4, FXSystem::now(), FALSE, FALSE);
4662 return FALSE;
4663 }
4664 }
4665 }
4666 else
4667 {
4668 return notConnected();
4669 }
4670 }
4671
commandMode(const FXString & commandtext)4672 FXbool IrcTabItem::commandMode(const FXString &commandtext)
4673 {
4674 if(m_engine->getConnected())
4675 {
4676 FXString params = commandtext.after(' ');
4677 if(params.empty())
4678 {
4679 appendIrcStyledText(_("/mode <channel> <modes>, sets modes for a channel."), 4, FXSystem::now(), FALSE, FALSE);
4680 return FALSE;
4681 }
4682 else
4683 {
4684 return m_engine->sendMode(params);
4685 }
4686 }
4687 else
4688 {
4689 return notConnected();
4690 }
4691 }
4692
commandMsg(const FXString & commandtext)4693 FXbool IrcTabItem::commandMsg(const FXString &commandtext)
4694 {
4695 if(m_engine->getConnected())
4696 {
4697 FXString params = commandtext.after(' ');
4698 FXString to = params.before(' ');
4699 FXString message = params.after(' ');
4700 if(!to.empty() && !message.empty())
4701 {
4702 if(message.length() > m_maxLen-10-to.length())
4703 {
4704 dxStringArray messages = cutText(message, m_maxLen-10-to.length());
4705 FXbool result = TRUE;
4706 for(FXint i=0; i<messages.no(); i++)
4707 {
4708 if(to == getText())
4709 {
4710 appendIrcNickText(getNickName(), messages[i], getNickStyle(getNickName()), FXSystem::now());
4711 IrcEvent ev;
4712 ev.eventType = IRC_PRIVMSG;
4713 ev.param1 = getNickName();
4714 ev.param2 = to;
4715 ev.param3 = messages[i];
4716 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4717 }
4718 result = m_engine->sendMsg(to, messages[i]) &result;
4719 }
4720 return result;
4721 }
4722 else
4723 {
4724 if(to == getText())
4725 {
4726 appendIrcNickText(getNickName(), message, getNickStyle(getNickName()), FXSystem::now());
4727 IrcEvent ev;
4728 ev.eventType = IRC_PRIVMSG;
4729 ev.param1 = getNickName();
4730 ev.param2 = to;
4731 ev.param3 = message;
4732 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4733 }
4734 return m_engine->sendMsg(to, message);
4735 }
4736 }
4737 else
4738 {
4739 appendIrcStyledText(_("/msg <nick/channel> <message>, sends a normal message."), 4, FXSystem::now(), FALSE, FALSE);
4740 return FALSE;
4741 }
4742 }
4743 else
4744 {
4745 return notConnected();
4746 }
4747 }
4748
commandNames(const FXString & commandtext)4749 FXbool IrcTabItem::commandNames(const FXString &commandtext)
4750 {
4751 if(m_engine->getConnected())
4752 {
4753 FXString params = commandtext.after(' ');
4754 if(m_type == CHANNEL)
4755 {
4756 if(params.empty())
4757 {
4758 return m_engine->sendNames(getText(), true);
4759 }
4760 else
4761 {
4762 return m_engine->sendNames(params, true);
4763 }
4764 }
4765 else
4766 {
4767 if(params.empty())
4768 {
4769 appendIrcStyledText(_("/names <channel>, for nicks on a channel."), 4, FXSystem::now(), FALSE, FALSE);
4770 return FALSE;
4771 }
4772 else
4773 {
4774 return m_engine->sendNames(params, true);
4775 }
4776 }
4777 }
4778 else
4779 {
4780 return notConnected();
4781 }
4782 }
4783
commandNick(const FXString & commandtext)4784 FXbool IrcTabItem::commandNick(const FXString &commandtext)
4785 {
4786 if(m_engine->getConnected())
4787 {
4788 FXString nick = commandtext.after(' ');
4789 if(nick.empty())
4790 {
4791 appendIrcStyledText(_("/nick <nick>, changes nick."), 4, FXSystem::now(), FALSE, FALSE);
4792 return FALSE;
4793 }
4794 else if(nick.length() > m_engine->getNickLen())
4795 {
4796 appendIrcStyledText(FXStringFormat(_("Warning: nick is too long. Max. nick length is %d."), m_engine->getNickLen()), 4, FXSystem::now(), FALSE, FALSE);
4797 return m_engine->sendNick(nick);
4798 }
4799 else
4800 {
4801 return m_engine->sendNick(nick);
4802 }
4803 }
4804 else
4805 {
4806 return notConnected();
4807 }
4808 }
4809
commandNotice(const FXString & commandtext)4810 FXbool IrcTabItem::commandNotice(const FXString &commandtext)
4811 {
4812 if(m_engine->getConnected())
4813 {
4814 FXString params = commandtext.after(' ');
4815 FXString to = params.before(' ');
4816 FXString message = params.after(' ');
4817 if(!to.empty() && !message.empty())
4818 {
4819 if(message.length() > m_maxLen-9-to.length())
4820 {
4821 dxStringArray messages = cutText(message, m_maxLen-9-to.length());
4822 FXbool result = TRUE;
4823 for(FXint i=0; i<messages.no(); i++)
4824 {
4825 appendIrcStyledText(FXStringFormat(_("NOTICE to %s: %s"), to.text(), messages[i].text()), 2, FXSystem::now());
4826 result = m_engine->sendNotice(to, messages[i]) &result;
4827 }
4828 return result;
4829 }
4830 else
4831 {
4832 appendIrcStyledText(FXStringFormat(_("NOTICE to %s: %s"), to.text(), message.text()), 2, FXSystem::now());
4833 return m_engine->sendNotice(to, message);
4834 }
4835 }
4836 else
4837 {
4838 appendIrcStyledText(_("/notice <nick/channel> <message>, sends a notice."), 4, FXSystem::now(), FALSE, FALSE);
4839 return FALSE;
4840 }
4841 }
4842 else
4843 {
4844 return notConnected();
4845 }
4846 }
4847
commandOp(const FXString & commandtext)4848 FXbool IrcTabItem::commandOp(const FXString &commandtext)
4849 {
4850 if(m_engine->getConnected())
4851 {
4852 FXString params = commandtext.after(' ');
4853 if(m_type == CHANNEL)
4854 {
4855 if(params.empty())
4856 {
4857 appendIrcStyledText(_("/op <nicks>, gives operator status for one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4858 return FALSE;
4859 }
4860 else if(isChannel(params) && params.after(' ').empty())
4861 {
4862 appendIrcStyledText(_("/op <channel> <nicks>, gives operator status for one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4863 return FALSE;
4864 }
4865 else if(isChannel(params) && !params.after(' ').empty())
4866 {
4867 FXString channel = params.before(' ');
4868 FXString nicks = params.after(' ');
4869 FXString modeparams = dxutils::createModes('+', 'o', nicks);
4870 return m_engine->sendMode(channel+" "+modeparams);
4871 }
4872 else
4873 {
4874 FXString channel = getText();
4875 FXString nicks = params;
4876 FXString modeparams = dxutils::createModes('+', 'o', nicks);
4877 return m_engine->sendMode(channel+" "+modeparams);
4878 }
4879 }
4880 else
4881 {
4882 if(isChannel(params) && !params.after(' ').empty())
4883 {
4884 FXString channel = params.before(' ');
4885 FXString nicks = params.after(' ');
4886 FXString modeparams = dxutils::createModes('+', 'o', nicks);
4887 return m_engine->sendMode(channel+" "+modeparams);
4888 }
4889 else
4890 {
4891 appendIrcStyledText(_("/op <channel> <nicks>, gives operator status for one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
4892 return FALSE;
4893 }
4894 }
4895 }
4896 else
4897 {
4898 return notConnected();
4899 }
4900 }
4901
commandOper(const FXString & commandtext)4902 FXbool IrcTabItem::commandOper(const FXString &commandtext)
4903 {
4904 if(m_engine->getConnected())
4905 {
4906 FXString params = commandtext.after(' ');
4907 FXString login = params.before(' ');
4908 FXString password = params.after(' ');
4909 if(!login.empty() && !password.empty())
4910 {
4911 return m_engine->sendOper(login, password);
4912 }
4913 else
4914 {
4915 appendIrcStyledText(_("/oper <login> <password>, oper up."), 4, FXSystem::now(), FALSE, FALSE);
4916 return FALSE;
4917 }
4918 }
4919 else
4920 {
4921 return notConnected();
4922 }
4923 }
4924
commandPart(const FXString & commandtext)4925 FXbool IrcTabItem::commandPart(const FXString &commandtext)
4926 {
4927 if(m_engine->getConnected())
4928 {
4929 if(m_type == CHANNEL)
4930 {
4931 if(commandtext.after(' ').empty())
4932 {
4933 return m_engine->sendPart(getText());
4934 }
4935 else
4936 {
4937 return m_engine->sendPart(getText(), commandtext.after(' '));
4938 }
4939 }
4940 else
4941 {
4942 if(isChannel(commandtext.after(' ')))
4943 {
4944 FXString channel = commandtext.after(' ').before(' ');
4945 FXString reason = commandtext.after(' ', 2);
4946 if(reason.empty())
4947 {
4948 return m_engine->sendPart(channel);
4949 }
4950 else
4951 {
4952 return m_engine->sendPart(channel, reason);
4953 }
4954 }
4955 else
4956 {
4957 appendIrcStyledText(_("/part <channel> [reason], leaves channel."), 4, FXSystem::now(), FALSE, FALSE);
4958 return FALSE;
4959 }
4960 }
4961 }
4962 else
4963 {
4964 return notConnected();
4965 }
4966 }
4967
commandQuery(const FXString & commandtext)4968 FXbool IrcTabItem::commandQuery(const FXString &commandtext)
4969 {
4970 if(m_engine->getConnected())
4971 {
4972 if(commandtext.after(' ').empty())
4973 {
4974 appendIrcStyledText(_("/query <nick>, opens query with nick."), 4, FXSystem::now(), FALSE, FALSE);
4975 return FALSE;
4976 }
4977 else
4978 {
4979 IrcEvent ev;
4980 ev.eventType = IRC_QUERY;
4981 ev.param1 = commandtext.after(' ').before(' ');
4982 ev.param2 = getNickName();
4983 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
4984 return TRUE;
4985 }
4986 }
4987 else
4988 {
4989 return notConnected();
4990 }
4991 }
4992
commandQuit()4993 FXbool IrcTabItem::commandQuit()
4994 {
4995 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_CQUIT), NULL);
4996 return TRUE;
4997 }
4998
commandQuote(const FXString & commandtext)4999 FXbool IrcTabItem::commandQuote(const FXString &commandtext)
5000 {
5001 if(m_engine->getConnected())
5002 {
5003 return m_engine->sendQuote(commandtext.after(' '));
5004 }
5005 else
5006 {
5007 return notConnected();
5008 }
5009 }
5010
commandSay(const FXString & commandtext)5011 FXbool IrcTabItem::commandSay(const FXString &commandtext)
5012 {
5013 if(m_engine->getConnected())
5014 {
5015 if (m_type != SERVER && !commandtext.after(' ').empty())
5016 {
5017 if(commandtext.after(' ').length() > m_maxLen-10-getText().length())
5018 {
5019 dxStringArray messages = cutText(commandtext.after(' '), m_maxLen-10-getText().length());
5020 FXbool result = TRUE;
5021 for(FXint i=0; i<messages.no(); i++)
5022 {
5023 appendMyMsg(messages[i], FXSystem::now());
5024 IrcEvent ev;
5025 ev.eventType = IRC_PRIVMSG;
5026 ev.param1 = getNickName();
5027 ev.param2 = getText();
5028 ev.param3 = messages[i];
5029 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
5030 result = m_engine->sendMsg(getText(), messages[i]) &result;
5031 }
5032 return result;
5033 }
5034 else
5035 {
5036 appendMyMsg(commandtext.after(' '), FXSystem::now());
5037 IrcEvent ev;
5038 ev.eventType = IRC_PRIVMSG;
5039 ev.param1 = getNickName();
5040 ev.param2 = getText();
5041 ev.param3 = commandtext.after(' ');
5042 m_parent->getParent()->getParent()->handle(m_engine, FXSEL(SEL_COMMAND, IrcEngine_SERVER), &ev);
5043 return m_engine->sendMsg(getText(), commandtext.after(' '));
5044 }
5045 }
5046 return FALSE;
5047 }
5048 else
5049 {
5050 return notConnected();
5051 }
5052 }
5053
commandStats(const FXString & commandtext)5054 FXbool IrcTabItem::commandStats(const FXString &commandtext)
5055 {
5056 if(m_engine->getConnected())
5057 {
5058 return m_engine->sendStats(commandtext.after(' '));
5059 }
5060 else
5061 {
5062 return notConnected();
5063 }
5064 }
5065
commandTetris()5066 FXbool IrcTabItem::commandTetris()
5067 {
5068 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_NEWTETRIS), NULL);
5069 return TRUE;
5070 }
5071
commandTime()5072 FXbool IrcTabItem::commandTime()
5073 {
5074 if(m_engine->getConnected())
5075 {
5076 return m_engine->sendQuote("TIME");
5077 }
5078 else
5079 {
5080 return notConnected();
5081 }
5082 }
5083
commandTopic(const FXString & commandtext)5084 FXbool IrcTabItem::commandTopic(const FXString &commandtext)
5085 {
5086 if(m_engine->getConnected())
5087 {
5088 FXString params = commandtext.after(' ');
5089 if(m_type == CHANNEL)
5090 {
5091 if(params.empty())
5092 {
5093 return m_engine->sendTopic(getText());
5094 }
5095 else if(isChannel(params) && !params.after(' ').empty())
5096 {
5097 FXString channel = params.before(' ');
5098 FXString topic = params.after(' ');
5099 if(topic.length() > m_engine->getTopicLen())
5100 {
5101 appendIrcStyledText(FXStringFormat(_("Warning: topic is too long. Max. topic length is %d."), m_engine->getTopicLen()), 4, FXSystem::now(), FALSE, FALSE);
5102 }
5103 return m_engine->sendTopic(channel, topic);
5104 }
5105 else
5106 {
5107 if(params.length() > m_engine->getTopicLen())
5108 {
5109 appendIrcStyledText(FXStringFormat(_("Warning: topic is too long. Max. topic length is %d."), m_engine->getTopicLen()), 4, FXSystem::now(), FALSE, FALSE);
5110 }
5111 return m_engine->sendTopic(getText(), params);
5112 }
5113 }
5114 else
5115 {
5116 if(isChannel(params))
5117 {
5118 FXString channel = params.before(' ');
5119 FXString topic = params.after(' ');
5120 if(topic.length() > m_engine->getTopicLen())
5121 {
5122 appendIrcStyledText(FXStringFormat(_("Warning: topic is too long. Max. topic length is %d."), m_engine->getTopicLen()), 4, FXSystem::now(), FALSE, FALSE);
5123 }
5124 return m_engine->sendTopic(channel, topic);
5125 }
5126 else
5127 {
5128 appendIrcStyledText(_("/topic <channel> [topic], views or changes channel topic."), 4, FXSystem::now(), FALSE, FALSE);
5129 return FALSE;
5130 }
5131 }
5132 }
5133 else
5134 {
5135 return notConnected();
5136 }
5137 }
5138
commandVoice(const FXString & commandtext)5139 FXbool IrcTabItem::commandVoice(const FXString &commandtext)
5140 {
5141 if(m_engine->getConnected())
5142 {
5143 FXString params = commandtext.after(' ');
5144 if(m_type == CHANNEL)
5145 {
5146 if(params.empty())
5147 {
5148 appendIrcStyledText(_("/voice <nicks>, gives voice for one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
5149 return FALSE;
5150 }
5151 else if(isChannel(params) && params.after(' ').empty())
5152 {
5153 appendIrcStyledText(_("/voice <channel> <nicks>, gives voice for one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
5154 return FALSE;
5155 }
5156 else if(isChannel(params) && !params.after(' ').empty())
5157 {
5158 FXString channel = params.before(' ');
5159 FXString nicks = params.after(' ');
5160 FXString modeparams = dxutils::createModes('+', 'v', nicks);
5161 return m_engine->sendMode(channel+" "+modeparams);
5162 }
5163 else
5164 {
5165 FXString channel = getText();
5166 FXString nicks = params;
5167 FXString modeparams = dxutils::createModes('+', 'v', nicks);
5168 return m_engine->sendMode(channel+" "+modeparams);
5169 }
5170 }
5171 else
5172 {
5173 if(isChannel(params) && !params.after(' ').empty())
5174 {
5175 FXString channel = params.before(' ');
5176 FXString nicks = params.after(' ');
5177 FXString modeparams = dxutils::createModes('+', 'v', nicks);
5178 return m_engine->sendMode(channel+" "+modeparams);
5179 }
5180 else
5181 {
5182 appendIrcStyledText(_("/voice <channel> <nicks>, gives voice for one or more nicks."), 4, FXSystem::now(), FALSE, FALSE);
5183 return FALSE;
5184 }
5185 }
5186 }
5187 else
5188 {
5189 return notConnected();
5190 }
5191 }
5192
commandWallops(const FXString & commandtext)5193 FXbool IrcTabItem::commandWallops(const FXString &commandtext)
5194 {
5195 if(m_engine->getConnected())
5196 {
5197 FXString params = commandtext.after(' ');
5198 if(params.empty())
5199 {
5200 appendIrcStyledText(_("/wallops <message>, sends wallop message."), 4, FXSystem::now(), FALSE, FALSE);
5201 return FALSE;
5202 }
5203 else
5204 {
5205 if(params.length() > m_maxLen-9)
5206 {
5207 dxStringArray messages = cutText(params, m_maxLen-9);
5208 FXbool result = TRUE;
5209 for(FXint i=0; i<messages.no(); i++)
5210 {
5211 result = m_engine->sendWallops(messages[i]) &result;
5212 }
5213 return result;
5214 }
5215 else return m_engine->sendWallops(params);
5216 }
5217 }
5218 else
5219 {
5220 return notConnected();
5221 }
5222 }
5223
commandWho(const FXString & commandtext)5224 FXbool IrcTabItem::commandWho(const FXString &commandtext)
5225 {
5226 if(m_engine->getConnected())
5227 {
5228 FXString params = commandtext.after(' ');
5229 if(params.empty())
5230 {
5231 appendIrcStyledText(_("/who <mask> [o], searchs for mask on network, if o is supplied, only search for opers."), 4, FXSystem::now(), FALSE, FALSE);
5232 return FALSE;
5233 }
5234 else
5235 {
5236 return m_engine->sendWho(params);
5237 }
5238 }
5239 else
5240 {
5241 return notConnected();
5242 }
5243 }
5244
commandWhoami()5245 FXbool IrcTabItem::commandWhoami()
5246 {
5247 if(m_engine->getConnected())
5248 {
5249 return m_engine->sendWhoami();
5250 }
5251 else
5252 {
5253 return notConnected();
5254 }
5255 }
5256
commandWhois(const FXString & commandtext)5257 FXbool IrcTabItem::commandWhois(const FXString &commandtext)
5258 {
5259 if(m_engine->getConnected())
5260 {
5261 FXString params = commandtext.after(' ');
5262 if(params.empty())
5263 {
5264 if(m_type == QUERY)
5265 {
5266 return m_engine->sendWhois(getText());
5267 }
5268 appendIrcStyledText(_("/whois <nick>, whois nick."), 4, FXSystem::now(), FALSE, FALSE);
5269 return FALSE;
5270 }
5271 else
5272 {
5273 return m_engine->sendWhois(params);
5274 }
5275 }
5276 else
5277 {
5278 return notConnected();
5279 }
5280 }
5281
commandWhowas(const FXString & commandtext)5282 FXbool IrcTabItem::commandWhowas(const FXString &commandtext)
5283 {
5284 if(m_engine->getConnected())
5285 {
5286 FXString params = commandtext.after(' ');
5287 if(params.empty())
5288 {
5289 appendIrcStyledText(_("/whowas <nick>, whowas nick."), 4, FXSystem::now(), FALSE, FALSE);
5290 return FALSE;
5291 }
5292 else
5293 {
5294 return m_engine->sendWhowas(params);
5295 }
5296 }
5297 else
5298 {
5299 return notConnected();
5300 }
5301 }
5302
5303 //fire request for connect dialog
notConnected()5304 FXbool IrcTabItem::notConnected()
5305 {
5306 appendIrcStyledText(_("You aren't connected"), 4, FXSystem::now(), FALSE, FALSE);
5307 m_parent->getParent()->getParent()->handle(this, FXSEL(SEL_COMMAND, IrcTabItem_CDIALOG), NULL);
5308 return TRUE;
5309 }
5310
5311