1 /*
2  *      dxirc.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 #else
26  #include <fcntl.h>
27  #include <stdlib.h>
28  #include <unistd.h>
29  #include <errno.h>
30  #include <signal.h>
31 #endif
32 
33 #include <string>
34 #include "defs.h"
35 #include "config.h"
36 #include "dxutils.h"
37 #include "FXTrayApp.h"
38 #include "dialogs/logviewer.h"
39 #include "dialogs/dccdialog.h"
40 #include "tabitems/dxtabbook.h"
41 #include "engine/ircengine.h"
42 #include "engine/dccengine.h"
43 #include "icons.h"
44 #include "i18n.h"
45 #include "help.h"
46 #include "tabitems/irctabitem.h"
47 #include "tabitems/dcctabitem.h"
48 #include "dialogs/configdialog.h"
49 #include "dialogs/serverdialog.h"
50 #include "dialogs/aliasdialog.h"
51 #include "tabitems/tetristabitem.h"
52 #include "tabitems/boatstabitem.h"
53 #include "dialogs/scriptdialog.h"
54 #include "dialogs/aboutdialog.h"
55 #include "dialogs/helpdialog.h"
56 #include "dialogs/listdialog.h"
57 #ifdef HAVE_X11
58  #include <X11/Xlib.h>
59 #endif //HAVE_X11
60 #ifdef HAVE_LUA
61 extern "C" {
62 #include <lua.h>
63 #include <lualib.h>
64 #include <lauxlib.h>
65 }
66 #endif
67 #include "dxirc.h"
68 
69 #define DISPLAY(app) ((Display*)((app)->getDisplay()))
70 
71 int argn; //argc for restart
72 char** args; //argv for restart
73 
74 #ifndef WIN32
dxunlink(void)75 void dxunlink(void)
76 {
77     unlink(FXString(FXSystem::getTempDirectory()+PATHSEPSTRING+"dxirc-"+FXSystem::currentUserName()).text());
78 }
79 #endif
80 
81 // For handling Single Instance of Application
IsInstanceRunningAlready()82 void IsInstanceRunningAlready()
83 {
84 #ifdef WIN32
85     HANDLE hSingleInstance = NULL;
86     hSingleInstance = CreateMutex( NULL, FALSE, TEXT("dxirc.exe"));
87     DWORD dwLastError = GetLastError();
88     if(dwLastError == ERROR_ALREADY_EXISTS)
89     {
90         MessageBox(NULL, TEXT("dxirc already running"), TEXT("dxirc"), MB_OK | MB_ICONINFORMATION);
91         CloseHandle(hSingleInstance);
92         exit(1);
93     }
94 #else
95     FXString path = FXSystem::getTempDirectory()+PATHSEPSTRING+"dxirc-"+FXSystem::currentUserName();
96     struct flock fl;
97     int fd;
98     fd = open(path.text(), O_RDWR | O_CREAT, 0600);
99     if(fd < 0)
100     {
101         perror(path.text());
102         _exit(1);
103     }
104     fl.l_start = 0;
105     fl.l_len = 0;
106     fl.l_type = F_WRLCK;
107     fl.l_whence = SEEK_SET;
108     if(fcntl(fd, F_SETLK, &fl) < 0)
109     {
110         FXApp application("dxirc");
111         application.init(argn, args);
112         FXMainWindow *main = new FXMainWindow(&application, "dxirc", NULL, NULL, DECOR_TITLE|DECOR_CLOSE);
113         new FXLabel(main, "dxirc already running");
114         new FXButton(main, "C&lose", NULL, &application, FXApp::ID_QUIT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_CENTER_X);
115         application.create();
116         main->show(PLACEMENT_SCREEN);
117         application.run();
118         _exit(1);
119     }
120     atexit(dxunlink);
121 #endif
122 }
123 
CompareTabs(const void ** a,const void ** b)124 int CompareTabs(const void **a,const void **b)
125 {
126     dxTabItem *fa = (dxTabItem*)*a;
127     dxTabItem *fb = (dxTabItem*)*b;
128     return comparecase((fa->getType() == SERVER ? fa->getRealServerName() : fa->getRealServerName()+fa->getText()), (fb->getType() == SERVER ? fb->getRealServerName() : fb->getRealServerName()+fb->getText()));
129 }
130 
131 /*from Goggles Music Manager
132 thanks Sander Jansen */
133 #ifdef ENABLE_NLS
134 #include <FXTranslator.h>
135 #include <fxdefs.h>
136 
137 class dxTranslator : public FXTranslator
138 {
139     FXDECLARE(dxTranslator)
140 private:
141     dxTranslator(const dxTranslator&);
142     dxTranslator & operator=(const dxTranslator&);
143 protected:
dxTranslator()144     dxTranslator() {
145     }
146 public:
147     /// Construct translator
148 
dxTranslator(FXApp * a)149     dxTranslator(FXApp* a) : FXTranslator(a) {
150 #ifndef WIN32
151         setlocale(LC_MESSAGES, "");
152         setlocale(LC_NUMERIC, "C");
153 #endif //WIN32
154         bindtextdomain("dxirc", LOCALEDIR);
155         bind_textdomain_codeset("dxirc", "UTF-8");
156         textdomain("dxirc");
157         dxUtils.debugLine(FXStringFormat("localedir: %s", LOCALEDIR));
158     }
159 
160     virtual const FXchar* tr(const FXchar* context, const FXchar* message, const FXchar* hint = NULL) const;
161 
~dxTranslator()162     ~dxTranslator() {}
163 };
164 
165 FXIMPLEMENT(dxTranslator, FXTranslator, NULL, 0)
166 
tr(const FXchar *,const FXchar * message,const FXchar *) const167 const FXchar* dxTranslator::tr(const FXchar*, const FXchar* message, const FXchar*) const {
168     return gettext(message);
169 }
170 #endif //ENABLE_NLS
171 
172 FXDEFMAP(dxirc) dxircMap[] = {
173     FXMAPFUNC(SEL_CLOSE,            0,                      dxirc::onCmdClose),
174     FXMAPFUNC(SEL_COMMAND,          dxirc_QUIT,             dxirc::onCmdQuit),
175     FXMAPFUNC(SEL_COMMAND,          dxirc_RESTART,          dxirc::onCmdRestart),
176     FXMAPFUNC(SEL_COMMAND,          dxirc_ABOUT,            dxirc::onCmdAbout),
177     FXMAPFUNC(SEL_COMMAND,          dxirc_CONNECT,          dxirc::onCmdConnect),
178     FXMAPFUNC(SEL_COMMAND,          dxirc_DISCONNECT,       dxirc::onCmdDisconnect),
179     FXMAPFUNC(SEL_COMMAND,          dxirc_RECONNECT,        dxirc::onCmdReconnect),
180     FXMAPFUNC(SEL_COMMAND,          dxirc_SERVERS,          dxirc::onCmdServers),
181     FXMAPFUNC(SEL_COMMAND,          dxirc_TABS,             dxirc::onTabBook),
182     FXMAPFUNC(SEL_COMMAND,          dxirc_CLEAR,            dxirc::onCmdClear),
183     FXMAPFUNC(SEL_COMMAND,          dxirc_CLEARALL,         dxirc::onCmdClearAll),
184     FXMAPFUNC(SEL_COMMAND,          dxirc_CLOSETAB,         dxirc::onCmdCloseTab),
185     FXMAPFUNC(SEL_COMMAND,          dxirc_USERS,            dxirc::onCmdUsers),
186     FXMAPFUNC(SEL_COMMAND,          dxirc_STATUS,           dxirc::onCmdStatus),
187     FXMAPFUNC(SEL_COMMAND,          dxirc_HELP,             dxirc::onCmdHelp),
188     FXMAPFUNC(SEL_COMMAND,          dxirc_OPTIONS,          dxirc::onCmdOptions),
189     FXMAPFUNC(SEL_COMMAND,          dxirc_SELECTTAB,        dxirc::onCmdSelectTab),
190     FXMAPFUNC(SEL_COMMAND,          dxirc_NEXTTAB,          dxirc::onCmdNextTab),
191     FXMAPFUNC(SEL_COMMAND,          dxirc_MOVETAB,          dxirc::onCmdMoveTab),
192     FXMAPFUNC(SEL_MOUSEWHEEL,       dxirc_TABS,             dxirc::onMouseWheel),
193     FXMAPFUNC(SEL_COMMAND,          dxirc_NEXTUNREAD,       dxirc::onCmdNextUnread),
194     FXMAPFUNC(SEL_COMMAND,          dxirc_ALIAS,            dxirc::onCmdAlias),
195     FXMAPFUNC(SEL_COMMAND,          dxirc_LOG,              dxirc::onCmdLog),
196     FXMAPFUNC(SEL_COMMAND,          dxirc_TRANSFERS,        dxirc::onCmdTransfers),
197     FXMAPFUNC(SEL_COMMAND,          dxirc_TRAY,             dxirc::onTrayClicked),
198     FXMAPFUNC(SEL_COMMAND,          dxirc_SCRIPTS,          dxirc::onCmdScripts),
199     FXMAPFUNC(SEL_TIMEOUT,          dxirc_STIMEOUT,         dxirc::onStatusTimeout),
200     FXMAPFUNC(SEL_KEYPRESS,         0,                      dxirc::onKeyPress),
201     FXMAPFUNC(SEL_COMMAND,          IrcEngine_SERVER,       dxirc::onIrcEvent),
202     FXMAPFUNC(SEL_COMMAND,          DccEngine_DCC,          dxirc::onDccEvent),
203     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_CDIALOG,     dxirc::onCmdConnect),
204     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_CSERVER,     dxirc::onTabConnect),
205     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_CQUIT,       dxirc::onCmdQuit),
206     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_NEWMSG,      dxirc::onNewMsg),
207     FXMAPFUNC(SEL_COMMAND,          DccTabItem_NEWMSG,      dxirc::onNewMsg),
208     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_LUA,         dxirc::onLua),
209     FXMAPFUNC(SEL_COMMAND,          DccTabItem_LUA,         dxirc::onLua),
210     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_COMMAND,     dxirc::onIrcCommand),
211     FXMAPFUNC(SEL_COMMAND,          DccTabItem_COMMAND,     dxirc::onIrcCommand),
212     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_OWNMSG,      dxirc::onIrcOwnMsg),
213     FXMAPFUNC(SEL_COMMAND,          DccTabItem_OWNMSG,      dxirc::onIrcOwnMsg),
214     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_NEWTETRIS,   dxirc::onNewTetris),
215     FXMAPFUNC(SEL_COMMAND,          DccTabItem_NEWTETRIS,   dxirc::onNewTetris),
216     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_ADDICOMMAND, dxirc::onAddIgnoreCommand),
217     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_RMICOMMAND,  dxirc::onRemoveIgnoreCommand),
218     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_ADDIUSER,    dxirc::onAddIgnoreUser),
219     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_RMIUSER,     dxirc::onRemoveIgnoreUser),
220     FXMAPFUNC(SEL_COMMAND,          DccDialog_DCCCANCEL,    dxirc::onCmdDccCancel),
221     FXMAPFUNC(SEL_COMMAND,          dxirc_SPELL,            dxirc::onCmdSpell),
222     FXMAPFUNC(SEL_COMMAND,          dxirc_FORCEFOCUS,       dxirc::onCmdForceFocus),
223     FXMAPFUNC(SEL_TIMEOUT,          dxirc_AWAYTIMEOUT,      dxirc::onAwayTimeout),
224     FXMAPFUNC(SEL_COMMAND,          dxirc_VERSION,          dxirc::onCmdCheckVersion),
225     FXMAPFUNC(SOCKET_CONNECTED,     dxirc_VERSIONSOCKET,    dxirc::onVersionSocketConnected),
226     FXMAPFUNC(SOCKET_CANREAD,       dxirc_VERSIONSOCKET,    dxirc::onVersionSocketCanRead),
227     FXMAPFUNC(SOCKET_ERR,           dxirc_VERSIONSOCKET,    dxirc::onVersionSocketError),
228     FXMAPFUNC(SEL_COMMAND,          DccTabItem_SHOWLOG,     dxirc::onShowLog),
229     FXMAPFUNC(SEL_COMMAND,          IrcTabItem_SHOWLOG,     dxirc::onShowLog),
230     FXMAPFUNC(SEL_TIMEOUT,          dxirc_NOTIFYHIDE,       dxirc::onNotifyHide),
231     FXMAPFUNC(SEL_COMMAND,          dxirc_LIST,             dxirc::onCmdList)
232 };
233 
234 FXIMPLEMENT(dxirc, FXMainWindow, dxircMap, ARRAYNUMBER(dxircMap))
235 
236 dxirc *dxirc::_pThis = NULL;
237 #ifdef HAVE_LUA
238 static luaL_Reg dxircFunctions[] = {
239     {"AddCommand",      dxirc::onLuaAddCommand},
240     {"AddEvent",        dxirc::onLuaAddEvent},
241     {"RemoveName",      dxirc::onLuaRemoveName},
242     {"Command",         dxirc::onLuaCommand},
243     {"Print",           dxirc::onLuaPrint},
244     {"GetServers",      dxirc::onLuaGetServers},
245     {"GetTab",          dxirc::onLuaGetTab},
246     {"GetCurrentTab",   dxirc::onLuaGetCurrentTab},
247     {"GetVersion",      dxirc::onLuaGetVersion},
248     {"GetTabInfo",      dxirc::onLuaGetTabInfo},
249     {"SetTab",          dxirc::onLuaSetTab},
250     {"CreateTab",       dxirc::onLuaCreateTab},
251     {"GetTabCount",     dxirc::onLuaGetTabCount},
252     {"Clear",           dxirc::onLuaClear},
253     {"GetChannelNames", dxirc::onLuaGetChannelNames},
254     {NULL,              NULL}
255 };
256 #endif //HAVE_LUA
257 
dxirc(FXApp * app)258 dxirc::dxirc(FXApp *app)
259     : FXMainWindow(app, "dxirc", 0, 0, DECOR_ALL, 0, 0, 800, 600), m_app(app), m_trayIcon(NULL)
260 {
261     setIcon(ICO_BIG);
262     setMiniIcon(ICO_SMALL);
263 
264     m_viewer = NULL;
265     m_transfers = NULL;
266     m_traymenu = NULL;
267     m_lastToken = 0;
268     m_lastID = 0;
269     m_versionSocket = NULL;
270     m_firstNotify = false;
271     m_notifiesHeight = 0;
272 
273     m_preferences.load();
274     if(!m_preferences.m_ircFont.empty())
275     {
276         m_ircFont = new FXFont(m_app, m_preferences.m_ircFont);
277         m_ircFont->create();
278     }
279     else
280     {
281         m_app->getNormalFont()->create();
282         FXFontDesc fontdescription;
283         m_app->getNormalFont()->getFontDesc(fontdescription);
284         m_ircFont = new FXFont(m_app,fontdescription);
285         m_ircFont->create();
286     }
287     setTempKeybindings(m_preferences.m_keybindings);
288 
289     m_menubar = new FXMenuBar(this, FRAME_RAISED|LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
290 
291     m_servermenu = new FXMenuPane(this);
292     new FXMenuCommand(m_servermenu, _("&Server list")+TAB+m_preferences.getBinding("serverList"), ICO_SERVERLIST, this, dxirc_SERVERS);
293     new FXMenuCommand(m_servermenu, _("Quick &connect")+TAB+m_preferences.getBinding("quickConnect"), ICO_CONNECT, this, dxirc_CONNECT);
294     m_reconnect = new FXMenuCommand(m_servermenu, _("&Reconnect all"), NULL, this, dxirc_RECONNECT);
295     m_reconnect->disable();
296     m_disconnect = new FXMenuCommand(m_servermenu, _("&Disconnect")+TAB+m_preferences.getBinding("disconnect"), ICO_DISCONNECT, this, dxirc_DISCONNECT);
297     m_disconnect->disable();
298     new FXMenuSeparator(m_servermenu);
299     new FXMenuCommand(m_servermenu, _("DCC &transfers")+TAB+m_preferences.getBinding("dccTransfers"), ICO_TRANSFER, this, dxirc_TRANSFERS);
300 #ifdef HAVE_LUA
301     new FXMenuSeparator(m_servermenu);
302     new FXMenuCommand(m_servermenu, _("S&cripts")+TAB+m_preferences.getBinding("scripts"), ICO_SCRIPT, this, dxirc_SCRIPTS);
303 #endif //HAVE_LUA
304     new FXMenuSeparator(m_servermenu);
305     m_logviewer = new FXMenuCommand(m_servermenu, _("&Log viewer")+TAB+m_preferences.getBinding("logViewer"), ICO_LOGS, this, dxirc_LOG);
306     if(!m_preferences.m_logging) m_logviewer->disable();
307     new FXMenuSeparator(m_servermenu);
308     new FXMenuCommand(m_servermenu, _("&Quit")+TAB+m_preferences.getBinding("quit"), ICO_QUIT, this, dxirc_QUIT);
309     new FXMenuTitle(m_menubar, _("&Server"), NULL, m_servermenu);
310 
311     m_editmenu = new FXMenuPane(this);
312     m_closeTab = new FXMenuCommand(m_editmenu, _("Close current tab")+TAB+m_preferences.getBinding("closeCurrentTab"), ICO_CLOSE, this, dxirc_CLOSETAB);
313     m_closeTab->disable();
314     new FXMenuSeparator(m_editmenu);
315     m_clearTab = new FXMenuCommand(m_editmenu, _("Clear window")+TAB+m_preferences.getBinding("clearWindow"), ICO_CLEAR, this, dxirc_CLEAR);
316     m_clearTabs = new FXMenuCommand(m_editmenu, _("Clear all windows")+TAB+m_preferences.getBinding("clearAllWindows"), NULL, this, dxirc_CLEARALL);
317     new FXMenuSeparator(m_editmenu);
318     m_preferences.m_usersShown = dxUtils.getBoolIniEntry("SETTINGS", "usersShown", TRUE);
319     m_users = new FXMenuCheck(m_editmenu, _("Users list")+TAB+m_preferences.getBinding("usersList")+TAB+_("Show/Hide users list"), this, dxirc_USERS);
320     m_users->setCheck(m_preferences.m_usersShown);
321 #ifdef HAVE_ENCHANT
322     m_spellCombo = new FXMenuCheck(m_editmenu, _("Spellchecking language list")+TAB+m_preferences.getBinding("spellList")+TAB+_("Show/Hide spellchecking language list"), this, dxirc_SPELL);
323     if(!(m_preferences.m_useSpell && dxUtils.getAvailableSpellLangsNum()))
324     {
325         m_preferences.m_showSpellCombo = FALSE;
326         m_spellCombo->disable();
327     }
328     m_spellCombo->setCheck(m_preferences.m_showSpellCombo);
329 #endif //HAVE_ENCHANT
330     m_status = new FXMenuCheck(m_editmenu, _("Status bar"), this, dxirc_STATUS);
331     m_status->setCheck(m_preferences.m_statusShown);
332     new FXMenuCommand(m_editmenu, _("&Aliases"), NULL, this, dxirc_ALIAS);
333     new FXMenuCommand(m_editmenu, _("&Preferences"), ICO_OPTION, this, dxirc_OPTIONS);
334     new FXMenuTitle(m_menubar, _("&Edit"), NULL, m_editmenu);
335 
336     m_helpmenu = new FXMenuPane(this);
337     new FXMenuCommand(m_helpmenu, _("&Check latest version"), NULL, this, dxirc_VERSION);
338     new FXMenuCommand(m_helpmenu, _("&About..."), NULL, this, dxirc_ABOUT);
339     new FXMenuCommand(m_helpmenu, _("&Help")+TAB+m_preferences.getBinding("help"), ICO_HELP, this, dxirc_HELP);
340     new FXMenuTitle(m_menubar, _("&Help"), NULL, m_helpmenu);
341 
342     m_mainframe = new FXVerticalFrame(this, LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 1,1,1,1);
343 
344     m_tabbook = new dxTabBook(m_mainframe, this, dxirc_TABS, PACK_UNIFORM_WIDTH|PACK_UNIFORM_HEIGHT|LAYOUT_FILL_X|LAYOUT_FILL_Y);
345 
346     IrcEngine *server = new IrcEngine(app, this, "", "");
347     m_ircengines.append(server);
348 
349     m_statusbar = new FXHorizontalFrame(m_mainframe, LAYOUT_LEFT|JUSTIFY_LEFT|LAYOUT_FILL_X|FRAME_NONE, 0,0,0,0, 1,1,1,1);
350     m_statuslabel = new FXLabel(m_statusbar, "dxirc", NULL, FRAME_SUNKEN|LAYOUT_LEFT|JUSTIFY_LEFT|LAYOUT_FILL_X);
351     if (m_preferences.m_statusShown)
352         m_statusbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_SHOW), NULL);
353     else
354         m_statusbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_HIDE), NULL);
355 
356 #ifdef HAVE_TRAY
357     if(m_preferences.m_useTray)
358     {
359         m_trayIcon = new FXTrayIcon(app, "dxirc", ICO_TRAY, 0, this, dxirc_TRAY, TRAY_CMD_ON_LEFT|TRAY_MENU_ON_RIGHT);
360         if(m_traymenu == NULL)
361             m_traymenu = new FXPopup(m_trayIcon);
362         new FXMenuCommand(m_traymenu, _("&Quit"), ICO_QUIT, this, dxirc_QUIT);
363         m_trayIcon->setMenu(m_traymenu);
364     }
365 #endif //HAVE_TRAY
366 
367     new FXToolTip(app,0);
368 
369     //set mainwindow size and position
370     setX(m_preferences.m_x);
371     setY(m_preferences.m_y);
372     setWidth(m_preferences.m_w);
373     setHeight(m_preferences.m_h);
374 
375     updateTheme(m_preferences.m_unreadColor, m_preferences.m_highlightColor);
376     updateFont();
377     updateTabs(m_preferences.m_useSmileys && (FXint)m_preferences.m_smileysMap.size());
378     updateTabPosition();
379     updateTrayColor();
380 
381     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("firstTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
382     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("secondTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
383     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("thirdTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
384     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("fourthTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
385     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("fifthTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
386     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("sixthTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
387     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("seventhTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
388     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("eighthTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
389     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("ninethTab")), this, FXSEL(SEL_COMMAND, dxirc_SELECTTAB));
390     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("switchTab")), this, FXSEL(SEL_COMMAND, dxirc_NEXTTAB));
391     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("moveTabUp")), this, FXSEL(SEL_COMMAND, dxirc_MOVETAB));
392     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("moveTabDown")), this, FXSEL(SEL_COMMAND, dxirc_MOVETAB));
393     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("unreadTab")), this, FXSEL(SEL_COMMAND, dxirc_NEXTUNREAD));
394     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("forceFocus")), this, FXSEL(SEL_COMMAND, dxirc_FORCEFOCUS));
395     getAccelTable()->addAccel(dxutils::parseAccel(m_preferences.getBinding("listCommand")), this, FXSEL(SEL_COMMAND, dxirc_LIST));
396 }
397 
~dxirc()398 dxirc::~dxirc()
399 {
400     m_app->removeTimeout(this, dxirc_STIMEOUT);
401     m_app->removeTimeout(this, dxirc_AWAYTIMEOUT);
402     delete ICO_BIG;
403     delete ICO_SMALL;
404     delete ICO_IRCADMIN;
405     delete ICO_IRCAWAYADMIN;
406     delete ICO_IRCAWAYHALFOP;
407     delete ICO_IRCAWAYNORMAL;
408     delete ICO_IRCAWAYOP;
409     delete ICO_IRCAWAYOWNER;
410     delete ICO_IRCAWAYVOICE;
411     delete ICO_IRCHALFOP;
412     delete ICO_IRCNORMAL;
413     delete ICO_IRCOP;
414     delete ICO_IRCOWNER;
415     delete ICO_IRCVOICE;
416     delete ICO_SERVERLIST;
417     delete ICO_CONNECT;
418     delete ICO_DISCONNECT;
419     delete ICO_QUIT;
420     delete ICO_CLOSE;
421     delete ICO_OPTION;
422     delete ICO_HELP;
423     delete ICO_SERVER;
424     delete ICO_CHANNEL;
425     delete ICO_QUERY;
426     delete ICO_CLEAR;
427     delete ICO_FLAG;
428     delete ICO_TRAY;
429     delete ICO_NEWMSG;
430     delete ICO_NEWFILE;
431     delete ICO_QUERYNEWMSG;
432     delete ICO_CHANNELNEWMSG;
433     delete ICO_CLOSEFOLDER;
434     delete ICO_OPENFOLDER;
435     delete ICO_FILE;
436     delete ICO_CANCEL;
437     delete ICO_FINISH;
438     delete ICO_DOWN;
439     delete ICO_UP;
440     delete ICO_DCC;
441     delete ICO_DCCNEWMSG;
442     delete ICO_LOGS;
443     delete ICO_SCRIPT;
444     delete ICO_TRANSFER;
445     delete ICO_PLAY;
446     delete ICO_COPY;
447     delete ICO_SELECTALL;
448     delete ICO_FIND;
449     delete ICO_REFRESH;
450     delete ICO_KEYBINDINGS;
451     while(m_smileys.no())
452     {
453         delete m_smileys[0].icon;
454         m_smileys.erase(0);
455     }
456     delete m_servermenu;
457     delete m_editmenu;
458     delete m_helpmenu;
459 #ifdef HAVE_TRAY
460     if(m_traymenu)
461     {
462         delete m_traymenu;
463     }
464 #endif //HAVE_TRAY
465     delete m_ircFont;
466     if(m_versionSocket) delete m_versionSocket;
467     _pThis = NULL;
468 }
469 
instance()470 dxirc* dxirc::instance()
471 {
472     return _pThis;
473 }
474 
create()475 void dxirc::create()
476 {
477     FXMainWindow::create();
478     if(m_preferences.m_maximized) maximize(TRUE);
479     //Checking for screen resolution and correction size, position
480     else
481     {
482         FXint maxWidth = getRoot()->getWidth();
483         FXint maxHeight = getRoot()->getHeight();
484         if(getX()+getWidth() > maxWidth || getX()<0)
485         {
486             setX(0);
487             setWidth(maxWidth);
488         }
489         if(getY()+getHeight() > maxHeight || getY()<0)
490         {
491             setY(0);
492             setHeight(maxHeight);
493         }
494     }
495     show();
496     _pThis = this;
497     createIrcTab("(server)", ICO_SERVER, SERVER, m_ircengines[0]);
498     for(FXint i=0; i<m_preferences.m_serverList.no(); i++)
499     {
500         if(m_preferences.m_serverList[i].autoConnect)
501         {
502             connectServer(m_preferences.m_serverList[i].hostname, m_preferences.m_serverList[i].port, m_preferences.m_serverList[i].passwd, m_preferences.m_serverList[i].nick, m_preferences.m_serverList[i].realname, m_preferences.m_serverList[i].channels, m_preferences.m_serverList[i].commands, m_preferences.m_serverList[i].useSsl);
503         }
504     }
505     autoloadScripts();
506     m_app->addTimeout(this, dxirc_AWAYTIMEOUT, 180000);
507 #ifndef WIN32
508 #ifdef HAVE_TRAY
509     m_trayIcon->create();
510     if(!m_trayIcon->dock())
511     {
512         delete m_trayIcon;
513         m_trayIcon=NULL;
514     }
515 #endif //HAVE_TRAY
516 #endif
517 }
518 
519 // Flash the window to get user's attention
520 // Taken from fox development version 1.7
flash(FXbool yes)521 void dxirc::flash(FXbool yes)
522 {
523     if(xid)
524     {
525 #ifdef WIN32
526         FlashWindow((HWND)xid, true);
527 #else
528     #ifdef HAVE_X11
529         XEvent se;
530         se.xclient.type=ClientMessage;
531         se.xclient.display=DISPLAY(m_app);
532         se.xclient.message_type=XInternAtom(DISPLAY(m_app), "_NET_WM_STATE", 0);;
533         se.xclient.format=32;
534         se.xclient.window=xid;
535         se.xclient.data.l[0]=yes;   // 0=_NET_WM_STATE_REMOVE, 1=_NET_WM_STATE_ADD, 2=_NET_WM_STATE_TOGGLE
536         se.xclient.data.l[1]=XInternAtom(DISPLAY(m_app), "_NET_WM_STATE_DEMANDS_ATTENTION", 0);
537         se.xclient.data.l[2]=0;
538         se.xclient.data.l[3]=0;
539         se.xclient.data.l[4]=0;
540         XSendEvent(DISPLAY(m_app),XDefaultRootWindow(DISPLAY(m_app)),False,SubstructureRedirectMask|SubstructureNotifyMask,&se);
541     #endif //HAVE_X11
542 #endif //WIN32
543     }
544 }
545 
setTempKeybindings(dxStringMap bindings)546 void dxirc::setTempKeybindings(dxStringMap bindings)
547 {
548     m_tempKeybindings = bindings;
549 }
550 
onCmdQuit(FXObject *,FXSelector,void *)551 long dxirc::onCmdQuit(FXObject*, FXSelector, void*)
552 {
553     m_preferences.m_x = getX();
554     m_preferences.m_y = getY();
555     m_preferences.m_w = getWidth();
556     m_preferences.m_h = getHeight();
557     m_preferences.m_maximized = isMaximized();
558     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
559     {
560         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass
561                 && static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType()==CHANNEL)
562         {
563             m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
564             m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
565         }
566     }
567     m_preferences.save();
568     while(m_ircengines.no())
569     {
570         m_ircengines[0]->clearTarget();
571         if(m_ircengines[0]->getConnected()) m_ircengines[0]->disconnect();
572         m_ircengines.erase(0);
573     }
574 #ifdef HAVE_LUA
575     for(FXint i=0; i<m_scriptEvents.no(); i++)
576     {
577         if(comparecase("quit", m_scriptEvents[i].name) == 0)
578         {
579             for(FXint j=0; j<m_scripts.no(); j++)
580             {
581                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
582                 {
583                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
584                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
585                     else
586                     {
587                         if (lua_pcall(m_scripts[j].L, 0, 0, 0))
588                         {
589                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
590                             lua_pop(m_scripts[j].L, 1);
591                         }
592                     }
593                 }
594             }
595         }
596     }
597     while(m_scripts.no())
598     {
599         if(m_scripts[0].L != NULL) lua_close(m_scripts[0].L);
600         m_scripts.erase(0);
601     }
602     while(m_scriptEvents.no())
603     {
604         m_scriptEvents.erase(0);
605     }
606 #endif //HAVE_LUA
607     m_app->exit(0);
608     return 1;
609 }
610 
onCmdRestart(FXObject *,FXSelector,void *)611 long dxirc::onCmdRestart(FXObject*, FXSelector, void*)
612 {
613     m_preferences.m_x = getX();
614     m_preferences.m_y = getY();
615     m_preferences.m_w = getWidth();
616     m_preferences.m_h = getHeight();
617     m_preferences.m_maximized = isMaximized();
618     m_preferences.m_keybindings = m_tempKeybindings;
619     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
620     {
621         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass
622                 && static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType()==CHANNEL)
623         {
624             m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
625             m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
626         }
627     }
628     m_preferences.save();
629     while(m_ircengines.no())
630     {
631         m_ircengines[0]->clearTarget();
632         if(m_ircengines[0]->getConnected()) m_ircengines[0]->disconnect();
633         m_ircengines.erase(0);
634     }
635 #ifdef HAVE_LUA
636     for(FXint i=0; i<m_scriptEvents.no(); i++)
637     {
638         if(comparecase("quit", m_scriptEvents[i].name) == 0)
639         {
640             for(FXint j=0; j<m_scripts.no(); j++)
641             {
642                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
643                 {
644                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
645                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
646                     else
647                     {
648                         if (lua_pcall(m_scripts[j].L, 0, 0, 0))
649                         {
650                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
651                             lua_pop(m_scripts[j].L, 1);
652                         }
653                     }
654                 }
655             }
656         }
657     }
658     while(m_scripts.no())
659     {
660         if(m_scripts[0].L != NULL) lua_close(m_scripts[0].L);
661         m_scripts.erase(0);
662     }
663     while(m_scriptEvents.no())
664     {
665         m_scriptEvents.erase(0);
666     }
667 #endif //HAVE_LUA
668 #ifdef WIN32
669     getApp()->exit();
670     FXString str ;
671     for(FXint i=0; i < argn; i++)
672     {
673         str += args[i];
674         str += (i != argn - 1? " " : "");
675     }
676     ShellExecuteA(NULL, "open", args[0], argn>1?str.text():NULL, NULL, SW_SHOWNORMAL);
677 #else
678     if(fork() == 0)
679         execvp(args[0], args);
680     else
681         _exit(0);
682 #endif //WIN32
683     return 1;
684 }
685 
onCmdClose(FXObject *,FXSelector,void *)686 long dxirc::onCmdClose(FXObject*, FXSelector, void*)
687 {
688 #ifdef HAVE_TRAY
689     if(m_trayIcon && m_preferences.m_useTray && m_preferences.m_closeToTray)
690         hide();
691     else
692         onCmdQuit(NULL, 0, NULL);
693 #else
694     onCmdQuit(NULL, 0, NULL);
695 #endif //HAVE_TRAY
696     return 1;
697 }
698 
onCmdHelp(FXObject *,FXSelector,void *)699 long dxirc::onCmdHelp(FXObject*, FXSelector, void*)
700 {
701     HelpDialog help(this);
702     help.execute(PLACEMENT_OWNER);
703     return 1;
704 }
705 
onCmdUsers(FXObject *,FXSelector,void *)706 long dxirc::onCmdUsers(FXObject*, FXSelector, void*)
707 {
708     m_preferences.m_usersShown = !m_preferences.m_usersShown;
709     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
710     {
711         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass)
712         {
713             IrcTabItem *tab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i));
714             if(m_preferences.m_usersShown) tab->showUsers();
715             else tab->hideUsers();
716         }
717     }
718     return 1;
719 }
720 
onCmdSpell(FXObject *,FXSelector,void *)721 long dxirc::onCmdSpell(FXObject*, FXSelector, void*)
722 {
723     m_preferences.m_showSpellCombo = !m_preferences.m_showSpellCombo;
724     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
725     {
726         if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
727         {
728             dxTabItem *tab = static_cast<dxTabItem*>(m_tabbook->childAtIndex(i));
729             tab->showSpellComboUpdated();
730         }
731     }
732     return 1;
733 }
734 
onCmdForceFocus(FXObject *,FXSelector,void *)735 long dxirc::onCmdForceFocus(FXObject*, FXSelector, void*)
736 {
737     if(m_tabbook->numChildren())
738     {
739         FXint index = m_tabbook->getCurrent()*2;
740         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()!=&TetrisTabItem::metaClass)
741             static_cast<dxTabItem*>(m_tabbook->childAtIndex(index))->setCommandFocus();
742     }
743     return 1;
744 }
745 
746 //check away on channels
onAwayTimeout(FXObject *,FXSelector,void *)747 long dxirc::onAwayTimeout(FXObject*, FXSelector, void*)
748 {
749     m_app->addTimeout(this, dxirc_AWAYTIMEOUT, 180000);
750     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
751     {
752         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass)
753             static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->checkAway();
754     }
755     return 1;
756 }
757 
758 //check dxirc version on dxirc.org
onCmdCheckVersion(FXObject *,FXSelector,void *)759 long dxirc::onCmdCheckVersion(FXObject*, FXSelector, void*)
760 {
761     if(!m_versionSocket)
762         m_versionSocket = new dxSocket(m_app, this, dxirc_VERSIONSOCKET);
763     if(m_versionSocket->isConnecting())
764     {
765         dxEXMessageBox::information(this, MBOX_OK, _("Information"), "%s", _("Checking version in progress"));
766         return 1;
767     }
768     if(m_versionSocket->isConnected())
769     {
770         dxEXMessageBox::information(this, MBOX_OK, _("Information"), "%s", _("Checking version in progress"));
771         return 1;
772     }
773     updateStatus(_("Checking version in progress"));
774     m_versionSocket->setTarget(this);
775     m_versionSocket->setHost("dxsolutions.org", 443);
776     m_versionSocket->setIsSSL(TRUE);
777     m_versionSocket->connectTo();
778     return 1;
779 }
780 
781 //versionsocket connected
onVersionSocketConnected(FXObject *,FXSelector,void *)782 long dxirc::onVersionSocketConnected(FXObject*, FXSelector, void*)
783 {
784     if(m_versionSocket)
785         m_versionSocket->writeLine("GET /dxirc-version HTTP/1.0\r\nHost: dxsolutions.org\r\nAccept: */*\r\nConnection: close\r\n\r\n", TRUE);
786     return 1;
787 }
788 
789 //versionsocket data available
onVersionSocketCanRead(FXObject *,FXSelector,void *)790 long dxirc::onVersionSocketCanRead(FXObject*, FXSelector, void*)
791 {
792     onStatusTimeout(NULL, 0, NULL);
793     if(m_versionSocket)
794     {
795         FXint read = m_versionSocket->getBytesAvailable();
796         if(!read) return 1;
797         FXchar *buffer = new FXchar[read];
798         read = m_versionSocket->read(buffer, read);
799         FXString serverVersion = buffer;
800         dxutils::debugLine(serverVersion);
801         serverVersion = serverVersion.after('\n', serverVersion.contains('\n')-(buffer[read-1]=='\n'?1:0)).before('\n');
802         if(serverVersion.empty())
803         {
804             return 1;
805         }
806         else
807         {
808             if(serverVersion[0] != '1') return 1;
809         }
810         FXString currentVersion = VERSION;
811         FXint current = FXIntVal(currentVersion.before('.'))*1000+FXIntVal(currentVersion.after('.').before('.'))*10+FXIntVal(currentVersion.after('.',2));
812         FXint server = FXIntVal(serverVersion.before('.'))*1000+FXIntVal(serverVersion.after('.').before('.'))*10+FXIntVal(serverVersion.after('.',2));
813         if(current==server)
814             dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("You have last version %s"), VERSION);
815         else if(current<server)
816             dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("New version %s available"), serverVersion.text());
817         else
818             dxEXMessageBox::information(this, MBOX_OK, _("Information"), _("You have svn version %s"), VERSION);
819         delete []buffer;
820         m_versionSocket->disconnect();
821     }
822     return 1;
823 }
824 
825 //versionsocket error
onVersionSocketError(FXObject *,FXSelector,void * ptr)826 long dxirc::onVersionSocketError(FXObject*, FXSelector, void *ptr)
827 {
828     onStatusTimeout(NULL, 0, NULL);
829     dxEXMessageBox::error(m_app, MBOX_OK, _("Error"), "%s", _("Error occurred during version check"));
830     if(ptr)
831     {
832         SocketError *err = *((SocketError**)ptr);
833         if(err) delete err;
834     }
835     return 1;
836 }
837 
onCmdStatus(FXObject *,FXSelector,void *)838 long dxirc::onCmdStatus(FXObject*, FXSelector, void*)
839 {
840     m_preferences.m_statusShown = !m_preferences.m_statusShown;
841     m_statusbar->handle(this, FXSEL(SEL_COMMAND, FXWindow::ID_TOGGLESHOWN), NULL);
842     return 1;
843 }
844 
onCmdOptions(FXObject *,FXSelector,void *)845 long dxirc::onCmdOptions(FXObject*, FXSelector, void*)
846 {
847     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
848     {
849         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass
850                 && static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType()==CHANNEL)
851         {
852             m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
853             m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
854         }
855     }
856     dxStringMap oldsmileysMap = m_preferences.m_smileysMap;
857     FXbool oldUseSmileys = m_preferences.m_useSmileys;
858     FXString oldThemePath = m_preferences.m_themePath;
859     FXbool oldOwnServerWindow = m_preferences.m_ownServerWindow;
860     FXColor oldIrcTextBackColor = m_preferences.m_colors.back;
861     FXColor oldUnreadColor = m_preferences.m_unreadColor;
862     FXColor oldHighlightColor = m_preferences.m_highlightColor;
863     ConfigDialog dialog(this);
864     if(dialog.execute(PLACEMENT_CURSOR))
865     {
866         FXbool recreateSmileys = oldUseSmileys!=m_preferences.m_useSmileys ? TRUE : FALSE;
867         if(m_preferences.m_logging) m_logviewer->enable();
868         else m_logviewer->disable();
869         if(m_viewer) m_viewer->setLogPath(m_preferences.m_logPath);
870 #ifdef HAVE_ENCHANT
871         if(m_preferences.m_useSpell && dxUtils.getAvailableSpellLangsNum()) m_spellCombo->enable();
872         else m_spellCombo->disable();
873 #endif
874         if(m_ircFont->getFont()!=m_preferences.m_ircFont)
875         {
876             recreateSmileys = TRUE;
877             if(!m_preferences.m_ircFont.empty())
878             {
879                 m_ircFont = new FXFont(m_app, m_preferences.m_ircFont);
880                 m_ircFont->create();
881             }
882             else
883             {
884                 m_app->getNormalFont()->create();
885                 FXFontDesc fontdescription;
886                 m_app->getNormalFont()->getFontDesc(fontdescription);
887                 m_ircFont = new FXFont(m_app,fontdescription);
888                 m_ircFont->create();
889             }
890         }
891         if(oldsmileysMap!=m_preferences.m_smileysMap) recreateSmileys = TRUE;
892         updateTheme(oldUnreadColor, oldHighlightColor);
893         updateFont();
894         updateTabs(recreateSmileys);
895         updateTabPosition();
896         if(oldThemePath!=m_preferences.m_themePath || oldIrcTextBackColor!=m_preferences.m_colors.back) updateNickIcons();
897         if(oldOwnServerWindow!=m_preferences.m_ownServerWindow) updateServerWindow();
898         updateTrayColor();
899         recalc();
900     }
901     return 1;
902 }
903 
onCmdAlias(FXObject *,FXSelector,void *)904 long dxirc::onCmdAlias(FXObject*, FXSelector, void*)
905 {
906     AliasDialog dialog(this);
907     dialog.execute(PLACEMENT_CURSOR);
908     return 1;
909 }
910 
onCmdLog(FXObject *,FXSelector,void *)911 long dxirc::onCmdLog(FXObject*, FXSelector, void*)
912 {
913     if(m_viewer == NULL)
914     {
915         m_viewer = new LogViewer(m_app, m_preferences.m_logPath, m_ircFont);
916         m_viewer->create();
917     }
918     m_viewer->show(PLACEMENT_CURSOR);
919     return 1;
920 }
921 
onCmdTransfers(FXObject *,FXSelector,void *)922 long dxirc::onCmdTransfers(FXObject*, FXSelector, void*)
923 {
924     if(m_transfers == NULL)
925         m_transfers = new DccDialog(m_app);
926     m_transfers->create();
927     return 1;
928 }
929 
updateTheme(FXColor oldUnread,FXColor oldHighlight)930 void dxirc::updateTheme(FXColor oldUnread, FXColor oldHighlight)
931 {
932     FXWindow *w = FXApp::instance()->getRootWindow();
933 
934     FX7Segment * sevensegment;
935     FXTextField * textfield;
936     FXIconList * iconlist;
937     FXList * list;
938     FXListBox * listbox;
939     FXTreeList * treelist;
940     FXComboBox * combobox;
941     FXArrowButton * arrowbuton;
942     dxEXButton * button;
943     FXFrame * frame;
944     FXLabel * label;
945     FXPopup * popup;
946     FXMenuTitle * menutitle;
947     FXMenuCheck * menucheck;
948     FXMenuRadio * menuradio;
949     FXMenuCaption * menucaption;
950     FXMenuSeparator * menuseparator;
951     FXText * text;
952     dxText * dtext;
953     FXFoldingList * foldinglist;
954     FXMDIChild * mdichild;
955     FXTable * table;
956     FXDockTitle * docktitle;
957     FXPacker * packer;
958     FXHeader * header;
959     FXGroupBox * groupbox;
960     FXScrollBar * scrollbar;
961     FXSlider * slider;
962     FXStatusLine * statusline;
963     FXDragCorner * dragcorner;
964     FXRadioButton * radiobutton;
965     FXCheckButton * checkbutton;
966     FXToolTip * tooltip;
967     FXImageFrame * imageframe;
968 
969     FXbool update = FALSE;
970     FXColor oldForeColor = m_app->getForeColor();
971     if(m_app->getBaseColor() != m_preferences.m_appTheme.base)
972     {
973         update = TRUE;
974         m_app->setBaseColor(m_preferences.m_appTheme.base);
975     }
976     if(m_app->getBackColor() != m_preferences.m_appTheme.back)
977     {
978         update = TRUE;
979         m_app->setBackColor(m_preferences.m_appTheme.back);
980     }
981     if(m_app->getBorderColor() != m_preferences.m_appTheme.border)
982     {
983         update = TRUE;
984         m_app->setBorderColor(m_preferences.m_appTheme.border);
985     }
986     if(m_app->getForeColor() != m_preferences.m_appTheme.fore)
987     {
988         update = TRUE;
989         m_app->setForeColor(m_preferences.m_appTheme.fore);
990     }
991     if(m_app->getSelMenuBackColor() != m_preferences.m_appTheme.menuback)
992     {
993         update = TRUE;
994         m_app->setSelMenuBackColor(m_preferences.m_appTheme.menuback);
995     }
996     if(m_app->getSelMenuTextColor() != m_preferences.m_appTheme.menufore)
997     {
998         update = TRUE;
999         m_app->setSelMenuTextColor(m_preferences.m_appTheme.menufore);
1000     }
1001     if(m_app->getSelbackColor() != m_preferences.m_appTheme.selback)
1002     {
1003         update = TRUE;
1004         m_app->setSelbackColor(m_preferences.m_appTheme.selback);
1005     }
1006     if(m_app->getSelforeColor() != m_preferences.m_appTheme.selfore)
1007     {
1008         update = TRUE;
1009         m_app->setSelforeColor(m_preferences.m_appTheme.selfore);
1010     }
1011     if(m_app->getTipbackColor() != m_preferences.m_appTheme.tipback)
1012     {
1013         update = TRUE;
1014         m_app->setTipbackColor(m_preferences.m_appTheme.tipback);
1015     }
1016     if(m_app->getTipforeColor() != m_preferences.m_appTheme.tipfore)
1017     {
1018         update = TRUE;
1019         m_app->setTipforeColor(m_preferences.m_appTheme.tipfore);
1020     }
1021     if(m_app->getHiliteColor() != m_preferences.m_appTheme.hilite)
1022     {
1023         update = TRUE;
1024         m_app->setHiliteColor(m_preferences.m_appTheme.hilite);
1025     }
1026     if(m_app->getShadowColor() != m_preferences.m_appTheme.shadow)
1027     {
1028         update = TRUE;
1029         m_app->setShadowColor(m_preferences.m_appTheme.shadow);
1030     }
1031     if(oldUnread != m_preferences.m_unreadColor)
1032     {
1033         update = TRUE;
1034     }
1035     if(oldHighlight != m_preferences.m_highlightColor)
1036     {
1037         update = TRUE;
1038     }
1039     if(!update)
1040         return;
1041 
1042     while (w)
1043     {
1044         w->setBackColor(m_preferences.m_appTheme.base);
1045         if ((frame = dynamic_cast<FXFrame*> (w)))
1046         {
1047             frame->setBaseColor(m_preferences.m_appTheme.base);
1048             frame->setBackColor(m_preferences.m_appTheme.base);
1049             frame->setShadowColor(m_preferences.m_appTheme.shadow);
1050             frame->setHiliteColor(m_preferences.m_appTheme.hilite);
1051             frame->setBorderColor(m_preferences.m_appTheme.border);
1052             if ((label = dynamic_cast<FXLabel*> (w)))
1053             {
1054                 if(label->getTextColor() == oldForeColor) label->setTextColor(m_preferences.m_appTheme.fore);
1055                 else if(label->getTextColor() == oldUnread) label->setTextColor(m_preferences.m_unreadColor);
1056                 else if(label->getTextColor() == oldHighlight) label->setTextColor(m_preferences.m_highlightColor);
1057                 if ((button = dynamic_cast<dxEXButton*> (w)))
1058                 {
1059                     if (dynamic_cast<FXListBox*> (button->getParent()))
1060                     {
1061                         w->setBackColor(m_preferences.m_appTheme.back);
1062                     }
1063                     else
1064                     {
1065                         w->setBackColor(m_preferences.m_appTheme.base);
1066                     }
1067                 }
1068                 else if ((checkbutton = dynamic_cast<FXCheckButton*> (w)))
1069                 {
1070                     checkbutton->setCheckColor(m_preferences.m_appTheme.fore);
1071                     checkbutton->setBoxColor(m_preferences.m_appTheme.back);
1072                 }
1073                 else if ((radiobutton = dynamic_cast<FXRadioButton*> (w)))
1074                 {
1075                     radiobutton->setRadioColor(m_preferences.m_appTheme.fore);
1076                     radiobutton->setDiskColor(m_preferences.m_appTheme.back);
1077                 }
1078             }
1079             else if ((arrowbuton = dynamic_cast<FXArrowButton*> (w)))
1080             {
1081                 arrowbuton->setArrowColor(m_preferences.m_appTheme.fore);
1082             }
1083             else if ((textfield = dynamic_cast<FXTextField*> (w)))
1084             {
1085                 w->setBackColor(m_preferences.m_appTheme.back);
1086                 textfield->setTextColor(m_preferences.m_appTheme.fore);
1087                 textfield->setSelTextColor(m_preferences.m_appTheme.selfore);
1088                 textfield->setSelBackColor(m_preferences.m_appTheme.selback);
1089             }
1090             else if ((docktitle = dynamic_cast<FXDockTitle*> (w)))
1091             {
1092                 docktitle->setCaptionColor(m_preferences.m_appTheme.selfore);
1093                 docktitle->setBackColor(m_preferences.m_appTheme.selback);
1094             }
1095             else if ((header = dynamic_cast<FXHeader*> (w)))
1096             {
1097                 header->setTextColor(m_preferences.m_appTheme.fore);
1098             }
1099             else if ((statusline = dynamic_cast<FXStatusLine*> (w)))
1100             {
1101                 statusline->setTextColor(m_preferences.m_appTheme.fore);
1102             }
1103             else if ((sevensegment = dynamic_cast<FX7Segment*> (w)))
1104             {
1105                 sevensegment->setTextColor(m_preferences.m_appTheme.fore);
1106             }
1107             else if ((slider = dynamic_cast<FXSlider*> (w)))
1108             {
1109                 slider->setSlotColor(m_preferences.m_appTheme.back);
1110             }
1111             else if ((imageframe = dynamic_cast<FXImageFrame*> (w)))
1112             {
1113                 imageframe->setBackColor(m_preferences.m_appTheme.back); /// fixme, only for coverframe in mainwindow
1114             }
1115         }
1116         else if ((packer = dynamic_cast<FXPacker*> (w)))
1117         {
1118             packer->setBaseColor(m_preferences.m_appTheme.base);
1119             packer->setBackColor(m_preferences.m_appTheme.base);
1120             packer->setShadowColor(m_preferences.m_appTheme.shadow);
1121             packer->setHiliteColor(m_preferences.m_appTheme.hilite);
1122             packer->setBorderColor(m_preferences.m_appTheme.border);
1123             if ((combobox = dynamic_cast<FXComboBox*> (w)))
1124             {
1125                 w->setBackColor(m_preferences.m_appTheme.back);
1126             }
1127             else if ((listbox = dynamic_cast<FXListBox*> (w)))
1128             {
1129                 w->setBackColor(m_preferences.m_appTheme.back);
1130             }
1131             else if ((groupbox = dynamic_cast<FXGroupBox*> (w)))
1132             {
1133                 groupbox->setTextColor(m_preferences.m_appTheme.fore);
1134             }
1135         }
1136         else if ((popup = dynamic_cast<FXPopup*> (w)))
1137         {
1138             popup->setBaseColor(m_preferences.m_appTheme.base);
1139             popup->setShadowColor(m_preferences.m_appTheme.shadow);
1140             popup->setHiliteColor(m_preferences.m_appTheme.hilite);
1141             popup->setBorderColor(m_preferences.m_appTheme.border);
1142         }
1143         else if ((menucaption = dynamic_cast<FXMenuCaption*> (w)))
1144         {
1145             w->setBackColor(m_preferences.m_appTheme.base);
1146             menucaption->setTextColor(m_preferences.m_appTheme.fore);
1147             menucaption->setSelTextColor(m_preferences.m_appTheme.menufore);
1148             menucaption->setSelBackColor(m_preferences.m_appTheme.menuback);
1149             menucaption->setShadowColor(m_preferences.m_appTheme.shadow);
1150             menucaption->setHiliteColor(m_preferences.m_appTheme.hilite);
1151 
1152             if ((menucheck = dynamic_cast<FXMenuCheck*> (w)))
1153             {
1154                 menucheck->setBoxColor(m_preferences.m_appTheme.back);
1155             }
1156             else if ((menuradio = dynamic_cast<FXMenuRadio*> (w)))
1157             {
1158                 menuradio->setRadioColor(m_preferences.m_appTheme.back);
1159             }
1160             else if ((menutitle = dynamic_cast<FXMenuTitle*> (w)))
1161             {
1162                 menutitle->setTextColor(m_preferences.m_appTheme.fore);
1163                 menutitle->setSelTextColor(m_preferences.m_appTheme.fore);
1164                 menutitle->setSelBackColor(m_preferences.m_appTheme.base);
1165             }
1166         }
1167         else if ((menuseparator = dynamic_cast<FXMenuSeparator*> (w)))
1168         {
1169             menuseparator->setShadowColor(m_preferences.m_appTheme.shadow);
1170             menuseparator->setHiliteColor(m_preferences.m_appTheme.hilite);
1171         }
1172         else if ((scrollbar = dynamic_cast<FXScrollBar*> (w)))
1173         {
1174             scrollbar->setShadowColor(m_preferences.m_appTheme.shadow);
1175             scrollbar->setHiliteColor(m_preferences.m_appTheme.hilite);
1176             scrollbar->setBorderColor(m_preferences.m_appTheme.border);
1177             scrollbar->setArrowColor(m_preferences.m_appTheme.fore);
1178         }
1179         else if ((dragcorner = dynamic_cast<FXDragCorner*> (w)))
1180         {
1181             dragcorner->setShadowColor(m_preferences.m_appTheme.shadow);
1182             dragcorner->setHiliteColor(m_preferences.m_appTheme.hilite);
1183         }
1184         else if (dynamic_cast<FXScrollArea*> (w))
1185         {
1186             if ((text = dynamic_cast<FXText*> (w)))
1187             {
1188                 w->setBackColor(m_preferences.m_appTheme.back);
1189                 text->setTextColor(m_preferences.m_appTheme.fore);
1190                 text->setSelTextColor(m_preferences.m_appTheme.selfore);
1191                 text->setSelBackColor(m_preferences.m_appTheme.selback);
1192             }
1193             else if ((dtext = dynamic_cast<dxText*> (w)))
1194             {
1195                 w->setBackColor(m_preferences.m_appTheme.back);
1196                 dtext->setTextColor(m_preferences.m_appTheme.fore);
1197                 dtext->setSelTextColor(m_preferences.m_appTheme.selfore);
1198                 dtext->setSelBackColor(m_preferences.m_appTheme.selback);
1199             }
1200             else if ((list = dynamic_cast<FXList*> (w)))
1201             {
1202                 w->setBackColor(m_preferences.m_appTheme.back);
1203                 list->setTextColor(m_preferences.m_appTheme.fore);
1204                 list->setSelTextColor(m_preferences.m_appTheme.selfore);
1205                 list->setSelBackColor(m_preferences.m_appTheme.selback);
1206             }
1207             else if ((treelist = dynamic_cast<FXTreeList*> (w)))
1208             {
1209                 w->setBackColor(m_preferences.m_appTheme.back);
1210                 treelist->setTextColor(m_preferences.m_appTheme.fore);
1211                 treelist->setLineColor(m_preferences.m_appTheme.shadow);
1212                 treelist->setSelTextColor(m_preferences.m_appTheme.selfore);
1213                 treelist->setSelBackColor(m_preferences.m_appTheme.selback);
1214             }
1215             else if ((iconlist = dynamic_cast<FXIconList*> (w)))
1216             {
1217                 w->setBackColor(m_preferences.m_appTheme.back);
1218                 iconlist->setTextColor(m_preferences.m_appTheme.fore);
1219                 iconlist->setSelTextColor(m_preferences.m_appTheme.selfore);
1220                 iconlist->setSelBackColor(m_preferences.m_appTheme.selback);
1221             }
1222             else if ((foldinglist = dynamic_cast<FXFoldingList*> (w)))
1223             {
1224                 w->setBackColor(m_preferences.m_appTheme.back);
1225                 foldinglist->setTextColor(m_preferences.m_appTheme.fore);
1226                 foldinglist->setSelTextColor(m_preferences.m_appTheme.selfore);
1227                 foldinglist->setSelBackColor(m_preferences.m_appTheme.selback);
1228                 foldinglist->setLineColor(m_preferences.m_appTheme.shadow);
1229             }
1230             else if ((table = dynamic_cast<FXTable*> (w)))
1231             {
1232                 w->setBackColor(m_preferences.m_appTheme.back);
1233                 table->setTextColor(m_preferences.m_appTheme.fore);
1234                 table->setSelTextColor(m_preferences.m_appTheme.selfore);
1235                 table->setSelBackColor(m_preferences.m_appTheme.selback);
1236             }
1237         }
1238         else if ((mdichild = dynamic_cast<FXMDIChild*> (w)))
1239         {
1240             mdichild->setBackColor(m_preferences.m_appTheme.base);
1241             mdichild->setBaseColor(m_preferences.m_appTheme.base);
1242             mdichild->setShadowColor(m_preferences.m_appTheme.shadow);
1243             mdichild->setHiliteColor(m_preferences.m_appTheme.hilite);
1244             mdichild->setBorderColor(m_preferences.m_appTheme.border);
1245             mdichild->setTitleColor(m_preferences.m_appTheme.selfore);
1246             mdichild->setTitleBackColor(m_preferences.m_appTheme.selback);
1247         }
1248         else if ((tooltip = dynamic_cast<FXToolTip*> (w)))
1249         {
1250             tooltip->setTextColor(m_preferences.m_appTheme.tipfore);
1251             tooltip->setBackColor(m_preferences.m_appTheme.tipback);
1252         }
1253 
1254         w->update();
1255         if (w->getFirst())
1256         {
1257             w = w->getFirst();
1258             continue;
1259         }
1260         while (!w->getNext() && w->getParent())
1261         {
1262             w = w->getParent();
1263         }
1264         w = w->getNext();
1265     }
1266 }
1267 
1268 //update tray backround color for X11
updateTrayColor()1269 void dxirc::updateTrayColor()
1270 {
1271 #ifndef WIN32
1272 #ifdef HAVE_TRAY
1273     if(m_preferences.m_useTray && m_trayIcon)
1274         m_trayIcon->setTrayColor(m_preferences.m_trayColor);
1275 #endif //HAVE_TRAY
1276 #endif //WIN32
1277 }
1278 
updateFont()1279 void dxirc::updateFont()
1280 {
1281     m_app->getNormalFont()->destroy();
1282     m_app->getNormalFont()->setFont(m_preferences.m_font);
1283     m_app->getNormalFont()->create();
1284     FXWindow *w = this;
1285     while(w)
1286     {
1287         w->recalc();
1288         if(w->getFirst())
1289         {
1290             w = w->getFirst();
1291             continue;
1292         }
1293         while(!w->getNext() && w->getParent())
1294         {
1295             w = w->getParent();
1296         }
1297         w = w->getNext();
1298     }
1299 }
1300 
updateTabs(FXbool recreateSmileys)1301 void dxirc::updateTabs(FXbool recreateSmileys)
1302 {
1303     if(recreateSmileys)
1304     {
1305         for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1306         {
1307             if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
1308             {
1309                 static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->removeSmileys();
1310             }
1311         }
1312         createSmileys();
1313     }
1314     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1315     {
1316         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass)
1317         {
1318             IrcTabItem *irctab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i));
1319             irctab->preferencesUpdated();
1320             irctab->setIrcFont(m_ircFont);
1321             irctab->setSmileys(m_preferences.m_useSmileys, m_smileys);
1322         }
1323         if(m_tabbook->childAtIndex(i)->getMetaClass()==&DccTabItem::metaClass)
1324         {
1325             DccTabItem *irctab = static_cast<DccTabItem*>(m_tabbook->childAtIndex(i));
1326             irctab->preferencesUpdated();
1327             irctab->setIrcFont(m_ircFont);
1328             irctab->setSmileys(m_preferences.m_useSmileys, m_smileys);
1329         }
1330         if(m_tabbook->childAtIndex(i)->getMetaClass()==&TetrisTabItem::metaClass)
1331         {
1332             TetrisTabItem *tetristab = static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(i));
1333             tetristab->setColor(m_preferences.m_colors);
1334         }
1335     }
1336     //update font in LogViewer too. Both must be same
1337     if(m_viewer) m_viewer->setFont(m_ircFont);
1338 }
1339 
updateTabPosition()1340 void dxirc::updateTabPosition()
1341 {
1342     switch(m_preferences.m_tabPosition) {
1343         case 0: //bottom
1344             {
1345                 m_tabbook->setTabStyle(TABBOOK_BOTTOMTABS);
1346                 for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1347                 {
1348                     static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->setTabOrientation(TAB_BOTTOM);
1349                 }
1350                 FXuint packing = m_tabbook->getPackingHints();
1351                 packing &= ~PACK_UNIFORM_WIDTH;
1352                 m_tabbook->setPackingHints(packing);
1353             }break;
1354         case 1: //left
1355             {
1356                 m_tabbook->setTabStyle(TABBOOK_LEFTTABS);
1357                 for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1358                 {
1359                     static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->setTabOrientation(TAB_LEFT);
1360                 }
1361                 FXuint packing = m_tabbook->getPackingHints();
1362                 packing |= PACK_UNIFORM_WIDTH;
1363                 m_tabbook->setPackingHints(packing);
1364             }break;
1365         case 2: //top
1366             {
1367                 m_tabbook->setTabStyle(TABBOOK_TOPTABS);
1368                 for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1369                 {
1370                     static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->setTabOrientation(TAB_TOP);
1371                 }
1372                 FXuint packing = m_tabbook->getPackingHints();
1373                 packing &= ~PACK_UNIFORM_WIDTH;
1374                 m_tabbook->setPackingHints(packing);
1375             }break;
1376         case 3: //right
1377             {
1378                 m_tabbook->setTabStyle(TABBOOK_RIGHTTABS);
1379                 for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1380                 {
1381                     static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->setTabOrientation(TAB_RIGHT);
1382                 }
1383                 FXuint packing = m_tabbook->getPackingHints();
1384                 packing |= PACK_UNIFORM_WIDTH;
1385                 m_tabbook->setPackingHints(packing);
1386             }break;
1387         default:
1388             {
1389                 m_tabbook->setTabStyle(TABBOOK_BOTTOMTABS);
1390                 for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1391                 {
1392                     static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->setTabOrientation(TAB_BOTTOM);
1393                 }
1394                 FXuint packing = m_tabbook->getPackingHints();
1395                 packing &= ~PACK_UNIFORM_WIDTH;
1396                 m_tabbook->setPackingHints(packing);
1397             }
1398     }
1399 }
1400 
updateNickIcons()1401 void dxirc::updateNickIcons()
1402 {
1403     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1404     {
1405         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass)
1406         {
1407             static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->clearNickIcons();
1408         }
1409     }
1410     recreateNickIcons(m_app, m_preferences.m_themePath, m_preferences.m_colors.back);
1411     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1412     {
1413         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass)
1414         {
1415             static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->recreateNickIcons(m_preferences.m_themePath!="internal");
1416         }
1417     }
1418 }
1419 
updateServerWindow()1420 void dxirc::updateServerWindow()
1421 {
1422     if(m_preferences.m_ownServerWindow)
1423     {
1424         for(FXint i=0; i<m_ircengines.no(); i++)
1425             createIrcTab(m_ircengines[i]->getNetworkName(), ICO_SERVER, SERVER, m_ircengines[i]);
1426     }
1427     else
1428     {
1429         for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
1430         {
1431             if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass
1432                     && static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType()==SERVER)
1433             {
1434                 IrcEngine *currentserver = NULL;
1435                 for(FXint j=0; j < m_ircengines.no(); j++)
1436                 {
1437                     if(m_ircengines[j]->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))))
1438                     {
1439                         currentserver = m_ircengines[j];
1440                         break;
1441                     }
1442                 }
1443                 if(currentserver) currentserver->removeTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i)));
1444                 delete m_tabbook->childAtIndex(i);
1445                 delete m_tabbook->childAtIndex(i);
1446             }
1447         }
1448         m_tabbook->recalc();
1449         if(m_tabbook->numChildren())
1450         {
1451             m_tabbook->setCurrent(0, TRUE);
1452         }
1453         sortTabs();
1454         updateMenus();
1455     }
1456 }
1457 
createSmileys()1458 void dxirc::createSmileys()
1459 {
1460     while(m_smileys.no())
1461     {
1462         delete m_smileys[0].icon;
1463         m_smileys[0].icon = NULL;
1464         m_smileys.erase(0);
1465     }
1466     if((FXint)m_preferences.m_smileysMap.size() && m_ircFont)
1467     {
1468         StringIt it;
1469         for(it=m_preferences.m_smileysMap.begin(); it!=m_preferences.m_smileysMap.end(); it++)
1470         {
1471             dxSmiley smiley;
1472             smiley.text = (*it).first;
1473             smiley.path = (*it).second;
1474             smiley.icon = makeIcon(m_app, smiley.path, m_ircFont->getFontHeight(), m_preferences.m_colors.back);
1475             m_smileys.append(smiley);
1476         }
1477     }
1478 }
1479 
onCmdAbout(FXObject *,FXSelector,void *)1480 long dxirc::onCmdAbout(FXObject*, FXSelector, void*)
1481 {
1482     AboutDialog about(this);
1483     about.execute(PLACEMENT_OWNER);
1484     return 1;
1485 }
1486 
onCmdDccCancel(FXObject *,FXSelector,void * ptr)1487 long dxirc::onCmdDccCancel(FXObject*, FXSelector, void *ptr)
1488 {
1489     FXint index = (FXint)(FXival)ptr;
1490     if(index >= m_dccfilesList.no())
1491         return 1;
1492     for(FXint i=0; i<m_dccengines.no(); i++)
1493     {
1494         if(m_dccengines[i]->hasDccFile(m_dccfilesList[index]))
1495         {
1496             m_dccengines[i]->disconnect();
1497             return 1;
1498         }
1499     }
1500     //dccfile hasn't server
1501     m_dccfilesList[index].canceled = TRUE;
1502     m_dccfilesList[index].token = -1;
1503     return 1;
1504 }
1505 
onCmdServers(FXObject *,FXSelector,void *)1506 long dxirc::onCmdServers(FXObject*, FXSelector, void*)
1507 {
1508     dxUtils.debugLine("OnCommandServers");
1509     ServerDialog *dialog = new ServerDialog(this, m_preferences.m_serverList);
1510     if(dialog->execute(PLACEMENT_OWNER))
1511     {
1512         FXint indexJoin = -1;
1513         m_preferences.m_serverList = dialog->getServers();
1514         indexJoin = dialog->getIndexJoin();
1515         if(indexJoin != -1 && !serverExist(m_preferences.m_serverList[indexJoin].hostname, m_preferences.m_serverList[indexJoin].port, m_preferences.m_serverList[indexJoin].nick))
1516         {
1517             connectServer(m_preferences.m_serverList[indexJoin].hostname, m_preferences.m_serverList[indexJoin].port, m_preferences.m_serverList[indexJoin].passwd, m_preferences.m_serverList[indexJoin].nick, m_preferences.m_serverList[indexJoin].realname, m_preferences.m_serverList[indexJoin].channels, m_preferences.m_serverList[indexJoin].commands, m_preferences.m_serverList[indexJoin].useSsl);
1518         }
1519     }
1520     return 1;
1521 }
1522 
onCmdConnect(FXObject *,FXSelector,void *)1523 long dxirc::onCmdConnect(FXObject*, FXSelector, void*)
1524 {
1525     FXDialogBox serverEdit(this, _("Quick connect"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
1526     serverEdit.getAccelTable()->addAccel(KEY_Return, &serverEdit, FXDialogBox::ID_ACCEPT);
1527     FXVerticalFrame *contents = new FXVerticalFrame(&serverEdit, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
1528     FXMatrix *matrix = new FXMatrix(contents,2,MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
1529 
1530     new FXLabel(matrix, _("Hostname:"),NULL,JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1531     FXTextField *hostname = new FXTextField(matrix, 25,NULL, 0, TEXTFIELD_ENTER_ONLY|FRAME_THICK|FRAME_SUNKEN|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1532 #ifdef DEBUG
1533     hostname->setText("localhost");
1534 #else
1535     hostname->setText("irc.libera.chat");
1536 #endif
1537 
1538     new FXLabel(matrix, _("Port:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1539     FXSpinner *port = new FXSpinner(matrix, 23,NULL, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1540     port->setRange(0, 65536);
1541     port->setValue(6667);
1542 
1543     new FXLabel(matrix, _("Password:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1544     FXTextField *passwd = new FXTextField(matrix, 25, NULL, 0, TEXTFIELD_PASSWD|TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1545 
1546     new FXLabel(matrix, _("Nickname:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1547     FXTextField *nick = new FXTextField(matrix, 25, NULL, 0, TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1548     nick->setText(FXSystem::currentUserName());
1549 
1550     new FXLabel(matrix, _("Realname:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1551     FXTextField* realname = new FXTextField(matrix, 25, NULL, 0, TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1552 
1553     new FXLabel(matrix, _("Channel(s):\tChannels need to be comma separated"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1554     FXTextField *channel = new FXTextField(matrix, 25, NULL, 0, TEXTFIELD_ENTER_ONLY|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1555     channel->setText("#");
1556 
1557 #ifdef HAVE_OPENSSL
1558     new FXLabel(matrix, _("Use SSL:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1559     FXCheckButton *ussl = new FXCheckButton(matrix, "", NULL, 0);
1560 #endif //HAVE_OPENSSL
1561 
1562     new FXLabel(matrix, _("Commands on connection:"), NULL, JUSTIFY_LEFT|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW);
1563     FXHorizontalFrame *commandsbox=new FXHorizontalFrame(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|FRAME_SUNKEN|FRAME_THICK,0,0,0,0, 0,0,0,0);
1564     FXText *command = new FXText(commandsbox, NULL, 0, TEXT_WORDWRAP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
1565     command->setVisibleRows(4);
1566     command->setVisibleColumns(25);
1567 
1568     FXHorizontalFrame *buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
1569     new dxEXButton(buttonframe, _("&Cancel"), NULL, &serverEdit, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1570     new dxEXButton(buttonframe, _("&OK"), NULL, &serverEdit, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1571     if (serverEdit.execute(PLACEMENT_OWNER))
1572     {
1573 #ifdef HAVE_OPENSSL
1574         connectServer(hostname->getText(), port->getValue(), passwd->getText(), nick->getText(), realname->getText(), channel->getText(), command->getText(), ussl->getCheck());
1575 #else
1576         connectServer(hostname->getText(), port->getValue(), passwd->getText(), nick->getText(), realname->getText(), channel->getText(), command->getText(), FALSE);
1577 #endif //HAVE_OPENSSL
1578     }
1579     return 1;
1580 }
1581 
onTabConnect(FXObject *,FXSelector,void * data)1582 long dxirc::onTabConnect(FXObject*, FXSelector, void *data)
1583 {
1584     ServerInfo *srv = (ServerInfo*)data;
1585     connectServer(srv->hostname, srv->port, srv->passwd, srv->nick, srv->realname, srv->channels, "", FALSE);
1586     return 1;
1587 }
1588 
connectServer(FXString hostname,FXint port,FXString pass,FXString nick,FXString rname,FXString channels,FXString commands,FXbool ssl)1589 void dxirc::connectServer(FXString hostname, FXint port, FXString pass, FXString nick, FXString rname, FXString channels, FXString commands, FXbool ssl)
1590 {
1591     dxUtils.debugLine("ConnectServer");
1592     if(m_ircengines.no() == 1 && !m_ircengines[0]->getConnected() && !m_ircengines[0]->getConnecting())
1593     {
1594         m_ircengines[0]->setServerName(hostname);
1595         m_ircengines[0]->setServerPort(port);
1596         m_ircengines[0]->setServerPassword(pass);
1597         nick.length() ? m_ircengines[0]->setNickName(nick) : m_ircengines[0]->setNickName("_xxx_");
1598         nick.length() ? m_ircengines[0]->setUserName(nick) : m_ircengines[0]->setUserName("_xxx_");
1599         rname.length() ? m_ircengines[0]->setRealName(rname) : m_ircengines[0]->setRealName(nick.length() ? nick : "_xxx_");
1600         if(channels.length()>1) m_ircengines[0]->setStartChannels(channels);
1601         if(commands.length()) m_ircengines[0]->setStartCommands(commands);
1602 #ifndef HAVE_OPENSSL
1603         ssl = FALSE;
1604 #endif //HAVE_OPENSSL
1605         m_ircengines[0]->setUseSsl(ssl);
1606         if(!m_tabbook->numChildren())
1607         {
1608             createIrcTab(hostname, ICO_SERVER, SERVER, m_ircengines[0]);
1609             m_tabbook->recalc();
1610         }
1611         else
1612         {
1613             FXbool needNewTab = TRUE;
1614             for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
1615             {
1616                 if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass
1617                         && static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType()==SERVER)
1618                 {
1619                     static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->setText(hostname);
1620                     sortTabs();
1621                     needNewTab = FALSE;
1622                     break;
1623                 }
1624             }
1625             if(needNewTab) createIrcTab(hostname, ICO_SERVER, SERVER, m_ircengines[0]);
1626         }
1627         m_ircengines[0]->clearAttempts();
1628         m_ircengines[0]->startConnection();
1629     }
1630     else if(!serverExist(hostname, port, nick))
1631     {
1632         IrcEngine *server = new IrcEngine(m_app, this, channels.length()>1 ? channels : "", commands.length() ? commands : "");
1633         m_ircengines.prepend(server);
1634         m_ircengines[0]->setServerName(hostname);
1635         m_ircengines[0]->setServerPort(port);
1636         m_ircengines[0]->setServerPassword(pass);
1637         nick.length() ? m_ircengines[0]->setNickName(nick) : m_ircengines[0]->setNickName("_xxx_");
1638         nick.length() ? m_ircengines[0]->setUserName(nick) : m_ircengines[0]->setUserName("_xxx_");
1639         rname.length() ? m_ircengines[0]->setRealName(rname) : m_ircengines[0]->setRealName(nick.length() ? nick : "_xxx_");
1640 #ifndef HAVE_OPENSSL
1641         ssl = FALSE;
1642 #endif //HAVE_OPENSSL
1643         m_ircengines[0]->setUseSsl(ssl);
1644         createIrcTab(hostname, ICO_SERVER, SERVER, m_ircengines[0]);
1645         m_ircengines[0]->clearAttempts();
1646         m_ircengines[0]->startConnection();
1647     }
1648     updateMenus();
1649 }
1650 
onCmdDisconnect(FXObject *,FXSelector,void *)1651 long dxirc::onCmdDisconnect(FXObject*, FXSelector, void*)
1652 {
1653     if(m_tabbook->numChildren())
1654     {
1655         FXint index = m_tabbook->getCurrent()*2;
1656         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&TetrisTabItem::metaClass) return 0;
1657         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&IrcTabItem::metaClass)
1658         {
1659             IrcTabItem *currenttab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index));
1660             IrcEngine *currentserver = NULL;
1661             for(FXint i=0; i < m_ircengines.no(); i++)
1662             {
1663                 if(m_ircengines[i]->findTarget(currenttab))
1664                 {
1665                     currentserver = m_ircengines[i];
1666                     break;
1667                 }
1668             }
1669             if(currentserver == NULL) return 0;
1670             if(currentserver->getConnected())
1671             {
1672                 FXDialogBox confirmDialog(this, _("Confirm disconnect"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
1673                 FXVerticalFrame *contents = new FXVerticalFrame(&confirmDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
1674                 new FXLabel(contents, FXStringFormat(_("Disconnect server: %s\nPort: %d\nNick: %s"), currentserver->getNetworkName().text(), currentserver->getServerPort(), currentserver->getNickName().text()), NULL, JUSTIFY_LEFT|ICON_BEFORE_TEXT);
1675                 FXHorizontalFrame* buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
1676                 new dxEXButton(buttonframe, _("&No"), NULL, &confirmDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1677                 new dxEXButton(buttonframe, _("&Yes"), NULL, &confirmDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1678                 if (confirmDialog.execute(PLACEMENT_OWNER))
1679                 {
1680                     currentserver->disconnect();
1681                     for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
1682                     {
1683                         if(currentserver->findTarget(m_tabbook->childAtIndex(i)))
1684                         {
1685                             if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == CHANNEL)
1686                             {
1687                                 m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
1688                                 m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
1689                             }
1690                             currentserver->removeTarget(m_tabbook->childAtIndex(i));
1691                             delete m_tabbook->childAtIndex(i);
1692                             delete m_tabbook->childAtIndex(i);
1693                         }
1694                     }
1695                     m_tabbook->recalc();
1696                     if(m_tabbook->numChildren())
1697                     {
1698                         sortTabs();
1699                         m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
1700                     }
1701                 }
1702             }
1703             else
1704             {
1705                 currentserver->disconnect();
1706                 for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
1707                 {
1708                     if(currentserver->findTarget(m_tabbook->childAtIndex(i)))
1709                     {
1710                         if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == CHANNEL)
1711                         {
1712                             m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
1713                             m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
1714                         }
1715                         currentserver->removeTarget(m_tabbook->childAtIndex(i));
1716                         delete m_tabbook->childAtIndex(i);
1717                         delete m_tabbook->childAtIndex(i);
1718                     }
1719                 }
1720                 m_tabbook->recalc();
1721                 if(m_tabbook->numChildren())
1722                 {
1723                     sortTabs();
1724                     m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
1725                 }
1726             }
1727         }
1728         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&DccTabItem::metaClass)
1729         {
1730             DccTabItem *currenttab = static_cast<DccTabItem*>(m_tabbook->childAtIndex(index));
1731             if(currenttab->getConnected())
1732             {
1733                 FXDialogBox confirmDialog(this, _("Confirm disconnect"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
1734                 FXVerticalFrame *contents = new FXVerticalFrame(&confirmDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
1735                 new FXLabel(contents, FXStringFormat(_("Disconnect dcc connection: %s\nPort: %d\nWith: %s"), currenttab->getServerName().text(), currenttab->getServerPort(), currenttab->getText().text()), NULL, JUSTIFY_LEFT|ICON_BEFORE_TEXT);
1736                 FXHorizontalFrame* buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
1737                 new dxEXButton(buttonframe, _("&No"), NULL, &confirmDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1738                 new dxEXButton(buttonframe, _("&Yes"), NULL, &confirmDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1739                 if (confirmDialog.execute(PLACEMENT_OWNER))
1740                 {
1741                     currenttab->disconnect();
1742                     delete m_tabbook->childAtIndex(index);
1743                     delete m_tabbook->childAtIndex(index);
1744                     m_tabbook->recalc();
1745                     if(m_tabbook->numChildren())
1746                     {
1747                         sortTabs();
1748                         m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
1749                     }
1750                 }
1751             }
1752             else
1753             {
1754                 delete m_tabbook->childAtIndex(index);
1755                 delete m_tabbook->childAtIndex(index);
1756                 m_tabbook->recalc();
1757                 if(m_tabbook->numChildren())
1758                 {
1759                     sortTabs();
1760                     m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
1761                 }
1762             }
1763         }
1764         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&BoatsTabItem::metaClass)
1765         {
1766             BoatsTabItem *currenttab = static_cast<BoatsTabItem*>(m_tabbook->childAtIndex(index));
1767             IrcEngine *currentserver = NULL;
1768             for(FXint i=0; i < m_ircengines.no(); i++)
1769             {
1770                 if(m_ircengines[i]->findTarget(currenttab))
1771                 {
1772                     currentserver = m_ircengines[i];
1773                     break;
1774                 }
1775             }
1776             if(currentserver == NULL) return 0;
1777             if(currentserver->getConnected())
1778             {
1779                 FXDialogBox confirmDialog(this, _("Confirm disconnect"), DECOR_TITLE|DECOR_BORDER, 0,0,0,0, 0,0,0,0, 0,0);
1780                 FXVerticalFrame *contents = new FXVerticalFrame(&confirmDialog, LAYOUT_SIDE_LEFT|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 10,10,10,10, 0,0);
1781                 new FXLabel(contents, FXStringFormat(_("Disconnect server: %s\nPort: %d\nNick: %s"), currentserver->getNetworkName().text(), currentserver->getServerPort(), currentserver->getNickName().text()), NULL, JUSTIFY_LEFT|ICON_BEFORE_TEXT);
1782                 FXHorizontalFrame* buttonframe = new FXHorizontalFrame(contents,LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH);
1783                 new dxEXButton(buttonframe, _("&No"), NULL, &confirmDialog, FXDialogBox::ID_CANCEL, FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1784                 new dxEXButton(buttonframe, _("&Yes"), NULL, &confirmDialog, FXDialogBox::ID_ACCEPT, BUTTON_INITIAL|BUTTON_DEFAULT|FRAME_RAISED|FRAME_THICK|LAYOUT_RIGHT, 0,0,0,0, 10,10,2,2);
1785                 if (confirmDialog.execute(PLACEMENT_OWNER))
1786                 {
1787                     currentserver->disconnect();
1788                     for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
1789                     {
1790                         if(currentserver->findTarget(m_tabbook->childAtIndex(i)))
1791                         {
1792                             if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == CHANNEL)
1793                             {
1794                                 m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
1795                                 m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
1796                             }
1797                             currentserver->removeTarget(m_tabbook->childAtIndex(i));
1798                             delete m_tabbook->childAtIndex(i);
1799                             delete m_tabbook->childAtIndex(i);
1800                         }
1801                     }
1802                     m_tabbook->recalc();
1803                     if(m_tabbook->numChildren())
1804                     {
1805                         sortTabs();
1806                         m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
1807                     }
1808                 }
1809             }
1810             else
1811             {
1812                 currentserver->disconnect();
1813                 for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
1814                 {
1815                     if(currentserver->findTarget(m_tabbook->childAtIndex(i)))
1816                     {
1817                         if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == CHANNEL)
1818                         {
1819                             m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
1820                             m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
1821                         }
1822                         currentserver->removeTarget(m_tabbook->childAtIndex(i));
1823                         delete m_tabbook->childAtIndex(i);
1824                         delete m_tabbook->childAtIndex(i);
1825                     }
1826                 }
1827                 m_tabbook->recalc();
1828                 if(m_tabbook->numChildren())
1829                 {
1830                     sortTabs();
1831                     m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
1832                 }
1833             }
1834         }
1835     }
1836     updateMenus();
1837     return 1;
1838 }
1839 
1840 //handle dxirc_RECONNECT
onCmdReconnect(FXObject *,FXSelector,void *)1841 long dxirc::onCmdReconnect(FXObject*, FXSelector, void*)
1842 {
1843     for(FXint i=0; i<m_ircengines.no(); i++)
1844         m_ircengines[i]->reconnect();
1845     return 1;
1846 }
1847 
onIrcEvent(FXObject * obj,FXSelector,void * data)1848 long dxirc::onIrcEvent(FXObject *obj, FXSelector, void *data)
1849 {
1850     IrcEvent *ev = (IrcEvent *)data;
1851     IrcEngine *server = (IrcEngine *)obj;
1852     if(ev->eventType == IRC_NEWCHANNEL)
1853     {
1854         onIrcNewchannel(server, ev);
1855         return 1;
1856     }
1857     if(ev->eventType == IRC_QUERY)
1858     {
1859         onIrcQuery(server, ev);
1860         return 1;
1861     }
1862     if(ev->eventType == IRC_PART)
1863     {
1864         onIrcPart(server, ev);
1865         return 1;
1866     }
1867     if(ev->eventType == IRC_KICK)
1868     {
1869         onIrcKick(server, ev);
1870         return 1;
1871     }
1872     if(ev->eventType == IRC_DISCONNECT)
1873     {
1874         onIrcDisconnect(server, ev);
1875         return 1;
1876     }
1877     if(ev->eventType == IRC_RECONNECT || ev->eventType == IRC_RECONNECTALL || ev->eventType == IRC_CONNECT)
1878     {
1879         onIrcConnectAndReconnect(ev);
1880         return 1;
1881     }
1882     if(ev->eventType == IRC_ENDMOTD)
1883     {
1884         onIrcEndmotd();
1885         return 1;
1886     }
1887     if(ev->eventType == IRC_PRIVMSG || ev->eventType == IRC_ACTION)
1888     {
1889         onIrcPrivmsgAndAction(server, ev);
1890         return 1;
1891     }
1892     if(ev->eventType == IRC_JOIN)
1893     {
1894         onIrcJoin(server, ev);
1895         return 1;
1896     }
1897     if(ev->eventType == IRC_QUIT)
1898     {
1899         onIrcQuit(server, ev);
1900         return 1;
1901     }
1902     if(ev->eventType == IRC_INVITE)
1903     {
1904         onIrcInvite(server, ev);
1905         return 1;
1906     }
1907     if(ev->eventType == IRC_DCCCHAT)
1908     {
1909         onIrcDccChat(server, ev);
1910         return 1;
1911     }
1912     if(ev->eventType == IRC_DCCSERVER)
1913     {
1914         onIrcDccServer(server, ev);
1915         return 1;
1916     }
1917     if(ev->eventType == IRC_DCCIN)
1918     {
1919         onIrcDccIn(server, ev);
1920         return 1;
1921     }
1922     if(ev->eventType == IRC_DCCOUT)
1923     {
1924         onIrcDccOut(server, ev);
1925         return 1;
1926     }
1927     if(ev->eventType == IRC_DCCPOUT)
1928     {
1929         onIrcDccPout(server, ev);
1930         return 1;
1931     }
1932     if(ev->eventType == IRC_DCCMYTOKEN)
1933     {
1934         onIrcDccMyToken(server, ev);
1935         return 1;
1936     }
1937     if(ev->eventType == IRC_DCCTOKEN)
1938     {
1939         onIrcDccToken(server, ev);
1940         return 1;
1941     }
1942     //IrcEngine couldn't send IRC_DCCPOSITION :)
1943     if(ev->eventType == IRC_DCCPOSITION)
1944     {
1945         return 1;
1946     }
1947     if(ev->eventType == IRC_DCCRESUME)
1948     {
1949         onIrcDccResume(server, ev);
1950         return 1;
1951     }
1952     if(ev->eventType == IRC_DCCPRESUME)
1953     {
1954         onIrcDccPresume(server, ev);
1955         return 1;
1956     }
1957     if(ev->eventType == IRC_DCCACCEPT)
1958     {
1959         onIrcDccAccept(server, ev);
1960         return 1;
1961     }
1962     if(ev->eventType == IRC_DCCPACCEPT)
1963     {
1964         onIrcDccPaccept(server, ev);
1965         return 1;
1966     }
1967     if(ev->eventType == IRC_BOATSINVITE)
1968     {
1969         onIrcBoatsInvite(server, ev);
1970         return 1;
1971     }
1972     if(ev->eventType == IRC_BOATSACCEPT)
1973     {
1974         onIrcBoatsAccept(server, ev);
1975         return 1;
1976     }
1977     if(ev->eventType == IRC_RAW)
1978     {
1979         onIrcRaw(server, ev);
1980         return 1;
1981     }
1982     if(ev->eventType == IRC_323)
1983     {
1984         onIrc323(server);
1985         return 1;
1986     }
1987     return 1;
1988 }
1989 
onDccEvent(FXObject * obj,FXSelector,void * data)1990 long dxirc::onDccEvent(FXObject *obj, FXSelector, void *data)
1991 {
1992     IrcEvent *ev = (IrcEvent *)data;
1993     DccEngine *dcc = (DccEngine *)obj;
1994     if(ev->eventType == IRC_DISCONNECT)
1995     {
1996         appendIrcStyledText(FXStringFormat("\"%s\": %s", FXPath::name(ev->dccFile.path).text(), ev->param1.text()), 4, FALSE);
1997         return 1;
1998     }
1999     if(ev->eventType == IRC_ERROR)
2000     {
2001         appendIrcStyledText(FXStringFormat("\"%s\": %s", FXPath::name(ev->dccFile.path).text(), ev->param1.text()), 4, FALSE);
2002         return 1;
2003     }
2004     if(ev->eventType == IRC_DCCPOSITION)
2005     {
2006         onIrcDccPosition(dcc, ev);
2007         return 1;
2008     }
2009     return 1;
2010 }
2011 
2012 //handle IrcEvent IRC_NEWCHANNEL
onIrcNewchannel(IrcEngine * server,IrcEvent * ev)2013 void dxirc::onIrcNewchannel(IrcEngine *server, IrcEvent *ev)
2014 {
2015     FXint serverTabIndex = getServerTab(server);
2016     if(tabExist(server, ev->param1, CHANNEL))
2017     {
2018         return;
2019     }
2020     if(serverTabIndex != -1 && !m_preferences.m_ownServerWindow)
2021     {
2022         static_cast<IrcTabItem*>(m_tabbook->childAtIndex(serverTabIndex))->setType(CHANNEL, ev->param1);
2023         static_cast<IrcTabItem*>(m_tabbook->childAtIndex(serverTabIndex))->setTextColor(m_preferences.m_appTheme.fore);
2024         m_tabbook->setCurrent(FXMAX(0,serverTabIndex/2-1), TRUE);
2025         sortTabs();
2026     }
2027     else
2028     {
2029         createIrcTab(ev->param1, ICO_CHANNEL, CHANNEL, server);
2030     }
2031     updateMenus();
2032 }
2033 
2034 //handle IrcEvent IRC_QUERY
onIrcQuery(IrcEngine * server,IrcEvent * ev)2035 void dxirc::onIrcQuery(IrcEngine *server, IrcEvent *ev)
2036 {
2037     if(tabExist(server, ev->param1, QUERY))
2038         return;
2039     FXint serverTabIndex = getServerTab(server);
2040     if(serverTabIndex != -1 && !m_preferences.m_ownServerWindow)
2041     {
2042         static_cast<IrcTabItem*>(m_tabbook->childAtIndex(serverTabIndex))->setType(QUERY, ev->param1);
2043         m_tabbook->setCurrent(FXMAX(0,serverTabIndex/2-1), TRUE);
2044         sortTabs();
2045     }
2046     else
2047     {
2048         setCurrentTabById(createIrcTab(ev->param1, ICO_QUERY, QUERY, server));
2049     }
2050     updateMenus();
2051 }
2052 
2053 //handle IrcEvent IRC_PART
onIrcPart(IrcEngine * server,IrcEvent * ev)2054 void dxirc::onIrcPart(IrcEngine *server, IrcEvent *ev)
2055 {
2056 #ifdef HAVE_LUA
2057     for(FXint i=0; i<m_scriptEvents.no(); i++)
2058     {
2059         if(comparecase("part", m_scriptEvents[i].name) == 0)
2060         {
2061             for(FXint j=0; j<m_scripts.no(); j++)
2062             {
2063                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
2064                 {
2065 //                    lua_pushstring(m_scripts[j].L, m_scriptEvents[i].funcname.text());
2066 //                    lua_gettable(m_scripts[j].L, LUA_GLOBALSINDEX);
2067                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
2068                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
2069                     else
2070                     {
2071                         lua_pushstring(m_scripts[j].L, ev->param1.text());
2072                         lua_pushinteger(m_scripts[j].L, getTabId(server, ev->param2));
2073                         if (lua_pcall(m_scripts[j].L, 2, 0, 0))
2074                         {
2075                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
2076                             lua_pop(m_scripts[j].L, 1);
2077                         }
2078                     }
2079                 }
2080             }
2081         }
2082     }
2083 #endif //HAVE_LUA
2084     if(isFriend(ev->param1, ev->param2, server->getNetworkName()))
2085     {
2086         if(m_preferences.m_sounds && m_preferences.m_soundDisconnect)
2087             dxutils::playFile(m_preferences.m_pathDisconnect);
2088         if(m_preferences.m_notify && m_preferences.m_notifyDisconnect)
2089             showNotify(FXStringFormat(_("%s has parted %s"), ev->param1.text(), ev->param2.text()));
2090     }
2091     if(tabExist(server, ev->param2, CHANNEL))
2092     {
2093         if(ev->param1 == server->getNickName())
2094         {
2095             if(server->getConnected() && isLastTab(server))
2096             {
2097                 for(FXint j = 0; j < m_tabbook->numChildren(); j+=2)
2098                 {
2099                     if(server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))))
2100                     {
2101                         m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))->getText());
2102                         m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))->getSpellLang()));
2103                         static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))->setType(SERVER, server->getNetworkName());
2104                         m_tabbook->setCurrent(j/2-1, TRUE);
2105                         break;
2106                     }
2107                 }
2108             }
2109             else
2110             {
2111                 FXint index = -1;
2112                 for(FXint j = 0; j < m_tabbook->numChildren(); j+=2)
2113                 {
2114                     if((comparecase(static_cast<FXTabItem*>(m_tabbook->childAtIndex(j))->getText(), ev->param2) == 0) && server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j)))) index = j;
2115                 }
2116                 if(index == -1) return;
2117                 m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index))->getText());
2118                 m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index))->getSpellLang()));
2119                 server->removeTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index)));
2120                 delete m_tabbook->childAtIndex(index);
2121                 delete m_tabbook->childAtIndex(index);
2122                 m_tabbook->recalc();
2123                 if(m_tabbook->numChildren())
2124                 {
2125                     m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
2126                 }
2127             }
2128             sortTabs();
2129             updateMenus();
2130         }
2131     }
2132 }
2133 
2134 //handle IrcEvent IRC_KICK
onIrcKick(IrcEngine * server,IrcEvent * ev)2135 void dxirc::onIrcKick(IrcEngine *server, IrcEvent *ev)
2136 {
2137     if(ev->param2 == server->getNickName())
2138     {
2139         if(server->getConnected() && isLastTab(server))
2140         {
2141             for(FXint j = 0; j < m_tabbook->numChildren(); j+=2)
2142             {
2143                 if(server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))))
2144                 {
2145                     static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j))->setType(SERVER, server->getNetworkName());
2146                     m_tabbook->setCurrent(j/2-1, TRUE);
2147                     break;
2148                 }
2149             }
2150         }
2151         else
2152         {
2153             FXint index = -1;
2154             for(FXint j = 0; j < m_tabbook->numChildren(); j+=2)
2155             {
2156                 if((comparecase(static_cast<FXTabItem*>(m_tabbook->childAtIndex(j))->getText(), ev->param3) == 0) && server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(j)))) index = j;
2157             }
2158             if(index == -1) return;
2159             server->removeTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index)));
2160             delete m_tabbook->childAtIndex(index);
2161             delete m_tabbook->childAtIndex(index);
2162             m_tabbook->recalc();
2163             if(m_tabbook->numChildren())
2164             {
2165                 m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
2166             }
2167         }
2168         sortTabs();
2169         updateMenus();
2170     }
2171 }
2172 
2173 //handle IrcEvent IRC_DISCONNECT
onIrcDisconnect(IrcEngine * server,IrcEvent * ev)2174 void dxirc::onIrcDisconnect(IrcEngine *server, IrcEvent *ev)
2175 {
2176     for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
2177     {
2178         if(server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))))
2179         {
2180             if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == CHANNEL)
2181             {
2182                 m_preferences.m_langs.erase(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText());
2183                 m_preferences.m_langs.insert(StringPair(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getText(), static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getSpellLang()));
2184             }
2185             server->removeTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i)));
2186             delete m_tabbook->childAtIndex(i);
2187             delete m_tabbook->childAtIndex(i);
2188         }
2189     }
2190     m_tabbook->recalc();
2191     if(m_tabbook->numChildren())
2192     {
2193         sortTabs();
2194         m_tabbook->setCurrent(0, TRUE);
2195     }
2196     updateMenus();
2197     updateStatus(ev->param1);
2198 }
2199 
2200 //handle IrcEvent IRC_CONNECT and IRC_RECONNECT
onIrcConnectAndReconnect(IrcEvent * ev)2201 void dxirc::onIrcConnectAndReconnect(IrcEvent *ev)
2202 {
2203     updateStatus(ev->param1);
2204 }
2205 
2206 //handle IrcEvent IRC_ENDMOTD
onIrcEndmotd()2207 void dxirc::onIrcEndmotd()
2208 {
2209     updateMenus();
2210 }
2211 
2212 //handle IrcEvent IRC_PRIVMSG and IRC_ACTION
onIrcPrivmsgAndAction(IrcEngine * server,IrcEvent * ev)2213 void dxirc::onIrcPrivmsgAndAction(IrcEngine *server, IrcEvent *ev)
2214 {
2215 
2216 #ifdef HAVE_TRAY
2217     if(m_trayIcon && m_preferences.m_notifyTray && m_trayIcon->getIcon() == ICO_TRAY && !shown())
2218         m_trayIcon->setIcon(ICO_NEWMSG);
2219 #endif //HAVE_TRAY
2220 #ifdef HAVE_LUA
2221     if(!m_scripts.no() || !m_scriptEvents.no()) return;
2222     for(FXint i=0; i<m_scriptEvents.no(); i++)
2223     {
2224         if(comparecase("privmsg", m_scriptEvents[i].name) == 0)
2225         {
2226             for(FXint j=0; j<m_scripts.no(); j++)
2227             {
2228                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
2229                 {
2230                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
2231                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
2232                     else
2233                     {
2234                         lua_pushstring(m_scripts[j].L, ev->param1.text());
2235                         lua_pushstring(m_scripts[j].L, ev->param3.text());
2236                         lua_pushinteger(m_scripts[j].L, getTabId(server, ev->param2 == server->getNickName() ? ev->param1 : ev->param2));
2237                         if (lua_pcall(m_scripts[j].L, 3, 0, 0))
2238                         {
2239                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
2240                             lua_pop(m_scripts[j].L, 1);
2241                         }
2242                     }
2243                 }
2244             }
2245         }
2246     }
2247 #endif //HAVE_LUA
2248 }
2249 
2250 //handle IrcEvent IRC_INVITE
onIrcInvite(IrcEngine * server,IrcEvent * ev)2251 void dxirc::onIrcInvite(IrcEngine *server, IrcEvent *ev)
2252 {
2253     if(m_preferences.m_ignoreCommandsList.contains("invite"))
2254         return;
2255     if(dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("%s invites you on %s on %s \n Do you want connect?"), ev->param1.text(), ev->param2.text(), server->getNetworkName().text()) == 1)
2256         server->sendJoin(ev->param2);
2257 }
2258 
2259 //handle IrcEvent IRC_JOIN
onIrcJoin(IrcEngine * server,IrcEvent * ev)2260 void dxirc::onIrcJoin(IrcEngine *server, IrcEvent *ev)
2261 {
2262     if(isFriend(ev->param1, ev->param2, server->getNetworkName()))
2263     {
2264         if(m_preferences.m_sounds && m_preferences.m_soundConnect)
2265             dxutils::playFile(m_preferences.m_pathConnect);
2266         if(m_preferences.m_notify && m_preferences.m_notifyConnect)
2267             showNotify(FXStringFormat(_("%s has joined to %s"), ev->param1.text(), ev->param2.text()));
2268     }
2269 #ifdef HAVE_LUA
2270     if(server->isUserIgnored(ev->param1, ev->param2)) return;
2271     if(!m_scripts.no() || !m_scriptEvents.no()) return;
2272     for(FXint i=0; i<m_scriptEvents.no(); i++)
2273     {
2274         if(comparecase("join", m_scriptEvents[i].name) == 0)
2275         {
2276             for(FXint j=0; j<m_scripts.no(); j++)
2277             {
2278                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
2279                 {
2280                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
2281                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
2282                     else
2283                     {
2284                         lua_pushstring(m_scripts[j].L, ev->param1.text());
2285                         lua_pushinteger(m_scripts[j].L, getTabId(server, ev->param2));
2286                         if (lua_pcall(m_scripts[j].L, 2, 0, 0))
2287                         {
2288                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
2289                             lua_pop(m_scripts[j].L, 1);
2290                         }
2291                     }
2292                 }
2293             }
2294         }
2295     }
2296 #endif //HAVE_LUA
2297 }
2298 
2299 //handle IrcEvent IRC_QUIT
onIrcQuit(IrcEngine * server,IrcEvent * ev)2300 void dxirc::onIrcQuit(IrcEngine *server, IrcEvent *ev)
2301 {
2302     if(isFriend(ev->param1, "all", server->getNetworkName()))
2303     {
2304         if(m_preferences.m_sounds && m_preferences.m_soundDisconnect)
2305             dxutils::playFile(m_preferences.m_pathDisconnect);
2306         if(m_preferences.m_notify && m_preferences.m_notifyDisconnect)
2307             showNotify(FXStringFormat(_("%s has quit"), ev->param1.text()));
2308     }
2309 }
2310 
2311 //handle IrcEvent IRC_DCCCHAT
onIrcDccChat(IrcEngine * server,IrcEvent * ev)2312 void dxirc::onIrcDccChat(IrcEngine *server, IrcEvent *ev)
2313 {
2314     if(m_preferences.m_autoDccChat)
2315         createDccTab(server->getNickName(), ev->param1, ev->param2, FXIntVal(ev->param3), FXIntVal(ev->param3), FALSE, server);
2316     if(!m_preferences.m_autoDccChat && dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("%s offers DCC Chat on %s(%s) port %s.\n Do you want connect?"), ev->param1.text(), ev->param2.text(), server->getHostname(ev->param2).text(), ev->param3.text()) == 1)
2317         createDccTab(server->getNickName(), ev->param1, ev->param2, FXIntVal(ev->param3), FXIntVal(ev->param3), FALSE, server);
2318 }
2319 
2320 //handle IrcEvent IRC_DCCSERVER
onIrcDccServer(IrcEngine * server,IrcEvent * ev)2321 void dxirc::onIrcDccServer(IrcEngine *server, IrcEvent *ev)
2322 {
2323     createDccTab(server->getNickName(), ev->param1, server->getLocalIP(), m_preferences.m_dccPortD, m_preferences.m_dccPortH, TRUE, server);
2324 }
2325 
2326 //handle IrcEvent IRC_DCCIN
onIrcDccIn(IrcEngine * server,IrcEvent * ev)2327 void dxirc::onIrcDccIn(IrcEngine *server, IrcEvent *ev)
2328 {
2329     if(m_preferences.m_autoDccFile)
2330     {
2331         DccFile dcc;
2332         dcc.path = getUniqueName(m_preferences.m_dccPath, FXPath::stripExtension(ev->param3), FXPath::extension(ev->param3));
2333         dcc.speed = 0;
2334         dcc.currentPosition = 0;
2335         dcc.size = FXLongVal(ev->param4);
2336         dcc.type = DCC_IN;
2337         dcc.started = FALSE;
2338         dcc.canceled = FALSE;
2339         dcc.finished = FALSE;
2340         dcc.finishedPosition = 0;
2341         dcc.token = -1;
2342         dcc.ip = ev->param2.before('@');
2343         dcc.port = FXIntVal(ev->param2.after('@'));
2344         dcc.nick = ev->param1;
2345         for(FXint i=0; i<m_dccfilesList.no(); i++)
2346         {
2347             if(dcc.path == m_dccfilesList[i].path && (m_dccfilesList[i].type==DCC_IN || m_dccfilesList[i].type==DCC_PIN))
2348             {
2349                 m_dccfilesList.erase(i);
2350                 break;
2351             }
2352         }
2353         m_dccfilesList.append(dcc);
2354         if(isForResume(FXPath::name(dcc.path)))
2355         {
2356             server->sendCtcp(ev->param1, "DCC RESUME "+FXPath::name(dcc.path)+" "+FXStringVal(dcc.port)+" "+FXStringVal(FXStat::size(dcc.path+".part")));
2357         }
2358         else
2359         {
2360             DccEngine *engine = new DccEngine(m_app, this, dcc, server);
2361             m_dccengines.append(engine);
2362             engine->startConnection();
2363             appendIrcStyledText(FXStringFormat(_("Receiving \"%s\" from %s"), ev->param3.text(), ev->param1.text()),8,FALSE);
2364         }
2365     }
2366     else
2367     {
2368         if(isForResume(ev->param3)
2369             &&dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("%s offers file %s with size %s over DCC .\nFile is already partially downloaded.\nDo you want continue in download?"), ev->param1.text(), ev->param3.text(), dxutils::getFileSize(ev->param4).text()) == 1)
2370         {
2371             DccFile dcc;
2372             dcc.path = m_preferences.m_dccPath+PATHSEPSTRING+ev->param3;
2373             dcc.speed = 0;
2374             dcc.currentPosition = 0;
2375             dcc.size = FXLongVal(ev->param4);
2376             dcc.type = DCC_IN;
2377             dcc.started = FALSE;
2378             dcc.canceled = FALSE;
2379             dcc.finished = FALSE;
2380             dcc.finishedPosition = 0;
2381             dcc.token = -1;
2382             dcc.ip = ev->param2.before('@');
2383             dcc.port = FXIntVal(ev->param2.after('@'));
2384             dcc.nick = ev->param1;
2385             for(FXint i=0; i<m_dccfilesList.no(); i++)
2386             {
2387                 if(dcc.path == m_dccfilesList[i].path && (m_dccfilesList[i].type==DCC_IN || m_dccfilesList[i].type==DCC_PIN))
2388                 {
2389                     m_dccfilesList.erase(i);
2390                     break;
2391                 }
2392             }
2393             m_dccfilesList.append(dcc);
2394             server->sendCtcp(ev->param1, "DCC RESUME "+FXPath::name(dcc.path)+" "+FXStringVal(dcc.port)+" "+FXStringVal(FXStat::size(dcc.path+".part")));
2395             return;
2396         }
2397         if(dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("%s offers file %s with size %s over DCC .\nDo you want connect?"), ev->param1.text(), ev->param3.text(), dxutils::getFileSize(ev->param4).text()) == 1)
2398         {
2399             dxEXFileDialog dialog(this, _("Save file"));
2400             dialog.setFilename(m_preferences.m_dccPath+PATHSEPSTRING+ev->param3);
2401             if(dialog.execute())
2402             {
2403                 DccFile dcc;
2404                 dcc.path = getUniqueName(FXPath::directory(dialog.getFilename()), FXPath::title(dialog.getFilename()), FXPath::extension(dialog.getFilename())); // dirty (owerwrite user opinion) but absolutely needed :)
2405                 dcc.speed = 0;
2406                 dcc.currentPosition = 0;
2407                 dcc.size = FXLongVal(ev->param4);
2408                 dcc.type = DCC_IN;
2409                 dcc.started = FALSE;
2410                 dcc.canceled = FALSE;
2411                 dcc.finished = FALSE;
2412                 dcc.finishedPosition = 0;
2413                 dcc.token = -1;
2414                 dcc.ip = ev->param2.before('@');
2415                 dcc.port = FXIntVal(ev->param2.after('@'));
2416                 dcc.nick = ev->param1;
2417                 for(FXint i=0; i<m_dccfilesList.no(); i++)
2418                 {
2419                     if(dcc.path == m_dccfilesList[i].path && (m_dccfilesList[i].type==DCC_IN || m_dccfilesList[i].type==DCC_PIN))
2420                     {
2421                         m_dccfilesList.erase(i);
2422                         break;
2423                     }
2424                 }
2425                 //old .part file have to be deleted
2426                 if(FXStat::exists(dcc.path+".part"))
2427                     FXFile::remove(dcc.path+".part");
2428                 m_dccfilesList.append(dcc);
2429                 DccEngine *engine = new DccEngine(m_app, this, dcc, server);
2430                 m_dccengines.append(engine);
2431                 engine->startConnection();
2432                 appendIrcStyledText(FXStringFormat(_("Receiving \"%s\" from %s"), ev->param3.text(), ev->param1.text()),8,FALSE);
2433                 onCmdTransfers(NULL, 0, NULL);
2434             }
2435         }
2436     }
2437 }
2438 
2439 //handle IrcEvent IRC_DCCOUT
onIrcDccOut(IrcEngine * server,IrcEvent * ev)2440 void dxirc::onIrcDccOut(IrcEngine *server, IrcEvent *ev)
2441 {
2442     DccFile dcc;
2443     dcc.path = ev->param2;
2444     dcc.speed = 0;
2445     dcc.currentPosition = 0;
2446     dcc.size = FXStat::size(ev->param2);
2447     dcc.type = DCC_OUT;
2448     dcc.started = FALSE;
2449     dcc.canceled = FALSE;
2450     dcc.finished = FALSE;
2451     dcc.finishedPosition = 0;
2452     dcc.ip = server->getLocalIP();
2453     dcc.port = 0;
2454     dcc.token = -1;
2455     dcc.nick = ev->param1;
2456     for(FXint i=0; i<m_dccfilesList.no(); i++)
2457     {
2458         if(dcc.path == m_dccfilesList[i].path && dcc.type == m_dccfilesList[i].type)
2459         {
2460             m_dccfilesList.erase(i);
2461             break;
2462         }
2463     }
2464     m_dccfilesList.append(dcc);
2465     DccEngine *engine = new DccEngine(m_app, this, dcc, server);
2466     m_dccengines.append(engine);
2467     engine->startConnection();
2468     onCmdTransfers(NULL, 0, NULL);
2469 }
2470 
2471 //handle IrcEvent IRC_DCCPOUT
onIrcDccPout(IrcEngine * server,IrcEvent * ev)2472 void dxirc::onIrcDccPout(IrcEngine *server, IrcEvent *ev)
2473 {
2474     DccFile dcc;
2475     dcc.path = ev->param2;
2476     dcc.speed = 0;
2477     dcc.currentPosition = 0;
2478     dcc.size = FXStat::size(ev->param2);
2479     dcc.type = DCC_POUT;
2480     dcc.started = FALSE;
2481     dcc.canceled = FALSE;
2482     dcc.finished = FALSE;
2483     dcc.finishedPosition = 0;
2484     if(m_lastToken==32767) m_lastToken=0;
2485     dcc.token = ++m_lastToken;
2486     dcc.nick = ev->param1;
2487     for(FXint i=0; i<m_dccfilesList.no(); i++)
2488     {
2489         if(dcc.path == m_dccfilesList[i].path && dcc.type == m_dccfilesList[i].type)
2490         {
2491             m_dccfilesList.erase(i);
2492             break;
2493         }
2494     }
2495     m_dccfilesList.append(dcc);
2496     server->sendCtcp(ev->param1, "DCC SEND "+dxutils::removeSpaces(dcc.path.rafter(PATHSEP))+" "+server->getLocalIPBinary()+" 0 "+FXStringVal(dcc.size)+" "+FXStringVal(dcc.token));
2497 }
2498 
2499 //handle IrcEvent IRC_DCCMYTOKEN
onIrcDccMyToken(IrcEngine * server,IrcEvent * ev)2500 void dxirc::onIrcDccMyToken(IrcEngine *server, IrcEvent *ev)
2501 {
2502     FXint token = FXIntVal(ev->param3);
2503     FXint index = -1;
2504     for(FXint i=0; i<m_dccfilesList.no(); i++)
2505     {
2506         if(m_dccfilesList[i].token == token && m_dccfilesList[i].type == DCC_POUT)
2507         {
2508             index = i;
2509             break;
2510         }
2511     }
2512     if(index == -1)
2513         return;
2514     m_dccfilesList[index].ip = ev->param1;
2515     m_dccfilesList[index].port = FXIntVal(ev->param2);
2516     DccEngine *engine = new DccEngine(m_app, this, m_dccfilesList[index], server);
2517     m_dccengines.append(engine);
2518     engine->startConnection();
2519     onCmdTransfers(NULL, 0, NULL);
2520 }
2521 
2522 //handle IrcEvent IRC_DCCTOKEN
onIrcDccToken(IrcEngine * server,IrcEvent * ev)2523 void dxirc::onIrcDccToken(IrcEngine *server, IrcEvent *ev)
2524 {
2525     if(m_preferences.m_autoDccFile)
2526     {
2527         DccFile dcc;
2528         dcc.path = getUniqueName(m_preferences.m_dccPath, FXPath::stripExtension(ev->param2), FXPath::extension(ev->param2));
2529         dcc.speed = 0;
2530         dcc.currentPosition = 0;
2531         dcc.size = FXLongVal(ev->param3);
2532         dcc.type = DCC_PIN;
2533         dcc.started = FALSE;
2534         dcc.canceled = FALSE;
2535         dcc.finished = FALSE;
2536         dcc.finishedPosition = 0;
2537         dcc.token = FXIntVal(ev->param4);
2538         dcc.nick = ev->param1;
2539         dcc.ip = server->getLocalIP();
2540         dcc.port = 0;
2541         for(FXint i=0; i<m_dccfilesList.no(); i++)
2542         {
2543             if(dcc.path == m_dccfilesList[i].path && (m_dccfilesList[i].type==DCC_IN || m_dccfilesList[i].type==DCC_PIN))
2544             {
2545                 m_dccfilesList.erase(i);
2546                 break;
2547             }
2548         }
2549         m_dccfilesList.append(dcc);
2550         if(isForResume(FXPath::name(dcc.path)))
2551         {
2552             server->sendCtcp(ev->param1, "DCC RESUME "+FXPath::name(dcc.path)+" 0 "+FXStringVal(FXStat::size(dcc.path+".part"))+" "+FXStringVal(dcc.token));
2553         }
2554         else
2555         {
2556             DccEngine *engine = new DccEngine(m_app, this, dcc, server);
2557             m_dccengines.append(engine);
2558             engine->startConnection();
2559             appendIrcStyledText(FXStringFormat(_("Receiving \"%s\" from %s"), ev->param2.text(), ev->param1.text()),8,FALSE);
2560         }
2561     }
2562     else
2563     {
2564         if(isForResume(ev->param2)
2565                 && dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("%s offers file %s with size %s over DCC passive.\nFile is already partially downloaded.\nDo you want continue in download?"), ev->param1.text(), ev->param2.text(), dxutils::getFileSize(ev->param3).text()) == 1)
2566         {
2567             DccFile dcc;
2568             dcc.path = m_preferences.m_dccPath+PATHSEPSTRING+ev->param2;
2569             dcc.speed = 0;
2570             dcc.currentPosition = 0;
2571             dcc.size = FXLongVal(ev->param3);
2572             dcc.type = DCC_PIN;
2573             dcc.started = FALSE;
2574             dcc.canceled = FALSE;
2575             dcc.finished = FALSE;
2576             dcc.finishedPosition = 0;
2577             dcc.token = FXIntVal(ev->param4);
2578             dcc.nick = ev->param1;
2579             for(FXint i=0; i<m_dccfilesList.no(); i++)
2580             {
2581                 if(dcc.path == m_dccfilesList[i].path && (m_dccfilesList[i].type==DCC_IN || m_dccfilesList[i].type==DCC_PIN))
2582                 {
2583                     m_dccfilesList.erase(i);
2584                     break;
2585                 }
2586             }
2587             m_dccfilesList.append(dcc);
2588             server->sendCtcp(ev->param1, "DCC RESUME "+ev->param2+" 0 "+FXStringVal(FXStat::size(dcc.path+".part"))+" "+FXStringVal(dcc.token));
2589             return;
2590         }
2591         if(dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("%s offers file %s with size %s over DCC passive.\n Do you want accept?"), ev->param1.text(), ev->param2.text(), dxutils::getFileSize(ev->param3).text()) == 1)
2592         {
2593             dxEXFileDialog dialog(this, _("Save file"));
2594             dialog.setFilename(m_preferences.m_dccPath+PATHSEPSTRING+ev->param2);
2595             if(dialog.execute())
2596             {
2597                 DccFile dcc;
2598                 dcc.path = getUniqueName(FXPath::directory(dialog.getFilename()), FXPath::title(dialog.getFilename()), FXPath::extension(dialog.getFilename())); // dirty (owerwrite user opinion) but absolutely needed :)
2599                 dcc.speed = 0;
2600                 dcc.currentPosition = 0;
2601                 dcc.size = FXLongVal(ev->param3);
2602                 dcc.type = DCC_PIN;
2603                 dcc.started = FALSE;
2604                 dcc.canceled = FALSE;
2605                 dcc.finished = FALSE;
2606                 dcc.finishedPosition = 0;
2607                 dcc.token = FXIntVal(ev->param4);
2608                 dcc.nick = ev->param1;
2609                 dcc.ip = server->getLocalIP();
2610                 dcc.port = 0;
2611                 for(FXint i=0; i<m_dccfilesList.no(); i++)
2612                 {
2613                     if(dcc.path == m_dccfilesList[i].path && (m_dccfilesList[i].type==DCC_IN || m_dccfilesList[i].type==DCC_PIN))
2614                     {
2615                         m_dccfilesList.erase(i);
2616                         break;
2617                     }
2618                 }
2619                 //old .part file have to be deleted
2620                 if(FXStat::exists(dcc.path+".part"))
2621                     FXFile::remove(dcc.path+".part");
2622                 m_dccfilesList.append(dcc);
2623                 DccEngine *engine = new DccEngine(m_app, this, dcc, server);
2624                 m_dccengines.append(engine);
2625                 engine->startConnection();
2626                 appendIrcStyledText(FXStringFormat(_("Receiving \"%s\" from %s"), ev->param2.text(), ev->param1.text()),8,FALSE);
2627                 onCmdTransfers(NULL, 0, NULL);
2628             }
2629         }
2630     }
2631 }
2632 
2633 //handle IrcEvent IRC_DCCPOSITION
onIrcDccPosition(DccEngine *,IrcEvent * ev)2634 void dxirc::onIrcDccPosition(DccEngine*, IrcEvent *ev)
2635 {
2636     FXint index = -1;
2637     for(FXint i=0; i<m_dccfilesList.no(); i++)
2638     {
2639         if(m_dccfilesList[i].path == ev->dccFile.path)
2640         {
2641             index = i;
2642             break;
2643         }
2644     }
2645     if(index == -1) return;
2646     m_dccfilesList[index].speed = ev->dccFile.speed;
2647     m_dccfilesList[index].currentPosition = ev->dccFile.currentPosition;
2648     m_dccfilesList[index].finishedPosition = ev->dccFile.finishedPosition;
2649     m_dccfilesList[index].canceled = ev->dccFile.canceled;
2650     m_dccfilesList[index].ip = ev->dccFile.ip;
2651     m_dccfilesList[index].port = ev->dccFile.port;
2652     m_dccfilesList[index].finished = ev->dccFile.finished;
2653     if(m_dccfilesList[index].type == DCC_IN  || m_dccfilesList[index].type == DCC_PIN)
2654     {
2655         if(m_dccfilesList[index].currentPosition >= m_dccfilesList[index].size)
2656         {
2657             if(m_dccfilesList[index].canceled)
2658             {
2659                 appendIrcStyledText(FXStringFormat(_("Download of \"%s\" from %s canceled"), FXPath::name(m_dccfilesList[index].path).text(), m_dccfilesList[index].nick.text()), 4, FALSE);
2660             }
2661             else
2662             {
2663                 appendIrcStyledText(FXStringFormat(_("Download of \"%s\" from %s finished"), FXPath::name(m_dccfilesList[index].path).text(), m_dccfilesList[index].nick.text()), 8, FALSE);
2664 #ifdef HAVE_TRAY
2665                 if(m_trayIcon && m_trayIcon->getIcon() != ICO_NEWFILE && !shown())
2666                     m_trayIcon->setIcon(ICO_NEWFILE);
2667 #endif //HAVE_TRAY
2668             }
2669         }
2670         else
2671         {
2672             if(m_dccfilesList[index].canceled)
2673             {
2674                 appendIrcStyledText(FXStringFormat(_("Download of \"%s\" from %s canceled"), FXPath::name(m_dccfilesList[index].path).text(), m_dccfilesList[index].nick.text()), 4, FALSE);
2675             }
2676         }
2677     }
2678     else
2679     {
2680         if(m_dccfilesList[index].finishedPosition >= m_dccfilesList[index].size)
2681         {
2682             if(m_dccfilesList[index].canceled)
2683             {
2684                 appendIrcStyledText(FXStringFormat(_("Upload of \"%s\" to %s canceled"), FXPath::name(m_dccfilesList[index].path).text(), m_dccfilesList[index].nick.text()), 4, FALSE);
2685             }
2686             else
2687             {
2688                 appendIrcStyledText(FXStringFormat(_("Upload of \"%s\" to %s finished"), FXPath::name(m_dccfilesList[index].path).text(), m_dccfilesList[index].nick.text()), 8, FALSE);
2689 #ifdef HAVE_TRAY
2690                 if(m_trayIcon && m_trayIcon->getIcon() != ICO_NEWFILE && !shown())
2691                     m_trayIcon->setIcon(ICO_NEWFILE);
2692 #endif //HAVE_TRAY
2693             }
2694         }
2695         else
2696         {
2697             if(m_dccfilesList[index].canceled)
2698             {
2699                 appendIrcStyledText(FXStringFormat(_("Upload of \"%s\" to %s canceled"), FXPath::name(m_dccfilesList[index].path).text(), m_dccfilesList[index].nick.text()), 4, FALSE);
2700             }
2701         }
2702     }
2703 }
2704 
2705 //handle IrcEvent IRC_DCCRESUME
onIrcDccResume(IrcEngine * server,IrcEvent * ev)2706 void dxirc::onIrcDccResume(IrcEngine *server, IrcEvent *ev)
2707 {
2708     FXint engineIndex = -1;
2709     for(FXint i=0; i<m_dccengines.no(); i++)
2710     {
2711         if(m_dccengines[i]->isForResume(ev->param1, ev->param2, FXIntVal(ev->param3)))
2712         {
2713             engineIndex = i;
2714             break;
2715         }
2716     }
2717     if(engineIndex == -1) return;
2718     FXint dccIndex = -1;
2719     for(FXint i=0; i<m_dccfilesList.no(); i++)
2720     {
2721         if(m_dccfilesList[i].path == m_dccengines[engineIndex]->getDccFile().path
2722                 && m_dccfilesList[i].size == m_dccengines[engineIndex]->getDccFile().size
2723                 && m_dccfilesList[i].nick == m_dccengines[engineIndex]->getDccFile().nick)
2724         {
2725             dccIndex = i;
2726             break;
2727         }
2728     }
2729     if(dccIndex == -1) return;
2730     FXulong position = FXULongVal(ev->param4);
2731     if(position >= m_dccfilesList[dccIndex].size) return;
2732     m_dccengines[engineIndex]->setDccPosition(position);
2733     m_dccfilesList[dccIndex].ip = m_dccengines[engineIndex]->getDccFile().ip;
2734     m_dccfilesList[dccIndex].port = m_dccengines[engineIndex]->getDccFile().port;
2735     m_dccfilesList[dccIndex].currentPosition = position;
2736     m_dccfilesList[dccIndex].speed = 0;
2737     m_dccfilesList[dccIndex].finishedPosition = position;
2738     m_dccfilesList[dccIndex].canceled = FALSE;
2739     server->sendCtcp(ev->param1, "DCC ACCEPT "+dxutils::removeSpaces(m_dccengines[engineIndex]->getDccFile().path.rafter(PATHSEP))+" "+FXStringVal(m_dccengines[engineIndex]->getDccFile().port)+" "+ev->param4);
2740 }
2741 
2742 //handle IrcEvent IRC_DCCPRESUME
onIrcDccPresume(IrcEngine * server,IrcEvent * ev)2743 void dxirc::onIrcDccPresume(IrcEngine *server, IrcEvent *ev)
2744 {
2745     FXint dccIndex = -1;
2746     FXint token = FXIntVal(ev->param1);
2747     for(FXint i=0; i<m_dccfilesList.no(); i++)
2748     {
2749         if(m_dccfilesList[i].token == token)
2750         {
2751             dccIndex = i;
2752             break;
2753         }
2754     }
2755     if(dccIndex == -1) return;
2756     FXulong position = FXULongVal(ev->param2);
2757     if(position >= m_dccfilesList[dccIndex].size) return;
2758     m_dccfilesList[dccIndex].currentPosition = position;
2759     m_dccfilesList[dccIndex].speed = 0;
2760     m_dccfilesList[dccIndex].finishedPosition = position;
2761     m_dccfilesList[dccIndex].canceled = FALSE;
2762     server->sendCtcp(m_dccfilesList[dccIndex].nick, "DCC ACCEPT "+dxutils::removeSpaces(m_dccfilesList[dccIndex].path.rafter(PATHSEP))+" 0 "+ev->param2+" "+FXStringVal(token));
2763 }
2764 
2765 //handle IrcEvent IRC_DCCACCEPT
onIrcDccAccept(IrcEngine * server,IrcEvent * ev)2766 void dxirc::onIrcDccAccept(IrcEngine *server, IrcEvent *ev)
2767 {
2768     FXint dccIndex = -1;
2769     for(FXint i=0; i<m_dccfilesList.no(); i++)
2770     {
2771         if(m_dccfilesList[i].nick == ev->param1 && FXPath::name(m_dccfilesList[i].path) == ev->param2
2772                 && m_dccfilesList[i].port == FXIntVal(ev->param3))
2773         {
2774             dccIndex = i;
2775             break;
2776         }
2777     }
2778     if(dccIndex == -1) return;
2779     FXulong position = FXULongVal(ev->param4);
2780     if(position >= m_dccfilesList[dccIndex].size) return;
2781     m_dccfilesList[dccIndex].currentPosition = position;
2782     m_dccfilesList[dccIndex].speed = 0;
2783     m_dccfilesList[dccIndex].finishedPosition = position;
2784     m_dccfilesList[dccIndex].canceled = FALSE;
2785     DccEngine *engine = new DccEngine(m_app, this, m_dccfilesList[dccIndex], server);
2786     m_dccengines.append(engine);
2787     engine->startConnection();
2788     appendIrcStyledText(FXStringFormat(_("Receiving \"%s\" from %s"), FXPath::name(m_dccfilesList[dccIndex].path).text(), m_dccfilesList[dccIndex].nick.text()),8,false);
2789     if(!m_preferences.m_autoDccFile) onCmdTransfers(NULL, 0, NULL);
2790 }
2791 
2792 //handle IrcEvent IRC_DCCPACCEPT
onIrcDccPaccept(IrcEngine * server,IrcEvent * ev)2793 void dxirc::onIrcDccPaccept(IrcEngine *server, IrcEvent *ev)
2794 {
2795     FXint dccIndex = -1;
2796     FXint token = FXIntVal(ev->param1);
2797     for(FXint i=0; i<m_dccfilesList.no(); i++)
2798     {
2799         if(m_dccfilesList[i].token == token)
2800         {
2801             dccIndex = i;
2802             break;
2803         }
2804     }
2805     if(dccIndex == -1) return;
2806     FXulong position = FXULongVal(ev->param2);
2807     if(position >= m_dccfilesList[dccIndex].size) return;
2808     m_dccfilesList[dccIndex].currentPosition = position;
2809     m_dccfilesList[dccIndex].speed = 0;
2810     m_dccfilesList[dccIndex].finishedPosition = position;
2811     m_dccfilesList[dccIndex].canceled = FALSE;
2812     m_dccfilesList[dccIndex].ip = server->getLocalIP();
2813     m_dccfilesList[dccIndex].port = 0;
2814     DccEngine *engine = new DccEngine(m_app, this, m_dccfilesList[dccIndex], server);
2815     m_dccengines.append(engine);
2816     engine->startConnection();
2817     appendIrcStyledText(FXStringFormat(_("Receiving \"%s\" from %s"), FXPath::name(m_dccfilesList[dccIndex].path).text(), m_dccfilesList[dccIndex].nick.text()),8,FALSE);
2818     if(!m_preferences.m_autoDccFile) onCmdTransfers(NULL, 0, NULL);
2819 }
2820 
2821 //handle IrcEvent IRC_BOATSINVITE
onIrcBoatsInvite(IrcEngine * server,IrcEvent * ev)2822 void dxirc::onIrcBoatsInvite(IrcEngine *server, IrcEvent *ev)
2823 {
2824     if(dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"),
2825                              _("%s invite you into Boats game.\n Do you want play?"), ev->param1.text())
2826             == 1)
2827     {
2828         createBoatsTab(ev->param1, 0, server, FALSE);
2829         server->sendCtcp(ev->param1, "BOATS ACCEPT");
2830     }
2831     else
2832     {
2833         server->sendCtcp(ev->param1, "BOATS DECLINE");
2834     }
2835 }
2836 
2837 //handle IrcEvent IRC_BOATSACCEPT
onIrcBoatsAccept(IrcEngine * server,IrcEvent * ev)2838 void dxirc::onIrcBoatsAccept(IrcEngine *server, IrcEvent *ev)
2839 {
2840     createBoatsTab(ev->param1, 0, server, TRUE);
2841 }
2842 
2843 //handle IrcEvent IRC_RAW
onIrcRaw(IrcEngine * server,IrcEvent * ev)2844 void dxirc::onIrcRaw(IrcEngine *server, IrcEvent *ev)
2845 {
2846 #ifdef HAVE_LUA
2847     if(!m_scripts.no() || !m_scriptEvents.no()) return;
2848     for(FXint i=0; i<m_scriptEvents.no(); i++)
2849     {
2850         if(comparecase("raw", m_scriptEvents[i].name) == 0)
2851         {
2852             for(FXint j=0; j<m_scripts.no(); j++)
2853             {
2854                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
2855                 {
2856                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
2857                     if(lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
2858                     else
2859                     {
2860                         lua_pushstring(m_scripts[j].L, ev->param1.text());
2861                         lua_newtable(m_scripts[j].L);
2862                         lua_pushstring(m_scripts[j].L, "server");
2863                         lua_pushstring(m_scripts[j].L, server->getServerName().text());
2864                         lua_settable(m_scripts[j].L, -3);
2865                         lua_pushstring(m_scripts[j].L, "port");
2866                         lua_pushnumber(m_scripts[j].L, server->getServerPort());
2867                         lua_settable(m_scripts[j].L, -3);
2868                         lua_pushstring(m_scripts[j].L, "nick");
2869                         lua_pushstring(m_scripts[j].L, server->getNickName().text());
2870                         lua_settable(m_scripts[j].L, -3);
2871                         if(lua_pcall(m_scripts[j].L, 2, 0, 0))
2872                         {
2873                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
2874                             lua_pop(m_scripts[j].L, 1);
2875                         }
2876                     }
2877                 }
2878             }
2879         }
2880     }
2881 #endif //HAVE_LUA
2882 }
2883 
2884 //handle IrcEvent IRC_323
onIrc323(IrcEngine * server)2885 void dxirc::onIrc323(IrcEngine *server)
2886 {
2887     ListDialog dialog(this, server);
2888     dialog.execute(PLACEMENT_CURSOR);
2889 }
2890 
onTabBook(FXObject *,FXSelector,void * ptr)2891 long dxirc::onTabBook(FXObject *, FXSelector, void *ptr)
2892 {
2893     FXint index = (FXint)(FXival)ptr*2;
2894     if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&IrcTabItem::metaClass)
2895     {
2896         IrcTabItem *currenttab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index));
2897         dxUtils.debugLine(FXStringFormat("OnTabBook(%d), Class: %s, id: %d", index, currenttab->getClassName(), currenttab->getID()));
2898         if(m_preferences.m_appTheme.fore != currenttab->getTextColor()) currenttab->setTextColor(m_preferences.m_appTheme.fore);
2899         if(currenttab->getType() == CHANNEL && currenttab->getIcon() == ICO_CHANNELNEWMSG)
2900         {
2901             currenttab->setIcon(ICO_CHANNEL);
2902 #ifdef HAVE_TRAY
2903             if(m_trayIcon && m_trayIcon->getIcon() == ICO_NEWMSG)
2904                 m_trayIcon->setIcon(ICO_TRAY);
2905 #endif //HAVE_TRAY
2906         }
2907         if(currenttab->getType() == QUERY && currenttab->getIcon() == ICO_QUERYNEWMSG)
2908         {
2909             currenttab->setIcon(ICO_QUERY);
2910 #ifdef HAVE_TRAY
2911             if(m_trayIcon && m_trayIcon->getIcon() == ICO_NEWMSG)
2912                 m_trayIcon->setIcon(ICO_TRAY);
2913 #endif //HAVE_TRAY
2914         }
2915         currenttab->setFocus();
2916         currenttab->setCommandFocus();
2917         currenttab->makeLastRowVisible();
2918         if(hasTetrisTab())
2919         {
2920             TetrisTabItem *tetristab = static_cast<TetrisTabItem*>(getTabItemById(getTabId("tetris")));
2921             if(tetristab && tetristab->isPauseEnable() && !tetristab->isPaused()) tetristab->pauseResumeGame();
2922         }
2923         if(currenttab->getType() == SERVER)
2924             updateStatus(currenttab->getRealServerName()+"-"+currenttab->getNickName());
2925         else if(currenttab->getType() == OTHER)
2926             updateStatus(currenttab->getText());
2927         else
2928             updateStatus((currenttab->getText()[0]=='&' ? "&"+currenttab->getText(): currenttab->getText())+"-"+currenttab->getRealServerName()+"-"+currenttab->getNickName());
2929     }
2930     if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&DccTabItem::metaClass)
2931     {
2932         DccTabItem *currenttab = static_cast<DccTabItem*>(m_tabbook->childAtIndex(index));
2933         dxUtils.debugLine(FXStringFormat("OnTabBook(%d), Class: %s, id: %d", index, currenttab->getClassName(), currenttab->getID()));
2934         if(m_preferences.m_appTheme.fore != currenttab->getTextColor()) currenttab->setTextColor(m_preferences.m_appTheme.fore);
2935         if(currenttab->getIcon() == ICO_DCCNEWMSG)
2936             currenttab->setIcon(ICO_DCC);
2937 #ifdef HAVE_TRAY
2938         if(m_trayIcon && m_trayIcon->getIcon() == ICO_NEWMSG)
2939             m_trayIcon->setIcon(ICO_TRAY);
2940 #endif //HAVE_TRAY
2941         currenttab->setFocus();
2942         currenttab->setCommandFocus();
2943         currenttab->makeLastRowVisible();
2944         if(hasTetrisTab())
2945         {
2946             TetrisTabItem *tetristab = static_cast<TetrisTabItem*>(getTabItemById(getTabId("tetris")));
2947             if(tetristab && tetristab->isPauseEnable() && !tetristab->isPaused()) tetristab->pauseResumeGame();
2948         }
2949         updateStatus((currenttab->getText()[0]=='&' ? "&"+currenttab->getText(): currenttab->getText())+"-"+currenttab->getServerName()+"-"+currenttab->getNickName());
2950     }
2951     if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&BoatsTabItem::metaClass)
2952     {
2953         BoatsTabItem *currenttab = static_cast<BoatsTabItem*>(m_tabbook->childAtIndex(index));
2954         dxUtils.debugLine(FXStringFormat("OnTabBook(%d), Class: %s, id: %d", index, currenttab->getClassName(), currenttab->getID()));
2955         currenttab->setFocus();
2956         currenttab->setCommandFocus();
2957         if(hasTetrisTab())
2958         {
2959             TetrisTabItem *tetristab = static_cast<TetrisTabItem*>(getTabItemById(getTabId("tetris")));
2960             if(tetristab && tetristab->isPauseEnable() && !tetristab->isPaused()) tetristab->pauseResumeGame();
2961         }
2962         updateStatus(currenttab->getText()+"-"+currenttab->getRealServerName()+"-"+currenttab->getNickName());
2963     }
2964     if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&TetrisTabItem::metaClass)
2965     {
2966         TetrisTabItem *tetristab = static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(index));
2967         dxUtils.debugLine(FXStringFormat("OnTabBook(%d), Class: %s, id: %d", index, tetristab->getClassName(), tetristab->getID()));
2968         tetristab->setFocus();
2969         tetristab->setGameFocus();
2970     }
2971     return 1;
2972 }
2973 
onCmdNextTab(FXObject *,FXSelector,void *)2974 long dxirc::onCmdNextTab(FXObject *, FXSelector, void *)
2975 {
2976     FXint index = m_tabbook->getCurrent();
2977     if(m_tabbook->numChildren())
2978     {
2979         if((index+1)*2 < m_tabbook->numChildren()) m_tabbook->setCurrent(index+1, m_tabbook->numChildren() > index*2 ? TRUE : FALSE);
2980         else m_tabbook->setCurrent(0, TRUE);
2981     }
2982     return 1;
2983 }
2984 
2985 //handle move tab
onCmdMoveTab(FXObject *,FXSelector,void * ptr)2986 long dxirc::onCmdMoveTab(FXObject*, FXSelector, void *ptr)
2987 {
2988     if(!m_preferences.m_disableSortTabs)
2989         return 1;
2990     FXString key = dxutils::getKeybinding((FXEvent*)ptr);
2991     if(comparecase(key, m_preferences.getBinding("moveTabUp"))==0)
2992     {
2993         moveTab(true);
2994     }
2995     else if(comparecase(key, m_preferences.getBinding("moveTabDown"))==0)
2996     {
2997         moveTab(false);
2998     }
2999     return 1;
3000 }
3001 
3002 //Handle mousewheel for change currenttab
onMouseWheel(FXObject *,FXSelector,void * ptr)3003 long dxirc::onMouseWheel(FXObject *, FXSelector, void *ptr)
3004 {
3005     FXEvent *event = (FXEvent*)ptr;
3006     FXint index = m_tabbook->getCurrent();
3007     if(event->code > 0) //positive movement
3008     {
3009         if(m_tabbook->numChildren())
3010         {
3011             if((index-1) >= 0) m_tabbook->setCurrent(index-1, TRUE);
3012             else m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
3013         }
3014     }
3015     else
3016     {
3017         if(m_tabbook->numChildren())
3018         {
3019             if((index+1)*2 < m_tabbook->numChildren()) m_tabbook->setCurrent(index+1, m_tabbook->numChildren() > index*2 ? TRUE : FALSE);
3020             else m_tabbook->setCurrent(0, TRUE);
3021         }
3022     }
3023     return 1;
3024 }
3025 
onCmdNextUnread(FXObject *,FXSelector,void *)3026 long dxirc::onCmdNextUnread(FXObject *, FXSelector, void*)
3027 {
3028     if(m_tabbook->numChildren())
3029     {
3030         for(FXint i = m_tabbook->getCurrent()*2; i<m_tabbook->numChildren(); i+=2)
3031         {
3032             if (m_preferences.m_appTheme.fore != static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->getTextColor())
3033             {
3034                 m_tabbook->setCurrent(i/2, TRUE);
3035                 return 1;
3036             }
3037         }
3038         for(FXint i = m_tabbook->getCurrent()*2; i>-1; i-=2)
3039         {
3040             if (m_preferences.m_appTheme.fore != static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->getTextColor())
3041             {
3042                 m_tabbook->setCurrent(i/2, TRUE);
3043                 return 1;
3044             }
3045         }
3046     }
3047     return 1;
3048 }
3049 
onCmdClear(FXObject *,FXSelector,void *)3050 long dxirc::onCmdClear(FXObject *, FXSelector, void *)
3051 {
3052     if(m_tabbook->numChildren())
3053     {
3054         FXint index = m_tabbook->getCurrent()*2;
3055         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()!=&TetrisTabItem::metaClass
3056                 && m_tabbook->childAtIndex(index)->getMetaClass()!=&BoatsTabItem::metaClass)
3057         {
3058             dxTabItem *currenttab = static_cast<dxTabItem*>(m_tabbook->childAtIndex(index));
3059             currenttab->clearChat();
3060         }
3061     }
3062     return 1;
3063 }
3064 
onCmdClearAll(FXObject *,FXSelector,void *)3065 long dxirc::onCmdClearAll(FXObject *, FXSelector, void *)
3066 {
3067     for(FXint i = 0; i<m_tabbook->numChildren(); i+=2)
3068     {
3069         if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass
3070                 && m_tabbook->childAtIndex(i)->getMetaClass()!=&BoatsTabItem::metaClass)
3071         {
3072             static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->clearChat();
3073             if (m_preferences.m_appTheme.fore != static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getTextColor()) static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->setTextColor(m_preferences.m_appTheme.fore);
3074             if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == CHANNEL) static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->setIcon(ICO_CHANNEL);
3075             if(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getType() == QUERY) static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->setIcon(ICO_QUERY);
3076             if(m_tabbook->childAtIndex(i)->getMetaClass()==&DccTabItem::metaClass) static_cast<DccTabItem*>(m_tabbook->childAtIndex(i))->setIcon(ICO_DCC);
3077         }
3078     }
3079 #ifdef HAVE_TRAY
3080     if(m_trayIcon && m_trayIcon->getIcon() == ICO_NEWMSG)
3081         m_trayIcon->setIcon(ICO_TRAY);
3082 #endif //HAVE_TRAY
3083     return 1;
3084 }
3085 
onCmdCloseTab(FXObject *,FXSelector,void *)3086 long dxirc::onCmdCloseTab(FXObject *, FXSelector, void *)
3087 {
3088     if(m_tabbook->numChildren())
3089     {
3090         FXint index = m_tabbook->getCurrent()*2;
3091         if(!m_tabbook->childAtIndex(index)) return 1;
3092         if(m_tabbook->childAtIndex(index)->getMetaClass()==&IrcTabItem::metaClass)
3093         {
3094             IrcTabItem *currenttab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index));
3095             if(currenttab->getType() == OTHER)
3096             {
3097                 delete m_tabbook->childAtIndex(index);
3098                 delete m_tabbook->childAtIndex(index);
3099                 m_tabbook->recalc();
3100                 sortTabs();
3101                 if(m_tabbook->numChildren())
3102                 {
3103                     m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3104                 }
3105                 updateMenus();
3106                 return 1;
3107             }
3108             IrcEngine *currentserver = NULL;
3109             for(FXint i=0; i < m_ircengines.no(); i++)
3110             {
3111                 if(m_ircengines[i]->findTarget(currenttab))
3112                 {
3113                     currentserver = m_ircengines[i];
3114                     break;
3115                 }
3116             }
3117             if(currentserver == NULL) return 0;
3118             if(currenttab->getType() == QUERY)
3119             {
3120                 if(currentserver->getConnected() && isLastTab(currentserver))
3121                 {
3122                     currenttab->setType(SERVER, currentserver->getNetworkName());
3123                 }
3124                 else
3125                 {
3126                     if(!currentserver->getConnected()) currentserver->disconnect();
3127                     currentserver->removeTarget(currenttab);
3128                     delete m_tabbook->childAtIndex(index);
3129                     delete m_tabbook->childAtIndex(index);
3130                     m_tabbook->recalc();
3131 
3132                 }
3133                 sortTabs();
3134                 if(m_tabbook->numChildren())
3135                 {
3136                     m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3137                 }
3138                 updateMenus();
3139                 return 1;
3140             }
3141             if(currenttab->getType() == CHANNEL)
3142             {
3143                 if(currentserver->getConnected()) currentserver->sendPart(currenttab->getText());
3144                 if(currentserver->getConnected() && isLastTab(currentserver))
3145                 {
3146                     currenttab->setType(SERVER, currentserver->getNetworkName());
3147                 }
3148                 else
3149                 {
3150                     if(!currentserver->getConnected()) currentserver->disconnect();
3151                     currentserver->removeTarget(currenttab);
3152                     delete m_tabbook->childAtIndex(index);
3153                     delete m_tabbook->childAtIndex(index);
3154                     m_tabbook->recalc();
3155                 }
3156                 sortTabs();
3157                 if(m_tabbook->numChildren())
3158                 {
3159                     m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3160                 }
3161                 updateMenus();
3162                 return 1;
3163             }
3164             if(currenttab->getType() == SERVER)
3165             {
3166                 currentserver->disconnect();
3167                 for(FXint i = m_tabbook->numChildren()-2; i > -1; i-=2)
3168                 {
3169                     if(currentserver->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))))
3170                     {
3171                         currentserver->removeTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i)));
3172                         delete m_tabbook->childAtIndex(i);
3173                         delete m_tabbook->childAtIndex(i);
3174                     }
3175                 }
3176                 m_tabbook->recalc();
3177                 sortTabs();
3178                 if(m_tabbook->numChildren())
3179                 {
3180                     m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3181                 }
3182                 updateMenus();
3183                 return 1;
3184             }
3185         }
3186         else if(m_tabbook->childAtIndex(index)->getMetaClass()==&DccTabItem::metaClass)
3187         {
3188             DccTabItem *dcctab = static_cast<DccTabItem*>(m_tabbook->childAtIndex(index));
3189             dcctab->disconnect();
3190             for(FXint i=0; i < m_ircengines.no(); i++)
3191             {
3192                 if(m_ircengines[i]->findTarget(dcctab))
3193                 {
3194                     m_ircengines[i]->removeTarget(dcctab);
3195                     break;
3196                 }
3197             }
3198             delete m_tabbook->childAtIndex(index);
3199             delete m_tabbook->childAtIndex(index);
3200             m_tabbook->recalc();
3201             sortTabs();
3202             if(m_tabbook->numChildren())
3203             {
3204                 m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3205             }
3206             updateMenus();
3207             return 1;
3208         }
3209         else if(m_tabbook->childAtIndex(index)->getMetaClass()==&BoatsTabItem::metaClass)
3210         {
3211             BoatsTabItem *tab = static_cast<BoatsTabItem*>(m_tabbook->childAtIndex(index));
3212             tab->leftGame();
3213             IrcEngine *currentserver = NULL;
3214             for(FXint i=0; i < m_ircengines.no(); i++)
3215             {
3216                 if(m_ircengines[i]->findTarget(tab))
3217                 {
3218                     currentserver = m_ircengines[i];
3219                     break;
3220                 }
3221             }
3222             if(currentserver != NULL) currentserver->removeTarget(tab);
3223             delete m_tabbook->childAtIndex(index);
3224             delete m_tabbook->childAtIndex(index);
3225             m_tabbook->recalc();
3226             sortTabs();
3227             if(m_tabbook->numChildren())
3228             {
3229                 m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3230             }
3231             updateMenus();
3232             return 1;
3233         }
3234         else
3235         {
3236             TetrisTabItem *tetristab = static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(index));
3237             tetristab->stopGame();
3238             delete m_tabbook->childAtIndex(index);
3239             delete m_tabbook->childAtIndex(index);
3240             m_tabbook->recalc();
3241             sortTabs();
3242             if(m_tabbook->numChildren())
3243             {
3244                 m_tabbook->setCurrent(FXMAX(0,index/2-1), TRUE);
3245             }
3246             updateMenus();
3247             return 1;
3248         }
3249     }
3250     return 1;
3251 }
3252 
onCmdSelectTab(FXObject *,FXSelector,void * ptr)3253 long dxirc::onCmdSelectTab(FXObject*, FXSelector, void *ptr)
3254 {
3255     FXint index = 0;
3256     FXString key = dxutils::getKeybinding((FXEvent*)ptr);
3257     if(comparecase(key, m_preferences.getBinding("firstTab"))==0)
3258         index = 0;
3259     else if(comparecase(key, m_preferences.getBinding("secondTab"))==0)
3260         index = 1;
3261     else if(comparecase(key, m_preferences.getBinding("thirdTab"))==0)
3262         index = 2;
3263     else if(comparecase(key, m_preferences.getBinding("fourthTab"))==0)
3264         index = 3;
3265     else if(comparecase(key, m_preferences.getBinding("fifthTab"))==0)
3266         index = 4;
3267     else if(comparecase(key, m_preferences.getBinding("sixthTab"))==0)
3268         index = 5;
3269     else if(comparecase(key, m_preferences.getBinding("seventhTab"))==0)
3270         index = 6;
3271     else if(comparecase(key, m_preferences.getBinding("eighthTab"))==0)
3272         index = 7;
3273     else if(comparecase(key, m_preferences.getBinding("ninethTab"))==0)
3274         index = 8;
3275     if((index)*2 < m_tabbook->numChildren()) m_tabbook->setCurrent(index, TRUE);
3276     return 1;
3277 }
3278 
onTrayClicked(FXObject *,FXSelector,void *)3279 long dxirc::onTrayClicked(FXObject*, FXSelector, void*)
3280 {
3281 #ifdef HAVE_TRAY
3282     if(shown())
3283         hide();
3284     else
3285     {
3286         show();
3287         if(m_trayIcon && m_trayIcon->getIcon() == ICO_NEWFILE) onCmdTransfers(NULL, 0, NULL);
3288     }
3289     if(m_trayIcon && m_trayIcon->getIcon() != ICO_TRAY)
3290         m_trayIcon->setIcon(ICO_TRAY);
3291 #endif //HAVE_TRAY
3292     return 1;
3293 }
3294 
3295 //handle highlighted msg from IrcTabITem::ID_NEWMSG or DccTabItem::ID_NEWMSG
onNewMsg(FXObject * obj,FXSelector,void *)3296 long dxirc::onNewMsg(FXObject *obj, FXSelector, void*)
3297 {
3298 #ifdef HAVE_TRAY
3299     if(m_trayIcon && m_trayIcon->getIcon() == ICO_TRAY && (!shown() || static_cast<dxTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2)) != static_cast<dxTabItem*>(obj)))
3300         m_trayIcon->setIcon(ICO_NEWMSG);
3301 #endif //HAVE_TRAY
3302     if(m_preferences.m_sounds && m_preferences.m_soundMessage && (!shown() || isMinimized() || static_cast<dxTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2)) != static_cast<dxTabItem*>(obj)))
3303         dxutils::playFile(m_preferences.m_pathMessage);
3304     if(static_cast<IrcTabItem*>(obj)->getType() == CHANNEL)
3305     {
3306         updateStatus(FXStringFormat(_("New highlighted message on %s"), static_cast<IrcTabItem*>(obj)->getText().text()));
3307         if(m_preferences.m_notify && m_preferences.m_notifyMessage)
3308             showNotify(FXStringFormat(_("New highlighted message on %s"), static_cast<IrcTabItem*>(obj)->getText().text()));
3309     }
3310     else
3311     {
3312         updateStatus(FXStringFormat(_("New message on chat with %s"), static_cast<dxTabItem*>(obj)->getText().text()));
3313         if(m_preferences.m_notify && m_preferences.m_notifyMessage)
3314             showNotify(FXStringFormat(_("New message on chat with %s"), static_cast<dxTabItem*>(obj)->getText().text()));
3315     }
3316     flash(TRUE);
3317     return 1;
3318 }
3319 
3320 //handle for: /ignore addcmd
onAddIgnoreCommand(FXObject * sender,FXSelector,void * data)3321 long dxirc::onAddIgnoreCommand(FXObject *sender, FXSelector, void *data)
3322 {
3323     if(sender->getMetaClass()!=&IrcTabItem::metaClass) return 0;
3324     IrcTabItem *tab = static_cast<IrcTabItem*>(sender);
3325     FXString text = static_cast<FXString*>(data)->lower().text();
3326     FXString available[11] = { "away", "ban", "ctcp", "invite", "join", "me", "nick", "notice", "mode", "part", "quit"};
3327     FXbool canAdd = FALSE;
3328     for(FXint i=0; i<11; i++)
3329     {
3330         if(comparecase(text,available[i])==0)
3331         {
3332             canAdd = TRUE;
3333             break;
3334         }
3335     }
3336     if(!canAdd)
3337     {
3338         tab->appendStyledText(FXStringFormat(_("'%s' can't be added to ignored commands"), text.text()), 4, FALSE, FALSE, FALSE);
3339         return 1;
3340     }
3341     else
3342     {
3343         for(FXint i=0; i<m_preferences.m_ignoreCommandsList.contains(';'); i++)
3344         {
3345             if(comparecase(text,m_preferences.m_ignoreCommandsList.section(';', i))==0)
3346             {
3347                 tab->appendStyledText(FXStringFormat(_("'%s' is already added in ignored commands"), text.text()), 4, FALSE, FALSE, FALSE);
3348                 return 1;
3349             }
3350         }
3351         tab->appendStyledText(FXStringFormat(_("'%s' was added to ignored commands"), text.text()), 3, FALSE, FALSE, FALSE);
3352         m_preferences.m_ignoreCommandsList.append(text+";");
3353     }
3354     return 1;
3355 }
3356 
3357 //handle for: /ignore rmcmd
onRemoveIgnoreCommand(FXObject * sender,FXSelector,void * data)3358 long dxirc::onRemoveIgnoreCommand(FXObject *sender, FXSelector, void *data)
3359 {
3360     if(sender->getMetaClass()!=&IrcTabItem::metaClass) return 0;
3361     IrcTabItem *tab = static_cast<IrcTabItem*>(sender);
3362     FXString text = static_cast<FXString*>(data)->lower().text();
3363     FXString tempList = "";
3364     FXbool inCommands = FALSE;
3365     for(FXint i=0; i<m_preferences.m_ignoreCommandsList.contains(';'); i++)
3366     {
3367         if(comparecase(text,m_preferences.m_ignoreCommandsList.section(';', i))==0)
3368         {
3369             tab->appendStyledText(FXStringFormat(_("'%s' was removed from ignored commands"), text.text()), 3, FALSE, FALSE, FALSE);
3370             inCommands = TRUE;
3371         }
3372         else
3373             tempList.append(m_preferences.m_ignoreCommandsList.section(';', i)+";");
3374     }
3375     if(!inCommands) tab->appendStyledText(FXStringFormat(_("'%s' isn't in ignored commands"), text.text()), 4, FALSE, FALSE, FALSE);
3376     m_preferences.m_ignoreCommandsList = tempList;
3377     return 1;
3378 }
3379 
3380 //handle for: /ignore addusr
onAddIgnoreUser(FXObject * sender,FXSelector,void * data)3381 long dxirc::onAddIgnoreUser(FXObject *sender, FXSelector, void *data)
3382 {
3383     if(sender->getMetaClass()!=&IrcTabItem::metaClass) return 0;
3384     IrcTabItem *tab = static_cast<IrcTabItem*>(sender);
3385     FXString text = static_cast<FXString*>(data)->text();
3386     FXString user = text.section(' ',0);
3387     FXString channel = text.section(' ',1);
3388     FXString network = dxutils::getParam(text, 3, TRUE);
3389     if(m_preferences.m_ignoreUsersList.no())
3390     {
3391         FXbool updated = FALSE;
3392         for(FXint i=0; i<m_preferences.m_ignoreUsersList.no(); i++)
3393         {
3394             if(compare(user, m_preferences.m_ignoreUsersList[i].nick)==0)
3395             {
3396                 updated = TRUE;
3397                 channel.empty() ? m_preferences.m_ignoreUsersList[i].channel = "all" : m_preferences.m_ignoreUsersList[i].channel = channel;
3398                 network.empty() ? m_preferences.m_ignoreUsersList[i].network = "all" : m_preferences.m_ignoreUsersList[i].network = network;
3399                 tab->appendStyledText(FXStringFormat(_("'%s' was updated in ignored users"), user.text()), 3, FALSE, FALSE, FALSE);
3400                 break;
3401             }
3402         }
3403         if(!updated)
3404         {
3405             UserInfo iuser;
3406             iuser.nick = user;
3407             channel.empty() ? iuser.channel = "all" : iuser.channel = channel;
3408             network.empty() ? iuser.network = "all" : iuser.network = network;
3409             m_preferences.m_ignoreUsersList.append(iuser);
3410             tab->appendStyledText(FXStringFormat(_("'%s' was added to ignored users"), user.text()), 3, FALSE, FALSE, FALSE);
3411         }
3412     }
3413     else
3414     {
3415         UserInfo iuser;
3416         iuser.nick = user;
3417         channel.empty() ? iuser.channel = "all" : iuser.channel = channel;
3418         network.empty() ? iuser.network = "all" : iuser.network = network;
3419         m_preferences.m_ignoreUsersList.append(iuser);
3420         tab->appendStyledText(FXStringFormat(_("'%s' was added to ignored users"), user.text()), 3, FALSE, FALSE, FALSE);
3421     }
3422     return 1;
3423 }
3424 
3425 //handle for: /ignore rmusr
onRemoveIgnoreUser(FXObject * sender,FXSelector,void * data)3426 long dxirc::onRemoveIgnoreUser(FXObject *sender, FXSelector, void *data)
3427 {
3428     if(sender->getMetaClass()!=&IrcTabItem::metaClass) return 0;
3429     IrcTabItem *tab = static_cast<IrcTabItem*>(sender);
3430     FXString text = static_cast<FXString*>(data)->text();
3431     FXbool updated = FALSE;
3432     if(m_preferences.m_ignoreUsersList.no())
3433     {
3434         for(FXint i=m_preferences.m_ignoreUsersList.no()-1; i>-1; i--)
3435         {
3436             if(compare(text, m_preferences.m_ignoreUsersList[i].nick)==0)
3437             {
3438                 updated = TRUE;
3439                 m_preferences.m_ignoreUsersList.erase(i);
3440                 tab->appendStyledText(FXStringFormat(_("'%s' was removed from ignored users"), text.text()), 3, FALSE, FALSE, FALSE);
3441                 break;
3442             }
3443         }
3444         if(!updated)
3445         {
3446             tab->appendStyledText(FXStringFormat(_("'%s' wasn't removed from ignored users"), text.text()), 3, FALSE, FALSE, FALSE);
3447         }
3448     }
3449     return 1;
3450 }
3451 
onNewTetris(FXObject *,FXSelector,void *)3452 long dxirc::onNewTetris(FXObject*, FXSelector, void*)
3453 {
3454     if(hasTetrisTab()) return 1;
3455     TetrisTabItem *tab = new TetrisTabItem(m_tabbook, "tetris", 0, TAB_TOP, m_lastID);
3456     sendNewTab(NULL, "tetris", m_lastID, TRUE, FALSE, OTHER);
3457     m_lastID++;
3458     tab->create();
3459     tab->createGeom();
3460     tab->setColor(m_preferences.m_colors);
3461     updateTabPosition();
3462     sortTabs();
3463     updateMenus();
3464     m_tabbook->setCurrent(m_tabbook->numChildren()/2-1, TRUE);
3465     return 1;
3466 }
3467 
onKeyPress(FXObject * sender,FXSelector sel,void * ptr)3468 long dxirc::onKeyPress(FXObject *sender, FXSelector sel, void *ptr)
3469 {
3470     FXEvent* event = (FXEvent*)ptr;
3471     if(m_tabbook->numTabs() && m_tabbook->childAtIndex(m_tabbook->getCurrent()*2)->getMetaClass()==&TetrisTabItem::metaClass)
3472     {
3473         switch(event->code){
3474             case KEY_N:
3475             case KEY_n:
3476             {
3477                 static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2))->newGame();
3478                 break;
3479             }
3480             case KEY_P:
3481             case KEY_p:
3482             {
3483                 static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2))->pauseResumeGame();
3484                 break;
3485             }
3486             case KEY_I:
3487             case KEY_i:
3488             {
3489                 static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2))->rotate();
3490                 break;
3491             }
3492             case KEY_L:
3493             case KEY_l:
3494             {
3495                 static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2))->moveRight();
3496                 break;
3497             }
3498             case KEY_K:
3499             case KEY_k:
3500             {
3501                 static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2))->drop();
3502                 break;
3503             }
3504             case KEY_J:
3505             case KEY_j:
3506             {
3507                 static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(m_tabbook->getCurrent()*2))->moveLeft();
3508                 break;
3509             }
3510         }
3511     }
3512     if(FXTopWindow::onKeyPress(sender, sel, ptr))
3513         return 1;
3514     return 0;
3515 }
3516 
autoloadScripts()3517 void dxirc::autoloadScripts()
3518 {
3519 #ifdef HAVE_LUA
3520     if(m_preferences.m_autoload && FXStat::exists(m_preferences.m_autoloadPath))
3521     {
3522         FXDir dir;
3523         FXString name, pathname;
3524         FXStat info;
3525         FXint islink;
3526         // Assume not a link
3527         islink = FALSE;
3528         // Managed to open directory
3529         if (dir.open(m_preferences.m_autoloadPath))
3530         {
3531             // Process directory entries
3532             while (dir.next())
3533             {
3534                 // Get name of entry
3535                 name = dir.name();
3536                 // A dot special file?
3537                 if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue;
3538                 // Hidden file or directory normally not shown
3539                 if (name[0] == '.') continue;
3540                 // Build full pathname of entry
3541                 pathname = m_preferences.m_autoloadPath;
3542                 if (!ISPATHSEP(pathname[pathname.length() - 1])) pathname += PATHSEPSTRING;
3543                 pathname += name;
3544 #ifndef WIN32
3545                 // Get file/link info
3546                 if (!FXStat::statLink(pathname, info)) continue;
3547                 // If its a link, get the info on file itself
3548                 islink = info.isLink();
3549                 if (islink && !FXStat::statFile(pathname, info)) continue;
3550 #else
3551                 // Get file/link info
3552                 if (!FXStat::statFile(pathname, info)) continue;
3553                 // Hidden file or directory normally not shown
3554                 if (info.isHidden()) continue;
3555 #endif //WIN32
3556                 // If it is a directory
3557                 if(info.isDirectory()) continue;
3558                 // If it is not matching pattern skip it
3559                 if (!FXPath::match("*.lua", name))continue;
3560                 loadLuaScript(pathname, FALSE);
3561             }
3562             // Close it
3563             dir.close();
3564         }
3565     }
3566 #endif //HAVE_LUA
3567 }
3568 
onCmdScripts(FXObject *,FXSelector,void *)3569 long dxirc::onCmdScripts(FXObject*, FXSelector, void*)
3570 {
3571 #ifdef HAVE_LUA
3572     ScriptDialog *dialog = new ScriptDialog(this);
3573     dialog->execute(PLACEMENT_OWNER);
3574 #endif //HAVE_LUA
3575     return 1;
3576 }
3577 
3578 //fired from tab by command /lua
onLua(FXObject * obj,FXSelector,void * data)3579 long dxirc::onLua(FXObject *obj, FXSelector, void *data)
3580 {
3581 #ifdef HAVE_LUA
3582     LuaRequest *lua = (LuaRequest*)data;
3583     if(lua->type == LUA_LOAD)
3584     {
3585         return loadLuaScript(lua->text);
3586     }
3587     if(lua->type == LUA_UNLOAD)
3588     {
3589         return unloadLuaScript(lua->text);
3590     }
3591     if(lua->type == LUA_LIST)
3592     {
3593         if(!m_scripts.no())
3594         {
3595             appendIrcStyledText(_("Scripts aren't loaded"), 4, FALSE);
3596             return 0;
3597         }
3598         else
3599         {
3600             appendIrcStyledText(_("Loaded scrips:"), 7, FALSE);
3601             for(FXint i=0; i<m_scripts.no(); i++)
3602             {
3603                 appendIrcText(FXStringFormat(_("Name: %s"), m_scripts[i].name.text()), FALSE);
3604                 appendIrcText(FXStringFormat(_("Description: %s"), m_scripts[i].description.text()), FALSE);
3605                 appendIrcText(FXStringFormat(_("Version: %s"), m_scripts[i].version.text()), FALSE);
3606                 appendIrcText(FXStringFormat(_("Path: %s"), m_scripts[i].path.text()), FALSE);
3607                 appendIrcText(dxUtils.availableScriptCommands(m_scripts[i].name), FALSE);
3608                 if(i+1<m_scripts.no()) appendIrcText("", FALSE);
3609             }
3610         }
3611         return 1;
3612     }
3613     if(lua->type == LUA_COMMAND)
3614     {
3615         dxTabItem *tab = static_cast<dxTabItem*>(obj);
3616         FXString command = lua->text.before(' ');
3617         FXString text = lua->text.after(' ');
3618         for(FXint i=0; i<m_scripts.no(); i++)
3619         {
3620             if(comparecase(dxUtils.getScriptName(command), m_scripts[i].name) == 0)
3621             {
3622                 lua_getglobal(m_scripts[i].L, dxUtils.getFuncname(command).text());
3623                 if(lua_isfunction(m_scripts[i].L, -1))
3624                 {
3625                     lua_pushstring(m_scripts[i].L, text.text());
3626                     lua_pushnumber(m_scripts[i].L, tab->getID());
3627                     if(lua_pcall(m_scripts[i].L, 2, 0, 0)) appendIrcStyledText(FXStringFormat(_("Error: %s"), lua_tostring(m_scripts[i].L, -1)), 4, FALSE);
3628                 }
3629                 else lua_pop(m_scripts[i].L, 1);
3630                 return 1;
3631             }
3632         }
3633     }
3634 #else
3635     appendIrcStyledText(_("dxirc is compiled without support for Lua scripting"), 4, FALSE);
3636 #endif //HAVE_LUA
3637     return 1;
3638 }
3639 
3640 //fired from tab command /log show
onShowLog(FXObject * sender,FXSelector,void * data)3641 long dxirc::onShowLog(FXObject *sender, FXSelector, void *data)
3642 {
3643     dxTabItem *tab = static_cast<dxTabItem*>(sender);
3644     FXint id = getTabId(tab->getText());
3645     if(id==-1) id = createIrcTab(tab->getText(), ICO_LOGS, OTHER, NULL);
3646     IrcTabItem *logtab = static_cast<IrcTabItem*>(getTabItemById(id));
3647     logtab->showLog(static_cast<FXString*>(data)->text());
3648     setCurrentTabById(id);
3649     return 1;
3650 }
3651 
3652 //notify hides
onNotifyHide(FXObject *,FXSelector,void *)3653 long dxirc::onNotifyHide(FXObject*, FXSelector, void*)
3654 {
3655     if(m_firstNotify)
3656         m_firstNotify = !m_firstNotify;
3657     return 1;
3658 }
3659 
onCmdList(FXObject *,FXSelector,void *)3660 long dxirc::onCmdList(FXObject *, FXSelector, void *)
3661 {
3662     if(m_tabbook->numChildren())
3663     {
3664         FXint index = m_tabbook->getCurrent()*2;
3665         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&TetrisTabItem::metaClass) return 0;
3666         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&DccTabItem::metaClass) return 0;
3667         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&IrcTabItem::metaClass)
3668         {
3669             IrcTabItem *currenttab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(index));
3670             IrcEngine *currentserver = NULL;
3671             for(FXint i=0; i < m_ircengines.no(); i++)
3672             {
3673                 if(m_ircengines[i]->findTarget(currenttab))
3674                 {
3675                     currentserver = m_ircengines[i];
3676                     break;
3677                 }
3678             }
3679             if(currentserver == NULL) return 0;
3680             if(currentserver->getConnected())
3681             {
3682                 FXString param = "";
3683                 if(dxEXInputDialog::getString(param, this, _("Question"), _("Parameters of /LIST command")+FXString("\n")+currentserver->getNetworkName()))
3684                     currentserver->sendList(param);
3685             }
3686         }
3687         if(m_tabbook->childAtIndex(index) && m_tabbook->childAtIndex(index)->getMetaClass()==&BoatsTabItem::metaClass)
3688         {
3689             BoatsTabItem *currenttab = static_cast<BoatsTabItem*>(m_tabbook->childAtIndex(index));
3690             IrcEngine *currentserver = NULL;
3691             for(FXint i=0; i < m_ircengines.no(); i++)
3692             {
3693                 if(m_ircengines[i]->findTarget(currenttab))
3694                 {
3695                     currentserver = m_ircengines[i];
3696                     break;
3697                 }
3698             }
3699             if(currentserver == NULL) return 0;
3700             if(currentserver->getConnected())
3701             {
3702                 FXString param = "";
3703                 if(dxEXInputDialog::getString(param, this, _("Question"), _("Parameters of /LIST command")+FXString("\n")+currentserver->getNetworkName()))
3704                     currentserver->sendList("");
3705             }
3706         }
3707     }
3708     return 1;
3709 }
3710 
3711 //Handle for entered text in IrcTab for ownmsg in lua scripting
onIrcOwnMsg(FXObject * sender,FXSelector,void * data)3712 long dxirc::onIrcOwnMsg(FXObject *sender, FXSelector, void *data)
3713 {
3714 #ifdef HAVE_LUA
3715     if(sender->getMetaClass()==&TetrisTabItem::metaClass) return 0;
3716     dxTabItem *tab = static_cast<dxTabItem*>(sender);
3717     FXString *text = static_cast<FXString*>(data);
3718     if(!m_scripts.no() || !m_scriptEvents.no())
3719     {
3720         tab->setHasOwnMsg(FALSE);
3721         return 0;
3722     }
3723     tab->setHasOwnMsg(hasOwnMsg());
3724     for(FXint i=0; i<m_scriptEvents.no(); i++)
3725     {
3726         if(comparecase("ownmsg", m_scriptEvents[i].name) == 0)
3727         {
3728             for(FXint j=0; j<m_scripts.no(); j++)
3729             {
3730                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
3731                 {
3732                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
3733                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
3734                     else
3735                     {
3736                         lua_pushstring(m_scripts[j].L, text->text());
3737                         lua_pushinteger(m_scripts[j].L, tab->getID());
3738                         if (lua_pcall(m_scripts[j].L, 2, 0, 0))
3739                         {
3740                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
3741                             lua_pop(m_scripts[j].L, 1);
3742                         }
3743                     }
3744                 }
3745             }
3746         }
3747     }
3748 #endif //HAVE_LUA
3749     return 1;
3750 }
3751 
3752 //send event to script for new created tab
sendNewTab(IrcEngine * server,const FXString & name,FXint id,FXbool isTetris,FXbool isDccTab,TYPE type)3753 void dxirc::sendNewTab(IrcEngine *server, const FXString &name, FXint id, FXbool isTetris, FXbool isDccTab, TYPE type)
3754 {
3755 #ifdef HAVE_LUA
3756     if(!m_scripts.no() || !m_scriptEvents.no())
3757         return;
3758     for(FXint i=0; i<m_scriptEvents.no(); i++)
3759     {
3760         if(comparecase("newtab", m_scriptEvents[i].name) == 0)
3761         {
3762             for(FXint j=0; j<m_scripts.no(); j++)
3763             {
3764                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
3765                 {
3766                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
3767                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
3768                     else
3769                     {
3770                         lua_newtable(m_scripts[j].L);
3771                         lua_pushstring(m_scripts[j].L, "id");
3772                         lua_pushinteger(m_scripts[j].L, id);
3773                         lua_settable(m_scripts[j].L, -3);
3774                         lua_pushstring(m_scripts[j].L, "name");
3775                         lua_pushstring(m_scripts[j].L, name.text());
3776                         lua_settable(m_scripts[j].L, -3);
3777                         if(isTetris)
3778                         {
3779                             lua_pushstring(m_scripts[j].L, "type");
3780                             lua_pushstring(m_scripts[j].L, "tetris");
3781                             lua_settable(m_scripts[j].L, -3);
3782                         }
3783                         else if(isDccTab)
3784                         {
3785                             lua_pushstring(m_scripts[j].L, "type");
3786                             lua_pushstring(m_scripts[j].L, "dccchat");
3787                             lua_settable(m_scripts[j].L, -3);
3788                         }
3789                         else
3790                         {
3791                             switch(type) {
3792                                 case SERVER:
3793                                 {
3794                                     lua_pushstring(m_scripts[j].L, "type");
3795                                     lua_pushstring(m_scripts[j].L, "server");
3796                                     lua_settable(m_scripts[j].L, -3);
3797                                 }break;
3798                                 case CHANNEL:
3799                                 {
3800                                     lua_pushstring(m_scripts[j].L, "type");
3801                                     lua_pushstring(m_scripts[j].L, "channel");
3802                                     lua_settable(m_scripts[j].L, -3);
3803                                 }break;
3804                                 case QUERY:
3805                                 {
3806                                     lua_pushstring(m_scripts[j].L, "type");
3807                                     lua_pushstring(m_scripts[j].L, "query");
3808                                     lua_settable(m_scripts[j].L, -3);
3809                                 }break;
3810                                 case OTHER:
3811                                 {
3812                                     lua_pushstring(m_scripts[j].L, "type");
3813                                     lua_pushstring(m_scripts[j].L, "other");
3814                                     lua_settable(m_scripts[j].L, -3);
3815                                 }break;
3816                                 case DCC:
3817                                 {
3818                                     lua_pushstring(m_scripts[j].L, "type");
3819                                     lua_pushstring(m_scripts[j].L, "dcc");
3820                                     lua_settable(m_scripts[j].L, -3);
3821                                 }break;
3822                                 case BOATS:
3823                                 {
3824                                     lua_pushstring(m_scripts[j].L, "type");
3825                                     lua_pushstring(m_scripts[j].L, "boats");
3826                                     lua_settable(m_scripts[j].L, -3);
3827                                 }break;
3828                             }
3829                         }
3830                         lua_pushstring(m_scripts[j].L, "servername");
3831                         lua_pushstring(m_scripts[j].L, server ? server->getServerName().text() : "");
3832                         lua_settable(m_scripts[j].L, -3);
3833                         lua_pushstring(m_scripts[j].L, "port");
3834                         lua_pushinteger(m_scripts[j].L, server ? server->getServerPort() : 0);
3835                         lua_settable(m_scripts[j].L, -3);
3836                         lua_pushstring(m_scripts[j].L, "nick");
3837                         lua_pushstring(m_scripts[j].L, server ? server->getNickName().text() : "");
3838                         lua_settable(m_scripts[j].L, -3);
3839                         if (lua_pcall(m_scripts[j].L, 1, 0, 0))
3840                         {
3841                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
3842                             lua_pop(m_scripts[j].L, 1);
3843                         }
3844                     }
3845                 }
3846             }
3847         }
3848     }
3849 #endif //HAVE_LUA
3850 }
3851 
3852 //Handle for entered command in IrcTab for all in lua scripting
onIrcCommand(FXObject * sender,FXSelector,void * data)3853 long dxirc::onIrcCommand(FXObject *sender, FXSelector, void *data)
3854 {
3855 #ifdef HAVE_LUA
3856     if(sender->getMetaClass()==&TetrisTabItem::metaClass) return 0;
3857     dxTabItem *tab = static_cast<dxTabItem*>(sender);
3858     FXString *commandtext = static_cast<FXString*>(data);
3859     if(!m_scripts.no() || !m_scriptEvents.no())
3860     {
3861         tab->setHasAllCommand(FALSE);
3862         return 0;
3863     }
3864     tab->setHasAllCommand(hasAllCommand());
3865     for(FXint i=0; i<m_scriptEvents.no(); i++)
3866     {
3867         if(comparecase("all", m_scriptEvents[i].name) == 0)
3868         {
3869             for(FXint j=0; j<m_scripts.no(); j++)
3870             {
3871                 if(comparecase(m_scriptEvents[i].script, m_scripts[j].name) == 0)
3872                 {
3873                     lua_getglobal(m_scripts[j].L, m_scriptEvents[i].funcname.text());
3874                     if (lua_type(m_scripts[j].L, -1) != LUA_TFUNCTION) lua_pop(m_scripts[j].L, 1);
3875                     else
3876                     {
3877                         if(commandtext->at(0) == '/')
3878                         {
3879                             lua_pushstring(m_scripts[j].L, commandtext->before(' ').after('/').text());
3880                             lua_pushstring(m_scripts[j].L, commandtext->after(' ').text());
3881                         }
3882                         else
3883                         {
3884                             lua_pushnil(m_scripts[j].L);
3885                             lua_pushstring(m_scripts[j].L, commandtext->text());
3886                         }
3887                         lua_pushinteger(m_scripts[j].L, tab->getID());
3888                         if (lua_pcall(m_scripts[j].L, 3, 0, 0))
3889                         {
3890                             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling %s %s"), m_scriptEvents[i].funcname.text(), lua_tostring(m_scripts[j].L, -1)), 4, FALSE);
3891                             lua_pop(m_scripts[j].L, 1);
3892                         }
3893                     }
3894                 }
3895             }
3896         }
3897     }
3898 #endif //HAVE_LUA
3899     return 1;
3900 }
3901 
tabExist(IrcEngine * server,FXString name,TYPE type)3902 FXbool dxirc::tabExist(IrcEngine *server, FXString name, TYPE type)
3903 {
3904     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
3905     {
3906         if(static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getType()==type && server
3907                 && server->findTarget(m_tabbook->childAtIndex(i))
3908                 && comparecase(static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->getText(), name) == 0)
3909             return TRUE;
3910     }
3911     return FALSE;
3912 }
3913 
serverExist(FXString server,FXint port,FXString nick)3914 FXbool dxirc::serverExist(FXString server, FXint port, FXString nick)
3915 {
3916     for(FXint i = 0; i < m_ircengines.no(); i++)
3917     {
3918         if(m_ircengines[i]->getServerName().lower() == server.lower() && m_ircengines[i]->getServerPort() == port && m_ircengines[i]->getNickName().lower() == nick.lower() && m_ircengines[i]->getConnected()) return TRUE;
3919     }
3920     return FALSE;
3921 }
3922 
getServerTab(IrcEngine * server)3923 FXint dxirc::getServerTab(IrcEngine *server)
3924 {
3925     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
3926     {
3927         if(m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass)
3928         {
3929             IrcTabItem *tab = static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i));
3930             if(server->findTarget(tab) && tab->getType() == SERVER) return i;
3931         }
3932     }
3933     return -1;
3934 }
3935 
getTabId(IrcEngine * server,FXString name)3936 FXint dxirc::getTabId(IrcEngine *server, FXString name)
3937 {
3938     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
3939     {
3940         if(server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))) && comparecase(name, static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->getText()) == 0)
3941             return static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i))->getID();
3942     }
3943     return -1;
3944 }
3945 
3946 //usefull only for tetristab, othertab
getTabId(FXString name)3947 FXint dxirc::getTabId(FXString name)
3948 {
3949     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
3950     {
3951         if(comparecase(name, static_cast<FXTabItem*>(m_tabbook->childAtIndex(i))->getText()) == 0)
3952         {
3953             if(m_tabbook->childAtIndex(i)->getMetaClass()==&TetrisTabItem::metaClass)
3954                 return static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(i))->getID();
3955             else
3956                 if(static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getType()==OTHER) return static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getID();
3957         }
3958     }
3959     return -1;
3960 }
3961 
getCurrentTabId()3962 FXint dxirc::getCurrentTabId()
3963 {
3964     FXint index = m_tabbook->getCurrent()*2;
3965     if(!m_tabbook->childAtIndex(index)) return -1;
3966     if(m_tabbook->childAtIndex(index)->getMetaClass()==&TetrisTabItem::metaClass)
3967         return static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(index))->getID();
3968     else
3969         return static_cast<dxTabItem*>(m_tabbook->childAtIndex(index))->getID();
3970     return -1;
3971 }
3972 
setCurrentTabById(FXint id)3973 void dxirc::setCurrentTabById(FXint id)
3974 {
3975     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
3976     {
3977         if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass
3978                 && static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getID() == id)
3979         {
3980             m_tabbook->setCurrent(i/2, TRUE);
3981             return;
3982         }
3983         if(m_tabbook->childAtIndex(i)->getMetaClass()==&TetrisTabItem::metaClass
3984                 && static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(i))->getID() == id)
3985         {
3986             m_tabbook->setCurrent(i/2, TRUE);
3987             return;
3988         }
3989     }
3990 }
3991 
getTabItemById(FXint id)3992 FXWindow* dxirc::getTabItemById(FXint id)
3993 {
3994     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
3995     {
3996         if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass
3997                 && static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getID() == id)
3998         {
3999             return m_tabbook->childAtIndex(i);
4000         }
4001         if(m_tabbook->childAtIndex(i)->getMetaClass()==&TetrisTabItem::metaClass
4002                 && static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(i))->getID() == id)
4003         {
4004             return m_tabbook->childAtIndex(i);
4005         }
4006     }
4007     return NULL;
4008 }
4009 
isValidTabId(FXint id)4010 FXbool dxirc::isValidTabId(FXint id)
4011 {
4012     if(id<0) return FALSE;
4013     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
4014     {
4015         if(m_tabbook->childAtIndex(i)->getMetaClass()==&TetrisTabItem::metaClass)
4016         {
4017             if(static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(i))->getID()==id) return TRUE;
4018         }
4019         else
4020         {
4021             if(static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getID()==id) return TRUE;
4022         }
4023     }
4024     return FALSE;
4025 }
4026 
isIddxTabItem(FXint id)4027 FXbool dxirc::isIddxTabItem(FXint id)
4028 {
4029     if(id<0) return FALSE;
4030     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
4031     {
4032         if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4033         {
4034             if(static_cast<dxTabItem*>(m_tabbook->childAtIndex(i))->getID()==id) return TRUE;
4035         }
4036     }
4037     return FALSE;
4038 }
4039 
isFriend(FXString nick,FXString on,FXString network)4040 FXbool dxirc::isFriend(FXString nick, FXString on, FXString network)
4041 {
4042     FXbool bnick = FALSE;
4043     FXbool bchannel = FALSE;
4044     FXbool bnetwork = FALSE;
4045     for(FXint i=0; i<m_preferences.m_friendsList.no(); i++)
4046     {
4047         FXString fnick = m_preferences.m_friendsList[i].nick;
4048         if(FXRex(FXString("\\<"+fnick+"\\>").lower().substitute("*","\\w*")).match(nick.lower())) bnick = TRUE;
4049         if(bnick)
4050         {
4051             if(m_preferences.m_friendsList[i].channel == "all") bchannel = TRUE;
4052             if(m_preferences.m_friendsList[i].channel.contains(','))
4053             {
4054                 for(FXint j=1; j<m_preferences.m_friendsList[i].channel.contains(',')+2; j++)
4055                 {
4056                     if(FXRex(FXString(dxutils::getParam(m_preferences.m_friendsList[i].channel, j, FALSE, ',').lower()+"\\>").substitute("*","\\w*")).match(on.lower()))
4057                     {
4058                         bchannel = TRUE;
4059                         break;
4060                     }
4061                 }
4062             }
4063             else
4064             {
4065                 if(FXRex(FXString(m_preferences.m_friendsList[i].channel+"\\>").lower().substitute("*","\\w*")).match(on.lower())) bchannel = TRUE;
4066             }
4067             if(m_preferences.m_friendsList[i].network == "all") bnetwork = TRUE;
4068             if(FXRex(FXString("\\<"+m_preferences.m_friendsList[i].network+"\\>").lower().substitute("*","\\w*")).match(network.lower())) bnetwork = TRUE;
4069             break;
4070         }
4071     }
4072     return bnick && bchannel && bnetwork;
4073 }
4074 
createIrcTab(const FXString & tabtext,FXIcon * icon,TYPE typ,IrcEngine * engine)4075 FXint dxirc::createIrcTab(const FXString& tabtext, FXIcon* icon, TYPE typ, IrcEngine* engine)
4076 {
4077     FXuint style;
4078     switch(m_preferences.m_tabPosition) {
4079         case 0: //bottom
4080             {
4081                 style = TAB_BOTTOM;
4082             }break;
4083         case 1: //left
4084             {
4085                 style = TAB_LEFT;
4086             }break;
4087         case 2: //top
4088             {
4089                 style = TAB_TOP;
4090             }break;
4091         case 3: //right
4092             {
4093                 style = TAB_RIGHT;
4094             }break;
4095         default:
4096             {
4097                 style = TAB_BOTTOM;
4098             }
4099     }
4100     IrcTabItem *tabitem = new IrcTabItem(m_tabbook, tabtext, icon, style, m_lastID, typ, engine, m_ircFont, m_preferences.m_themePath!="internal");
4101     sendNewTab(engine, tabtext, m_lastID, FALSE, FALSE, typ);
4102     m_lastID++;
4103     tabitem->create();
4104     tabitem->createGeom();
4105     tabitem->setSmileys(m_preferences.m_useSmileys, m_smileys);
4106     if(engine) engine->appendTarget(tabitem);
4107     sortTabs();
4108     return m_lastID-1;
4109 }
4110 
createDccTab(const FXString & mynick,const FXString & nick,const FXString & address,FXint portD,FXint portH,FXbool listen,IrcEngine * engine)4111 void dxirc::createDccTab(const FXString &mynick, const FXString &nick, const FXString &address, FXint portD, FXint portH, FXbool listen, IrcEngine *engine)
4112 {
4113     FXuint style;
4114     switch(m_preferences.m_tabPosition) {
4115         case 0: //bottom
4116             {
4117                 style = TAB_BOTTOM;
4118             }break;
4119         case 1: //left
4120             {
4121                 style = TAB_LEFT;
4122             }break;
4123         case 2: //top
4124             {
4125                 style = TAB_TOP;
4126             }break;
4127         case 3: //right
4128             {
4129                 style = TAB_RIGHT;
4130             }break;
4131         default:
4132             {
4133                 style = TAB_BOTTOM;
4134             }
4135     }
4136     DccTabItem *tabitem = new DccTabItem(m_tabbook, mynick, nick, address, portD, portH, listen, ICO_DCC, style, m_lastID, m_ircFont, engine);
4137     sendNewTab(NULL, nick, m_lastID, FALSE, TRUE, DCC);
4138     m_lastID++;
4139     tabitem->create();
4140     tabitem->createGeom();
4141     tabitem->setSmileys(m_preferences.m_useSmileys, m_smileys);
4142     if(engine) engine->appendTarget(tabitem);
4143     sortTabs();
4144 }
4145 
createBoatsTab(const FXString & tabtext,FXIcon * icon,IrcEngine * engine,FXbool first)4146 void dxirc::createBoatsTab(const FXString &tabtext, FXIcon *icon, IrcEngine *engine, FXbool first)
4147 {
4148     FXuint style;
4149     switch(m_preferences.m_tabPosition) {
4150         case 0: //bottom
4151             {
4152                 style = TAB_BOTTOM;
4153             }break;
4154         case 1: //left
4155             {
4156                 style = TAB_LEFT;
4157             }break;
4158         case 2: //top
4159             {
4160                 style = TAB_TOP;
4161             }break;
4162         case 3: //right
4163             {
4164                 style = TAB_RIGHT;
4165             }break;
4166         default:
4167             {
4168                 style = TAB_BOTTOM;
4169             }
4170     }
4171     BoatsTabItem *tabitem = new BoatsTabItem(m_tabbook, tabtext, first, icon, style, m_lastID, engine);
4172     sendNewTab(engine, tabtext, m_lastID, FALSE, FALSE, BOATS);
4173     m_lastID++;
4174     tabitem->create();
4175     tabitem->createGeom();
4176     if(engine) engine->appendTarget(tabitem);
4177     sortTabs();
4178     setCurrentTabById(m_lastID-1);
4179 }
4180 
isLastTab(IrcEngine * server)4181 FXbool dxirc::isLastTab(IrcEngine *server)
4182 {
4183     FXint numTabs = 0;
4184     for(FXint i = 0; i < m_tabbook->numChildren(); i+=2)
4185     {
4186         if(server->findTarget(static_cast<IrcTabItem*>(m_tabbook->childAtIndex(i)))) numTabs++;
4187     }
4188     if(numTabs > 1) return FALSE;
4189     else return TRUE;
4190 }
4191 
hasTetrisTab()4192 FXbool dxirc::hasTetrisTab()
4193 {
4194     if(m_tabbook->numChildren())
4195     {
4196         for(FXint i = 0; i < m_tabbook->numChildren()/2; i++)
4197         {
4198             if(m_tabbook->childAtIndex(i*2)->getMetaClass()==&TetrisTabItem::metaClass) return TRUE;
4199         }
4200     }
4201     return FALSE;
4202 }
4203 
sortTabs()4204 void dxirc::sortTabs()
4205 {
4206     if(m_preferences.m_disableSortTabs)
4207         return;
4208     if(m_tabbook->numTabs() > 1)
4209     {
4210         FXint id = getCurrentTabId();
4211         if(hasTetrisTab())
4212         {
4213             FXint index = 0;
4214             TetrisTabItem *tetristab = NULL;
4215             dxTabItem* *tabpole = new dxTabItem*[m_tabbook->numTabs()-1];
4216             for(FXint i = 0; i < m_tabbook->numTabs(); i++)
4217             {
4218                 if(m_tabbook->childAtIndex(i*2)->getMetaClass()!=&TetrisTabItem::metaClass)
4219                 {
4220                     tabpole[index] = static_cast<dxTabItem*>(m_tabbook->childAtIndex(i*2));
4221                     index++;
4222                 }
4223                 else tetristab = static_cast<TetrisTabItem*>(m_tabbook->childAtIndex(i*2));
4224             }
4225             qsort(tabpole, m_tabbook->numTabs()-1, sizeof(tabpole[0]), (int(*)(const void*, const void*))&CompareTabs);
4226             for(FXint i = 0; i < m_tabbook->numTabs()-1; i++)
4227             {
4228                 tabpole[i]->reparentTab();
4229             }
4230             tetristab->reparentTab();
4231             m_tabbook->recalc();
4232             delete []tabpole;
4233         }
4234         else
4235         {
4236             dxTabItem* *tabpole = new dxTabItem*[m_tabbook->numTabs()];
4237             for(FXint i = 0; i < m_tabbook->numTabs(); i++)
4238             {
4239                 tabpole[i] = (dxTabItem*)m_tabbook->childAtIndex(i*2);
4240             }
4241             qsort(tabpole, m_tabbook->numTabs(), sizeof(tabpole[0]), (int(*)(const void*, const void*))&CompareTabs);
4242             for(int i=0; i < m_tabbook->numTabs(); i++)
4243             {
4244                 tabpole[i]->reparentTab();
4245             }
4246             m_tabbook->recalc();
4247             delete []tabpole;
4248         }
4249         setCurrentTabById(id);
4250     }
4251 }
4252 
moveTab(bool up)4253 void dxirc::moveTab(bool up)
4254 {
4255     if(m_tabbook->numTabs()>1)
4256     {
4257         FXint id = getCurrentTabId();
4258         FXint index = m_tabbook->getCurrent();
4259         dxEXTabItem* *tabpole = new dxEXTabItem*[m_tabbook->numTabs()];
4260         for(FXint i = 0; i < m_tabbook->numTabs(); i++)
4261         {
4262             tabpole[i] = (dxEXTabItem*)m_tabbook->childAtIndex(i*2);
4263         }
4264         if(up)
4265         {
4266             if(index)
4267             {
4268                 dxEXTabItem *temp = tabpole[index-1];
4269                 tabpole[index-1] = tabpole[index];
4270                 tabpole[index] = temp;
4271             }
4272             else
4273             {
4274                 dxEXTabItem *temp = tabpole[index];
4275                 for(FXint i = 0; i < m_tabbook->numTabs()-1; i++)
4276                 {
4277                     tabpole[i] = tabpole[i+1];
4278                 }
4279                 tabpole[m_tabbook->numTabs()-1] = temp;
4280             }
4281         }
4282         else
4283         {
4284             if(index==m_tabbook->numTabs()-1)
4285             {
4286                 dxEXTabItem *temp = tabpole[index];
4287                 for(FXint i = m_tabbook->numTabs()-1; i > 0; i--)
4288                 {
4289                     tabpole[i] = tabpole[i-1];
4290                 }
4291                 tabpole[0] = temp;
4292             }
4293             else
4294             {
4295                 dxEXTabItem *temp = tabpole[index+1];
4296                 tabpole[index+1] = tabpole[index];
4297                 tabpole[index] = temp;
4298             }
4299         }
4300         for(FXint i = 0; i < m_tabbook->numTabs(); i++)
4301         {
4302             if(tabpole[i]->getMetaClass()!=&TetrisTabItem::metaClass)
4303                 static_cast<dxTabItem*>(tabpole[i])->reparentTab();
4304             else
4305                 static_cast<TetrisTabItem*>(tabpole[i])->reparentTab();
4306 
4307         }
4308         m_tabbook->recalc();
4309         delete []tabpole;
4310         setCurrentTabById(id);
4311     }
4312 }
4313 
updateMenus()4314 void dxirc::updateMenus()
4315 {
4316     if(m_tabbook->numChildren())
4317     {
4318         m_closeTab->enable();
4319         m_clearTab->enable();
4320         m_clearTabs->enable();
4321     }
4322     else
4323     {
4324         m_closeTab->disable();
4325         m_clearTab->disable();
4326         m_clearTabs->disable();
4327     }
4328     FXbool someConnected = FALSE;
4329     for(FXint i = 0; i < m_ircengines.no(); i++)
4330     {
4331         if(m_ircengines[i]->getConnected())
4332         {
4333             someConnected = TRUE;
4334             break;
4335         }
4336     }
4337     if(someConnected)
4338     {
4339         m_disconnect->enable();
4340         m_reconnect->enable();
4341     }
4342     else
4343     {
4344         m_disconnect->disable();
4345         m_reconnect->disable();
4346     }
4347 }
4348 
updateStatus(FXString text)4349 void dxirc::updateStatus(FXString text)
4350 {
4351     m_statuslabel->setText(text);
4352 #ifdef HAVE_TRAY
4353     if(m_trayIcon && m_preferences.m_useTray)
4354     {
4355         m_trayIcon->setText("dxirc\n"+text);
4356     }
4357 #endif //HAVE_TRAY
4358     m_app->addTimeout(this, dxirc_STIMEOUT, 5000);
4359 }
4360 
onStatusTimeout(FXObject *,FXSelector,void *)4361 long dxirc::onStatusTimeout(FXObject*, FXSelector, void*)
4362 {
4363     m_statuslabel->setText(" ");
4364 #ifdef HAVE_TRAY
4365     if(m_trayIcon && m_preferences.m_useTray)
4366     {
4367         m_trayIcon->setText("dxirc");
4368     }
4369 #endif //HAVE_TRAY
4370     return 1;
4371 }
4372 
appendIrcText(FXString text,FXbool logLine)4373 void dxirc::appendIrcText(FXString text, FXbool logLine)
4374 {
4375     if(m_tabbook->numChildren())
4376     {
4377         FXint index = m_tabbook->getCurrent()*2;
4378         if(!m_tabbook->childAtIndex(index)) return;
4379         if(m_tabbook->childAtIndex(index)->getMetaClass()==&TetrisTabItem::metaClass)
4380         {
4381             for(FXint i=0; i<m_tabbook->numChildren(); i+=2)
4382             {
4383                 if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4384                 {
4385                     index = i;
4386                     break;
4387                 }
4388             }
4389         }
4390         dxTabItem *currenttab = static_cast<dxTabItem*>(m_tabbook->childAtIndex(index));
4391         FXASSERT(currenttab != 0);
4392         currenttab->appendText(text, TRUE, logLine);
4393         currenttab->makeLastRowVisible();
4394     }
4395 }
4396 
appendIrcStyledText(FXString text,FXint style,FXbool logLine)4397 void dxirc::appendIrcStyledText(FXString text, FXint style, FXbool logLine)
4398 {
4399     if(m_tabbook->numChildren())
4400     {
4401         FXint index = m_tabbook->getCurrent()*2;
4402         if(!m_tabbook->childAtIndex(index)) return;
4403         if(m_tabbook->childAtIndex(index)->getMetaClass()==&TetrisTabItem::metaClass)
4404         {
4405             for(FXint i=0; i<m_tabbook->numChildren(); i+=2)
4406             {
4407                 if(m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4408                 {
4409                     index = i;
4410                     break;
4411                 }
4412             }
4413         }
4414         dxTabItem *currenttab = static_cast<dxTabItem*>(m_tabbook->childAtIndex(index));
4415         FXASSERT(currenttab != 0);
4416         currenttab->appendStyledText(text, style, TRUE, FALSE, logLine);
4417         currenttab->makeLastRowVisible();
4418     }
4419 }
4420 
loadLuaScript(FXString path,FXbool showMessage)4421 FXint dxirc::loadLuaScript(FXString path, FXbool showMessage)
4422 {
4423 #ifdef HAVE_LUA
4424     if(m_scripts.no())
4425     {
4426        for(FXint i=0; i<m_scripts.no(); i++)
4427         {
4428             if(comparecase(path, m_scripts[i].path)==0)
4429             {
4430                 appendIrcStyledText(FXStringFormat(_("Script %s is already loaded"), path.text()), 4, FALSE);
4431                 return 0;
4432             }
4433         }
4434     }
4435     if(hasLuaAll(path))
4436     {
4437         if(showMessage)
4438         {
4439             if(dxEXMessageBox::question(this, MBOX_YES_NO, _("Question"), _("Script %s contains dxirc.AddAll\nThis can BREAK dxirc funcionality.\nLoad it anyway?"), path.text()) == 2) return 0;
4440         }
4441         else appendIrcStyledText(FXStringFormat(_("Script %s contains dxirc.AddAll. This can BREAK dxirc funcionality."), path.text()), 4, FALSE);
4442     }
4443     lua_State *L = luaL_newstate();
4444     if(L == NULL)
4445     {
4446         appendIrcStyledText(_("Unable to initialize Lua."), 4, FALSE);
4447         return 0;
4448     }
4449     luaL_openlibs(L);
4450 #if LUA_VERSION_NUM > 501
4451     lua_newtable(L);
4452     lua_pushvalue(L, -1);
4453     lua_setglobal(L, "dxirc");
4454     luaL_setfuncs(L, dxircFunctions, 0);
4455 #else
4456     luaL_register(L, "dxirc", dxircFunctions);
4457 #endif
4458     if(luaL_dofile(L, path.text()))
4459     {
4460         appendIrcStyledText(FXStringFormat(_("Unable to load/run the file %s"), lua_tostring(L, -1)), 4, FALSE);
4461         return 0;
4462     }
4463     lua_getglobal(L, "dxirc_Register");
4464     if(lua_pcall(L, 0, 3, 0))
4465     {
4466         appendIrcStyledText(FXStringFormat(_("Lua plugin: error registering script %s"), lua_tostring(L, -1)), 4, FALSE);
4467         return 0;
4468     }
4469     FXString name = lua_tostring(L, -3);
4470     FXString version = lua_tostring(L, -2);
4471     FXString description = lua_tostring(L, -1);
4472     lua_pop(L, 4);
4473     if(m_scripts.no())
4474     {
4475        for(FXint i=0; i<m_scripts.no(); i++)
4476         {
4477             if(comparecase(name, m_scripts[i].name)==0)
4478             {
4479                 appendIrcStyledText(FXStringFormat(_("Script with name %s is already loaded"), name.lower().text()), 4, FALSE);
4480                 return 0;
4481             }
4482         }
4483     }
4484     LuaScript script;
4485     script.L = L;
4486     script.name = name;
4487     script.version = version;
4488     script.description = description;
4489     script.path = path;
4490     m_scripts.append(script);
4491     appendIrcStyledText(FXStringFormat(_("Script %s was loaded"), path.text()), 3, FALSE);
4492     appendIrcStyledText(FXStringFormat("%s: %s", script.name.text(), script.description.text()), 3, FALSE);
4493     lua_getglobal(L, "dxirc_Init");
4494     if (lua_type(L, -1) != LUA_TFUNCTION) lua_pop(L, 1);
4495     else
4496     {
4497         if (lua_pcall(L, 0, 0, 0))
4498         {
4499             appendIrcStyledText(FXStringFormat(_("Lua plugin: error calling dxirc_Init() %s"), lua_tostring(L, -1)), 4, FALSE);
4500             lua_pop(L, 1);
4501         }
4502     }
4503     return 1;
4504 #else
4505     return 0;
4506 #endif //HAVE_LUA
4507 }
4508 
unloadLuaScript(FXString name)4509 FXint dxirc::unloadLuaScript(FXString name)
4510 {
4511 #ifdef HAVE_LUA
4512     FXbool success = FALSE;
4513     if(!m_scripts.no())
4514     {
4515         appendIrcStyledText(FXStringFormat(_("Script %s isn't loaded"), name.text()), 4, FALSE);
4516         return 0;
4517     }
4518     else
4519     {
4520         for(FXint i=m_scripts.no()-1; i>-1; i--)
4521         {
4522             if(comparecase(name, m_scripts[i].name)==0)
4523             {
4524                 dxUtils.removeScriptCommands(m_scripts[i].name);
4525                 lua_close(m_scripts[i].L);
4526                 m_scripts.erase(i);
4527                 success = TRUE;
4528             }
4529         }
4530     }
4531     for(FXint i=m_scriptEvents.no()-1; i>-1; i--)
4532     {
4533         if(comparecase(name, m_scriptEvents[i].script)==0)
4534         {
4535             m_scriptEvents.erase(i);
4536             success = TRUE;
4537         }
4538     }
4539     if(success) appendIrcStyledText(FXStringFormat(_("Script %s was unloaded"), name.text()), 4, FALSE);
4540     else appendIrcStyledText(FXStringFormat(_("Script %s isn't loaded"), name.text()), 4, FALSE);
4541     return 1;
4542 #else
4543     return 0;
4544 #endif //HAVE_LUA
4545 }
4546 
hasLuaAll(const FXString & file)4547 FXbool dxirc::hasLuaAll(const FXString &file)
4548 {
4549     std::ifstream fin(file.text());
4550     std::string line;
4551     while(fin.good())
4552     {
4553         std::getline(fin, line);
4554         if(line.find("dxirc.AddEvent") != std::string::npos)
4555         {
4556             FXString fxline = FXString(line.c_str()).lower();
4557             if(fxline.contains("\"all\""))
4558                 return TRUE;
4559         }
4560     }
4561     return FALSE;
4562 }
4563 
4564 //check for mymsg in loaded script
hasOwnMsg()4565 FXbool dxirc::hasOwnMsg()
4566 {
4567     if(!m_scripts.no() || !m_scriptEvents.no())
4568     {
4569         return FALSE;
4570     }
4571     for(FXint i=0; i<m_scriptEvents.no(); i++)
4572     {
4573         if(comparecase("ownmsg", m_scriptEvents[i].name) == 0)
4574         {
4575             return TRUE;
4576         }
4577     }
4578     return FALSE;
4579 }
4580 
4581 //check for all in loaded script
hasAllCommand()4582 FXbool dxirc::hasAllCommand()
4583 {
4584     if(!m_scripts.no() || !m_scriptEvents.no())
4585     {
4586         return FALSE;
4587     }
4588     for(FXint i=0; i<m_scriptEvents.no(); i++)
4589     {
4590         if(comparecase("all", m_scriptEvents[i].name) == 0)
4591         {
4592             return TRUE;
4593         }
4594     }
4595     return FALSE;
4596 }
4597 
4598 /*return unique filename
4599 usefull mainly for autoDccFile */
getUniqueName(const FXString & path,const FXString & name,const FXString & extension)4600 FXString dxirc::getUniqueName(const FXString &path, const FXString &name, const FXString &extension)
4601 {
4602     if(extension.empty())
4603     {
4604         if(!FXStat::exists(path+PATHSEPSTRING+name)) return path+PATHSEPSTRING+name;
4605         else return path+PATHSEPSTRING+name+"-"+FXSystem::time("%Y%m%d%H%M%S", FXSystem::now());
4606     }
4607     else
4608     {
4609         if(!FXStat::exists(path+PATHSEPSTRING+name+"."+extension)) return path+PATHSEPSTRING+name+"."+extension;
4610         else return path+PATHSEPSTRING+name+"-"+FXSystem::time("%Y%m%d%H%M%S", FXSystem::now())+"."+extension;
4611     }
4612 }
4613 
4614 //check if exist .part file in dccpath
isForResume(const FXString & name)4615 FXbool dxirc::isForResume(const FXString& name)
4616 {
4617     return FXStat::exists(m_preferences.m_dccPath+PATHSEPSTRING+name+".part");
4618 }
4619 
onLuaAddCommand(lua_State * lua)4620 int dxirc::onLuaAddCommand(lua_State *lua)
4621 {
4622 #ifdef HAVE_LUA
4623     FXString name, funcname, helptext, script;
4624     if(lua_isstring(lua, 1)) name = lua_tostring(lua,1);
4625     if(lua_isstring(lua, 2)) funcname = lua_tostring(lua,2);
4626     if(lua_isstring(lua, 3)) helptext = lua_tostring(lua,3);
4627     if(name.empty() || funcname.empty() || helptext.empty()) return 0;
4628     if(dxUtils.isCommand(name))
4629     {
4630         _pThis->appendIrcStyledText(FXStringFormat(_("Command %s already exists"), name.text()), 4, FALSE);
4631         return 0;
4632     }
4633     if(_pThis->m_scripts.no())
4634     {
4635         for(FXint i=0; i<_pThis->m_scripts.no(); i++)
4636         {
4637             if(lua == _pThis->m_scripts[i].L) script = _pThis->m_scripts[i].name;
4638         }
4639     }
4640     if(script.empty()) return 0;
4641     LuaScriptCommand command;
4642     command.name = name;
4643     command.funcname = funcname;
4644     command.helptext = helptext;
4645     command.script = script;
4646     dxUtils.addScriptCommand(command);
4647     return  1;
4648 #else
4649     return 0;
4650 #endif //HAVE_LUA
4651 }
4652 
onLuaAddEvent(lua_State * lua)4653 int dxirc::onLuaAddEvent(lua_State *lua)
4654 {
4655 #ifdef HAVE_LUA
4656     FXString name, funcname, script;
4657     if(lua_isstring(lua, 1)) name = lua_tostring(lua,1);
4658     if(lua_isstring(lua, 2)) funcname = lua_tostring(lua,2);
4659     if(name.empty() || funcname.empty()) return 0;
4660     if(_pThis->m_scripts.no())
4661     {
4662         for(FXint i=0; i<_pThis->m_scripts.no(); i++)
4663         {
4664             if(lua == _pThis->m_scripts[i].L) script = _pThis->m_scripts[i].name;
4665         }
4666     }
4667     if(script.empty()) return 0;
4668     if(_pThis->m_scriptEvents.no())
4669     {
4670         for(FXint i=0; i<_pThis->m_scriptEvents.no(); i++)
4671         {
4672             if(comparecase(name, _pThis->m_scriptEvents[i].name)==0 && comparecase(funcname, _pThis->m_scriptEvents[i].funcname)==0 && comparecase(script, _pThis->m_scriptEvents[i].script)==0)
4673             {
4674                 _pThis->appendIrcStyledText(FXStringFormat(_("Function %s for event %s already exists"), funcname.text(), name.text()), 4, FALSE);
4675                 return 0;
4676             }
4677         }
4678     }
4679     LuaScriptEvent event;
4680     event.name = name;
4681     event.funcname = funcname;
4682     event.script = script;
4683     _pThis->m_scriptEvents.append(event);
4684     return  1;
4685 #else
4686     return 0;
4687 #endif //HAVE_LUA
4688 }
4689 
onLuaRemoveName(lua_State * lua)4690 int dxirc::onLuaRemoveName(lua_State *lua)
4691 {
4692 #ifdef HAVE_LUA
4693     FXString command, script;
4694     if(lua_isstring(lua, 1)) command = lua_tostring(lua, 1);
4695     if(command.empty()) return 0;
4696     if(dxUtils.removeScriptCommand(command)) return 1;
4697     if(_pThis->m_scripts.no())
4698     {
4699         for(FXint i=0; i<_pThis->m_scripts.no(); i++)
4700         {
4701             if(lua == _pThis->m_scripts[i].L) script = _pThis->m_scripts[i].name;
4702         }
4703     }
4704     if(script.empty()) return 0;
4705     if(_pThis->m_scriptEvents.no())
4706     {
4707         for(FXint i=0; i<_pThis->m_scriptEvents.no(); i++)
4708         {
4709             if(comparecase(command, _pThis->m_scriptEvents[i].name) == 0 && comparecase(script, _pThis->m_scriptEvents[i].script) == 0)
4710             {
4711                 _pThis->m_scriptEvents.erase(i);
4712                 _pThis->appendIrcStyledText(FXStringFormat(_("Command/event %s in script %s was removed"), command.text(), script.text()), 3, FALSE);
4713             }
4714         }
4715     }
4716     return  1;
4717 #else
4718     return 0;
4719 #endif //HAVE_LUA
4720 }
4721 
onLuaCommand(lua_State * lua)4722 int dxirc::onLuaCommand(lua_State *lua)
4723 {
4724 #ifdef HAVE_LUA
4725     FXString command;
4726     if(lua_isstring(lua, 1)) command = lua_tostring(lua, 1);
4727     if(command.empty()) return 0;
4728     FXint id;
4729     if(lua_isnumber(lua, 2) && _pThis->isValidTabId(lua_tointeger(lua, 2))) id = lua_tointeger(lua, 2);
4730     else id = _pThis->getCurrentTabId();
4731     if(_pThis->m_tabbook->numChildren())
4732     {
4733         for(FXint i = 0; i<_pThis->m_tabbook->numChildren(); i+=2)
4734         {
4735             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4736             {
4737                 dxTabItem *tab = static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i));
4738                 if(id==tab->getID())
4739                 {
4740                     tab->processLine(command);
4741                     return 1;
4742                 }
4743             }
4744         }
4745     }
4746     return  1;
4747 #else
4748     return 0;
4749 #endif //HAVE_LUA
4750 }
4751 
onLuaPrint(lua_State * lua)4752 int dxirc::onLuaPrint(lua_State *lua)
4753 {
4754 #ifdef HAVE_LUA
4755     FXString text;
4756     if(lua_isstring(lua, 1)) text = lua_tostring(lua, 1);
4757     if(text.empty()) return 0;
4758     FXint id, style;
4759     if(lua_isnumber(lua, 2) && _pThis->isIddxTabItem(lua_tointeger(lua, 2))) id = lua_tointeger(lua, 2);
4760     else id = _pThis->getCurrentTabId();
4761     if(lua_isnumber(lua, 3))
4762     {
4763         style = lua_tointeger(lua, 3);
4764         if(style<0 || style>8) style = 0;
4765     }
4766     else style = 0;
4767     if(_pThis->m_tabbook->numChildren())
4768     {
4769         for(FXint i = 0; i<_pThis->m_tabbook->numChildren(); i+=2)
4770         {
4771             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4772             {
4773                 dxTabItem *tab = static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i));
4774                 if(id==tab->getID())
4775                 {
4776                     tab->appendStyledText(text, style, TRUE, TRUE, TRUE);
4777                     tab->makeLastRowVisible();
4778                     return 1;
4779                 }
4780             }
4781         }
4782     }
4783     return  1;
4784 #else
4785     return 0;
4786 #endif //HAVE_LUA
4787 }
4788 
onLuaGetServers(lua_State * lua)4789 int dxirc::onLuaGetServers(lua_State *lua)
4790 {
4791 #ifdef HAVE_LUA
4792     if(_pThis->m_ircengines.no())
4793     {
4794         lua_newtable(lua);
4795         for(FXint i=0; i<_pThis->m_ircengines.no(); i++)
4796         {
4797             lua_pushnumber(lua, i+1);
4798             lua_newtable(lua);
4799             lua_pushstring(lua, "server");
4800             lua_pushstring(lua, _pThis->m_ircengines[i]->getServerName().text());
4801             lua_settable(lua, -3);
4802             lua_pushstring(lua, "port");
4803             lua_pushnumber(lua, _pThis->m_ircengines[i]->getServerPort());
4804             lua_settable(lua, -3);
4805             lua_pushstring(lua, "nick");
4806             lua_pushstring(lua, _pThis->m_ircengines[i]->getNickName().text());
4807             lua_settable(lua, -3);
4808             lua_settable(lua, -3);
4809         }
4810     }
4811     else
4812     {
4813         lua_newtable(lua);
4814         lua_pushnumber(lua, 1);
4815         lua_newtable(lua);
4816         lua_pushstring(lua, "server");
4817         lua_pushnil(lua);
4818         lua_settable(lua, -3);
4819         lua_pushstring(lua, "port");
4820         lua_pushnil(lua);
4821         lua_settable(lua, -3);
4822         lua_pushstring(lua, "nick");
4823         lua_pushnil(lua);
4824         lua_settable(lua, -3);
4825         lua_settable(lua, -3);
4826     }
4827     return  1;
4828 #else
4829     return 0;
4830 #endif //HAVE_LUA
4831 }
4832 
onLuaGetTab(lua_State * lua)4833 int dxirc::onLuaGetTab(lua_State *lua)
4834 {
4835 #ifdef HAVE_LUA
4836     FXString tab, server;
4837     if(lua_isstring(lua, 1)) tab = lua_tostring(lua, 1);
4838     if(lua_isstring(lua, 2)) server = lua_tostring(lua,2);
4839     if(_pThis->m_tabbook->numChildren())
4840     {
4841         for(FXint i = 0; i<_pThis->m_tabbook->numChildren(); i+=2)
4842         {
4843             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4844             {
4845                 if(comparecase(tab, static_cast<FXTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getText()) == 0 && comparecase(server, static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getServerName()) == 0)
4846                 {
4847                     lua_pushnumber(lua, static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getID());
4848                     return 1;
4849                 }
4850             }
4851         }
4852         lua_pushnumber(lua, _pThis->getCurrentTabId());
4853         return 1;
4854     }
4855     else lua_pushnumber(lua, -1);
4856     return  1;
4857 #else
4858     return 0;
4859 #endif //HAVE_LUA
4860 }
4861 
onLuaGetCurrentTab(lua_State * lua)4862 int dxirc::onLuaGetCurrentTab(lua_State *lua)
4863 {
4864 #ifdef HAVE_LUA
4865     lua_pushnumber(lua, _pThis->getCurrentTabId());
4866     return 1;
4867 #else
4868     return 0;
4869 #endif //HAVE_LUA
4870 }
4871 
onLuaGetVersion(lua_State * lua)4872 int dxirc::onLuaGetVersion(lua_State *lua)
4873 {
4874 #ifdef HAVE_LUA
4875     lua_pushstring(lua, VERSION);
4876     return 1;
4877 #else
4878     return 0;
4879 #endif //HAVE_LUA
4880 }
4881 
onLuaGetTabInfo(lua_State * lua)4882 int dxirc::onLuaGetTabInfo(lua_State *lua)
4883 {
4884 #ifdef HAVE_LUA
4885     FXint id;
4886     if(lua_isnumber(lua, 1))  id = lua_tointeger(lua, 1);
4887     else id = -1;
4888     if(_pThis->m_tabbook->numChildren() && _pThis->isIddxTabItem(id))
4889     {
4890         dxTabItem *tab = NULL;
4891         for(FXint i = 0; i<_pThis->m_tabbook->numChildren(); i+=2)
4892         {
4893             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
4894             {
4895                 tab = static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i));
4896                 if(id==tab->getID())
4897                 {
4898                     break;
4899                 }
4900             }
4901         }
4902         lua_newtable(lua);
4903         lua_pushstring(lua, "name");
4904         lua_pushstring(lua, tab->getText().text());
4905         lua_settable(lua, -3);
4906         switch(tab->getType()) {
4907             case SERVER:
4908             {
4909                 lua_pushstring(lua, "type");
4910                 lua_pushstring(lua, "server");
4911                 lua_settable(lua, -3);
4912             }break;
4913             case CHANNEL:
4914             {
4915                 lua_pushstring(lua, "type");
4916                 lua_pushstring(lua, "channel");
4917                 lua_settable(lua, -3);
4918             }break;
4919             case QUERY:
4920             {
4921                 lua_pushstring(lua, "type");
4922                 lua_pushstring(lua, "query");
4923                 lua_settable(lua, -3);
4924             }break;
4925             case OTHER:
4926             {
4927                 lua_pushstring(lua, "type");
4928                 lua_pushstring(lua, "other");
4929                 lua_settable(lua, -3);
4930             }break;
4931             case DCC:
4932             {
4933                 lua_pushstring(lua, "type");
4934                 lua_pushstring(lua, "dcc");
4935                 lua_settable(lua, -3);
4936             }break;
4937             case BOATS:
4938             {
4939                 lua_pushstring(lua, "type");
4940                 lua_pushstring(lua, "boats");
4941                 lua_settable(lua, -3);
4942             }break;
4943         }
4944         if(tab->getMetaClass()==&DccTabItem::metaClass)
4945         {
4946             lua_pushstring(lua, "type");
4947             lua_pushstring(lua, "dccchat");
4948             lua_settable(lua, -3);
4949         }
4950         lua_pushstring(lua, "servername");
4951         lua_pushstring(lua, tab->getServerName().text());
4952         lua_settable(lua, -3);
4953         lua_pushstring(lua, "port");
4954         lua_pushinteger(lua, tab->getServerPort());
4955         lua_settable(lua, -3);
4956         lua_pushstring(lua, "nick");
4957         lua_pushstring(lua, tab->getNickName().text());
4958         lua_settable(lua, -3);
4959     }
4960     else
4961     {
4962         lua_newtable(lua);
4963         lua_pushstring(lua, "name");
4964         lua_pushnil(lua);
4965         lua_settable(lua, -3);
4966         lua_pushstring(lua, "type");
4967         lua_pushnil(lua);
4968         lua_settable(lua, -3);
4969         lua_pushstring(lua, "servername");
4970         lua_pushnil(lua);
4971         lua_settable(lua, -3);
4972         lua_pushstring(lua, "port");
4973         lua_pushnil(lua);
4974         lua_settable(lua, -3);
4975         lua_pushstring(lua, "nick");
4976         lua_pushnil(lua);
4977         lua_settable(lua, -3);
4978     }
4979     return  1;
4980 #else
4981     return 0;
4982 #endif //HAVE_LUA
4983 }
4984 
onLuaSetTab(lua_State * lua)4985 int dxirc::onLuaSetTab(lua_State *lua)
4986 {
4987 #ifdef HAVE_LUA
4988     _pThis->setCurrentTabById(lua_tointeger(lua, 1));
4989     return  1;
4990 #else
4991     return 0;
4992 #endif //HAVE_LUA
4993 }
4994 
onLuaCreateTab(lua_State * lua)4995 int dxirc::onLuaCreateTab(lua_State *lua)
4996 {
4997 #ifdef HAVE_LUA
4998     FXString name;
4999     if(lua_isstring(lua, 1)) name = lua_tostring(lua, 1);
5000     else
5001     {
5002         lua_pushnil(lua);
5003         return 0;
5004     }
5005     if(_pThis->m_tabbook->numChildren())
5006     {
5007         for(FXint i = 0; i < _pThis->m_tabbook->numChildren(); i+=2)
5008         {
5009             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()==&IrcTabItem::metaClass
5010                     && comparecase(static_cast<FXTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getText(), name) == 0
5011                     && static_cast<IrcTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getType() == OTHER)
5012             {
5013                 lua_pushnil(lua);
5014                 return 0;
5015             }
5016         }
5017     }
5018     lua_pushnumber(lua, _pThis->createIrcTab(name, NULL, OTHER, NULL));
5019     return 1;
5020 #else
5021     return 0;
5022 #endif //HAVE_LUA
5023 }
5024 
onLuaGetTabCount(lua_State * lua)5025 int dxirc::onLuaGetTabCount(lua_State *lua)
5026 {
5027 #ifdef HAVE_LUA
5028     lua_pushnumber(lua, _pThis->m_tabbook->numChildren()/2);
5029     return 1;
5030 #else
5031     return 0;
5032 #endif //HAVE_LUA
5033 }
5034 
onLuaClear(lua_State * lua)5035 int dxirc::onLuaClear(lua_State *lua)
5036 {
5037 #ifdef HAVE_LUA
5038     FXint id = -1;
5039     if(lua_isnumber(lua, 1) && _pThis->isIddxTabItem(lua_tointeger(lua, 1)))  id = lua_tointeger(lua, 1);
5040     else return 0;
5041     dxutils::debugLine(FXStringFormat("onLuaClear id:%d",id));
5042     if(_pThis->m_tabbook->numChildren())
5043     {
5044         for(FXint i = 0; i < _pThis->m_tabbook->numChildren(); i+=2)
5045         {
5046             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass
5047                     && static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getID() == id)
5048             {
5049                 static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i))->clearChat();
5050                 return 1;
5051             }
5052         }
5053     }
5054     return  1;
5055 #else
5056     return 0;
5057 #endif //HAVE_LUA
5058 }
5059 
onLuaGetChannelNames(lua_State * lua)5060 int dxirc::onLuaGetChannelNames(lua_State *lua)
5061 {
5062 #ifdef HAVE_LUA
5063     FXString tab, server;
5064     if(lua_isstring(lua, 1)) tab = lua_tostring(lua, 1);
5065     if(lua_isstring(lua, 2)) server = lua_tostring(lua,2);
5066     if(_pThis->m_tabbook->numChildren())
5067     {
5068         for(FXint i = 0; i<_pThis->m_tabbook->numChildren(); i+=2)
5069         {
5070             if(_pThis->m_tabbook->childAtIndex(i)->getMetaClass()!=&TetrisTabItem::metaClass)
5071             {
5072                 if(comparecase(tab, static_cast<FXTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getText()) == 0
5073                     && comparecase(server, static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getServerName()) == 0
5074                     && static_cast<dxTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getType() == CHANNEL)
5075                 {
5076                     lua_newtable(lua);
5077                     dxStringArray names = static_cast<IrcTabItem*>(_pThis->m_tabbook->childAtIndex(i))->getNicks();
5078                     for(FXint j=0; j<names.no(); j++)
5079                     {
5080                         lua_pushnumber(lua, j+1);
5081                         lua_pushstring(lua, names[j].text());
5082                         lua_settable(lua, -3);
5083                     }
5084                     return 1;
5085                 }
5086             }
5087         }
5088         lua_pushnil(lua);
5089         return 1;
5090     }
5091     lua_pushnil(lua);
5092     return  1;
5093 #else
5094     return 0;
5095 #endif //HAVE_LUA
5096 }
5097 
5098 //show notify
showNotify(const FXString & notify,FXint pos)5099 void dxirc::showNotify(const FXString& notify, FXint pos)
5100 {
5101     if(dxUtils.haveNotify())
5102     {
5103         FXString exec;
5104         exec.format("notify-send -i %s/icons/big_dxirc.png dxirc '%s'", DXIRC_DATADIR, notify.text());
5105         system(exec.text());
5106     }
5107     else
5108     {
5109         if(!m_firstNotify)
5110         {
5111             m_firstNotify = true;
5112             m_notifiesHeight = 0;
5113         }
5114         if(pos<0 || pos>3) pos = m_preferences.m_notifyPosition;
5115         dxEXNotify *wnotify = new dxEXNotify(m_app, ICO_BIG, "dxirc", notify, m_notifiesHeight, 5000, m_preferences.m_appTheme.notifyfore, m_preferences.m_appTheme.notifyback);
5116         wnotify->notify(getX(), getY(), pos);
5117         getApp()->addTimeout(this, dxirc_NOTIFYHIDE, 5000);
5118         m_notifiesHeight += wnotify->getDefaultHeight()+4;
5119     }
5120 }
5121 
5122 
5123 #define USAGE_MSG _("\
5124 \nUsage: dxirc [options] \n\
5125 \n\
5126     [options] can be any of the following:\n\
5127 \n\
5128         -h, --help         Print (this) help screen and exit.\n\
5129         -v, --version      Print version information and exit.\n\
5130         -l [FILE]          Load configuration from FILE.\n\
5131         -i [PATH]          Use PATH for icons.\n\
5132 \n")
5133 
main(int argc,char * argv[])5134 int main(int argc,char *argv[])
5135 {
5136 #ifndef WIN32
5137     signal(SIGPIPE, SIG_IGN);
5138 #endif //WIN32
5139 
5140     argn = argc;
5141     args = argv;
5142 
5143     FXString datadir = DXIRC_DATADIR;
5144 
5145     for(FXint i=0; i<argc; ++i)
5146     {
5147         if(compare(argv[i],"-v")==0 || compare(argv[i],"--version")==0)
5148         {
5149             fprintf(stdout, "%s %s\n", PACKAGE, VERSION);
5150             exit(0);
5151         }
5152         if(compare(argv[i],"-h")==0 || compare(argv[i],"--help")==0)
5153         {
5154             fprintf(stdout, "%s", USAGE_MSG);
5155             exit(0);
5156         }
5157         if(compare(argv[i],"-l")==0)
5158         {
5159             dxUtils.setIniFile(argv[i+1]);
5160         }
5161         if(compare(argv[i],"-i")==0)
5162         {
5163             if(FXStat::exists(argv[i+1])) datadir = argv[i+1];
5164         }
5165     }
5166 
5167     if(dxUtils.getBoolIniEntry("SETTINGS", "oneinstance", FALSE))
5168         IsInstanceRunningAlready();
5169 
5170     dxUtils.loadAvailableSpellLangs();
5171 
5172 #ifdef HAVE_TRAY
5173     FXTrayApp app(PACKAGE, FXString::null);
5174 #else
5175     FXApp app(PACKAGE, FXString::null);
5176 #endif //HAVE_TRAY
5177     app.reg().setAsciiMode(TRUE);
5178     app.init(argc,argv);
5179 #ifdef ENABLE_NLS
5180     app.setTranslator(new dxTranslator(&app));
5181 #endif //ENABLE_NLS
5182     makeAllIcons(&app, dxUtils.getIniFile(), datadir);
5183     new dxirc(&app);
5184     app.create();
5185     dxUtils.loadAlias();
5186     return app.run();
5187 }
5188