VirtualBox

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

Last change on this file since 104229 was 104229, checked in by vboxsync, 6 months ago

FE/Qt. bugref:10622. scm fix.

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