1 //=============================================================================
2 //
3 // File : libkviwindow.cpp
4 // Creation date : Sat Sep 01 2001 17:13:12 CEST by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #include "UserWindow.h"
26
27 #include "KviModule.h"
28 #include "KviConsoleWindow.h"
29 #include "KviOptions.h"
30 #include "KviIrcSocket.h"
31 #include "KviMainWindow.h"
32 #include "KviLocale.h"
33 #include "KviApplication.h"
34 #include "KviError.h"
35 #include "KviIrcView.h"
36 #include "KviInput.h"
37 #include "KviIconManager.h"
38 #include "KviModuleManager.h"
39 #include "KviMemory.h"
40 #include "KviChannelWindow.h"
41
42 #include <QTimer>
43 #include <map>
44 #include <vector>
45
46 #ifdef COMPILE_CRYPT_SUPPORT
47 #include "KviCryptEngine.h"
48 #include "KviCryptController.h"
49 // KviApplication.cpp
50 extern KVIRC_API KviCryptEngineManager * g_pCryptEngineManager;
51 #endif
52
53 // KviApplication.cpp
54 extern KVIRC_API std::map<QString, KviWindow *> g_pGlobalWindowDict;
55 std::vector<UserWindow *> g_pUserWindowList;
56
57 // $window.caption $window.x $window.y $window.width $window.height $window.isActive $window.type
58 // $window.input.text $window.input.cursorpos $window.input.textlen
59
60 #define GET_KVS_WINDOW_ID \
61 QString szWnd; \
62 KviWindow * pWnd; \
63 KVSM_PARAMETERS_BEGIN(c) \
64 KVSM_PARAMETER("window_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szWnd) \
65 KVSM_PARAMETERS_END(c) \
66 if(c->parameterList()->count() == 0) \
67 { \
68 pWnd = c->window(); \
69 } \
70 else \
71 { \
72 pWnd = g_pApp->findWindow(szWnd.toUtf8().data()); \
73 if(!pWnd) \
74 { \
75 if(!c->hasSwitch('q', "quiet")) \
76 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data()); \
77 return true; \
78 } \
79 }
80
81 #define GET_KVS_FNC_WINDOW_ID \
82 QString szWnd; \
83 KviWindow * pWnd; \
84 KVSM_PARAMETERS_BEGIN(c) \
85 KVSM_PARAMETER("window_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szWnd) \
86 KVSM_PARAMETERS_END(c) \
87 if(c->parameterList()->count() == 0) \
88 { \
89 pWnd = c->window(); \
90 } \
91 else \
92 { \
93 pWnd = g_pApp->findWindow(szWnd.toUtf8().data()); \
94 if(!pWnd) \
95 return true; \
96 }
97
98 /*
99 @doc: window.clearOutput
100 @type:
101 command
102 @title:
103 window.clearOutput
104 @short:
105 Clears the output a window
106 @syntax:
107 window.clearOutput [-q] [window_id]
108 @switches:
109 !sw: -q | --quiet
110 Don't warn if the specified window doesn't exist. Just continue silently.
111 @description:
112 Clears the text output of the window specified by window_id. If window_id is missing then
113 the current window is used. If the window has no text output then no operation is performed.
114 If the specified window does not exist a warning is printed (unless the -q switch is used)
115 but the execution continues normally.
116 @seealso:
117 [fnc]$window.hasOutput[/fnc]
118 */
119
window_kvs_cmd_clearOutput(KviKvsModuleCommandCall * c)120 static bool window_kvs_cmd_clearOutput(KviKvsModuleCommandCall * c)
121 {
122 GET_KVS_WINDOW_ID
123 if(pWnd)
124 {
125 if(pWnd->view())
126 pWnd->view()->clearBuffer();
127 if(pWnd->type() == KviWindow::Channel)
128 {
129 KviChannelWindow * chan = (KviChannelWindow *)pWnd;
130 if(chan->messageView())
131 chan->messageView()->clearBuffer();
132 }
133 }
134 return true;
135 }
136
137 /*
138 @doc: window.close
139 @type:
140 command
141 @title:
142 window.close
143 @short:
144 Closes a window
145 @syntax:
146 window.close [-q] [window_id]
147 @description:
148 Closes the window specified by window_id. If window_id is missing then
149 the current window is closed. The close operation is asynchronous: it is
150 performed immediately after the script has terminated the execution and
151 the control is returned to the main KVIrc core. If the specified window
152 does not exist a warning is printed unless the -q switch is used.
153 */
154
window_kvs_cmd_close(KviKvsModuleCommandCall * c)155 static bool window_kvs_cmd_close(KviKvsModuleCommandCall * c)
156 {
157 GET_KVS_WINDOW_ID
158 if(pWnd)
159 {
160 pWnd->delayedClose();
161 }
162 return true;
163 }
164
165 /*
166 @doc: window.dock
167 @type:
168 command
169 @title:
170 window.dock
171 @short:
172 Docks a window
173 @syntax:
174 window.dock [-q] [window_id]
175 @description:
176 Docks the window specified by window_id. If window_id is missing then
177 the current window is docked. If the specified window was already docked then
178 no operation is performed. If the specified window
179 does not exist a warning is printed unless the -q switch is used.
180 @seealso:
181 [cmd]window.undock[/cmd], [fnc]$window.isDocked[/fnc]
182 */
183
window_kvs_cmd_dock(KviKvsModuleCommandCall * c)184 static bool window_kvs_cmd_dock(KviKvsModuleCommandCall * c)
185 {
186 GET_KVS_WINDOW_ID
187 if(pWnd)
188 {
189 pWnd->dock();
190 }
191 return true;
192 }
193
194 /*
195 @doc: window.undock
196 @type:
197 command
198 @title:
199 window.undock
200 @short:
201 Undocks a window
202 @syntax:
203 window.undock [-q] [window_id]
204 @description:
205 Undocks the window specified by window_id. If window_id is missing then
206 the current window is undocked. If the specified window was already undocked then
207 no operation is performed. If the specified window
208 does not exist a warning is printed unless the -q switch is used.
209 @seealso:
210 [cmd]window.dock[/cmd], [fnc]$window.isDocked[/fnc]
211 */
212
window_kvs_cmd_undock(KviKvsModuleCommandCall * c)213 static bool window_kvs_cmd_undock(KviKvsModuleCommandCall * c)
214 {
215 GET_KVS_WINDOW_ID
216 if(pWnd)
217 {
218 pWnd->undock();
219 }
220 return true;
221 }
222
223 /*
224 @doc: window.splitView
225 @type:
226 command
227 @title:
228 window.splitView
229 @short:
230 Splits the view of a channel window
231 @syntax:
232 window.splitView [-q] [window_id]
233 @description:
234 Splits the view of a channel specified by window_id. If window_id is missing then
235 the current window is split. If the specified window was already split then no
236 operation is performed. If the specified window does not exist or is not a channel
237 window then a warning is printed unless the -q switch is used.
238 @seealso:
239 [cmd]window.unsplitView[/cmd], [fnc]$window.isSplitView[/fnc]
240 */
241
window_kvs_cmd_splitView(KviKvsModuleCommandCall * c)242 static bool window_kvs_cmd_splitView(KviKvsModuleCommandCall * c)
243 {
244 GET_KVS_WINDOW_ID
245 if(pWnd && pWnd->type() == KviWindow::Channel)
246 {
247 KviChannelWindow * chan = (KviChannelWindow *)pWnd;
248 if(!chan->messageView())
249 chan->toggleDoubleView();
250 }
251 else
252 {
253 if(!c->hasSwitch('q', "quiet"))
254 c->warning(__tr2qs("The window with ID '%s' isn't a channel window."), szWnd.toUtf8().data());
255 }
256 return true;
257 }
258
259 /*
260 @doc: window.unsplitView
261 @type:
262 command
263 @title:
264 window.unsplitView
265 @short:
266 Unsplits the view of a channel window
267 @syntax:
268 window.splitView [-q] [window_id]
269 @description:
270 Unsplits the view of a channel specified by window_id. If window_id is missing then
271 the current window is unsplit. If the specified window wasn't already split then no
272 operation is performed. If the specified window does not exist or is not a channel
273 window then a warning is printed unless the -q switch is used.
274 @seealso:
275 [cmd]window.unsplitView[/cmd], [fnc]$window.isSplitView[/fnc]
276 */
277
window_kvs_cmd_unsplitView(KviKvsModuleCommandCall * c)278 static bool window_kvs_cmd_unsplitView(KviKvsModuleCommandCall * c)
279 {
280 GET_KVS_WINDOW_ID
281 if(pWnd && pWnd->type() == KviWindow::Channel)
282 {
283 KviChannelWindow * chan = (KviChannelWindow *)pWnd;
284 if(chan->messageView())
285 chan->toggleDoubleView();
286 }
287 else
288 {
289 if(!c->hasSwitch('q', "quiet"))
290 c->warning(__tr2qs("The window with ID '%s' isn't a channel window."), szWnd.toUtf8().data());
291 }
292 return true;
293 }
294
295 /*
296 @doc: window.activate
297 @type:
298 command
299 @title:
300 window.activate
301 @short:
302 Activates a window
303 @syntax:
304 window.activate [-q] [window_id]
305 @description:
306 Activates the window specified by window_id. If window_id is missing then
307 the current window is activated. If the specified window
308 does not exist a warning is printed unless the -q switch is used.
309 Please note that if the window is currently docked to a frame then this
310 command will [b]not[/b] raise the frame window. If you're interested in
311 the user's attention then you might be interested in [cmd]window.demandAttention[/cmd].
312 @seealso:
313 [cmd]window.demandAttention[/cmd]
314 */
315
window_kvs_cmd_activate(KviKvsModuleCommandCall * c)316 static bool window_kvs_cmd_activate(KviKvsModuleCommandCall * c)
317 {
318 GET_KVS_WINDOW_ID
319 if(pWnd)
320 {
321 pWnd->autoRaise();
322 }
323 return true;
324 }
325
326 /*
327 @doc: window.demandAttention
328 @type:
329 command
330 @title:
331 window.demandAttention
332 @short:
333 Flashes a window's system taskbar entry
334 @syntax:
335 window.demandAttention [-q] [window_id]
336 @description:
337 Flashes the system taskbar entry of the window
338 specified by the window_id. If window_id is missing then
339 the current window's system taskbar entry is flashed. If the specified window
340 does not exist a warning is printed unless the -q switch is used.
341 If the window is currently docked in a frame then the frame's
342 system taskbar entry will be flashed.
343 Please note that this command is highly system dependent:
344 on systems that do not have a system taskbar or there
345 is no way to flash an entry this command will do nothing.
346 At the time of writing this command works flawlessly on
347 Windows and in KDE compilations.
348 @seealso:
349 [cmd]window.demandAttention[/cmd]
350 */
351
window_kvs_cmd_demandAttention(KviKvsModuleCommandCall * c)352 static bool window_kvs_cmd_demandAttention(KviKvsModuleCommandCall * c)
353 {
354 GET_KVS_WINDOW_ID
355 if(pWnd)
356 {
357 pWnd->demandAttention();
358 }
359 return true;
360 }
361
362 /*
363 @doc: window.activityLevel
364 @type:
365 function
366 @title:
367 $window.activityLevel
368 @short:
369 Returns the current activity level of a window
370 @syntax:
371 $window.activityLevel
372 $window.activityLevel(<window_id>)
373 @description:
374 Returns the current activity level of the window specified by <window_id>.
375 The form without parameters works on the current window.[br]
376 The activity level is a number describing the level of traffic in the window
377 and depends on the window type. On channels and queries it is dependent on the number
378 and frequency of actions performed by the users.
379 @seealso:
380 [fnc]$window.activityTemperature[/fnc]
381 */
382
window_kvs_fnc_activityLevel(KviKvsModuleFunctionCall * c)383 static bool window_kvs_fnc_activityLevel(KviKvsModuleFunctionCall * c)
384 {
385 GET_KVS_FNC_WINDOW_ID
386 if(pWnd)
387 {
388 unsigned int v, t;
389 pWnd->activityMeter(&v, &t);
390 c->returnValue()->setInteger(v);
391 }
392 else
393 {
394 c->returnValue()->setInteger(0);
395 }
396 return true;
397 }
398
399 /*
400 @doc: window.activityTemperature
401 @type:
402 function
403 @title:
404 $window.activityTemperature
405 @short:
406 Returns the current activity temperature of a window
407 @syntax:
408 $window.activityTemperature
409 $window.activityTemperature(<window_id>)
410 @description:
411 Returns the current activity temperature of the window specified by <window_id>.
412 The form without parameters works on the current window.[br]
413 The activity temperature describes the type of traffic in the window and is
414 strictly related to the [fnc]$window.activityLevel[/fnc].[br]
415 On channels and queries the temperature describes the type of the actions
416 performed by the users. High temperatures denote more "human" behaviour (like
417 speaking to the channel, changing the topic etc...),
418 low temperatures denote automatic behaviours (like changing the channel limit
419 or mode: actions often performed by bots).[br]
420 @seealso:
421 [fnc]$window.activityLevel[/fnc]
422 */
423
window_kvs_fnc_activityTemperature(KviKvsModuleFunctionCall * c)424 static bool window_kvs_fnc_activityTemperature(KviKvsModuleFunctionCall * c)
425 {
426 GET_KVS_FNC_WINDOW_ID
427 if(pWnd)
428 {
429 unsigned int v, t;
430 pWnd->activityMeter(&v, &t);
431 c->returnValue()->setInteger(t);
432 }
433 else
434 {
435 c->returnValue()->setInteger(0);
436 }
437 return true;
438 }
439
440 /*
441 @doc: window.isDocked
442 @type:
443 function
444 @title:
445 $window.isDocked
446 @short:
447 Checks if a window is currently docked
448 @syntax:
449 $window.isDocked
450 $window.isDocked(<window_id>)
451 @description:
452 Returns [b]1[/b] if the window specified by <window_id> is currently docked and [b]0[/b] otherwise.
453 The form with no parameters works on the current window. If the specified window
454 doesn't exist then 0 is returned.
455 @seealso:
456 [cmd]window.dock[/cmd], [cmd]window.undock[/cmd]
457 */
458
window_kvs_fnc_isDocked(KviKvsModuleFunctionCall * c)459 static bool window_kvs_fnc_isDocked(KviKvsModuleFunctionCall * c)
460 {
461 GET_KVS_FNC_WINDOW_ID
462 if(pWnd)
463 {
464 c->returnValue()->setBoolean(pWnd->parentWidget() ? true : false);
465 }
466 return true;
467 }
468
469 /*
470 @doc: window.isSplitView
471 @type:
472 function
473 @title:
474 $window.isSplitView
475 @short:
476 Checks if a window is currently in split view mode
477 @syntax:
478 $window.isSplitView
479 $window.isSplitView(<window_id>)
480 @description:
481 Returns [b]1[/b] if the window specified by <window_id> is in split view mode and [b]0[/b] otherwise.
482 This is only intended to apply to channel windows. If the specified window doesn't exist
483 or is not a channel window then 0 is returned.
484 @seealso:
485 [cmd]window.splitView[/cmd], [cmd]window.unsplitView[/cmd]
486 */
window_kvs_fnc_isSplitView(KviKvsModuleFunctionCall * c)487 static bool window_kvs_fnc_isSplitView(KviKvsModuleFunctionCall * c)
488 {
489 c->returnValue()->setBoolean(false);
490 GET_KVS_FNC_WINDOW_ID
491 if(pWnd && pWnd->type() == KviWindow::Channel)
492 c->returnValue()->setBoolean(((KviChannelWindow *)pWnd)->messageView() ? true : false);
493 return true;
494 }
495
496 /*
497 @doc: window.hasInput
498 @type:
499 function
500 @title:
501 $window.hasInput
502 @short:
503 Checks if a window has an input field
504 @syntax:
505 $window.hasInput
506 $window.hasInput(<window_id>)
507 @description:
508 Returns [b]1[/b] if the window specified by <window_id> has an input field and [b]0[/b] otherwise.
509 The form with no parameters works on the current window. If the specified window
510 doesn't exist then 0 is returned.
511 @seealso:
512 [fnc]$window.hasOutput[/fnc]
513 */
514
window_kvs_fnc_hasInput(KviKvsModuleFunctionCall * c)515 static bool window_kvs_fnc_hasInput(KviKvsModuleFunctionCall * c)
516 {
517 GET_KVS_FNC_WINDOW_ID
518 if(pWnd)
519 {
520 c->returnValue()->setBoolean(pWnd->input() ? true : false);
521 }
522 else
523 c->returnValue()->setBoolean(false);
524 return true;
525 }
526
527 /*
528 @doc: window.hasUserFocus
529 @type:
530 function
531 @title:
532 $window.hasUserFocus
533 @short:
534 Checks if a window has the user focus
535 @syntax:
536 $window.hasUserFocus
537 $window.hasUserFocus(<window_id>)
538 @description:
539 Returns [b]1[/b] if the window specified by <window_id> has
540 currently the user focus and [b]0[/b] otherwise.
541 The form with no parameters works on the current window.
542 If the specified window doesn't exist then 0 is returned.
543 A window has the user focus if it is the KVIrc's active
544 window and has the user's input focus (i.e. typing
545 on the keyboard will write in this window).
546 @seealso:
547 */
548
window_kvs_fnc_hasUserFocus(KviKvsModuleFunctionCall * c)549 static bool window_kvs_fnc_hasUserFocus(KviKvsModuleFunctionCall * c)
550 {
551 GET_KVS_FNC_WINDOW_ID
552 if(pWnd)
553 {
554 bool b = (pWnd == g_pActiveWindow) && pWnd->isActiveWindow();
555 c->returnValue()->setBoolean(b ? true : false);
556 }
557 else
558 c->returnValue()->setBoolean(false);
559 return true;
560 }
561
562 /*
563 @doc: window.console
564 @type:
565 function
566 @title:
567 $window.console
568 @short:
569 Returns the console that a window is attached to
570 @syntax:
571 $window.console
572 $window.console(<window_id>)
573 @description:
574 Returns the ID of the console window that the window specified by window_id is attached to.
575 The console is the main (and only) console of the IRC context. If window_id is missing then
576 the current window is used. If this window does not belong to an IRC context (and thus has
577 no attached console) then 0 is returned.
578 @seealso:
579 */
580
window_kvs_fnc_console(KviKvsModuleFunctionCall * c)581 static bool window_kvs_fnc_console(KviKvsModuleFunctionCall * c)
582 {
583 GET_KVS_FNC_WINDOW_ID
584 if(pWnd)
585 {
586 c->returnValue()->setInteger(pWnd->console() ? QString(pWnd->console()->id()).toInt() : 0);
587 }
588 return true;
589 }
590
591 /*
592 @doc: window.hasOutput
593 @type:
594 function
595 @title:
596 $window.hasOutput
597 @short:
598 Checks if a window has a text output widget
599 @syntax:
600 $window.hasOutput
601 $window.hasOutput(<window_id>)
602 @description:
603 Returns [b]1[/b] if the window specified by <window_id> has a text output widget and [b]0[/b] otherwise.
604 The form with no parameters works on the current window. If the specified window
605 doesn't exist then 0 is returned.
606 @seealso:
607 [fnc]$window.hasInput[/fnc]
608 */
609
window_kvs_fnc_hasOutput(KviKvsModuleFunctionCall * c)610 static bool window_kvs_fnc_hasOutput(KviKvsModuleFunctionCall * c)
611 {
612 GET_KVS_FNC_WINDOW_ID
613 if(pWnd)
614 {
615 c->returnValue()->setBoolean(pWnd->view() ? true : false);
616 }
617 else
618 c->returnValue()->setBoolean(false);
619 return true;
620 }
621
622 /*
623 @doc: window.exists
624 @type:
625 function
626 @title:
627 $window.exists
628 @short:
629 Checks for the existence of a window
630 @syntax:
631 $window.exists(<window_id>)
632 @description:
633 Returns 1 if a specified window exists
634 @seealso:
635 */
636
window_kvs_fnc_exists(KviKvsModuleFunctionCall * c)637 static bool window_kvs_fnc_exists(KviKvsModuleFunctionCall * c)
638 {
639 GET_KVS_FNC_WINDOW_ID
640 if(pWnd)
641 {
642 c->returnValue()->setBoolean(true);
643 }
644 else
645 c->returnValue()->setBoolean(false);
646 return true;
647 }
648
649 /*
650 @doc: window.highlight
651 @type:
652 command
653 @title:
654 window.highlight
655 @short:
656 Sets the highlight (alert) level of a window
657 @syntax:
658 window.highlight [-q] <level> [window_id]
659 @switches:
660 !sw: -q | --quiet
661 Be quiet
662 @description:
663 Sets the highlight the user window specified by [window_id] to <level>.[br]
664 If <window_id> is an empty string then the current window is assumed.[br]
665 If the specified window does not exist a warning is printed unless the -q switch is used.[br]
666 For more infos on this feature read the documentation about [fnc]$window.highlightLevel[/fnc].
667 @seealso:
668 [fnc]$window.highlightLevel[/fnc]
669 */
670
window_kvs_cmd_highlight(KviKvsModuleCommandCall * c)671 static bool window_kvs_cmd_highlight(KviKvsModuleCommandCall * c)
672 {
673 QString szWnd;
674 KviWindow * pWnd;
675 kvs_uint_t level;
676
677 KVSM_PARAMETERS_BEGIN(c)
678 KVSM_PARAMETER("level", KVS_PT_UINT, 0, level)
679 KVSM_PARAMETER("window_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szWnd)
680 KVSM_PARAMETERS_END(c)
681 if(c->parameterList()->count() == 1)
682 {
683 pWnd = c->window();
684 }
685 else
686 {
687 pWnd = g_pApp->findWindow(szWnd.toUtf8().data());
688 if(!pWnd)
689 {
690 if(!c->hasSwitch('q', "quiet"))
691 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data());
692 return true;
693 }
694 }
695
696 //force the previous level to be lower
697 pWnd->unhighlight();
698 //level boundaries checking is done by the upstream function
699 pWnd->highlightMe(level);
700 return true;
701 }
702
703 /*
704 @doc: window.highlightLevel
705 @type:
706 function
707 @title:
708 $window.highlightLevel
709 @short:
710 Returns the current highlight (alert) level of a window
711 @syntax:
712 $window.highlightLevel
713 $window.highlightLevel(<window_id>)
714 @description:
715 Every window has a current alert level; it corresponds to an highlight color of that window in the window list.
716 There are 6 defined levels, they start from 0 (normal) to 5 (max alarm level). The classic window list and the tree window list use different colors to represent these levels. Classic task bar uses options:
717 [ul][li]colorWindowListNormalText : normal state[/li][li]colorWindowListHighlight1Text : highlight state 1[/li][li]...[/li][li]colorWindowListHighlight5Text : highlight state 5[/li][/ul]
718 While the tree window list uses options:
719 [ul][li]colorTreeWindowListForeground : normal state[/li][li]colorTreeWindowListHighlight1Foreground : highlight state 1[/li][li]...[/li][li]colorTreeWindowListHighlight5Foreground : highlight state 5[/li][/ul]
720 You can use [fnc]$option[/fnc] to read these options and the [cmd]option[/cmd] command to set them.
721 @seealso:
722 [fnc]$window.activityTemperature[/fnc]
723 [fnc]$window.activityLevel[/fnc]
724 [fnc]$option[/fnc]
725 [cmd]option[/cmd]
726 */
727
window_kvs_fnc_highlightLevel(KviKvsModuleFunctionCall * c)728 static bool window_kvs_fnc_highlightLevel(KviKvsModuleFunctionCall * c)
729 {
730 GET_KVS_FNC_WINDOW_ID
731 if(pWnd)
732 {
733 unsigned int v;
734 pWnd->highlightMeter(&v);
735 c->returnValue()->setInteger(v);
736 }
737 else
738 {
739 c->returnValue()->setInteger(0);
740 }
741 return true;
742 }
743
744 /*
745 @doc: window.type
746 @type:
747 function
748 @title:
749 $window.type
750 @short:
751 Returns the type of a window
752 @syntax:
753 $window.type
754 $window.type(<window_id>)
755 @description:
756 Returns the type of the window with <window_id>.[br]
757 The form with no parameters returns the type of the current window.[br]
758 If the window with the specified ID does not exist, an empty string is returned.[br]
759 @seealso:
760 */
761
window_kvs_fnc_type(KviKvsModuleFunctionCall * c)762 static bool window_kvs_fnc_type(KviKvsModuleFunctionCall * c)
763 {
764 GET_KVS_FNC_WINDOW_ID
765 if(pWnd)
766 {
767 c->returnValue()->setString(pWnd->typeString());
768 }
769 return true;
770 }
771
772 /*
773 @doc: window.context
774 @type:
775 function
776 @title:
777 $window.context
778 @short:
779 Returns the IRC context of a window
780 @syntax:
781 $window.context
782 $window.context(<window_id>)
783 @description:
784 Returns the IRC context of the window with the specified <window_id>.[br]
785 The form with no parameters returns the IRC context of the current window.[br]
786 If the window with the specified ID does not exist, an empty string is returned.[br]
787 @seealso:
788 */
789
window_kvs_fnc_context(KviKvsModuleFunctionCall * c)790 static bool window_kvs_fnc_context(KviKvsModuleFunctionCall * c)
791 {
792 GET_KVS_FNC_WINDOW_ID
793 if(pWnd)
794 {
795 c->returnValue()->setInteger(pWnd->context() ? pWnd->context()->id() : 0);
796 }
797 return true;
798 }
799
800 /*
801 @doc: window.caption
802 @type:
803 function
804 @title:
805 $window.caption
806 @short:
807 Returns the caption of a window
808 @syntax:
809 $window.caption
810 $window.caption(<window_id>)
811 @description:
812 Returns the caption of the window with <window_id>.[br]
813 The form with no parameters returns the caption of the current window.[br]
814 If the window with the specified ID does not exist, an empty string is returned.[br]
815 @seealso:
816 */
817
window_kvs_fnc_caption(KviKvsModuleFunctionCall * c)818 static bool window_kvs_fnc_caption(KviKvsModuleFunctionCall * c)
819 {
820 GET_KVS_FNC_WINDOW_ID
821 if(pWnd)
822 {
823 c->returnValue()->setString(pWnd->plainTextCaption());
824 }
825 return true;
826 }
827
828 /*
829 @doc: window.listtypes
830 @type:
831 command
832 @title:
833 window.listtypes
834 @short:
835 Lists available types of windows
836 @syntax:
837 window.listtypes
838 @description:
839 Lists the types of windows that are built in the current release of KVIrc.[br]
840 This is actually a command and not a static list just because new window
841 types may be added in subsequent releases.[br]
842 @seealso:
843 [cmd]window.listtypes[/cmd]
844 */
845
window_kvs_cmd_listtypes(KviKvsModuleCommandCall * c)846 static bool window_kvs_cmd_listtypes(KviKvsModuleCommandCall * c)
847 {
848 c->window()->listWindowTypes();
849 return true;
850 }
851
852 /*
853 @doc: window.list
854 @type:
855 function
856 @title:
857 $window.list
858 @short:
859 Generates lists of windows
860 @syntax:
861 $window.list(<type>[,<irc_context_id>])
862 @description:
863 Returns an array of window identifiers with a specified type and eventually belonging to a specified
864 irc context.[br]
865 <type> is a window type such as 'query' or 'channel'.[br]
866 See [cmd]window.listtypes[/cmd] for a list of available window types in this KVIrc release.[br]
867 If <type> is the special word 'all', all the window types are listed.[br]
868 <irc_context_id> specifies the IRC context in which the windows are searched.[br]
869 If no <irc_context_id> is specified, the current one is used.[br]
870 If <irc_context_id> is the special word 'all', all the IRC context are searched.[br]
871 If <irc_context_id> is the special word 'none' then only windows not belonging to any
872 irc context are listed.[br]
873 The special word 'any' used as <irc_context_id> merges the effects of 'all' and 'none'
874 by searching all the IRC contexts AND the windows not belonging to any IRC context.[br]
875 The windows that do not belong to any IRC context (such as DCC windows), must be searched
876 by using 'none' or 'any' as <irc_context_id>.
877 @examples:
878 [example]
879 [comment]# List all the queries of the current IRC context[/comment]
880 [cmd]echo[/cmd] $window.list(query)
881 [comment]# Equivalent to the above[/comment]
882 [cmd]echo[/cmd] $window.list(query,[fnc]$ic[/fnc])
883 [comment]# List all the channels in all the IRC contexts[/comment]
884 [cmd]echo[/cmd] $window.list(channel,all)
885 [comment]# List all the windows in the current IRC context[/comment]
886 [cmd]echo[/cmd] $window.list(all)
887 [comment]# List all the windows in all IRC contexts[/comment]
888 [cmd]echo[/cmd] $window.list(all,all)
889 [comment]# List all the DCC Send windows: They don't belong to any IRC context[/comment]
890 [cmd]echo[/cmd] $window.list(dcctransfer,none)
891 [comment]# List all the user windows created with $window.open[/comment]
892 [comment]# They may either belong to an IRC context or not[/comment]
893 [cmd]echo[/cmd] $window.list(userwnd,any)
894 [comment]# Ok, let's use it[/comment]
895 [comment]# A nice alias that allows iterating commands through all the consoles[/comment]
896 [comment]# Note the array returned by $window.list[/comment]
897 [comment]# This is by LatinSuD :)[/comment]
898 [cmd]alias[/cmd](iterate)
899 {
900 %ctxt[]=[fnc]$window.list[/fnc](console,all)
901 [cmd]for[/cmd](%i=0;%i<%ctxt[]#;%i++)
902 {
903 [cmd]eval[/cmd] -r=%ctxt[%i] $0-
904 }
905 }
906 iterate [cmd]echo[/cmd] Hi ppl! :)
907 [comment]# The returned array works nicely also in [cmd]foreach[/cmd][/comment]
908 [comment]# Say hi to all the channels :)[/comment]
909 [cmd]alias[/cmd](sayallchans)
910 {
911 [cmd]foreach[/cmd](%x,[fnc]$window.list[/fnc](channel,all))
912 [cmd]say[/cmd] -r=%x $0-;
913 }
914 sayallchans Hi ppl :)
915 [/example]
916 @seealso:
917 [cmd]window.listtypes[/cmd]
918 */
919
window_kvs_fnc_list(KviKvsModuleFunctionCall * c)920 static bool window_kvs_fnc_list(KviKvsModuleFunctionCall * c)
921 {
922 QString szType;
923 QString szContext;
924
925 KVSM_PARAMETERS_BEGIN(c)
926 KVSM_PARAMETER("type", KVS_PT_STRING, 0, szType)
927 KVSM_PARAMETER("irc_context_id", KVS_PT_STRING, KVS_PF_OPTIONAL, szContext)
928 KVSM_PARAMETERS_END(c)
929 KviKvsArray * pArray = new KviKvsArray();
930 c->returnValue()->setArray(pArray);
931
932 if(szType.isEmpty())
933 {
934 c->warning(__tr2qs("Window type or 'all' expected as first parameter"));
935 return true;
936 }
937
938 int id = 0;
939
940 if(KviQString::equalCI(szContext, "all"))
941 {
942 // all contexts but no "no_context" windows
943 bool bAllWindows = KviQString::equalCI(szType, "all");
944
945 for(auto & wnd : g_pGlobalWindowDict)
946 {
947 if(wnd.second->context())
948 {
949 if(bAllWindows)
950 {
951 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
952 id++;
953 }
954 else
955 {
956 if(szType.toLower() == wnd.second->typeString())
957 {
958 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
959 id++;
960 }
961 }
962 }
963 }
964 }
965 else if(KviQString::equalCI(szContext, "any"))
966 {
967 // all contexts and also "no_context" windows
968 bool bAllWindows = KviQString::equalCI(szType.toLower(), "all");
969
970 for(auto & wnd : g_pGlobalWindowDict)
971 {
972 if(bAllWindows)
973 {
974 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
975 id++;
976 }
977 else
978 {
979 if(szType.toLower() == wnd.second->typeString())
980 {
981 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
982 id++;
983 }
984 }
985 }
986 }
987 else if(KviQString::equalCI(szContext, "none"))
988 {
989 // only "no_context" windows
990 bool bAllWindows = KviQString::equalCI(szType.toLower(), "all");
991
992 for(auto & wnd : g_pGlobalWindowDict)
993 {
994 if(!wnd.second->context())
995 {
996 if(bAllWindows)
997 {
998 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
999 id++;
1000 }
1001 else
1002 {
1003 if(szType.toLower() == wnd.second->typeString())
1004 {
1005 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
1006 id++;
1007 }
1008 }
1009 }
1010 }
1011 }
1012 else
1013 {
1014 // some specified context
1015 unsigned int uId = 0;
1016
1017 if(!szContext.isEmpty())
1018 {
1019 // specific context
1020 bool bOk;
1021 uId = szContext.toUInt(&bOk);
1022 if(!bOk)
1023 {
1024 c->warning(__tr2qs("Invalid IRC context ID '%Q'"), &szContext);
1025 return true;
1026 }
1027 }
1028 else
1029 {
1030 // current irc context
1031 if(!c->window()->console())
1032 {
1033 return true;
1034 }
1035 uId = c->window()->context()->id();
1036 }
1037
1038 bool bAllWindows = KviQString::equalCI(szType.toLower(), "all");
1039
1040 for(auto & wnd : g_pGlobalWindowDict)
1041 {
1042 if(wnd.second->context())
1043 {
1044 if(wnd.second->context()->id() == uId)
1045 {
1046 if(bAllWindows)
1047 {
1048 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
1049 id++;
1050 }
1051 else
1052 {
1053 if(szType.toLower() == wnd.second->typeString())
1054 {
1055 pArray->set(id, new KviKvsVariant(QString(wnd.second->id())));
1056 id++;
1057 }
1058 }
1059 }
1060 }
1061 }
1062 }
1063 return true;
1064 }
1065
1066 /*
1067 @doc: window.open
1068 @type:
1069 function
1070 @title:
1071 $window.open
1072 @short:
1073 Creates and opens a new window
1074 @syntax:
1075 $window.open([<flags:string>[,<caption:string>[,<irc_context:integer>[,<icon:integer>]]]])
1076 @description:
1077 Creates a new window, opens it and returns its window identifier.
1078 <flags> may be any combination of the following flag characters:[br]
1079 [b]i[/b]: Causes the window to have an input field in that
1080 the user can type commands or text. The text typed is reported
1081 by the [event:ontextinput]OnTextInput[/event] event.[br]
1082 [b]m[/b]: Creates a window that is initially minimized.[br]
1083 [b]q[/b]: Don't print warning messages during the creation.[br]
1084 If <caption> is given then the new window will have it as the initial plain text <caption>.
1085 You can change the caption later by calling [cmd]window.setWindowTitle[/cmd].[br]
1086 If <irc_context> is given then the new window is bound to the specified IRC context
1087 and will be destroyed when the attached console closes.
1088 If <irc_context> is omitted or is 0 then the window will be context free (not bound
1089 to any context) and will exist until it is closed by the GUI, by a [cmd]window.close[/cmd]
1090 call or until KVIrc terminates. When <irc_context> is given but is not valid
1091 then a warning is printed (unless the q flag is used) and the created window is context free.[br]
1092 You will generally use the [fnc]$context[/fnc] function to retrieve the current IRC context ID.[br]
1093 [br]
1094 <icon> is interpreted as the index of the internal icon to be used
1095 for the window. If <icon> is omitted then a default icon is used.[br]
1096 @examples:
1097 [example]
1098 %w = $window.open()
1099 [cmd]window.close[/cmd] %w
1100 %w = $window.open("m","My funky window")
1101 [cmd]window.close[/cmd] %w
1102 %w = $window.open("im","My funky window 2",$context,10)
1103 [/example]
1104 @seealso:
1105 [cmd]window.close[/cmd]
1106 */
1107
window_kvs_fnc_open(KviKvsModuleFunctionCall * c)1108 static bool window_kvs_fnc_open(KviKvsModuleFunctionCall * c)
1109 {
1110 QString szFlags;
1111 QString szCaption;
1112 kvs_uint_t uCtx;
1113 QString szIcon;
1114
1115 KVSM_PARAMETERS_BEGIN(c)
1116 KVSM_PARAMETER("flags", KVS_PT_STRING, KVS_PF_OPTIONAL, szFlags)
1117 KVSM_PARAMETER("caption", KVS_PT_STRING, KVS_PF_OPTIONAL, szCaption)
1118 KVSM_PARAMETER("irc_context", KVS_PT_UINT, KVS_PF_OPTIONAL, uCtx)
1119 KVSM_PARAMETER("icon", KVS_PT_STRING, KVS_PF_OPTIONAL, szIcon)
1120 KVSM_PARAMETERS_END(c)
1121 QPixmap * pPix = g_pIconManager->getImage(szIcon);
1122 if(!pPix)
1123 {
1124
1125 c->warning(__tr2qs("The specified icon doesn't exist: switching to 'none'"));
1126 szIcon.prepend("$icon(");
1127 szIcon.append(")");
1128 }
1129 int iFlags = 0;
1130 if(szFlags.contains('i'))
1131 iFlags |= UserWindow::HasInput;
1132
1133 KviConsoleWindow * pConsole = nullptr;
1134 if(c->parameterList()->count() >= 3)
1135 {
1136 pConsole = g_pApp->findConsole(uCtx);
1137 if(!pConsole && !szFlags.contains('q'))
1138 {
1139 c->warning(__tr2qs("The specified IRC context is not valid: creating a context free window"));
1140 }
1141 }
1142
1143 UserWindow * pWnd = new UserWindow(
1144 szCaption.toUtf8().data(),
1145 szIcon,
1146 pConsole,
1147 iFlags);
1148
1149 g_pMainWindow->addWindow(pWnd, !szFlags.contains('m'));
1150
1151 c->returnValue()->setInteger(QString(pWnd->id()).toUInt());
1152 return true;
1153 }
1154
1155 /*
1156 @doc: window.setWindowTitle
1157 @type:
1158 command
1159 @title:
1160 window.setWindowTitle
1161 @short:
1162 Sets the caption of a user window
1163 @syntax:
1164 window.setWindowTitle [-q] <window_id> <plain_text_caption>
1165 @switches:
1166 !sw: -q | --quiet
1167 Be quiet
1168 @description:
1169 Sets the caption of the user window specified by <window_id> to <plain_text_caption>.[br]
1170 If <window_id> is an empty string then the current window is assumed.[br]
1171 If the window does not exist then a warning is printed unless the -q switch is used.[br]
1172 @seealso:
1173 */
1174
window_kvs_cmd_setWindowTitle(KviKvsModuleCommandCall * c)1175 static bool window_kvs_cmd_setWindowTitle(KviKvsModuleCommandCall * c)
1176 {
1177 QString szWnd;
1178 QString szPlain;
1179 KviWindow * pWnd;
1180 KVSM_PARAMETERS_BEGIN(c)
1181 KVSM_PARAMETER("window_id", KVS_PT_STRING, 0, szWnd)
1182 KVSM_PARAMETER("plain_text_caption", KVS_PT_STRING, 0, szPlain)
1183 KVSM_PARAMETERS_END(c)
1184
1185 pWnd = g_pApp->findWindow(szWnd.toUtf8().data());
1186 if(!pWnd)
1187 {
1188 if(!c->hasSwitch('q', "quiet"))
1189 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data());
1190 return true;
1191 }
1192
1193 if(pWnd->type() == KviWindow::UserWindow)
1194 {
1195 ((UserWindow *)pWnd)->setWindowTitleStrings(szPlain);
1196 }
1197 else
1198 {
1199 //store the window title (needed for functions that search windows by their captions)
1200 ((KviWindow *)pWnd)->setFixedCaption(szPlain);
1201 ((KviWindow *)pWnd)->setWindowTitle(szPlain);
1202 }
1203 return true;
1204 }
1205
1206 /*
1207 @doc: window.setInputText
1208 @type:
1209 command
1210 @title:
1211 window.setInputText
1212 @short:
1213 Sets the window input text to <text>
1214 @syntax:
1215 window.setInputText [-q] <window_id:integer> <text:string>
1216 @switches:
1217 !sw: -q | --quiet
1218 Be quiet
1219 @description:
1220 Sets the window input text to <text>
1221 @seealso:
1222 [cmd]window.setInputText[/cmd] [cmd]window.insertInInputText[/cmd] [fnc]$window.inputText[/fnc]
1223 */
1224
window_kvs_cmd_setInputText(KviKvsModuleCommandCall * c)1225 static bool window_kvs_cmd_setInputText(KviKvsModuleCommandCall * c)
1226 {
1227 QString szWnd;
1228 QString szText;
1229 KviWindow * pWnd;
1230 KVSM_PARAMETERS_BEGIN(c)
1231 KVSM_PARAMETER("window_id", KVS_PT_STRING, 0, szWnd)
1232 KVSM_PARAMETER("text", KVS_PT_STRING, 0, szText)
1233 KVSM_PARAMETERS_END(c)
1234
1235 pWnd = g_pApp->findWindow(szWnd.toUtf8().data());
1236 if(!pWnd)
1237 {
1238 if(!c->hasSwitch('q', "quiet"))
1239 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data());
1240 return true;
1241 }
1242 if(pWnd->input())
1243 pWnd->input()->setText(szText);
1244 else if(!c->hasSwitch('q', "quiet"))
1245 c->warning(__tr2qs("Window doesn't have input widget"));
1246
1247 return true;
1248 }
1249
1250 /*
1251 @doc: window.insertInInputText
1252 @type:
1253 command
1254 @title:
1255 window.insertInInputText
1256 @short:
1257 Sets the window input text to <text>
1258 @syntax:
1259 window.insertInInputText [-q] <window_id:integer> <text:string>
1260 @switches:
1261 !sw: -q | --quiet
1262 Be quiet
1263 @description:
1264 Sets the window input text to <text>
1265 @seealso:
1266 [cmd]window.setInputText[/cmd], [fnc]$window.inputText[/fnc]
1267 */
1268
window_kvs_cmd_insertInInputText(KviKvsModuleCommandCall * c)1269 static bool window_kvs_cmd_insertInInputText(KviKvsModuleCommandCall * c)
1270 {
1271 QString szWnd;
1272 QString szText;
1273 KviWindow * pWnd;
1274 KVSM_PARAMETERS_BEGIN(c)
1275 KVSM_PARAMETER("window_id", KVS_PT_STRING, 0, szWnd)
1276 KVSM_PARAMETER("text", KVS_PT_STRING, 0, szText)
1277 KVSM_PARAMETERS_END(c)
1278
1279 pWnd = g_pApp->findWindow(szWnd.toUtf8().data());
1280 if(!pWnd)
1281 {
1282 if(!c->hasSwitch('q', "quiet"))
1283 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data());
1284 return true;
1285 }
1286 if(pWnd->input())
1287 pWnd->input()->insertText(szText);
1288 else if(!c->hasSwitch('q', "quiet"))
1289 c->warning(__tr2qs("Window doesn't have input widget"));
1290
1291 return true;
1292 }
1293
1294 /*
1295 @doc: $window.inputText
1296 @type:
1297 function
1298 @title:
1299 $window.inputText
1300 @short:
1301 Returns the window input line text
1302 @syntax:
1303 $window.inputText(<window_id:integer>)
1304 @description:
1305 Returns the window input line text
1306 @seealso:
1307 [cmd]window.setInputText[/cmd],
1308 [cmd]window.insertInInputText[/cmd]
1309 */
1310
window_kvs_fnc_inputText(KviKvsModuleFunctionCall * c)1311 static bool window_kvs_fnc_inputText(KviKvsModuleFunctionCall * c)
1312 {
1313 GET_KVS_FNC_WINDOW_ID
1314 if(pWnd)
1315 {
1316 if(pWnd->input())
1317 c->returnValue()->setString(pWnd->input()->text());
1318 }
1319 return true;
1320 }
1321
1322 /*
1323 @doc: window.setBackground
1324 @type:
1325 command
1326 @title:
1327 window.setBackground
1328 @short:
1329 Sets the background image of a window
1330 @syntax:
1331 window.setBackground [-q] <window_id:integer> [image_id:string]
1332 @switches:
1333 !sw: -q | --quiet
1334 Be quiet
1335 @description:
1336 Sets the background image of the window specified by <window_id> to <image_id>.[br]
1337 If <image_id> is not provided, then the background is cleared and reset to global setting.[br]
1338 If the specified window or the background image does not exist a warning is printed unless the -q switch is used.
1339 @seealso:
1340 */
1341
window_kvs_cmd_setBackground(KviKvsModuleCommandCall * c)1342 static bool window_kvs_cmd_setBackground(KviKvsModuleCommandCall * c)
1343 {
1344 QString szWnd;
1345 QString szBackground;
1346 KVSM_PARAMETERS_BEGIN(c)
1347 KVSM_PARAMETER("window_id", KVS_PT_STRING, 0, szWnd)
1348 KVSM_PARAMETER("background_path", KVS_PT_STRING, KVS_PF_OPTIONAL, szBackground)
1349 KVSM_PARAMETERS_END(c)
1350
1351 KviWindow * pWnd = g_pApp->findWindow(szWnd.toUtf8().data());
1352 if(!pWnd)
1353 {
1354 if(!c->hasSwitch('q', "quiet"))
1355 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data());
1356 return true;
1357 }
1358
1359 if(!pWnd->view())
1360 {
1361 if(!c->hasSwitch('q', "quiet"))
1362 c->warning(__tr2qs("The window with ID '%s' does not support background images!"));
1363 return true;
1364 }
1365
1366 QPixmap p;
1367 if(!szBackground.isEmpty())
1368 {
1369 p = QPixmap(szBackground);
1370 if(p.isNull())
1371 {
1372 if(!c->hasSwitch('q', "quiet"))
1373 c->warning(__tr2qs("Failed to load the selected image!"));
1374 return true;
1375 }
1376 }
1377
1378 pWnd->view()->setPrivateBackgroundPixmap(p);
1379 if(pWnd->isChannel())
1380 {
1381 KviChannelWindow * pChanWin = (KviChannelWindow *)pWnd;
1382 if(pChanWin->messageView())
1383 pChanWin->messageView()->setPrivateBackgroundPixmap(p);
1384 }
1385
1386 return true;
1387 }
1388
1389 /*
1390 @doc: window.savePropertiesAsDefault
1391 @type:
1392 command
1393 @title:
1394 window.savePropertiesAsDefault
1395 @short:
1396 Saves the window properties as default
1397 @syntax:
1398 window.savePropertiesAsDefault [window_id]
1399 @description:
1400 Saves the window properties of the specified window as default for every window
1401 of the same type (e.g. all queries, all channels, ..).
1402 If window_id is missing then the current window properties are used.
1403 */
1404
window_kvs_cmd_savePropertiesAsDefault(KviKvsModuleCommandCall * c)1405 static bool window_kvs_cmd_savePropertiesAsDefault(KviKvsModuleCommandCall * c)
1406 {
1407 GET_KVS_WINDOW_ID
1408 if(pWnd)
1409 {
1410 pWnd->savePropertiesAsDefault();
1411 }
1412 return true;
1413 }
1414
1415 #ifdef COMPILE_CRYPT_SUPPORT
initializeCryptEngine(KviCryptEngine * eng,KviCString & szEncryptKey,KviCString & szDecryptKey,QString & szError)1416 static bool initializeCryptEngine(KviCryptEngine * eng, KviCString & szEncryptKey, KviCString & szDecryptKey, QString & szError)
1417 {
1418 char * encKey = nullptr;
1419
1420 char * tmpKey;
1421 int encKeyLen = szEncryptKey.hexToBuffer(&tmpKey, false);
1422 if(encKeyLen > 0)
1423 {
1424 encKey = (char *)KviMemory::allocate(encKeyLen);
1425 KviMemory::move(encKey, tmpKey, encKeyLen);
1426 KviCString::freeBuffer(tmpKey);
1427 }
1428 else
1429 {
1430 szError = __tr2qs("The encryption key wasn't a valid hexadecimal string");
1431 return false;
1432 }
1433
1434 char * decKey = nullptr;
1435
1436 int decKeyLen = szDecryptKey.hexToBuffer(&tmpKey, false);
1437 if(decKeyLen > 0)
1438 {
1439 decKey = (char *)KviMemory::allocate(decKeyLen);
1440 KviMemory::move(decKey, tmpKey, decKeyLen);
1441 KviCString::freeBuffer(tmpKey);
1442 }
1443 else
1444 {
1445 szError = __tr2qs("The decryption key wasn't a valid hexadecimal string");
1446 if(encKey)
1447 KviMemory::free(encKey);
1448 return false;
1449 }
1450 bool bRet = eng->init(encKey, encKeyLen, decKey, decKeyLen);
1451 if(!bRet)
1452 szError = eng->lastError();
1453 if(encKey)
1454 KviMemory::free(encKey);
1455 if(decKey)
1456 KviMemory::free(decKey);
1457 return bRet;
1458 }
1459 #endif
1460
1461 /*
1462 @doc: window.setCryptEngine
1463 @type:
1464 command
1465 @title:
1466 window.setCryptEngine
1467 @short:
1468 Sets the crypt engine for a window that supports it
1469 @syntax:
1470 window.setCryptEngine [-q] [-n] [-m] <window_id:integer> <enginename:string> <hex_encrypt_key:string> [hex_decrypt_key:string]
1471 @switches:
1472 !sw: -q | --quiet
1473 Be quiet: do echo the raw data.
1474 !sw: -n | --onlydecrypt
1475 Disables encryption
1476 !sw: -m | --onlyencrypt
1477 Disables decryption
1478 @description:
1479 Sets the specified [doc:crypt_engines]cryptographic engine[/doc] for the window. If <enginename> is empty
1480 then any current encryption engine is removed (i.e. encrypting is disabled).
1481 The must be both expressed in hexadecimal notation and are internally transformed in bytes.
1482 If only the encrypt key is specified then it will be used for both encrypting and
1483 decrypting. This command works only if cryptography support is compiled in.
1484 @examples:
1485 [example]
1486 [comment]# This is a really lame example :D[/comment]
1487 alias(saylame)
1488 {
1489 window.setCryptEngine $window Lamerizer
1490 say $0-
1491 window.setCryptEngine $window
1492 }
1493 saylame Hello eleet!
1494 [/example]
1495
1496 @seealso:
1497 [fnc]$asciiToHex[/fnc], [fnc]$features[/fnc]
1498 */
1499
window_kvs_cmd_setCryptEngine(KviKvsModuleCommandCall * c)1500 static bool window_kvs_cmd_setCryptEngine(KviKvsModuleCommandCall * c)
1501 {
1502 QString szWnd;
1503 QString szEngine;
1504 QString szEncryptKey;
1505 QString szDecryptKey;
1506
1507 KVSM_PARAMETERS_BEGIN(c)
1508 KVSM_PARAMETER("window_id", KVS_PT_STRING, 0, szWnd)
1509 KVSM_PARAMETER("enginename", KVS_PT_STRING, KVS_PF_OPTIONAL, szEngine)
1510 KVSM_PARAMETER("hex_encrypt_key", KVS_PT_STRING, KVS_PF_OPTIONAL, szEncryptKey)
1511 KVSM_PARAMETER("hex_decrypt_key", KVS_PT_STRING, KVS_PF_OPTIONAL, szDecryptKey)
1512 KVSM_PARAMETERS_END(c)
1513 if(szDecryptKey.isEmpty())
1514 szDecryptKey = szEncryptKey;
1515 #ifdef COMPILE_CRYPT_SUPPORT
1516 KviWindow * pWnd = g_pApp->findWindow(szWnd.toUtf8().data());
1517 if(!pWnd)
1518 {
1519 if(!c->hasSwitch('q', "quiet"))
1520 c->warning(__tr2qs("The window with ID '%s' doesn't exist"), szWnd.toUtf8().data());
1521 return true;
1522 }
1523 if(c->hasSwitch('n', "onlydecrypt") && c->hasSwitch('m', "onlyencrypt"))
1524 {
1525 if(!c->hasSwitch('q', "quiet"))
1526 c->warning(__tr2qs("Both -n and -m switches specified, -n takes precedence"));
1527 }
1528
1529 if(szEngine.isEmpty())
1530 {
1531 pWnd->setCryptSessionInfo(nullptr);
1532 }
1533 else
1534 {
1535 if(szEncryptKey.isEmpty() || szDecryptKey.isEmpty())
1536 {
1537 if(!c->hasSwitch('q', "quiet"))
1538 c->warning(__tr2qs("No encryption key specified: can't allocate engine"));
1539 return true;
1540 }
1541
1542 (void)g_pModuleManager->loadModulesByCaps("crypt");
1543
1544 KviCryptEngine * e = g_pCryptEngineManager->allocateEngine(szEngine.toUtf8().data());
1545 if(e)
1546 {
1547 KviCString enc = KviCString(szEncryptKey.toUtf8().data());
1548 KviCString dec = KviCString(szDecryptKey.toUtf8().data());
1549 QString szError;
1550 if(initializeCryptEngine(e, enc, dec, szError))
1551 {
1552 KviCryptSessionInfo * inf = KviCryptController::allocateCryptSessionInfo();
1553 inf->m_pEngine = e;
1554 inf->m_szEngineName = szEngine;
1555
1556 inf->m_bDoEncrypt = (!c->hasSwitch('n', "onlydecrypt"));
1557 inf->m_bDoDecrypt = (!c->hasSwitch('m', "onlyencrypt")) || c->hasSwitch('n', "onlydecrypt");
1558 pWnd->setCryptSessionInfo(inf);
1559 }
1560 else
1561 {
1562 if(szError.isEmpty())
1563 szError = __tr2qs("Unknown engine error");
1564 g_pCryptEngineManager->deallocateEngine(e);
1565 if(!c->hasSwitch('q', "quiet"))
1566 c->warning(__tr2qs("Failed to initialize the specified encryption engine: %Q"), &szError);
1567 }
1568 }
1569 else
1570 {
1571 if(!c->hasSwitch('q', "quiet"))
1572 c->warning(__tr2qs("The encryption engine \"%Q\" doesn't exist"), &szEngine);
1573 }
1574 }
1575 #else
1576 if(!c->hasSwitch('q', "quiet"))
1577 c->warning(__tr2qs("This executable has been compiled without crypt support"));
1578 #endif
1579 return true;
1580 }
1581
1582 /*
1583 @doc: $window.cryptEngine
1584 @type:
1585 function
1586 @title:
1587 $window.cryptEngine
1588 @short:
1589 Returns the name of the encryption engine currently set in a window
1590 @syntax:
1591 $window.cryptEngine(<window_id:integer>)
1592 @description:
1593 Returns the name of the encryption engine set in the current window.
1594 If no current engine is set then empty string is returned.
1595 @seealso:
1596 [cmd]window.setCryptEngine[/cmd]
1597 */
1598
window_kvs_fnc_cryptEngine(KviKvsModuleFunctionCall * c)1599 static bool window_kvs_fnc_cryptEngine(KviKvsModuleFunctionCall * c)
1600 {
1601 GET_KVS_FNC_WINDOW_ID
1602 if(pWnd)
1603 {
1604 #ifdef COMPILE_CRYPT_SUPPORT
1605 if(KviCryptSessionInfo * pCryptSessionInfo = pWnd->cryptSessionInfo())
1606 c->returnValue()->setString(pCryptSessionInfo->m_szEngineName);
1607 #else //!COMPILE_CRYPT_SUPPORT
1608 // do nothing
1609 #endif //!COMPILE_CRYPT_SUPPORT
1610 }
1611 return true;
1612 }
1613
window_kvs_fnc_fake(KviKvsModuleFunctionCall * c)1614 static bool window_kvs_fnc_fake(KviKvsModuleFunctionCall * c)
1615 {
1616 return true;
1617 }
1618
window_kvs_cmd_fake(KviKvsModuleCommandCall * c)1619 static bool window_kvs_cmd_fake(KviKvsModuleCommandCall * c)
1620 {
1621 qDebug("This command was removed due to structural interface changes");
1622 return true;
1623 }
1624
window_module_init(KviModule * m)1625 static bool window_module_init(KviModule * m)
1626 {
1627 KVSM_REGISTER_FUNCTION(m, "activityTemperature", window_kvs_fnc_activityTemperature);
1628 KVSM_REGISTER_FUNCTION(m, "activityLevel", window_kvs_fnc_activityLevel);
1629 KVSM_REGISTER_FUNCTION(m, "highlightLevel", window_kvs_fnc_highlightLevel);
1630 KVSM_REGISTER_FUNCTION(m, "console", window_kvs_fnc_console);
1631 KVSM_REGISTER_FUNCTION(m, "hasUserFocus", window_kvs_fnc_hasUserFocus);
1632 KVSM_REGISTER_FUNCTION(m, "hasOutput", window_kvs_fnc_hasOutput);
1633 KVSM_REGISTER_FUNCTION(m, "isDocked", window_kvs_fnc_isDocked);
1634 KVSM_REGISTER_FUNCTION(m, "isSplitView", window_kvs_fnc_isSplitView);
1635 KVSM_REGISTER_FUNCTION(m, "isMinimized", window_kvs_fnc_fake); // compat only
1636 KVSM_REGISTER_FUNCTION(m, "isMaximized", window_kvs_fnc_fake); // compat only
1637 KVSM_REGISTER_FUNCTION(m, "caption", window_kvs_fnc_caption);
1638 KVSM_REGISTER_FUNCTION(m, "type", window_kvs_fnc_type);
1639 KVSM_REGISTER_FUNCTION(m, "exists", window_kvs_fnc_exists);
1640 KVSM_REGISTER_FUNCTION(m, "hasInput", window_kvs_fnc_hasInput);
1641 KVSM_REGISTER_FUNCTION(m, "list", window_kvs_fnc_list);
1642 KVSM_REGISTER_FUNCTION(m, "open", window_kvs_fnc_open);
1643 KVSM_REGISTER_FUNCTION(m, "inputText", window_kvs_fnc_inputText);
1644 KVSM_REGISTER_FUNCTION(m, "context", window_kvs_fnc_context);
1645 KVSM_REGISTER_FUNCTION(m, "cryptEngine", window_kvs_fnc_cryptEngine);
1646
1647 KVSM_REGISTER_SIMPLE_COMMAND(m, "highlight", window_kvs_cmd_highlight);
1648 KVSM_REGISTER_SIMPLE_COMMAND(m, "close", window_kvs_cmd_close);
1649 KVSM_REGISTER_SIMPLE_COMMAND(m, "clearOutput", window_kvs_cmd_clearOutput);
1650 KVSM_REGISTER_SIMPLE_COMMAND(m, "dock", window_kvs_cmd_dock);
1651 KVSM_REGISTER_SIMPLE_COMMAND(m, "undock", window_kvs_cmd_undock);
1652 KVSM_REGISTER_SIMPLE_COMMAND(m, "splitView", window_kvs_cmd_splitView);
1653 KVSM_REGISTER_SIMPLE_COMMAND(m, "unsplitView", window_kvs_cmd_unsplitView);
1654 KVSM_REGISTER_SIMPLE_COMMAND(m, "minimize", window_kvs_cmd_fake);
1655 KVSM_REGISTER_SIMPLE_COMMAND(m, "maximize", window_kvs_cmd_fake);
1656 KVSM_REGISTER_SIMPLE_COMMAND(m, "restore", window_kvs_cmd_fake);
1657 KVSM_REGISTER_SIMPLE_COMMAND(m, "activate", window_kvs_cmd_activate);
1658 KVSM_REGISTER_SIMPLE_COMMAND(m, "demandAttention", window_kvs_cmd_demandAttention);
1659 KVSM_REGISTER_SIMPLE_COMMAND(m, "listtypes", window_kvs_cmd_listtypes);
1660 KVSM_REGISTER_SIMPLE_COMMAND(m, "setBackground", window_kvs_cmd_setBackground);
1661 KVSM_REGISTER_SIMPLE_COMMAND(m, "setWindowTitle", window_kvs_cmd_setWindowTitle);
1662 KVSM_REGISTER_SIMPLE_COMMAND(m, "setCryptEngine", window_kvs_cmd_setCryptEngine);
1663 KVSM_REGISTER_SIMPLE_COMMAND(m, "setInputText", window_kvs_cmd_setInputText);
1664 KVSM_REGISTER_SIMPLE_COMMAND(m, "insertInInputText", window_kvs_cmd_insertInInputText);
1665 KVSM_REGISTER_SIMPLE_COMMAND(m, "savePropertiesAsDefault", window_kvs_cmd_savePropertiesAsDefault);
1666
1667 return true;
1668 }
1669
window_module_cleanup(KviModule *)1670 static bool window_module_cleanup(KviModule *)
1671 {
1672 while(!g_pUserWindowList.empty())
1673 {
1674 auto & w = g_pUserWindowList.front();
1675 w->close();
1676 }
1677 return true;
1678 }
1679
window_module_can_unload(KviModule *)1680 static bool window_module_can_unload(KviModule *)
1681 {
1682 return g_pUserWindowList.empty();
1683 }
1684
1685 KVIRC_MODULE(
1686 "Window", // module name
1687 "4.0.0", // module version
1688 "Copyright (C) 2001-2004 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
1689 "KVIrc window management functions",
1690 window_module_init,
1691 window_module_can_unload,
1692 0,
1693 window_module_cleanup,
1694 0)
1695