SessionManager.h 18.2 KB
Newer Older
Robert Knight's avatar
Robert Knight committed
1 2 3
/*
    This source file is part of Konsole, a terminal emulator.

4
    Copyright (C) 2006-7 by Robert Knight <robertknight@gmail.com>
Robert Knight's avatar
Robert Knight committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

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

Robert Knight's avatar
 
Robert Knight committed
22 23 24
#ifndef SESSIONMANAGER_H
#define SESSIONMANAGER_H

25 26
// Qt
#include <QFont>
27
#include <QHash>
28
#include <QList>
29
#include <QSet>
30
#include <QStringList>
31
#include <QPair>
32
#include <QPointer>
33
#include <QVariant>
34

35 36
class KConfigGroup;
class KDesktopFile;
37
class KConfig;
Robert Knight's avatar
 
Robert Knight committed
38

39 40 41 42
namespace Konsole
{

class Session;
43

44
class Profile : public QObject 
45 46 47 48
{
public:
    enum Property
    {
49
        // Path to profile's config file
50
        Path,   // QString
51 52

        // General profile options
53 54 55 56 57 58 59
        Name,   // QString
        Title,  // QString
        Icon,   // QString
        Command,        // QString
        Arguments,      // QStringList
        Environment,    // QStringList
        Directory,      // QString
60

61
        // Tab Title Formats
62 63
        LocalTabTitleFormat,    // QString
        RemoteTabTitleFormat,   // QString
64 65

        // Window & Tab Bar 
66 67
        ShowMenuBar,    // bool
        TabBarMode,     // TabBarMode
68

69
        // Appearence
70 71
        Font,           // QFont
        ColorScheme,    // QString
72 73

        // Keyboard
74
        KeyBindings,    // QString
75

76
        // Scrolling
77 78 79
        HistoryMode,        // HistoryMode
        HistorySize,        // int
        ScrollBarPosition,  // ScrollBarPosition
80

81
        // Terminal Features
82 83 84
        SelectWordCharacters,       // QString   
        BlinkingTextEnabled,        // bool
        FlowControlEnabled,         // bool
85 86
        AllowProgramsToResizeWindow,// bool
        BlinkingCursorEnabled       // bool 
87 88 89
        
    };

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
    enum TabBarModeEnum
    {
        AlwaysHideTabBar,
        ShowTabBarAsNeeded,
        AlwaysShowTabBar
    };

    enum HistoryModeEnum
    {
        DisableHistory,
        FixedSizeHistory,
        UnlimitedHistory
    };

    enum ScrollBarPositionEnum
    {
        ScrollBarLeft,
        ScrollBarRight,
        ScrollBarHidden
    };

111 112 113
    /**
     * Constructs a new profile
     */
114
    Profile(Profile* parent = 0);
115
    virtual ~Profile() {}
116

117 118 119 120 121
    /** 
     * Changes the parent profile.  When calling the property() method,
     * if the specified property has not been set for this profile,
     * the parent's value for the property will be returned instead.
     */
122
    void setParent(Profile* parent);
123 124 125 126

    /** Returns the parent profile. */
    const Profile* parent() const;

127 128 129 130 131 132 133
    /** 
     * Returns the current value of the specified @p property. 
     *
     * If the specified @p property has not been set in this profile,
     * and a non-null parent was specified in the Profile's constructor,
     * the parent's value for @p property will be returned.
     */
134
    virtual QVariant property(Property property) const;
135 136
    /** Sets the value of the specified @p property to @p value. */
    virtual void setProperty(Property property,const QVariant& value);
137 138
    /** Returns true if the specified property has been set in this Profile instance. */
    virtual bool isPropertySet(Property property) const;
139

140 141 142
    /** Returns a map of the properties set in this Profile instance. */
    virtual QHash<Property,QVariant> setProperties() const;

143 144 145 146 147 148 149 150 151 152 153 154
    /** Returns true if no properties have been set in this Profile instance. */
    bool isEmpty() const;

    /** 
     * Returns true if this is a 'hidden' profile which should not be displayed
     * in menus.
     */
    bool isHidden() const;

    /** Specifies whether this is a hidden profile.  See isHidden() */
    void setHidden(bool hidden);

155 156 157 158
    //
    // Convenience methods for property() and setProperty() go here
    //

159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
    /** Convenience method for property(Profile::Path) */
    QString path() const { return property(Profile::Path).value<QString>(); }

    /** Convenience method for property(Profile::Name) */
    QString name() const { return property(Profile::Name).value<QString>(); }
    
    /** Convenience method for property(Profile::Directory) */
    QString defaultWorkingDirectory() const 
            { return property(Profile::Directory).value<QString>(); }

    /** Convenience method for property(Profile::Icon) */
    QString icon() const { return property(Profile::Icon).value<QString>(); }

    /** Convenience method for property(Profile::Command) */
    QString command() const { return property(Profile::Command).value<QString>(); }

    /** Convenience method for property(Profile::Arguments) */
    QStringList arguments() const { return property(Profile::Arguments).value<QStringList>(); }

    /** Convenience method for property(Profile::Font) */
    QFont font() const { return property(Profile::Font).value<QFont>(); }

    /** Convenience method for property(Profile::ColorScheme) */
    QString colorScheme() const { return property(Profile::ColorScheme).value<QString>(); }

    /** Convenience method for property(Profile::Environment) */
    QStringList environment() const { return property(Profile::Environment).value<QStringList>(); }

    /** 
     * Convenience method.
     * Returns the value of the "TERM" value in the environment list.
     */
    QString terminal() const { return "xterm"; }

193 194 195 196 197 198
    /**
     * Returns true if @p name has been associated with an element
     * from the Property enum or false otherwise.
     */
    static bool isNameRegistered(const QString& name);

199 200 201 202
    /** 
     * Returns the element from the Property enum associated with the 
     * specified @p name.
     */
203
    static Property lookupByName(const QString& name);
204 205 206 207 208 209 210 211 212 213 214 215 216 217
    /**
     * Returns the string names associated with the specified @p property from
     * the Property enum, in the order the associations were created using
     * registerName()
     */
    static QList<QString> namesForProperty(Property property); 
    /**
     * Adds an association between a string @p name and a @p property.
     * Subsequent calls to lookupByName() with @p name as the argument
     * will return @p property.
     */
    static void registerName(Property property , const QString& name); 

private:
218
    QHash<Property,QVariant> _propertyValues;
219 220 221
    QPointer<Profile> _parent;

    bool _hidden;
222

223 224 225
    static QHash<QString,Property> _propertyNames;
};

226 227 228 229 230 231
class FallbackProfile : public Profile
{
public:
    FallbackProfile();
};

232 233 234 235 236
/** Interface for all classes which can load profile settings from a file. */
class ProfileReader
{
public:
    virtual ~ProfileReader() {}
237
    virtual QStringList findProfiles() { return QStringList(); }
238 239 240 241 242 243
    virtual bool readProfile(const QString& path , Profile* profile) = 0;
};
/** Reads a KDE 3 profile .desktop file. */
class KDE3ProfileReader : public ProfileReader
{
public:
244
    virtual QStringList findProfiles();
245 246
    virtual bool readProfile(const QString& path , Profile* profile);
};
247
/** Reads a KDE 4 .profile file. */
248 249
class KDE4ProfileReader : public ProfileReader
{
250 251
public:
    virtual QStringList findProfiles();
252
    virtual bool readProfile(const QString& path , Profile* profile);
253 254 255 256 257
private:
    void readStandardElement(const KConfigGroup& group , 
                             char* name , 
                             Profile* info , 
                             Profile::Property property);
258 259 260 261 262 263
};
/** Interface for all classes which can write profile settings to a file. */
class ProfileWriter
{
public:
    virtual ~ProfileWriter() {}
264
    virtual QString getPath(const Profile* profile) = 0;
265 266
    virtual bool writeProfile(const QString& path , const Profile* profile) = 0;
};
267
/** Writes a KDE 4 .profile file. */
268 269 270
class KDE4ProfileWriter : public ProfileWriter
{
public:
271 272
    virtual QString getPath(const Profile* profile);
    virtual bool writeProfile(const QString& path , const Profile* profile);
273 274 275 276 277 278

private:
    void writeStandardElement(KConfigGroup& group,
                              char* name,
                              const Profile* profile,
                              Profile::Property property);
279 280 281
};

#if 0
Robert Knight's avatar
 
Robert Knight committed
282 283 284 285 286 287 288
/** 
 * Provides information about a type of 
 * session, including the title of the session
 * type, whether or not the session will run
 * as root and whether or not the binary
 * for the session is available.
 *
289
 * The availability of the profile is not determined until the
Robert Knight's avatar
 
Robert Knight committed
290
 * isAvailable() method is called.
291 292
 *
 */
293
class Profile
Robert Knight's avatar
 
Robert Knight committed
294 295
{
public:
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317

    enum Property
    {
        // General session options
        Name,
        Title,
        Icon,
        Command,
        Arguments,
        Environment,
        Directory,

        // Appearence
        Font,
        ColorScheme,

        // Keyboard
        KeyBindings,

        // Terminal Features
    };

318
    /**
319
     * Construct a new Profile
320
     * to provide information on a profile.
Robert Knight's avatar
 
Robert Knight committed
321 322 323 324
     *
     * @p path Path to the configuration file
     * for this type of session
     */
325
    Profile(const QString& path);
326
    
327
    virtual ~Profile();
328

329
    /** Sets the parent profile. */
330
    void setParent( Profile* parent );
331
    /** Returns the parent profile. */
332
    Profile* parent() const;
333 334 335 336 337
    /** Sets the value of a property. */
    virtual void setProperty( Property property , const QVariant& value );
    /** Retrieves the value of a property. */
    virtual QVariant property( Property property ) const;

338
    /**
Robert Knight's avatar
 
Robert Knight committed
339 340 341 342 343
     * Returns the path to the session's
     * config file
     */
    QString path() const;

344
    /** Returns the title of the profile */
345
    QString name() const;
346
    /**
Robert Knight's avatar
 
Robert Knight committed
347
     * Returns the path of an icon associated
348
     * with this profile
Robert Knight's avatar
 
Robert Knight committed
349
     */
350
    QString icon() const;
351
    /**
Robert Knight's avatar
 
Robert Knight committed
352 353 354
     * Returns the command that will be executed
     * when the session is run
     *
Robert Knight's avatar
 
Robert Knight committed
355
     * @param stripSu For commands of the form
Robert Knight's avatar
 
Robert Knight committed
356 357 358
     * "su -flags 'commandname'", specifies whether
     * to return the whole command string or just
     * the 'commandname' part
359 360
     *
     * eg.  If the command string is
Robert Knight's avatar
 
Robert Knight committed
361 362
     * "su -c 'screen'", command(true) will
     * just return "screen"
Robert Knight's avatar
 
Robert Knight committed
363
     *
364
     * @param stripArguments Specifies whether the arguments should be
Robert Knight's avatar
 
Robert Knight committed
365
     * removed from the returned string.  Anything after the first space
366
     * character in the command string is considered an argument
Robert Knight's avatar
 
Robert Knight committed
367
     */
368
    QString command(bool stripSu , bool stripArguments = true) const;
369 370

    /**
Robert Knight's avatar
 
Robert Knight committed
371 372
     * Extracts the arguments from the command string for this session.  The first
     * argument is always the command name
Robert Knight's avatar
 
Robert Knight committed
373
     */
374
    QStringList arguments() const;
375 376

    /**
Robert Knight's avatar
 
Robert Knight committed
377 378 379
     * Returns true if the session will run as
     * root
     */
380
    bool isRootSession() const;
Robert Knight's avatar
 
Robert Knight committed
381 382 383 384
    /**
     * Searches the user's PATH for the binary
     * specified in the command string.
     *
385 386
     * TODO:  isAvailable() assumes and does not yet verify the
     * existence of additional binaries(usually 'su' or 'sudo') required
Robert Knight's avatar
 
Robert Knight committed
387 388
     * to run the command as root.
     */
389
    bool isAvailable() const;
Robert Knight's avatar
 
Robert Knight committed
390

391 392
    /**
     * Returns the terminal-type string which is made available to
Robert Knight's avatar
 
Robert Knight committed
393 394 395 396
     * programs running in sessions of this type via the $TERM environment variable.
     *
     * This defaults to "xterm"
     */
397
    QString terminal() const;
Robert Knight's avatar
 
Robert Knight committed
398 399

    /** Returns the path of the default keyboard setup file for sessions of this type */
400
    QString keyboardSetup() const;
Robert Knight's avatar
 
Robert Knight committed
401 402

    /** Returns the path of the default colour scheme for sessions of this type */
403
    QString colorScheme() const;
Robert Knight's avatar
 
Robert Knight committed
404

405
    /**
Robert Knight's avatar
 
Robert Knight committed
406 407 408
     * Returns the default font for sessions of this type.
     * If no font is specified in the session's configuration file, @p font will be returned.
     */
409
    QFont defaultFont() const;
Robert Knight's avatar
 
Robert Knight committed
410 411

    /** Returns the default working directory for sessions of this type */
412
    QString defaultWorkingDirectory() const;
Robert Knight's avatar
 
Robert Knight committed
413

414
    /**
Robert Knight's avatar
 
Robert Knight committed
415 416 417
     * Returns the text that should be displayed in menus or in other UI widgets
     * which are used to create new instances of this type of session
     */
418
    QString newSessionText() const;
419

Robert Knight's avatar
 
Robert Knight committed
420
private:
421
    Profile* _parent;
422 423
    KDesktopFile* _desktopFile;
    KConfigGroup* _config;
Robert Knight's avatar
 
Robert Knight committed
424
    QString  _path;
425

426
    QHash<Property,QVariant> _properties;
427
};
428
#endif
429

430 431 432
/**
 * Creates new terminal sessions using information in configuration files.
 * Information about the available session kinds can be obtained using
433
 * availableprofiles().  Call createSession() to create a new session.
434
 * The session will automatically notify the SessionManager when it finishes running.
435 436 437
 *
 * Session types in the manager have a concept of favorite status, which can be used
 * by widgets and dialogs in the application decide which sessions to list and
438
 * how to display them.  The favorite status of a profile can be altered using
439
 * setFavorite() and retrieved using isFavorite() 
440
 */
Robert Knight's avatar
 
Robert Knight committed
441
class SessionManager : public QObject
Robert Knight's avatar
 
Robert Knight committed
442
{
443
Q_OBJECT
Robert Knight's avatar
 
Robert Knight committed
444

Robert Knight's avatar
 
Robert Knight committed
445
public:
446 447
    /** 
     * Constructs a new session manager and loads information about the available 
448
     * profiles.
449
     */
Robert Knight's avatar
 
Robert Knight committed
450 451
    SessionManager();
    virtual ~SessionManager();
452

Robert Knight's avatar
 
Robert Knight committed
453
    /**
454
     * Returns a list of keys for registered profiles. 
455
     */
456
    QList<QString> availableProfiles() const;
457
    /**
458 459
     * Returns the session information object for the profile with the specified
     * key or 0 if no profile with the specified key exists.
460
     *
461
     * If @p key is empty, a pointer to the default profile is returned.
462
     */
463
    Profile* profile(const QString& key) const;
464 465 466 467

    /**
     * Registers a new type of session and returns the key
     * which can be passed to createSession() to create new instances of the session.
468 469 470
     *
     * The favorite status of the session ( as returned by isFavorite() ) is set
     * to false by default.
Robert Knight's avatar
 
Robert Knight committed
471
     */
472
    QString addProfile(Profile* type);
Robert Knight's avatar
 
Robert Knight committed
473

474 475 476 477 478 479 480 481 482
    /**
     * Updates the profile associated with the specified @p key with
     * the changes specified in @p propertyMap.
     *
     * @param key The profile's key
     * @param propertyMap A map between profile properties and values describing the changes
     */
    void changeProfile(const QString& key , QHash<Profile::Property,QVariant> propertyMap);

483
    /**
484
     * Returns a Profile object describing the default type of session, which is used
485
     * if createSession() is called with an empty configPath argument.
486
     */
487
    Profile* defaultProfile() const;
488 489

    /**
490
     * Returns the key for the default profile.
491
     */
492
    QString defaultProfileKey() const;
493 494

    /**
495 496 497
     * Creates a new session from the specified profile, using the settings specified
     * using addSetting() and from profile associated with the specified key.
     * The profile must have been previously registered using addprofile()
498
     * or upon construction of the SessionManager. 
499
     *
500
     * The new session has no views associated with it.  A new TerminalDisplay view
501
     * must be created in order to display the output from the terminal session and
502
     * send keyboard or mouse input to it.
Robert Knight's avatar
 
Robert Knight committed
503 504 505 506
     *
     * @param type Specifies the type of session to create.  Passing an empty
     *             string will create a session using the default configuration.
     */
507
    Session* createSession(QString key = QString());
508

Robert Knight's avatar
 
Robert Knight committed
509 510 511
    /**
     * Returns a list of active sessions.
     */
512
    const QList<Session*> sessions();
Robert Knight's avatar
 
Robert Knight committed
513

514
    /**
515 516
     * Deletes the profile with the specified key.
     * The configuration file associated with the profile is
517 518
     * deleted if possible.
     */
519
    void deleteProfile(const QString& key);
520 521

    /**
522
     * Sets the profile with the specified key
523 524
     * as the default type.
     */
525
    void setDefaultProfile(const QString& key);
526 527

    /**
528
     * Returns the set of keys for the user's favorite profiles.
529
     */
530
    QSet<QString> findFavorites() ;
531 532

    /**
533
     * Specifies whether a profile should be included in the user's
534 535 536 537
     * list of favorite sessions.
     */
    void setFavorite(const QString& key , bool favorite);

538 539 540
    /** Loads all available profiles. */
    void loadAllProfiles();

541 542 543 544 545 546 547 548 549 550
    /**
     * Sets the global session manager instance.
     */
    static void setInstance(SessionManager* instance);
    /**
     * Returns the session manager instance.
     */
    static SessionManager* instance();

signals:
551 552 553 554
    /** Emitted when a profile is added to the manager. */
    void profileAdded(const QString& key);
    /** Emitted when a profile is removed from the manager. */
    void profileRemoved(const QString& key);
555 556 557
    /** Emitted when a profile's properties are modified. */
    void profileChanged(const QString& key);

558
    /** 
559
     * Emitted when the favorite status of a profile changes. 
560
     * 
561
     * @param key The key for the profile
562 563 564 565
     * @param favorite Specifies whether the session is a favorite or not 
     */
    void favoriteStatusChanged(const QString& key , bool favorite);

Robert Knight's avatar
 
Robert Knight committed
566 567 568
protected Q_SLOTS:

    /**
569
     * Called to inform the manager that a session has finished executing
Robert Knight's avatar
 
Robert Knight committed
570
     */
571
    void sessionTerminated( Session* session );
Robert Knight's avatar
 
Robert Knight committed
572 573

private:
574
    //loads the set of favorite sessions
575 576 577
    void loadFavorites();
    //saves the set of favorite sessions
    void saveFavorites();
578 579 580 581
    //loads a profile from a file
    QString loadProfile(const QString& path);
        // saves a profile to a file
    void saveProfile(const QString& path , Profile* profile);
582

583 584 585 586 587 588 589 590 591
    // applies updates to the profile associated with @p key
    // to all sessions currently using that profile
    // if modifiedPropertiesOnly is true, only properties which
    // are set in the profile @p key are updated
    void applyProfile(const QString& key , bool modifiedPropertiesOnly);
    // apples updates to the profile @p info to the session @p session
    // if modifiedPropertiesOnly is true, only properties which
    // are set in @p info are update ( ie. properties for which info->isPropertySet(<property>) 
    // returns true )
592
    void applyProfile(Session* session , const Profile* info , bool modifiedPropertiesOnly); 
593

594
    QHash<QString,Profile*> _types;
595
    QList<Session*> _sessions;
Robert Knight's avatar
 
Robert Knight committed
596

597
    QString _defaultProfile;
598 599 600
    
    QSet<QString> _favorites;

601 602
    bool _loadedAllProfiles;

603
    static SessionManager* _instance;
Robert Knight's avatar
 
Robert Knight committed
604 605
};

606
};
Robert Knight's avatar
 
Robert Knight committed
607
#endif //SESSIONMANAGER_H