VirtualBox

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

Last change on this file since 102493 was 101020, checked in by vboxsync, 13 months ago

FE/Qt: bugref:10496, bugref:6699. Some refactoring.

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