1 /*
2     SPDX-FileCopyrightText: 2008 Andreas Pakulat <apaku@gmx.de>
3     SPDX-FileCopyrightText: 2013 Milian Wolff <mail@milianw.de>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef KDEVPLATFORM_SESSIONCONTROLLER_H
9 #define KDEVPLATFORM_SESSIONCONTROLLER_H
10 
11 #include "shellexport.h"
12 
13 #include "session.h"
14 #include <interfaces/isessionlock.h>
15 
16 #include <QObject>
17 
18 #include <KXMLGUIClient>
19 
20 namespace KDevelop
21 {
22 
23 class SessionControllerPrivate;
24 
25 struct SessionRunInfo
26 {
SessionRunInfoSessionRunInfo27     SessionRunInfo()
28     {}
29     bool operator==(const SessionRunInfo& o) const
30     {
31         return isRunning == o.isRunning && holderPid == o.holderPid
32                 && holderApp == o.holderApp && holderHostname == o.holderHostname;
33     }
34     bool operator!=(const SessionRunInfo& o) const
35     {
36         return !(operator==(o));
37     }
38     // if this is true, this session is currently running in an external process
39     bool isRunning = false;
40     // if the session is running, this contains the PID of its process
41     qint64 holderPid = -1;
42     // if the session is running, this contains the name of its process
43     QString holderApp;
44     // if the session is running, this contains the host name where the process runs
45     QString holderHostname;
46 };
47 
48 struct TryLockSessionResult
49 {
TryLockSessionResultTryLockSessionResult50     explicit TryLockSessionResult(const ISessionLock::Ptr& _lock)
51     : lock(_lock)
52     {}
TryLockSessionResultTryLockSessionResult53     explicit TryLockSessionResult(const SessionRunInfo& _runInfo)
54     : runInfo(_runInfo)
55     {}
56     // if this is non-null then the session was locked
57     ISessionLock::Ptr lock;
58     // otherwise this contains information about who is locking the session
59     SessionRunInfo runInfo;
60 };
61 
62 class KDEVPLATFORMSHELL_EXPORT SessionController : public QObject, public KXMLGUIClient
63 {
64     Q_OBJECT
65     Q_CLASSINFO("D-Bus Interface", "org.kdevelop.SessionController")
66 
67 public:
68     explicit SessionController( QObject *parent = nullptr );
69     ~SessionController() override;
70     void initialize( const QString& session );
71     void cleanup();
72 
73     /// Returns whether the given session can be locked (i. e., is not locked currently).
74     /// @param doLocking whether to really lock the session or just "dry-run" the locking process
75     static TryLockSessionResult tryLockSession(const QString& id, bool doLocking=true);
76 
77     /**
78      * @return true when the given session is currently running, false otherwise
79      */
80     static bool isSessionRunning(const QString& id);
81 
82     /**
83      * @return information about whether the session @p id is running
84      */
85     static SessionRunInfo sessionRunInfo(const QString& id);
86 
87     /// The application should call this on startup to tell the
88     /// session-controller about the received arguments.
89     /// Some of them may need to be passed to newly opened sessions.
90     static void setArguments(int argc, char** argv);
91 
92     ///Finds a session by its name or by its UUID
93     Session* session( const QString& nameOrId ) const;
94     virtual ISession* activeSession() const;
95     ISessionLock::Ptr activeSessionLock() const;
96     QList<QString> sessionNames() const;
97     Session* createSession( const QString& name );
98 
99     QList<const Session*> sessions() const;
100 
101     void loadDefaultSession( const QString& session );
102 
103     void startNewSession();
104 
105     void loadSession( const QString& nameOrId );
106     void deleteSession( const ISessionLock::Ptr& lock );
107     static void deleteSessionFromDisk( const ISessionLock::Ptr& lock );
108     QString cloneSession( const QString& nameOrid );
109     /**
110      * Path to session directory for the session with the given @p sessionId.
111      */
112     static QString sessionDirectory( const QString& sessionId );
113     static QString cfgSessionGroup();
114     static QString cfgActiveSessionEntry();
115 
116     static SessionInfos availableSessionInfos();
117 
118     /**
119      * Shows a dialog where the user can choose the session
120      * @param headerText an additional text that will be shown at the top in a label
121      * @param onlyRunning whether only currently running sessions should be shown
122      * @return UUID on success, empty string in any other case
123      */
124     static QString showSessionChooserDialog(const QString& headerText = QString(), bool onlyRunning = false);
125 
126     /// Should be called if session to be opened is locked.
127     /// It attempts to bring existing instance's window up via a DBus call; if that succeeds, empty string is returned.
128     /// Otherwise (if the app did not respond) it shows a dialog where the user may choose
129     /// 1) to force-remove the lockfile and continue,
130     /// 2) to select another session via @ref showSessionChooserDialog,
131     /// 3) to quit the current (starting-up) instance.
132     /// @param sessionName session name (for the message)
133     /// @param currentSessionId current session GUID (to return if user chooses force-removal)
134     /// @param runInfo the run information about the session
135     /// @return new session GUID to try or an empty string if application startup shall be aborted
136     static QString handleLockedSession( const QString& sessionName, const QString& currentSessionId, const SessionRunInfo& runInfo );
137 
138     void updateXmlGuiActionList();
139 
emitQuitSession()140     void emitQuitSession()
141     {
142         emit quitSession();
143     }
144 
145 public Q_SLOTS:
146     // Returns the pretty name of the currently active session (used in the shell integration)
147     virtual Q_SCRIPTABLE QString sessionName();
148     // Returns the directory associated to the active session (used in the shell integration)
149     virtual Q_SCRIPTABLE QString sessionDir();
150 
151 Q_SIGNALS:
152     void sessionLoaded( ISession* );
153     void sessionDeleted( const QString& id);
154     void quitSession();
155 
156 private:
157     const QScopedPointer<class SessionControllerPrivate> d_ptr;
158     Q_DECLARE_PRIVATE(SessionController)
159 };
160 
161 
162 }
163 #endif
164 
165