Part.cpp 8.85 KB
Newer Older
1
/*
2
    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

    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.
*/

20 21 22
// Own
#include "Part.h"

23
// Qt
Dirk Mueller's avatar
Dirk Mueller committed
24
#include <QtCore/QStringList>
25
#include <QDir>
26

27
// KDE
28 29
#include <KAction>
#include <KActionCollection>
30
#include <KDebug>
31
#include <KLocale>
32
#include <KWindowSystem>
33
#include <kdeversion.h>
34
#include <kde_file.h>
35 36 37

// Konsole
#include "ColorScheme.h"
38
#include "EditProfileDialog.h"
39
#include "Emulation.h"
40
#include "KeyboardTranslator.h"
41
#include "ManageProfilesDialog.h"
42 43 44
#include "Session.h"
#include "SessionController.h"
#include "SessionManager.h"
45
#include "TerminalDisplay.h"
46
#include "ViewManager.h"
47
#include "MainWindow.h"
48

49
// X
50
#include "config-konsole.h"
51

52 53 54 55 56 57 58 59 60 61 62 63
extern "C"
{
    // entry point for Konsole part library,
    // returns a new factory which can be used to construct Konsole parts
    KDE_EXPORT void* init_libkonsolepart()
    {
        return new Konsole::PartFactory;
    }
}

using namespace Konsole;

64
KParts::Part* PartFactory::createPartObject( QWidget* parentWidget,
65 66 67 68
                                             QObject* parent,
                                             const char* /*classname*/,
                                             const QStringList& /*args*/)
{
69
    return new Part(parentWidget,parent);
70 71
}

72 73
K_EXPORT_PLUGIN(Konsole::PartFactory())

74
Part::Part(QWidget* parentWidget , QObject* parent)
75 76 77
 : KParts::ReadOnlyPart(parent)
  ,_viewManager(0)
  ,_pluggedController(0)
78
  ,_manageProfilesAction(0)
79
{
80
    // make sure the konsole catalog is loaded
81
    KGlobal::locale()->insertCatalog("konsole");
82

83

84

85 86
    // setup global actions
    createGlobalActions();
87

88
    // create view widget
89
    _viewManager = new ViewManager(this,actionCollection());
90
    _viewManager->setNavigationMethod( ViewManager::NoNavigation );
91

92
    connect( _viewManager , SIGNAL(activeViewChanged(SessionController*)) , this ,
93
           SLOT(activeViewChanged(SessionController*)) );
94
    connect( _viewManager , SIGNAL(empty()) , this , SLOT(terminalExited()) );
95
    connect( _viewManager , SIGNAL(newViewRequest()) , this , SLOT(newTab()) );
96 97 98

    _viewManager->widget()->setParent(parentWidget);

99
    setWidget(_viewManager->widget());
100 101 102
    actionCollection()->addAssociatedWidget(_viewManager->widget());
    foreach (QAction* action, actionCollection()->actions())
        action->setShortcutContext(Qt::WidgetWithChildrenShortcut);
103

104 105 106 107
    // Enable translucency support.
    _viewManager->widget()->setAttribute(Qt::WA_TranslucentBackground, true);
    TerminalDisplay::HAVE_TRANSPARENCY = KWindowSystem::compositingActive();

108
    // create basic session
109
    createSession();
110 111 112
}
Part::~Part()
{
113
    SessionManager::instance()->saveState();
114
}
115 116
void Part::createGlobalActions()
{
117 118
    _manageProfilesAction = new QAction(i18n("Manage Profiles..."),this);
    connect(_manageProfilesAction,SIGNAL(triggered()),this,SLOT(showManageProfilesDialog()));
119 120 121
}
void Part::setupActionsForSession(SessionController* session)
{
122 123
    KActionCollection* collection = session->actionCollection();
    collection->addAction("manage-profiles",_manageProfilesAction);
124
}
125 126 127 128
bool Part::openFile()
{
    return false;
}
129
void Part::terminalExited()
130
{
131
    deleteLater();
132
}
133 134
void Part::newTab()
{
135
    createSession();
136 137
    showShellInDir( QString() );
}
138 139
Session* Part::activeSession() const
{
140 141 142 143 144 145 146 147 148 149
    if ( _viewManager->activeViewController() )
    {
        Q_ASSERT( _viewManager->activeViewController()->session());

        return _viewManager->activeViewController()->session();
    }
    else
    {
        return 0;
    }
150
}
151 152 153
void Part::startProgram( const QString& program,
                           const QStringList& arguments )
{
154
    Q_ASSERT( activeSession() );
155

156
    if ( !activeSession()->isRunning() )
157 158 159 160 161 162
    {
        if ( !program.isEmpty() && !arguments.isEmpty() )
        {
            activeSession()->setProgram(program);
            activeSession()->setArguments(arguments);
        }
163

164 165
        activeSession()->run();
    }
166
}
167 168
void Part::openTeletype(int fd)
{
169
    Q_ASSERT( activeSession() );
170

171
    activeSession()->openTeletype(fd);
172
}
173 174
void Part::showShellInDir( const QString& dir )
{
175
    Q_ASSERT( activeSession() );
176

177
    if ( !activeSession()->isRunning() )
178 179 180 181 182
    {
        if ( !dir.isEmpty() )
            activeSession()->setInitialWorkingDirectory(dir);
        activeSession()->run();
    }
183 184 185
}
void Part::sendInput( const QString& text )
{
186 187
    Q_ASSERT( activeSession() );
    activeSession()->emulation()->sendText(text);
188
}
189

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
int Part::terminalProcessId()
{
    Q_ASSERT( activeSession() );

    return activeSession()->processId();

}

int Part::foregroundProcessId()
{
    Q_ASSERT( activeSession() );

    if (activeSession()->isForegroundProcessActive()) {
        return activeSession()->foregroundProcessId();
    } else {
        return -1;
    }
}

QString Part::foregroundProcessName()
{
    Q_ASSERT( activeSession() );

    if (activeSession()->isForegroundProcessActive()) {
        return activeSession()->foregroundProcessName();
    } else {
        return "";
    }
}

220
Session* Part::createSession(const Profile::Ptr profile)
221
{
222
    Session* session = SessionManager::instance()->createSession(profile);
223
    _viewManager->createView(session);
Robert Knight's avatar
Robert Knight committed
224 225

    return session;
226 227 228
}
void Part::activeViewChanged(SessionController* controller)
{
229 230
    Q_ASSERT( controller );
    Q_ASSERT( controller->view() );
231

232
    // remove existing controller
233
    if (_pluggedController)
234 235 236 237 238 239 240 241
    {
        removeChildClient (_pluggedController);
        disconnect(_pluggedController,SIGNAL(titleChanged(ViewProperties*)),this,
                    SLOT(activeViewTitleChanged(ViewProperties*)));
    }

    // insert new controller
    setupActionsForSession(controller);
242
    insertChildClient(controller);
243 244 245
    connect(controller,SIGNAL(titleChanged(ViewProperties*)),this,
            SLOT(activeViewTitleChanged(ViewProperties*)));
    activeViewTitleChanged(controller);
246

247 248
    const char* displaySignal = SIGNAL(overrideShortcutCheck(QKeyEvent*,bool&));
    const char* partSlot = SLOT(overrideTerminalShortcut(QKeyEvent*,bool&));
249

250 251
    disconnect(controller->view(),displaySignal,this,partSlot);
    connect(controller->view(),displaySignal,this,partSlot);
252

253 254
    _pluggedController = controller;
}
255 256
void Part::overrideTerminalShortcut(QKeyEvent* event, bool& override)
{
257 258 259
    // override all shortcuts in the embedded terminal by default
    override = true;
    emit overrideShortcut(event,override);
260
}
261 262
void Part::activeViewTitleChanged(ViewProperties* properties)
{
263
    emit setWindowCaption(properties->title());
264
}
265 266
void Part::showManageProfilesDialog()
{
267
    showManageProfilesDialog(_viewManager->widget());
268
}
269 270
void Part::showManageProfilesDialog(QWidget* parent)
{
271 272 273 274
    ManageProfilesDialog* dialog = new ManageProfilesDialog(parent);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setShortcutEditorVisible(false);
    dialog->show();
275 276 277
}
void Part::showEditCurrentProfileDialog(QWidget* parent)
{
278
    Q_ASSERT( activeSession() );
279

280 281 282 283
    EditProfileDialog* dialog = new EditProfileDialog(parent);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setProfile( SessionManager::instance()->sessionProfile(activeSession()) );
    dialog->show();
284
}
285 286
void Part::changeSessionSettings(const QString& text)
{
287 288 289 290 291 292 293 294
    // send a profile change command, the escape code format
    // is the same as the normal X-Term commands used to change the window title or icon,
    // but with a magic value of '50' for the parameter which specifies what to change
    Q_ASSERT( activeSession() );
    QByteArray buffer;
    buffer.append("\033]50;").append(text.toUtf8()).append('\a');

    activeSession()->emulation()->receiveData(buffer.constData(),buffer.length());
295 296 297 298 299
}

// Konqueror integration
bool Part::openUrl( const KUrl & _url )
{
300 301 302 303
    if ( url() == _url ) {
        emit completed();
        return true;
    }
304

305 306
    setUrl( _url );
    emit setWindowCaption( _url.pathOrUrl() );
307
    //kdDebug(1211) << "Set Window Caption to " << url.pathOrUrl();
308
    emit started( 0 );
309

310 311 312 313 314
    if ( _url.isLocalFile() /*&& b_openUrls*/ ) {
        KDE_struct_stat buff;
        KDE_stat( QFile::encodeName( _url.path() ), &buff );
        QString text = ( S_ISDIR( buff.st_mode ) ? _url.path() : _url.directory() );
        showShellInDir( text );
315 316
    } else {
        showShellInDir( QDir::homePath() );
317
    }
318

319 320
    emit completed();
    return true;
321
}
322 323

#include "Part.moc"