1 //=============================================================================
2 //
3 // File : KviCoreActions.cpp
4 // Creation date : Mon 22 Nov 2004 02:30:47 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC Client distribution
7 // Copyright (C) 2004-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 "KviCoreActions.h"
26 #include "KviShortcut.h"
27 #include "KviMainWindow.h"
28 #include "KviLocale.h"
29 #include "KviIrcContext.h"
30 #include "KviIconManager.h"
31 #include "KviApplication.h"
32 #include "KviCustomToolBar.h"
33 #include "KviActionDrawer.h"
34 #include "KviActionManager.h"
35 #include "KviKvsAction.h"
36 #include "KviWindowStack.h"
37 #include "KviIrcToolBar.h"
38 #include "KviIrcUrl.h"
39 #include "KviIrcConnection.h"
40 #include "KviIrcConnectionUserInfo.h"
41 #include "KviCoreActionNames.h"
42 #include "KviIrcConnectionServerInfo.h"
43 #include "KviKvsScript.h"
44 #include "KviOptions.h"
45
46 #include <QObject>
47 #include <QMenu>
48
register_core_actions(KviActionManager * m)49 void register_core_actions(KviActionManager * m)
50 {
51 m->registerAction(new KviConnectAction(m)); // this as parent will destroy it on exit!
52 m->registerAction(new KviSeparatorAction(m));
53 m->registerAction(new KviIrcContextDisplayAction(m));
54 m->registerAction(new KviJoinChannelAction(m));
55 m->registerAction(new KviChangeNickAction(m));
56 m->registerAction(new KviConnectToServerAction(m));
57 m->registerAction(new KviChangeUserModeAction(m));
58 m->registerAction(new KviGoAwayAction(m));
59 m->registerAction(new KviIrcToolsAction(m));
60 m->registerAction(new KviIrcOperationsAction(m));
61
62 KviAction * a;
63
64 #define SCRIPT_ACTION(__name, __code, __visible, __description, __category, __icon, __smallicon, __flags, __accel) \
65 a = new KviKvsAction(m, \
66 QString(__name), \
67 QString(__code), \
68 QString(__visible), \
69 QString(__description), \
70 __category, \
71 QString(__icon), \
72 __smallicon, \
73 __flags, \
74 QKeySequence(__accel).toString()); \
75 m->registerAction(a)
76
77 #define SLOT_ACTION(__name, __object, __slot, __visible, __description, __category, __icon, __smallicon, __flags, __accel) \
78 a = new KviAction(m, \
79 QString(__name), \
80 QString(__visible), \
81 QString(__description), \
82 __category, \
83 QString(__icon), \
84 __smallicon, \
85 __flags, \
86 QKeySequence(__accel).toString()); \
87 QObject::connect(a, SIGNAL(activated()), __object, __slot); \
88 m->registerAction(a)
89
90 SCRIPT_ACTION(
91 KVI_COREACTION_SERVEROPTIONS,
92 "options.edit -n OptionsWidget_servers",
93 __tr2qs("Configure Servers..."),
94 __tr2qs("Allows you to configure the servers and eventually to connect to them"),
95 KviActionManager::categorySettings(),
96 "kvi_bigicon_serverconfiguration.png",
97 KviIconManager::ServerConfiguration,
98 0,
99 KVI_SHORTCUTS_SERVERS);
100
101 SCRIPT_ACTION(
102 KVI_COREACTION_MANAGEADDONS,
103 "addon.dialog -t",
104 __tr2qs("Manage Addons..."),
105 __tr2qs("Allows you to manage the script-based addons"),
106 KviActionManager::categorySettings(),
107 "kvi_bigicon_addons.png",
108 KviIconManager::Addons,
109 0,
110 KVI_SHORTCUTS_MANAGE_ADDONS);
111
112 SCRIPT_ACTION(
113 KVI_COREACTION_EDITREGUSERS,
114 "reguser.edit -t",
115 __tr2qs("Configure Registered Users..."),
116 __tr2qs("Shows a dialog that allows editing the registered user entries"),
117 KviActionManager::categorySettings(),
118 "kvi_bigicon_regusers.png",
119 KviIconManager::RegUsers,
120 0,
121 KVI_SHORTCUTS_USERS);
122
123 SCRIPT_ACTION(
124 KVI_COREACTION_IDENTITYOPTIONS,
125 "options.edit OptionsWidget_identity",
126 __tr2qs("Configure Identity..."),
127 __tr2qs("Allows you to configure nickname, username, avatar etc..."),
128 KviActionManager::categorySettings(),
129 "kvi_bigicon_identity.png",
130 KviIconManager::Identity,
131 0,
132 KVI_SHORTCUTS_IDENTITY);
133
134 SCRIPT_ACTION(
135 KVI_COREACTION_SOCKETSPY,
136 "socketspy.open",
137 __tr2qs("Show Socket Spy"),
138 __tr2qs("Shows a window that allows monitoring the socket traffic"),
139 KviActionManager::categoryIrc(),
140 "kvi_bigicon_socketspy.png",
141 KviIconManager::Spy,
142 KviAction::NeedsContext,
143 QString());
144
145 SCRIPT_ACTION(
146 KVI_COREACTION_NETWORKLINKS,
147 "links.open",
148 __tr2qs("Get Network Links"),
149 __tr2qs("Shows a window that allows viewing the network links"),
150 KviActionManager::categoryIrc(),
151 "kvi_bigicon_links.png",
152 KviIconManager::Links,
153 KviAction::NeedsContext,
154 QString());
155
156 SCRIPT_ACTION(
157 KVI_COREACTION_CHANNELLIST,
158 "list.open",
159 __tr2qs("Get Channel List"),
160 __tr2qs("Shows a window that allows listing the network channels"),
161 KviActionManager::categoryIrc(),
162 "kvi_bigicon_channellist.png",
163 KviIconManager::List,
164 KviAction::NeedsContext,
165 QString());
166
167 SCRIPT_ACTION(
168 KVI_COREACTION_GENERALOPTIONS,
169 "options.dialog",
170 __tr2qs("Configure KVIrc..."),
171 __tr2qs("Shows the general options dialog"),
172 KviActionManager::categorySettings(),
173 "kvi_bigicon_settings.png",
174 KviIconManager::Options,
175 0,
176 KVI_SHORTCUTS_OPTIONS);
177
178 SCRIPT_ACTION(
179 KVI_COREACTION_THEMEOPTIONS,
180 "options.dialog theme",
181 __tr2qs("Configure Theme..."),
182 __tr2qs("Shows the theme options dialog"),
183 KviActionManager::categorySettings(),
184 "kvi_bigicon_themeoptions.png",
185 KviIconManager::ThemeOptions,
186 0,
187 KVI_SHORTCUTS_THEME);
188
189 SCRIPT_ACTION(
190 KVI_COREACTION_MANAGETHEMES,
191 "theme.dialog -t",
192 __tr2qs("Manage Themes..."),
193 __tr2qs("Allows you to manage the themes"),
194 KviActionManager::categorySettings(),
195 "kvi_bigicon_theme.png",
196 KviIconManager::Theme,
197 0,
198 KVI_SHORTCUTS_MANAGE_THEMES);
199
200 SCRIPT_ACTION(
201 KVI_COREACTION_TOOLBAREDITOR,
202 "toolbareditor.open -t",
203 __tr2qs("Customize Toolbars..."),
204 __tr2qs("Shows a window that allows editing script toolbars"),
205 KviActionManager::categorySettings(),
206 "kvi_bigicon_toolbareditor.png",
207 KviIconManager::ToolBarEditor,
208 0,
209 KVI_SHORTCUTS_EDITORS_TOOLBAR);
210
211 SCRIPT_ACTION(
212 KVI_COREACTION_JOINCHANNELS,
213 "channelsjoin.open",
214 __tr2qs("Join Channels..."),
215 __tr2qs("Shows a dialog that allows you join channels"),
216 KviActionManager::categoryIrc(),
217 "kvi_bigicon_channels.png",
218 KviIconManager::Channel,
219 KviKvsAction::NeedsConnection | KviKvsAction::NeedsContext,
220 KVI_SHORTCUTS_JOIN);
221
222 SCRIPT_ACTION(
223 KVI_COREACTION_ACTIONEDITOR,
224 "actioneditor.open",
225 __tr2qs("Edit Actions..."),
226 __tr2qs("Shows a window that allows editing actions"),
227 KviActionManager::categoryScripting(),
228 "kvi_bigicon_actioneditor.png",
229 KviIconManager::ActionEditor,
230 0,
231 KVI_SHORTCUTS_EDITORS_ACTION);
232
233 SCRIPT_ACTION(
234 KVI_COREACTION_ALIASEDITOR,
235 "aliaseditor.open",
236 __tr2qs("Edit Aliases..."),
237 __tr2qs("Shows a window that allows editing aliases"),
238 KviActionManager::categoryScripting(),
239 "kvi_bigicon_aliaseditor.png",
240 KviIconManager::AliasEditor,
241 0,
242 KVI_SHORTCUTS_EDITORS_ALIAS);
243
244 SCRIPT_ACTION(
245 KVI_COREACTION_CLASSEDITOR,
246 "classeditor.open",
247 __tr2qs("Edit Classes..."),
248 __tr2qs("Shows a window that allows editing classes"),
249 KviActionManager::categoryScripting(),
250 "kvi_bigicon_classeditor.png",
251 KviIconManager::ClassEditor,
252 0,
253 KVI_SHORTCUTS_EDITORS_CLASS);
254
255 SCRIPT_ACTION(
256 KVI_COREACTION_EVENTEDITOR,
257 "eventeditor.open",
258 __tr2qs("Edit Events..."),
259 __tr2qs("Shows a window that allows editing script events"),
260 KviActionManager::categoryScripting(),
261 "kvi_bigicon_eventeditor.png",
262 KviIconManager::EventEditor,
263 0,
264 KVI_SHORTCUTS_EDITORS_EVENT);
265
266 SCRIPT_ACTION(
267 KVI_COREACTION_POPUPEDITOR,
268 "popupeditor.open",
269 __tr2qs("Edit Popups..."),
270 __tr2qs("Shows a window that allows editing popup menus"),
271 KviActionManager::categoryScripting(),
272 "kvi_bigicon_popupeditor.png",
273 KviIconManager::PopupEditor,
274 0,
275 KVI_SHORTCUTS_EDITORS_POPUP);
276
277 SCRIPT_ACTION(
278 KVI_COREACTION_RAWEDITOR,
279 "raweditor.open",
280 __tr2qs("Edit RAW Events..."),
281 __tr2qs("Shows a window that allows editing RAW scripting events"),
282 KviActionManager::categoryScripting(),
283 "kvi_bigicon_raweditor.png",
284 KviIconManager::RawEventEditor,
285 0,
286 KVI_SHORTCUTS_EDITORS_RAW);
287
288 SCRIPT_ACTION(
289 KVI_COREACTION_CODETESTER,
290 "codetester.open",
291 __tr2qs("Script Tester"),
292 __tr2qs("Creates an embedded editor for long scripts"),
293 KviActionManager::categoryScripting(),
294 "kvi_bigicon_codetester.png",
295 KviIconManager::Bomb,
296 0,
297 KVI_SHORTCUTS_EDITORS_TESTER);
298
299 SCRIPT_ACTION(
300 KVI_COREACTION_EXECUTEKVS,
301 "dialog.file(open,$tr(\"Select a File - KVIrc\")){ if(!$str.isEmpty($0))parse $0; }",
302 __tr2qs("Execute Script..."),
303 __tr2qs("Allows executing a KVS script from file"),
304 KviActionManager::categoryScripting(),
305 "kvi_bigicon_folder.png",
306 KviIconManager::Folder,
307 0,
308 KVI_SHORTCUTS_EXEC);
309
310 SCRIPT_ACTION(
311 KVI_COREACTION_HELPINDEX,
312 "help.open -m",
313 __tr2qs("Help Index"),
314 __tr2qs("Shows the documentation index"),
315 KviActionManager::categoryGeneric(),
316 "kvi_bigicon_help.png",
317 KviIconManager::Help,
318 0,
319 KVI_SHORTCUTS_HELP);
320
321 SCRIPT_ACTION(
322 KVI_COREACTION_KVIRCHOMEPAGE,
323 "openurl http://www.kvirc.net",
324 __tr2qs("KVIrc WWW"),
325 __tr2qs("Opens the KVIrc homepage"),
326 KviActionManager::categoryGeneric(),
327 "kvi_bigicon_homepage.png",
328 KviIconManager::HomePage,
329 0,
330 QString());
331
332 SCRIPT_ACTION(
333 KVI_COREACTION_KVIRCRUHOMEPAGE,
334 "openurl http://www.kvirc.ru",
335 __tr2qs("KVIrc Russian WWW"),
336 __tr2qs("Opens the KVIrc homepage in Russian"),
337 KviActionManager::categoryGeneric(),
338 "kvi_bigicon_homepage.png",
339 KviIconManager::HomePage,
340 0,
341 QString());
342
343 SCRIPT_ACTION(
344 KVI_COREACTION_SCREENSHOT,
345 "theme.screenshot",
346 __tr2qs("Acquire Screenshot"),
347 __tr2qs("Acquires a screenshot of the KVIrc main window"),
348 KviActionManager::categoryGeneric(),
349 "kvi_bigicon_screenshot.png",
350 KviIconManager::ScreenShot,
351 0,
352 QString());
353
354 SCRIPT_ACTION(
355 KVI_COREACTION_FILETRANSFER,
356 "filetransferwindow.open",
357 __tr2qs("Manage File &Transfers"),
358 __tr2qs("Shows a window that lists file transfers"),
359 KviActionManager::categoryGeneric(),
360 "kvi_bigicon_filetransfer.png",
361 KviIconManager::FileTransfer,
362 0,
363 QString());
364
365 SCRIPT_ACTION(
366 KVI_COREACTION_IOGRAPH,
367 "iograph.open",
368 __tr2qs("Show I/O &Traffic Graph"),
369 __tr2qs("Shows a graph representing I/O bandwidth traffic"),
370 KviActionManager::categoryIrc(),
371 "kvi_bigicon_sysmonitor.png",
372 KviIconManager::SysMonitor,
373 0,
374 QString());
375
376 SCRIPT_ACTION(
377 KVI_COREACTION_LOGVIEWER,
378 "logview.open",
379 __tr2qs("Browse Log Files"),
380 __tr2qs("Shows a window that lists and filter log files"),
381 KviActionManager::categoryGeneric(),
382 "kvi_bigicon_log.png",
383 KviIconManager::Log,
384 0,
385 QString());
386
387 SCRIPT_ACTION(
388 KVI_COREACTION_SHAREDFILES,
389 "sharedfileswindow.open",
390 __tr2qs("Manage S&hared Files"),
391 __tr2qs("Shows a window that list shared files"),
392 KviActionManager::categoryGeneric(),
393 "kvi_bigicon_sharedfiles.png",
394 KviIconManager::SharedFiles,
395 0,
396 QString());
397
398 SCRIPT_ACTION(
399 KVI_COREACTION_URLLIST,
400 "url.list",
401 __tr2qs("View URL List"),
402 __tr2qs("Shows a window that lists caught URLs"),
403 KviActionManager::categoryGeneric(),
404 "kvi_bigicon_url.png",
405 KviIconManager::Url,
406 0,
407 QString());
408
409 SLOT_ACTION(
410 KVI_COREACTION_NEWIRCCONTEXT,
411 g_pMainWindow,
412 SLOT(newConsole()),
413 __tr2qs("New IRC Context"),
414 __tr2qs("Creates a new IRC context console"),
415 KviActionManager::categoryIrc(),
416 "kvi_bigicon_newitem.png",
417 KviIconManager::NewItem,
418 0,
419 KVI_SHORTCUTS_CONTEXT);
420
421 SLOT_ACTION(
422 KVI_COREACTION_QUITKVIRC,
423 g_pMainWindow,
424 SLOT(close()),
425 __tr2qs("&Quit KVIrc"),
426 __tr2qs("Quits KVIrc closing all the current connections"),
427 KviActionManager::categoryIrc(),
428 "kvi_bigicon_quitapp.png",
429 KviIconManager::QuitApp,
430 0,
431 KVI_SHORTCUTS_QUIT);
432 }
433
KviIrcContextDisplayAction(QObject * pParent)434 KviIrcContextDisplayAction::KviIrcContextDisplayAction(QObject * pParent)
435 : KviAction(pParent,
436 QString(KVI_COREACTION_IRCCONTEXTDISPLAY),
437 __tr2qs("IRC Context Display"),
438 __tr2qs("Shows a small display with IRC context information"),
439 KviActionManager::categoryIrc(),
440 "kvi_bigicon_irccontextdisplay.png",
441 KviIconManager::PopupMenu,
442 NeedsContext | NeedsConnection)
443 {
444 }
445
setup()446 void KviIrcContextDisplayAction::setup()
447 {
448 KviAction::setup();
449 connect(g_pMainWindow, SIGNAL(activeConnectionServerInfoChanged()), this, SLOT(activeContextStateChanged()));
450 connect(g_pMainWindow, SIGNAL(activeConnectionNickNameChanged()), this, SLOT(activeContextStateChanged()));
451 connect(g_pMainWindow, SIGNAL(activeConnectionUserModeChanged()), this, SLOT(activeContextStateChanged()));
452 connect(g_pMainWindow, SIGNAL(activeConnectionAwayStateChanged()), this, SLOT(activeContextStateChanged()));
453 connect(g_pMainWindow, SIGNAL(activeConnectionLagChanged()), this, SLOT(activeContextStateChanged()));
454 }
455
addToPopupMenu(QMenu *)456 bool KviIrcContextDisplayAction::addToPopupMenu(QMenu *)
457 {
458 // QT4SUX: Widgets can be no longer added to popup menus.. what about labels ?
459 return true;
460 }
461
addToCustomToolBar(KviCustomToolBar * t)462 QAction * KviIrcContextDisplayAction::addToCustomToolBar(KviCustomToolBar * t)
463 {
464 if(!setupDone())
465 setup();
466 KviIrcContextDisplay * w = new KviIrcContextDisplay(t, KVI_COREACTION_IRCCONTEXTDISPLAY);
467 QAction * pAction = t->addWidget(w);
468 // important: when customizing the toolbar, we'll get the action name from QAction::objectName();
469 pAction->setObjectName(KVI_COREACTION_IRCCONTEXTDISPLAY);
470 registerAction(pAction);
471 return pAction;
472 }
473
activeContextChanged()474 void KviIrcContextDisplayAction::activeContextChanged()
475 {
476 for(auto & pAction : m_pActionList)
477 {
478 QToolBar * t = (QToolBar *)pAction->parentWidget();
479 if(t)
480 {
481 KviIrcContextDisplay * w = (KviIrcContextDisplay *)t->widgetForAction(pAction);
482 if(w)
483 w->update();
484 }
485 }
486 }
487
activeContextStateChanged()488 void KviIrcContextDisplayAction::activeContextStateChanged()
489 {
490 for(auto & pAction : m_pActionList)
491 {
492 QToolBar * t = (QToolBar *)pAction->parentWidget();
493 if(t)
494 {
495 KviIrcContextDisplay * w = (KviIrcContextDisplay *)t->widgetForAction(pAction);
496 if(w)
497 w->update();
498 }
499 }
500 }
501
setEnabled(bool)502 void KviIrcContextDisplayAction::setEnabled(bool)
503 {
504 // does nothing here : always enabled!
505 }
506
KviSeparatorAction(QObject * pParent)507 KviSeparatorAction::KviSeparatorAction(QObject * pParent)
508 : KviAction(pParent,
509 QString(KVI_COREACTION_SEPARATOR),
510 __tr2qs("Separator"),
511 __tr2qs("Acts as a separator for other items: performs no action"),
512 KviActionManager::categoryGeneric(),
513 KVI_BIGICON_SEPARATOR,
514 KviIconManager::None,
515 0)
516 {
517 }
518
addToPopupMenu(QMenu * p)519 bool KviSeparatorAction::addToPopupMenu(QMenu * p)
520 {
521 if(!setupDone())
522 setup();
523 p->addSeparator();
524 return true;
525 }
526
addToCustomToolBar(KviCustomToolBar * t)527 QAction * KviSeparatorAction::addToCustomToolBar(KviCustomToolBar * t)
528 {
529 if(!setupDone())
530 setup();
531 QWidget * w = new KviCustomToolBarSeparator(t, KVI_COREACTION_SEPARATOR);
532 QAction * pAction = t->addWidget(w);
533 // important: when customizing the toolbar, we'll get the action name from QAction::objectName();
534 pAction->setObjectName(KVI_COREACTION_SEPARATOR);
535 registerAction(pAction);
536 return pAction;
537 }
538
KviConnectAction(QObject * pParent)539 KviConnectAction::KviConnectAction(QObject * pParent)
540 : KviAction(pParent,
541 QString(KVI_COREACTION_CONNECT),
542 __tr2qs("Connect/Disconnect"),
543 __tr2qs("Allows you to connect to a server or to terminate the current connection"),
544 KviActionManager::categoryIrc(),
545 KVI_BIGICON_CONNECTED,
546 KviIconManager::None, // no small icon for now
547 NeedsContext | NeedsConnection,
548 QString(KVI_SHORTCUTS_CONNECT))
549 {
550 }
551
reloadImages()552 void KviConnectAction::reloadImages()
553 {
554 activeContextStateChanged();
555 }
556
activeContextChanged()557 void KviConnectAction::activeContextChanged()
558 {
559 activeContextStateChanged();
560 }
561
activeContextStateChanged()562 void KviConnectAction::activeContextStateChanged()
563 {
564
565 std::unordered_set<QAction *> const & bl = actionList();
566 if(bl.empty())
567 return;
568
569 bool bIconVisibleInMenu = KVI_OPTION_BOOL(KviOption_boolShowIconsInPopupMenus);
570 QPixmap * p;
571 QString txt;
572 KviIrcContext * c = g_pMainWindow->activeContext();
573 if(c)
574 {
575 switch(c->state())
576 {
577 case KviIrcContext::Idle:
578 p = g_pIconManager->getBigIcon(KVI_BIGICON_DISCONNECTED);
579 txt = m_szConnectString;
580 break;
581 case KviIrcContext::PendingReconnection:
582 case KviIrcContext::Connecting:
583 case KviIrcContext::LoggingIn:
584 p = g_pIconManager->getBigIcon(KVI_BIGICON_CONNECTING);
585 txt = m_szAbortConnectionString;
586 break;
587 case KviIrcContext::Connected:
588 p = g_pIconManager->getBigIcon(KVI_BIGICON_CONNECTED);
589 txt = m_szDisconnectString;
590 break;
591 default:
592 p = nullptr;
593 break;
594 }
595 }
596 else
597 {
598 p = nullptr;
599 }
600
601 if(p)
602 {
603 for(auto & b : bl)
604 {
605 if(!b->isEnabled())
606 b->setEnabled(true);
607 b->setIcon(QIcon(*p));
608 b->setText(txt);
609 b->setIconVisibleInMenu(bIconVisibleInMenu);
610 }
611 }
612 else
613 {
614 for(auto & b : bl)
615 {
616 if(b->isEnabled())
617 b->setEnabled(false);
618 b->setIconVisibleInMenu(bIconVisibleInMenu);
619 }
620 }
621 }
622
setup()623 void KviConnectAction::setup()
624 {
625 KviAction::setup();
626 m_szConnectString = __tr2qs("Connect");
627 m_szAbortConnectionString = __tr2qs("Abort Connection");
628 m_szDisconnectString = __tr2qs("Disconnect");
629 }
630
activate()631 void KviConnectAction::activate()
632 {
633 KviIrcContext * c = g_pMainWindow->activeContext();
634 if(c)
635 c->connectOrDisconnect();
636 }
637
addToPopupMenu(QMenu * p)638 bool KviConnectAction::addToPopupMenu(QMenu * p)
639 {
640 if(!setupDone())
641 setup();
642 KviIrcContext * c = g_pMainWindow->activeContext();
643 QAction * pAction;
644 QString t;
645 if(c)
646 {
647 switch(c->state())
648 {
649 case KviIrcContext::Idle:
650 t = m_szConnectString;
651 if(!m_szKeySequence.isEmpty())
652 t += '\t' + m_szKeySequence;
653 p->addAction(t, this, SLOT(activate()));
654 break;
655 case KviIrcContext::PendingReconnection:
656 case KviIrcContext::Connecting:
657 case KviIrcContext::LoggingIn:
658 t = m_szAbortConnectionString;
659 if(!m_szKeySequence.isEmpty())
660 t += '\t' + m_szKeySequence;
661 p->addAction(t, this, SLOT(activate()));
662 break;
663 case KviIrcContext::Connected:
664 t = m_szDisconnectString;
665 if(!m_szKeySequence.isEmpty())
666 t += '\t' + m_szKeySequence;
667 p->addAction(t, this, SLOT(activate()));
668 break;
669 default:
670 t = m_szConnectString;
671 if(!m_szKeySequence.isEmpty())
672 t += '\t' + m_szKeySequence;
673 pAction = p->addAction(t, this, SLOT(activate()));
674 pAction->setEnabled(false);
675 break;
676 }
677 }
678 else
679 {
680 t = m_szConnectString;
681 if(!m_szKeySequence.isEmpty())
682 t += '\t' + m_szKeySequence;
683 pAction = p->addAction(t, this, SLOT(activate()));
684 pAction->setEnabled(false);
685 }
686 return true;
687 }
688
addToCustomToolBar(KviCustomToolBar * t)689 QAction * KviConnectAction::addToCustomToolBar(KviCustomToolBar * t)
690 {
691 if(!setupDone())
692 setup();
693 QAction * pAction = new QAction(*(g_pIconManager->getBigIcon(KVI_BIGICON_DISCONNECTED)), m_szConnectString, t);
694 pAction->setStatusTip(m_szConnectString);
695 pAction->setObjectName(KVI_COREACTION_CONNECT);
696 t->addAction(pAction);
697 connect(pAction, SIGNAL(triggered()), this, SLOT(activate()));
698 registerAction(pAction);
699 activeContextStateChanged();
700 return pAction;
701 }
702
KviSubmenuAction(QObject * pParent,const QString & szName,const QString & szScriptCode,const QString & szVisibleName,const QString & szDescription,KviActionCategory * pCategory,const QString & szBigIconId,KviIconManager::SmallIcon eSmallIcon,unsigned int uFlags)703 KviSubmenuAction::KviSubmenuAction(
704 QObject * pParent,
705 const QString & szName,
706 const QString & szScriptCode,
707 const QString & szVisibleName,
708 const QString & szDescription,
709 KviActionCategory * pCategory,
710 const QString & szBigIconId,
711 KviIconManager::SmallIcon eSmallIcon,
712 unsigned int uFlags)
713 : KviKvsAction(
714 pParent,
715 szName,
716 szScriptCode,
717 szVisibleName,
718 szDescription,
719 pCategory,
720 szBigIconId,
721 eSmallIcon,
722 uFlags)
723 {
724 m_pPopup = nullptr;
725 }
726
~KviSubmenuAction()727 KviSubmenuAction::~KviSubmenuAction()
728 {
729 if(m_pPopup)
730 delete m_pPopup;
731 }
732
setup()733 void KviSubmenuAction::setup()
734 {
735 KviKvsAction::setup();
736 if(!m_pPopup)
737 {
738 m_pPopup = new QMenu();
739 connect(m_pPopup, SIGNAL(aboutToShow()), this, SLOT(popupAboutToShow()));
740 connect(m_pPopup, SIGNAL(triggered(QAction *)), this, SLOT(popupActivated(QAction *)));
741 }
742 }
743
popupAboutToShow()744 void KviSubmenuAction::popupAboutToShow()
745 {
746 }
747
popupActivated(QAction *)748 void KviSubmenuAction::popupActivated(QAction *)
749 {
750 }
751
addToPopupMenu(QMenu * p)752 bool KviSubmenuAction::addToPopupMenu(QMenu * p)
753 {
754 if(!setupDone())
755 setup();
756 QAction * pAction = p->addAction(*(smallIcon()), visibleName());
757 pAction->setMenu(m_pPopup);
758 if(!isEnabled())
759 pAction->setEnabled(false);
760 return true;
761 }
762
addToCustomToolBar(KviCustomToolBar * t)763 QAction * KviSubmenuAction::addToCustomToolBar(KviCustomToolBar * t)
764 {
765 if(!setupDone())
766 setup();
767 QPixmap * p = bigIcon();
768
769 QAction * pAction = new QAction(p ? *p : QPixmap(), visibleName(), t);
770 pAction->setStatusTip(visibleName());
771 pAction->setObjectName(name());
772 t->addAction(pAction);
773 connect(pAction, SIGNAL(triggered()), this, SLOT(activate()));
774 pAction->setMenu(m_pPopup);
775
776 QToolButton * pButton = (QToolButton *)t->widgetForAction(pAction);
777 if(pButton)
778 pButton->setPopupMode(scriptCode().isEmpty() ? QToolButton::InstantPopup : QToolButton::MenuButtonPopup);
779
780 registerAction(pAction);
781 if(!isEnabled())
782 pAction->setEnabled(false);
783 return pAction;
784 }
785
KviJoinChannelAction(QObject * pParent)786 KviJoinChannelAction::KviJoinChannelAction(QObject * pParent)
787 : KviSubmenuAction(pParent,
788 QString(KVI_COREACTION_CHANNELMENU),
789 QString("channelsjoin.open"),
790 __tr2qs("Join Channel"),
791 __tr2qs("Shows a popup menu that allows quickly selecting a channel to join"),
792 KviActionManager::categoryIrc(),
793 "kvi_bigicon_channelspopup.png",
794 KviIconManager::Channel,
795 NeedsConnection | NeedsContext)
796 {
797 }
798
popupAboutToShow()799 void KviJoinChannelAction::popupAboutToShow()
800 {
801 KviConsoleWindow * c = g_pActiveWindow->console();
802 if(!c)
803 return;
804
805 g_pApp->fillRecentChannelsPopup(m_pPopup, c);
806
807 m_pPopup->addSeparator();
808 m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Channel)), __tr2qs("Other..."));
809 m_pPopup->addSeparator();
810 m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Remove)), __tr2qs("Clear Recent Channels List"));
811 }
812
popupActivated(QAction * pAction)813 void KviJoinChannelAction::popupActivated(QAction * pAction)
814 {
815 KviConsoleWindow * c = g_pActiveWindow->console();
816 if(!c)
817 return;
818
819 QString szItemText = pAction->text();
820 if(!szItemText.isEmpty())
821 {
822 QString szText;
823 if(szItemText == __tr2qs("Other..."))
824 {
825 szText = "channelsjoin.open";
826 }
827 else if(szItemText == __tr2qs("Clear Recent Channels List"))
828 {
829 szText = "option stringlistRecentChannels";
830 }
831 else
832 {
833 szText = szItemText;
834 szText.prepend("join ");
835 }
836 KviKvsScript::run(szText, c);
837 }
838 }
839
KviChangeNickAction(QObject * pParent)840 KviChangeNickAction::KviChangeNickAction(QObject * pParent)
841 : KviSubmenuAction(
842 pParent,
843 QString(KVI_COREACTION_NICKNAMEMENU),
844 QString("dialog.textinput(\"" + __tr2qs("Change Nickname") + "\",\"" + __tr2qs("Please enter the new nickname") + "\",\"" + __tr2qs("OK") + "\",\"" + __tr2qs("Cancel") + R"("){ if($0 == 0 && $1 != "")nick $1; })"),
845 __tr2qs("Change Nickname"),
846 __tr2qs("Shows a popup menu that allows quickly changing the nickname"),
847 KviActionManager::categoryIrc(),
848 "kvi_bigicon_nickpopup.png",
849 KviIconManager::NickPopup,
850 NeedsConnection | NeedsContext)
851 {
852 }
853
popupAboutToShow()854 void KviChangeNickAction::popupAboutToShow()
855 {
856 KviConsoleWindow * c = g_pActiveWindow->console();
857 if(!c)
858 return;
859
860 g_pApp->fillRecentNicknamesPopup(m_pPopup, c);
861
862 m_pPopup->addSeparator();
863 m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::NickPopup)), __tr2qs("Other..."));
864
865 m_pPopup->addSeparator();
866 m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Remove)), __tr2qs("Clear Recent Nicks List"));
867 }
868
869 void KviChangeNickAction::popupActivated(QAction * pAction)
870 {
871 KviConsoleWindow * c = g_pActiveWindow->console();
872 if(!c)
873 return;
874
875 QString text = pAction->text();
876 if(!text.isEmpty())
877 {
878 QString szText;
879 if(__tr2qs("Other...") == text)
880 {
881 activate();
882 }
883 else if(__tr2qs("Clear Recent Nicks List") == text)
884 {
885 KviKvsScript::run("option stringlistRecentNicknames", c);
886 }
887 else
888 {
889 szText = text;
890 szText.prepend("nick ");
891 KviKvsScript::run(szText, c);
892 }
893 }
894 }
895
896 KviConnectToServerAction::KviConnectToServerAction(QObject * pParent)
897 : KviSubmenuAction(
898 pParent,
899 QString(KVI_COREACTION_SERVERMENU),
900 QString("options.edit -n OptionsWidget_servers"),
901 __tr2qs("Connect to"),
902 __tr2qs("Shows a popup menu that allows quickly connecting to a server"),
903 KviActionManager::categoryIrc(),
904 "kvi_bigicon_server.png",
905 KviIconManager::Server,
906 NeedsContext)
907 {
908 }
909
910 void KviConnectToServerAction::popupAboutToShow()
911 {
912 g_pApp->fillRecentServersPopup(m_pPopup);
913 m_pPopup->addSeparator();
914 m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Server)), __tr2qs("Other..."));
915 m_pPopup->addSeparator();
916 m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Remove)), __tr2qs("Clear Recent Servers List"));
917 }
918
919 void KviConnectToServerAction::popupActivated(QAction * pAction)
920 {
921 KviConsoleWindow * c = g_pActiveWindow->console();
922 if(!c)
923 return;
924
925 QString szItemText = pAction->text();
926 if(!szItemText.isEmpty())
927 {
928 if(szItemText == __tr2qs("Other..."))
929 {
930 activate();
931 }
932 else if(szItemText == __tr2qs("Clear Recent Servers List"))
933 {
934 KviKvsScript::run("option stringlistRecentServers", c);
935 }
936 else
937 {
938 KviCString szCommand;
939 QString szText = szItemText;
940 if(KviIrcUrl::parse(szText.toUtf8().data(), szCommand, KVI_IRCURL_CONTEXT_FIRSTFREE))
941 {
942 KviKvsScript::run(szCommand.ptr(), c);
943 }
944 }
945 }
946 }
947
948 KviChangeUserModeAction::KviChangeUserModeAction(QObject * pParent)
949 : KviSubmenuAction(
950 pParent,
951 QString(KVI_COREACTION_USERMODEMENU),
952 QString(""),
953 __tr2qs("User Mode"),
954 __tr2qs("Shows a popup menu that allows quickly changing user modes"),
955 KviActionManager::categoryIrc(),
956 "kvi_bigicon_usermode.png",
957 KviIconManager::UserMode,
958 NeedsContext | NeedsConnection)
959 {
960 }
961
962 void KviChangeUserModeAction::popupAboutToShow()
963 {
964 KviConsoleWindow * c = g_pActiveWindow->console();
965 if(!c)
966 return;
967
968 m_pPopup->clear();
969 QAction * pAction;
970 QString szModes = g_pActiveWindow->connection()->serverInfo()->supportedUserModes();
971
972 pAction = m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::WallOps)), __tr2qs("w: WALLOPS"));
973 pAction->setCheckable(true);
974 pAction->setChecked(c->connection()->userInfo()->hasUserMode('w'));
975
976 if(szModes.contains('s'))
977 {
978 pAction = m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::ServerNotice)), __tr2qs("s: Server Notices"));
979 pAction->setCheckable(true);
980 // Only if the IRCd allows us
981 pAction->setEnabled(c->connection()->serverInfo()->getNeedsOperToSetS() ? c->connection()->userInfo()->hasUserMode('o') : true);
982 pAction->setChecked(c->connection()->userInfo()->hasUserMode('s'));
983 }
984
985 pAction = m_pPopup->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Invisible)), __tr2qs("i: Invisible"));
986 pAction->setCheckable(true);
987 pAction->setChecked(c->connection()->userInfo()->hasUserMode('i'));
988
989 szModes.replace("w", "");
990 szModes.replace("s", "");
991 szModes.replace("i", "");
992 while(!szModes.isEmpty())
993 {
994 QChar ccc = szModes[0];
995 szModes.remove(0, 1);
996 QString modeDesc = c->connection()->serverInfo()->getUserModeDescription(ccc);
997 QChar requiredMode = c->connection()->serverInfo()->getUserModeRequirement(ccc);
998 bool canCheck = true;
999 bool isSet = c->connection()->userInfo()->hasUserMode(ccc.toLatin1());
1000
1001 // See if the usermode is even settable by the user
1002 if(!requiredMode.isNull())
1003 {
1004 // Untouchable
1005 if(requiredMode == '!')
1006 canCheck = false;
1007 else
1008 canCheck = c->connection()->userInfo()->hasUserMode(requiredMode.toLatin1());
1009 }
1010
1011 pAction = m_pPopup->addAction(*(g_pIconManager->getSmallIcon(isSet ? KviIconManager::ChanMode : KviIconManager::UnsetMode)),
1012 !modeDesc.isEmpty() ? modeDesc : QString("%1: Unknown").arg(ccc));
1013 pAction->setEnabled(canCheck);
1014 pAction->setCheckable(true);
1015 pAction->setChecked(isSet);
1016 }
1017 }
1018
1019 void KviChangeUserModeAction::popupActivated(QAction * pAction)
1020 {
1021 KviConsoleWindow * c = g_pActiveWindow->console();
1022 if(!c)
1023 return;
1024
1025 QString text = pAction->text();
1026 if(!c->isConnected())
1027 return;
1028 if(!text.isEmpty() && text[0].isLetter())
1029 {
1030 QChar m = text[0];
1031 QString szNick = c->connection()->userInfo()->nickName();
1032 KviQString::escapeKvs(&szNick);
1033 QString command = "mode ";
1034 command.append(szNick);
1035 command.append(c->connection()->userInfo()->hasUserMode(m) ? " -" : " +");
1036 command.append(m);
1037 KviKvsScript::run(command, c);
1038 }
1039 }
1040
1041 KviGoAwayAction::KviGoAwayAction(QObject * pParent)
1042 : KviKvsAction(
1043 pParent,
1044 QString(KVI_COREACTION_AWAYBACK),
1045 QString("if($away())back; else away -d;"),
1046 __tr2qs("Away/Back"),
1047 __tr2qs("Allows entering and leaving away state"),
1048 KviActionManager::categoryIrc(),
1049 "kvi_bigicon_away.png",
1050 KviIconManager::Away,
1051 KviKvsAction::NeedsContext | KviKvsAction::NeedsConnection,
1052 KVI_SHORTCUTS_AWAY)
1053 {
1054 }
1055
reloadImages()1056 void KviGoAwayAction::reloadImages()
1057 {
1058 activeContextStateChanged();
1059 }
1060
1061 void KviGoAwayAction::activeContextChanged()
1062 {
1063 activeContextStateChanged();
1064 }
1065
1066 void KviGoAwayAction::activeContextStateChanged()
1067 {
1068 std::unordered_set<QAction *> const & bl = actionList();
1069 if(bl.empty())
1070 return;
1071
1072 bool bIconVisibleInMenu = KVI_OPTION_BOOL(KviOption_boolShowIconsInPopupMenus);
1073 QPixmap * p;
1074 QString txt;
1075 KviIrcContext * c = g_pMainWindow->activeContext();
1076 if(c)
1077 {
1078 if(c->state() == KviIrcContext::Connected)
1079 {
1080 if(c->connection()->userInfo()->isAway())
1081 {
1082 p = g_pIconManager->getBigIcon("kvi_bigicon_away.png");
1083 txt = m_szBackString;
1084 }
1085 else
1086 {
1087 p = g_pIconManager->getBigIcon("kvi_bigicon_notaway.png");
1088 txt = m_szAwayString;
1089 }
1090 }
1091 else
1092 {
1093 p = nullptr;
1094 }
1095 }
1096 else
1097 {
1098 p = nullptr;
1099 }
1100
1101 if(p)
1102 {
1103 for(auto & b : bl)
1104 {
1105 if(!b->isEnabled())
1106 b->setEnabled(true);
1107 b->setIcon(QIcon(*p));
1108 b->setText(txt);
1109 b->setIconVisibleInMenu(bIconVisibleInMenu);
1110 }
1111 m_uInternalFlags |= KviAction::Enabled;
1112 }
1113 else
1114 {
1115 for(auto & b : bl)
1116 {
1117 if(b->isEnabled())
1118 b->setEnabled(false);
1119 b->setIconVisibleInMenu(bIconVisibleInMenu);
1120 }
1121 m_uInternalFlags &= ~KviAction::Enabled;
1122 }
1123
1124 setEnabled(true);
1125 }
1126
1127 void KviGoAwayAction::setup()
1128 {
1129 KviKvsAction::setup();
1130 m_szAwayString = __tr2qs("Enter Away Mode");
1131 m_szBackString = __tr2qs("Leave Away Mode");
1132 connect(g_pMainWindow, SIGNAL(activeConnectionAwayStateChanged()), this, SLOT(activeContextStateChanged()));
1133 }
1134
1135 bool KviGoAwayAction::addToPopupMenu(QMenu * p)
1136 {
1137 if(!setupDone())
1138 setup();
1139 KviIrcContext * c = g_pMainWindow->activeContext();
1140 QAction * pAction;
1141 QString t;
1142 if(c)
1143 {
1144 if(c->state() == KviIrcContext::Connected)
1145 {
1146 if(c->connection()->userInfo()->isAway())
1147 {
1148 t = m_szBackString;
1149 if(!m_szKeySequence.isEmpty())
1150 t += '\t' + m_szKeySequence;
1151 p->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::Away)), t, this, SLOT(activate()));
1152 }
1153 else
1154 {
1155 t = m_szAwayString;
1156 if(!m_szKeySequence.isEmpty())
1157 t += '\t' + m_szKeySequence;
1158 p->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::NotAway)), t, this, SLOT(activate()));
1159 }
1160 }
1161 else
1162 {
1163 t = m_szAwayString;
1164 if(!m_szKeySequence.isEmpty())
1165 t += '\t' + m_szKeySequence;
1166 pAction = p->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::NotAway)), t, this, SLOT(activate()));
1167 pAction->setEnabled(false);
1168 }
1169 }
1170 else
1171 {
1172 t = m_szAwayString;
1173 if(!m_szKeySequence.isEmpty())
1174 t += '\t' + m_szKeySequence;
1175 pAction = p->addAction(*(g_pIconManager->getSmallIcon(KviIconManager::NotAway)), t, this, SLOT(activate()));
1176 pAction->setEnabled(false);
1177 }
1178 return true;
1179 }
1180
1181 QAction * KviGoAwayAction::addToCustomToolBar(KviCustomToolBar * t)
1182 {
1183 if(!setupDone())
1184 setup();
1185
1186 QAction * pAction = new QAction(*(g_pIconManager->getBigIcon("kvi_bigicon_away.png")), m_szAwayString, t);
1187 pAction->setStatusTip(m_szAwayString);
1188 pAction->setObjectName(KVI_COREACTION_AWAYBACK);
1189 t->addAction(pAction);
1190 connect(pAction, SIGNAL(triggered()), this, SLOT(activate()));
1191
1192 registerAction(pAction);
1193 activeContextStateChanged();
1194 return pAction;
1195 }
1196
1197 KviIrcToolsAction::KviIrcToolsAction(QObject * pParent)
1198 : KviSubmenuAction(
1199 pParent,
1200 QString(KVI_COREACTION_IRCTOOLS),
1201 QString(""),
1202 __tr2qs("IRC Tools"),
1203 __tr2qs("Shows a popup menu with some IRC tools"),
1204 KviActionManager::categoryIrc(),
1205 "kvi_bigicon_tools.png",
1206 KviIconManager::Tools,
1207 NeedsConnection | NeedsContext)
1208 {
1209 }
1210
1211 void KviIrcToolsAction::popupAboutToShow()
1212 {
1213 m_pPopup->clear();
1214 KviAction * a;
1215 a = KviActionManager::instance()->getAction(KVI_COREACTION_SOCKETSPY);
1216 if(a)
1217 a->addToPopupMenu(m_pPopup);
1218 a = KviActionManager::instance()->getAction(KVI_COREACTION_SEPARATOR);
1219 if(a)
1220 a->addToPopupMenu(m_pPopup);
1221 a = KviActionManager::instance()->getAction(KVI_COREACTION_CHANNELLIST);
1222 if(a)
1223 a->addToPopupMenu(m_pPopup);
1224 a = KviActionManager::instance()->getAction(KVI_COREACTION_NETWORKLINKS);
1225 if(a)
1226 a->addToPopupMenu(m_pPopup);
1227 }
1228
1229 void KviIrcToolsAction::popupActivated(QAction *)
1230 {
1231 }
1232
1233 KviIrcOperationsAction::KviIrcOperationsAction(QObject * pParent)
1234 : KviSubmenuAction(
1235 pParent,
1236 QString(KVI_COREACTION_IRCACTIONS),
1237 QString(""),
1238 __tr2qs("IRC Actions"),
1239 __tr2qs("Shows a popup menu with some IRC actions"),
1240 KviActionManager::categoryIrc(),
1241 "kvi_bigicon_actions.png",
1242 KviIconManager::Action,
1243 NeedsConnection | NeedsContext)
1244 {
1245 }
1246
1247 void KviIrcOperationsAction::popupAboutToShow()
1248 {
1249 m_pPopup->clear();
1250 KviAction * a;
1251 a = KviActionManager::instance()->getAction(KVI_COREACTION_AWAYBACK);
1252 if(a)
1253 a->addToPopupMenu(m_pPopup);
1254 a = KviActionManager::instance()->getAction(KVI_COREACTION_USERMODEMENU);
1255 if(a)
1256 a->addToPopupMenu(m_pPopup);
1257 a = KviActionManager::instance()->getAction(KVI_COREACTION_SEPARATOR);
1258 if(a)
1259 a->addToPopupMenu(m_pPopup);
1260 a = KviActionManager::instance()->getAction(KVI_COREACTION_CHANNELMENU);
1261 if(a)
1262 a->addToPopupMenu(m_pPopup);
1263 a = KviActionManager::instance()->getAction(KVI_COREACTION_NICKNAMEMENU);
1264 if(a)
1265 a->addToPopupMenu(m_pPopup);
1266 a = KviActionManager::instance()->getAction(KVI_COREACTION_SEPARATOR);
1267 if(a)
1268 a->addToPopupMenu(m_pPopup);
1269 a = KviActionManager::instance()->getAction(KVI_COREACTION_SERVERMENU);
1270 if(a)
1271 a->addToPopupMenu(m_pPopup);
1272 }
1273
1274 void KviIrcOperationsAction::popupActivated(QAction *)
1275 {
1276 }
1277