VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerHostTable.cpp@ 103977

Last change on this file since 103977 was 102515, checked in by vboxsync, 12 months ago

FE/Qt: ​bugref:9080, bugref:10141. Fixing host browser's menu entries.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.0 KB
Line 
1/* $Id: UIFileManagerHostTable.cpp 102515 2023-12-07 09:08:14Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIFileManagerHostTable 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 <QAction>
30#include <QDateTime>
31#include <QDir>
32
33/* GUI includes: */
34#include "QILabel.h"
35#include "UIActionPool.h"
36#include "UICommon.h"
37#include "UIFileManager.h"
38#include "UIFileTableNavigationWidget.h"
39#include "UIFileSystemModel.h"
40#include "UIFileManagerHostTable.h"
41#include "UIPathOperations.h"
42#include "QIToolBar.h"
43
44
45/*********************************************************************************************************************************
46* UIHostDirectoryDiskUsageComputer definition. *
47*********************************************************************************************************************************/
48
49/** Open directories recursively and sum the disk usage. Don't block the GUI thread while doing this */
50class UIHostDirectoryDiskUsageComputer : public UIDirectoryDiskUsageComputer
51{
52 Q_OBJECT;
53
54public:
55
56 UIHostDirectoryDiskUsageComputer(QObject *parent, QStringList strStartPath);
57
58protected:
59
60 virtual void directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics) RT_OVERRIDE;
61};
62
63
64/*********************************************************************************************************************************
65* UIHostDirectoryDiskUsageComputer implementation. *
66*********************************************************************************************************************************/
67
68UIHostDirectoryDiskUsageComputer::UIHostDirectoryDiskUsageComputer(QObject *parent, QStringList pathList)
69 :UIDirectoryDiskUsageComputer(parent, pathList)
70{
71}
72
73void UIHostDirectoryDiskUsageComputer::directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics)
74{
75 /* Prevent modification of the continue flag while reading: */
76 m_mutex.lock();
77 /* Check if m_fOkToContinue is set to false. if so just end recursion: */
78 if (!isOkToContinue())
79 {
80 m_mutex.unlock();
81 return;
82 }
83 m_mutex.unlock();
84
85 QFileInfo fileInfo(path);
86 if (!fileInfo.exists())
87 return;
88 /* if the object is a file or a symlink then read the size and return: */
89 if (fileInfo.isFile())
90 {
91 statistics.m_totalSize += fileInfo.size();
92 ++statistics.m_uFileCount;
93 sigResultUpdated(statistics);
94 return;
95 }
96 else if (fileInfo.isSymLink())
97 {
98 statistics.m_totalSize += fileInfo.size();
99 ++statistics.m_uSymlinkCount;
100 sigResultUpdated(statistics);
101 return;
102 }
103
104 /* if it is a directory then read the content: */
105 QDir dir(path);
106 if (!dir.exists())
107 return;
108
109 QFileInfoList entryList = dir.entryInfoList();
110 for (int i = 0; i < entryList.size(); ++i)
111 {
112 const QFileInfo &entryInfo = entryList.at(i);
113 if (entryInfo.baseName().isEmpty() || entryInfo.baseName() == "." ||
114 entryInfo.baseName() == UIFileSystemModel::strUpDirectoryString)
115 continue;
116 statistics.m_totalSize += entryInfo.size();
117 if (entryInfo.isSymLink())
118 statistics.m_uSymlinkCount++;
119 else if(entryInfo.isFile())
120 statistics.m_uFileCount++;
121 else if (entryInfo.isDir())
122 {
123 statistics.m_uDirectoryCount++;
124 directoryStatisticsRecursive(entryInfo.absoluteFilePath(), statistics);
125 }
126 }
127 sigResultUpdated(statistics);
128}
129
130
131/*********************************************************************************************************************************
132* UIFileManagerHostTable implementation. *
133*********************************************************************************************************************************/
134
135UIFileManagerHostTable::UIFileManagerHostTable(UIActionPool *pActionPool, QWidget *pParent /* = 0 */)
136 :UIFileManagerTable(pActionPool, pParent)
137 , m_pModifierActionSeparator(0)
138{
139 setModelFileSystem(isWindowsFileSystem());
140 initializeFileTree();
141 prepareToolbar();
142 prepareActionConnections();
143 determinePathSeparator();
144 retranslateUi();
145}
146
147/* static */ bool UIFileManagerHostTable::scanDirectory(const QString& strPath, UIFileSystemItem *parent,
148 QMap<QString, UIFileSystemItem*> &fileObjects)
149{
150
151 QDir directory(UIPathOperations::addTrailingDelimiters(strPath));
152 /* For some reason when this filter is applied, folder content QDir::entryInfoList()
153 returns an empty list: */
154 /*directory.setFilter(QDir::NoDotAndDotDot);*/
155 if (!directory.exists() || !directory.isReadable())
156 return false;
157 QFileInfoList entries = directory.entryInfoList(QDir::Hidden|QDir::AllEntries|QDir::NoDotAndDotDot);
158
159 parent->setIsOpened(true);
160 for (int i = 0; i < entries.size(); ++i)
161 {
162 const QFileInfo &fileInfo = entries.at(i);
163 UIFileSystemItem *item = new UIFileSystemItem(fileInfo.fileName(), parent, fileType(fileInfo));
164 if (!item)
165 continue;
166
167 item->setData(fileInfo.size(), UIFileSystemModelData_Size);
168 item->setData(fileInfo.lastModified(), UIFileSystemModelData_ChangeTime);
169 item->setData(fileInfo.owner(), UIFileSystemModelData_Owner);
170 item->setData(permissionString(fileInfo.permissions()), UIFileSystemModelData_Permissions);
171
172 /* if the item is a symlink set the target path and
173 check the target if it is a directory: */
174 if (fileInfo.isSymLink()) /** @todo No symlinks here on windows, while fsObjectPropertyString() does see them. RTDirReadEx works wrt symlinks, btw. */
175 {
176 item->setTargetPath(fileInfo.symLinkTarget());
177 item->setIsSymLinkToADirectory(QFileInfo(fileInfo.symLinkTarget()).isDir());
178 }
179 item->setIsHidden(fileInfo.isHidden());
180 fileObjects.insert(fileInfo.fileName(), item);
181 item->setIsOpened(false);
182 }
183 return true;
184}
185
186void UIFileManagerHostTable::retranslateUi()
187{
188 if (m_pLocationLabel)
189 m_pLocationLabel->setText(UIFileManager::tr("Host File System:"));
190 m_strTableName = UIFileManager::tr("Host");
191 UIFileManagerTable::retranslateUi();
192}
193
194void UIFileManagerHostTable::prepareToolbar()
195{
196 if (m_pToolBar && m_pActionPool)
197 {
198 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoBackward));
199 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoForward));
200 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoUp));
201 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoHome));
202 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Refresh));
203
204 m_pModifierActionSeparator = m_pToolBar->addSeparator();
205 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Delete));
206 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Rename));
207 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_CreateNewDirectory));
208
209 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Copy));
210 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Cut));
211 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Paste));
212 m_pToolBar->addSeparator();
213 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_SelectAll));
214 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_InvertSelection));
215 m_pToolBar->addSeparator();
216 m_pToolBar->addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_ShowProperties));
217
218 m_selectionDependentActions.insert(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Delete));
219 m_selectionDependentActions.insert(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Rename));
220 m_selectionDependentActions.insert(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_ShowProperties));
221
222 /* Hide cut, copy, and paste for now. We will implement those
223 when we have an API for host file operations: */
224 m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Copy)->setVisible(false);
225 m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Cut)->setVisible(false);
226 m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Paste)->setVisible(false);
227 }
228 setSelectionDependentActionsEnabled(false);
229}
230
231void UIFileManagerHostTable::createFileViewContextMenu(const QWidget *pWidget, const QPoint &point)
232{
233 if (!pWidget)
234 return;
235
236 QMenu menu;
237 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoUp));
238
239 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoHome));
240 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Refresh));
241 menu.addSeparator();
242 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Delete));
243 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Rename));
244 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_CreateNewDirectory));
245 // menu.addSeparator();
246 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Copy));
247 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Cut));
248 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Paste));
249 menu.addSeparator();
250 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_SelectAll));
251 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_InvertSelection));
252 menu.addSeparator();
253 menu.addAction(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_ShowProperties));
254 menu.exec(pWidget->mapToGlobal(point));
255}
256
257void UIFileManagerHostTable::toggleForwardBackwardActions()
258{
259 if (!m_pNavigationWidget)
260 return;
261 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoForward))
262 m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoForward)->setEnabled(m_pNavigationWidget->canGoForward());
263 if (m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoBackward))
264 m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoBackward)->setEnabled(m_pNavigationWidget->canGoBackward());
265}
266
267bool UIFileManagerHostTable::isWindowsFileSystem() const
268{
269 return uiCommon().hostOperatingSystem().contains("windows", Qt::CaseInsensitive);
270}
271
272bool UIFileManagerHostTable::readDirectory(const QString& strPath, UIFileSystemItem *parent, bool isStartDir /*= false*/)
273{
274 if (!parent)
275 return false;
276
277 QMap<QString, UIFileSystemItem*> fileObjects;
278 if (!scanDirectory(strPath, parent, fileObjects))
279 return false;
280 checkDotDot(fileObjects, parent, isStartDir);
281 return true;
282}
283
284void UIFileManagerHostTable::deleteByItem(UIFileSystemItem *item)
285{
286 if (item->isUpDirectory())
287 return;
288 if (!item->isDirectory())
289 {
290 QDir itemToDelete;
291 itemToDelete.remove(UIPathOperations::removeTrailingDelimiters(item->path()));
292 }
293 QDir itemToDelete(item->path());
294 itemToDelete.setFilter(QDir::NoDotAndDotDot);
295 /* Try to delete item recursively (in case of directories).
296 note that this is no good way of deleting big directory
297 trees. We need a better error reporting and a kind of progress
298 indicator: */
299 /** @todo replace this recursive delete by a better implementation: */
300 bool deleteSuccess = itemToDelete.removeRecursively();
301
302 if (!deleteSuccess)
303 emit sigLogOutput(QString(item->path()).append(" could not be deleted"), m_strTableName, FileManagerLogType_Error);
304}
305
306void UIFileManagerHostTable::goToHomeDirectory()
307{
308 if (!rootItem() || rootItem()->childCount() <= 0)
309 return;
310 UIFileSystemItem *startDirItem = rootItem()->child(0);
311 if (!startDirItem)
312 return;
313
314 QString userHome = UIPathOperations::sanitize(QDir::homePath());
315 goIntoDirectory(UIPathOperations::pathTrail(userHome));
316}
317
318bool UIFileManagerHostTable::renameItem(UIFileSystemItem *item, const QString &strOldPath)
319{
320 if (!item || item->isUpDirectory())
321 return false;
322 QDir tempDir;
323 if (tempDir.rename(strOldPath, item->path()))
324 return true;
325
326 return false;
327}
328
329bool UIFileManagerHostTable::createDirectory(const QString &path, const QString &directoryName)
330{
331 QDir parentDir(path);
332 if (!parentDir.mkdir(directoryName))
333 {
334 emit sigLogOutput(UIPathOperations::mergePaths(path, directoryName).append(" could not be created"), m_strTableName, FileManagerLogType_Error);
335 return false;
336 }
337
338 return true;
339}
340
341/* static */
342KFsObjType UIFileManagerHostTable::fileType(const QFileInfo &fsInfo)
343{
344 if (!fsInfo.exists())
345 return KFsObjType_Unknown;
346 /* first check if it is symlink becacuse for Qt
347 being smylin and directory/file is not mutually exclusive: */
348 if (fsInfo.isSymLink())
349 return KFsObjType_Symlink;
350 else if (fsInfo.isFile())
351 return KFsObjType_File;
352 else if (fsInfo.isDir())
353 return KFsObjType_Directory;
354 return KFsObjType_Unknown;
355}
356
357/* static */
358KFsObjType UIFileManagerHostTable::fileType(const QString &strPath)
359{
360 return fileType(QFileInfo(strPath));
361}
362
363QString UIFileManagerHostTable::fsObjectPropertyString()
364{
365 QStringList selectedObjects = selectedItemPathList();
366 if (selectedObjects.isEmpty())
367 return QString();
368 if (selectedObjects.size() == 1)
369 {
370 if (selectedObjects.at(0).isNull())
371 return QString();
372 QFileInfo fileInfo(selectedObjects.at(0));
373 if (!fileInfo.exists())
374 return QString();
375 QStringList propertyStringList;
376 /* Name: */
377 propertyStringList << UIFileManager::tr("<b>Name:</b> %1<br/>").arg(fileInfo.fileName());
378 /* Size: */
379 propertyStringList << UIFileManager::tr("<b>Size:</b> %1 bytes").arg(QString::number(fileInfo.size()));
380 if (fileInfo.size() >= m_iKiloByte)
381 propertyStringList << QString(" (%1)").arg(humanReadableSize(fileInfo.size()));
382 propertyStringList << "<br/>";
383 /* Type: */
384 propertyStringList << UIFileManager::tr("<b>Type:</b> %1<br/>").arg(fileTypeString(fileType(fileInfo)));
385 /* Creation Date: */
386#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
387 propertyStringList << UIFileManager::tr("<b>Created:</b> %1<br/>").arg(fileInfo.birthTime().toString());
388#else
389 propertyStringList << UIFileManager::tr("<b>Created:</b> %1<br/>").arg(fileInfo.created().toString());
390#endif
391 /* Last Modification Date: */
392 propertyStringList << UIFileManager::tr("<b>Modified:</b> %1<br/>").arg(fileInfo.lastModified().toString());
393 /* Owner: */
394 propertyStringList << UIFileManager::tr("<b>Owner:</b> %1").arg(fileInfo.owner());
395
396 return propertyStringList.join(QString());
397 }
398
399 int fileCount = 0;
400 int directoryCount = 0;
401 ULONG64 totalSize = 0;
402
403 for(int i = 0; i < selectedObjects.size(); ++i)
404 {
405 QFileInfo fileInfo(selectedObjects.at(i));
406 if (!fileInfo.exists())
407 continue;
408 if (fileInfo.isFile())
409 ++fileCount;
410 if (fileInfo.isDir())
411 ++directoryCount;
412 totalSize += fileInfo.size();
413 }
414 QStringList propertyStringList;
415 propertyStringList << UIFileManager::tr("<b>Selected:</b> %1 files and %2 directories<br/>").
416 arg(QString::number(fileCount)).arg(QString::number(directoryCount));
417 propertyStringList << UIFileManager::tr("<b>Size:</b> %1 bytes").arg(QString::number(totalSize));
418 if (totalSize >= m_iKiloByte)
419 propertyStringList << QString(" (%1)").arg(humanReadableSize(totalSize));
420
421 return propertyStringList.join(QString());
422}
423
424void UIFileManagerHostTable::showProperties()
425{
426 qRegisterMetaType<UIDirectoryStatistics>();
427 QString fsPropertyString = fsObjectPropertyString();
428 if (fsPropertyString.isEmpty())
429 return;
430 if (!m_pPropertiesDialog)
431 m_pPropertiesDialog = new UIPropertiesDialog(this);
432 if (!m_pPropertiesDialog)
433 return;
434
435 UIHostDirectoryDiskUsageComputer *directoryThread = 0;
436
437 QStringList selectedObjects = selectedItemPathList();
438 if ((selectedObjects.size() == 1 && QFileInfo(selectedObjects.at(0)).isDir())
439 || selectedObjects.size() > 1)
440 {
441 directoryThread = new UIHostDirectoryDiskUsageComputer(this, selectedObjects);
442 if (directoryThread)
443 {
444 connect(directoryThread, &UIHostDirectoryDiskUsageComputer::sigResultUpdated,
445 this, &UIFileManagerHostTable::sltReceiveDirectoryStatistics/*, Qt::DirectConnection*/);
446 directoryThread->start();
447 }
448 }
449 m_pPropertiesDialog->setWindowTitle("Properties");
450 m_pPropertiesDialog->setPropertyText(fsPropertyString);
451 m_pPropertiesDialog->execute();
452 if (directoryThread)
453 {
454 if (directoryThread->isRunning())
455 directoryThread->stopRecursion();
456 disconnect(directoryThread, &UIHostDirectoryDiskUsageComputer::sigResultUpdated,
457 this, &UIFileManagerHostTable::sltReceiveDirectoryStatistics/*, Qt::DirectConnection*/);
458 directoryThread->wait();
459 }
460}
461
462void UIFileManagerHostTable::determineDriveLetters()
463{
464 QFileInfoList drive = QDir::drives();
465 m_driveLetterList.clear();
466 for (int i = 0; i < drive.size(); ++i)
467 {
468 if (UIPathOperations::doesPathStartWithDriveLetter(drive[i].filePath()))
469 m_driveLetterList.push_back(drive[i].filePath());
470 }
471}
472
473void UIFileManagerHostTable::determinePathSeparator()
474{
475 setPathSeparator(QDir::separator());
476}
477
478/* static */QString UIFileManagerHostTable::permissionString(QFileDevice::Permissions permissions)
479{
480 QString strPermissions;
481 if (permissions & QFileDevice::ReadOwner)
482 strPermissions += 'r';
483 else
484 strPermissions += '-';
485
486 if (permissions & QFileDevice::WriteOwner)
487 strPermissions += 'w';
488 else
489 strPermissions += '-';
490
491 if (permissions & QFileDevice::ExeOwner)
492 strPermissions += 'x';
493 else
494 strPermissions += '-';
495
496 if (permissions & QFileDevice::ReadGroup)
497 strPermissions += 'r';
498 else
499 strPermissions += '-';
500
501 if (permissions & QFileDevice::WriteGroup)
502 strPermissions += 'w';
503 else
504 strPermissions += '-';
505
506 if (permissions & QFileDevice::ExeGroup)
507 strPermissions += 'x';
508 else
509 strPermissions += '-';
510
511 if (permissions & QFileDevice::ReadOther)
512 strPermissions += 'r';
513 else
514 strPermissions += '-';
515
516 if (permissions & QFileDevice::WriteOther)
517 strPermissions += 'w';
518 else
519 strPermissions += '-';
520
521 if (permissions & QFileDevice::ExeOther)
522 strPermissions += 'x';
523 else
524 strPermissions += '-';
525 return strPermissions;
526}
527
528void UIFileManagerHostTable::prepareActionConnections()
529{
530 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoUp), &QAction::triggered,
531 this, &UIFileManagerTable::sltGoUp);
532 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoHome), &QAction::triggered,
533 this, &UIFileManagerTable::sltGoHome);
534 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoForward), &QAction::triggered,
535 this, &UIFileManagerTable::sltGoForward);
536 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_GoBackward), &QAction::triggered,
537 this, &UIFileManagerTable::sltGoBackward);
538 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Refresh), &QAction::triggered,
539 this, &UIFileManagerTable::sltRefresh);
540 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Delete), &QAction::triggered,
541 this, &UIFileManagerTable::sltDelete);
542 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Rename), &QAction::triggered,
543 this, &UIFileManagerTable::sltRename);
544 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Copy), &QAction::triggered,
545 this, &UIFileManagerTable::sltCopy);
546 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Cut), &QAction::triggered,
547 this, &UIFileManagerTable::sltCut);
548 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_Paste), &QAction::triggered,
549 this, &UIFileManagerTable::sltPaste);
550 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_SelectAll), &QAction::triggered,
551 this, &UIFileManagerTable::sltSelectAll);
552 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_InvertSelection), &QAction::triggered,
553 this, &UIFileManagerTable::sltInvertSelection);
554 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_ShowProperties), &QAction::triggered,
555 this, &UIFileManagerTable::sltShowProperties);
556 connect(m_pActionPool->action(UIActionIndex_M_FileManager_S_Host_CreateNewDirectory), &QAction::triggered,
557 this, &UIFileManagerTable::sltCreateNewDirectory);
558}
559
560#include "UIFileManagerHostTable.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