• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Konsole

MainWindow.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301  USA.
00018 */
00019 
00020 // Own
00021 #include "MainWindow.h"
00022 #include "SessionManager.h"
00023 
00024 // Qt
00025 #include <QtGui/QBoxLayout>
00026 
00027 // KDE
00028 #include <KAcceleratorManager>
00029 #include <KAction>
00030 #include <KActionCollection>
00031 #include <KActionMenu>
00032 #include <KApplication>
00033 #include <KShortcutsDialog>
00034 #include <KLocale>
00035 #include <KMenu>
00036 #include <KMenuBar>
00037 #include <KMessageBox>
00038 #include <KService>
00039 #include <KToggleAction>
00040 #include <KToggleFullScreenAction>
00041 #include <KToolInvocation>
00042 #include <KStandardAction>
00043 #include <KStandardGuiItem>
00044 #include <KXMLGUIFactory>
00045 #include <KNotifyConfigWidget>
00046 
00047 // Konsole
00048 #include "BookmarkHandler.h"
00049 #include "IncrementalSearchBar.h"
00050 #include "RemoteConnectionDialog.h"
00051 #include "SessionController.h"
00052 #include "ProfileList.h"
00053 #include "ManageProfilesDialog.h"
00054 #include "Session.h"
00055 #include "ViewManager.h"
00056 #include "ViewSplitter.h"
00057 
00058 using namespace Konsole;
00059 
00060 MainWindow::MainWindow()
00061  : KXmlGuiWindow() ,
00062    _bookmarkHandler(0),
00063    _pluggedController(0),
00064    _menuBarVisibilitySet(false)
00065 {
00066     // create actions for menus
00067     // the directory ('konsole') is included in the path here so that the XML
00068     // file can be found when this code is being used in the Konsole part.
00069     setXMLFile("konsole/konsoleui.rc");
00070     setupActions();
00071 
00072     // create view manager
00073         _viewManager = new ViewManager(this,actionCollection());
00074     connect( _viewManager , SIGNAL(empty()) , this , SLOT(close()) );
00075     connect( _viewManager , SIGNAL(activeViewChanged(SessionController*)) , this ,
00076             SLOT(activeViewChanged(SessionController*)) );
00077     connect( _viewManager , SIGNAL(viewPropertiesChanged(const QList<ViewProperties*>&)) ,
00078            bookmarkHandler() , SLOT(setViews(const QList<ViewProperties*>&)) );
00079 
00080     connect( _viewManager , SIGNAL(setMenuBarVisibleRequest(bool)) , this ,
00081             SLOT(setMenuBarVisibleOnce(bool)) );
00082     connect( _viewManager , SIGNAL(newViewRequest(Profile::Ptr)) , 
00083         this , SLOT(newFromProfile(Profile::Ptr)) );
00084     connect( _viewManager , SIGNAL(newViewRequest()) , 
00085         this , SLOT(newTab()));
00086 
00087     // create main window widgets
00088     setupWidgets();
00089 
00090     // disable automatically generated accelerators in top-level
00091     // menu items - to avoid conflicting with Alt+[Letter] shortcuts
00092     // in terminal applications
00093     KAcceleratorManager::setNoAccel(menuBar());
00094     // create menus
00095     createGUI();
00096     // remove accelerators for standard menu items (eg. &File, &View, &Edit)
00097     // etc. which are defined in kdelibs/kdeui/xmlgui/ui_standards.rc, again,
00098     // to avoid conflicting with Alt+[Letter] terminal shortcuts
00099     //
00100     // TODO - Modify XMLGUI so that it allows the text for standard actions
00101     // defined in ui_standards.rc to be re-defined in the local application
00102     // XMLGUI file (konsoleui.rc in this case) - the text for standard items
00103     // can then be redefined there to exclude the standard accelerators
00104     removeMenuAccelerators();
00105     // replace standard shortcuts which cannot be used in a terminal
00106     // (as they are reserved for use by terminal programs)
00107     correctShortcuts();
00108 
00109     // enable save and restore of window size
00110     setAutoSaveSettings("MainWindow",true);
00111 }
00112 void MainWindow::removeMenuAccelerators()
00113 {
00114     foreach(QAction* menuItem, menuBar()->actions())
00115     {
00116         QString itemText = menuItem->text();
00117         itemText = KGlobal::locale()->removeAcceleratorMarker(itemText);
00118         menuItem->setText(itemText);
00119     }
00120 }
00121 void MainWindow::setMenuBarVisibleOnce(bool visible)
00122 {
00123     if (_menuBarVisibilitySet || menuBar()->isTopLevelMenu() )
00124         return;
00125 
00126     menuBar()->setVisible(visible);
00127     _toggleMenuBarAction->setChecked(visible);
00128 
00129     _menuBarVisibilitySet = true;
00130 }
00131 
00132 void MainWindow::correctShortcuts()
00133 {
00134     // replace F1 shortcut for help contents
00135     QAction* helpAction = actionCollection()->action("help_contents");
00136 
00137     Q_ASSERT( helpAction );
00138 
00139     helpAction->setShortcut(QKeySequence());
00140    
00141     // replace Ctrl+B shortcut for bookmarks
00142     // TODO - Make this configurable
00143     QAction* bookmarkAction = actionCollection()->action("add_bookmark");
00144     Q_ASSERT(bookmarkAction);
00145     bookmarkAction->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_B));
00146 }
00147 
00148 void MainWindow::setDefaultProfile(Profile::Ptr profile)
00149 {
00150     _defaultProfile = profile;
00151 }
00152 Profile::Ptr MainWindow::defaultProfile() const
00153 {
00154     return _defaultProfile;
00155 }
00156 
00157 ViewManager* MainWindow::viewManager() const
00158 {
00159     return _viewManager;
00160 }
00161 
00162 void MainWindow::disconnectController(SessionController* controller)
00163 {
00164     disconnect( controller , SIGNAL(titleChanged(ViewProperties*))
00165                      , this , SLOT(activeViewTitleChanged(ViewProperties*)) );
00166 
00167     // KXmlGuiFactory::removeClient() will try to access actions associated
00168     // with the controller internally, which may not be valid after the controller
00169     // itself is no longer valid (after the associated session and or view have
00170     // been destroyed)
00171     if (controller->isValid())
00172         guiFactory()->removeClient(controller);
00173 
00174     controller->setSearchBar(0);
00175 }
00176 
00177 void MainWindow::activeViewChanged(SessionController* controller)
00178 {
00179     // associate bookmark menu with current session
00180     bookmarkHandler()->setActiveView(controller);
00181     disconnect( bookmarkHandler() , SIGNAL(openUrl(const KUrl&)) , 0 , 0 );
00182     connect( bookmarkHandler() , SIGNAL(openUrl(const KUrl&)) , controller ,
00183              SLOT(openUrl(const KUrl&)) );
00184 
00185     if ( _pluggedController )
00186         disconnectController(_pluggedController);
00187 
00188     // listen for title changes from the current session
00189     Q_ASSERT( controller );
00190 
00191     connect( controller , SIGNAL(titleChanged(ViewProperties*)) ,
00192             this , SLOT(activeViewTitleChanged(ViewProperties*)) );
00193 
00194     controller->setShowMenuAction( _toggleMenuBarAction );
00195     guiFactory()->addClient(controller);
00196 
00197     // set the current session's search bar
00198     controller->setSearchBar( searchBar() );
00199 
00200     // update session title to match newly activated session
00201     activeViewTitleChanged(controller);
00202 
00203     _pluggedController = controller;
00204 }
00205 
00206 void MainWindow::activeViewTitleChanged(ViewProperties* properties)
00207 {
00208     setPlainCaption(properties->title());
00209 }
00210 
00211 IncrementalSearchBar* MainWindow::searchBar() const
00212 {
00213     return _viewManager->searchBar();
00214 }
00215 
00216 void MainWindow::setupActions()
00217 {
00218     KActionCollection* collection = actionCollection();
00219 
00220     // File Menu
00221     KAction* newTabAction = collection->addAction("new-tab");
00222     newTabAction->setIcon( KIcon("tab-new") );
00223     newTabAction->setText( i18n("New &Tab") );
00224     newTabAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_N) );
00225     connect( newTabAction , SIGNAL(triggered()) , this , SLOT(newTab()) );
00226 
00227     KAction* newWindowAction = collection->addAction("new-window");
00228     newWindowAction->setIcon( KIcon("window-new") );
00229     newWindowAction->setText( i18n("New &Window") );
00230     newWindowAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_M) );
00231     connect( newWindowAction , SIGNAL(triggered()) , this , SLOT(newWindow()) );
00232 
00233     KAction* remoteConnectionAction = collection->addAction("remote-connection");
00234     remoteConnectionAction->setText( i18n("Remote Connection...") );
00235     remoteConnectionAction->setIcon( KIcon("network-connect") );
00236     remoteConnectionAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_R) );
00237     connect( remoteConnectionAction , SIGNAL(triggered()) , this , SLOT(showRemoteConnectionDialog()) );
00238 
00239     KAction* quitAction = KStandardAction::quit( this , SLOT(close()) , collection );
00240     // the default shortcut for quit is typically Ctrl+[Some Letter, usually Q] but that is reserved for
00241     // use by terminal applications
00242     quitAction->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_Q);
00243 
00244     // Bookmark Menu
00245     KActionMenu* bookmarkMenu = new KActionMenu(i18n("&Bookmarks") , collection );
00246     _bookmarkHandler = new BookmarkHandler( collection , bookmarkMenu->menu() , true , this );
00247     collection->addAction("bookmark" , bookmarkMenu);
00248 
00249     connect( _bookmarkHandler , SIGNAL(openUrls(QList<KUrl>)) , this , SLOT(openUrls(QList<KUrl>)) );
00250 
00251     //TODO - The 'Add Bookmark' menu action currently has a Ctrl+B shortcut by
00252     // default which cannot be overridden
00253 
00254     // View Menu
00255     _toggleMenuBarAction = new KToggleAction(this);
00256     _toggleMenuBarAction->setText( i18n("Show Menu Bar") );
00257     _toggleMenuBarAction->setIcon( KIcon("show-menu") );
00258     _toggleMenuBarAction->setChecked( !menuBar()->isHidden() );
00259     connect( _toggleMenuBarAction , SIGNAL(toggled(bool)) , menuBar() , SLOT(setVisible(bool)) );
00260     collection->addAction("show-menubar",_toggleMenuBarAction);
00261 
00262     // Hide the Show/Hide menubar item if the menu bar is a MacOS-style menu bar
00263     if ( menuBar()->isTopLevelMenu() )
00264         _toggleMenuBarAction->setVisible(false);
00265 
00266     // Full Screen
00267     KToggleFullScreenAction* fullScreenAction = new KToggleFullScreenAction(this);
00268     fullScreenAction->setWindow(this);
00269     fullScreenAction->setShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_F11 );
00270     collection->addAction("view-full-screen",fullScreenAction);
00271     connect( fullScreenAction , SIGNAL(toggled(bool)) , this , SLOT(viewFullScreen(bool)) );
00272 
00273     // Settings Menu
00274     KStandardAction::configureNotifications( this , SLOT(configureNotifications()) , collection  );
00275     KStandardAction::keyBindings( this , SLOT(showShortcutsDialog()) , collection  );
00276 
00277     KAction* manageProfilesAction = collection->addAction("manage-profiles");
00278     manageProfilesAction->setText( i18n("Manage Profiles...") );
00279     manageProfilesAction->setIcon( KIcon("configure") );
00280     connect( manageProfilesAction , SIGNAL(triggered()) , this , SLOT(showManageProfilesDialog()) );
00281 
00282 }
00283 
00284 void MainWindow::viewFullScreen(bool fullScreen)
00285 {
00286     if ( fullScreen )
00287         setWindowState( windowState() | Qt::WindowFullScreen );
00288     else
00289         setWindowState( windowState() & ~Qt::WindowFullScreen );
00290 }
00291 
00292 BookmarkHandler* MainWindow::bookmarkHandler() const
00293 {
00294     return _bookmarkHandler;
00295 }
00296 
00297 void MainWindow::setSessionList(ProfileList* list)
00298 {
00299     sessionListChanged(list->actions());
00300 
00301     connect( list , SIGNAL(profileSelected(Profile::Ptr)) , this ,
00302             SLOT(newFromProfile(Profile::Ptr)) );
00303 
00304     connect( list , SIGNAL(actionsChanged(const QList<QAction*>&)) , this ,
00305             SLOT(sessionListChanged(const QList<QAction*>&)) );
00306 }
00307 
00308 void MainWindow::sessionListChanged(const QList<QAction*>& actions)
00309 {
00310     unplugActionList("favorite-profiles");
00311     plugActionList("favorite-profiles",actions);
00312 }
00313 
00314 QString MainWindow::activeSessionDir() const
00315 {
00316     if ( _pluggedController )
00317         return _pluggedController->currentDir();
00318     else
00319         return QString();
00320 }
00321 
00322 void MainWindow::openUrls(const QList<KUrl>& urls)
00323 {
00324     // TODO Implement support for SSH bookmarks here
00325     foreach( const KUrl& url , urls )
00326     {
00327         if ( url.isLocalFile() )
00328             emit newSessionRequest( _defaultProfile , url.path() , _viewManager );
00329     }
00330 }
00331 
00332 void MainWindow::newTab()
00333 {
00334     emit newSessionRequest( _defaultProfile , activeSessionDir() , _viewManager);
00335 }
00336 
00337 void MainWindow::newWindow()
00338 {
00339     emit newWindowRequest( _defaultProfile , activeSessionDir() );
00340 }
00341 
00342 bool MainWindow::queryClose()
00343 {
00344     if (kapp->sessionSaving() ||
00345         _viewManager->viewProperties().count() < 2)
00346         return true;
00347 
00348     int result = KMessageBox::warningYesNoCancel(this,
00349                 i18n("You have multiple tabs in this window, "
00350                      "are you sure you want to quit?"),
00351                 i18n("Confirm Close"),
00352                 KStandardGuiItem::quit(),
00353                 KGuiItem(i18n("Close Current Tab"), "tab-close"),
00354                 KStandardGuiItem::cancel(),
00355                 "CloseAllTabs");
00356 
00357     switch (result)
00358     {
00359     case KMessageBox::Yes:
00360         return true;
00361     case KMessageBox::No:
00362         if (_pluggedController && _pluggedController->session())
00363         {
00364             disconnectController(_pluggedController);
00365             _pluggedController->session()->close();
00366         }
00367         return false;
00368     case KMessageBox::Cancel:
00369         return false;
00370     }
00371 
00372     return true;
00373 }
00374 
00375 void MainWindow::saveProperties(KConfigGroup& group)
00376 {
00377     if (_defaultProfile)
00378         group.writePathEntry("Default Profile", _defaultProfile->path());
00379     _viewManager->saveSessions(group);
00380 }
00381 
00382 void MainWindow::readProperties(const KConfigGroup& group)
00383 {
00384     SessionManager *manager = SessionManager::instance();
00385     QString profilePath = group.readPathEntry("Default Profile", QString());
00386     Profile::Ptr profile = manager->defaultProfile();
00387     if (!profilePath.isEmpty()) 
00388         profile = manager->loadProfile(profilePath);
00389     setDefaultProfile(profile);
00390     _viewManager->restoreSessions(group);
00391 }
00392 
00393 void MainWindow::saveGlobalProperties(KConfig* config)
00394 {
00395     SessionManager::instance()->saveSessions(config);
00396 }
00397 
00398 void MainWindow::readGlobalProperties(KConfig* config)
00399 {
00400     SessionManager::instance()->restoreSessions(config);
00401 }
00402 
00403 void MainWindow::syncActiveShortcuts(KActionCollection* dest, const KActionCollection* source)
00404 {
00405     foreach(QAction* qAction, source->actions()) 
00406     {
00407         if (KAction* kAction = qobject_cast<KAction*>(qAction))
00408         {
00409            if (KAction* destKAction = qobject_cast<KAction*>(dest->action(kAction->objectName())))
00410                destKAction->setShortcut(kAction->shortcut(KAction::ActiveShortcut),KAction::ActiveShortcut);
00411         }
00412     }
00413 }
00414 void MainWindow::showShortcutsDialog()
00415 {
00416     KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this);
00417 
00418     // add actions from this window and the current session controller
00419     foreach(KXMLGUIClient* client, guiFactory()->clients())
00420                 dialog.addCollection(client->actionCollection());
00421 
00422     if (dialog.configure())
00423     {
00424         // sync shortcuts for non-session actions (defined in "konsoleui.rc") in other main windows
00425         foreach(QWidget* widget, QApplication::topLevelWidgets())
00426         {
00427             MainWindow* window = qobject_cast<MainWindow*>(widget);
00428             if (window && window != this)
00429                 syncActiveShortcuts(window->actionCollection(),actionCollection());
00430         }
00431         // sync shortcuts for session actions (defined in "sessionui.rc") in other session controllers.
00432         // Controllers which are currently plugged in (ie. their actions are part of the current menu)
00433         // must be updated immediately via syncActiveShortcuts().  Other controllers will be updated
00434         // when they are plugged into a main window.
00435         foreach(SessionController* controller, SessionController::allControllers())
00436         {
00437             controller->reloadXML();
00438             if (controller->factory() && controller != _pluggedController)
00439                 syncActiveShortcuts(controller->actionCollection(),_pluggedController->actionCollection());
00440         }
00441     }
00442 }
00443 
00444 void MainWindow::newFromProfile(Profile::Ptr profile)
00445 {
00446     emit newSessionRequest(profile, activeSessionDir(), _viewManager);
00447 }
00448 void MainWindow::showManageProfilesDialog()
00449 {
00450     ManageProfilesDialog* dialog = new ManageProfilesDialog(this);
00451     dialog->show();
00452 }
00453 
00454 void MainWindow::showRemoteConnectionDialog()
00455 {
00456 //    RemoteConnectionDialog dialog(this);
00457 //    if ( dialog.exec() == QDialog::Accepted )
00458 //        emit newSessionRequest(dialog.sessionKey(),QString(),_viewManager);
00459 }
00460 
00461 void MainWindow::setupWidgets()
00462 {
00463     QWidget* widget = new QWidget(this);
00464     QVBoxLayout* layout = new QVBoxLayout();
00465 
00466     layout->addWidget( _viewManager->widget() );
00467     layout->setMargin(0);
00468     layout->setSpacing(0);
00469 
00470     widget->setLayout(layout);
00471 
00472     setCentralWidget(widget);
00473 }
00474 
00475 void MainWindow::configureNotifications()
00476 {
00477     KNotifyConfigWidget::configure( this );
00478 }
00479 
00480 #include "MainWindow.moc"
00481 
00482 /*
00483   Local Variables:
00484   mode: c++
00485   c-file-style: "stroustrup"
00486   indent-tabs-mode: nil
00487   tab-width: 4
00488   End:
00489 */

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal