Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konsole / src / Profile.h
blobae7da8e3a8b68a7b02456b741896ac956b99532f
1 /*
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
19 02110-1301 USA.
22 #ifndef PROFILE_H
23 #define PROFILE_H
25 // Qt
26 #include <QtCore/QHash>
27 #include <QtCore/QObject>
28 #include <QtCore/QPointer>
29 #include <QtCore/QStringList>
30 #include <QtCore/QVariant>
32 #include <QtGui/QFont>
34 // KDE
35 #include <KSharedPtr>
36 #include <KDebug>
37 #include <kdemacros.h>
39 class KConfig;
40 class KConfigGroup;
42 namespace Konsole
44 class ProfileGroup;
46 /**
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;
71 public:
72 typedef KSharedPtr<Profile> Ptr;
73 typedef KSharedPtr<ProfileGroup> GroupPtr;
75 /**
76 * This enum describes the available properties
77 * which a Profile may consist of.
79 * Properties can be set using setProperty() and read
80 * using property()
82 enum Property
84 /** (QString) Path to the profile's configuration file on-disk. */
85 Path,
86 /** (QString) The descriptive name of this profile. */
87 Name,
88 /** (QString) Title of this profile that will be displayed. */
89 Title,
90 /** (QString) The name of the icon associated with this profile. This
91 * is used in menus and tabs to represent the profile.
93 Icon,
94 /** (QString) The command to execute ( excluding arguments ) when creating a new terminal
95 * session using this profile.
97 Command,
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.
101 Arguments,
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.
106 Environment,
107 /** (QString) The initial working directory for sessions created using this profile. */
108 Directory,
109 /** (QString) The format used for tab titles when running normal commands. */
110 LocalTabTitleFormat,
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. */
115 ShowMenuBar,
116 /** (TabBarModeEnum) Specifies when the tab bar should be shown in
117 * the main application window. */
118 TabBarMode,
119 /** (QFont) The font to use in terminal displays using this profile. */
120 Font,
121 /** (QString)
122 * The name of the color scheme to use in terminal displays using this profile.
123 * Color schemes are managed by the ColorSchemeManager class.
125 ColorScheme,
126 /** (QString) The name of the key bindings.
127 * Key bindings are managed by the KeyboardTranslatorManager class.
129 KeyBindings,
130 /** (HistoryModeEnum) Specifies the storage type used for keeping the output produced
131 * by terminal sessions using this profile.
133 HistoryMode,
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
138 HistorySize,
139 /** (ScrollBarPositionEnum) Specifies the position of the scroll bar in
140 * terminal displays using this profile.
142 ScrollBarPosition,
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. */
146 BlinkingTextEnabled,
147 /** (bool) Specifies whether the flow control keys ( typically Ctrl+S , Ctrl+Q )
148 * have any effect. Also known as Xon/Xoff
150 FlowControlEnabled,
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. */
165 CursorShape,
166 /** (QColor) The color used by terminal displays to draw the cursor. Only applicable
167 * if the UseCustomCursorColor property is true. */
168 CustomCursorColor,
169 /** (QString) A string consisting of the characters used to delimit words when
170 * selecting text in the terminal display.
172 WordCharacters,
173 /** (TabBarPositionEnum) Position of the tab-bar relative to the terminal displays. */
174 TabBarPosition,
175 /** (String) Default text codec */
176 DefaultEncoding,
177 /** (bool) Whether fonts should be aliased or not */
178 AntiAliasFonts,
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
186 /**
187 * This enum describes the available modes for showing or hiding the tab bar.
189 enum TabBarModeEnum
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. */
196 AlwaysShowTabBar = 2
199 /**
200 * This enum describes the available tab bar positions.
202 enum TabBarPositionEnum
204 /** Show tab bar below displays. */
205 TabBarBottom = 0,
206 /** Show tab bar above displays. */
207 TabBarTop = 1
210 /**
211 * This enum describes the modes available to remember lines of output produced
212 * by the terminal.
214 enum HistoryModeEnum
216 /** No output is remembered. As soon as lines of text are scrolled off-screen they are lost. */
217 DisableHistory = 0,
218 /** A fixed number of lines of output are remembered. Once the limit is reached, the oldest
219 * lines are lost. */
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.
225 UnlimitedHistory = 2
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. */
234 ScrollBarLeft = 0,
235 /** Show the scroll-bar on the right of the terminal display. */
236 ScrollBarRight = 1,
237 /** Do not show the scroll-bar. */
238 ScrollBarHidden = 2
241 /** This enum describes the shapes used to draw the cursor in terminal displays. */
242 enum CursorShapeEnum
244 /** Use a solid rectangular block to draw the cursor. */
245 BlockCursor = 0,
246 /** Use an 'I' shape, similar to that used in text editing applications, to draw the cursor. */
247 IBeamCursor = 1,
248 /** Draw a line underneath the cursor's position. */
249 UnderlineCursor = 2
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());
260 virtual ~Profile();
263 * Copies all properties except Name and Path from the specified @p profile
264 * into this 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);
273 /**
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;
285 GroupPtr asGroup();
287 /**
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.
296 template <class T>
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;
310 /**
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);
361 /**
362 * Returns the element from the Property enum associated with the
363 * specified @p name.
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
371 * registerName()
373 static QList<QString> namesForProperty(Property property);
375 /**
376 * Returns the primary name for the specified @p property.
377 * TODO More documentation
379 static QString primaryNameForProperty(Property property);
381 private:
382 struct PropertyInfo;
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;
396 Ptr _parent;
398 bool _hidden;
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.
405 struct PropertyInfo
407 Property property;
408 const char* name;
409 const char* group;
410 QVariant::Type type;
412 static const PropertyInfo DefaultPropertyNames[];
415 template <class T>
416 inline T Profile::property(Property theProperty) const
418 return property<QVariant>(theProperty).value<T>();
420 template <>
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);
429 else {
430 return QVariant();
433 inline bool Profile::canInheritProperty(Property property)
434 { return property != Name && property != Path; }
437 /**
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
444 public:
445 FallbackProfile();
448 /**
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
463 public:
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; }
484 /**
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.
495 void updateValues();
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);
500 private:
501 QList<Profile::Ptr> _profiles;
503 inline ProfileGroup::ProfileGroup(Profile::Ptr parent)
504 : Profile(parent)
506 setHidden(true);
508 inline const Profile::GroupPtr Profile::asGroup() const
510 const Profile::GroupPtr ptr(dynamic_cast<ProfileGroup*>(
511 const_cast<Profile*>(this)));
512 return ptr;
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. */
520 class ProfileReader
522 public:
523 virtual ~ProfileReader() {}
524 /** Returns a list of paths to profiles which this reader can read. */
525 virtual QStringList findProfiles() { return QStringList(); }
526 /**
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
541 public:
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
548 public:
549 virtual QStringList findProfiles();
550 virtual bool readProfile(const QString& path , Profile::Ptr profile, QString& parentProfile);
551 private:
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. */
556 class ProfileWriter
558 public:
559 virtual ~ProfileWriter() {}
560 /**
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
575 public:
576 virtual QString getPath(const Profile::Ptr profile);
577 virtual bool writeProfile(const QString& path , const Profile::Ptr profile);
579 private:
580 void writeProperties(KConfig& config, const Profile::Ptr profile,
581 const Profile::PropertyInfo* properties);
584 /**
585 * Parses an input string consisting of property names
586 * and assigned values and returns a table of properties
587 * and values.
589 * The input string will typically look like this:
591 * @code
592 * PropertyName=Value;PropertyName=Value ...
593 * @endcode
595 * For example:
597 * @code
598 * Icon=konsole;Directory=/home/bob
599 * @endcode
601 class ProfileCommandParser
603 public:
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)
616 #endif // PROFILE_H