VirtualBox

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

Last change on this file since 103982 was 103771, checked in by vboxsync, 9 months ago

FE/Qt: UICommon: Switching dependency from UICommon to UIGlobalSession whenever is possible.

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