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
24 #include <QtCore/QStringList>
29 #include <KActionCollection>
32 #include <KWindowSystem>
33 #include <kdeversion.h>
37 #include "ColorScheme.h"
38 #include "EditProfileDialog.h"
39 #include "Emulation.h"
40 #include "KeyboardTranslator.h"
41 #include "ManageProfilesDialog.h"
43 #include "SessionController.h"
44 #include "SessionManager.h"
45 #include "TerminalDisplay.h"
46 #include "ViewManager.h"
47 #include "MainWindow.h"
50 #include "config-konsole.h"
54 #include <X11/extensions/Xrender.h>
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
,
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
)
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();
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
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)
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
)
147 return KWindowSystem::compositingActive();
156 bool Part::openFile()
160 void Part::terminalExited()
167 showShellInDir( QString() );
169 Session
* Part::activeSession() const
171 if ( _viewManager
->activeViewController() )
173 Q_ASSERT( _viewManager
->activeViewController()->session());
175 return _viewManager
->activeViewController()->session();
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
);
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
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);
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()) );
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() );
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
) {
307 emit
setWindowCaption( _url
.pathOrUrl() );
308 //kdDebug(1211) << "Set Window Caption to " << url.pathOrUrl();
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
);