1 /*
2 SPDX-FileCopyrightText: 2008-2014 Eike Hein <hein@kde.org>
3 SPDX-FileCopyrightText: 2009 Juan Carlos Torres <carlosdgtorres@gmail.com>
4
5 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
6 */
7
8 #include "sessionstack.h"
9 #include "settings.h"
10 #include "terminal.h"
11 #include "visualeventoverlay.h"
12
13 #include <config-yakuake.h>
14
15 #include <KLocalizedString>
16 #include <KMessageBox>
17 #include <KNotification>
18
19 #include <QDBusConnection>
20
21 static bool show_disallow_certain_dbus_methods_message = true;
22
SessionStack(QWidget * parent)23 SessionStack::SessionStack(QWidget *parent)
24 : QStackedWidget(parent)
25 {
26 QDBusConnection::sessionBus().registerObject(QStringLiteral("/yakuake/sessions"), this, QDBusConnection::ExportScriptableSlots);
27
28 m_activeSessionId = -1;
29
30 m_visualEventOverlay = new VisualEventOverlay(this);
31 connect(this, SIGNAL(removeTerminalHighlight()), m_visualEventOverlay, SLOT(removeTerminalHighlight()));
32 }
33
~SessionStack()34 SessionStack::~SessionStack()
35 {
36 }
37
addSessionImpl(Session::SessionType type)38 int SessionStack::addSessionImpl(Session::SessionType type)
39 {
40 Session *currentSession = m_sessions.value(activeSessionId());
41 Terminal *currentTerminal = currentSession ? currentSession->getTerminal(currentSession->activeTerminalId()) : nullptr;
42 QString workingDir = currentTerminal ? currentTerminal->currentWorkingDirectory() : QString();
43
44 Session *session = new Session(workingDir, type, this);
45 // clang-format off
46 connect(session, SIGNAL(titleChanged(int,QString)), this, SIGNAL(titleChanged(int,QString)));
47 connect(session, SIGNAL(terminalManuallyActivated(Terminal*)), this, SLOT(handleManualTerminalActivation(Terminal*)));
48 connect(session, SIGNAL(keyboardInputBlocked(Terminal*)), m_visualEventOverlay, SLOT(indicateKeyboardInputBlocked(Terminal*)));
49 connect(session, SIGNAL(activityDetected(Terminal*)), parentWidget(), SLOT(handleTerminalActivity(Terminal*)));
50 connect(session, SIGNAL(silenceDetected(Terminal*)), parentWidget(), SLOT(handleTerminalSilence(Terminal*)));
51 connect(parentWidget(), SIGNAL(windowClosed()), session, SLOT(reconnectMonitorActivitySignals()));
52 // clang-format on
53 connect(session, SIGNAL(destroyed(int)), this, SLOT(cleanup(int)));
54
55 addWidget(session->widget());
56
57 m_sessions.insert(session->id(), session);
58
59 if (Settings::dynamicTabTitles())
60 Q_EMIT sessionAdded(session->id(), session->title());
61 else
62 Q_EMIT sessionAdded(session->id(), QString());
63
64 return session->id();
65 }
66
addSession()67 int SessionStack::addSession()
68 {
69 return addSessionImpl(Session::Single);
70 }
71
addSessionTwoHorizontal()72 int SessionStack::addSessionTwoHorizontal()
73 {
74 return addSessionImpl(Session::TwoHorizontal);
75 }
76
addSessionTwoVertical()77 int SessionStack::addSessionTwoVertical()
78 {
79 return addSessionImpl(Session::TwoVertical);
80 }
81
addSessionQuad()82 int SessionStack::addSessionQuad()
83 {
84 return addSessionImpl(Session::Quad);
85 }
86
raiseSession(int sessionId)87 void SessionStack::raiseSession(int sessionId)
88 {
89 if (sessionId == -1 || !m_sessions.contains(sessionId))
90 return;
91 Session *session = m_sessions.value(sessionId);
92
93 if (!m_visualEventOverlay->isHidden())
94 m_visualEventOverlay->hide();
95
96 if (m_activeSessionId != -1 && m_sessions.contains(m_activeSessionId)) {
97 Session *oldActiveSession = m_sessions.value(m_activeSessionId);
98
99 disconnect(oldActiveSession, SLOT(closeTerminal()));
100 disconnect(oldActiveSession, SLOT(focusPreviousTerminal()));
101 disconnect(oldActiveSession, SLOT(focusNextTerminal()));
102 disconnect(oldActiveSession, SLOT(manageProfiles()));
103 disconnect(oldActiveSession, SIGNAL(titleChanged(QString)), this, SIGNAL(activeTitleChanged(QString)));
104
105 oldActiveSession->reconnectMonitorActivitySignals();
106 }
107
108 m_activeSessionId = sessionId;
109
110 setCurrentWidget(session->widget());
111
112 if (session->widget()->focusWidget())
113 session->widget()->focusWidget()->setFocus();
114
115 if (session->hasTerminalsWithKeyboardInputDisabled())
116 m_visualEventOverlay->show();
117
118 connect(this, SIGNAL(closeTerminal()), session, SLOT(closeTerminal()));
119 connect(this, SIGNAL(previousTerminal()), session, SLOT(focusPreviousTerminal()));
120 connect(this, SIGNAL(nextTerminal()), session, SLOT(focusNextTerminal()));
121 connect(this, SIGNAL(manageProfiles()), session, SLOT(manageProfiles()));
122 connect(session, SIGNAL(titleChanged(QString)), this, SIGNAL(activeTitleChanged(QString)));
123
124 Q_EMIT sessionRaised(sessionId);
125
126 Q_EMIT activeTitleChanged(session->title());
127 }
128
removeSession(int sessionId)129 void SessionStack::removeSession(int sessionId)
130 {
131 if (sessionId == -1)
132 sessionId = m_activeSessionId;
133 if (sessionId == -1)
134 return;
135 if (!m_sessions.contains(sessionId))
136 return;
137
138 if (queryClose(sessionId, QueryCloseSession))
139 m_sessions.value(sessionId)->deleteLater();
140 }
141
removeTerminal(int terminalId)142 void SessionStack::removeTerminal(int terminalId)
143 {
144 int sessionId = sessionIdForTerminalId(terminalId);
145
146 if (terminalId == -1) {
147 if (m_activeSessionId == -1)
148 return;
149 if (!m_sessions.contains(m_activeSessionId))
150 return;
151
152 if (m_sessions.value(m_activeSessionId)->closable())
153 m_sessions.value(m_activeSessionId)->closeTerminal();
154 } else {
155 if (m_sessions.value(sessionId)->closable())
156 m_sessions.value(sessionId)->closeTerminal(terminalId);
157 }
158 }
159
closeActiveTerminal(int sessionId)160 void SessionStack::closeActiveTerminal(int sessionId)
161 {
162 if (sessionId == -1)
163 sessionId = m_activeSessionId;
164 if (sessionId == -1)
165 return;
166 if (!m_sessions.contains(sessionId))
167 return;
168
169 if (queryClose(sessionId, QueryCloseTerminal))
170 m_sessions.value(sessionId)->closeTerminal();
171 }
172
cleanup(int sessionId)173 void SessionStack::cleanup(int sessionId)
174 {
175 if (sessionId == m_activeSessionId)
176 m_activeSessionId = -1;
177
178 m_sessions.remove(sessionId);
179
180 Q_EMIT sessionRemoved(sessionId);
181 }
182
activeTerminalId()183 int SessionStack::activeTerminalId()
184 {
185 if (!m_sessions.contains(m_activeSessionId))
186 return -1;
187
188 return m_sessions.value(m_activeSessionId)->activeTerminalId();
189 }
190
sessionIdList()191 const QString SessionStack::sessionIdList()
192 {
193 QList<int> keyList = m_sessions.keys();
194 QStringList idList;
195
196 QListIterator<int> i(keyList);
197
198 while (i.hasNext())
199 idList << QString::number(i.next());
200
201 return idList.join(QLatin1Char(','));
202 }
203
terminalIdList()204 const QString SessionStack::terminalIdList()
205 {
206 QStringList idList;
207
208 QHashIterator<int, Session *> it(m_sessions);
209
210 while (it.hasNext()) {
211 it.next();
212
213 idList << it.value()->terminalIdList();
214 }
215
216 return idList.join(QLatin1Char(','));
217 }
218
terminalIdsForSessionId(int sessionId)219 const QString SessionStack::terminalIdsForSessionId(int sessionId)
220 {
221 if (!m_sessions.contains(sessionId))
222 return QString::number(-1);
223
224 return m_sessions.value(sessionId)->terminalIdList();
225 }
226
sessionIdForTerminalId(int terminalId)227 int SessionStack::sessionIdForTerminalId(int terminalId)
228 {
229 int sessionId = -1;
230
231 QHashIterator<int, Session *> it(m_sessions);
232
233 while (it.hasNext()) {
234 it.next();
235
236 if (it.value()->hasTerminal(terminalId)) {
237 sessionId = it.key();
238
239 break;
240 }
241 }
242
243 return sessionId;
244 }
245
warnAboutDBus()246 static void warnAboutDBus()
247 {
248 #if !defined(REMOVE_SENDTEXT_RUNCOMMAND_DBUS_METHODS)
249 if (show_disallow_certain_dbus_methods_message) {
250 KNotification::event(
251 KNotification::Warning,
252 QStringLiteral("Yakuake D-Bus Warning"),
253 i18n("The D-Bus method runCommand was just used. There are security concerns about allowing these methods to be public. If desired, these "
254 "methods can be changed to internal use only by re-compiling Yakuake. <p>This warning will only show once for this Yakuake instance.</p>"));
255 show_disallow_certain_dbus_methods_message = false;
256 }
257 #endif
258 }
259
runCommand(const QString & command)260 void SessionStack::runCommand(const QString &command)
261 {
262 warnAboutDBus();
263
264 if (m_activeSessionId == -1)
265 return;
266 if (!m_sessions.contains(m_activeSessionId))
267 return;
268
269 m_sessions.value(m_activeSessionId)->runCommand(command);
270 }
271
runCommandInTerminal(int terminalId,const QString & command)272 void SessionStack::runCommandInTerminal(int terminalId, const QString &command)
273 {
274 warnAboutDBus();
275
276 QHashIterator<int, Session *> it(m_sessions);
277
278 while (it.hasNext()) {
279 it.next();
280
281 it.value()->runCommand(command, terminalId);
282 }
283 }
284
isSessionClosable(int sessionId)285 bool SessionStack::isSessionClosable(int sessionId)
286 {
287 if (sessionId == -1)
288 sessionId = m_activeSessionId;
289 if (sessionId == -1)
290 return false;
291 if (!m_sessions.contains(sessionId))
292 return false;
293
294 return m_sessions.value(sessionId)->closable();
295 }
296
setSessionClosable(int sessionId,bool closable)297 void SessionStack::setSessionClosable(int sessionId, bool closable)
298 {
299 if (sessionId == -1)
300 sessionId = m_activeSessionId;
301 if (sessionId == -1)
302 return;
303 if (!m_sessions.contains(sessionId))
304 return;
305
306 m_sessions.value(sessionId)->setClosable(closable);
307 }
308
hasUnclosableSessions() const309 bool SessionStack::hasUnclosableSessions() const
310 {
311 QHashIterator<int, Session *> it(m_sessions);
312
313 while (it.hasNext()) {
314 it.next();
315
316 if (!it.value()->closable())
317 return true;
318 }
319
320 return false;
321 }
322
isSessionKeyboardInputEnabled(int sessionId)323 bool SessionStack::isSessionKeyboardInputEnabled(int sessionId)
324 {
325 if (sessionId == -1)
326 sessionId = m_activeSessionId;
327 if (sessionId == -1)
328 return false;
329 if (!m_sessions.contains(sessionId))
330 return false;
331
332 return m_sessions.value(sessionId)->keyboardInputEnabled();
333 }
334
setSessionKeyboardInputEnabled(int sessionId,bool enabled)335 void SessionStack::setSessionKeyboardInputEnabled(int sessionId, bool enabled)
336 {
337 if (sessionId == -1)
338 sessionId = m_activeSessionId;
339 if (sessionId == -1)
340 return;
341 if (!m_sessions.contains(sessionId))
342 return;
343
344 m_sessions.value(sessionId)->setKeyboardInputEnabled(enabled);
345
346 if (sessionId == m_activeSessionId) {
347 if (enabled)
348 m_visualEventOverlay->hide();
349 else
350 m_visualEventOverlay->show();
351 }
352 }
353
isTerminalKeyboardInputEnabled(int terminalId)354 bool SessionStack::isTerminalKeyboardInputEnabled(int terminalId)
355 {
356 int sessionId = sessionIdForTerminalId(terminalId);
357 if (sessionId == -1)
358 return false;
359 if (!m_sessions.contains(sessionId))
360 return false;
361
362 return m_sessions.value(sessionId)->keyboardInputEnabled(terminalId);
363 }
364
setTerminalKeyboardInputEnabled(int terminalId,bool enabled)365 void SessionStack::setTerminalKeyboardInputEnabled(int terminalId, bool enabled)
366 {
367 int sessionId = sessionIdForTerminalId(terminalId);
368 if (sessionId == -1)
369 return;
370 if (!m_sessions.contains(sessionId))
371 return;
372
373 m_sessions.value(sessionId)->setKeyboardInputEnabled(terminalId, enabled);
374
375 if (sessionId == m_activeSessionId) {
376 if (enabled)
377 m_visualEventOverlay->hide();
378 else
379 m_visualEventOverlay->show();
380 }
381 }
382
hasTerminalsWithKeyboardInputEnabled(int sessionId)383 bool SessionStack::hasTerminalsWithKeyboardInputEnabled(int sessionId)
384 {
385 if (sessionId == -1)
386 sessionId = m_activeSessionId;
387 if (sessionId == -1)
388 return false;
389 if (!m_sessions.contains(sessionId))
390 return false;
391
392 return m_sessions.value(sessionId)->hasTerminalsWithKeyboardInputEnabled();
393 }
394
hasTerminalsWithKeyboardInputDisabled(int sessionId)395 bool SessionStack::hasTerminalsWithKeyboardInputDisabled(int sessionId)
396 {
397 if (sessionId == -1)
398 sessionId = m_activeSessionId;
399 if (sessionId == -1)
400 return false;
401 if (!m_sessions.contains(sessionId))
402 return false;
403
404 return m_sessions.value(sessionId)->hasTerminalsWithKeyboardInputDisabled();
405 }
406
isSessionMonitorActivityEnabled(int sessionId)407 bool SessionStack::isSessionMonitorActivityEnabled(int sessionId)
408 {
409 if (sessionId == -1)
410 sessionId = m_activeSessionId;
411 if (sessionId == -1)
412 return false;
413 if (!m_sessions.contains(sessionId))
414 return false;
415
416 return m_sessions.value(sessionId)->monitorActivityEnabled();
417 }
418
setSessionMonitorActivityEnabled(int sessionId,bool enabled)419 void SessionStack::setSessionMonitorActivityEnabled(int sessionId, bool enabled)
420 {
421 if (sessionId == -1)
422 sessionId = m_activeSessionId;
423 if (sessionId == -1)
424 return;
425 if (!m_sessions.contains(sessionId))
426 return;
427
428 m_sessions.value(sessionId)->setMonitorActivityEnabled(enabled);
429 }
430
isTerminalMonitorActivityEnabled(int terminalId)431 bool SessionStack::isTerminalMonitorActivityEnabled(int terminalId)
432 {
433 int sessionId = sessionIdForTerminalId(terminalId);
434 if (sessionId == -1)
435 return false;
436 if (!m_sessions.contains(sessionId))
437 return false;
438
439 return m_sessions.value(sessionId)->monitorActivityEnabled(terminalId);
440 }
441
setTerminalMonitorActivityEnabled(int terminalId,bool enabled)442 void SessionStack::setTerminalMonitorActivityEnabled(int terminalId, bool enabled)
443 {
444 int sessionId = sessionIdForTerminalId(terminalId);
445 if (sessionId == -1)
446 return;
447 if (!m_sessions.contains(sessionId))
448 return;
449
450 m_sessions.value(sessionId)->setMonitorActivityEnabled(terminalId, enabled);
451 }
452
hasTerminalsWithMonitorActivityEnabled(int sessionId)453 bool SessionStack::hasTerminalsWithMonitorActivityEnabled(int sessionId)
454 {
455 if (sessionId == -1)
456 sessionId = m_activeSessionId;
457 if (sessionId == -1)
458 return false;
459 if (!m_sessions.contains(sessionId))
460 return false;
461
462 return m_sessions.value(sessionId)->hasTerminalsWithMonitorActivityEnabled();
463 }
464
hasTerminalsWithMonitorActivityDisabled(int sessionId)465 bool SessionStack::hasTerminalsWithMonitorActivityDisabled(int sessionId)
466 {
467 if (sessionId == -1)
468 sessionId = m_activeSessionId;
469 if (sessionId == -1)
470 return false;
471 if (!m_sessions.contains(sessionId))
472 return false;
473
474 return m_sessions.value(sessionId)->hasTerminalsWithMonitorActivityDisabled();
475 }
476
isSessionMonitorSilenceEnabled(int sessionId)477 bool SessionStack::isSessionMonitorSilenceEnabled(int sessionId)
478 {
479 if (sessionId == -1)
480 sessionId = m_activeSessionId;
481 if (sessionId == -1)
482 return false;
483 if (!m_sessions.contains(sessionId))
484 return false;
485
486 return m_sessions.value(sessionId)->monitorSilenceEnabled();
487 }
488
setSessionMonitorSilenceEnabled(int sessionId,bool enabled)489 void SessionStack::setSessionMonitorSilenceEnabled(int sessionId, bool enabled)
490 {
491 if (sessionId == -1)
492 sessionId = m_activeSessionId;
493 if (sessionId == -1)
494 return;
495 if (!m_sessions.contains(sessionId))
496 return;
497
498 m_sessions.value(sessionId)->setMonitorSilenceEnabled(enabled);
499 }
500
isTerminalMonitorSilenceEnabled(int terminalId)501 bool SessionStack::isTerminalMonitorSilenceEnabled(int terminalId)
502 {
503 int sessionId = sessionIdForTerminalId(terminalId);
504 if (sessionId == -1)
505 return false;
506 if (!m_sessions.contains(sessionId))
507 return false;
508
509 return m_sessions.value(sessionId)->monitorSilenceEnabled(terminalId);
510 }
511
setTerminalMonitorSilenceEnabled(int terminalId,bool enabled)512 void SessionStack::setTerminalMonitorSilenceEnabled(int terminalId, bool enabled)
513 {
514 int sessionId = sessionIdForTerminalId(terminalId);
515 if (sessionId == -1)
516 return;
517 if (!m_sessions.contains(sessionId))
518 return;
519
520 m_sessions.value(sessionId)->setMonitorSilenceEnabled(terminalId, enabled);
521 }
522
hasTerminalsWithMonitorSilenceEnabled(int sessionId)523 bool SessionStack::hasTerminalsWithMonitorSilenceEnabled(int sessionId)
524 {
525 if (sessionId == -1)
526 sessionId = m_activeSessionId;
527 if (sessionId == -1)
528 return false;
529 if (!m_sessions.contains(sessionId))
530 return false;
531
532 return m_sessions.value(sessionId)->hasTerminalsWithMonitorSilenceEnabled();
533 }
534
hasTerminalsWithMonitorSilenceDisabled(int sessionId)535 bool SessionStack::hasTerminalsWithMonitorSilenceDisabled(int sessionId)
536 {
537 if (sessionId == -1)
538 sessionId = m_activeSessionId;
539 if (sessionId == -1)
540 return false;
541 if (!m_sessions.contains(sessionId))
542 return false;
543
544 return m_sessions.value(sessionId)->hasTerminalsWithMonitorSilenceDisabled();
545 }
546
editProfile(int sessionId)547 void SessionStack::editProfile(int sessionId)
548 {
549 if (sessionId == -1)
550 sessionId = m_activeSessionId;
551 if (sessionId == -1)
552 return;
553 if (!m_sessions.contains(sessionId))
554 return;
555
556 m_sessions.value(sessionId)->editProfile();
557 }
558
splitSessionLeftRight(int sessionId)559 int SessionStack::splitSessionLeftRight(int sessionId)
560 {
561 if (sessionId == -1)
562 return -1;
563 if (!m_sessions.contains(sessionId))
564 return -1;
565
566 return m_sessions.value(sessionId)->splitLeftRight();
567 }
568
splitSessionTopBottom(int sessionId)569 int SessionStack::splitSessionTopBottom(int sessionId)
570 {
571 if (sessionId == -1)
572 return -1;
573 if (!m_sessions.contains(sessionId))
574 return -1;
575
576 return m_sessions.value(sessionId)->splitTopBottom();
577 }
578
splitTerminalLeftRight(int terminalId)579 int SessionStack::splitTerminalLeftRight(int terminalId)
580 {
581 int sessionId = sessionIdForTerminalId(terminalId);
582
583 if (sessionId == -1)
584 return -1;
585
586 return m_sessions.value(sessionId)->splitLeftRight(terminalId);
587 }
588
splitTerminalTopBottom(int terminalId)589 int SessionStack::splitTerminalTopBottom(int terminalId)
590 {
591 int sessionId = sessionIdForTerminalId(terminalId);
592
593 if (sessionId == -1)
594 return -1;
595
596 return m_sessions.value(sessionId)->splitTopBottom(terminalId);
597 }
598
tryGrowTerminalRight(int terminalId,uint pixels)599 int SessionStack::tryGrowTerminalRight(int terminalId, uint pixels)
600 {
601 int sessionId = sessionIdForTerminalId(terminalId);
602
603 if (sessionId == -1)
604 return -1;
605
606 return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Right, pixels);
607 }
608
tryGrowTerminalLeft(int terminalId,uint pixels)609 int SessionStack::tryGrowTerminalLeft(int terminalId, uint pixels)
610 {
611 int sessionId = sessionIdForTerminalId(terminalId);
612
613 if (sessionId == -1)
614 return -1;
615
616 return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Left, pixels);
617 }
618
tryGrowTerminalTop(int terminalId,uint pixels)619 int SessionStack::tryGrowTerminalTop(int terminalId, uint pixels)
620 {
621 int sessionId = sessionIdForTerminalId(terminalId);
622
623 if (sessionId == -1)
624 return -1;
625
626 return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Up, pixels);
627 }
628
tryGrowTerminalBottom(int terminalId,uint pixels)629 int SessionStack::tryGrowTerminalBottom(int terminalId, uint pixels)
630 {
631 int sessionId = sessionIdForTerminalId(terminalId);
632
633 if (sessionId == -1)
634 return -1;
635
636 return m_sessions.value(sessionId)->tryGrowTerminal(terminalId, Session::Down, pixels);
637 }
638
emitTitles()639 void SessionStack::emitTitles()
640 {
641 QString title;
642
643 QHashIterator<int, Session *> it(m_sessions);
644
645 while (it.hasNext()) {
646 it.next();
647
648 title = it.value()->title();
649
650 if (!title.isEmpty())
651 Q_EMIT titleChanged(it.value()->id(), title);
652 }
653 }
654
requiresVisualEventOverlay()655 bool SessionStack::requiresVisualEventOverlay()
656 {
657 if (m_activeSessionId == -1)
658 return false;
659 if (!m_sessions.contains(m_activeSessionId))
660 return false;
661
662 return m_sessions.value(m_activeSessionId)->hasTerminalsWithKeyboardInputDisabled();
663 }
664
handleTerminalHighlightRequest(int terminalId)665 void SessionStack::handleTerminalHighlightRequest(int terminalId)
666 {
667 Terminal *terminal = nullptr;
668
669 QHashIterator<int, Session *> it(m_sessions);
670
671 while (it.hasNext()) {
672 it.next();
673
674 terminal = it.value()->getTerminal(terminalId);
675
676 if (terminal && it.value()->id() == m_activeSessionId) {
677 m_visualEventOverlay->highlightTerminal(terminal, true);
678
679 break;
680 }
681 }
682 }
683
showEvent(QShowEvent * event)684 void SessionStack::showEvent(QShowEvent *event)
685 {
686 Q_UNUSED(event)
687
688 if (m_activeSessionId == -1)
689 return;
690 if (!m_sessions.contains(m_activeSessionId))
691 return;
692
693 Terminal *terminal = m_sessions.value(m_activeSessionId)->getTerminal(activeTerminalId());
694
695 if (terminal) {
696 QWidget *terminalWidget = terminal->terminalWidget();
697 if (terminalWidget)
698 terminalWidget->setFocus();
699 }
700 }
701
handleManualTerminalActivation(Terminal * terminal)702 void SessionStack::handleManualTerminalActivation(Terminal *terminal)
703 {
704 if (!Settings::terminalHighlightOnManualActivation())
705 return;
706
707 Session *session = qobject_cast<Session *>(QObject::sender());
708
709 if (session->terminalCount() > 1)
710 m_visualEventOverlay->highlightTerminal(terminal, false);
711 }
712
queryClose(int sessionId,QueryCloseType type)713 bool SessionStack::queryClose(int sessionId, QueryCloseType type)
714 {
715 if (!m_sessions.contains(sessionId))
716 return false;
717
718 if (!m_sessions.value(sessionId)->closable()) {
719 QString closeQuestionIntro = xi18nc("@info", "<warning>You have locked this session to prevent accidental closing of terminals.</warning>");
720 QString closeQuestion;
721
722 if (type == QueryCloseSession)
723 closeQuestion = xi18nc("@info", "Are you sure you want to close this session?");
724 else if (type == QueryCloseTerminal)
725 closeQuestion = xi18nc("@info", "Are you sure you want to close this terminal?");
726
727 int result = KMessageBox::warningContinueCancel(this,
728 closeQuestionIntro + QStringLiteral("<br/><br/>") + closeQuestion,
729 xi18nc("@title:window", "Really Close?"),
730 KStandardGuiItem::close(),
731 KStandardGuiItem::cancel());
732
733 if (result != KMessageBox::Continue)
734 return false;
735 }
736
737 return true;
738 }
739
getPartActionCollections()740 QList<KActionCollection *> SessionStack::getPartActionCollections()
741 {
742 QList<KActionCollection *> actionCollections;
743
744 const auto sessions = m_sessions.values();
745 for (auto *session : sessions) {
746 const auto terminalIds = session->terminalIdList().split(QStringLiteral(","));
747
748 for (const auto &terminalID : terminalIds) {
749 auto *terminal = session->getTerminal(terminalID.toInt());
750 if (terminal) {
751 auto *collection = terminal->actionCollection();
752 if (collection) {
753 actionCollections.append(collection);
754 }
755 }
756 }
757 }
758
759 return actionCollections;
760 }
761