mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 10:52:51 +00:00
837 lines
28 KiB
C++
837 lines
28 KiB
C++
/*
|
|
Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA.
|
|
*/
|
|
|
|
// Own
|
|
#include "MainWindow.h"
|
|
|
|
// Qt
|
|
#include <QTextStream>
|
|
#include <QVBoxLayout>
|
|
#include <QMenuBar>
|
|
|
|
// KDE
|
|
#include <KAcceleratorManager>
|
|
#include <KAction>
|
|
#include <KActionCollection>
|
|
#include <KActionMenu>
|
|
#include <KCmdLineArgs>
|
|
#include <KShortcutsDialog>
|
|
#include <KLocale>
|
|
#include <KMenu>
|
|
#include <KMessageBox>
|
|
#include <KToggleFullScreenAction>
|
|
#include <KStandardAction>
|
|
#include <KStandardGuiItem>
|
|
#include <KWindowSystem>
|
|
#include <KXMLGUIFactory>
|
|
#include <KNotifyConfigWidget>
|
|
#include <KConfigDialog>
|
|
#include <KApplication>
|
|
|
|
// Konsole
|
|
#include "BookmarkHandler.h"
|
|
#include "SessionController.h"
|
|
#include "ProfileList.h"
|
|
#include "ManageProfilesDialog.h"
|
|
#include "Session.h"
|
|
#include "ViewManager.h"
|
|
#include "SessionManager.h"
|
|
#include "ProfileManager.h"
|
|
#include "KonsoleSettings.h"
|
|
#include "settings/GeneralSettings.h"
|
|
#include "settings/TabBarSettings.h"
|
|
|
|
using namespace Konsole;
|
|
|
|
/* Normally it would be enough to just have this determined via the window
|
|
manager. But there exist GPU drivers (NVIDIA) that have serious performance
|
|
issues if transparency is enabled inside Konsole. The rest of the system
|
|
works fine. NVIDIA users might want to use --notransparency to work
|
|
around such issues. */
|
|
static bool useTransparency()
|
|
{
|
|
const KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
|
|
const bool compositingAvailable = KWindowSystem::compositingActive();
|
|
return compositingAvailable && args->isSet("transparency");
|
|
}
|
|
|
|
MainWindow::MainWindow()
|
|
: KXmlGuiWindow()
|
|
, _bookmarkHandler(0)
|
|
, _pluggedController(0)
|
|
, _menuBarInitialVisibility(true)
|
|
, _menuBarInitialVisibilityApplied(false)
|
|
{
|
|
if (!KonsoleSettings::saveGeometryOnExit()) {
|
|
// If we are not using the global Konsole save geometry on exit,
|
|
// remove all Height and Width from [MainWindow] from konsolerc
|
|
// Each screen resolution will have entries (Width 1280=619)
|
|
KSharedConfigPtr konsoleConfig = KSharedConfig::openConfig("konsolerc");
|
|
KConfigGroup group = konsoleConfig->group("MainWindow");
|
|
QMap<QString, QString> configEntries = group.entryMap();
|
|
QMapIterator<QString, QString> i(configEntries);
|
|
while (i.hasNext()) {
|
|
i.next();
|
|
if (i.key().startsWith(QLatin1String("Width"))
|
|
|| i.key().startsWith(QLatin1String("Height"))) {
|
|
group.deleteEntry(i.key());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (useTransparency()) {
|
|
// It is useful to have translucent terminal area
|
|
setAttribute(Qt::WA_TranslucentBackground, true);
|
|
// But it is mostly annoying to have translucent menubar and tabbar
|
|
setAttribute(Qt::WA_NoSystemBackground, false);
|
|
}
|
|
|
|
// create actions for menus
|
|
setupActions();
|
|
|
|
// create view manager
|
|
_viewManager = new ViewManager(this, actionCollection());
|
|
connect(_viewManager, SIGNAL(empty()), this, SLOT(close()));
|
|
connect(_viewManager, SIGNAL(activeViewChanged(SessionController*)), this,
|
|
SLOT(activeViewChanged(SessionController*)));
|
|
connect(_viewManager, SIGNAL(unplugController(SessionController*)), this,
|
|
SLOT(disconnectController(SessionController*)));
|
|
connect(_viewManager, SIGNAL(viewPropertiesChanged(QList<ViewProperties*>)),
|
|
bookmarkHandler(), SLOT(setViews(QList<ViewProperties*>)));
|
|
|
|
connect(_viewManager, SIGNAL(updateWindowIcon()), this,
|
|
SLOT(updateWindowIcon()));
|
|
connect(_viewManager, SIGNAL(newViewRequest(Profile::Ptr)),
|
|
this, SLOT(newFromProfile(Profile::Ptr)));
|
|
connect(_viewManager, SIGNAL(newViewRequest()),
|
|
this, SLOT(newTab()));
|
|
connect(_viewManager, SIGNAL(viewDetached(Session*)),
|
|
this, SIGNAL(viewDetached(Session*)));
|
|
|
|
// create the main widget
|
|
setupMainWidget();
|
|
|
|
// disable automatically generated accelerators in top-level
|
|
// menu items - to avoid conflicting with Alt+[Letter] shortcuts
|
|
// in terminal applications
|
|
KAcceleratorManager::setNoAccel(menuBar());
|
|
|
|
// create menus
|
|
createGUI();
|
|
|
|
// remember the original menu accelerators for later use
|
|
rememberMenuAccelerators();
|
|
|
|
// replace standard shortcuts which cannot be used in a terminal
|
|
// emulator (as they are reserved for use by terminal applications)
|
|
correctStandardShortcuts();
|
|
|
|
setProfileList(new ProfileList(true, this));
|
|
|
|
// this must come at the end
|
|
applyKonsoleSettings();
|
|
connect(KonsoleSettings::self(), SIGNAL(configChanged()), this, SLOT(applyKonsoleSettings()));
|
|
}
|
|
|
|
void MainWindow::rememberMenuAccelerators()
|
|
{
|
|
foreach(QAction* menuItem, menuBar()->actions()) {
|
|
QString itemText = menuItem->text();
|
|
menuItem->setData(itemText);
|
|
}
|
|
}
|
|
|
|
// remove accelerators for standard menu items (eg. &File, &View, &Edit)
|
|
// etc. which are defined in kdelibs/kdeui/xmlgui/ui_standards.rc, again,
|
|
// to avoid conflicting with Alt+[Letter] terminal shortcuts
|
|
//
|
|
// TODO - Modify XMLGUI so that it allows the text for standard actions
|
|
// defined in ui_standards.rc to be re-defined in the local application
|
|
// XMLGUI file (konsoleui.rc in this case) - the text for standard items
|
|
// can then be redefined there to exclude the standard accelerators
|
|
void MainWindow::removeMenuAccelerators()
|
|
{
|
|
foreach(QAction* menuItem, menuBar()->actions()) {
|
|
QString itemText = menuItem->text();
|
|
itemText = KGlobal::locale()->removeAcceleratorMarker(itemText);
|
|
menuItem->setText(itemText);
|
|
}
|
|
}
|
|
|
|
void MainWindow::restoreMenuAccelerators()
|
|
{
|
|
foreach(QAction* menuItem, menuBar()->actions()) {
|
|
QString itemText = menuItem->data().toString();
|
|
menuItem->setText(itemText);
|
|
}
|
|
}
|
|
|
|
void MainWindow::correctStandardShortcuts()
|
|
{
|
|
// replace F1 shortcut for help contents
|
|
QAction* helpAction = actionCollection()->action("help_contents");
|
|
if (helpAction) {
|
|
helpAction->setShortcut(QKeySequence());
|
|
}
|
|
|
|
// replace Ctrl+B shortcut for bookmarks only if user hasn't already
|
|
// changed the shortcut; however, if the user changed it to Ctrl+B
|
|
// this will still get changed to Ctrl+Shift+B
|
|
QAction* bookmarkAction = actionCollection()->action("add_bookmark");
|
|
if (bookmarkAction && bookmarkAction->shortcut() == QKeySequence(Qt::CTRL + Qt::Key_B)) {
|
|
bookmarkAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B));
|
|
}
|
|
}
|
|
|
|
ViewManager* MainWindow::viewManager() const
|
|
{
|
|
return _viewManager;
|
|
}
|
|
|
|
void MainWindow::disconnectController(SessionController* controller)
|
|
{
|
|
disconnect(controller, SIGNAL(titleChanged(ViewProperties*)),
|
|
this, SLOT(activeViewTitleChanged(ViewProperties*)));
|
|
disconnect(controller, SIGNAL(rawTitleChanged()),
|
|
this, SLOT(updateWindowCaption()));
|
|
|
|
// KXmlGuiFactory::removeClient() will try to access actions associated
|
|
// with the controller internally, which may not be valid after the controller
|
|
// itself is no longer valid (after the associated session and or view have
|
|
// been destroyed)
|
|
if (controller->isValid())
|
|
guiFactory()->removeClient(controller);
|
|
|
|
controller->setSearchBar(0);
|
|
}
|
|
|
|
void MainWindow::activeViewChanged(SessionController* controller)
|
|
{
|
|
// associate bookmark menu with current session
|
|
bookmarkHandler()->setActiveView(controller);
|
|
disconnect(bookmarkHandler(), SIGNAL(openUrl(KUrl)), 0, 0);
|
|
connect(bookmarkHandler(), SIGNAL(openUrl(KUrl)), controller,
|
|
SLOT(openUrl(KUrl)));
|
|
|
|
if (_pluggedController)
|
|
disconnectController(_pluggedController);
|
|
|
|
Q_ASSERT(controller);
|
|
_pluggedController = controller;
|
|
|
|
// listen for title changes from the current session
|
|
connect(controller, SIGNAL(titleChanged(ViewProperties*)),
|
|
this, SLOT(activeViewTitleChanged(ViewProperties*)));
|
|
connect(controller, SIGNAL(rawTitleChanged()),
|
|
this, SLOT(updateWindowCaption()));
|
|
|
|
controller->setShowMenuAction(_toggleMenuBarAction);
|
|
|
|
const bool isMenuBarVisible = menuBar()->isVisible();
|
|
guiFactory()->addClient(controller);
|
|
menuBar()->setVisible(isMenuBarVisible);
|
|
|
|
// set the current session's search bar
|
|
controller->setSearchBar(searchBar());
|
|
|
|
// update session title to match newly activated session
|
|
activeViewTitleChanged(controller);
|
|
|
|
// Update window icon to newly activated session's icon
|
|
updateWindowIcon();
|
|
}
|
|
|
|
void MainWindow::activeViewTitleChanged(ViewProperties* properties)
|
|
{
|
|
Q_UNUSED(properties);
|
|
updateWindowCaption();
|
|
}
|
|
|
|
void MainWindow::updateWindowCaption()
|
|
{
|
|
if (!_pluggedController)
|
|
return;
|
|
|
|
const QString& title = _pluggedController->title();
|
|
const QString& userTitle = _pluggedController->userTitle();
|
|
|
|
// use tab title as caption by default
|
|
QString caption = title;
|
|
|
|
// use window title as caption only when enabled and it is not empty
|
|
if (KonsoleSettings::showWindowTitleOnTitleBar() && !userTitle.isEmpty()) {
|
|
caption = userTitle;
|
|
}
|
|
|
|
if (KonsoleSettings::showAppNameOnTitleBar()) {
|
|
setCaption(caption);
|
|
} else {
|
|
setWindowTitle(caption);
|
|
}
|
|
}
|
|
|
|
void MainWindow::updateWindowIcon()
|
|
{
|
|
if (_pluggedController)
|
|
setWindowIcon(_pluggedController->icon());
|
|
}
|
|
|
|
IncrementalSearchBar* MainWindow::searchBar() const
|
|
{
|
|
return _viewManager->searchBar();
|
|
}
|
|
|
|
void MainWindow::setupActions()
|
|
{
|
|
KActionCollection* collection = actionCollection();
|
|
KAction* menuAction = 0;
|
|
|
|
// File Menu
|
|
_newTabMenuAction = new KActionMenu(KIcon("tab-new"), i18nc("@action:inmenu", "&New Tab"), collection);
|
|
_newTabMenuAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_T));
|
|
_newTabMenuAction->setShortcutConfigurable(true);
|
|
_newTabMenuAction->setAutoRepeat(false);
|
|
connect(_newTabMenuAction, SIGNAL(triggered()), this, SLOT(newTab()));
|
|
collection->addAction("new-tab", _newTabMenuAction);
|
|
|
|
menuAction = collection->addAction("clone-tab");
|
|
menuAction->setIcon(KIcon("tab-duplicate"));
|
|
menuAction->setText(i18nc("@action:inmenu", "&Clone Tab"));
|
|
menuAction->setShortcut(QKeySequence());
|
|
menuAction->setAutoRepeat(false);
|
|
connect(menuAction, SIGNAL(triggered()), this, SLOT(cloneTab()));
|
|
|
|
menuAction = collection->addAction("new-window");
|
|
menuAction->setIcon(KIcon("window-new"));
|
|
menuAction->setText(i18nc("@action:inmenu", "New &Window"));
|
|
menuAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_N));
|
|
menuAction->setAutoRepeat(false);
|
|
connect(menuAction, SIGNAL(triggered()), this, SLOT(newWindow()));
|
|
|
|
menuAction = collection->addAction("close-window");
|
|
menuAction->setIcon(KIcon("window-close"));
|
|
menuAction->setText(i18nc("@action:inmenu", "Close Window"));
|
|
menuAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Q));
|
|
connect(menuAction, SIGNAL(triggered()), this, SLOT(close()));
|
|
|
|
// Bookmark Menu
|
|
KActionMenu* bookmarkMenu = new KActionMenu(i18nc("@title:menu", "&Bookmarks"), collection);
|
|
_bookmarkHandler = new BookmarkHandler(collection, bookmarkMenu->menu(), true, this);
|
|
collection->addAction("bookmark", bookmarkMenu);
|
|
connect(_bookmarkHandler, SIGNAL(openUrls(QList<KUrl>)), this, SLOT(openUrls(QList<KUrl>)));
|
|
|
|
// Settings Menu
|
|
_toggleMenuBarAction = KStandardAction::showMenubar(menuBar(), SLOT(setVisible(bool)), collection);
|
|
_toggleMenuBarAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_M));
|
|
|
|
// Full Screen
|
|
menuAction = KStandardAction::fullScreen(this, SLOT(viewFullScreen(bool)), this, collection);
|
|
menuAction->setShortcut(QKeySequence(Qt::Key_F11));
|
|
|
|
KStandardAction::configureNotifications(this, SLOT(configureNotifications()), collection);
|
|
KStandardAction::keyBindings(this, SLOT(showShortcutsDialog()), collection);
|
|
KStandardAction::preferences(this, SLOT(showSettingsDialog()), collection);
|
|
|
|
menuAction = collection->addAction("manage-profiles");
|
|
menuAction->setText(i18nc("@action:inmenu", "Manage Profiles..."));
|
|
menuAction->setIcon(KIcon("configure"));
|
|
connect(menuAction, SIGNAL(triggered()), this, SLOT(showManageProfilesDialog()));
|
|
|
|
// Set up an shortcut-only action for activating menu bar.
|
|
menuAction = collection->addAction("activate-menu");
|
|
menuAction->setText(i18nc("@item", "Activate Menu"));
|
|
menuAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_F10));
|
|
connect(menuAction, SIGNAL(triggered()), this, SLOT(activateMenuBar()));
|
|
}
|
|
|
|
void MainWindow::viewFullScreen(bool fullScreen)
|
|
{
|
|
if (fullScreen)
|
|
setWindowState(windowState() | Qt::WindowFullScreen);
|
|
else
|
|
setWindowState(windowState() & ~Qt::WindowFullScreen);
|
|
}
|
|
|
|
BookmarkHandler* MainWindow::bookmarkHandler() const
|
|
{
|
|
return _bookmarkHandler;
|
|
}
|
|
|
|
void MainWindow::setProfileList(ProfileList* list)
|
|
{
|
|
profileListChanged(list->actions());
|
|
|
|
connect(list, SIGNAL(profileSelected(Profile::Ptr)), this,
|
|
SLOT(newFromProfile(Profile::Ptr)));
|
|
|
|
connect(list, SIGNAL(actionsChanged(QList<QAction*>)), this,
|
|
SLOT(profileListChanged(QList<QAction*>)));
|
|
}
|
|
|
|
void MainWindow::profileListChanged(const QList<QAction*>& sessionActions)
|
|
{
|
|
// If only 1 profile is to be shown in the menu, only display
|
|
// it if it is the non-default profile.
|
|
if (sessionActions.size() > 2) {
|
|
// Update the 'New Tab' KActionMenu
|
|
KMenu* newTabMenu = _newTabMenuAction->menu();
|
|
newTabMenu->clear();
|
|
foreach(QAction* sessionAction, sessionActions) {
|
|
newTabMenu->addAction(sessionAction);
|
|
|
|
// NOTE: defaultProfile seems to not work here, sigh.
|
|
Profile::Ptr profile = ProfileManager::instance()->defaultProfile();
|
|
if (profile && profile->name() == sessionAction->text().remove('&')) {
|
|
sessionAction->setIcon(KIcon(profile->icon(), 0, QStringList("emblem-favorite")));
|
|
newTabMenu->setDefaultAction(sessionAction);
|
|
QFont actionFont = sessionAction->font();
|
|
actionFont.setBold(true);
|
|
sessionAction->setFont(actionFont);
|
|
}
|
|
}
|
|
} else {
|
|
KMenu* newTabMenu = _newTabMenuAction->menu();
|
|
newTabMenu->clear();
|
|
Profile::Ptr profile = ProfileManager::instance()->defaultProfile();
|
|
|
|
// NOTE: Compare names w/o any '&'
|
|
if (sessionActions.size() == 2 && sessionActions[1]->text().remove('&') != profile->name()) {
|
|
newTabMenu->addAction(sessionActions[1]);
|
|
} else {
|
|
delete newTabMenu;
|
|
}
|
|
}
|
|
}
|
|
|
|
QString MainWindow::activeSessionDir() const
|
|
{
|
|
if (_pluggedController) {
|
|
if (Session* session = _pluggedController->session()) {
|
|
// For new tabs to get the correct working directory,
|
|
// force the updating of the currentWorkingDirectory.
|
|
session->getDynamicTitle();
|
|
}
|
|
return _pluggedController->currentDir();
|
|
} else {
|
|
return QString();
|
|
}
|
|
}
|
|
|
|
void MainWindow::openUrls(const QList<KUrl>& urls)
|
|
{
|
|
Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile();
|
|
|
|
foreach(const KUrl& url, urls) {
|
|
if (url.isLocalFile())
|
|
createSession(defaultProfile, url.path());
|
|
|
|
else if (url.protocol() == "ssh")
|
|
createSSHSession(defaultProfile, url);
|
|
}
|
|
}
|
|
|
|
void MainWindow::newTab()
|
|
{
|
|
Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile();
|
|
createSession(defaultProfile, activeSessionDir());
|
|
}
|
|
|
|
void MainWindow::cloneTab()
|
|
{
|
|
Q_ASSERT(_pluggedController);
|
|
|
|
Session* session = _pluggedController->session();
|
|
Profile::Ptr profile = SessionManager::instance()->sessionProfile(session);
|
|
if (profile) {
|
|
createSession(profile, activeSessionDir());
|
|
} else {
|
|
// something must be wrong: every session should be associated with profile
|
|
Q_ASSERT(false);
|
|
newTab();
|
|
}
|
|
}
|
|
|
|
Session* MainWindow::createSession(Profile::Ptr profile, const QString& directory)
|
|
{
|
|
if (!profile)
|
|
profile = ProfileManager::instance()->defaultProfile();
|
|
|
|
Session* session = SessionManager::instance()->createSession(profile);
|
|
|
|
if (!directory.isEmpty() && profile->startInCurrentSessionDir())
|
|
session->setInitialWorkingDirectory(directory);
|
|
|
|
session->addEnvironmentEntry(QString("KONSOLE_DBUS_WINDOW=/Windows/%1").arg(_viewManager->managerId()));
|
|
|
|
// create view before starting the session process so that the session
|
|
// doesn't suffer a change in terminal size right after the session
|
|
// starts. Some applications such as GNU Screen and Midnight Commander
|
|
// don't like this happening
|
|
createView(session);
|
|
|
|
return session;
|
|
}
|
|
|
|
Session* MainWindow::createSSHSession(Profile::Ptr profile, const KUrl& url)
|
|
{
|
|
if (!profile)
|
|
profile = ProfileManager::instance()->defaultProfile();
|
|
|
|
Session* session = SessionManager::instance()->createSession(profile);
|
|
|
|
QString sshCommand = "ssh ";
|
|
if (url.port() > -1) {
|
|
sshCommand += QString("-p %1 ").arg(url.port());
|
|
}
|
|
if (url.hasUser()) {
|
|
sshCommand += (url.userName() + '@');
|
|
}
|
|
if (url.hasHost()) {
|
|
sshCommand += url.host();
|
|
}
|
|
|
|
session->sendText(sshCommand + '\r');
|
|
|
|
// create view before starting the session process so that the session
|
|
// doesn't suffer a change in terminal size right after the session
|
|
// starts. some applications such as GNU Screen and Midnight Commander
|
|
// don't like this happening
|
|
createView(session);
|
|
|
|
return session;
|
|
}
|
|
|
|
void MainWindow::createView(Session* session)
|
|
{
|
|
_viewManager->createView(session);
|
|
}
|
|
|
|
void MainWindow::setFocus()
|
|
{
|
|
_viewManager->activeView()->setFocus();
|
|
}
|
|
|
|
void MainWindow::newWindow()
|
|
{
|
|
Profile::Ptr defaultProfile = ProfileManager::instance()->defaultProfile();
|
|
emit newWindowRequest(defaultProfile, activeSessionDir());
|
|
}
|
|
|
|
bool MainWindow::queryClose()
|
|
{
|
|
// Do not ask for confirmation during log out and power off
|
|
// TODO: rework the dealing of this case to make it has its own confirmation
|
|
// dialog.
|
|
if (kapp->sessionSaving()) {
|
|
return true;
|
|
}
|
|
|
|
// Check what processes are running,
|
|
// if just the default shell is running don't ask for confirmation
|
|
|
|
QStringList processesRunning;
|
|
foreach(Session *session, _viewManager->sessions()) {
|
|
if (!session)
|
|
continue;
|
|
|
|
const QString defaultProc = session->program().split('/').last();
|
|
const QString currentProc = session->foregroundProcessName().split('/').last();
|
|
|
|
if (currentProc.isEmpty())
|
|
continue;
|
|
|
|
if (defaultProc != currentProc) {
|
|
processesRunning.append(currentProc);
|
|
}
|
|
}
|
|
if (processesRunning.count() == 0) {
|
|
return true;
|
|
}
|
|
|
|
// NOTE: Some, if not all, of the below KWindowSystem calls are only
|
|
// implemented under x11 (KDE4.8 kdelibs/kdeui/windowmanagement).
|
|
|
|
// make sure the window is shown on current desktop and is not minimized
|
|
KWindowSystem::setOnDesktop(winId(), KWindowSystem::currentDesktop());
|
|
if (isMinimized()) {
|
|
KWindowSystem::unminimizeWindow(winId(), true);
|
|
}
|
|
|
|
int result = KMessageBox::warningYesNoCancelList(this,
|
|
i18ncp("@info", "There is a process running in this window. "
|
|
"Do you still want to quit?",
|
|
"There are %1 processes running in this window. "
|
|
"Do you still want to quit?",
|
|
processesRunning.count()),
|
|
processesRunning,
|
|
i18nc("@title", "Confirm Close"),
|
|
KGuiItem(i18nc("@action:button", "Close &Window"), "window-close"),
|
|
KGuiItem(i18nc("@action:button", "Close Current &Tab"), "tab-close"),
|
|
KStandardGuiItem::cancel(),
|
|
"CloseAllTabs");
|
|
|
|
switch (result) {
|
|
case KMessageBox::Yes:
|
|
return true;
|
|
case KMessageBox::No:
|
|
if (_pluggedController && _pluggedController->session()) {
|
|
disconnectController(_pluggedController);
|
|
_pluggedController->closeSession();
|
|
}
|
|
return false;
|
|
case KMessageBox::Cancel:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void MainWindow::saveProperties(KConfigGroup& group)
|
|
{
|
|
_viewManager->saveSessions(group);
|
|
}
|
|
|
|
void MainWindow::readProperties(const KConfigGroup& group)
|
|
{
|
|
_viewManager->restoreSessions(group);
|
|
}
|
|
|
|
void MainWindow::saveGlobalProperties(KConfig* config)
|
|
{
|
|
SessionManager::instance()->saveSessions(config);
|
|
}
|
|
|
|
void MainWindow::readGlobalProperties(KConfig* config)
|
|
{
|
|
SessionManager::instance()->restoreSessions(config);
|
|
}
|
|
|
|
void MainWindow::syncActiveShortcuts(KActionCollection* dest, const KActionCollection* source)
|
|
{
|
|
foreach(QAction * qAction, source->actions()) {
|
|
if (KAction* kAction = qobject_cast<KAction*>(qAction)) {
|
|
if (KAction* destKAction = qobject_cast<KAction*>(dest->action(kAction->objectName())))
|
|
destKAction->setShortcut(kAction->shortcut(KAction::ActiveShortcut), KAction::ActiveShortcut);
|
|
}
|
|
}
|
|
}
|
|
void MainWindow::showShortcutsDialog()
|
|
{
|
|
KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this);
|
|
|
|
// add actions from this window and the current session controller
|
|
foreach(KXMLGUIClient * client, guiFactory()->clients()) {
|
|
dialog.addCollection(client->actionCollection());
|
|
}
|
|
|
|
if (dialog.configure()) {
|
|
// sync shortcuts for non-session actions (defined in "konsoleui.rc") in other main windows
|
|
foreach(QWidget* mainWindowWidget, QApplication::topLevelWidgets()) {
|
|
MainWindow* mainWindow = qobject_cast<MainWindow*>(mainWindowWidget);
|
|
if (mainWindow && mainWindow != this)
|
|
syncActiveShortcuts(mainWindow->actionCollection(), actionCollection());
|
|
}
|
|
// sync shortcuts for session actions (defined in "sessionui.rc") in other session controllers.
|
|
// Controllers which are currently plugged in (ie. their actions are part of the current menu)
|
|
// must be updated immediately via syncActiveShortcuts(). Other controllers will be updated
|
|
// when they are plugged into a main window.
|
|
foreach(SessionController * controller, SessionController::allControllers()) {
|
|
controller->reloadXML();
|
|
if (controller->factory() && controller != _pluggedController)
|
|
syncActiveShortcuts(controller->actionCollection(), _pluggedController->actionCollection());
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::newFromProfile(Profile::Ptr profile)
|
|
{
|
|
createSession(profile, activeSessionDir());
|
|
}
|
|
void MainWindow::showManageProfilesDialog()
|
|
{
|
|
ManageProfilesDialog* dialog = new ManageProfilesDialog(this);
|
|
dialog->show();
|
|
}
|
|
|
|
void MainWindow::showSettingsDialog()
|
|
{
|
|
if (KConfigDialog::showDialog("settings"))
|
|
return;
|
|
|
|
KConfigDialog* settingsDialog = new KConfigDialog(this, "settings", KonsoleSettings::self());
|
|
settingsDialog->setFaceType(KPageDialog::List);
|
|
|
|
GeneralSettings* generalSettings = new GeneralSettings(settingsDialog);
|
|
settingsDialog->addPage(generalSettings,
|
|
i18nc("@title Preferences page name", "General"),
|
|
"utilities-terminal");
|
|
|
|
TabBarSettings* tabBarSettings = new TabBarSettings(settingsDialog);
|
|
settingsDialog->addPage(tabBarSettings,
|
|
i18nc("@title Preferences page name", "TabBar"),
|
|
"system-run");
|
|
|
|
settingsDialog->show();
|
|
}
|
|
|
|
void MainWindow::applyKonsoleSettings()
|
|
{
|
|
setMenuBarInitialVisibility(KonsoleSettings::showMenuBarByDefault());
|
|
|
|
if (KonsoleSettings::allowMenuAccelerators()) {
|
|
restoreMenuAccelerators();
|
|
} else {
|
|
removeMenuAccelerators();
|
|
}
|
|
|
|
setNavigationVisibility(KonsoleSettings::tabBarVisibility());
|
|
setNavigationPosition(KonsoleSettings::tabBarPosition());
|
|
setNavigationBehavior(KonsoleSettings::newTabBehavior());
|
|
setShowQuickButtons(KonsoleSettings::showQuickButtons());
|
|
|
|
if (KonsoleSettings::tabBarUseUserStyleSheet()) {
|
|
setNavigationStyleSheetFromFile(KonsoleSettings::tabBarUserStyleSheetFile());
|
|
} else {
|
|
// Apply default values
|
|
setNavigationStyleSheet(KonsoleSettings::tabBarStyleSheet());
|
|
}
|
|
|
|
setAutoSaveSettings("MainWindow", KonsoleSettings::saveGeometryOnExit());
|
|
|
|
updateWindowCaption();
|
|
}
|
|
|
|
void MainWindow::setNavigationVisibility(int visibility)
|
|
{
|
|
_viewManager->setNavigationVisibility(visibility);
|
|
}
|
|
|
|
void MainWindow::setNavigationPosition(int position)
|
|
{
|
|
_viewManager->setNavigationPosition(position);
|
|
}
|
|
|
|
void MainWindow::setNavigationStyleSheet(const QString& styleSheet)
|
|
{
|
|
_viewManager->setNavigationStyleSheet(styleSheet);
|
|
}
|
|
|
|
void MainWindow::setNavigationBehavior(int behavior)
|
|
{
|
|
_viewManager->setNavigationBehavior(behavior);
|
|
}
|
|
|
|
void MainWindow::setNavigationStyleSheetFromFile(const KUrl& styleSheetFile)
|
|
{
|
|
// Let's only deal w/ local files for now
|
|
if (!styleSheetFile.isLocalFile()) {
|
|
setNavigationStyleSheet(KonsoleSettings::tabBarStyleSheet());
|
|
}
|
|
|
|
QFile file(styleSheetFile.toLocalFile());
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
setNavigationStyleSheet(KonsoleSettings::tabBarStyleSheet());
|
|
}
|
|
|
|
QString styleSheetText;
|
|
QTextStream in(&file);
|
|
while (!in.atEnd()) {
|
|
styleSheetText.append(in.readLine());
|
|
}
|
|
|
|
// Replace current style sheet w/ loaded file
|
|
setNavigationStyleSheet(styleSheetText);
|
|
}
|
|
|
|
void MainWindow::setShowQuickButtons(bool show)
|
|
{
|
|
_viewManager->setShowQuickButtons(show);
|
|
}
|
|
|
|
void MainWindow::activateMenuBar()
|
|
{
|
|
const QList<QAction*> menuActions = menuBar()->actions();
|
|
|
|
if (menuActions.isEmpty())
|
|
return;
|
|
|
|
// Show menubar if it is hidden at the moment
|
|
if (menuBar()->isHidden()) {
|
|
menuBar()->setVisible(true);
|
|
_toggleMenuBarAction->setChecked(true);
|
|
}
|
|
|
|
// First menu action should be 'File'
|
|
QAction* menuAction = menuActions.first();
|
|
|
|
// TODO: Handle when menubar is top level (MacOS)
|
|
menuBar()->setActiveAction(menuAction);
|
|
}
|
|
|
|
void MainWindow::setupMainWidget()
|
|
{
|
|
QWidget* mainWindowWidget = new QWidget(this);
|
|
QVBoxLayout* mainWindowLayout = new QVBoxLayout();
|
|
|
|
mainWindowLayout->addWidget(_viewManager->widget());
|
|
mainWindowLayout->setContentsMargins(0, 0, 0, 0);
|
|
mainWindowLayout->setSpacing(0);
|
|
|
|
mainWindowWidget->setLayout(mainWindowLayout);
|
|
|
|
setCentralWidget(mainWindowWidget);
|
|
}
|
|
|
|
void MainWindow::configureNotifications()
|
|
{
|
|
KNotifyConfigWidget::configure(this);
|
|
}
|
|
|
|
void MainWindow::setMenuBarInitialVisibility(bool visible)
|
|
{
|
|
_menuBarInitialVisibility = visible;
|
|
}
|
|
void MainWindow::showEvent(QShowEvent* aEvent)
|
|
{
|
|
// Make sure the 'initial' visibility is applied only once.
|
|
if (!_menuBarInitialVisibilityApplied) {
|
|
// the initial visibility of menubar should be applied at this last
|
|
// moment. Otherwise, the initial visibility will be determined by
|
|
// what KMainWindow has automatically stored in konsolerc, but not by
|
|
// what users has explicitly configured .
|
|
menuBar()->setVisible(_menuBarInitialVisibility);
|
|
_toggleMenuBarAction->setChecked(_menuBarInitialVisibility);
|
|
_menuBarInitialVisibilityApplied = true;
|
|
}
|
|
|
|
// Call parent method
|
|
KXmlGuiWindow::showEvent(aEvent);
|
|
}
|
|
|
|
bool MainWindow::focusNextPrevChild(bool)
|
|
{
|
|
// In stand-alone konsole, always disable implicit focus switching
|
|
// through 'Tab' and 'Shift+Tab'
|
|
//
|
|
// Kpart is another different story
|
|
return false;
|
|
}
|
|
|
|
#include "moc_MainWindow.cpp"
|
|
|