VirtualBox

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

Last change on this file was 104445, checked in by vboxsync, 5 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
RevLine 
[71025]1/* $Id: UIFileManager.cpp 104445 2024-04-26 14:09:35Z vboxsync $ */
2/** @file
[76177]3 * VBox Qt GUI - UIFileManager class implementation.
[71025]4 */
5
6/*
[98103]7 * Copyright (C) 2016-2023 Oracle and/or its affiliates.
[71025]8 *
[96407]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
[71025]26 */
27
28/* Qt includes: */
[104393]29#include <QApplication>
[76606]30#include <QHBoxLayout>
31#include <QPushButton>
32#include <QSplitter>
[71025]33
34/* GUI includes: */
[92688]35#include "QITabWidget.h"
[76606]36#include "QITreeWidget.h"
[92610]37#include "QIToolBar.h"
[76606]38#include "UIActionPool.h"
[92610]39#include "UICommon.h"
40#include "UIConverter.h"
[76606]41#include "UIErrorString.h"
42#include "UIExtraDataManager.h"
[103771]43#include "UIGlobalSession.h"
[76606]44#include "UIIconPool.h"
45#include "UIFileManager.h"
[101020]46#include "UIFileManagerPaneContainer.h"
[76606]47#include "UIFileManagerGuestTable.h"
[77528]48#include "UIFileManagerHostTable.h"
[76606]49#include "UIGuestControlInterface.h"
[92688]50#include "UIVirtualMachineItem.h"
[71025]51
52/* COM includes: */
[92630]53#include "CConsole.h"
[76606]54#include "CFsObjInfo.h"
55#include "CGuestDirectory.h"
56#include "CGuestFsObjInfo.h"
57#include "CGuestSession.h"
[71025]58
[74947]59
[71439]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/*********************************************************************************************************************************
[76177]74* UIFileManagerOptions implementation. *
[75193]75*********************************************************************************************************************************/
76
[76177]77UIFileManagerOptions *UIFileManagerOptions::m_pInstance = 0;
[75193]78
[76177]79UIFileManagerOptions* UIFileManagerOptions::instance()
[75193]80{
[75220]81 if (!m_pInstance)
[76177]82 m_pInstance = new UIFileManagerOptions;
[75193]83 return m_pInstance;
84}
85
[76177]86void UIFileManagerOptions::create()
[75193]87{
88 if (m_pInstance)
89 return;
[76177]90 m_pInstance = new UIFileManagerOptions;
[75193]91}
92
[76177]93void UIFileManagerOptions::destroy()
[75193]94{
95 delete m_pInstance;
96 m_pInstance = 0;
97}
98
[76177]99 UIFileManagerOptions::~UIFileManagerOptions()
[75193]100{
101}
102
[76177]103UIFileManagerOptions::UIFileManagerOptions()
[76627]104 : fListDirectoriesOnTop(true)
105 , fAskDeleteConfirmation(false)
106 , fShowHumanReadableSizes(true)
107 , fShowHiddenObjects(true)
[75193]108{
109}
110
111/*********************************************************************************************************************************
[71439]112* UIFileOperationsList implementation. *
113*********************************************************************************************************************************/
[71133]114
[71439]115UIFileOperationsList::UIFileOperationsList(QWidget *pParent)
116 :QITreeWidget(pParent)
117{}
[71133]118
[71439]119
[71133]120/*********************************************************************************************************************************
[76177]121* UIFileManager implementation. *
[71133]122*********************************************************************************************************************************/
123
[76177]124UIFileManager::UIFileManager(EmbedTo enmEmbedding, UIActionPool *pActionPool,
[92638]125 const CMachine &comMachine, QWidget *pParent, bool fShowToolbar)
[104297]126 : QWidget(pParent)
[71105]127 , m_pMainLayout(0)
[75246]128 , m_pVerticalSplitter(0)
[92641]129 , m_pFileTableSplitter(0)
[71191]130 , m_pToolBar(0)
[92847]131 , m_pVerticalToolBar(0)
[71185]132 , m_pHostFileTable(0)
[92688]133 , m_pGuestTablesContainer(0)
[75087]134 , m_enmEmbedding(enmEmbedding)
135 , m_pActionPool(pActionPool)
[75220]136 , m_fShowToolbar(fShowToolbar)
137 , m_pLogPanel(0)
[100879]138 , m_pPanel(0)
[92790]139 , m_fCommitDataSignalReceived(false)
[71059]140{
[75642]141 loadOptions();
[71105]142 prepareObjects();
143 prepareConnections();
[75762]144 restorePanelVisibility();
[76177]145 UIFileManagerOptions::create();
[86986]146 uiCommon().setHelpKeyword(this, "guestadd-gc-file-manager");
[92741]147
148 if (!comMachine.isNull())
149 setMachines( QVector<QUuid>() << comMachine.GetId());
[71059]150}
151
[76177]152UIFileManager::~UIFileManager()
[71133]153{
[76177]154 UIFileManagerOptions::destroy();
[92814]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 }
[71133]164}
165
[76177]166QMenu *UIFileManager::menu() const
[75136]167{
168 if (!m_pActionPool)
169 return 0;
[76177]170 return m_pActionPool->action(UIActionIndex_M_FileManager)->menu();
[75136]171}
172
[76177]173void UIFileManager::prepareObjects()
[71037]174{
[75246]175 /* m_pMainLayout is the outer most layout containing the main toolbar and splitter widget: */
[71105]176 m_pMainLayout = new QVBoxLayout(this);
177 if (!m_pMainLayout)
[71037]178 return;
179
[71105]180 /* Configure layout: */
[75246]181 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
[75247]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
[71037]187
[75220]188 if (m_fShowToolbar)
189 prepareToolBar();
[71089]190
[75246]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
[92643]197 m_pFileTableSplitter = new QSplitter;
198
199 if (m_pFileTableSplitter)
[71133]200 {
[92643]201 m_pFileTableSplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
202 m_pFileTableSplitter->setContentsMargins(0, 0, 0, 0);
[75246]203
[92641]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
[76177]210 m_pHostFileTable = new UIFileManagerHostTable(m_pActionPool);
[75246]211 if (m_pHostFileTable)
[92641]212 pHostTableAndVerticalToolbarLayout->addWidget(m_pHostFileTable);
[92645]213
[92643]214 m_pFileTableSplitter->addWidget(pHostTableAndVerticalToolbarWidget);
[92641]215 prepareVerticalToolBar(pHostTableAndVerticalToolbarLayout);
[92688]216
217 m_pGuestTablesContainer = new QITabWidget;
218 if (m_pGuestTablesContainer)
219 {
[92733]220 m_pGuestTablesContainer->setTabPosition(QTabWidget::East);
[92688]221 m_pGuestTablesContainer->setTabBarAutoHide(true);
222 m_pFileTableSplitter->addWidget(m_pGuestTablesContainer);
223 }
[93682]224 m_pFileTableSplitter->setStretchFactor(0, 1);
225 m_pFileTableSplitter->setStretchFactor(1, 1);
[71133]226 }
[71105]227
[92643]228 pTopLayout->addWidget(m_pFileTableSplitter);
229 for (int i = 0; i < m_pFileTableSplitter->count(); ++i)
230 m_pFileTableSplitter->setCollapsible(i, false);
231
[92645]232 m_pVerticalSplitter = new QSplitter;
233 if (m_pVerticalSplitter)
[71439]234 {
[92645]235 m_pMainLayout->addWidget(m_pVerticalSplitter);
236 m_pVerticalSplitter->setOrientation(Qt::Vertical);
237 m_pVerticalSplitter->setHandleWidth(4);
[75480]238
[92645]239 m_pVerticalSplitter->addWidget(pTopWidget);
[75295]240
[92645]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);
[75246]246 }
[100879]247
[101020]248 m_pPanel = new UIFileManagerPaneContainer(this, UIFileManagerOptions::instance());
[100879]249 AssertReturnVoid(m_pPanel);
[100905]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
[101020]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));
[100905]258
[100879]259 m_pVerticalSplitter->addWidget(m_pPanel);
[100905]260 m_pPanel->hide();
[71049]261}
262
[76177]263void UIFileManager::prepareVerticalToolBar(QHBoxLayout *layout)
[71391]264{
[86233]265 m_pVerticalToolBar = new QIToolBar;
[92640]266 if (!m_pVerticalToolBar && !m_pActionPool)
[71391]267 return;
268
[75835]269 m_pVerticalToolBar->setOrientation(Qt::Vertical);
[71391]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
[75835]279 m_pVerticalToolBar->addWidget(topSpacerWidget);
[92899]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
[75835]291 m_pVerticalToolBar->addWidget(bottomSpacerWidget);
[71391]292
[75835]293 layout ->addWidget(m_pVerticalToolBar);
[71391]294}
295
[76177]296void UIFileManager::prepareConnections()
[71037]297{
[92640]298 if (m_pActionPool)
299 {
[100888]300 if (m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences))
301 connect(m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences), &QAction::toggled,
[92640]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 }
[100890]316
[100887]317 if (m_pPanel)
318 {
[101020]319 connect(m_pPanel, &UIFileManagerPaneContainer::sigOptionsChanged,
[100887]320 this, &UIFileManager::sltHandleOptionsUpdated);
[101020]321 connect(m_pPanel, &UIFileManagerPaneContainer::sigFileOperationComplete,
[100893]322 this, &UIFileManager::sltFileOperationComplete);
[101020]323 connect(m_pPanel, &UIFileManagerPaneContainer::sigFileOperationFail,
[100893]324 this, &UIFileManager::sltReceieveLogOutput);
[101020]325 connect(m_pPanel, &UIFileManagerPaneContainer::sigCurrentTabChanged,
[100906]326 this, &UIFileManager::sltPanelCurrentTabChanged);
[101020]327 connect(m_pPanel, &UIFileManagerPaneContainer::sigHidden,
[100955]328 this, &UIFileManager::sltPanelContainerHidden);
[100887]329 }
[100893]330
[92645]331 if (m_pHostFileTable)
332 {
333 connect(m_pHostFileTable, &UIFileManagerHostTable::sigLogOutput,
334 this, &UIFileManager::sltReceieveLogOutput);
[100887]335 connect(m_pHostFileTable, &UIFileManagerHostTable::sigDeleteConfirmationOptionChanged,
336 this, &UIFileManager::sltHandleOptionsUpdated);
[92899]337 connect(m_pHostFileTable, &UIFileManagerGuestTable::sigSelectionChanged,
338 this, &UIFileManager::sltFileTableSelectionChanged);
[92645]339 }
[92947]340 if (m_pGuestTablesContainer)
341 connect(m_pGuestTablesContainer, &QITabWidget::currentChanged, this,
342 &UIFileManager::sltCurrentTabChanged);
343
[92790]344 connect(&uiCommon(), &UICommon::sigAskToCommitData,
345 this, &UIFileManager::sltCommitDataSignalReceived);
[71133]346}
[71049]347
[76177]348void UIFileManager::prepareToolBar()
[75220]349{
350 /* Create toolbar: */
[86233]351 m_pToolBar = new QIToolBar(parentWidget());
[75220]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
[100888]359 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences));
[76177]360 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations));
361 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_T_Log));
[75220]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
[92733]377void UIFileManager::sltReceieveLogOutput(QString strOutput, const QString &strMachineName, FileManagerLogType eLogType)
[71234]378{
[92733]379 appendLog(strOutput, strMachineName, eLogType);
[71234]380}
381
[76177]382void UIFileManager::sltCopyGuestToHost()
[71276]383{
[75903]384 copyToHost();
[71276]385}
386
[76177]387void UIFileManager::sltCopyHostToGuest()
[71276]388{
[75903]389 copyToGuest();
[71276]390}
391
[76177]392void UIFileManager::sltPanelActionToggled(bool fChecked)
[75220]393{
394 QAction *pSenderAction = qobject_cast<QAction*>(sender());
395 if (!pSenderAction)
396 return;
[100905]397
398 m_pPanel->setVisible(fChecked);
399
400 if (fChecked)
[75220]401 {
[100905]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 }
[100906]412 m_pPanel->blockSignals(true);
[100905]413 m_pPanel->setCurrentIndex(pSenderAction->data().toInt());
[100906]414 m_pPanel->blockSignals(false);
[75220]415 }
[100905]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);
[75220]431}
432
[92917]433void UIFileManager::sltReceieveNewFileOperation(const CProgress &comProgress, const QString &strTableName)
434{
[100893]435 if (m_pPanel)
436 m_pPanel->addNewProgress(comProgress, strTableName);
[92917]437}
[75425]438
[76177]439void UIFileManager::sltFileOperationComplete(QUuid progressId)
[75610]440{
[75903]441 Q_UNUSED(progressId);
[92688]442 if (m_pHostFileTable)
443 m_pHostFileTable->refresh();
[92689]444 /// @todo we need to refresh only the table from which the completed file operation has originated
[92688]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 }
[75619]451}
452
[76950]453void UIFileManager::sltHandleHidePanel(UIDialogPanel *pPanel)
454{
455 hidePanel(pPanel);
456}
457
[97450]458void UIFileManager::sltHandleShowPanel(UIDialogPanel *pPanel)
459{
460 showPanel(pPanel);
461}
462
[92790]463void UIFileManager::sltCommitDataSignalReceived()
464{
465 m_fCommitDataSignalReceived = true;
466}
467
[92899]468void UIFileManager::sltFileTableSelectionChanged(bool fHasSelection)
469{
[92947]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
[92899]478 /* Enable/disable vertical toolbar actions: */
479 UIFileManagerGuestTable *pGuestTable = qobject_cast<UIFileManagerGuestTable*>(sender());
480
[92947]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
[92899]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
[92947]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();
[92979]500
501 /* Mark the current guest table: */
502 UIFileManagerGuestTable *pCurrentGuestTable = currentGuestTable();
[93180]503 if (!pCurrentGuestTable)
504 return;
[92979]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 }
[93476]512 /* Disable host file table if guest session is not running: */
[93180]513 if (m_pHostFileTable)
514 m_pHostFileTable->setEnabled(pCurrentGuestTable->isGuestSessionRunning());
[93476]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());
[92947]522}
523
[93180]524void UIFileManager::sltGuestFileTableStateChanged(bool fIsRunning)
525{
526 if (m_pHostFileTable)
527 m_pHostFileTable->setEnabled(fIsRunning);
528}
529
[100887]530void UIFileManager::sltHandleOptionsUpdated()
531{
532 if (m_pPanel)
[100890]533 m_pPanel->updatePreferences();
[100887]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
[100906]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
[101020]560 switch (static_cast<UIFileManagerPaneContainer::Page>(iIndex))
[100906]561 {
[101020]562 case UIFileManagerPaneContainer::Page_Preferences:
[100906]563 m_pActionPool->action(UIActionIndex_M_FileManager_T_Preferences)->setChecked(true);
564 break;
[101020]565 case UIFileManagerPaneContainer::Page_Operations:
[100906]566 m_pActionPool->action(UIActionIndex_M_FileManager_T_Operations)->setChecked(true);
567 break;
[101020]568 case UIFileManagerPaneContainer::Page_Log:
[100906]569 m_pActionPool->action(UIActionIndex_M_FileManager_T_Log)->setChecked(true);
570 break;
[101020]571 case UIFileManagerPaneContainer::Page_Max:
[100906]572 default:
573 break;
574 }
575}
576
[100955]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
[92947]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))
[92899]602 {
[92947]603 bool fHostHasSelection = m_pHostFileTable ? m_pHostFileTable->hasSelection() : false;
604 m_pActionPool->action(UIActionIndex_M_FileManager_S_CopyToGuest)->setEnabled(fRunning && fHostHasSelection);
[92899]605 }
606}
607
[76177]608void UIFileManager::copyToHost()
[75610]609{
[92688]610 if (m_pGuestTablesContainer && m_pHostFileTable)
611 {
[92947]612 UIFileManagerGuestTable *pGuestFileTable = currentGuestTable();
[92688]613 if (pGuestFileTable)
614 pGuestFileTable->copyGuestToHost(m_pHostFileTable->currentDirectoryPath());
615 }
[75610]616}
617
[76177]618void UIFileManager::copyToGuest()
[75610]619{
[92688]620 if (m_pGuestTablesContainer && m_pHostFileTable)
[92640]621 {
[92947]622 UIFileManagerGuestTable *pGuestFileTable = currentGuestTable();
[92688]623 if (pGuestFileTable)
624 pGuestFileTable->copyHostToGuest(m_pHostFileTable->selectedItemPathList());
[92640]625 }
[71133]626}
627
[71169]628template<typename T>
[76177]629QStringList UIFileManager::getFsObjInfoStringList(const T &fsObjectInfo) const
[71169]630{
631 QStringList objectInfo;
632 if (!fsObjectInfo.isOk())
633 return objectInfo;
634 objectInfo << fsObjectInfo.GetName();
635 return objectInfo;
636}
637
[76177]638void UIFileManager::saveOptions()
[71523]639{
[92790]640 if (m_fCommitDataSignalReceived)
641 return;
[75642]642 /* Save the options: */
[76177]643 UIFileManagerOptions *pOptions = UIFileManagerOptions::instance();
[75762]644 if (pOptions)
[75642]645 {
[76627]646 gEDataManager->setFileManagerOptions(pOptions->fListDirectoriesOnTop,
647 pOptions->fAskDeleteConfirmation,
648 pOptions->fShowHumanReadableSizes,
[78010]649 pOptions->fShowHiddenObjects);
[75642]650 }
[71523]651}
652
[76177]653void UIFileManager::restorePanelVisibility()
[71523]654{
[75948]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: */
[100893]657 // foreach(QAction* pAction, m_panelActionMap.values())
658 // {
659 // pAction->blockSignals(true);
660 // pAction->setChecked(false);
661 // pAction->blockSignals(false);
662 // }
[75224]663 /* Load the visible panel list and show them: */
[100893]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 // }
[75220]676}
677
[76177]678void UIFileManager::loadOptions()
[75642]679{
680 /* Load options: */
[76177]681 UIFileManagerOptions *pOptions = UIFileManagerOptions::instance();
[75762]682 if (pOptions)
[75642]683 {
[76627]684 pOptions->fListDirectoriesOnTop = gEDataManager->fileManagerListDirectoriesFirst();
685 pOptions->fAskDeleteConfirmation = gEDataManager->fileManagerShowDeleteConfirmation();
686 pOptions->fShowHumanReadableSizes = gEDataManager->fileManagerShowHumanReadableSizes();
687 pOptions->fShowHiddenObjects = gEDataManager->fileManagerShowHiddenObjects();
[75642]688 }
689}
690
[76950]691void UIFileManager::hidePanel(UIDialogPanel* panel)
[75220]692{
[100893]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();
[75220]707}
708
[76950]709void UIFileManager::showPanel(UIDialogPanel* panel)
[75220]710{
[100893]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();
[75220]724}
725
[76177]726void UIFileManager::manageEscapeShortCut()
[75220]727{
728 /* if there is no visible panels give the escape shortcut to parent dialog: */
[100893]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());
[92645]740
[100893]741 // m_visiblePanelsList.back()->setCloseButtonShortCut(QKeySequence(Qt::Key_Escape));
[75220]742}
743
[92733]744void UIFileManager::appendLog(const QString &strLog, const QString &strMachineName, FileManagerLogType eLogType)
[75220]745{
[100890]746 if (m_pPanel)
747 m_pPanel->appendLog(strLog, strMachineName, eLogType);
[71523]748}
749
[89111]750void UIFileManager::savePanelVisibility()
751{
[92790]752 if (m_fCommitDataSignalReceived)
753 return;
[100893]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);
[89111]759}
760
[92688]761void UIFileManager::setSelectedVMListItems(const QList<UIVirtualMachineItem*> &items)
[92632]762{
[92947]763 AssertReturnVoid(m_pGuestTablesContainer);
[92688]764 QVector<QUuid> selectedMachines;
765
766 foreach (const UIVirtualMachineItem *item, items)
767 {
768 if (!item)
769 continue;
770 selectedMachines << item->id();
771 }
[92979]772 QUuid lastSelection = selectedMachines.isEmpty() ? QUuid() : selectedMachines.last();
[92947]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
[92979]784 setMachines(selectedMachines, lastSelection);
[92632]785}
786
[92979]787void UIFileManager::setMachines(const QVector<QUuid> &machineIds, const QUuid &lastSelectedMachineId /* = QUuid() */)
[92688]788{
[92947]789 AssertReturnVoid(m_pGuestTablesContainer);
790
[92688]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);
[92979]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 }
[92688]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));
[92947]830 if (!pTable)
[92688]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 {
[103771]848 CMachine comMachine = gpGlobalSession->virtualBox().FindMachine(id.toString());
[92688]849 if (comMachine.isNull())
850 continue;
[92790]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);
[92899]857 connect(pGuestFileTable, &UIFileManagerGuestTable::sigSelectionChanged,
858 this, &UIFileManager::sltFileTableSelectionChanged);
[92917]859 connect(pGuestFileTable, &UIFileManagerGuestTable::sigNewFileOperation,
860 this, &UIFileManager::sltReceieveNewFileOperation);
[93180]861 connect(pGuestFileTable, &UIFileManagerGuestTable::sigStateChanged,
862 this, &UIFileManager::sltGuestFileTableStateChanged);
[100887]863 connect(pGuestFileTable, &UIFileManagerGuestTable::sigDeleteConfirmationOptionChanged,
864 this, &UIFileManager::sltHandleOptionsUpdated);
[92790]865 }
[92688]866 }
867}
868
[92947]869UIFileManagerGuestTable *UIFileManager::currentGuestTable()
870{
871 if (!m_pGuestTablesContainer)
872 return 0;
873 return qobject_cast<UIFileManagerGuestTable*>(m_pGuestTablesContainer->currentWidget());
874}
[76177]875#include "UIFileManager.moc"
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use