/* This source file is part of Konsole, a terminal emulator. Copyright 2006-2008 by Robert Knight 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. */ #ifndef SESSIONMANAGER_H #define SESSIONMANAGER_H // Qt #include #include #include #include #include #include #include #include #include #include #include // Konsole #include "Profile.h" class QSignalMapper; namespace Konsole { class Session; /** * Manages running terminal sessions and the profiles which specify various * settings for terminal sessions and their displays. * * Profiles 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 * how to display them. The favorite status of a profile can be altered using * setFavorite() and retrieved using isFavorite() */ class KDE_EXPORT SessionManager : public QObject { Q_OBJECT public: /** * Constructs a new session manager and loads information about the available * profiles. */ SessionManager(); /** * Destroys the SessionManager. All running sessions should be closed (via closeAll()) and the * SessionManager's state should be saved via saveState() before the SessionManager is destroyed. */ virtual ~SessionManager(); /** Kill all running sessions. */ void closeAll(); /** Saves state information (favorites, shortcuts, default profile etc.) to disk. */ void saveState(); /** * Returns a list of profiles which have been loaded. * Initially only the profile currently set as the default is loaded. * * Favorite profiles are loaded automatically when findFavorites() is called. * * All other profiles can be loaded by calling loadAllProfiles(). This may * involves opening, reading and parsing all profiles from disk, and * should only be done when necessary. */ QList loadedProfiles() const; /** * Searches for available profiles on-disk and returns a list * of paths of profiles which can be loaded. */ QStringList availableProfilePaths() const; /** * Loads a profile from the specified path and registers * it with the SessionManager. * * @p path may be relative or absolute. The path may just be the * base name of the profile to load (eg. if the profile's full path * is "/My Profile.profile" then both * "konsole/My Profile.profile" , "My Profile.profile" and * "My Profile" will be accepted) * * @return Pointer to a profile which can be passed to createSession() * to create a new session using this profile. */ Profile::Ptr loadProfile(const QString& path); /** * Updates a @p profile with the changes specified in @p propertyMap. * * All sessions currently using the profile will be updated to reflect the new settings. * * After the profile is updated, the profileChanged() signal will be emitted. * * @param profile The profile to change * @param propertyMap A map between profile properties and values describing the changes * @param persistant If true, the changes are saved to the profile's configuration file, * set this to false if you want to preview possible changes to a profile but do not * wish to make them permanent. */ void changeProfile(Profile::Ptr profile , QHash propertyMap, bool persistant = true); /** * Returns a Profile object describing the default type of session, which is used * if createSession() is called with an empty configPath argument. */ Profile::Ptr defaultProfile() const; /** * Returns a Profile object with hard-coded settings which is always available. * This can be used as a parent for new profiles which provides suitable default settings * for all properties. */ Profile::Ptr fallbackProfile() const; /** * Creates a new session using the settings specified by the specified * profile. * * The new session has no views associated with it. A new TerminalDisplay view * must be created in order to display the output from the terminal session and * send keyboard or mouse input to it. * * @param profile A profile containing the settings for the new session. If @p profile * is null the default profile (see defaultProfile()) will be used. */ Session* createSession(Profile::Ptr profile = Profile::Ptr()); /** Returns the profile associated with a session. */ Profile::Ptr sessionProfile(Session* session) const; /** Sets the profile associated with a session. */ void setSessionProfile(Session* session, Profile::Ptr profile); /** * Updates a session's properties to match its current profile. */ void updateSession(Session* session); /** * Returns a list of active sessions. */ const QList sessions(); /** * Deletes the configuration file used to store a profile. * The profile will continue to exist while sessions are still using it. The profile * will be marked as hidden (see Profile::setHidden() ) so that it does not show * up in profile lists and future changes to the profile are not stored to disk. * * Returns true if the profile was successfully deleted or false otherwise. */ bool deleteProfile(Profile::Ptr profile); /** * Sets the @p profile as the default profile for new sessions created * with createSession() */ void setDefaultProfile(Profile::Ptr profile); /** * Returns the set of the user's favorite profiles. */ QSet findFavorites(); /** * Returns the list of shortcut key sequences which * can be used to create new sessions based on * existing profiles * * When one of the shortcuts is activated, * use findByShortcut() to load the profile associated * with the shortcut. */ QList shortcuts(); /** * Finds and loads the profile associated with * the specified @p shortcut key sequence and returns a pointer to it. */ Profile::Ptr findByShortcut(const QKeySequence& shortcut); /** * Associates a shortcut with a particular profile. */ void setShortcut(Profile::Ptr profile , const QKeySequence& shortcut); /** Returns the shortcut associated with a particular profile. */ QKeySequence shortcut(Profile::Ptr profile) const; /** * Registers a new type of session. * The favorite status of the session ( as returned by isFavorite() ) is set to false by default. */ void addProfile(Profile::Ptr type); /** * Specifies whether a profile should be included in the user's * list of favorite sessions. */ void setFavorite(Profile::Ptr profile , bool favorite); /** * Loads all available profiles. This involves reading each * profile configuration file from disk and parsing it. * Therefore it should only be done when necessary. */ void loadAllProfiles(); /** * Sets the global session manager instance. */ static void setInstance(SessionManager* instance); /** * Returns the session manager instance. */ static SessionManager* instance(); signals: /** Emitted when a profile is added to the manager. */ void profileAdded(Profile::Ptr ptr); /** Emitted when a profile is removed from the manager. */ void profileRemoved(Profile::Ptr ptr); /** Emitted when a profile's properties are modified. */ void profileChanged(Profile::Ptr ptr); /** * Emitted when a session's settings are updated to match * its current profile. */ void sessionUpdated(Session* session); /** * Emitted when the favorite status of a profile changes. * * @param profile The profile to change * @param favorite Specifies whether the session is a favorite or not */ void favoriteStatusChanged(Profile::Ptr profile , bool favorite); /** * Emitted when the shortcut for a profile is changed. * * @param profile The profile whoose status was changed * @param newShortcut The new shortcut key sequence for the profile */ void shortcutChanged(Profile::Ptr profile , const QKeySequence& newShortcut); protected Q_SLOTS: /** * Called to inform the manager that a session has finished executing. * * @param session The Session which has finished executing. */ void sessionTerminated( QObject* session ); private slots: void sessionProfileCommandReceived(const QString& text); private: // loads the mappings between shortcut key sequences and // profile paths void loadShortcuts(); // saves the mappings between shortcut key sequences and // profile paths void saveShortcuts(); //loads the set of favorite sessions void loadFavorites(); //saves the set of favorite sessions void saveFavorites(); // saves a profile to a file // returns the path to which the profile was saved, which will // be the same as the path property of profile if valid or a newly generated path // otherwise QString saveProfile(Profile::Ptr profile); // applies updates to a profile // 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(Profile::Ptr ptr , 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() // returns true ) void applyProfile(Session* session , const Profile::Ptr info , bool modifiedPropertiesOnly); QSet _types; QHash _sessionProfiles; struct ShortcutData { Profile::Ptr profileKey; QString profilePath; }; QMap _shortcuts; // shortcut keys -> profile path QList _sessions; // list of running sessions Profile::Ptr _defaultProfile; Profile::Ptr _fallbackProfile; QSet _favorites; // list of favorite profiles bool _loadedAllProfiles; // set to true after loadAllProfiles has been called bool _loadedFavorites; // set to true after loadFavorites has been called QSignalMapper* _sessionMapper; }; class ShouldApplyProperty { public: ShouldApplyProperty(const Profile::Ptr profile , bool modifiedOnly) : _profile(profile) , _modifiedPropertiesOnly(modifiedOnly) {} bool shouldApply(Profile::Property property) const { return !_modifiedPropertiesOnly || _profile->isPropertySet(property); } private: const Profile::Ptr _profile; bool _modifiedPropertiesOnly; }; /** * PopStackOnExit is a utility to remove all values from a stack which are added during * the lifetime of a PopStackOnExit instance. * * When a PopStackOnExit instance is destroyed, elements are removed from the stack * until the stack count is reduced the value when the PopStackOnExit instance was created. */ template class PopStackOnExit { public: PopStackOnExit(QStack& stack) : _stack(stack) , _count(stack.count()) {} ~PopStackOnExit() { while (_stack.count() > _count) _stack.pop(); } private: QStack& _stack; int _count; }; class SessionListModel : public QAbstractListModel { Q_OBJECT public: SessionListModel(QObject* parent = 0); void setSessions(const QList& sessions); virtual QModelIndex index(int row, int column, const QModelIndex& parent) const; virtual QVariant data(const QModelIndex& index, int role) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; virtual int columnCount(const QModelIndex& parent) const; virtual int rowCount(const QModelIndex& parent) const; virtual QModelIndex parent(const QModelIndex& index) const; protected: virtual void sessionRemoved(Session*) {} private slots: void sessionFinished(); private: QList _sessions; }; } #endif //SESSIONMANAGER_H