Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konsole / src / SessionController.h
blobc368aebf1242ed71c86ab7d27df7b4d9c16b353a
1 /*
2 Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
20 #ifndef SESSIONCONTROLLER_H
21 #define SESSIONCONTROLLER_H
23 // Qt
24 #include <QtGui/QIcon>
25 #include <QtCore/QList>
26 #include <QtCore/QPointer>
27 #include <QtCore/QString>
28 #include <QtCore/QThread>
29 #include <QtCore/QHash>
31 // KDE
32 #include <KActionCollection>
33 #include <KIcon>
34 #include <KXMLGUIClient>
36 // Konsole
37 #include "HistorySizeDialog.h"
38 #include "ViewProperties.h"
39 #include "Profile.h"
41 namespace KIO
43 class Job;
46 class QAction;
47 class QTextCodec;
48 class KCodecAction;
49 class KMenu;
50 class KUrl;
51 class KJob;
53 namespace Konsole
56 class Session;
57 class SessionGroup;
58 class ScreenWindow;
59 class TerminalDisplay;
60 class IncrementalSearchBar;
61 class ProfileList;
62 class UrlFilter;
63 class RegExpFilter;
65 // SaveHistoryTask
66 class TerminalCharacterDecoder;
69 typedef QPointer<Session> SessionPtr;
71 /**
72 * Provides the menu actions to manipulate a single terminal session and view pair.
73 * The actions provided by this class are defined in the sessionui.rc XML file.
75 * SessionController monitors the session and provides access to basic information
76 * about the session such as title(), icon() and currentDir(). SessionController
77 * provides notifications of activity in the session via the activity() signal.
79 * When the controlled view receives the focus, the focused() signal is emitted
80 * with a pointer to the controller. This can be used by main application window
81 * which contains the view to plug the controller's actions into the menu when
82 * the view is focused.
84 class SessionController : public ViewProperties , public KXMLGUIClient
86 Q_OBJECT
88 public:
89 /**
90 * Constructs a new SessionController which operates on @p session and @p view.
92 SessionController(Session* session , TerminalDisplay* view, QObject* parent);
93 ~SessionController();
95 /** Returns the session associated with this controller */
96 QPointer<Session> session() { return _session; }
97 /** Returns the view associated with this controller */
98 QPointer<TerminalDisplay> view() { return _view; }
100 /**
101 * Returns true if the controller is valid.
102 * A valid controller is one which has a non-null session() and view().
104 * Equivalent to "!session().isNull() && !view().isNull()"
106 bool isValid() const;
108 /**
109 * Sets the widget used for searches through the session's output.
111 * When the user clicks on the "Search Output" menu action the @p searchBar 's
112 * show() method will be called. The SessionController will then connect to the search
113 * bar's signals to update the search when the widget's controls are pressed.
115 void setSearchBar( IncrementalSearchBar* searchBar );
116 /**
117 * see setSearchBar()
119 IncrementalSearchBar* searchBar() const;
122 * Sets the action displayed in the session's context menu to hide or
123 * show the menu bar.
125 void setShowMenuAction(QAction* action);
127 // reimplemented
128 virtual KUrl url() const;
129 virtual QString currentDir() const;
130 virtual void rename();
131 virtual bool confirmClose() const;
133 // Reimplemented to watch for events happening to the view
134 virtual bool eventFilter(QObject* watched , QEvent* event);
136 /** Returns the set of all controllers that exist. */
137 static QSet<SessionController*> allControllers()
138 { return _allControllers; }
140 signals:
142 * Emitted when the view associated with the controller is focused.
143 * This can be used by other classes to plug the controller's actions into a window's
144 * menus.
146 void focused( SessionController* controller );
148 public slots:
150 * Issues a command to the session to navigate to the specified URL.
151 * This may not succeed if the foreground program does not understand
152 * the command sent to it ( 'cd path' for local URLs ) or is not
153 * responding to input.
155 * openUrl() currently supports urls for local paths and those
156 * using the 'ssh' protocol ( eg. ssh://joebloggs@hostname )
158 void openUrl( const KUrl& url );
160 private slots:
161 // menu item handlers
162 void openBrowser();
163 void copy();
164 void paste();
165 void pasteSelection(); // shortcut only
166 void clear();
167 void clearAndReset();
168 void copyInputTo();
169 void editCurrentProfile();
170 void changeCodec(QTextCodec* codec);
171 void searchHistory(bool showSearchBar);
172 void findNextInHistory();
173 void findPreviousInHistory();
174 void saveHistory();
175 void showHistoryOptions();
176 void clearHistory();
177 void clearHistoryAndReset();
178 void closeSession();
179 void monitorActivity(bool monitor);
180 void monitorSilence(bool monitor);
181 void increaseTextSize();
182 void decreaseTextSize();
183 void renameSession();
184 void saveSession();
185 void changeProfile(Profile::Ptr profile);
187 // other
188 void prepareChangeProfileMenu();
189 void updateCodecAction();
190 void showDisplayContextMenu(const QPoint& position);
191 void sessionStateChanged(int state);
192 void sessionTitleChanged();
193 void searchTextChanged(const QString& text);
194 void searchCompleted(bool success);
195 void searchClosed(); // called when the user clicks on the
196 // history search bar's close button
198 void snapshot(); // called periodically as the user types
199 // to take a snapshot of the state of the
200 // foreground process in the terminal
202 void requireUrlFilterUpdate();
203 void highlightMatches(bool highlight);
204 void scrollBackOptionsChanged(int mode , int lines);
205 void sessionResizeRequest(const QSize& size);
206 void trackOutput(QKeyEvent* event); // move view to end of current output
207 // when a key press occurs in the
208 // display area
210 void updateSearchFilter();
212 private:
213 // begins the search
214 // text - pattern to search for
215 // direction - value from SearchHistoryTask::SearchDirection enum to specify
216 // the search direction
217 void beginSearch(const QString& text , int direction);
218 void setupActions();
219 void removeSearchFilter(); // remove and delete the current search filter if set
220 void setFindNextPrevEnabled(bool enabled);
221 void listenForScreenWindowUpdates();
223 private:
224 QPointer<Session> _session;
225 QPointer<TerminalDisplay> _view;
226 SessionGroup* _copyToGroup;
228 ProfileList* _profileList;
230 KIcon _sessionIcon;
231 QString _sessionIconName;
232 int _previousState;
234 UrlFilter* _viewUrlFilter;
235 RegExpFilter* _searchFilter;
237 KAction* _searchToggleAction;
238 KAction* _findNextAction;
239 KAction* _findPreviousAction;
242 bool _urlFilterUpdateRequired;
244 QPointer<IncrementalSearchBar> _searchBar;
246 KCodecAction* _codecAction;
248 KMenu* _changeProfileMenu;
250 bool _listenForScreenWindowUpdates;
251 bool _preventClose;
253 static QSet<SessionController*> _allControllers;
254 static int _lastControllerId;
255 static KIcon _activityIcon;
256 static KIcon _silenceIcon;
258 inline bool SessionController::isValid() const
260 return !_session.isNull() && !_view.isNull();
263 /**
264 * Abstract class representing a task which can be performed on a group of sessions.
266 * Create a new instance of the appropriate sub-class for the task you want to perform and
267 * call the addSession() method to add each session which needs to be processed.
269 * Finally, call the execute() method to perform the sub-class specific action on each
270 * of the sessions.
272 class SessionTask : public QObject
274 Q_OBJECT
276 public:
277 SessionTask(QObject* parent = 0);
279 /**
280 * Sets whether the task automatically deletes itself when the task has been finished.
281 * Depending on whether the task operates synchronously or asynchronously, the deletion
282 * may be scheduled immediately after execute() returns or it may happen some time later.
284 void setAutoDelete(bool enable);
285 /** Returns true if the task automatically deletes itself. See setAutoDelete() */
286 bool autoDelete() const;
288 /** Adds a new session to the group */
289 void addSession(Session* session);
291 /**
292 * Executes the task on each of the sessions in the group.
293 * The completed() signal is emitted when the task is finished, depending on the specific sub-class
294 * execute() may be synchronous or asynchronous
296 virtual void execute() = 0;
298 signals:
299 /**
300 * Emitted when the task has completed.
301 * Depending on the task this may occur just before execute() returns, or it
302 * may occur later
304 * @param success Indicates whether the task completed successfully or not
306 void completed(bool success);
308 protected:
310 /** Returns a list of sessions in the group */
311 QList< SessionPtr > sessions() const;
313 private:
315 bool _autoDelete;
316 QList< SessionPtr > _sessions;
320 * A task which prompts for a URL for each session and saves that session's output
321 * to the given URL
323 class SaveHistoryTask : public SessionTask
325 Q_OBJECT
327 public:
328 /** Constructs a new task to save session output to URLs */
329 SaveHistoryTask(QObject* parent = 0);
330 virtual ~SaveHistoryTask();
333 * Opens a save file dialog for each session in the group and begins saving
334 * each session's history to the given URL.
336 * The data transfer is performed asynchronously and will continue after execute() returns.
338 virtual void execute();
340 private slots:
341 void jobDataRequested(KIO::Job* job , QByteArray& data);
342 void jobResult(KJob* job);
344 private:
345 class SaveJob // structure to keep information needed to process
346 // incoming data requests from jobs
348 public:
349 SessionPtr session; // the session associated with a history save job
350 int lastLineFetched; // the last line processed in the previous data request
351 // set this to -1 at the start of the save job
353 TerminalCharacterDecoder* decoder; // decoder used to convert terminal characters
354 // into output
358 QHash<KJob*,SaveJob> _jobSession;
361 class SearchHistoryThread;
363 * A task which searches through the output of sessions for matches for a given regular expression.
364 * SearchHistoryTask operates on ScreenWindow instances rather than sessions added by addSession().
365 * A screen window can be added to the list to search using addScreenWindow()
367 * When execute() is called, the search begins in the direction specified by searchDirection(),
368 * starting at the position of the current selection.
370 * FIXME - This is not a proper implementation of SessionTask, in that it ignores sessions specified
371 * with addSession()
373 * TODO - Implementation requirements:
374 * May provide progress feedback to the user when searching very large output logs.
376 class SearchHistoryTask : public SessionTask
378 Q_OBJECT
380 public:
381 /**
382 * This enum describes the strategies available for searching through the
383 * session's output.
385 enum SearchDirection
387 /** Searches forwards through the output, starting at the current selection. */
388 ForwardsSearch,
389 /** Searches backwars through the output, starting at the current selection. */
390 BackwardsSearch
393 /**
394 * Constructs a new search task.
396 explicit SearchHistoryTask(QObject* parent = 0);
398 /** Adds a screen window to the list to search when execute() is called. */
399 void addScreenWindow( Session* session , ScreenWindow* searchWindow);
401 /** Sets the regular expression which is searched for when execute() is called */
402 void setRegExp(const QRegExp& regExp);
403 /** Returns the regular expression which is searched for when execute() is called */
404 QRegExp regExp() const;
406 /** Specifies the direction to search in when execute() is called. */
407 void setSearchDirection( SearchDirection direction );
408 /** Returns the current search direction. See setSearchDirection(). */
409 SearchDirection searchDirection() const;
411 /**
412 * Performs a search through the session's history, starting at the position
413 * of the current selection, in the direction specified by setSearchDirection().
415 * If it finds a match, the ScreenWindow specified in the constructor is
416 * scrolled to the position where the match occurred and the selection
417 * is set to the matching text. execute() then returns immediately.
419 * To continue the search looking for further matches, call execute() again.
421 virtual void execute();
423 private:
424 typedef QPointer<ScreenWindow> ScreenWindowPtr;
426 void executeOnScreenWindow( SessionPtr session , ScreenWindowPtr window );
427 void highlightResult( ScreenWindowPtr window , int position);
429 QMap< SessionPtr , ScreenWindowPtr > _windows;
430 QRegExp _regExp;
431 SearchDirection _direction;
433 static QPointer<SearchHistoryThread> _thread;
438 #endif //SESSIONCONTROLLER_H
441 Local Variables:
442 mode: c++
443 c-file-style: "stroustrup"
444 indent-tabs-mode: nil
445 tab-width: 4
446 End: