2 This source file is part of Konsole, a terminal emulator.
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include <QtCore/QHash>
27 #include <QtCore/QObject>
28 #include <QtCore/QPointer>
29 #include <QtCore/QStringList>
30 #include <QtCore/QVariant>
32 #include <QtGui/QFont>
37 #include <kdemacros.h>
47 * Represents a terminal set-up which can be used to
48 * set the initial state of new terminal sessions or applied
49 * to existing sessions. Profiles consist of a number of named
50 * properties, which can be retrieved using property() and
51 * set using setProperty(). isPropertySet() can be used to check
52 * whether a particular property has been set in a profile.
54 * Profiles support a simple form of inheritance. When a new Profile
55 * is constructed, a pointer to a parent profile can be passed to
56 * the constructor. When querying a particular property of a profile
57 * using property(), the profile will return its own value for that
58 * property if one has been set or otherwise it will return the
59 * parent's value for that property.
61 * Profiles can be loaded from disk using ProfileReader instances
62 * and saved to disk using ProfileWriter instances.
64 class KDE_EXPORT Profile
: public QSharedData
67 friend class KDE4ProfileReader
;
68 friend class KDE4ProfileWriter
;
69 friend class ProfileGroup
;
72 typedef KSharedPtr
<Profile
> Ptr
;
73 typedef KSharedPtr
<ProfileGroup
> GroupPtr
;
76 * This enum describes the available properties
77 * which a Profile may consist of.
79 * Properties can be set using setProperty() and read
84 /** (QString) Path to the profile's configuration file on-disk. */
86 /** (QString) The descriptive name of this profile. */
88 /** (QString) Title of this profile that will be displayed. */
90 /** (QString) The name of the icon associated with this profile. This
91 * is used in menus and tabs to represent the profile.
94 /** (QString) The command to execute ( excluding arguments ) when creating a new terminal
95 * session using this profile.
98 /** (QStringList) The arguments which are passed to the program specified by
99 * the Command property when creating a new terminal session using this profile.
102 /** (QStringList) Additional environment variables ( in the form of NAME=VALUE pairs )
103 * which are passed to the program specified by the Command property
104 * when creating a new terminal session using this profile.
107 /** (QString) The initial working directory for sessions created using this profile. */
109 /** (QString) The format used for tab titles when running normal commands. */
111 /** (QString) The format used for tab titles when the session is running
112 * a remote command (eg. SSH) */
113 RemoteTabTitleFormat
,
114 /** (bool) Specifies whether the menu bar should be shown in the main application window. */
116 /** (TabBarModeEnum) Specifies when the tab bar should be shown in
117 * the main application window. */
119 /** (QFont) The font to use in terminal displays using this profile. */
122 * The name of the color scheme to use in terminal displays using this profile.
123 * Color schemes are managed by the ColorSchemeManager class.
126 /** (QString) The name of the key bindings.
127 * Key bindings are managed by the KeyboardTranslatorManager class.
130 /** (HistoryModeEnum) Specifies the storage type used for keeping the output produced
131 * by terminal sessions using this profile.
134 /** (int) Specifies the number of lines of output to remember in terminal sessions
135 * using this profile. Once the limit is reached, the oldest lines are lost.
136 * Only applicable if the HistoryMode property is FixedSizeHistory
139 /** (ScrollBarPositionEnum) Specifies the position of the scroll bar in
140 * terminal displays using this profile.
143 /** (bool) Specifies whether the terminal will enable Bidirectional text display */
144 BidiRenderingEnabled
,
145 /** (bool) Specifies whether text in terminal displays is allowed to blink. */
147 /** (bool) Specifies whether the flow control keys ( typically Ctrl+S , Ctrl+Q )
148 * have any effect. Also known as Xon/Xoff
151 /** (bool) Specifies whether programs running in the terminal are allowed to
152 * resize the terminal display.
154 AllowProgramsToResizeWindow
,
155 /** (bool) Specifies whether the cursor blinks ( in a manner similar
156 * to text editing applications )
158 BlinkingCursorEnabled
,
159 /** (bool) If true, terminal displays use a fixed color to draw the cursor,
160 * specified by the CustomCursorColor property. Otherwise the cursor changes
161 * color to match the character underneath it.
163 UseCustomCursorColor
,
164 /** (CursorShapeEnum) The shape used by terminal displays to represent the cursor. */
166 /** (QColor) The color used by terminal displays to draw the cursor. Only applicable
167 * if the UseCustomCursorColor property is true. */
169 /** (QString) A string consisting of the characters used to delimit words when
170 * selecting text in the terminal display.
173 /** (TabBarPositionEnum) Position of the tab-bar relative to the terminal displays. */
175 /** (String) Default text codec */
177 /** (bool) Whether fonts should be aliased or not */
179 /** (bool) Whether new sessions should be started in the same directory as the
180 * currently active session. */
181 StartInCurrentSessionDir
,
182 /** (bool) Whether a 'New Tab' and 'Close Tab' buttons should be shown on the tab bar */
183 ShowNewAndCloseTabButtons
187 * This enum describes the available modes for showing or hiding the tab bar.
191 /** The tab bar is never shown. */
192 AlwaysHideTabBar
= 0,
193 /** The tab bar is shown if there are multiple tabs open or hidden otherwise. */
194 ShowTabBarAsNeeded
= 1,
195 /** The tab bar is always shown. */
200 * This enum describes the available tab bar positions.
202 enum TabBarPositionEnum
204 /** Show tab bar below displays. */
206 /** Show tab bar above displays. */
211 * This enum describes the modes available to remember lines of output produced
216 /** No output is remembered. As soon as lines of text are scrolled off-screen they are lost. */
218 /** A fixed number of lines of output are remembered. Once the limit is reached, the oldest
220 FixedSizeHistory
= 1,
221 /** All output is remembered for the duration of the session.
222 * Typically this means that lines are recorded to
223 * a file as they are scrolled off-screen.
229 * This enum describes the positions where the terminal display's scroll bar may be placed.
231 enum ScrollBarPositionEnum
233 /** Show the scroll-bar on the left of the terminal display. */
235 /** Show the scroll-bar on the right of the terminal display. */
237 /** Do not show the scroll-bar. */
241 /** This enum describes the shapes used to draw the cursor in terminal displays. */
244 /** Use a solid rectangular block to draw the cursor. */
246 /** Use an 'I' shape, similar to that used in text editing applications, to draw the cursor. */
248 /** Draw a line underneath the cursor's position. */
253 * Constructs a new profile
255 * @param parent The parent profile. When querying the value of a property
256 * using property(), if the property has not been set in this profile then
257 * the parent's value for the property will be returned instead.
259 explicit Profile(Ptr parent
= Ptr());
263 * Copies all properties except Name and Path from the specified @p profile
266 * @param profile The profile to copy properties from
267 * @param differentOnly If true, only properties in @p profile which have a
268 * different value from this profile's current value (either set via
269 * setProperty() or inherited from the parent profile) will be set.
271 void clone(Ptr profile
, bool differentOnly
= true);
274 * Changes the parent profile. When calling the property() method,
275 * if the specified property has not been set for this profile,
276 * the parent's value for the property will be returned instead.
278 void setParent(Ptr parent
);
280 /** Returns the parent profile. */
281 const Ptr
parent() const;
283 /** Returns this profile as a group or null if this profile is not a group. */
284 const GroupPtr
asGroup() const;
288 * Returns the current value of the specified @p property, cast to type T.
289 * Internally properties are stored using the QVariant type and cast to T
290 * using QVariant::value<T>();
292 * If the specified @p property has not been set in this profile,
293 * and a non-null parent was specified in the Profile's constructor,
294 * the parent's value for @p property will be returned.
297 T
property(Property property
) const;
299 /** Sets the value of the specified @p property to @p value. */
300 virtual void setProperty(Property property
,const QVariant
& value
);
301 /** Returns true if the specified property has been set in this Profile instance. */
302 virtual bool isPropertySet(Property property
) const;
304 /** Returns a map of the properties set in this Profile instance. */
305 virtual QHash
<Property
,QVariant
> setProperties() const;
307 /** Returns true if no properties have been set in this Profile instance. */
308 bool isEmpty() const;
311 * Returns true if this is a 'hidden' profile which should not be displayed
312 * in menus or saved to disk.
314 * This is used for the fallback profile, in case there are no profiles on
315 * disk which can be loaded, or for overlay profiles created to handle
316 * command-line arguments which change profile properties.
318 bool isHidden() const;
320 /** Specifies whether this is a hidden profile. See isHidden() */
321 void setHidden(bool hidden
);
324 // Convenience methods for property() and setProperty() go here
327 /** Convenience method for property<QString>(Profile::Path) */
328 QString
path() const { return property
<QString
>(Profile::Path
); }
330 /** Convenience method for property<QString>(Profile::Name) */
331 QString
name() const { return property
<QString
>(Profile::Name
); }
333 /** Convenience method for property<QString>(Profile::Directory) */
334 QString
defaultWorkingDirectory() const
335 { return property
<QString
>(Profile::Directory
); }
337 /** Convenience method for property<QString>(Profile::Icon) */
338 QString
icon() const { return property
<QString
>(Profile::Icon
); }
340 /** Convenience method for property<QString>(Profile::Command) */
341 QString
command() const { return property
<QString
>(Profile::Command
); }
343 /** Convenience method for property<QStringList>(Profile::Arguments) */
344 QStringList
arguments() const { return property
<QStringList
>(Profile::Arguments
); }
346 /** Convenience method for property<QFont>(Profile::Font) */
347 QFont
font() const { return property
<QFont
>(Profile::Font
); }
349 /** Convenience method for property<QString>(Profile::ColorScheme) */
350 QString
colorScheme() const { return property
<QString
>(Profile::ColorScheme
); }
352 /** Convenience method for property<QStringList>(Profile::Environment) */
353 QStringList
environment() const { return property
<QStringList
>(Profile::Environment
); }
356 * Returns true if @p name has been associated with an element
357 * from the Property enum or false otherwise.
359 static bool isNameRegistered(const QString
& name
);
362 * Returns the element from the Property enum associated with the
365 * @param The name of the property to look for, this is case insensitive.
367 static Property
lookupByName(const QString
& name
);
369 * Returns the string names associated with the specified @p property from
370 * the Property enum, in the order the associations were created using
373 static QList
<QString
> namesForProperty(Property property
);
376 * Returns the primary name for the specified @p property.
377 * TODO More documentation
379 static QString
primaryNameForProperty(Property property
);
383 // Defines a new property, this property is then available
384 // to all Profile instances.
385 static void registerProperty(const PropertyInfo
& info
);
387 // fills the table with default names for profile properties
388 // the first time it is called.
389 // subsequent calls return immediately
390 static void fillTableWithDefaultNames();
392 // returns true if the property can be inherited
393 static bool canInheritProperty(Property property
);
395 QHash
<Property
,QVariant
> _propertyValues
;
400 static QHash
<QString
,PropertyInfo
> _propertyInfoByName
;
401 static QHash
<Property
,PropertyInfo
> _infoByProperty
;
403 // Describes a property. Each property has a name and group
404 // which is used when saving/loading the profile.
412 static const PropertyInfo DefaultPropertyNames
[];
416 inline T
Profile::property(Property theProperty
) const
418 return property
<QVariant
>(theProperty
).value
<T
>();
421 inline QVariant
Profile::property(Property property
) const
423 if ( _propertyValues
.contains(property
) ) {
424 return _propertyValues
[property
];
426 else if ( _parent
&& canInheritProperty(property
) ) {
427 return _parent
->property
<QVariant
>(property
);
433 inline bool Profile::canInheritProperty(Property property
)
434 { return property
!= Name
&& property
!= Path
; }
438 * A profile which contains a number of default settings for various properties.
439 * This can be used as a parent for other profiles or a fallback in case
440 * a profile cannot be loaded from disk.
442 class FallbackProfile
: public Profile
449 * A composite profile which allows a group of profiles to be treated as one.
450 * When setting a property, the new value is applied to all profiles in the group.
451 * When reading a property, if all profiles in the group have the same value
452 * then that value is returned, otherwise the result is null.
454 * Profiles can be added to the group using addProfile(). When all profiles
455 * have been added updateValues() must be called
456 * to sync the group's property values with those of the group's profiles.
458 * The Profile::Name and Profile::Path properties are unique to individual profiles,
459 * setting these properties on a ProfileGroup has no effect.
461 class KDE_EXPORT ProfileGroup
: public Profile
464 typedef KSharedPtr
<ProfileGroup
> Ptr
;
466 /** Construct a new profile group, which is hidden by default. */
467 ProfileGroup(Profile::Ptr parent
= Profile::Ptr());
469 /** Add a profile to the group. Calling setProperty() will update this profile.
470 * When creating a group, add the profiles to the group then call updateValues() to
471 * make the group's property values reflect the profiles currently in the group. */
472 void addProfile(Profile::Ptr profile
)
473 { _profiles
.append(profile
); }
475 /** Remove a profile from the group. Calling setProperty() will no longer
476 * affect this profile. */
477 void removeProfile(Profile::Ptr profile
)
478 { _profiles
.removeAll(profile
); }
480 /** Returns the profiles in this group .*/
481 QList
<Profile::Ptr
> profiles() const
482 { return _profiles
; }
485 * Updates the property values in this ProfileGroup to match those from
486 * the group's profiles()
488 * For each available property, if each profile in the group has the same value then
489 * the ProfileGroup will use that value for the property. Otherwise the value for the property
490 * will be set to a null QVariant
492 * Some properties such as the name and the path of the profile
493 * will always be set to null if the group has more than one profile.
497 /** Sets the value of @p property in each of the group's profiles to @p value. */
498 void setProperty(Property property
, const QVariant
& value
);
501 QList
<Profile::Ptr
> _profiles
;
503 inline ProfileGroup::ProfileGroup(Profile::Ptr parent
)
508 inline const Profile::GroupPtr
Profile::asGroup() const
510 const Profile::GroupPtr
ptr(dynamic_cast<ProfileGroup
*>(
511 const_cast<Profile
*>(this)));
514 inline Profile::GroupPtr
Profile::asGroup()
516 return Profile::GroupPtr(dynamic_cast<ProfileGroup
*>(this));
519 /** Interface for all classes which can load profile settings from a file. */
523 virtual ~ProfileReader() {}
524 /** Returns a list of paths to profiles which this reader can read. */
525 virtual QStringList
findProfiles() { return QStringList(); }
527 * Attempts to read a profile from @p path and
528 * save the property values described into @p profile.
530 * Returns true if the profile was successfully read or false otherwise.
532 * @param path Path to the profile to read
533 * @param profile Pointer to the Profile the settings will be read into
534 * @param parentProfile Receives the name of the parent profile specified in
536 virtual bool readProfile(const QString
& path
, Profile::Ptr profile
, QString
& parentProfile
) = 0;
538 /** Reads a KDE 3 profile .desktop file. */
539 class KDE3ProfileReader
: public ProfileReader
542 virtual QStringList
findProfiles();
543 virtual bool readProfile(const QString
& path
, Profile::Ptr profile
, QString
& parentProfile
);
545 /** Reads a KDE 4 .profile file. */
546 class KDE4ProfileReader
: public ProfileReader
549 virtual QStringList
findProfiles();
550 virtual bool readProfile(const QString
& path
, Profile::Ptr profile
, QString
& parentProfile
);
552 void readProperties(const KConfig
& config
, Profile::Ptr profile
,
553 const Profile::PropertyInfo
* properties
);
555 /** Interface for all classes which can write profile settings to a file. */
559 virtual ~ProfileWriter() {}
561 * Returns a suitable path-name for writing
562 * @p profile to. The path-name should be accepted by
563 * the corresponding ProfileReader class.
565 virtual QString
getPath(const Profile::Ptr profile
) = 0;
567 * Writes the properties and values from @p profile to the file specified by
568 * @p path. This profile should be readable by the corresponding ProfileReader class.
570 virtual bool writeProfile(const QString
& path
, const Profile::Ptr profile
) = 0;
572 /** Writes a KDE 4 .profile file. */
573 class KDE4ProfileWriter
: public ProfileWriter
576 virtual QString
getPath(const Profile::Ptr profile
);
577 virtual bool writeProfile(const QString
& path
, const Profile::Ptr profile
);
580 void writeProperties(KConfig
& config
, const Profile::Ptr profile
,
581 const Profile::PropertyInfo
* properties
);
585 * Parses an input string consisting of property names
586 * and assigned values and returns a table of properties
589 * The input string will typically look like this:
592 * PropertyName=Value;PropertyName=Value ...
598 * Icon=konsole;Directory=/home/bob
601 class ProfileCommandParser
605 * Parses an input string consisting of property names
606 * and assigned values and returns a table of
607 * properties and values.
609 QHash
<Profile::Property
,QVariant
> parse(const QString
& input
);
614 Q_DECLARE_METATYPE(Konsole::Profile::Ptr
)