VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMItem.cpp@ 35740

Last change on this file since 35740 was 34065, checked in by vboxsync, 14 years ago

FE/Qt4: use the global file extension lists

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/* $Id: UIVMItem.cpp 34065 2010-11-15 11:34:50Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UIVMItem class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#ifdef VBOX_WITH_PRECOMPILED_HEADERS
21# include "precomp.h"
22#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
23
24/* Local includes */
25#include "UIVMItem.h"
26
27/* Qt includes */
28#include <QFileInfo>
29
30#ifdef Q_WS_MAC
31//# include "VBoxUtils.h"
32# include <ApplicationServices/ApplicationServices.h>
33#endif /* Q_WS_MAC */
34
35#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
36
37// Helpers
38////////////////////////////////////////////////////////////////////////////////
39
40/// @todo Remove. See @c todo in #switchTo() below.
41#if 0
42
43#if defined (Q_WS_WIN32)
44
45struct EnumWindowsProcData
46{
47 ULONG pid;
48 WId wid;
49};
50
51BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
52{
53 EnumWindowsProcData *d = (EnumWindowsProcData *) lParam;
54
55 DWORD pid = 0;
56 GetWindowThreadProcessId(hwnd, &pid);
57
58 if (d->pid == pid)
59 {
60 WINDOWINFO info;
61 if (!GetWindowInfo(hwnd, &info))
62 return TRUE;
63
64#if 0
65 LogFlowFunc(("pid=%d, wid=%08X\n", pid, hwnd));
66 LogFlowFunc((" parent=%08X\n", GetParent(hwnd)));
67 LogFlowFunc((" owner=%08X\n", GetWindow(hwnd, GW_OWNER)));
68 TCHAR buf [256];
69 LogFlowFunc((" rcWindow=%d,%d;%d,%d\n",
70 info.rcWindow.left, info.rcWindow.top,
71 info.rcWindow.right, info.rcWindow.bottom));
72 LogFlowFunc((" dwStyle=%08X\n", info.dwStyle));
73 LogFlowFunc((" dwExStyle=%08X\n", info.dwExStyle));
74 GetClassName(hwnd, buf, 256);
75 LogFlowFunc((" class=%ls\n", buf));
76 GetWindowText(hwnd, buf, 256);
77 LogFlowFunc((" text=%ls\n", buf));
78#endif
79
80 /* we are interested in unowned top-level windows only */
81 if (!(info.dwStyle & (WS_CHILD | WS_POPUP)) &&
82 info.rcWindow.left < info.rcWindow.right &&
83 info.rcWindow.top < info.rcWindow.bottom &&
84 GetParent(hwnd) == NULL &&
85 GetWindow(hwnd, GW_OWNER) == NULL)
86 {
87 d->wid = hwnd;
88 /* if visible, stop the search immediately */
89 if (info.dwStyle & WS_VISIBLE)
90 return FALSE;
91 /* otherwise, give other top-level windows a chance
92 * (the last one wins) */
93 }
94 }
95
96 return TRUE;
97}
98
99#endif
100
101/**
102 * Searches for a main window of the given process.
103 *
104 * @param aPid process ID to search for
105 *
106 * @return window ID on success or <tt>(WId) ~0</tt> otherwise.
107 */
108static WId FindWindowIdFromPid(ULONG aPid)
109{
110#if defined (Q_WS_WIN32)
111
112 EnumWindowsProcData d = { aPid, (WId) ~0 };
113 EnumWindows(EnumWindowsProc, (LPARAM) &d);
114 LogFlowFunc(("SELECTED wid=%08X\n", d.wid));
115 return d.wid;
116
117#elif defined (Q_WS_X11)
118
119 NOREF(aPid);
120 return (WId) ~0;
121
122#elif defined (Q_WS_MAC)
123
124 /** @todo Figure out how to get access to another windows of another process...
125 * Or at least check that it's not a VBoxVRDP process. */
126 NOREF (aPid);
127 return (WId) 0;
128
129#else
130
131 return (WId) ~0;
132
133#endif
134}
135
136#endif
137
138UIVMItem::UIVMItem(const CMachine &aMachine)
139 : m_machine(aMachine)
140{
141 recache();
142}
143
144UIVMItem::~UIVMItem()
145{
146}
147
148// public members
149////////////////////////////////////////////////////////////////////////////////
150
151QString UIVMItem::machineStateName() const
152{
153 return m_fAccessible ? vboxGlobal().toString(m_machineState) :
154 QApplication::translate("UIVMListView", "Inaccessible");
155}
156
157QString UIVMItem::sessionStateName() const
158{
159 return m_fAccessible ? vboxGlobal().toString(m_sessionState) :
160 QApplication::translate("UIVMListView", "Inaccessible");
161}
162
163QString UIVMItem::toolTipText() const
164{
165 QString dateTime = (m_lastStateChange.date() == QDate::currentDate()) ?
166 m_lastStateChange.time().toString(Qt::LocalDate) :
167 m_lastStateChange.toString(Qt::LocalDate);
168
169 QString toolTip;
170
171 if (m_fAccessible)
172 {
173 toolTip = QString("<b>%1</b>").arg(m_strName);
174 if (!m_strSnapshotName.isNull())
175 toolTip += QString(" (%1)").arg(m_strSnapshotName);
176 toolTip = QApplication::translate("UIVMListView",
177 "<nobr>%1<br></nobr>"
178 "<nobr>%2 since %3</nobr><br>"
179 "<nobr>Session %4</nobr>",
180 "VM tooltip (name, last state change, session state)")
181 .arg(toolTip)
182 .arg(vboxGlobal().toString(m_machineState))
183 .arg(dateTime)
184 .arg(vboxGlobal().toString(m_sessionState));
185 }
186 else
187 {
188 toolTip = QApplication::translate("UIVMListView",
189 "<nobr><b>%1</b><br></nobr>"
190 "<nobr>Inaccessible since %2</nobr>",
191 "Inaccessible VM tooltip (name, last state change)")
192 .arg(m_strSettingsFile)
193 .arg(dateTime);
194 }
195
196 return toolTip;
197}
198
199bool UIVMItem::recache()
200{
201 bool needsResort = true;
202
203 m_strId = m_machine.GetId();
204 m_strSettingsFile = m_machine.GetSettingsFilePath();
205
206 m_fAccessible = m_machine.GetAccessible();
207 if (m_fAccessible)
208 {
209 QString name = m_machine.GetName();
210
211 CSnapshot snp = m_machine.GetCurrentSnapshot();
212 m_strSnapshotName = snp.isNull() ? QString::null : snp.GetName();
213 needsResort = name != m_strName;
214 m_strName = name;
215
216 m_machineState = m_machine.GetState();
217 m_lastStateChange.setTime_t(m_machine.GetLastStateChange() / 1000);
218 m_sessionState = m_machine.GetSessionState();
219 m_strOSTypeId = m_machine.GetOSTypeId();
220 m_cSnaphot = m_machine.GetSnapshotCount();
221
222 if ( m_machineState == KMachineState_PoweredOff
223 || m_machineState == KMachineState_Saved
224 || m_machineState == KMachineState_Teleported
225 || m_machineState == KMachineState_Aborted
226 )
227 {
228 m_pid = (ULONG) ~0;
229 /// @todo Remove. See @c todo in #switchTo() below.
230#if 0
231 mWinId = (WId) ~0;
232#endif
233 }
234 else
235 {
236 m_pid = m_machine.GetSessionPid();
237 /// @todo Remove. See @c todo in #switchTo() below.
238#if 0
239 mWinId = FindWindowIdFromPid(m_pid);
240#endif
241 }
242 }
243 else
244 {
245 m_accessError = m_machine.GetAccessError();
246
247 /* this should be in sync with
248 * VBoxProblemReporter::confirm_machineDeletion() */
249 QFileInfo fi(m_strSettingsFile);
250 QString name = VBoxGlobal::hasAllowedExtension(fi.completeSuffix(), VBoxDefs::VBoxFileExts) ?
251 fi.completeBaseName() : fi.fileName();
252 needsResort = name != m_strName;
253 m_strName = name;
254 m_machineState = KMachineState_Null;
255 m_sessionState = KSessionState_Null;
256 m_lastStateChange = QDateTime::currentDateTime();
257 m_strOSTypeId = QString::null;
258 m_cSnaphot = 0;
259
260 m_pid = (ULONG) ~0;
261 /// @todo Remove. See @c todo in #switchTo() below.
262#if 0
263 mWinId = (WId) ~0;
264#endif
265 }
266
267 return needsResort;
268}
269
270/**
271 * Returns @a true if we can activate and bring the VM console window to
272 * foreground, and @a false otherwise.
273 */
274bool UIVMItem::canSwitchTo() const
275{
276 return const_cast <CMachine &>(m_machine).CanShowConsoleWindow();
277
278 /// @todo Remove. See @c todo in #switchTo() below.
279#if 0
280 return mWinId != (WId) ~0;
281#endif
282}
283
284/**
285 * Tries to switch to the main window of the VM process.
286 *
287 * @return true if successfully switched and false otherwise.
288 */
289bool UIVMItem::switchTo()
290{
291#ifdef Q_WS_MAC
292 ULONG64 id = m_machine.ShowConsoleWindow();
293#else
294 WId id = (WId) m_machine.ShowConsoleWindow();
295#endif
296 AssertWrapperOk(m_machine);
297 if (!m_machine.isOk())
298 return false;
299
300 /* winId = 0 it means the console window has already done everything
301 * necessary to implement the "show window" semantics. */
302 if (id == 0)
303 return true;
304
305#if defined (Q_WS_WIN32) || defined (Q_WS_X11)
306
307 return vboxGlobal().activateWindow(id, true);
308
309#elif defined (Q_WS_MAC)
310 /*
311 * This is just for the case were the other process cannot steal
312 * the focus from us. It will send us a PSN so we can try.
313 */
314 ProcessSerialNumber psn;
315 psn.highLongOfPSN = id >> 32;
316 psn.lowLongOfPSN = (UInt32)id;
317 OSErr rc = ::SetFrontProcess(&psn);
318 if (!rc)
319 Log(("GUI: %#RX64 couldn't do SetFrontProcess on itself, the selector (we) had to do it...\n", id));
320 else
321 Log(("GUI: Failed to bring %#RX64 to front. rc=%#x\n", id, rc));
322 return !rc;
323
324#endif
325
326 return false;
327
328 /// @todo Below is the old method of switching to the console window
329 // based on the process ID of the console process. It should go away
330 // after the new (callback-based) method is fully tested.
331#if 0
332
333 if (!canSwitchTo())
334 return false;
335
336#if defined (Q_WS_WIN32)
337
338 HWND hwnd = mWinId;
339
340 /* if there are blockers (modal and modeless dialogs, etc), find the
341 * topmost one */
342 HWND hwndAbove = NULL;
343 do
344 {
345 hwndAbove = GetNextWindow(hwnd, GW_HWNDPREV);
346 HWND hwndOwner;
347 if (hwndAbove != NULL &&
348 ((hwndOwner = GetWindow(hwndAbove, GW_OWNER)) == hwnd ||
349 hwndOwner == hwndAbove))
350 hwnd = hwndAbove;
351 else
352 break;
353 }
354 while (1);
355
356 /* first, check that the primary window is visible */
357 if (IsIconic(mWinId))
358 ShowWindow(mWinId, SW_RESTORE);
359 else if (!IsWindowVisible(mWinId))
360 ShowWindow(mWinId, SW_SHOW);
361
362#if 0
363 LogFlowFunc(("mWinId=%08X hwnd=%08X\n", mWinId, hwnd));
364#endif
365
366 /* then, activate the topmost in the group */
367 AllowSetForegroundWindow(m_pid);
368 SetForegroundWindow(hwnd);
369
370 return true;
371
372#elif defined (Q_WS_X11)
373
374 return false;
375
376#elif defined (Q_WS_MAC)
377
378 ProcessSerialNumber psn;
379 OSStatus rc = ::GetProcessForPID(m_pid, &psn);
380 if (!rc)
381 {
382 rc = ::SetFrontProcess(&psn);
383
384 if (!rc)
385 {
386 ShowHideProcess(&psn, true);
387 return true;
388 }
389 }
390 return false;
391
392#else
393
394 return false;
395
396#endif
397
398#endif
399}
400
401QString UIVMItemMimeData::m_type = "application/org.virtualbox.gui.vmselector.uivmitem";
402
403UIVMItemMimeData::UIVMItemMimeData(UIVMItem *pItem)
404 : m_pItem(pItem)
405{
406}
407
408UIVMItem *UIVMItemMimeData::item() const
409{
410 return m_pItem;
411}
412
413QStringList UIVMItemMimeData::formats() const
414{
415 QStringList types;
416 types << type();
417 return types;
418}
419
420/* static */
421QString UIVMItemMimeData::type()
422{
423 return m_type;
424}
425
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use