1 //=============================================================================
2 //
3 // File : KviMainWindow.cpp
4 // Creation date : Sun Jun 18 2000 17:59:02 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #define _KVI_FRAME_CPP_
26
27 #include "kvi_debug.h"
28 #include "KviApplication.h"
29 #include "kvi_settings.h"
30 #include "KviMainWindow.h"
31 #include "KviMenuBar.h"
32 #include "KviWindowStack.h"
33 #include "KviIconManager.h"
34 #include "KviWindow.h"
35 #include "KviWindowListBase.h"
36 #include "KviTreeWindowList.h"
37 #include "KviConsoleWindow.h"
38 #include "KviConfigurationFile.h"
39 #include "KviInternalCommand.h"
40 #include "KviTrayIcon.h"
41 #include "KviIrcToolBar.h"
42 #include "kvi_confignames.h"
43 #include "KviModule.h"
44 #include "KviMexToolBar.h"
45 #include "KviLocale.h"
46 #include "KviIrcContext.h"
47 #include "KviStatusBar.h"
48 #include "KviCustomToolBar.h"
49 #include "KviCustomToolBarManager.h"
50 #include "KviCustomToolBarDescriptor.h"
51 #include "KviActionManager.h"
52 #include "kvi_defaults.h"
53 #include "KviIrcView.h"
54 #include "KviKvsScript.h"
55 #include "KviKvsEventTriggers.h"
56 #include "KviTextIconManager.h"
57 #include "KviShortcut.h"
58
59 #define _WANT_OPTION_FLAGS_
60 #include "KviOptions.h"
61
62 #include <QCheckBox>
63 #include <QCloseEvent>
64 #include <QDesktopWidget>
65 #include <QEvent>
66 #include <QFile>
67 #include <QLayout>
68 #include <QLineEdit>
69 #include <QMenu>
70 #include <QMessageBox>
71 #include <QShortcut>
72 #include <QSplitter>
73 #include <QString>
74 #include <QTimer>
75 #include <QVariant>
76 #include <QWindowStateChangeEvent>
77
78 #include <algorithm>
79 #include <ctime>
80
81 #ifdef COMPILE_PSEUDO_TRANSPARENCY
82 #include <QPixmap>
83 // KviApplication.h
84 extern QPixmap * g_pShadedParentGlobalDesktopBackground;
85 extern QPixmap * g_pShadedChildGlobalDesktopBackground;
86 #endif
87
88 #define KVI_DEFAULT_FRAME_CAPTION "KVIrc " KVI_VERSION " " KVI_RELEASE_NAME
89
90 // Declared and managed by KviApplication (KviApplication.cpp)
91 extern KviConfigurationFile * g_pWinPropertiesConfig;
92 KVIRC_API KviMainWindow * g_pMainWindow = nullptr; // the one and only frame object
93
KviMainWindow(QWidget * pParent)94 KviMainWindow::KviMainWindow(QWidget * pParent)
95 : KviTalMainWindow(pParent, "kvirc_frame")
96 {
97 g_pMainWindow = this;
98 setAttribute(Qt::WA_DeleteOnClose);
99 setAutoFillBackground(false);
100 setAttribute(Qt::WA_TranslucentBackground);
101 //disable this flag that gets enabled by qt when using Qt::WA_TranslucentBackground
102 setAttribute(Qt::WA_NoSystemBackground, false);
103 #if !(defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW) || defined(COMPILE_KDE_SUPPORT))
104 // Under windows, the icon is builtin; under kde, KApplication sets it for us
105 // We try to avois this as much as possible, since it forces the use of the low-res 16x16 icon
106 setWindowIcon(*(g_pIconManager->getSmallIcon(KviIconManager::KVIrc)));
107 #endif
108
109 setWindowTitle(KVI_DEFAULT_FRAME_CAPTION);
110
111 m_pSplitter = new QSplitter(Qt::Horizontal, this);
112 m_pSplitter->setObjectName("main_frame_splitter");
113 m_pSplitter->setChildrenCollapsible(false);
114
115 setCentralWidget(m_pSplitter);
116
117 setIconSize(KVI_OPTION_UINT(KviOption_uintToolBarIconSize));
118 setButtonStyle(KVI_OPTION_UINT(KviOption_uintToolBarButtonStyle));
119
120 m_pWindowStack = new KviWindowStack(m_pSplitter, "mdi_manager");
121
122 // This theoretically had to exists before KviWindowStack (that uses enterSdiMode)
123 m_pMenuBar = new KviMenuBar(this, "main_menu_bar");
124 setMenuWidget(m_pMenuBar);
125 #ifndef COMPILE_ON_MAC
126 m_pMenuBar->setVisible(KVI_OPTION_BOOL(KviOption_boolMenuBarVisible));
127 #endif
128
129 if(KVI_OPTION_BOOL(KviOption_boolStatusBarVisible))
130 {
131 m_pStatusBar = new KviStatusBar(this);
132 setStatusBar(m_pStatusBar);
133 // torque: moved out of status bar constructor
134 // because module init functions executed in load()
135 // couldn't access the status bar via g_pMainWindow->mainStatusBar()
136 // (assignment of m_pStatusBar happened after load() and
137 // the init function)
138 m_pStatusBar->load();
139 }
140
141 createWindowList();
142
143 if((KVI_OPTION_RECT(KviOption_rectFrameGeometry).width() < 100) || (KVI_OPTION_RECT(KviOption_rectFrameGeometry).height() < 100) || (KVI_OPTION_RECT(KviOption_rectFrameGeometry).x() > g_pApp->desktop()->width()) || (KVI_OPTION_RECT(KviOption_rectFrameGeometry).y() > g_pApp->desktop()->height()))
144 {
145 // Try to find some reasonable defaults
146 // prefer primary screen for first startup
147 int primary_screen = g_pApp->desktop()->primaryScreen();
148 QRect r = g_pApp->desktop()->screenGeometry(primary_screen);
149 r.setLeft(r.left() + 10);
150 r.setRight(r.right() - 100);
151 r.setTop(r.top() + 10);
152 r.setBottom(r.bottom() - 200);
153 KVI_OPTION_RECT(KviOption_rectFrameGeometry) = r;
154 }
155
156 resize(KVI_OPTION_RECT(KviOption_rectFrameGeometry).width(),
157 KVI_OPTION_RECT(KviOption_rectFrameGeometry).height());
158 move(KVI_OPTION_RECT(KviOption_rectFrameGeometry).x(),
159 KVI_OPTION_RECT(KviOption_rectFrameGeometry).y());
160
161 if(KVI_OPTION_BOOL(KviOption_boolFrameIsMaximized))
162 showMaximized();
163
164 applyOptions();
165
166 installAccelerators();
167 }
168
~KviMainWindow()169 KviMainWindow::~KviMainWindow()
170 {
171 KVI_OPTION_BOOL(KviOption_boolFrameIsMaximized) = isMaximized();
172 KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(pos().x(), pos().y(),
173 size().width(), size().height());
174
175 KVI_OPTION_BOOL(KviOption_boolStatusBarVisible) = m_pStatusBar ? true : false;
176
177 KviCustomToolBarManager::instance()->storeVisibilityState();
178
179 saveToolBarPositions();
180 saveModuleExtensionToolBars();
181
182 // Call the frame destructor callback AFTER saving the toolbar positions
183 // This is because the destructor callback kills alls the KVS objects
184 // and thus the eventual user toolbar objects too and their position
185 // wouldn't be saved if they are shown at startup.
186
187 g_pApp->frameDestructorCallback();
188
189 // Now start killing stuff
190
191 // Explicitly kill all the module extension toolbars: qt has NOT to delete them: we must call their "die" method
192 while(!m_pModuleExtensionToolBarList.empty())
193 {
194 auto & t = *m_pModuleExtensionToolBarList.begin();
195 t->die();
196 }
197
198 KVI_OPTION_BOOL(KviOption_boolShowDockExtension) = m_pTrayIcon != nullptr;
199
200 delete m_pTrayIcon;
201 m_pTrayIcon = nullptr;
202
203 delete m_pStatusBar;
204 m_pStatusBar = nullptr;
205
206 std::vector<KviWindow *> lWinListCopy(m_WinList.begin(), m_WinList.end());
207 // Sort the console windows to the end so they are closed last
208 std::sort(begin(lWinListCopy), end(lWinListCopy), [](KviWindow * a, KviWindow * b){
209 return !a->isConsole() && b->isConsole();
210 });
211
212 for(auto & i : lWinListCopy)
213 closeWindow(i);
214
215 g_pMainWindow = nullptr;
216 }
217
registerModuleExtensionToolBar(KviMexToolBar * t)218 void KviMainWindow::registerModuleExtensionToolBar(KviMexToolBar * t)
219 {
220 m_pModuleExtensionToolBarList.insert(t);
221 }
222
unregisterModuleExtensionToolBar(KviMexToolBar * t)223 void KviMainWindow::unregisterModuleExtensionToolBar(KviMexToolBar * t)
224 {
225 m_pModuleExtensionToolBarList.erase(t);
226 }
227
restoreModuleExtensionToolBars()228 void KviMainWindow::restoreModuleExtensionToolBars()
229 {
230 for(auto szEntry : KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars))
231 {
232 int idx = szEntry.indexOf(':');
233 if(idx != -1)
234 {
235 QString szMod = szEntry.left(idx);
236 szEntry.remove(0, idx + 1);
237 g_pModuleExtensionManager->allocateExtension("toolbar", KviCString(szEntry), firstConsole(), nullptr, nullptr, szMod);
238 }
239 }
240 }
241
saveModuleExtensionToolBars()242 void KviMainWindow::saveModuleExtensionToolBars()
243 {
244 KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars).clear();
245
246 for(auto & t : m_pModuleExtensionToolBarList)
247 {
248 QString s = t->descriptor()->module()->name();
249 s += ':';
250 s += t->descriptor()->name().ptr();
251
252 KVI_OPTION_STRINGLIST(KviOption_stringlistModuleExtensionToolbars).append(s);
253 }
254 }
255
moduleExtensionToolBar(int extensionId)256 KviMexToolBar * KviMainWindow::moduleExtensionToolBar(int extensionId)
257 {
258 for(auto & t : m_pModuleExtensionToolBarList)
259 if(extensionId == t->descriptor()->id())
260 return t;
261
262 return nullptr;
263 }
264
installAccelerators()265 void KviMainWindow::installAccelerators()
266 {
267 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_PREV, this, SLOT(switchToPrevWindow()), nullptr, Qt::ApplicationShortcut));
268 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_NEXT, this, SLOT(switchToNextWindow()), nullptr, Qt::ApplicationShortcut));
269 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_PREV_CONTEXT, this, SLOT(switchToPrevWindowInContext()), nullptr, Qt::ApplicationShortcut));
270 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_NEXT_CONTEXT, this, SLOT(switchToNextWindowInContext()), nullptr, Qt::ApplicationShortcut));
271 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_PREV_HIGHLIGHT, this, SLOT(switchToPrevHighlightedWindow()), nullptr, Qt::ApplicationShortcut));
272 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_NEXT_HIGHLIGHT, this, SLOT(switchToNextHighlightedWindow()), nullptr, Qt::ApplicationShortcut));
273 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_CLOSE, this, SLOT(closeActiveWindow()), nullptr, Qt::ApplicationShortcut));
274 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_PREV_TAB, this, SLOT(switchToPrevWindow()), nullptr, Qt::ApplicationShortcut));
275 m_pAccellerators.push_back(KviShortcut::create(KVI_SHORTCUTS_WIN_NEXT_TAB, this, SLOT(switchToNextWindow()), nullptr, Qt::ApplicationShortcut));
276
277 static int accel_table[] = {
278 Qt::Key_1 + Qt::ControlModifier, // script accels...
279 Qt::Key_2 + Qt::ControlModifier,
280 Qt::Key_3 + Qt::ControlModifier,
281 Qt::Key_4 + Qt::ControlModifier,
282 Qt::Key_5 + Qt::ControlModifier,
283 Qt::Key_6 + Qt::ControlModifier,
284 Qt::Key_7 + Qt::ControlModifier,
285 Qt::Key_8 + Qt::ControlModifier,
286 Qt::Key_9 + Qt::ControlModifier,
287 Qt::Key_0 + Qt::ControlModifier,
288 Qt::Key_F2,
289 Qt::Key_F3,
290 Qt::Key_F4,
291 Qt::Key_F5,
292 Qt::Key_F6,
293 Qt::Key_F7,
294 Qt::Key_F8,
295 Qt::Key_F9,
296 Qt::Key_F10,
297 Qt::Key_F11,
298 Qt::Key_F12,
299 Qt::Key_F1 + Qt::ShiftModifier,
300 Qt::Key_F2 + Qt::ShiftModifier,
301 Qt::Key_F3 + Qt::ShiftModifier,
302 Qt::Key_F4 + Qt::ShiftModifier,
303 Qt::Key_F5 + Qt::ShiftModifier,
304 Qt::Key_F6 + Qt::ShiftModifier,
305 Qt::Key_F7 + Qt::ShiftModifier,
306 Qt::Key_F8 + Qt::ShiftModifier,
307 Qt::Key_F9 + Qt::ShiftModifier,
308 Qt::Key_F10 + Qt::ShiftModifier,
309 Qt::Key_F11 + Qt::ShiftModifier,
310 Qt::Key_F12 + Qt::ShiftModifier
311 };
312
313 for(auto key : accel_table)
314 m_pAccellerators.push_back(KviShortcut::create(key, this, SLOT(accelActivated()), SLOT(accelActivated()), Qt::ApplicationShortcut));
315 }
316
freeAccelleratorKeySequence(const QString & key)317 void KviMainWindow::freeAccelleratorKeySequence(const QString & key)
318 {
319 QKeySequence kS(key);
320 for(auto & pS : m_pAccellerators)
321 {
322 if(pS->key() == kS)
323 {
324 m_pAccellerators.erase(
325 std::remove(m_pAccellerators.begin(), m_pAccellerators.end(), pS),
326 m_pAccellerators.end()
327 );
328 return;
329 }
330 }
331 }
332
accelActivated()333 void KviMainWindow::accelActivated()
334 {
335 KVS_TRIGGER_EVENT_1(KviEvent_OnAccelKeyPressed, g_pActiveWindow, ((qobject_cast<QShortcut *>(sender()))->key()).toString());
336 }
337
executeInternalCommand(int index)338 void KviMainWindow::executeInternalCommand(int index)
339 {
340 KviConsoleWindow * pConsole = nullptr;
341 if(activeContext() && activeContext()->console())
342 pConsole = activeContext()->console();
343 else
344 pConsole = firstConsole();
345 KviKvsScript::run(kvi_getInternalCommandBuffer(index), pConsole);
346 }
347
saveWindowProperties(KviWindow * wnd,const QString & szSection)348 void KviMainWindow::saveWindowProperties(KviWindow * wnd, const QString & szSection)
349 {
350 g_pWinPropertiesConfig->setGroup(szSection);
351 g_pWinPropertiesConfig->writeEntry("EntryTimestamp", (unsigned int)time(nullptr));
352
353 // Allow max 80 window properties to be floating around
354 while(g_pWinPropertiesConfig->groupsCount() > 80)
355 {
356 // Kill the oldest group
357 KviConfigurationFileIterator it(*(g_pWinPropertiesConfig->dict()));
358 QString minKey;
359 unsigned int minVal = time(nullptr);
360 while(it.current() && minVal)
361 {
362 QString * pVal = it.current()->find("EntryTimestamp");
363 if(pVal)
364 {
365 bool bOk;
366 unsigned int uVal = pVal->toUInt(&bOk);
367 if(bOk)
368 {
369 if(uVal < minVal)
370 {
371 minVal = uVal;
372 minKey = it.currentKey();
373 }
374 }
375 else
376 {
377 minVal = 0;
378 minKey = it.currentKey();
379 }
380 }
381 else
382 {
383 minVal = 0;
384 minKey = it.currentKey();
385 }
386 ++it;
387 }
388
389 if(!minKey.isEmpty())
390 g_pWinPropertiesConfig->clearGroup(minKey);
391 else
392 qDebug("Oops! No minimum key found.");
393 }
394
395 // The following line should NOT be needed...but just to be sure...
396 g_pWinPropertiesConfig->setGroup(szSection);
397
398 g_pWinPropertiesConfig->writeEntry("IsDocked", wnd->isDocked());
399
400 wnd->saveProperties(g_pWinPropertiesConfig);
401 }
402
closeActiveWindow()403 void KviMainWindow::closeActiveWindow()
404 {
405 if(!g_pActiveWindow)
406 return;
407 // Don't directly call closeWindow(g_pActiveWindow)
408 // as it won't handle last console closing.
409 g_pActiveWindow->delayedClose();
410 }
411
closeWindow(KviWindow * wnd)412 void KviMainWindow::closeWindow(KviWindow * wnd)
413 {
414 if(wnd->isConsole() && consoleCount() <= 1)
415 {
416 KVS_TRIGGER_EVENT_0(KviEvent_OnFrameWindowDestroyed, wnd);
417 KVS_TRIGGER_EVENT_0(KviEvent_OnKVIrcShutdown, wnd);
418 }
419 // notify the destruction
420 wnd->triggerDestructionEvents();
421
422 // save it's properties
423 if(KVI_OPTION_BOOL(KviOption_boolWindowsRememberProperties))
424 {
425 QString group;
426 wnd->getConfigGroupName(group);
427
428 // not uses default settings : store it always
429 saveWindowProperties(wnd, group);
430 }
431
432 // forget it...
433 const auto iter = std::find(m_WinList.begin(), m_WinList.end(), wnd);
434 if (iter != m_WinList.end())
435 m_WinList.erase(iter);
436
437 if(wnd == g_pActiveWindow)
438 {
439 if(!g_pApp->kviClosingDown())
440 {
441 qDebug("Have no active window: trying to pick one");
442
443 // this happens when there are only minimized windows in the Mdi area
444 // just pick another window to be the active one
445 bool bGotIt = false;
446 for(auto & pOther : m_WinList)
447 {
448 if(wnd != pOther)
449 {
450 windowActivated(pOther);
451 bGotIt = true;
452 break;
453 }
454 }
455
456 if(!bGotIt)
457 {
458 g_pActiveWindow = nullptr;
459 m_pActiveContext = nullptr;
460 }
461 }
462 else
463 {
464 g_pActiveWindow = nullptr;
465 m_pActiveContext = nullptr;
466 }
467 }
468
469 // and shut it down...
470 // KviWindow will call childWindowDestroyed() here
471 if(wnd->isDocked())
472 {
473 //this deletes the wnd, too
474 m_pWindowStack->destroyWindow(wnd);
475 }
476 else
477 {
478 delete wnd;
479 }
480 }
481
addWindow(KviWindow * wnd,bool bShow)482 void KviMainWindow::addWindow(KviWindow * wnd, bool bShow)
483 {
484 m_WinList.push_back(wnd);
485 wnd->createWindowListItem(); // create the window WindowList item AFTER it has been constructed
486
487 QString group;
488 wnd->getConfigGroupName(group);
489
490 bool bDefaultDocking = false;
491
492 if(g_pWinPropertiesConfig->hasGroup(group))
493 {
494 g_pWinPropertiesConfig->setGroup(group);
495 }
496 else if(wnd->isChannel() && g_pWinPropertiesConfig->hasGroup(group = wnd->windowName()))
497 {
498 // try to load pre-4.2 channel settings
499 g_pWinPropertiesConfig->setGroup(group);
500 }
501 else
502 {
503 if(g_pWinPropertiesConfig->hasGroup(wnd->typeString()))
504 {
505 g_pWinPropertiesConfig->setGroup(wnd->typeString());
506 }
507 else
508 {
509 g_pWinPropertiesConfig->setGroup("no_settings_group");
510 wnd->loadProperties(g_pWinPropertiesConfig); // load it anyway (will set defaults if windows don't remember properties)
511 bDefaultDocking = true; // no settings stored
512 }
513 }
514
515 wnd->loadProperties(g_pWinPropertiesConfig); // load it anyway (will set defaults if windows don't remember properties)
516
517 if(KVI_OPTION_BOOL(KviOption_boolWindowsRememberProperties) && !bDefaultDocking)
518 {
519 bool bDocked = g_pWinPropertiesConfig->readBoolEntry("IsDocked", true);
520
521 if(bDocked)
522 {
523 // when group settings are used, we always cascade the windows
524 // this means that windows that have no specialized config group name
525 // are always cascaded : this is true for consoles, queries (and other windows) but not channels (and some other windows)
526 // FIXME: Since the introduction of QMdiArea cascading (and positioning of windows in general) no longer works
527 dockWindow(wnd);
528 wnd->triggerCreationEvents();
529 if(bShow)
530 {
531 m_pWindowStack->showAndActivate(wnd);
532 // Handle the special case of this top level widget not being the active one.
533 // In this situation the child will not get the focusInEvent
534 // and thus will not call out windowActivated() method
535 if(!isActiveWindow())
536 windowActivated(wnd);
537 }
538 }
539 else
540 {
541 wnd->triggerCreationEvents();
542 if(bShow)
543 wnd->show();
544 wnd->youAreUndocked();
545 if(bShow)
546 {
547 wnd->raise();
548 wnd->setFocus();
549 }
550 }
551 }
552 else
553 {
554
555 dockWindow(wnd);
556 wnd->triggerCreationEvents();
557 if(bShow)
558 {
559 m_pWindowStack->showAndActivate(wnd);
560 // Handle the special case of this top level widget not being the active one.
561 // In this situation the child will not get the focusInEvent
562 // and thus will not call out windowActivated() method
563 if(!isActiveWindow())
564 windowActivated(wnd);
565 }
566 }
567
568 // we like to have an active window.. but don't trigger the events until it is really shown
569 if(!g_pActiveWindow)
570 {
571 g_pActiveWindow = wnd;
572 m_pActiveContext = wnd->context();
573 }
574 }
575
dockWindow(KviWindow * wnd)576 void KviMainWindow::dockWindow(KviWindow * wnd)
577 {
578 if(wnd->parentWidget())
579 return; // already docked
580
581 m_pWindowStack->addWindow(wnd);
582 wnd->youAreDocked();
583 }
584
undockWindow(KviWindow * wnd)585 void KviMainWindow::undockWindow(KviWindow * wnd)
586 {
587 if(!(wnd->parentWidget()))
588 return;
589
590 m_pWindowStack->removeWidget(wnd);
591 wnd->setParent(nullptr);
592
593 wnd->show();
594 wnd->youAreUndocked();
595 wnd->raise();
596 wnd->setFocus();
597 }
598
newConsole()599 void KviMainWindow::newConsole()
600 {
601 createNewConsole();
602 }
603
createNewConsole(bool bFirstInFrame,bool bShowIt)604 KviConsoleWindow * KviMainWindow::createNewConsole(bool bFirstInFrame, bool bShowIt)
605 {
606 // the first console must be created BEFORE the toolbars visible
607 // at startup otherwise we cannot execute script code
608 // which is necessary for the actions that are going to be added
609 // to the toolbars
610 KviConsoleWindow * c = new KviConsoleWindow(bFirstInFrame ? KVI_CONSOLE_FLAG_FIRSTINFRAME : 0);
611 addWindow(c, bShowIt);
612
613 if(bFirstInFrame)
614 {
615 restoreModuleExtensionToolBars();
616 KviCustomToolBarManager::instance()->createToolBarsVisibleAtStartup();
617 KviActionManager::instance()->delayedRegisterAccelerators();
618 restoreToolBarPositions();
619 }
620
621 return c;
622 }
623
consoleCount()624 int KviMainWindow::consoleCount()
625 {
626 return std::count_if(begin(m_WinList), end(m_WinList), [](KviWindow * w){ return w->isConsole(); });
627 }
628
firstConsole()629 KviConsoleWindow * KviMainWindow::firstConsole()
630 {
631 for(auto & wnd : m_WinList)
632 if(wnd->isConsole())
633 return qobject_cast<KviConsoleWindow *>(wnd);
634
635 // We end up here when we have not console windows.
636 // This may happen at early startup or late before shutdown.
637 return nullptr;
638 }
639
firstNotConnectedConsole()640 KviConsoleWindow * KviMainWindow::firstNotConnectedConsole()
641 {
642 for(auto & wnd : m_WinList)
643 {
644 if(wnd->type() == KviWindow::Console)
645 {
646 if(!qobject_cast<KviConsoleWindow *>(wnd)->connectionInProgress())
647 return qobject_cast<KviConsoleWindow *>(wnd);
648 }
649 }
650 return nullptr;
651 }
652
childWindowCloseRequest(KviWindow * wnd)653 void KviMainWindow::childWindowCloseRequest(KviWindow * wnd)
654 {
655 closeWindow(wnd);
656 }
657
setActiveWindow(KviWindow * wnd)658 void KviMainWindow::setActiveWindow(KviWindow * wnd)
659 {
660 m_pWindowStack->showAndActivate(wnd);
661 }
662
activeConnection()663 KviIrcConnection * KviMainWindow::activeConnection()
664 {
665 return m_pActiveContext ? m_pActiveContext->connection() : nullptr;
666 }
667
childWindowSelectionStateChange(KviWindow * pWnd,bool bGotSelectionNow)668 void KviMainWindow::childWindowSelectionStateChange(KviWindow * pWnd, bool bGotSelectionNow)
669 {
670 if(pWnd != g_pActiveWindow)
671 return;
672 emit activeWindowSelectionStateChanged(bGotSelectionNow);
673 }
674
childContextStateChange(KviIrcContext * c)675 void KviMainWindow::childContextStateChange(KviIrcContext * c)
676 {
677 if(c != m_pActiveContext)
678 return;
679 emit activeContextStateChanged();
680 }
681
childConnectionLagChange(KviIrcConnection * c)682 void KviMainWindow::childConnectionLagChange(KviIrcConnection * c)
683 {
684 KviIrcContext * ctx = c->context();
685 if(ctx != m_pActiveContext)
686 return;
687 emit activeConnectionLagChanged();
688 }
689
childConnectionServerInfoChange(KviIrcConnection * c)690 void KviMainWindow::childConnectionServerInfoChange(KviIrcConnection * c)
691 {
692 KviIrcContext * ctx = c->context();
693 if(ctx != m_pActiveContext)
694 return;
695 emit activeConnectionServerInfoChanged();
696 }
697
childConnectionNickNameChange(KviIrcConnection * c)698 void KviMainWindow::childConnectionNickNameChange(KviIrcConnection * c)
699 {
700 KviIrcContext * ctx = c->context();
701 if(ctx != m_pActiveContext)
702 return;
703 emit activeConnectionNickNameChanged();
704 }
705
childConnectionAwayStateChange(KviIrcConnection * c)706 void KviMainWindow::childConnectionAwayStateChange(KviIrcConnection * c)
707 {
708 KviIrcContext * ctx = c->context();
709 if(ctx != m_pActiveContext)
710 return;
711 emit activeConnectionAwayStateChanged();
712 }
713
childConnectionUserModeChange(KviIrcConnection * c)714 void KviMainWindow::childConnectionUserModeChange(KviIrcConnection * c)
715 {
716 KviIrcContext * ctx = c->context();
717 if(ctx != m_pActiveContext)
718 return;
719 emit activeConnectionUserModeChanged();
720 }
721
windowActivated(KviWindow * wnd,bool bForce)722 void KviMainWindow::windowActivated(KviWindow * wnd, bool bForce)
723 {
724 if(!wnd)
725 return; // this can happen?
726
727 // unless we want to bForce the active window to be re-activated
728 if(g_pActiveWindow == wnd && !bForce)
729 return;
730
731 if(g_pActiveWindow != wnd)
732 {
733 if(g_pActiveWindow)
734 g_pActiveWindow->lostUserFocus();
735 g_pActiveWindow = wnd;
736 }
737
738 updateWindowTitle(wnd);
739
740 m_pWindowList->setActiveItem(wnd->windowListItem());
741
742 bool bActiveContextChanged = (m_pActiveContext != wnd->context());
743 m_pActiveContext = wnd->context();
744
745 if(g_pActiveWindow->view())
746 g_pActiveWindow->view()->clearUnreaded();
747
748 emit activeWindowChanged();
749 if(bActiveContextChanged)
750 emit activeContextChanged();
751
752 KVS_TRIGGER_EVENT_0(KviEvent_OnWindowActivated, wnd);
753 }
754
changeEvent(QEvent * e)755 void KviMainWindow::changeEvent(QEvent * e)
756 {
757 #ifndef COMPILE_ON_MAC
758 // For Qt5 this should be used to minimize to tray
759 if((e->type() == QEvent::WindowStateChange) && (windowState() & Qt::WindowMinimized) && KVI_OPTION_BOOL(KviOption_boolMinimizeInTray) && e->spontaneous())
760 {
761
762 if(!trayIcon())
763 {
764 executeInternalCommand(KVI_INTERNALCOMMAND_TRAYICON_SHOW);
765 }
766 if(trayIcon())
767 {
768 QWindowStateChangeEvent * ev = static_cast<QWindowStateChangeEvent *>(e);
769 KVI_OPTION_BOOL(KviOption_boolFrameIsMaximized) = ev->oldState() & Qt::WindowMaximized;
770 QTimer::singleShot(0, this, &KviMainWindow::hide);
771 }
772 return;
773 }
774 #endif
775 if(e->type() == QEvent::ActivationChange)
776 {
777 //WINDOW (DE)ACTIVATION
778 // if we have just been activated by the WM
779 // then update the active window task bar item
780 // It will then reset its highlight state
781 // and hopefully make the dock widget work correctly
782 // in this case.
783 // This will also trigger the OnWindowActivated event :)
784 if(g_pActiveWindow)
785 {
786 if(isActiveWindow())
787 windowActivated(g_pActiveWindow, true);
788 else
789 g_pActiveWindow->lostUserFocus();
790 }
791 }
792 KviTalMainWindow::changeEvent(e);
793 }
794
closeEvent(QCloseEvent * e)795 void KviMainWindow::closeEvent(QCloseEvent * e)
796 {
797 //check if the user just want us to minimize in tray; if we're not the sender
798 //of this signal (sender!=0), it has been generated by a "quit" action in a menu
799 if(KVI_OPTION_BOOL(KviOption_boolCloseInTray) && QObject::sender() == nullptr && e->spontaneous())
800 {
801 if(!trayIcon())
802 {
803 executeInternalCommand(KVI_INTERNALCOMMAND_TRAYICON_SHOW);
804 }
805 if(trayIcon())
806 {
807 e->ignore();
808 KVI_OPTION_BOOL(KviOption_boolFrameIsMaximized) = isMaximized();
809 QTimer::singleShot(0, this, &KviMainWindow::hide);
810 }
811 return;
812 }
813
814 if(KVI_OPTION_BOOL(KviOption_boolConfirmCloseWhenThereAreConnections))
815 {
816 // check for running connections
817 bool bGotRunningConnection = false;
818 for(auto & w : m_WinList)
819 {
820 if(w->isConsole() && qobject_cast<KviConsoleWindow *>(w)->connectionInProgress())
821 {
822 bGotRunningConnection = true;
823 break;
824 }
825 }
826
827 if(bGotRunningConnection)
828 {
829 QString txt = __tr2qs("There are active connections, are you sure you wish to quit KVIrc?");
830
831 switch(QMessageBox::warning(this, __tr2qs("Confirm Close - KVIrc"), txt, __tr2qs("&Yes"), __tr2qs("&Always"), __tr2qs("&No"), 2, 2))
832 {
833 case 0:
834 // ok to close
835 break;
836 case 1:
837 // ok to close but don't ask again
838 KVI_OPTION_BOOL(KviOption_boolConfirmCloseWhenThereAreConnections) = false;
839 break;
840 case 2:
841 e->ignore();
842 return;
843 break;
844 }
845 }
846 }
847
848 e->accept();
849
850 if(g_pApp)
851 {
852 g_pApp->setKviClosingDown();
853 g_pApp->quit();
854 }
855 }
856
857 // For Qt4, see changeEvent method for Qt5
hideEvent(QHideEvent * e)858 void KviMainWindow::hideEvent(QHideEvent * e)
859 {
860 #ifndef COMPILE_ON_MAC
861 if(KVI_OPTION_BOOL(KviOption_boolMinimizeInTray) && e->spontaneous())
862 {
863 if(!trayIcon())
864 {
865 executeInternalCommand(KVI_INTERNALCOMMAND_TRAYICON_SHOW);
866 }
867 if(trayIcon())
868 {
869 KVI_OPTION_BOOL(KviOption_boolFrameIsMaximized) = isMaximized();
870 QTimer::singleShot(0, this, &KviMainWindow::hide);
871 }
872 return;
873 }
874 #endif
875 }
876
resizeEvent(QResizeEvent * e)877 void KviMainWindow::resizeEvent(QResizeEvent * e)
878 {
879 KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(pos().x(), pos().y(),
880 size().width(), size().height());
881 KviTalMainWindow::resizeEvent(e);
882 }
883
contextMenuEvent(QContextMenuEvent *)884 void KviMainWindow::contextMenuEvent(QContextMenuEvent *)
885 {
886 // do nothing! avoids builtin popup from qmainwindow
887 }
888
updatePseudoTransparency()889 void KviMainWindow::updatePseudoTransparency()
890 {
891 #ifdef COMPILE_PSEUDO_TRANSPARENCY
892 uint uOpacity = KVI_OPTION_UINT(KviOption_uintGlobalWindowOpacityPercent) < 50 ? 50 : KVI_OPTION_UINT(KviOption_uintGlobalWindowOpacityPercent);
893 setWindowOpacity(uOpacity / 100.f);
894 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
895 #ifndef Q_WS_EX_LAYERED
896 #define Q_WS_EX_LAYERED WS_EX_LAYERED
897 #endif
898 if(uOpacity < 100)
899 {
900 SetWindowLong(reinterpret_cast<HWND>(effectiveWinId()), GWL_EXSTYLE,
901 GetWindowLong(reinterpret_cast<HWND>(effectiveWinId()), GWL_EXSTYLE) | Q_WS_EX_LAYERED);
902 }
903 else
904 {
905 SetWindowLong(reinterpret_cast<HWND>(effectiveWinId()), GWL_EXSTYLE,
906 GetWindowLong(reinterpret_cast<HWND>(effectiveWinId()), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED);
907 }
908 #endif
909 if(g_pShadedParentGlobalDesktopBackground)
910 m_pWindowStack->update();
911
912 if(g_pShadedChildGlobalDesktopBackground)
913 {
914 for(auto & wnd : m_WinList)
915 wnd->updateBackgrounds();
916 m_pWindowList->updatePseudoTransparency();
917 }
918 #endif
919 }
920
moveEvent(QMoveEvent * e)921 void KviMainWindow::moveEvent(QMoveEvent * e)
922 {
923 KVI_OPTION_RECT(KviOption_rectFrameGeometry) = QRect(pos().x(), pos().y(),
924 size().width(), size().height());
925 #ifdef COMPILE_PSEUDO_TRANSPARENCY
926 updatePseudoTransparency();
927 #endif
928 KviTalMainWindow::moveEvent(e);
929 }
930
applyOptions()931 void KviMainWindow::applyOptions()
932 {
933 m_pWindowStack->update();
934
935 for(auto & wnd : m_WinList)
936 wnd->applyOptions();
937
938 m_pWindowList->applyOptions();
939 g_pTextIconManager->applyOptions();
940
941 #ifndef COMPILE_ON_MAC
942 m_pMenuBar->setVisible(KVI_OPTION_BOOL(KviOption_boolMenuBarVisible));
943 #endif
944 }
945
toggleStatusBar()946 void KviMainWindow::toggleStatusBar()
947 {
948 if(m_pStatusBar)
949 {
950 delete m_pStatusBar;
951 m_pStatusBar = nullptr;
952 }
953 else
954 {
955 m_pStatusBar = new KviStatusBar(this);
956 m_pStatusBar->load();
957 setStatusBar(m_pStatusBar);
958 m_pStatusBar->show();
959 }
960 }
961
toggleMenuBar()962 void KviMainWindow::toggleMenuBar()
963 {
964 if(KVI_OPTION_BOOL(KviOption_boolMenuBarVisible) == true)
965 {
966 if(KVI_OPTION_BOOL(KviOption_boolWarnAboutHidingMenuBar))
967 {
968 // ah, we need an abstraction for this setCheckBox() qt5 shiny stuff
969 QMessageBox pMsgBox;
970 QCheckBox cb(__tr2qs("Do not show this message again"));
971 pMsgBox.setText(__tr2qs("This will hide the menu bar completely. "
972 "You can show it again by pressing %1.").arg(QString(KVI_SHORTCUTS_TOGGLE_MENU_BAR)));
973 pMsgBox.setWindowTitle(__tr2qs("Hide Menu Bar - KVIrc"));
974 pMsgBox.setIcon(QMessageBox::Icon::Information);
975 pMsgBox.addButton(QMessageBox::Ok);
976 pMsgBox.addButton(QMessageBox::Cancel);
977 pMsgBox.setDefaultButton(QMessageBox::Ok);
978 pMsgBox.setCheckBox(&cb);
979 if(pMsgBox.exec() == QMessageBox::Ok)
980 {
981 if(cb.isChecked())
982 {
983 KVI_OPTION_BOOL(KviOption_boolWarnAboutHidingMenuBar) = false;
984 }
985 }
986 else
987 {
988 return;
989 }
990 }
991 m_pMenuBar->hide();
992 KVI_OPTION_BOOL(KviOption_boolMenuBarVisible) = false;
993 }
994 else
995 {
996 m_pMenuBar->show();
997 KVI_OPTION_BOOL(KviOption_boolMenuBarVisible) = true;
998 }
999 }
1000
toggleWindowList()1001 void KviMainWindow::toggleWindowList()
1002 {
1003 KVI_OPTION_BOOL(KviOption_boolUseTreeWindowList) = !KVI_OPTION_BOOL(KviOption_boolUseTreeWindowList);
1004 recreateWindowList();
1005 applyOptions();
1006 }
1007
fillToolBarsPopup(QMenu * p)1008 void KviMainWindow::fillToolBarsPopup(QMenu * p)
1009 {
1010 p->clear();
1011
1012 disconnect(p, &QMenu::triggered, this, &KviMainWindow::toolbarsPopupSelected); // just to be sure
1013 connect(p, &QMenu::triggered, this, &KviMainWindow::toolbarsPopupSelected);
1014
1015 int cnt = 0;
1016
1017 KviModuleExtensionDescriptorList * l = g_pModuleExtensionManager->getExtensionList("toolbar");
1018 if(l)
1019 {
1020 for(KviModuleExtensionDescriptor * d = l->first(); d; d = l->next())
1021 {
1022 QString label = __tr2qs("Show %1").arg(d->visibleName());
1023 QAction * pAction;
1024 if(d->icon())
1025 pAction = p->addAction(*(d->icon()), label);
1026 else
1027 pAction = p->addAction(label);
1028 pAction->setCheckable(true);
1029 pAction->setChecked(moduleExtensionToolBar(d->id()));
1030 pAction->setData(d->id());
1031 cnt++;
1032 }
1033 }
1034
1035 // FIXME: Should this display "Hide %1" when the toolbar is already visible ?
1036 KviPointerHashTableIterator<QString, KviCustomToolBarDescriptor> it2(*(KviCustomToolBarManager::instance()->descriptors()));
1037 if(it2.current())
1038 {
1039 if(cnt > 0)
1040 p->addSeparator();
1041
1042 while(KviCustomToolBarDescriptor * d = it2.current())
1043 {
1044 QString label = __tr2qs("Show %1").arg(d->label());
1045 QString ico = d->iconId();
1046 QAction * pAction;
1047 if(!ico.isEmpty())
1048 {
1049 QPixmap * pix = g_pIconManager->getImage(d->iconId());
1050 if(pix)
1051 pAction = p->addAction(*pix, label);
1052 else
1053 pAction = p->addAction(label);
1054 }
1055 else
1056 {
1057 pAction = p->addAction(label);
1058 }
1059 pAction->setData(d->internalId());
1060 pAction->setCheckable(true);
1061 pAction->setChecked(d->toolBar());
1062 ++it2;
1063 cnt++;
1064 }
1065 }
1066
1067 if(cnt > 0)
1068 p->addSeparator();
1069
1070 p->addAction(
1071 *(g_pIconManager->getSmallIcon(KviIconManager::ToolBarEditor)),
1072 __tr2qs("Customize..."),
1073 this,
1074 SLOT(customizeToolBars()));
1075 }
1076
customizeToolBars()1077 void KviMainWindow::customizeToolBars()
1078 {
1079 KviKvsScript::run("toolbareditor.open -t", g_pActiveWindow);
1080 }
1081
toolbarsPopupSelected(QAction * pAction)1082 void KviMainWindow::toolbarsPopupSelected(QAction * pAction)
1083 {
1084 bool bOk;
1085 int idext = pAction->data().toInt(&bOk);
1086 if(!bOk)
1087 return;
1088
1089 KviCustomToolBarDescriptor * dd = KviCustomToolBarManager::instance()->findDescriptorByInternalId(idext);
1090 if(dd)
1091 {
1092 if(dd->toolBar())
1093 dd->toolBar()->deleteLater();
1094 else
1095 dd->createToolBar();
1096 }
1097
1098 if(KviMexToolBar * t = moduleExtensionToolBar(idext))
1099 t->die();
1100 else
1101 g_pModuleExtensionManager->allocateExtension("toolbar", idext, firstConsole());
1102 }
1103
iconSizePopupSelected(QAction * pAction)1104 void KviMainWindow::iconSizePopupSelected(QAction * pAction)
1105 {
1106 if(!pAction)
1107 return;
1108
1109 bool bOk;
1110 uint uSize = pAction->data().toUInt(&bOk);
1111 if(!bOk)
1112 return;
1113
1114 setIconSize(uSize);
1115 g_pApp->optionResetUpdate(KviOption_resetReloadImages);
1116 }
1117
buttonStylePopupSelected(QAction * pAction)1118 void KviMainWindow::buttonStylePopupSelected(QAction * pAction)
1119 {
1120 if(!pAction)
1121 return;
1122
1123 bool bOk;
1124 uint uStyle = pAction->data().toUInt(&bOk);
1125 if(!bOk)
1126 return;
1127
1128 setButtonStyle(uStyle);
1129 }
1130
focusNextPrevChild(bool next)1131 bool KviMainWindow::focusNextPrevChild(bool next)
1132 {
1133 if(QWidget * w = focusWidget(); w)
1134 {
1135 if(w->focusPolicy() == Qt::StrongFocus)
1136 return false;
1137 if(w->parent())
1138 {
1139 QVariant v = w->parent()->property("KviProperty_ChildFocusOwner");
1140 if(v.isValid())
1141 return false; // Do NOT change the focus widget!
1142 }
1143 }
1144 return KviTalMainWindow::focusNextPrevChild(next);
1145 }
1146
updateWindowTitle(KviWindow * wnd)1147 void KviMainWindow::updateWindowTitle(KviWindow * wnd)
1148 {
1149 if(g_pActiveWindow == wnd)
1150 {
1151 QString szCaption = QString("%1 - %2").arg(wnd->windowTitle()).arg(KVI_DEFAULT_FRAME_CAPTION);
1152 setWindowTitle(szCaption);
1153 }
1154 }
1155
1156 //
1157 // Toolbar positioning stuff
1158 //
1159
saveToolBarPositions()1160 void KviMainWindow::saveToolBarPositions()
1161 {
1162 QString szTemp;
1163 g_pApp->getLocalKvircDirectory(szTemp, KviApplication::Config, KVI_CONFIGFILE_TOOLBARS);
1164
1165 QFile f(szTemp);
1166 if(f.open(QIODevice::WriteOnly | QIODevice::Truncate))
1167 f.write(saveState(1));
1168 }
1169
restoreToolBarPositions()1170 void KviMainWindow::restoreToolBarPositions()
1171 {
1172 QString szTemp;
1173 g_pApp->getLocalKvircDirectory(szTemp, KviApplication::Config, KVI_CONFIGFILE_TOOLBARS);
1174
1175 QFile f(szTemp);
1176
1177 if(f.open(QIODevice::ReadOnly))
1178 {
1179 if(!restoreState(f.readAll(), 1))
1180 qDebug("Error while restoring toolbars position");
1181 }
1182
1183 if(m_pWindowList->inherits("KviTreeWindowList"))
1184 {
1185 // ensure that it is not too wide
1186 m_pWindowList->setMaximumWidth(600);
1187 if(m_pWindowList->width() > 600)
1188 m_pWindowList->setFixedWidth(250);
1189 }
1190 }
1191
createWindowList()1192 void KviMainWindow::createWindowList()
1193 {
1194 Qt::DockWidgetArea ePreviousArea = Qt::NoDockWidgetArea;
1195
1196 if(m_pWindowList)
1197 {
1198 ePreviousArea = m_pWindowList->currentDockArea();
1199 delete m_pWindowList;
1200 }
1201
1202 if(KVI_OPTION_BOOL(KviOption_boolUseTreeWindowList))
1203 {
1204 m_pWindowList = new KviTreeWindowList();
1205 m_pWindowList->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
1206 if((ePreviousArea != Qt::LeftDockWidgetArea) && (ePreviousArea != Qt::RightDockWidgetArea))
1207 ePreviousArea = Qt::LeftDockWidgetArea;
1208 }
1209 else
1210 {
1211 m_pWindowList = new KviClassicWindowList();
1212 m_pWindowList->setAllowedAreas(Qt::AllDockWidgetAreas);
1213 if(ePreviousArea == Qt::NoDockWidgetArea || ePreviousArea == Qt::LeftDockWidgetArea || ePreviousArea == Qt::RightDockWidgetArea)
1214 ePreviousArea = Qt::BottomDockWidgetArea;
1215 }
1216 addDockWidget(ePreviousArea, m_pWindowList);
1217 }
1218
recreateWindowList()1219 void KviMainWindow::recreateWindowList()
1220 {
1221 for(auto & w : m_WinList)
1222 w->destroyWindowListItem();
1223
1224 createWindowList();
1225
1226 for(auto & w : m_WinList)
1227 w->createWindowListItem();
1228
1229 if(g_pActiveWindow)
1230 m_pWindowList->setActiveItem(g_pActiveWindow->windowListItem());
1231 }
1232
1233 //
1234 // Some accelerators
1235 //
1236
switchToPrevWindow()1237 void KviMainWindow::switchToPrevWindow()
1238 {
1239 m_pWindowList->switchWindow(false, false);
1240 }
1241
switchToNextWindow()1242 void KviMainWindow::switchToNextWindow()
1243 {
1244 m_pWindowList->switchWindow(true, false);
1245 }
1246
switchToPrevHighlightedWindow()1247 void KviMainWindow::switchToPrevHighlightedWindow()
1248 {
1249 m_pWindowList->switchWindow(false, false, true);
1250 }
1251
switchToNextHighlightedWindow()1252 void KviMainWindow::switchToNextHighlightedWindow()
1253 {
1254 m_pWindowList->switchWindow(true, false, true);
1255 }
1256
switchToPrevWindowInContext()1257 void KviMainWindow::switchToPrevWindowInContext()
1258 {
1259 m_pWindowList->switchWindow(false, true);
1260 }
1261
switchToNextWindowInContext()1262 void KviMainWindow::switchToNextWindowInContext()
1263 {
1264 m_pWindowList->switchWindow(true, true);
1265 }
1266
setIconSize(unsigned int uSize)1267 void KviMainWindow::setIconSize(unsigned int uSize)
1268 {
1269 if((uSize != 16) && (uSize != 22) && (uSize != 32) && (uSize != 48))
1270 uSize = 22;
1271
1272 KVI_OPTION_UINT(KviOption_uintToolBarIconSize) = uSize;
1273
1274 QSize sSize(uSize, uSize);
1275
1276 KviTalMainWindow::setIconSize(sSize);
1277
1278 for(auto & t : m_pModuleExtensionToolBarList)
1279 {
1280 t->setIconSize(sSize);
1281 t->update();
1282 }
1283
1284 KviPointerHashTableIterator<QString, KviCustomToolBarDescriptor> it2(*(KviCustomToolBarManager::instance()->descriptors()));
1285 if(it2.current())
1286 {
1287 while(KviCustomToolBarDescriptor * d = it2.current())
1288 {
1289 if(d->toolBar())
1290 {
1291 d->toolBar()->setIconSize(sSize);
1292 d->toolBar()->update();
1293 }
1294 ++it2;
1295 }
1296 }
1297 }
1298
setButtonStyle(unsigned int uStyle)1299 void KviMainWindow::setButtonStyle(unsigned int uStyle)
1300 {
1301
1302 KVI_OPTION_UINT(KviOption_uintToolBarButtonStyle) = uStyle;
1303
1304 for(auto & t : m_pModuleExtensionToolBarList)
1305 {
1306 t->setToolButtonStyle((Qt::ToolButtonStyle)uStyle);
1307 t->update();
1308 }
1309
1310 KviPointerHashTableIterator<QString, KviCustomToolBarDescriptor> it2(*(KviCustomToolBarManager::instance()->descriptors()));
1311 if(it2.current())
1312 {
1313 while(KviCustomToolBarDescriptor * d = it2.current())
1314 {
1315 if(d->toolBar())
1316 {
1317 d->toolBar()->setToolButtonStyle((Qt::ToolButtonStyle)uStyle);
1318 d->toolBar()->update();
1319 }
1320 ++it2;
1321 }
1322 }
1323 }
1324