File indexing completed on 2018-12-13 10:55:37

0001 /*
0002     Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
0003     Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
0004 
0005     This program is free software; you can redistribute it and/or modify
0006     it under the terms of the GNU General Public License as published by
0007     the Free Software Foundation; either version 2 of the License, or
0008     (at your option) any later version.
0009 
0010     This program is distributed in the hope that it will be useful,
0011     but WITHOUT ANY WARRANTY; without even the implied warranty of
0012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013     GNU General Public License for more details.
0014 
0015     You should have received a copy of the GNU General Public License
0016     along with this program; if not, write to the Free Software
0017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0018     02110-1301  USA.
0019 */
0020 
0021 #ifndef SESSIONCONTROLLER_H
0022 #define SESSIONCONTROLLER_H
0023 
0024 // Qt
0025 #include <QList>
0026 #include <QSet>
0027 #include <QPointer>
0028 #include <QString>
0029 #include <QHash>
0030 #include <QRegularExpression>
0031 
0032 // KDE
0033 #include <KXMLGUIClient>
0034 
0035 // Konsole
0036 #include "ViewProperties.h"
0037 #include "Profile.h"
0038 #include "Enumeration.h"
0039 
0040 namespace KIO {
0041 class Job;
0042 }
0043 
0044 class QAction;
0045 class QTextCodec;
0046 class QKeyEvent;
0047 class QTimer;
0048 class QUrl;
0049 
0050 class KCodecAction;
0051 class KJob;
0052 class QAction;
0053 class KActionMenu;
0054 
0055 namespace Konsole {
0056 class Session;
0057 class SessionGroup;
0058 class ScreenWindow;
0059 class TerminalDisplay;
0060 class IncrementalSearchBar;
0061 class ProfileList;
0062 class RegExpFilter;
0063 class UrlFilter;
0064 class FileFilter;
0065 class EditProfileDialog;
0066 
0067 using SessionPtr = QPointer<Session>;
0068 
0069 /**
0070  * Provides the menu actions to manipulate a single terminal session and view pair.
0071  * The actions provided by this class are defined in the sessionui.rc XML file.
0072  *
0073  * SessionController monitors the session and provides access to basic information
0074  * about the session such as title(), icon() and currentDir().  SessionController
0075  * provides notifications of activity in the session via the activity() signal.
0076  *
0077  * When the controlled view receives the focus, the focused() signal is emitted
0078  * with a pointer to the controller.  This can be used by main application window
0079  * which contains the view to plug the controller's actions into the menu when
0080  * the view is focused.
0081  */
0082 class KONSOLEPRIVATE_EXPORT SessionController : public ViewProperties, public KXMLGUIClient
0083 {
0084     Q_OBJECT
0085 
0086 public:
0087     enum CopyInputToEnum {
0088         /** Copy keyboard input to all the other tabs in current window */
0089         CopyInputToAllTabsMode = 0,
0090 
0091         /** Copy keyboard input to user selected tabs in current window */
0092         CopyInputToSelectedTabsMode = 1,
0093 
0094         /** Do not copy keyboard input to other tabs */
0095         CopyInputToNoneMode = 2
0096     };
0097 
0098     /**
0099      * Constructs a new SessionController which operates on @p session and @p view.
0100      */
0101     SessionController(Session *session, TerminalDisplay *view, QObject *parent);
0102     ~SessionController() Q_DECL_OVERRIDE;
0103 
0104     /** Returns the session associated with this controller */
0105     QPointer<Session> session()
0106     {
0107         return _session;
0108     }
0109 
0110     /** Returns the view associated with this controller */
0111     QPointer<TerminalDisplay> view()
0112     {
0113         return _view;
0114     }
0115 
0116     /**
0117      * Returns the "window title" of the associated session.
0118      */
0119     QString userTitle() const;
0120 
0121     /**
0122      * Returns true if the controller is valid.
0123      * A valid controller is one which has a non-null session() and view().
0124      *
0125      * Equivalent to "!session().isNull() && !view().isNull()"
0126      */
0127     bool isValid() const;
0128 
0129     /** Set the start line from which the next search will be done **/
0130     void setSearchStartTo(int line);
0131 
0132     /** set start line to the first or last line (depending on the reverse search
0133      * setting) in the terminal display **/
0134     void setSearchStartToWindowCurrentLine();
0135 
0136     /**
0137      * Sets the action displayed in the session's context menu to hide or
0138      * show the menu bar.
0139      */
0140     void setShowMenuAction(QAction *action);
0141 
0142     EditProfileDialog *profileDialogPointer();
0143 
0144     // reimplemented
0145     QUrl url() const Q_DECL_OVERRIDE;
0146     QString currentDir() const Q_DECL_OVERRIDE;
0147     void rename() Q_DECL_OVERRIDE;
0148     bool confirmClose() const Q_DECL_OVERRIDE;
0149     virtual bool confirmForceClose() const;
0150 
0151     // Reimplemented to watch for events happening to the view
0152     bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE;
0153 
0154     /** Returns the set of all controllers that exist. */
0155     static QSet<SessionController *> allControllers()
0156     {
0157         return _allControllers;
0158     }
0159 
0160     /* Returns true if called within a KPart; false if called within Konsole. */
0161     bool isKonsolePart() const;
0162     bool isReadOnly() const;
0163 
0164 Q_SIGNALS:
0165     /**
0166      * Emitted when the view associated with the controller is focused.
0167      * This can be used by other classes to plug the controller's actions into a window's
0168      * menus.
0169      */
0170     void focused(SessionController *controller);
0171 
0172     void rawTitleChanged();
0173 
0174     /**
0175      * Emitted when the current working directory of the session associated with
0176      * the controller is changed.
0177      */
0178     void currentDirectoryChanged(const QString &dir);
0179 
0180     /**
0181      * Emitted when the user changes the tab title.
0182      */
0183     void tabRenamedByUser(bool renamed) const;
0184 
0185 public Q_SLOTS:
0186     /**
0187      * Issues a command to the session to navigate to the specified URL.
0188      * This may not succeed if the foreground program does not understand
0189      * the command sent to it ( 'cd path' for local URLs ) or is not
0190      * responding to input.
0191      *
0192      * openUrl() currently supports urls for local paths and those
0193      * using the 'ssh' protocol ( eg. "ssh://joebloggs@hostname" )
0194      */
0195     void openUrl(const QUrl &url);
0196 
0197     /**
0198      * update actions which are meaningful only when primary screen is in use.
0199      */
0200     void setupPrimaryScreenSpecificActions(bool use);
0201 
0202     /**
0203      * update actions which are closely related with the selected text.
0204      */
0205     void selectionChanged(const QString &selectedText);
0206 
0207     /**
0208      * close the associated session. This might involve user interaction for
0209      * confirmation.
0210      */
0211     void closeSession();
0212 
0213     /**  Increase font size */
0214     void increaseFontSize();
0215 
0216     /**  Decrease font size */
0217     void decreaseFontSize();
0218 
0219     /** Reset font size */
0220     void resetFontSize();
0221 
0222     /** Close the incremental search */
0223     void searchClosed(); // called when the user clicks on the
0224 
0225 private Q_SLOTS:
0226     // menu item handlers
0227     void openBrowser();
0228     void copy();
0229     void paste();
0230     void selectAll();
0231     void selectLine();
0232     void pasteFromX11Selection(); // shortcut only
0233     void copyInputActionsTriggered(QAction *action);
0234     void copyInputToAllTabs();
0235     void copyInputToSelectedTabs();
0236     void copyInputToNone();
0237     void editCurrentProfile();
0238     void changeCodec(QTextCodec *codec);
0239     void enableSearchBar(bool showSearchBar);
0240     void searchHistory(bool showSearchBar);
0241     void searchBarEvent();
0242     void searchFrom();
0243     void findNextInHistory();
0244     void findPreviousInHistory();
0245     void changeSearchMatch();
0246     void print_screen();
0247     void saveHistory();
0248     void showHistoryOptions();
0249     void clearHistory();
0250     void clearHistoryAndReset();
0251     void monitorActivity(bool monitor);
0252     void monitorSilence(bool monitor);
0253     void renameSession();
0254     void switchProfile(Profile::Ptr profile);
0255     void handleWebShortcutAction();
0256     void configureWebShortcuts();
0257     void sendSignal(QAction *action);
0258     void sendBackgroundColor();
0259     void toggleReadOnly();
0260 
0261     // other
0262     void setupSearchBar();
0263     void prepareSwitchProfileMenu();
0264     void updateCodecAction();
0265     void showDisplayContextMenu(const QPoint &position);
0266     void movementKeyFromSearchBarReceived(QKeyEvent *event);
0267     void sessionStateChanged(int state);
0268     void sessionAttributeChanged();
0269     void sessionReadOnlyChanged();
0270     void searchTextChanged(const QString &text);
0271     void searchCompleted(bool success);
0272 
0273     void updateFilterList(Profile::Ptr profile); // Called when the profile has changed, so we might need to change the list of filters
0274 
0275     void interactionHandler();
0276     void snapshot(); // called periodically as the user types
0277     // to take a snapshot of the state of the
0278     // foreground process in the terminal
0279 
0280     void highlightMatches(bool highlight);
0281     void scrollBackOptionsChanged(int mode, int lines);
0282     void sessionResizeRequest(const QSize &size);
0283     void trackOutput(QKeyEvent *event);  // move view to end of current output
0284     // when a key press occurs in the
0285     // display area
0286 
0287     void updateSearchFilter();
0288 
0289     void zmodemDownload();
0290     void zmodemUpload();
0291 
0292     // update actions related with selected text
0293     void updateCopyAction(const QString &selectedText);
0294     void updateWebSearchMenu();
0295 
0296 private:
0297     Q_DISABLE_COPY(SessionController)
0298 
0299     // begins the search
0300     // text - pattern to search for
0301     // direction - value from SearchHistoryTask::SearchDirection enum to specify
0302     //             the search direction
0303     void beginSearch(const QString &text, Enum::SearchDirection direction);
0304     QRegularExpression regexpFromSearchBarOptions() const;
0305     bool reverseSearchChecked() const;
0306     void setupCommonActions();
0307     void setupExtraActions();
0308     void removeSearchFilter(); // remove and delete the current search filter if set
0309     void setFindNextPrevEnabled(bool enabled);
0310     void listenForScreenWindowUpdates();
0311 
0312 private:
0313     void updateSessionIcon();
0314     void updateReadOnlyActionStates();
0315 
0316     QPointer<Session> _session;
0317     QPointer<TerminalDisplay> _view;
0318     SessionGroup *_copyToGroup;
0319 
0320     ProfileList *_profileList;
0321 
0322     QIcon _sessionIcon;
0323     QString _sessionIconName;
0324     int _previousState;
0325 
0326     RegExpFilter *_searchFilter;
0327     UrlFilter *_urlFilter;
0328     FileFilter *_fileFilter;
0329 
0330     QAction *_copyInputToAllTabsAction;
0331 
0332     QAction *_findAction;
0333     QAction *_findNextAction;
0334     QAction *_findPreviousAction;
0335 
0336     QTimer *_interactionTimer;
0337 
0338     int _searchStartLine;
0339     int _prevSearchResultLine;
0340 
0341     KCodecAction *_codecAction;
0342 
0343     KActionMenu *_switchProfileMenu;
0344     KActionMenu *_webSearchMenu;
0345 
0346     bool _listenForScreenWindowUpdates;
0347     bool _preventClose;
0348 
0349     bool _keepIconUntilInteraction;
0350 
0351     QString _selectedText;
0352 
0353     QAction *_showMenuAction;
0354 
0355     static QSet<SessionController *> _allControllers;
0356     static int _lastControllerId;
0357 
0358     QStringList _bookmarkValidProgramsToClear;
0359 
0360     bool _isSearchBarEnabled;
0361     QPointer<EditProfileDialog> _editProfileDialog;
0362 
0363     QString _searchText;
0364     QPointer<IncrementalSearchBar> _searchBar;
0365 };
0366 inline bool SessionController::isValid() const
0367 {
0368     return !_session.isNull() && !_view.isNull();
0369 }
0370 
0371 }
0372 
0373 #endif //SESSIONCONTROLLER_H