VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIGuestControlTreeItem.cpp@ 103551

Last change on this file since 103551 was 98875, checked in by vboxsync, 20 months ago

FE/Qt: bugref:10322: Cleanup for UIGuestProcessControlDialog related to UIMachine global pointer.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1/* $Id: UIGuestControlTreeItem.cpp 98875 2023-03-08 09:40:48Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIGuestSessionTreeItem class implementation.
4 */
5
6/*
7 * Copyright (C) 2016-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* GUI includes: */
29#include "UIConverter.h"
30#include "UIExtraDataManager.h"
31#include "UIGuestControlTreeItem.h"
32#include "UIGuestProcessControlWidget.h"
33#include "UICommon.h"
34
35/* COM includes: */
36#include "CGuest.h"
37#include "CEventSource.h"
38#include "CGuestProcessStateChangedEvent.h"
39#include "CGuestSessionStateChangedEvent.h"
40
41
42/*********************************************************************************************************************************
43* UIGuestControlTreeItem implementation. *
44*********************************************************************************************************************************/
45
46UIGuestControlTreeItem::UIGuestControlTreeItem(QITreeWidget *pTreeWidget, const QStringList &strings /* = QStringList() */)
47 :QITreeWidgetItem(pTreeWidget,strings)
48{
49}
50
51UIGuestControlTreeItem::UIGuestControlTreeItem(UIGuestControlTreeItem *pTreeWidgetItem,
52 const QStringList &strings/* = QStringList() */)
53 :QITreeWidgetItem(pTreeWidgetItem, strings)
54{
55
56}
57
58UIGuestControlTreeItem::~UIGuestControlTreeItem()
59{
60}
61
62void UIGuestControlTreeItem::prepare()
63{
64 prepareListener();
65 prepareConnections();
66 setColumnText();
67}
68
69void UIGuestControlTreeItem::prepareListener(CEventSource comEventSource, QVector<KVBoxEventType>& eventTypes)
70{
71 if (!comEventSource.isOk())
72 return;
73 /* Create event listener instance: */
74 m_pQtListener.createObject();
75 m_pQtListener->init(new UIMainEventListener, this);
76 m_comEventListener = CEventListener(m_pQtListener);
77
78 /* Register event listener for CProgress event source: */
79 comEventSource.RegisterListener(m_comEventListener, eventTypes, FALSE /* active? */);
80
81 /* Register event sources in their listeners as well: */
82 m_pQtListener->getWrapped()->registerSource(comEventSource, m_comEventListener);
83}
84
85void UIGuestControlTreeItem::cleanupListener(CEventSource comEventSource)
86{
87 if (!comEventSource.isOk())
88 return;
89 /* Unregister everything: */
90 m_pQtListener->getWrapped()->unregisterSources();
91
92 /* Make sure VBoxSVC is available: */
93 if (!uiCommon().isVBoxSVCAvailable())
94 return;
95
96 /* Unregister event listener for CProgress event source: */
97 comEventSource.UnregisterListener(m_comEventListener);
98}
99
100
101/*********************************************************************************************************************************
102* UIGuestSessionTreeItem implementation. *
103*********************************************************************************************************************************/
104
105UIGuestSessionTreeItem::UIGuestSessionTreeItem(QITreeWidget *pTreeWidget, CGuestSession& guestSession,
106 const QStringList &strings /* = QStringList() */)
107 :UIGuestControlTreeItem(pTreeWidget, strings)
108 , m_comGuestSession(guestSession)
109{
110 prepare();
111 initProcessSubTree();
112}
113
114UIGuestSessionTreeItem::UIGuestSessionTreeItem(UIGuestControlTreeItem *pTreeWidgetItem, CGuestSession& guestSession,
115 const QStringList &strings /* = QStringList() */)
116 :UIGuestControlTreeItem(pTreeWidgetItem, strings)
117 , m_comGuestSession(guestSession)
118{
119 prepare();
120 initProcessSubTree();
121}
122
123UIGuestSessionTreeItem::~UIGuestSessionTreeItem()
124{
125 cleanupListener();
126}
127
128const CGuestSession& UIGuestSessionTreeItem::guestSession() const
129{
130 return m_comGuestSession;
131}
132
133void UIGuestSessionTreeItem::prepareConnections()
134{
135
136 qRegisterMetaType<CGuestProcess>();
137 qRegisterMetaType<CGuestSessionStateChangedEvent>();
138 connect(m_pQtListener->getWrapped(), &UIMainEventListener::sigGuestSessionStatedChanged,
139 this, &UIGuestSessionTreeItem::sltGuestSessionUpdated);
140 connect(m_pQtListener->getWrapped(), &UIMainEventListener::sigGuestProcessRegistered,
141 this, &UIGuestSessionTreeItem::sltGuestProcessRegistered);
142 connect(m_pQtListener->getWrapped(), &UIMainEventListener::sigGuestProcessUnregistered,
143 this, &UIGuestSessionTreeItem::sltGuestProcessUnregistered);
144}
145
146void UIGuestSessionTreeItem::prepareListener()
147{
148 QVector<KVBoxEventType> eventTypes;
149 eventTypes << KVBoxEventType_OnGuestSessionStateChanged
150 << KVBoxEventType_OnGuestProcessRegistered;
151
152 UIGuestControlTreeItem::prepareListener(m_comGuestSession.GetEventSource(), eventTypes);
153}
154
155void UIGuestSessionTreeItem::cleanupListener()
156{
157 UIGuestControlTreeItem::cleanupListener(m_comGuestSession.GetEventSource());
158}
159
160void UIGuestSessionTreeItem::initProcessSubTree()
161{
162 if (!m_comGuestSession.isOk())
163 return;
164 QVector<CGuestProcess> processes = m_comGuestSession.GetProcesses();
165 for (int i =0; i < processes.size(); ++i)
166 addGuestProcess(processes[i]);
167}
168
169void UIGuestSessionTreeItem::sltGuestSessionUpdated(const CGuestSessionStateChangedEvent& cEvent)
170{
171 if (cEvent.isOk() && m_comGuestSession.isOk() && m_comGuestSession.GetStatus() == KGuestSessionStatus_Error)
172 {
173 CVirtualBoxErrorInfo cErrorInfo = cEvent.GetError();
174 if (cErrorInfo.isOk() && cErrorInfo.GetResultCode() != S_OK)
175 {
176 emit sigGuestSessionErrorText(cErrorInfo.GetText());
177 }
178 }
179 setColumnText();
180 emit sigGuessSessionUpdated();
181}
182
183void UIGuestSessionTreeItem::sltGuestProcessRegistered(CGuestProcess guestProcess)
184{
185 const ULONG waitTimeout = 2000;
186 KProcessWaitResult waitResult = guestProcess.WaitFor(KProcessWaitForFlag_Start, waitTimeout);
187 if (waitResult != KProcessWaitResult_Start)
188 {
189 return ;
190 }
191
192 if (!guestProcess.isOk())
193 return;
194 addGuestProcess(guestProcess);
195}
196
197void UIGuestSessionTreeItem::addGuestProcess(CGuestProcess guestProcess)
198{
199 /* Dont add the tree items for already terminated or currently being terminated
200 guest processes: */
201 KProcessStatus processStatus = guestProcess.GetStatus();
202 if (processStatus != KProcessStatus_Starting &&
203 processStatus != KProcessStatus_Started &&
204 processStatus != KProcessStatus_Paused)
205 return;
206
207 UIGuestProcessTreeItem *newItem = new UIGuestProcessTreeItem(this, guestProcess);
208 connect(newItem, &UIGuestProcessTreeItem::sigGuestProcessErrorText,
209 this, &UIGuestSessionTreeItem::sigGuestSessionErrorText);
210 setExpanded(true);
211}
212
213void UIGuestSessionTreeItem::errorString(QString strError)
214{
215 emit sigGuestSessionErrorText(strError);
216}
217
218KGuestSessionStatus UIGuestSessionTreeItem::status() const
219{
220 if (!m_comGuestSession.isOk())
221 return KGuestSessionStatus_Undefined;
222 return m_comGuestSession.GetStatus();
223}
224
225QString UIGuestSessionTreeItem::propertyString() const
226{
227 QString strProperty;
228 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Session Name")).arg(m_comGuestSession.GetName());
229 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Session Id")).arg(m_comGuestSession.GetId());
230 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Session Status")).arg(gpConverter->toString(m_comGuestSession.GetStatus()));
231 return strProperty;
232}
233
234void UIGuestSessionTreeItem::sltGuestProcessUnregistered(CGuestProcess guestProcess)
235{
236 if (!UIGuestProcessControlWidget::s_fDeleteAfterUnregister)
237 return;
238 for (int i = 0; i < childCount(); ++i)
239 {
240 UIGuestProcessTreeItem* item = dynamic_cast<UIGuestProcessTreeItem*>(child(i));
241 if (item && item->guestProcess() == guestProcess)
242 {
243 delete item;
244 break;
245 }
246 }
247}
248
249void UIGuestSessionTreeItem::setColumnText()
250{
251 if (!m_comGuestSession.isOk())
252 return;
253 setText(0, QString("%1").arg(m_comGuestSession.GetId()));
254 setText(1, QString("%1").arg(m_comGuestSession.GetName()));
255 setText(2, QString("%1").arg(gpConverter->toString(m_comGuestSession.GetStatus())));
256}
257
258
259/*********************************************************************************************************************************
260* UIGuestProcessTreeItem implementation. *
261*********************************************************************************************************************************/
262UIGuestProcessTreeItem::UIGuestProcessTreeItem(QITreeWidget *pTreeWidget, CGuestProcess& guestProcess,
263 const QStringList &strings /* = QStringList() */)
264 :UIGuestControlTreeItem(pTreeWidget, strings)
265 , m_comGuestProcess(guestProcess)
266{
267 prepare();
268}
269
270UIGuestProcessTreeItem::UIGuestProcessTreeItem(UIGuestControlTreeItem *pTreeWidgetItem, CGuestProcess& guestProcess,
271 const QStringList &strings /* = QStringList() */)
272 :UIGuestControlTreeItem(pTreeWidgetItem, strings)
273 , m_comGuestProcess(guestProcess)
274{
275 prepare();
276}
277
278void UIGuestProcessTreeItem::prepareConnections()
279{
280 qRegisterMetaType<CGuestProcessStateChangedEvent>();
281 connect(m_pQtListener->getWrapped(), &UIMainEventListener::sigGuestProcessStateChanged,
282 this, &UIGuestProcessTreeItem::sltGuestProcessUpdated);
283}
284
285UIGuestProcessTreeItem::~UIGuestProcessTreeItem()
286{
287 cleanupListener();
288}
289
290KProcessStatus UIGuestProcessTreeItem::status() const
291{
292 if (!m_comGuestProcess.isOk())
293 return KProcessStatus_Undefined;
294 return m_comGuestProcess.GetStatus();
295}
296
297QString UIGuestProcessTreeItem::propertyString() const
298{
299 QString strProperty;
300 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Process Name")).arg(m_comGuestProcess.GetName());
301 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Process Id")).arg(m_comGuestProcess.GetPID());
302 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Process Status")).arg(gpConverter->toString(m_comGuestProcess.GetStatus()));
303 strProperty += QString("<b>%1: </b>%2<br/>").arg(tr("Executable Path")).arg(m_comGuestProcess.GetExecutablePath());
304
305 strProperty += QString("<b>%1: </b>").arg(tr("Arguments"));
306 QVector<QString> processArguments = m_comGuestProcess.GetArguments();
307 for (int i = 0; i < processArguments.size() - 1; ++i)
308 strProperty += QString("%1, ").arg(processArguments.at(i));
309 if (processArguments.size() > 0)
310 strProperty += QString("%1<br/> ").arg(processArguments.last());
311
312 return strProperty;
313}
314
315void UIGuestProcessTreeItem::prepareListener()
316{
317 QVector<KVBoxEventType> eventTypes;
318 eventTypes << KVBoxEventType_OnGuestProcessStateChanged
319 << KVBoxEventType_OnGuestProcessInputNotify
320 << KVBoxEventType_OnGuestProcessOutput;
321 UIGuestControlTreeItem::prepareListener(m_comGuestProcess.GetEventSource(), eventTypes);
322}
323
324void UIGuestProcessTreeItem::cleanupListener()
325{
326 UIGuestControlTreeItem::cleanupListener(m_comGuestProcess.GetEventSource());
327}
328
329void UIGuestProcessTreeItem::sltGuestProcessUpdated(const CGuestProcessStateChangedEvent &cEvent)
330{
331 if (cEvent.isOk() && m_comGuestProcess.isOk() && m_comGuestProcess.GetStatus() == KProcessStatus_Error)
332 {
333 CVirtualBoxErrorInfo cErrorInfo = cEvent.GetError();
334 if (cErrorInfo.isOk() && cErrorInfo.GetResultCode() != S_OK)
335 emit sigGuestProcessErrorText(cErrorInfo.GetText());
336
337 }
338 setColumnText();
339 KProcessStatus processStatus = m_comGuestProcess.GetStatus();
340 if (processStatus != KProcessStatus_Starting &&
341 processStatus != KProcessStatus_Started &&
342 processStatus != KProcessStatus_Paused)
343 {
344 if (UIGuestProcessControlWidget::s_fDeleteAfterUnregister)
345 this->deleteLater();
346 }
347}
348
349 void UIGuestProcessTreeItem::setColumnText()
350{
351 if (!m_comGuestProcess.isOk())
352 return;
353 setText(0, QString("%1").arg(m_comGuestProcess.GetPID()));
354 setText(1, QString("%1").arg(m_comGuestProcess.GetExecutablePath()));
355 setText(2, QString("%1").arg(gpConverter->toString(m_comGuestProcess.GetStatus())));
356}
357
358const CGuestProcess& UIGuestProcessTreeItem::guestProcess() const
359{
360 return m_comGuestProcess;
361}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette