Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konsole / src / Part.cpp
bloba25535393313e92abe9df15f93deaea9ae36301f
1 /*
2 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
20 // Own
21 #include "Part.h"
23 // Qt
24 #include <QtCore/QStringList>
27 // KDE
28 #include <KAction>
29 #include <KActionCollection>
30 #include <KDebug>
31 #include <KLocale>
32 #include <KWindowSystem>
33 #include <kdeversion.h>
34 #include <kde_file.h>
36 // Konsole
37 #include "ColorScheme.h"
38 #include "EditProfileDialog.h"
39 #include "Emulation.h"
40 #include "KeyboardTranslator.h"
41 #include "ManageProfilesDialog.h"
42 #include "Session.h"
43 #include "SessionController.h"
44 #include "SessionManager.h"
45 #include "TerminalDisplay.h"
46 #include "ViewManager.h"
47 #include "MainWindow.h"
49 // X
50 #include "config-konsole.h"
51 #ifdef Q_WS_X11
52 #include <X11/Xlib.h>
53 #ifdef HAVE_XRENDER
54 #include <X11/extensions/Xrender.h>
55 #endif
56 #endif
58 extern "C"
60 // entry point for Konsole part library,
61 // returns a new factory which can be used to construct Konsole parts
62 KDE_EXPORT void* init_libkonsolepart()
64 return new Konsole::PartFactory;
68 using namespace Konsole;
70 KParts::Part* PartFactory::createPartObject( QWidget* parentWidget,
71 QObject* parent,
72 const char* /*classname*/,
73 const QStringList& /*args*/)
75 return new Part(parentWidget,parent);
78 K_EXPORT_PLUGIN(Konsole::PartFactory())
80 Part::Part(QWidget* parentWidget , QObject* parent)
81 : KParts::ReadOnlyPart(parent)
82 ,_viewManager(0)
83 ,_pluggedController(0)
84 ,_manageProfilesAction(0)
86 // make sure the konsole catalog is loaded
87 KGlobal::locale()->insertCatalog("konsole");
89 TerminalDisplay::HAVE_TRANSPARENCY = transparencyAvailable();
91 // setup global actions
92 createGlobalActions();
94 // create view widget
95 _viewManager = new ViewManager(this,actionCollection());
96 _viewManager->setNavigationMethod( ViewManager::NoNavigation );
98 connect( _viewManager , SIGNAL(activeViewChanged(SessionController*)) , this ,
99 SLOT(activeViewChanged(SessionController*)) );
100 connect( _viewManager , SIGNAL(empty()) , this , SLOT(terminalExited()) );
101 connect( _viewManager , SIGNAL(newViewRequest()) , this , SLOT(newTab()) );
103 _viewManager->widget()->setParent(parentWidget);
105 setWidget(_viewManager->widget());
106 actionCollection()->addAssociatedWidget(_viewManager->widget());
107 foreach (QAction* action, actionCollection()->actions())
108 action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
110 // create basic session
111 createSession();
113 Part::~Part()
115 SessionManager::instance()->saveState();
117 void Part::createGlobalActions()
119 _manageProfilesAction = new QAction(i18n("Manage Profiles..."),this);
120 connect(_manageProfilesAction,SIGNAL(triggered()),this,SLOT(showManageProfilesDialog()));
122 void Part::setupActionsForSession(SessionController* session)
124 KActionCollection* collection = session->actionCollection();
125 collection->addAction("manage-profiles",_manageProfilesAction);
127 bool Part::transparencyAvailable()
129 #if defined(Q_WS_X11) && defined(HAVE_XRENDER)
130 bool ARGB = false;
132 int screen = QX11Info::appScreen();
133 bool depth = (QX11Info::appDepth() == 32);
135 Display* display = QX11Info::display();
136 Visual* visual = static_cast<Visual*>(QX11Info::appVisual(screen));
138 XRenderPictFormat* format = XRenderFindVisualFormat(display, visual);
140 if (depth && format->type == PictTypeDirect && format->direct.alphaMask)
142 ARGB = true;
145 if (ARGB)
147 return KWindowSystem::compositingActive();
149 else
150 #endif
152 return false;
156 bool Part::openFile()
158 return false;
160 void Part::terminalExited()
162 deleteLater();
164 void Part::newTab()
166 createSession();
167 showShellInDir( QString() );
169 Session* Part::activeSession() const
171 if ( _viewManager->activeViewController() )
173 Q_ASSERT( _viewManager->activeViewController()->session());
175 return _viewManager->activeViewController()->session();
177 else
179 return 0;
182 void Part::startProgram( const QString& program,
183 const QStringList& arguments )
185 Q_ASSERT( activeSession() );
187 if ( !activeSession()->isRunning() )
189 if ( !program.isEmpty() && !arguments.isEmpty() )
191 activeSession()->setProgram(program);
192 activeSession()->setArguments(arguments);
195 activeSession()->run();
198 void Part::openTeletype(int fd)
200 Q_ASSERT( activeSession() );
202 activeSession()->openTeletype(fd);
204 void Part::showShellInDir( const QString& dir )
206 Q_ASSERT( activeSession() );
208 if ( !activeSession()->isRunning() )
210 if ( !dir.isEmpty() )
211 activeSession()->setInitialWorkingDirectory(dir);
212 activeSession()->run();
215 void Part::sendInput( const QString& text )
217 Q_ASSERT( activeSession() );
218 activeSession()->emulation()->sendText(text);
221 Session* Part::createSession(const Profile::Ptr profile)
223 Session* session = SessionManager::instance()->createSession(profile);
224 _viewManager->createView(session);
226 return session;
228 void Part::activeViewChanged(SessionController* controller)
230 Q_ASSERT( controller );
231 Q_ASSERT( controller->view() );
233 // remove existing controller
234 if (_pluggedController)
236 removeChildClient (_pluggedController);
237 disconnect(_pluggedController,SIGNAL(titleChanged(ViewProperties*)),this,
238 SLOT(activeViewTitleChanged(ViewProperties*)));
241 // insert new controller
242 setupActionsForSession(controller);
243 insertChildClient(controller);
244 connect(controller,SIGNAL(titleChanged(ViewProperties*)),this,
245 SLOT(activeViewTitleChanged(ViewProperties*)));
246 activeViewTitleChanged(controller);
248 const char* displaySignal = SIGNAL(overrideShortcutCheck(QKeyEvent*,bool&));
249 const char* partSlot = SLOT(overrideTerminalShortcut(QKeyEvent*,bool&));
251 disconnect(controller->view(),displaySignal,this,partSlot);
252 connect(controller->view(),displaySignal,this,partSlot);
254 _pluggedController = controller;
256 void Part::overrideTerminalShortcut(QKeyEvent* event, bool& override)
258 // override all shortcuts in the embedded terminal by default
259 override = true;
260 emit overrideShortcut(event,override);
262 void Part::activeViewTitleChanged(ViewProperties* properties)
264 emit setWindowCaption(properties->title());
266 void Part::showManageProfilesDialog()
268 showManageProfilesDialog(_viewManager->widget());
270 void Part::showManageProfilesDialog(QWidget* parent)
272 ManageProfilesDialog* dialog = new ManageProfilesDialog(parent);
273 dialog->setAttribute(Qt::WA_DeleteOnClose);
274 dialog->setShortcutEditorVisible(false);
275 dialog->show();
277 void Part::showEditCurrentProfileDialog(QWidget* parent)
279 Q_ASSERT( activeSession() );
281 EditProfileDialog* dialog = new EditProfileDialog(parent);
282 dialog->setAttribute(Qt::WA_DeleteOnClose);
283 dialog->setProfile( SessionManager::instance()->sessionProfile(activeSession()) );
284 dialog->show();
286 void Part::changeSessionSettings(const QString& text)
288 // send a profile change command, the escape code format
289 // is the same as the normal X-Term commands used to change the window title or icon,
290 // but with a magic value of '50' for the parameter which specifies what to change
291 Q_ASSERT( activeSession() );
292 QByteArray buffer;
293 buffer.append("\033]50;").append(text.toUtf8()).append('\a');
295 activeSession()->emulation()->receiveData(buffer.constData(),buffer.length());
298 // Konqueror integration
299 bool Part::openUrl( const KUrl & _url )
301 if ( url() == _url ) {
302 emit completed();
303 return true;
306 setUrl( _url );
307 emit setWindowCaption( _url.pathOrUrl() );
308 //kdDebug(1211) << "Set Window Caption to " << url.pathOrUrl();
309 emit started( 0 );
311 if ( _url.isLocalFile() /*&& b_openUrls*/ ) {
312 KDE_struct_stat buff;
313 KDE_stat( QFile::encodeName( _url.path() ), &buff );
314 QString text = ( S_ISDIR( buff.st_mode ) ? _url.path() : _url.directory() );
315 showShellInDir( text );
318 emit completed();
319 return true;
322 #include "Part.moc"