1 | /* $Id: UIFileManagerTable.h 102507 2023-12-06 15:39:31Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VBox Qt GUI - UIFileManagerTable class declaration.
|
---|
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 | #ifndef FEQT_INCLUDED_SRC_guestctrl_UIFileManagerTable_h
|
---|
29 | #define FEQT_INCLUDED_SRC_guestctrl_UIFileManagerTable_h
|
---|
30 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
31 | # pragma once
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | /* Qt includes: */
|
---|
35 | #include <QItemSelectionModel>
|
---|
36 | #include <QMutex>
|
---|
37 | #include <QThread>
|
---|
38 | #include <QWidget>
|
---|
39 |
|
---|
40 | /* COM includes: */
|
---|
41 | #include "COMEnums.h"
|
---|
42 | #include "CGuestSession.h"
|
---|
43 |
|
---|
44 | /* GUI includes: */
|
---|
45 | #include "QIDialog.h"
|
---|
46 | #include "QITableView.h"
|
---|
47 | #include "QIWithRetranslateUI.h"
|
---|
48 | #include "UIGuestControlDefs.h"
|
---|
49 |
|
---|
50 | /* Forward declarations: */
|
---|
51 | class QAction;
|
---|
52 | class QFileInfo;
|
---|
53 | class QILabel;
|
---|
54 | class QILineEdit;
|
---|
55 | class QGridLayout;
|
---|
56 | class QSortFilterProxyModel;
|
---|
57 | class QTextEdit;
|
---|
58 | class QHBoxLayout;
|
---|
59 | class QVBoxLayout;
|
---|
60 | class UIActionPool;
|
---|
61 | class UIFileSystemItem;
|
---|
62 | class UIFileSystemModel;
|
---|
63 | class UIFileSystemProxyModel;
|
---|
64 | class UIFileTableNavigationWidget;
|
---|
65 | class UIGuestControlFileView;
|
---|
66 | class QIToolBar;
|
---|
67 |
|
---|
68 | /** A simple struck to store some statictics for a directory. Mainly used by UIDirectoryDiskUsageComputer instances. */
|
---|
69 | class UIDirectoryStatistics
|
---|
70 | {
|
---|
71 | public:
|
---|
72 | UIDirectoryStatistics();
|
---|
73 | ULONG64 m_totalSize;
|
---|
74 | unsigned m_uFileCount;
|
---|
75 | unsigned m_uDirectoryCount;
|
---|
76 | unsigned m_uSymlinkCount;
|
---|
77 | };
|
---|
78 |
|
---|
79 | Q_DECLARE_METATYPE(UIDirectoryStatistics);
|
---|
80 |
|
---|
81 |
|
---|
82 | /** Examines the paths in @p strStartPath and collects some staticstics from them recursively (in case directories)
|
---|
83 | * Runs on a worker thread to avoid GUI freezes. UIGuestFileTable and UIHostFileTable uses specialized children
|
---|
84 | * of this class since the calls made on file objects are different. */
|
---|
85 | class UIDirectoryDiskUsageComputer : public QThread
|
---|
86 | {
|
---|
87 | Q_OBJECT;
|
---|
88 |
|
---|
89 | signals:
|
---|
90 |
|
---|
91 | void sigResultUpdated(UIDirectoryStatistics);
|
---|
92 |
|
---|
93 | public:
|
---|
94 |
|
---|
95 | UIDirectoryDiskUsageComputer(QObject *parent, QStringList strStartPath);
|
---|
96 | /** Sets the m_fOkToContinue to false. This results an early termination
|
---|
97 | * of the directoryStatisticsRecursive member function. */
|
---|
98 | void stopRecursion();
|
---|
99 |
|
---|
100 | protected:
|
---|
101 |
|
---|
102 | /** Read the directory with the path @p path recursively and collect #of objects and total size */
|
---|
103 | virtual void directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics) = 0;
|
---|
104 | virtual void run() RT_OVERRIDE;
|
---|
105 | /** Returns the m_fOkToContinue flag */
|
---|
106 | bool isOkToContinue() const;
|
---|
107 |
|
---|
108 | /** Stores a list of paths whose statistics are accumulated, can be file, directory etc: */
|
---|
109 | QStringList m_pathList;
|
---|
110 | UIDirectoryStatistics m_resultStatistics;
|
---|
111 | QMutex m_mutex;
|
---|
112 |
|
---|
113 | private:
|
---|
114 |
|
---|
115 | bool m_fOkToContinue;
|
---|
116 | };
|
---|
117 |
|
---|
118 | /** A QIDialog child to display properties of a file object */
|
---|
119 | class UIPropertiesDialog : public QIDialog
|
---|
120 | {
|
---|
121 |
|
---|
122 | Q_OBJECT;
|
---|
123 |
|
---|
124 | public:
|
---|
125 |
|
---|
126 | UIPropertiesDialog(QWidget *pParent = 0, Qt::WindowFlags enmFlags = Qt::WindowFlags());
|
---|
127 | void setPropertyText(const QString &strProperty);
|
---|
128 | void addDirectoryStatistics(UIDirectoryStatistics statictics);
|
---|
129 |
|
---|
130 | private:
|
---|
131 |
|
---|
132 | QVBoxLayout *m_pMainLayout;
|
---|
133 | QTextEdit *m_pInfoEdit;
|
---|
134 | QString m_strProperty;
|
---|
135 | };
|
---|
136 |
|
---|
137 | /** This class serves a base class for file table. Currently a guest version
|
---|
138 | * and a host version are derived from this base. Each of these children
|
---|
139 | * populates the UIFileSystemModel by scanning the file system
|
---|
140 | * differently. The file structure kept in this class as a tree. */
|
---|
141 | class UIFileManagerTable : public QIWithRetranslateUI<QWidget>
|
---|
142 | {
|
---|
143 | Q_OBJECT;
|
---|
144 |
|
---|
145 | signals:
|
---|
146 |
|
---|
147 | void sigLogOutput(QString strLog, const QString &strMachineName, FileManagerLogType eLogType);
|
---|
148 | void sigDeleteConfirmationOptionChanged();
|
---|
149 | void sigSelectionChanged(bool fHasSelection);
|
---|
150 |
|
---|
151 | public:
|
---|
152 |
|
---|
153 | UIFileManagerTable(UIActionPool *pActionPool, QWidget *pParent = 0);
|
---|
154 | virtual ~UIFileManagerTable();
|
---|
155 | /** Deletes all the tree nodes */
|
---|
156 | void reset();
|
---|
157 | /** Returns the path of the rootIndex */
|
---|
158 | QString currentDirectoryPath() const;
|
---|
159 | /** Returns the paths of the selected items (if any) as a list */
|
---|
160 | QStringList selectedItemPathList();
|
---|
161 | virtual void refresh();
|
---|
162 | static const unsigned m_iKiloByte;
|
---|
163 | static QString humanReadableSize(ULONG64 size);
|
---|
164 | /** Peroforms whatever is necessary after a UIFileManagerOptions change. */
|
---|
165 | void optionsUpdated();
|
---|
166 | bool hasSelection() const;
|
---|
167 | void setDragDropMode(QAbstractItemView::DragDropMode behavior);
|
---|
168 | virtual bool isWindowsFileSystem() const = 0;
|
---|
169 |
|
---|
170 | public slots:
|
---|
171 |
|
---|
172 | void sltReceiveDirectoryStatistics(UIDirectoryStatistics statictics);
|
---|
173 | void sltCreateNewDirectory();
|
---|
174 | /* index is passed by the item view and represents the double clicked object's 'proxy' model index */
|
---|
175 | void sltItemDoubleClicked(const QModelIndex &index);
|
---|
176 | void sltItemClicked(const QModelIndex &index);
|
---|
177 | void sltGoUp();
|
---|
178 | void sltGoHome();
|
---|
179 | void sltGoForward();
|
---|
180 | void sltGoBackward();
|
---|
181 | void sltRefresh();
|
---|
182 | void sltDelete();
|
---|
183 | /** Calls the edit on the data item over m_pView. This causes setData(..) call on the model. After setting
|
---|
184 | * user entered text as the name of the item m_pModel signals. This signal is handled by sltHandleItemRenameAttempt which
|
---|
185 | * tries to rename the corresponding file object by calling renameItem(...). If this rename fails the old name of the
|
---|
186 | * model item is restored and view is refreshed by sltHandleItemRenameAttempt. */
|
---|
187 | void sltRename();
|
---|
188 | void sltCopy();
|
---|
189 | void sltCut();
|
---|
190 | void sltPaste();
|
---|
191 | void sltShowProperties();
|
---|
192 | void sltSelectAll();
|
---|
193 | void sltInvertSelection();
|
---|
194 |
|
---|
195 | protected:
|
---|
196 |
|
---|
197 | /** This enum is used when performing a gueest-to-guest or host-to-host
|
---|
198 | * file operations. Paths of source file objects are kept in a single buffer
|
---|
199 | * and a flag to determine if it is a cut or copy operation is needed */
|
---|
200 | enum FileOperationType
|
---|
201 | {
|
---|
202 | FileOperationType_Copy,
|
---|
203 | FileOperationType_Cut,
|
---|
204 | FileOperationType_None,
|
---|
205 | FileOperationType_Max
|
---|
206 | };
|
---|
207 |
|
---|
208 | void retranslateUi();
|
---|
209 | void updateCurrentLocationEdit(const QString& strLocation);
|
---|
210 | /* @p index is for model not for 'proxy' model */
|
---|
211 | void changeLocation(const QModelIndex &index);
|
---|
212 | void initializeFileTree();
|
---|
213 | void checkDotDot(QMap<QString,UIFileSystemItem*> &map, UIFileSystemItem *parent, bool isStartDir);
|
---|
214 |
|
---|
215 | virtual bool readDirectory(const QString& strPath, UIFileSystemItem *parent, bool isStartDir = false) = 0;
|
---|
216 | virtual void deleteByItem(UIFileSystemItem *item) = 0;
|
---|
217 | virtual void goToHomeDirectory() = 0;
|
---|
218 | virtual bool renameItem(UIFileSystemItem *item, const QString &strOldPath) = 0;
|
---|
219 | virtual bool createDirectory(const QString &path, const QString &directoryName) = 0;
|
---|
220 | virtual QString fsObjectPropertyString() = 0;
|
---|
221 | virtual void showProperties() = 0;
|
---|
222 | /** For non-windows system does nothing and for windows systems populates m_driveLetterList with
|
---|
223 | * drive letters */
|
---|
224 | virtual void determineDriveLetters() = 0;
|
---|
225 | virtual void determinePathSeparator() = 0;
|
---|
226 | virtual void prepareToolbar() = 0;
|
---|
227 | virtual void createFileViewContextMenu(const QWidget *pWidget, const QPoint &point) = 0;
|
---|
228 | virtual void toggleForwardBackwardActions() = 0;
|
---|
229 | virtual bool event(QEvent *pEvent) RT_OVERRIDE;
|
---|
230 |
|
---|
231 | /** @name Copy/Cut guest-to-guest (host-to-host) stuff.
|
---|
232 | * @{ */
|
---|
233 | /** Disable/enable paste action depending on the m_eFileOperationType. */
|
---|
234 | virtual void setPasteActionEnabled(bool fEnabled) = 0;
|
---|
235 | virtual void pasteCutCopiedObjects() = 0;
|
---|
236 | /** stores the type of the pending guest-to-guest (host-to-host) file operation. */
|
---|
237 | FileOperationType m_eFileOperationType;
|
---|
238 | /** @} */
|
---|
239 |
|
---|
240 | QString fileTypeString(KFsObjType type);
|
---|
241 | /* @p item index is item location in model not in 'proxy' model */
|
---|
242 | void goIntoDirectory(const QModelIndex &itemIndex);
|
---|
243 | /** Follows the path trail, opens directories as it descends */
|
---|
244 | void goIntoDirectory(const QStringList &pathTrail);
|
---|
245 | /** Goes into directory pointed by the @p item */
|
---|
246 | void goIntoDirectory(UIFileSystemItem *item);
|
---|
247 | UIFileSystemItem* indexData(const QModelIndex &index) const;
|
---|
248 | bool eventFilter(QObject *pObject, QEvent *pEvent) RT_OVERRIDE;
|
---|
249 | CGuestFsObjInfo guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const;
|
---|
250 | void setSelectionDependentActionsEnabled(bool fIsEnabled);
|
---|
251 | UIFileSystemItem* rootItem();
|
---|
252 | void setPathSeparator(const QChar &separator);
|
---|
253 | QHBoxLayout* toolBarLayout();
|
---|
254 | void setSessionWidgetsEnabled(bool fEnabled);
|
---|
255 | void setModelFileSystem(bool fIsWindowsFileSystem);
|
---|
256 |
|
---|
257 | QILabel *m_pLocationLabel;
|
---|
258 | UIPropertiesDialog *m_pPropertiesDialog;
|
---|
259 | UIActionPool *m_pActionPool;
|
---|
260 | QIToolBar *m_pToolBar;
|
---|
261 | QGridLayout *m_pMainLayout;
|
---|
262 | /** Stores the drive letters the file system has (for windows system). For non-windows
|
---|
263 | * systems this is empty and for windows system it should at least contain C:/ */
|
---|
264 | QStringList m_driveLetterList;
|
---|
265 | /** The set of actions which need some selection to work on. Like cut, copy etc. */
|
---|
266 | QSet<QAction*> m_selectionDependentActions;
|
---|
267 | /** The absolute path list of the file objects which user has chosen to cut/copy. this
|
---|
268 | * list will be cleaned after a paste operation or overwritten by a subsequent cut/copy.
|
---|
269 | * Currently only used by the guest side. */
|
---|
270 | QStringList m_copyCutBuffer;
|
---|
271 | /** This name is appended to the log messages which are shown in the log panel. */
|
---|
272 | QString m_strTableName;
|
---|
273 | /** Contains m_pBreadCrumbsWidget and m_pLocationComboBox. */
|
---|
274 | UIFileTableNavigationWidget *m_pNavigationWidget;
|
---|
275 |
|
---|
276 | private slots:
|
---|
277 |
|
---|
278 | void sltCreateFileViewContextMenu(const QPoint &point);
|
---|
279 | void sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
|
---|
280 | void sltSearchTextChanged(const QString &strText);
|
---|
281 | /** m_pModel signals when an tree item is renamed. we try to apply this rename to the file system.
|
---|
282 | * if the file system rename fails we restore the old name of the item. See the comment of
|
---|
283 | * sltRename() for more details. Note that when this slot is called item->path() has also changed. Thus strOldPath. */
|
---|
284 | void sltHandleItemRenameAttempt(UIFileSystemItem *pItem, const QString &strOldPath,
|
---|
285 | const QString &strOldName, const QString &strNewName);
|
---|
286 | void sltHandleNavigationWidgetPathChange(const QString& strPath);
|
---|
287 | void sltHandleNavigationWidgetHistoryListChanged();
|
---|
288 |
|
---|
289 | private:
|
---|
290 |
|
---|
291 | void relist();
|
---|
292 | void prepareObjects();
|
---|
293 | /** @p itemIndex is assumed to be 'model' index not 'proxy model' index */
|
---|
294 | void deleteByIndex(const QModelIndex &itemIndex);
|
---|
295 | /** Returns the UIFileSystemItem for path / which is a direct (and single) child of m_pRootItem */
|
---|
296 | UIFileSystemItem *getStartDirectoryItem();
|
---|
297 | void deSelectUpDirectoryItem();
|
---|
298 | void setSelectionForAll(QItemSelectionModel::SelectionFlags flags);
|
---|
299 | void setSelection(const QModelIndex &indexInProxyModel);
|
---|
300 | /** The start directory requires a special attention since on file systems with drive letters
|
---|
301 | * drive letter are direct children of the start directory. On other systems start directory is '/' */
|
---|
302 | void populateStartDirectory(UIFileSystemItem *startItem);
|
---|
303 | /** Root index of the m_pModel */
|
---|
304 | QModelIndex currentRootIndex() const;
|
---|
305 | /* Searches the content of m_pSearchLineEdit within the current items' names and selects the item if found. */
|
---|
306 | void performSelectionSearch(const QString &strSearchText);
|
---|
307 | /** Clears the m_pSearchLineEdit and hides it. */
|
---|
308 | void disableSelectionSearch();
|
---|
309 | /** Checks if delete confirmation dialog is shown and users choice. Returns true
|
---|
310 | * if deletion can continue */
|
---|
311 | bool checkIfDeleteOK();
|
---|
312 | /** Marks/umarks the search line edit to signal that there are no matches for the current search.
|
---|
313 | * uses m_searchLineUnmarkColor and m_searchLineMarkColor. */
|
---|
314 | void markUnmarkSearchLineEdit(bool fMark);
|
---|
315 | QStringList currentDirectoryListing() const;
|
---|
316 | UIFileSystemModel *m_pModel;
|
---|
317 | UIGuestControlFileView *m_pView;
|
---|
318 | UIFileSystemProxyModel *m_pProxyModel;
|
---|
319 |
|
---|
320 | QILineEdit *m_pSearchLineEdit;
|
---|
321 | QColor m_searchLineUnmarkColor;
|
---|
322 | QColor m_searchLineMarkColor;
|
---|
323 | QChar m_pathSeparator;
|
---|
324 | QHBoxLayout *m_pToolBarLayout;
|
---|
325 | QVector<QWidget*> m_sessionWidgets;
|
---|
326 | friend class UIFileSystemModel;
|
---|
327 | };
|
---|
328 |
|
---|
329 | #endif /* !FEQT_INCLUDED_SRC_guestctrl_UIFileManagerTable_h */
|
---|