VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp@ 104158

Last change on this file since 104158 was 101230, checked in by vboxsync, 17 months ago

FE/Qt: bugref:10513: Update UIEditor with API to register sub-editors; This will be useful to use outside of the editor code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.3 KB
Line 
1/* $Id: UIMachineSettingsSF.cpp 101230 2023-09-21 20:17:24Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineSettingsSF class implementation.
4 */
5
6/*
7 * Copyright (C) 2008-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/* Qt includes: */
29#include <QVBoxLayout>
30
31/* GUI includes: */
32#include "UIErrorString.h"
33#include "UIMachineSettingsSF.h"
34#include "UISharedFoldersEditor.h"
35
36
37/** Machine settings: Shared Folder data structure. */
38struct UIDataSettingsSharedFolder
39{
40 /** Constructs data. */
41 UIDataSettingsSharedFolder() {}
42
43 /** Returns whether the @a other passed data is equal to this one. */
44 bool equal(const UIDataSettingsSharedFolder &other) const
45 {
46 return true
47 && m_guiData == other.m_guiData
48 ;
49 }
50
51 /** Returns whether the @a other passed data is equal to this one. */
52 bool operator==(const UIDataSettingsSharedFolder &other) const { return equal(other); }
53 /** Returns whether the @a other passed data is different from this one. */
54 bool operator!=(const UIDataSettingsSharedFolder &other) const { return !equal(other); }
55
56 /** Holds the shared folder data. */
57 UIDataSharedFolder m_guiData;
58};
59
60
61/** Machine settings: Shared Folders page data structure. */
62struct UIDataSettingsSharedFolders
63{
64 /** Constructs data. */
65 UIDataSettingsSharedFolders() {}
66
67 /** Returns whether the @a other passed data is equal to this one. */
68 bool operator==(const UIDataSettingsSharedFolders & /* other */) const { return true; }
69 /** Returns whether the @a other passed data is different from this one. */
70 bool operator!=(const UIDataSettingsSharedFolders & /* other */) const { return false; }
71};
72
73
74UIMachineSettingsSF::UIMachineSettingsSF()
75 : m_pCache(0)
76 , m_pEditorSharedFolders(0)
77{
78 prepare();
79}
80
81UIMachineSettingsSF::~UIMachineSettingsSF()
82{
83 cleanup();
84}
85
86bool UIMachineSettingsSF::changed() const
87{
88 return m_pCache ? m_pCache->wasChanged() : false;
89}
90
91void UIMachineSettingsSF::loadToCacheFrom(QVariant &data)
92{
93 /* Sanity check: */
94 if (!m_pCache)
95 return;
96
97 /* Fetch data to machine: */
98 UISettingsPageMachine::fetchData(data);
99
100 /* Clear cache initially: */
101 m_pCache->clear();
102
103 /* Prepare old data: */
104 UIDataSettingsSharedFolders oldFoldersData;
105
106 /* Get actual folders: */
107 QMultiMap<UISharedFolderType, CSharedFolder> folders;
108 /* Load machine (permanent) folders if allowed: */
109 if (isSharedFolderTypeSupported(UISharedFolderType_Machine))
110 {
111 foreach (const CSharedFolder &folder, getSharedFolders(UISharedFolderType_Machine))
112 folders.insert(UISharedFolderType_Machine, folder);
113 }
114 /* Load console (temporary) folders if allowed: */
115 if (isSharedFolderTypeSupported(UISharedFolderType_Console))
116 {
117 foreach (const CSharedFolder &folder, getSharedFolders(UISharedFolderType_Console))
118 folders.insert(UISharedFolderType_Console, folder);
119 }
120
121 /* For each folder type: */
122 foreach (const UISharedFolderType &enmFolderType, folders.keys())
123 {
124 /* For each folder of current type: */
125 const QList<CSharedFolder> &currentTypeFolders = folders.values(enmFolderType);
126 for (int iFolderIndex = 0; iFolderIndex < currentTypeFolders.size(); ++iFolderIndex)
127 {
128 /* Prepare old data & cache key: */
129 UIDataSettingsSharedFolder oldFolderData;
130 QString strFolderKey = QString::number(iFolderIndex);
131
132 /* Check whether folder is valid: */
133 const CSharedFolder &comFolder = currentTypeFolders.at(iFolderIndex);
134 if (!comFolder.isNull())
135 {
136 /* Gather old data: */
137 oldFolderData.m_guiData.m_enmType = enmFolderType;
138 oldFolderData.m_guiData.m_strName = comFolder.GetName();
139 oldFolderData.m_guiData.m_strPath = comFolder.GetHostPath();
140 oldFolderData.m_guiData.m_fWritable = comFolder.GetWritable();
141 oldFolderData.m_guiData.m_fAutoMount = comFolder.GetAutoMount();
142 oldFolderData.m_guiData.m_strAutoMountPoint = comFolder.GetAutoMountPoint();
143 /* Override folder cache key: */
144 strFolderKey = oldFolderData.m_guiData.m_strName;
145 }
146
147 /* Cache old data: */
148 m_pCache->child(strFolderKey).cacheInitialData(oldFolderData);
149 }
150 }
151
152 /* Cache old data: */
153 m_pCache->cacheInitialData(oldFoldersData);
154
155 /* Upload machine to data: */
156 UISettingsPageMachine::uploadData(data);
157}
158
159void UIMachineSettingsSF::getFromCache()
160{
161 /* Sanity check: */
162 if ( !m_pCache
163 || !m_pEditorSharedFolders)
164 return;
165
166 /* Load old data from cache: */
167 QList<UIDataSharedFolder> folders;
168 for (int iFolderIndex = 0; iFolderIndex < m_pCache->childCount(); ++iFolderIndex)
169 folders << m_pCache->child(iFolderIndex).base().m_guiData;
170 m_pEditorSharedFolders->setValue(folders);
171
172 /* Polish page finally: */
173 polishPage();
174}
175
176void UIMachineSettingsSF::putToCache()
177{
178 /* Sanity check: */
179 if ( !m_pCache
180 || !m_pEditorSharedFolders)
181 return;
182
183 /* Prepare new data: */
184 UIDataSettingsSharedFolders newFoldersData;
185
186 /* Cache new data: */
187 foreach (const UIDataSharedFolder &guiData, m_pEditorSharedFolders->value())
188 {
189 /* Gather and cache new data: */
190 UIDataSettingsSharedFolder newFolderData;
191 newFolderData.m_guiData = guiData;
192 m_pCache->child(newFolderData.m_guiData.m_strName).cacheCurrentData(newFolderData);
193 }
194 m_pCache->cacheCurrentData(newFoldersData);
195}
196
197void UIMachineSettingsSF::saveFromCacheTo(QVariant &data)
198{
199 /* Fetch data to machine: */
200 UISettingsPageMachine::fetchData(data);
201
202 /* Update data and failing state: */
203 setFailed(!saveData());
204
205 /* Upload machine to data: */
206 UISettingsPageMachine::uploadData(data);
207}
208
209void UIMachineSettingsSF::retranslateUi()
210{
211}
212
213void UIMachineSettingsSF::polishPage()
214{
215 /* Polish availability: */
216 m_pEditorSharedFolders->setFeatureAvailable(isMachineInValidMode());
217 m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Machine, isSharedFolderTypeSupported(UISharedFolderType_Machine));
218 m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Console, isSharedFolderTypeSupported(UISharedFolderType_Console));
219}
220
221void UIMachineSettingsSF::prepare()
222{
223 /* Prepare cache: */
224 m_pCache = new UISettingsCacheSharedFolders;
225 AssertPtrReturnVoid(m_pCache);
226
227 /* Prepare everything: */
228 prepareWidgets();
229 prepareConnections();
230
231 /* Apply language settings: */
232 retranslateUi();
233}
234
235void UIMachineSettingsSF::prepareWidgets()
236{
237 /* Prepare main layout: */
238 QVBoxLayout *pLayout = new QVBoxLayout(this);
239 if (pLayout)
240 {
241 /* Prepare settings editor: */
242 m_pEditorSharedFolders = new UISharedFoldersEditor(this);
243 if (m_pEditorSharedFolders)
244 {
245 addEditor(m_pEditorSharedFolders);
246 pLayout->addWidget(m_pEditorSharedFolders);
247 }
248 }
249}
250
251void UIMachineSettingsSF::prepareConnections()
252{
253}
254
255void UIMachineSettingsSF::cleanup()
256{
257 /* Cleanup cache: */
258 delete m_pCache;
259 m_pCache = 0;
260}
261
262bool UIMachineSettingsSF::isSharedFolderTypeSupported(UISharedFolderType enmSharedFolderType) const
263{
264 switch (enmSharedFolderType)
265 {
266 case UISharedFolderType_Machine: return isMachineInValidMode();
267 case UISharedFolderType_Console: return isMachineOnline();
268 default: return false;
269 }
270}
271
272CSharedFolderVector UIMachineSettingsSF::getSharedFolders(UISharedFolderType enmFoldersType)
273{
274 /* Wrap up the getter below: */
275 CSharedFolderVector folders;
276 getSharedFolders(enmFoldersType, folders);
277 return folders;
278}
279
280bool UIMachineSettingsSF::getSharedFolders(UISharedFolderType enmFoldersType, CSharedFolderVector &folders)
281{
282 /* Prepare result: */
283 bool fSuccess = true;
284 /* Load folders of passed type: */
285 if (fSuccess)
286 {
287 /* Make sure folder type is supported: */
288 AssertReturn(isSharedFolderTypeSupported(enmFoldersType), false);
289 switch (enmFoldersType)
290 {
291 case UISharedFolderType_Machine:
292 {
293 /* Make sure machine was specified: */
294 AssertReturn(!m_machine.isNull(), false);
295 /* Load machine folders: */
296 folders = m_machine.GetSharedFolders();
297 fSuccess = m_machine.isOk();
298
299 /* Show error message if necessary: */
300 if (!fSuccess)
301 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
302
303 break;
304 }
305 case UISharedFolderType_Console:
306 {
307 /* Make sure console was specified: */
308 AssertReturn(!m_console.isNull(), false);
309 /* Load console folders: */
310 folders = m_console.GetSharedFolders();
311 fSuccess = m_console.isOk();
312
313 /* Show error message if necessary: */
314 if (!fSuccess)
315 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_console));
316
317 break;
318 }
319 default:
320 AssertFailedReturn(false);
321 }
322 }
323 /* Return result: */
324 return fSuccess;
325}
326
327bool UIMachineSettingsSF::getSharedFolder(const QString &strFolderName, const CSharedFolderVector &folders, CSharedFolder &comFolder)
328{
329 /* Prepare result: */
330 bool fSuccess = true;
331 /* Look for a folder with passed name: */
332 for (int iFolderIndex = 0; fSuccess && iFolderIndex < folders.size(); ++iFolderIndex)
333 {
334 /* Get current folder: */
335 const CSharedFolder &comCurrentFolder = folders.at(iFolderIndex);
336
337 /* Get current folder name for further activities: */
338 QString strCurrentFolderName;
339 if (fSuccess)
340 {
341 strCurrentFolderName = comCurrentFolder.GetName();
342 fSuccess = comCurrentFolder.isOk();
343 }
344
345 /* Show error message if necessary: */
346 if (!fSuccess)
347 notifyOperationProgressError(UIErrorString::formatErrorInfo(comCurrentFolder));
348
349 /* If that's the folder we are looking for => take it: */
350 if (fSuccess && strCurrentFolderName == strFolderName)
351 comFolder = folders[iFolderIndex];
352 }
353 /* Return result: */
354 return fSuccess;
355}
356
357bool UIMachineSettingsSF::saveData()
358{
359 /* Sanity check: */
360 if (!m_pCache)
361 return false;
362
363 /* Prepare result: */
364 bool fSuccess = true;
365 /* Save folders settings from cache: */
366 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())
367 {
368 /* For each folder: */
369 for (int iFolderIndex = 0; fSuccess && iFolderIndex < m_pCache->childCount(); ++iFolderIndex)
370 {
371 /* Get folder cache: */
372 const UISettingsCacheSharedFolder &folderCache = m_pCache->child(iFolderIndex);
373
374 /* Remove folder marked for 'remove' or 'update': */
375 if (fSuccess && (folderCache.wasRemoved() || folderCache.wasUpdated()))
376 fSuccess = removeSharedFolder(folderCache);
377
378 /* Create folder marked for 'create' or 'update': */
379 if (fSuccess && (folderCache.wasCreated() || folderCache.wasUpdated()))
380 fSuccess = createSharedFolder(folderCache);
381 }
382 }
383 /* Return result: */
384 return fSuccess;
385}
386
387bool UIMachineSettingsSF::removeSharedFolder(const UISettingsCacheSharedFolder &folderCache)
388{
389 /* Prepare result: */
390 bool fSuccess = true;
391 /* Remove folder: */
392 if (fSuccess)
393 {
394 /* Get folder data: */
395 const UIDataSettingsSharedFolder &newFolderData = folderCache.base();
396 const UISharedFolderType enmFoldersType = newFolderData.m_guiData.m_enmType;
397 const QString strFolderName = newFolderData.m_guiData.m_strName;
398
399 /* Get current folders: */
400 CSharedFolderVector folders;
401 if (fSuccess)
402 fSuccess = getSharedFolders(enmFoldersType, folders);
403
404 /* Search for a folder with the same name: */
405 CSharedFolder comFolder;
406 if (fSuccess)
407 fSuccess = getSharedFolder(strFolderName, folders, comFolder);
408
409 /* Make sure such folder really exists: */
410 if (fSuccess && !comFolder.isNull())
411 {
412 /* Remove existing folder: */
413 switch (enmFoldersType)
414 {
415 case UISharedFolderType_Machine:
416 {
417 /* Remove existing folder: */
418 m_machine.RemoveSharedFolder(strFolderName);
419 /* Check that machine is OK: */
420 fSuccess = m_machine.isOk();
421 if (!fSuccess)
422 {
423 /* Show error message: */
424 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
425 }
426 break;
427 }
428 case UISharedFolderType_Console:
429 {
430 /* Remove existing folder: */
431 m_console.RemoveSharedFolder(strFolderName);
432 /* Check that console is OK: */
433 fSuccess = m_console.isOk();
434 if (!fSuccess)
435 {
436 /* Show error message: */
437 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_console));
438 }
439 break;
440 }
441 default:
442 break;
443 }
444 }
445 }
446 /* Return result: */
447 return fSuccess;
448}
449
450bool UIMachineSettingsSF::createSharedFolder(const UISettingsCacheSharedFolder &folderCache)
451{
452 /* Get folder data: */
453 const UIDataSettingsSharedFolder &newFolderData = folderCache.data();
454 const UISharedFolderType enmFoldersType = newFolderData.m_guiData.m_enmType;
455 const QString strFolderName = newFolderData.m_guiData.m_strName;
456 const QString strFolderPath = newFolderData.m_guiData.m_strPath;
457 const bool fIsWritable = newFolderData.m_guiData.m_fWritable;
458 const bool fIsAutoMount = newFolderData.m_guiData.m_fAutoMount;
459 const QString strAutoMountPoint = newFolderData.m_guiData.m_strAutoMountPoint;
460
461 /* Get current folders: */
462 CSharedFolderVector folders;
463 bool fSuccess = getSharedFolders(enmFoldersType, folders);
464
465 /* Search for a folder with the same name: */
466 CSharedFolder comFolder;
467 if (fSuccess)
468 fSuccess = getSharedFolder(strFolderName, folders, comFolder);
469
470 /* Make sure such folder doesn't exist: */
471 if (fSuccess && comFolder.isNull())
472 {
473 /* Create new folder: */
474 switch (enmFoldersType)
475 {
476 case UISharedFolderType_Machine:
477 {
478 /* Create new folder: */
479 m_machine.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount, strAutoMountPoint);
480 /* Show error if the operation failed: */
481 fSuccess = m_machine.isOk();
482 if (!fSuccess)
483 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
484 break;
485 }
486 case UISharedFolderType_Console:
487 {
488 /* Create new folder: */
489 m_console.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount, strAutoMountPoint);
490 /* Show error if the operation failed: */
491 fSuccess = m_console.isOk();
492 if (!fSuccess)
493 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_console));
494 break;
495 }
496 default:
497 break;
498 }
499 }
500
501 /* Return result: */
502 return fSuccess;
503}
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