VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManager.cpp

Last change on this file was 104445, checked in by vboxsync, 3 weeks ago

FE/Qt. bugref:9510. Adding a new pane container to activity monitor widget to host setting controls.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.0 KB
Line 
1/* $Id: UIFileManager.cpp 104445 2024-04-26 14:09:35Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIFileManager 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/* Qt includes: */
29#include <QApplication>
30#include <QHBoxLayout>
31#include <QPushButton>
32#include <QSplitter>
33
34/* GUI includes: */
35#include "QITabWidget.h"
36#include "QITreeWidget.h"
37#include "QIToolBar.h"
38#include "UIActionPool.h"
39#include "UICommon.h"
40#include "UIConverter.h"
41#include "UIErrorString.h"
42#include "UIExtraDataManager.h"
43#include "UIGlobalSession.h"
44#include "UIIconPool.h"
45#include "UIFileManager.h"
46#include "UIFileManagerPaneContainer.h"
47#include "UIFileManagerGuestTable.h"
48#include "UIFileManagerHostTable.h"
49#include "UIGuestControlInterface.h"
50#include "UIVirtualMachineItem.h"
51
52/* COM includes: */
53#include "CConsole.h"
54#include "CFsObjInfo.h"
55#include "CGuestDirectory.h"
56#include "CGuestFsObjInfo.h"
57#include "CGuestSession.h"
58
59
60/*********************************************************************************************************************************
61* UIFileOperationsList definition. *
62*********************************************************************************************************************************/
63
64class UIFileOperationsList : public QITreeWidget
65{
66 Q_OBJECT;
67public:
68
69 UIFileOperationsList(QWidget *pParent = 0);
70};
71
72
73/*********************************************************************************************************************************
74* UIFileManagerOptions implementation. *
75*********************************************************************************************************************************/
76
77UIFileManagerOptions *UIFileManagerOptions::m_pInstance = 0;
78
79UIFileManagerOptions* UIFileManagerOptions::instance()
80{
81 if (!m_pInstance)
82 m_pInstance = new UIFileManagerOptions;
83 return m_pInstance;
84}
85
86void UIFileManagerOptions::create()
87{
88 if (m_pInstance)
89 return;
90 m_pInstance = new UIFileManagerOptions;
91}
92
93void UIFileManagerOptions::destroy()
94{
95 delete m_pInstance;
96 m_pInstance = 0;
97}
98
99 UIFileManagerOptions::~UIFileManagerOptions()
100{
101}
102
103UIFileManagerOptions::UIFileManagerOptions()
104 : fListDirectoriesOnTop(true)
105 , fAskDeleteConfirmation(false)
106 , fShowHumanReadableSizes(true)
107 , fShowHiddenObjects(true)
108{
109}
110
111/*********************************************************************************************************************************
112* UIFileOperationsList implementation. *
113*********************************************************************************************************************************/
114
115UIFileOperationsList::UIFileOperationsList(QWidget *pParent)
116 :QITreeWidget(pParent)
117{}
118
119
120/*********************************************************************************************************************************
121* UIFileManager implementation. *
122*********************************************************************************************************************************/
123
124UIFileManager::UIFileManager(EmbedTo enmEmbedding, UIActionPool *pActionPool,
125 const CMachine &comMachine, QWidget *pParent, bool fShowToolbar)
126 : QWidget(pParent)
127 , m_pMainLayout(0)
128 , m_pVerticalSplitter(0)
129 , m_pFileTableSplitter(0)
130 , m_pToolBar(0)
131 , m_pVerticalToolBar(0)
132 , m_pHostFileTable(0)
133 , m_pGuestTablesContainer(0)
134 , m_enmEmbedding(enmEmbedding)
135 , m_pActionPool(pActionPool)
136 , m_fShowToolbar(fShowToolbar)
137 , m_pLogPanel(0)
138 , m_pPanel(0)
139 , m_fCommitDataSignalReceived(false)
140{
141 loadOptions();
142 prepareObjects();
143 prepareConnections();
144 restorePanelVisibility();
145 UIFileManagerOptions::create();
146 uiCommon().setHelpKeyword(this, "guestadd-gc-file-manager");
147
148 if (!comMachine.isNull())
149 setMachines( QVector<QUuid>() << comMachine.GetId());
150}
151
152UIFileManager::~UIFileManager()
153{
154 UIFileManagerOptions::destroy();
155 if (m_pGuestTablesContainer)
156 {
157 for (int i = 0; i < m_pGuestTablesContainer->count(); ++i)
158 {
159 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
160 if (pTable)
161 pTable->disconnect();
162 }
163 }
164}
165
166QMenu *UIFileManager::menu() const
167{
168 if (!m_pActionPool)
169 return 0;
170 return m_pActionPool->action(UIActionIndex_M_FileManager)->menu();
171}
172
173void UIFileManager::prepareObjects()
174{
175 /* m_pMainLayout is the outer most layout containing the main toolbar and splitter widget: */
176 m_pMainLayout = new QVBoxLayout(this);
177 if (!m_pMainLayout)
178 return;
179
180 /* Configure layout: */
181 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
182#ifdef VBOX_WS_MAC
183 m_pMainLayout->setSpacing(10);
184#else
185 m_pMainLayout->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2);
186#endif
187
188 if (m_fShowToolbar)
189 prepareToolBar();
190
191 QWidget *pTopWidget = new QWidget;
192 QVBoxLayout *pTopLayout = new QVBoxLayout;
193 pTopLayout->setSpacing(0);
194 pTopLayout->setContentsMargins(0, 0, 0, 0);
195 pTopWidget->setLayout(pTopLayout);
196
197 m_pFileTableSplitter = new QSplitter;
198
199 if (m_pFileTableSplitter)
200 {
201 m_pFileTableSplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
202 m_pFileTableSplitter->setContentsMargins(0, 0, 0, 0);
203
204 /* This widget hosts host file table and vertical toolbar. */
205 QWidget *pHostTableAndVerticalToolbarWidget = new QWidget;
206 QHBoxLayout *pHostTableAndVerticalToolbarLayout = new QHBoxLayout(pHostTableAndVerticalToolbarWidget);
207 pHostTableAndVerticalToolbarLayout->setSpacing(0);
208 pHostTableAndVerticalToolbarLayout->setContentsMargins(0, 0, 0, 0);
209
210 m_pHostFileTable = new UIFileManagerHostTable(m_pActionPool);
211 if (m_pHostFileTable)
212 pHostTableAndVerticalToolbarLayout->addWidget(m_pHostFileTable);
213
214 m_pFileTableSplitter->addWidget(pHostTableAndVerticalToolbarWidget);
215 prepareVerticalToolBar(pHostTableAndVerticalToolbarLayout);
216
217 m_pGuestTablesContainer = new QITabWidget;
218 if (m_pGuestTablesContainer)
219 {
220 m_pGuestTablesContainer->setTabPosition(QTabWidget::East);
221 m_pGuestTablesContainer->setTabBarAutoHide(true);
222 m_pFileTableSplitter->addWidget(m_pGuestTablesContainer);
223 }
224 m_pFileTableSplitter->setStretchFactor(0, 1);
225 m_pFileTableSplitter->setStretchFactor(1, 1);
226 }
227
228 pTopLayout->addWidget(m_pFileTableSplitter);
229 for (int i = 0; i < m_pFileTableSplitter->count(); ++i)
230 m_pFileTableSplitter->setCollapsible(i, false);
231
232 m_pVerticalSplitter = new QSplitter;
233 if (m_pVerticalSplitter)
234 {
235 m_pMainLayout->addWidget(m_pVerticalSplitter);
236 m_pVerticalSplitter->setOrientation(Qt::Vertical);
237 m_pVerticalSplitter->setHandleWidth(4);
238
239 m_pVerticalSplitter->addWidget(pTopWidget);
240
241 for (int i = 0; i < m_pVerticalSplitter->count(); ++i)
242 m_pVerticalSplitter->setCollapsible(i, false);
243 m_pVerticalSplitter->setStretchFactor(0, 3);
244 m_pVerticalSplitter->setStretchFactor(1, 1);
245 m_pVerticalSplitter->setStretchFactor(2, 1);
246 }
247
248 m_pPanel = new UIFileManagerPaneContainer(this, UIFileManagerOptions::instance());
249 AssertReturnVoid(m_pPanel);
250
251 m_panelActions.insert(m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences));
252 m_panelActions.insert(m_pActionPool->action(UIActionIndex_M_FileManager_T_Log));
253 m_panelActions.insert(m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations));
254
255 m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences)->setData(static_cast<int>(UIFileManagerPaneContainer::Page_Preferences));
256 m_pActionPool->action(UIActionIndex_M_FileManager_T_Log)->setData(static_cast<int>(UIFileManagerPaneContainer::Page_Log));
257 m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations)->setData(static_cast<int>(UIFileManagerPaneContainer::Page_Operations));
258
259 m_pVerticalSplitter->addWidget(m_pPanel);
260 m_pPanel->hide();
261}
262
263void UIFileManager::prepareVerticalToolBar(QHBoxLayout *layout)
264{
265 m_pVerticalToolBar = new QIToolBar;
266 if (!m_pVerticalToolBar && !m_pActionPool)
267 return;
268
269 m_pVerticalToolBar->setOrientation(Qt::Vertical);
270
271 /* Add to dummy QWidget to toolbar to center the action icons vertically: */
272 QWidget *topSpacerWidget = new QWidget(this);
273 topSpacerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
274 topSpacerWidget->setVisible(true);
275 QWidget *bottomSpacerWidget = new QWidget(this);
276 bottomSpacerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
277 bottomSpacerWidget->setVisible(true);
278
279 m_pVerticalToolBar->addWidget(topSpacerWidget);
280 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost))
281 {
282 m_pVerticalToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost));
283 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost)->setEnabled(false);
284 }
285 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest))
286 {
287 m_pVerticalToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest));
288 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest)->setEnabled(false);
289 }
290
291 m_pVerticalToolBar->addWidget(bottomSpacerWidget);
292
293 layout ->addWidget(m_pVerticalToolBar);
294}
295
296void UIFileManager::prepareConnections()
297{
298 if (m_pActionPool)
299 {
300 if (m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences))
301 connect(m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences), &QAction::toggled,
302 this, &UIFileManager::sltPanelActionToggled);
303 if (m_pActionPool->action(UIActionIndex_M_FileManager_T_Log))
304 connect(m_pActionPool->action(UIActionIndex_M_FileManager_T_Log), &QAction::toggled,
305 this, &UIFileManager::sltPanelActionToggled);
306 if (m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations))
307 connect(m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations), &QAction::toggled,
308 this, &UIFileManager::sltPanelActionToggled);
309 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost))
310 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost), &QAction::triggered,
311 this, &UIFileManager::sltCopyGuestToHost);
312 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest))
313 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest), &QAction::triggered,
314 this, &UIFileManager::sltCopyHostToGuest);
315 }
316
317 if (m_pPanel)
318 {
319 connect(m_pPanel, &UIFileManagerPaneContainer::sigOptionsChanged,
320 this, &UIFileManager::sltHandleOptionsUpdated);
321 connect(m_pPanel, &UIFileManagerPaneContainer::sigFileOperationComplete,
322 this, &UIFileManager::sltFileOperationComplete);
323 connect(m_pPanel, &UIFileManagerPaneContainer::sigFileOperationFail,
324 this, &UIFileManager::sltReceieveLogOutput);
325 connect(m_pPanel, &UIFileManagerPaneContainer::sigCurrentTabChanged,
326 this, &UIFileManager::sltPanelCurrentTabChanged);
327 connect(m_pPanel, &UIFileManagerPaneContainer::sigHidden,
328 this, &UIFileManager::sltPanelContainerHidden);
329 }
330
331 if (m_pHostFileTable)
332 {
333 connect(m_pHostFileTable, &UIFileManagerHostTable::sigLogOutput,
334 this, &UIFileManager::sltReceieveLogOutput);
335 connect(m_pHostFileTable, &UIFileManagerHostTable::sigDeleteConfirmationOptionChanged,
336 this, &UIFileManager::sltHandleOptionsUpdated);
337 connect(m_pHostFileTable, &UIFileManagerGuestTable::sigSelectionChanged,
338 this, &UIFileManager::sltFileTableSelectionChanged);
339 }
340 if (m_pGuestTablesContainer)
341 connect(m_pGuestTablesContainer, &QITabWidget::currentChanged, this,
342 &UIFileManager::sltCurrentTabChanged);
343
344 connect(&uiCommon(), &UICommon::sigAskToCommitData,
345 this, &UIFileManager::sltCommitDataSignalReceived);
346}
347
348void UIFileManager::prepareToolBar()
349{
350 /* Create toolbar: */
351 m_pToolBar = new QIToolBar(parentWidget());
352 if (m_pToolBar)
353 {
354 /* Configure toolbar: */
355 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize));
356 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
357 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
358
359 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences));
360 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations));
361 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Log));
362
363#ifdef VBOX_WS_MAC
364 /* Check whether we are embedded into a stack: */
365 if (m_enmEmbedding == EmbedTo_Stack)
366 {
367 /* Add into layout: */
368 m_pMainLayout->addWidget(m_pToolBar);
369 }
370#else
371 /* Add into layout: */
372 m_pMainLayout->addWidget(m_pToolBar);
373#endif
374 }
375}
376
377void UIFileManager::sltReceieveLogOutput(QString strOutput, const QString &strMachineName, FileManagerLogType eLogType)
378{
379 appendLog(strOutput, strMachineName, eLogType);
380}
381
382void UIFileManager::sltCopyGuestToHost()
383{
384 copyToHost();
385}
386
387void UIFileManager::sltCopyHostToGuest()
388{
389 copyToGuest();
390}
391
392void UIFileManager::sltPanelActionToggled(bool fChecked)
393{
394 QAction *pSenderAction = qobject_cast<QAction*>(sender());
395 if (!pSenderAction)
396 return;
397
398 m_pPanel->setVisible(fChecked);
399
400 if (fChecked)
401 {
402 /* Make sure only pSenderAction is toggled on. */
403 for(QSet<QAction*>::iterator iter = m_panelActions.begin(); iter != m_panelActions.end(); ++iter)
404 {
405 QAction *pAction = *iter;
406 if (!pAction || pAction == pSenderAction)
407 continue;
408 pAction->blockSignals(true);
409 pAction->setChecked(false);
410 pAction->blockSignals(false);
411 }
412 m_pPanel->blockSignals(true);
413 m_pPanel->setCurrentIndex(pSenderAction->data().toInt());
414 m_pPanel->blockSignals(false);
415 }
416
417 // UIDialogPanel* pPanel = 0;
418 // /* Look for the sender() within the m_panelActionMap's values: */
419 // for (QMap<UIDialogPanel*, QAction*>::const_iterator iterator = m_panelActionMap.begin();
420 // iterator != m_panelActionMap.end(); ++iterator)
421 // {
422 // if (iterator.value() == pSenderAction)
423 // pPanel = iterator.key();
424 // }
425 // if (!pPanel)
426 // return;
427 // if (fChecked)
428 // showPanel(pPanel);
429 // else
430 // hidePanel(pPanel);
431}
432
433void UIFileManager::sltReceieveNewFileOperation(const CProgress &comProgress, const QString &strTableName)
434{
435 if (m_pPanel)
436 m_pPanel->addNewProgress(comProgress, strTableName);
437}
438
439void UIFileManager::sltFileOperationComplete(QUuid progressId)
440{
441 Q_UNUSED(progressId);
442 if (m_pHostFileTable)
443 m_pHostFileTable->refresh();
444 /// @todo we need to refresh only the table from which the completed file operation has originated
445 for (int i = 0; i < m_pGuestTablesContainer->count(); ++i)
446 {
447 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
448 if (pTable)
449 pTable->refresh();
450 }
451}
452
453void UIFileManager::sltHandleHidePanel(UIDialogPanel *pPanel)
454{
455 hidePanel(pPanel);
456}
457
458void UIFileManager::sltHandleShowPanel(UIDialogPanel *pPanel)
459{
460 showPanel(pPanel);
461}
462
463void UIFileManager::sltCommitDataSignalReceived()
464{
465 m_fCommitDataSignalReceived = true;
466}
467
468void UIFileManager::sltFileTableSelectionChanged(bool fHasSelection)
469{
470 /* If we dont have a guest session running that actions should stay disabled: */
471 if (!currentGuestTable() || !currentGuestTable()->isGuestSessionRunning())
472 {
473 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest)->setEnabled(false);
474 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost)->setEnabled(false);
475 return;
476 }
477
478 /* Enable/disable vertical toolbar actions: */
479 UIFileManagerGuestTable *pGuestTable = qobject_cast<UIFileManagerGuestTable*>(sender());
480
481 /* If the signal is coming from a guest table which is not the current one just dont do anything: */
482 if (pGuestTable && pGuestTable != currentGuestTable())
483 return;
484
485 if (pGuestTable)
486 {
487 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost))
488 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost)->setEnabled(fHasSelection);
489 return;
490 }
491
492 if (sender() == m_pHostFileTable && m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest))
493 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest)->setEnabled(fHasSelection);
494}
495
496void UIFileManager::sltCurrentTabChanged(int iIndex)
497{
498 Q_UNUSED(iIndex);
499 setVerticalToolBarActionsEnabled();
500
501 /* Mark the current guest table: */
502 UIFileManagerGuestTable *pCurrentGuestTable = currentGuestTable();
503 if (!pCurrentGuestTable)
504 return;
505 for (int i = 0; i < m_pGuestTablesContainer->count(); ++i)
506 {
507 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
508 if (!pTable)
509 continue;
510 pTable->setIsCurrent(pTable == pCurrentGuestTable);
511 }
512 /* Disable host file table if guest session is not running: */
513 if (m_pHostFileTable)
514 m_pHostFileTable->setEnabled(pCurrentGuestTable->isGuestSessionRunning());
515 /* Disable/enable file table submenus of the menu: */
516 UIMenu *pGuestSubmenu = m_pActionPool->action(UIActionIndex_M_FileManager_M_GuestSubmenu)->menu();
517 if (pGuestSubmenu)
518 pGuestSubmenu->setEnabled(pCurrentGuestTable->isGuestSessionRunning());
519 UIMenu *pHostSubmenu = m_pActionPool->action(UIActionIndex_M_FileManager_M_HostSubmenu)->menu();
520 if (pHostSubmenu)
521 pHostSubmenu->setEnabled(pCurrentGuestTable->isGuestSessionRunning());
522}
523
524void UIFileManager::sltGuestFileTableStateChanged(bool fIsRunning)
525{
526 if (m_pHostFileTable)
527 m_pHostFileTable->setEnabled(fIsRunning);
528}
529
530void UIFileManager::sltHandleOptionsUpdated()
531{
532 if (m_pPanel)
533 m_pPanel->updatePreferences();
534
535 for (int i = 0; i < m_pGuestTablesContainer->count(); ++i)
536 {
537 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
538 if (pTable)
539 pTable->optionsUpdated();
540 }
541 if (m_pHostFileTable)
542 m_pHostFileTable->optionsUpdated();
543 saveOptions();
544}
545
546void UIFileManager::sltPanelCurrentTabChanged(int iIndex)
547{
548 if (!m_pPanel || !m_pPanel->isVisible())
549 return;
550
551 for(QSet<QAction*>::iterator iter = m_panelActions.begin(); iter != m_panelActions.end(); ++iter)
552 {
553 QAction *pAction = *iter;
554
555 pAction->blockSignals(true);
556 pAction->setChecked(false);
557 pAction->blockSignals(false);
558 }
559
560 switch (static_cast<UIFileManagerPaneContainer::Page>(iIndex))
561 {
562 case UIFileManagerPaneContainer::Page_Preferences:
563 m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences)->setChecked(true);
564 break;
565 case UIFileManagerPaneContainer::Page_Operations:
566 m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations)->setChecked(true);
567 break;
568 case UIFileManagerPaneContainer::Page_Log:
569 m_pActionPool->action(UIActionIndex_M_FileManager_T_Log)->setChecked(true);
570 break;
571 case UIFileManagerPaneContainer::Page_Max:
572 default:
573 break;
574 }
575}
576
577void UIFileManager::sltPanelContainerHidden()
578{
579 foreach (QAction *pPanelAction, m_panelActions)
580 {
581 if (!pPanelAction)
582 continue;
583 pPanelAction->blockSignals(true);
584 pPanelAction->setChecked(false);
585 pPanelAction->blockSignals(false);
586 }
587}
588
589void UIFileManager::setVerticalToolBarActionsEnabled()
590{
591 if (!m_pGuestTablesContainer)
592 return;
593 UIFileManagerGuestTable *pTable = currentGuestTable();
594 if (!pTable)
595 return;
596
597 bool fRunning = pTable->isGuestSessionRunning();
598 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost))
599 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToHost)->setEnabled(fRunning && pTable->hasSelection());
600
601 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest))
602 {
603 bool fHostHasSelection = m_pHostFileTable ? m_pHostFileTable->hasSelection() : false;
604 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest)->setEnabled(fRunning && fHostHasSelection);
605 }
606}
607
608void UIFileManager::copyToHost()
609{
610 if (m_pGuestTablesContainer && m_pHostFileTable)
611 {
612 UIFileManagerGuestTable *pGuestFileTable = currentGuestTable();
613 if (pGuestFileTable)
614 pGuestFileTable->copyGuestToHost(m_pHostFileTable->currentDirectoryPath());
615 }
616}
617
618void UIFileManager::copyToGuest()
619{
620 if (m_pGuestTablesContainer && m_pHostFileTable)
621 {
622 UIFileManagerGuestTable *pGuestFileTable = currentGuestTable();
623 if (pGuestFileTable)
624 pGuestFileTable->copyHostToGuest(m_pHostFileTable->selectedItemPathList());
625 }
626}
627
628template<typename T>
629QStringList UIFileManager::getFsObjInfoStringList(const T &fsObjectInfo) const
630{
631 QStringList objectInfo;
632 if (!fsObjectInfo.isOk())
633 return objectInfo;
634 objectInfo << fsObjectInfo.GetName();
635 return objectInfo;
636}
637
638void UIFileManager::saveOptions()
639{
640 if (m_fCommitDataSignalReceived)
641 return;
642 /* Save the options: */
643 UIFileManagerOptions *pOptions = UIFileManagerOptions::instance();
644 if (pOptions)
645 {
646 gEDataManager->setFileManagerOptions(pOptions->fListDirectoriesOnTop,
647 pOptions->fAskDeleteConfirmation,
648 pOptions->fShowHumanReadableSizes,
649 pOptions->fShowHiddenObjects);
650 }
651}
652
653void UIFileManager::restorePanelVisibility()
654{
655 /** Make sure the actions are set to not-checked. this prevents an unlikely
656 * bug when the extrakey for the visible panels are manually modified: */
657 // foreach(QAction* pAction, m_panelActionMap.values())
658 // {
659 // pAction->blockSignals(true);
660 // pAction->setChecked(false);
661 // pAction->blockSignals(false);
662 // }
663 /* Load the visible panel list and show them: */
664 // QStringList strNameList = gEDataManager->fileManagerVisiblePanels();
665 // foreach(const QString strName, strNameList)
666 // {
667 // foreach(UIDialogPanel* pPanel, m_panelActionMap.keys())
668 // {
669 // if (strName == pPanel->panelName())
670 // {
671 // showPanel(pPanel);
672 // break;
673 // }
674 // }
675 // }
676}
677
678void UIFileManager::loadOptions()
679{
680 /* Load options: */
681 UIFileManagerOptions *pOptions = UIFileManagerOptions::instance();
682 if (pOptions)
683 {
684 pOptions->fListDirectoriesOnTop = gEDataManager->fileManagerListDirectoriesFirst();
685 pOptions->fAskDeleteConfirmation = gEDataManager->fileManagerShowDeleteConfirmation();
686 pOptions->fShowHumanReadableSizes = gEDataManager->fileManagerShowHumanReadableSizes();
687 pOptions->fShowHiddenObjects = gEDataManager->fileManagerShowHiddenObjects();
688 }
689}
690
691void UIFileManager::hidePanel(UIDialogPanel* panel)
692{
693 Q_UNUSED(panel);
694 // if (!m_pActionPool)
695 // return;
696 // if (panel && panel->isVisible())
697 // panel->setVisible(false);
698 // QMap<UIDialogPanel*, QAction*>::iterator iterator = m_panelActionMap.find(panel);
699 // if (iterator != m_panelActionMap.end())
700 // {
701 // if (iterator.value() && iterator.value()->isChecked())
702 // iterator.value()->setChecked(false);
703 // }
704 // m_visiblePanelsList.removeAll(panel);
705 // manageEscapeShortCut();
706 // savePanelVisibility();
707}
708
709void UIFileManager::showPanel(UIDialogPanel* panel)
710{
711 Q_UNUSED(panel);
712 // if (panel && panel->isHidden())
713 // panel->setVisible(true);
714 // QMap<UIDialogPanel*, QAction*>::iterator iterator = m_panelActionMap.find(panel);
715 // if (iterator != m_panelActionMap.end())
716 // {
717 // if (!iterator.value()->isChecked())
718 // iterator.value()->setChecked(true);
719 // }
720 // if (!m_visiblePanelsList.contains(panel))
721 // m_visiblePanelsList.push_back(panel);
722 // manageEscapeShortCut();
723 // savePanelVisibility();
724}
725
726void UIFileManager::manageEscapeShortCut()
727{
728 /* if there is no visible panels give the escape shortcut to parent dialog: */
729 // if (m_visiblePanelsList.isEmpty())
730 // {
731 // emit sigSetCloseButtonShortCut(QKeySequence(Qt::Key_Escape));
732 // return;
733 // }
734 // /* Take the escape shortcut from the dialog: */
735 // emit sigSetCloseButtonShortCut(QKeySequence());
736 // /* Just loop thru the visible panel list and set the esc key to the
737 // panel which made visible latest */
738 // for (int i = 0; i < m_visiblePanelsList.size() - 1; ++i)
739 // m_visiblePanelsList[i]->setCloseButtonShortCut(QKeySequence());
740
741 // m_visiblePanelsList.back()->setCloseButtonShortCut(QKeySequence(Qt::Key_Escape));
742}
743
744void UIFileManager::appendLog(const QString &strLog, const QString &strMachineName, FileManagerLogType eLogType)
745{
746 if (m_pPanel)
747 m_pPanel->appendLog(strLog, strMachineName, eLogType);
748}
749
750void UIFileManager::savePanelVisibility()
751{
752 if (m_fCommitDataSignalReceived)
753 return;
754 // /* Save a list of currently visible panels: */
755 // QStringList strNameList;
756 // foreach(UIDialogPanel* pPanel, m_visiblePanelsList)
757 // strNameList.append(pPanel->panelName());
758 // gEDataManager->setFileManagerVisiblePanels(strNameList);
759}
760
761void UIFileManager::setSelectedVMListItems(const QList<UIVirtualMachineItem*> &items)
762{
763 AssertReturnVoid(m_pGuestTablesContainer);
764 QVector<QUuid> selectedMachines;
765
766 foreach (const UIVirtualMachineItem *item, items)
767 {
768 if (!item)
769 continue;
770 selectedMachines << item->id();
771 }
772 QUuid lastSelection = selectedMachines.isEmpty() ? QUuid() : selectedMachines.last();
773 /** Iterate through the current tabs and add any machine id for which we have a running guest session to the
774 * list of machine ids we want to have a tab for: */
775 for (int i = 0; i < m_pGuestTablesContainer->count(); ++i)
776 {
777 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
778 if (!pTable || !pTable->isGuestSessionRunning())
779 continue;
780 if (!selectedMachines.contains(pTable->machineId()))
781 selectedMachines << pTable->machineId();
782 }
783
784 setMachines(selectedMachines, lastSelection);
785}
786
787void UIFileManager::setMachines(const QVector<QUuid> &machineIds, const QUuid &lastSelectedMachineId /* = QUuid() */)
788{
789 AssertReturnVoid(m_pGuestTablesContainer);
790
791 /* List of machines that are newly added to selected machine list: */
792 QVector<QUuid> newSelections;
793 QVector<QUuid> unselectedMachines(m_machineIds);
794
795 foreach (const QUuid &id, machineIds)
796 {
797 unselectedMachines.removeAll(id);
798 if (!m_machineIds.contains(id))
799 newSelections << id;
800 }
801 m_machineIds = machineIds;
802
803 addTabs(newSelections);
804 removeTabs(unselectedMachines);
805 if (!lastSelectedMachineId.isNull())
806 {
807 int iIndexToSelect = -1;
808 for (int i = 0; i < m_pGuestTablesContainer->count() && iIndexToSelect == -1; ++i)
809 {
810 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
811 if (!pTable)
812 continue;
813 if (lastSelectedMachineId == pTable->machineId())
814 iIndexToSelect = i;
815 }
816 if (iIndexToSelect != -1)
817 m_pGuestTablesContainer->setCurrentIndex(iIndexToSelect);
818 }
819}
820
821void UIFileManager::removeTabs(const QVector<QUuid> &machineIdsToRemove)
822{
823 if (!m_pGuestTablesContainer)
824 return;
825 QVector<UIFileManagerGuestTable*> removeList;
826
827 for (int i = m_pGuestTablesContainer->count() - 1; i >= 0; --i)
828 {
829 UIFileManagerGuestTable *pTable = qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->widget(i));
830 if (!pTable)
831 continue;
832 if (machineIdsToRemove.contains(pTable->machineId()))
833 {
834 removeList << pTable;
835 m_pGuestTablesContainer->removeTab(i);
836 }
837 }
838 qDeleteAll(removeList.begin(), removeList.end());
839}
840
841void UIFileManager::addTabs(const QVector<QUuid> &machineIdsToAdd)
842{
843 if (!m_pGuestTablesContainer)
844 return;
845
846 foreach (const QUuid &id, machineIdsToAdd)
847 {
848 CMachine comMachine = gpGlobalSession->virtualBox().FindMachine(id.toString());
849 if (comMachine.isNull())
850 continue;
851 UIFileManagerGuestTable *pGuestFileTable = new UIFileManagerGuestTable(m_pActionPool, comMachine, m_pGuestTablesContainer);
852 m_pGuestTablesContainer->addTab(pGuestFileTable, comMachine.GetName());
853 if (pGuestFileTable)
854 {
855 connect(pGuestFileTable, &UIFileManagerGuestTable::sigLogOutput,
856 this, &UIFileManager::sltReceieveLogOutput);
857 connect(pGuestFileTable, &UIFileManagerGuestTable::sigSelectionChanged,
858 this, &UIFileManager::sltFileTableSelectionChanged);
859 connect(pGuestFileTable, &UIFileManagerGuestTable::sigNewFileOperation,
860 this, &UIFileManager::sltReceieveNewFileOperation);
861 connect(pGuestFileTable, &UIFileManagerGuestTable::sigStateChanged,
862 this, &UIFileManager::sltGuestFileTableStateChanged);
863 connect(pGuestFileTable, &UIFileManagerGuestTable::sigDeleteConfirmationOptionChanged,
864 this, &UIFileManager::sltHandleOptionsUpdated);
865 }
866 }
867}
868
869UIFileManagerGuestTable *UIFileManager::currentGuestTable()
870{
871 if (!m_pGuestTablesContainer)
872 return 0;
873 return qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->currentWidget());
874}
875#include "UIFileManager.moc"
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use