VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UICustomFileSystemModel.cpp@ 82781

Last change on this file since 82781 was 82605, checked in by vboxsync, 4 years ago

FE/Qt: Dealing with todo's mentioned r135326. Part 1.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.0 KB
Line 
1/* $Id: UICustomFileSystemModel.cpp 82605 2019-12-17 12:32:26Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UICustomFileSystemModel class implementation.
4 */
5
6/*
7 * Copyright (C) 2016-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QApplication>
20#include <QDateTime>
21#include <QHeaderView>
22
23/* GUI includes: */
24#include "UIErrorString.h"
25#include "UICustomFileSystemModel.h"
26#include "UIPathOperations.h"
27#include "UICommon.h"
28
29const char *UICustomFileSystemModel::strUpDirectoryString = "..";
30
31
32/*********************************************************************************************************************************
33* UICustomFileSystemItem implementation. *
34*********************************************************************************************************************************/
35
36UICustomFileSystemItem::UICustomFileSystemItem(const QString &strName, UICustomFileSystemItem *parent, KFsObjType type)
37 : m_parentItem(parent)
38 , m_bIsOpened(false)
39 , m_fIsTargetADirectory(false)
40 , m_type(type)
41 , m_fIsDriveItem(false)
42 , m_fIsHidden(false)
43{
44 for (int i = static_cast<int>(UICustomFileSystemModelColumn_Name);
45 i < static_cast<int>(UICustomFileSystemModelColumn_Max); ++i)
46 m_itemData[static_cast<UICustomFileSystemModelColumn>(i)] = QVariant();
47 m_itemData[UICustomFileSystemModelColumn_Name] = strName;
48 if (parent)
49 parent->appendChild(this);
50}
51
52UICustomFileSystemItem::~UICustomFileSystemItem()
53{
54 reset();
55}
56
57void UICustomFileSystemItem::appendChild(UICustomFileSystemItem *item)
58{
59 if (!item)
60 return;
61 if (m_childItems.contains(item))
62 return;
63 m_childItems.append(item);
64 m_childMap.insert(item->name(), item);
65}
66
67void UICustomFileSystemItem::reset()
68{
69 qDeleteAll(m_childItems);
70 m_childItems.clear();
71 m_childMap.clear();
72 m_bIsOpened = false;
73}
74
75UICustomFileSystemItem *UICustomFileSystemItem::child(int row) const
76{
77 return m_childItems.value(row);
78}
79
80UICustomFileSystemItem *UICustomFileSystemItem::child(const QString &path) const
81{
82 if (!m_childMap.contains(path))
83 return 0;
84 return m_childMap.value(path);
85}
86
87int UICustomFileSystemItem::childCount() const
88{
89 return m_childItems.count();
90}
91
92QList<UICustomFileSystemItem*> UICustomFileSystemItem::children() const
93{
94 QList<UICustomFileSystemItem*> childList;
95 foreach (UICustomFileSystemItem *child, m_childItems)
96 childList << child;
97 return childList;
98}
99
100void UICustomFileSystemItem::removeChild(UICustomFileSystemItem *pItem)
101{
102 int iIndex = m_childItems.indexOf(pItem);
103 if (iIndex == -1 || iIndex > m_childItems.size())
104 return;
105 m_childItems.removeAt(iIndex);
106 m_childMap.remove(pItem->name());
107 delete pItem;
108 pItem = 0;
109}
110
111void UICustomFileSystemItem::removeChildren()
112{
113 reset();
114}
115
116int UICustomFileSystemItem::columnCount() const
117{
118 return m_itemData.count();
119}
120
121QVariant UICustomFileSystemItem::data(int column) const
122{
123 return m_itemData.value(static_cast<UICustomFileSystemModelColumn>(column), QVariant());
124}
125
126QString UICustomFileSystemItem::name() const
127{
128 QVariant data = m_itemData.value(UICustomFileSystemModelColumn_Name, QVariant());
129 if (!data.canConvert(QMetaType::QString))
130 return QString();
131 return data.toString();
132}
133
134void UICustomFileSystemItem::setData(const QVariant &data, int index)
135{
136 m_itemData[static_cast<UICustomFileSystemModelColumn>(index)] = data;
137}
138
139void UICustomFileSystemItem::setData(const QVariant &data, UICustomFileSystemModelColumn enmColumn)
140{
141 m_itemData[enmColumn] = data;
142}
143
144UICustomFileSystemItem *UICustomFileSystemItem::parentItem()
145{
146 return m_parentItem;
147}
148
149int UICustomFileSystemItem::row() const
150{
151 if (m_parentItem)
152 return m_parentItem->m_childItems.indexOf(const_cast<UICustomFileSystemItem*>(this));
153 return 0;
154}
155
156bool UICustomFileSystemItem::isDirectory() const
157{
158 return m_type == KFsObjType_Directory;
159}
160
161bool UICustomFileSystemItem::isSymLink() const
162{
163 return m_type == KFsObjType_Symlink;
164}
165
166bool UICustomFileSystemItem::isFile() const
167{
168 return m_type == KFsObjType_File;
169}
170
171void UICustomFileSystemItem::clearChildren()
172{
173 qDeleteAll(m_childItems);
174 m_childItems.clear();
175 m_childMap.clear();
176}
177
178bool UICustomFileSystemItem::isOpened() const
179{
180 return m_bIsOpened;
181}
182
183void UICustomFileSystemItem::setIsOpened(bool flag)
184{
185 m_bIsOpened = flag;
186}
187
188QString UICustomFileSystemItem::path(bool fRemoveTrailingDelimiters /* = false */) const
189{
190 const QString &strPath = m_itemData.value(UICustomFileSystemModelColumn_Path, QString()).toString();
191
192 if (fRemoveTrailingDelimiters)
193 return UIPathOperations::removeTrailingDelimiters(strPath);
194
195 return strPath;
196}
197
198void UICustomFileSystemItem::setPath(const QString &path)
199{
200 if (path.isNull() || path.isEmpty())
201 return;
202 m_itemData[UICustomFileSystemModelColumn_Path] = path;
203}
204
205bool UICustomFileSystemItem::isUpDirectory() const
206{
207 if (!isDirectory())
208 return false;
209 if (data(0) == UICustomFileSystemModel::strUpDirectoryString)
210 return true;
211 return false;
212}
213
214KFsObjType UICustomFileSystemItem::type() const
215{
216 return m_type;
217}
218
219const QString &UICustomFileSystemItem::targetPath() const
220{
221 return m_strTargetPath;
222}
223
224void UICustomFileSystemItem::setTargetPath(const QString &path)
225{
226 m_strTargetPath = path;
227}
228
229bool UICustomFileSystemItem::isSymLinkToADirectory() const
230{
231 return m_fIsTargetADirectory;
232}
233
234void UICustomFileSystemItem::setIsSymLinkToADirectory(bool flag)
235{
236 m_fIsTargetADirectory = flag;
237}
238
239bool UICustomFileSystemItem::isSymLinkToAFile() const
240{
241 return isSymLink() && !m_fIsTargetADirectory;
242}
243
244void UICustomFileSystemItem::setIsDriveItem(bool flag)
245{
246 m_fIsDriveItem = flag;
247}
248
249bool UICustomFileSystemItem::isDriveItem() const
250{
251 return m_fIsDriveItem;
252}
253
254void UICustomFileSystemItem::setIsHidden(bool flag)
255{
256 m_fIsHidden = flag;
257}
258
259bool UICustomFileSystemItem::isHidden() const
260{
261 return m_fIsHidden;
262}
263
264
265/*********************************************************************************************************************************
266* UICustomFileSystemProxyModel implementation. *
267*********************************************************************************************************************************/
268
269UICustomFileSystemProxyModel::UICustomFileSystemProxyModel(QObject *parent /* = 0 */)
270 :QSortFilterProxyModel(parent)
271 , m_fListDirectoriesOnTop(false)
272 , m_fShowHiddenObjects(true)
273{
274}
275
276bool UICustomFileSystemProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
277{
278 UICustomFileSystemItem *pLeftItem = static_cast<UICustomFileSystemItem*>(left.internalPointer());
279 UICustomFileSystemItem *pRightItem = static_cast<UICustomFileSystemItem*>(right.internalPointer());
280
281 if (pLeftItem && pRightItem)
282 {
283 /* List the directories before the files if options say so: */
284 if (m_fListDirectoriesOnTop)
285 {
286 if ((pLeftItem->isDirectory() || pLeftItem->isSymLinkToADirectory()) && !pRightItem->isDirectory())
287 return (sortOrder() == Qt::AscendingOrder);
288 if ((pRightItem->isDirectory() || pRightItem->isSymLinkToADirectory()) && !pLeftItem->isDirectory())
289 return (sortOrder() == Qt::DescendingOrder);
290 }
291 /* Up directory item should be always the first item: */
292 if (pLeftItem->isUpDirectory())
293 return (sortOrder() == Qt::AscendingOrder);
294 else if (pRightItem->isUpDirectory())
295 return (sortOrder() == Qt::DescendingOrder);
296
297 /* If the sort column is QDateTime than handle it correctly: */
298 if (sortColumn() == UICustomFileSystemModelColumn_ChangeTime)
299 {
300 QVariant dataLeft = pLeftItem->data(UICustomFileSystemModelColumn_ChangeTime);
301 QVariant dataRight = pRightItem->data(UICustomFileSystemModelColumn_ChangeTime);
302 QDateTime leftDateTime = dataLeft.toDateTime();
303 QDateTime rightDateTime = dataRight.toDateTime();
304 return (leftDateTime < rightDateTime);
305 }
306 /* When we show human readble sizes in size column sorting gets confused, so do it here: */
307 else if(sortColumn() == UICustomFileSystemModelColumn_Size)
308 {
309 qulonglong leftSize = pLeftItem->data(UICustomFileSystemModelColumn_Size).toULongLong();
310 qulonglong rightSize = pRightItem->data(UICustomFileSystemModelColumn_Size).toULongLong();
311 return (leftSize < rightSize);
312
313 }
314 }
315 return QSortFilterProxyModel::lessThan(left, right);
316}
317
318bool UICustomFileSystemProxyModel::filterAcceptsRow(int iSourceRow, const QModelIndex &sourceParent) const
319{
320 if (m_fShowHiddenObjects)
321 return true;
322
323 QModelIndex itemIndex = sourceModel()->index(iSourceRow, 0, sourceParent);
324 if (!itemIndex.isValid())
325 return false;
326
327 UICustomFileSystemItem *item = static_cast<UICustomFileSystemItem*>(itemIndex.internalPointer());
328 if (!item)
329 return false;
330
331 if (item->isHidden())
332 return false;
333
334 return true;
335}
336
337void UICustomFileSystemProxyModel::setListDirectoriesOnTop(bool fListDirectoriesOnTop)
338{
339 m_fListDirectoriesOnTop = fListDirectoriesOnTop;
340}
341
342bool UICustomFileSystemProxyModel::listDirectoriesOnTop() const
343{
344 return m_fListDirectoriesOnTop;
345}
346
347void UICustomFileSystemProxyModel::setShowHiddenObjects(bool fShowHiddenObjects)
348{
349 m_fShowHiddenObjects = fShowHiddenObjects;
350}
351
352bool UICustomFileSystemProxyModel::showHiddenObjects() const
353{
354 return m_fShowHiddenObjects;
355}
356
357
358/*********************************************************************************************************************************
359* UICustomFileSystemModel implementation. *
360*********************************************************************************************************************************/
361
362UICustomFileSystemModel::UICustomFileSystemModel(QObject *parent)
363 : QAbstractItemModel(parent)
364 , m_fShowHumanReadableSizes(false)
365{
366 initializeTree();
367}
368
369UICustomFileSystemItem* UICustomFileSystemModel::rootItem()
370{
371 return m_pRootItem;
372}
373
374const UICustomFileSystemItem* UICustomFileSystemModel::rootItem() const
375{
376 return m_pRootItem;
377}
378
379UICustomFileSystemModel::~UICustomFileSystemModel()
380{
381 delete m_pRootItem;
382}
383
384int UICustomFileSystemModel::columnCount(const QModelIndex &parent) const
385{
386 if (parent.isValid())
387 return static_cast<UICustomFileSystemItem*>(parent.internalPointer())->columnCount();
388 else
389 {
390 if (!rootItem())
391 return 0;
392 else
393 return rootItem()->columnCount();
394 }
395}
396
397bool UICustomFileSystemModel::setData(const QModelIndex &index, const QVariant &value, int role)
398{
399 if (index.isValid() && role == Qt::EditRole)
400 {
401 if (index.column() == 0 && value.canConvert(QMetaType::QString))
402 {
403 UICustomFileSystemItem *pItem = static_cast<UICustomFileSystemItem*>(index.internalPointer());
404 if (!pItem)
405 return false;
406 QString strOldName = pItem->name();
407 pItem->setData(value, index.column());
408 emit dataChanged(index, index);
409 emit sigItemRenamed(pItem, strOldName, value.toString());
410 return true;
411 }
412 }
413 return false;
414}
415
416QVariant UICustomFileSystemModel::data(const QModelIndex &index, int role) const
417{
418 if (!index.isValid())
419 return QVariant();
420 UICustomFileSystemItem *item = static_cast<UICustomFileSystemItem*>(index.internalPointer());
421 if (!item)
422 return QVariant();
423
424 if (role == Qt::DisplayRole || role == Qt::EditRole)
425 {
426 /* dont show anything but the name for up directories: */
427 if (item->isUpDirectory() && index.column() != UICustomFileSystemModelColumn_Name)
428 return QVariant();
429 /* Format date/time column: */
430 if (item->data(index.column()).canConvert(QMetaType::QDateTime))
431 {
432 QDateTime dateTime = item->data(index.column()).toDateTime();
433 if (dateTime.isValid())
434 return dateTime.toString("dd.MM.yyyy hh:mm:ss");
435 }
436 /* Decide whether to show human-readable file object sizes: */
437 if (index.column() == UICustomFileSystemModelColumn_Size)
438 {
439 if (m_fShowHumanReadableSizes)
440 {
441 qulonglong size = item->data(index.column()).toULongLong();
442 return uiCommon().formatSize(size);
443 }
444 else
445 return item->data(index.column());
446 }
447 return item->data(index.column());
448 }
449 /* Show the up directory array: */
450 if (role == Qt::DecorationRole && index.column() == 0)
451 {
452 if (item->isDirectory())
453 {
454 if (item->isUpDirectory())
455 return QIcon(":/arrow_up_10px_x2.png");
456 else if(item->isDriveItem())
457 return QIcon(":/hd_32px.png");
458 else
459 return QIcon(":/file_manager_folder_16px.png");
460 }
461 else if (item->isFile())
462 return QIcon(":/file_manager_file_16px.png");
463 else if (item->isSymLink())
464 {
465 if (item->isSymLinkToADirectory())
466 return QIcon(":/file_manager_folder_symlink_16px.png");
467 else
468 return QIcon(":/file_manager_file_symlink_16px.png");
469 }
470 }
471
472 return QVariant();
473}
474
475Qt::ItemFlags UICustomFileSystemModel::flags(const QModelIndex &index) const
476{
477 if (!index.isValid())
478 return 0;
479 UICustomFileSystemItem *item = static_cast<UICustomFileSystemItem*>(index.internalPointer());
480 if (!item)
481 return QAbstractItemModel::flags(index);
482
483 if (!item->isUpDirectory() && index.column() == 0)
484 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
485 return QAbstractItemModel::flags(index);
486}
487
488QVariant UICustomFileSystemModel::headerData(int section, Qt::Orientation orientation,
489 int role) const
490{
491 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
492 {
493 if (!rootItem())
494 return QVariant();
495 else
496 return rootItem()->data(section);
497 }
498 return QVariant();
499}
500
501QModelIndex UICustomFileSystemModel::index(UICustomFileSystemItem* item)
502{
503 if (!item)
504 return QModelIndex();
505 return createIndex(item->row(), 0, item);
506}
507
508QModelIndex UICustomFileSystemModel::index(int row, int column, const QModelIndex &parent) const
509{
510 if (!hasIndex(row, column, parent))
511 return QModelIndex();
512
513 const UICustomFileSystemItem* parentItem = rootItem();
514
515 if (parent.isValid())
516 parentItem = static_cast<UICustomFileSystemItem*>(parent.internalPointer());
517
518 if (!parentItem)
519 return QModelIndex();
520
521 UICustomFileSystemItem *childItem = parentItem->child(row);
522 if (childItem)
523 return createIndex(row, column, childItem);
524 else
525 return QModelIndex();
526}
527
528
529QModelIndex UICustomFileSystemModel::parent(const QModelIndex &index) const
530{
531 if (!index.isValid())
532 return QModelIndex();
533
534 UICustomFileSystemItem *childItem = static_cast<UICustomFileSystemItem*>(index.internalPointer());
535 UICustomFileSystemItem *parentItem = childItem->parentItem();
536
537 if (!parentItem || parentItem == rootItem())
538 return QModelIndex();
539
540 return createIndex(parentItem->row(), 0, parentItem);
541}
542
543int UICustomFileSystemModel::rowCount(const QModelIndex &parent) const
544{
545 if (parent.column() > 0)
546 return 0;
547 const UICustomFileSystemItem *parentItem = rootItem();
548 if (parent.isValid())
549 parentItem = static_cast<UICustomFileSystemItem*>(parent.internalPointer());
550 if (!parentItem)
551 return 0;
552 return parentItem->childCount();
553}
554
555void UICustomFileSystemModel::signalUpdate()
556{
557 emit layoutChanged();
558}
559
560QModelIndex UICustomFileSystemModel::rootIndex() const
561{
562 if (!rootItem())
563 return QModelIndex();
564 if (!rootItem()->child(0))
565 return QModelIndex();
566 return createIndex(rootItem()->child(0)->row(), 0,
567 rootItem()->child(0));
568}
569
570void UICustomFileSystemModel::beginReset()
571{
572 beginResetModel();
573}
574
575void UICustomFileSystemModel::endReset()
576{
577 endResetModel();
578}
579
580void UICustomFileSystemModel::reset()
581{
582 beginResetModel();
583 m_pRootItem->reset();
584 endResetModel();
585}
586
587void UICustomFileSystemModel::setShowHumanReadableSizes(bool fShowHumanReadableSizes)
588{
589 m_fShowHumanReadableSizes = fShowHumanReadableSizes;
590}
591
592bool UICustomFileSystemModel::showHumanReadableSizes() const
593{
594 return m_fShowHumanReadableSizes;
595}
596
597void UICustomFileSystemModel::deleteItem(UICustomFileSystemItem* pItem)
598{
599 if (!pItem)
600 return;
601 UICustomFileSystemItem *pParent = pItem->parentItem();
602 if (pParent)
603 pParent->removeChild(pItem);
604}
605
606void UICustomFileSystemModel::initializeTree()
607{
608 m_pRootItem = new UICustomFileSystemItem(UICustomFileSystemModel::tr("Name"), 0, KFsObjType_Directory);
609 m_pRootItem->setData(UICustomFileSystemModel::tr("Size"), UICustomFileSystemModelColumn_Size);
610 m_pRootItem->setData(UICustomFileSystemModel::tr("Change Time"), UICustomFileSystemModelColumn_ChangeTime);
611 m_pRootItem->setData(UICustomFileSystemModel::tr("Owner"), UICustomFileSystemModelColumn_Owner);
612 m_pRootItem->setData(UICustomFileSystemModel::tr("Permissions"), UICustomFileSystemModelColumn_Permissions);
613 m_pRootItem->setData(UICustomFileSystemModel::tr("Local Path"), UICustomFileSystemModelColumn_LocalPath);
614 m_pRootItem->setData(UICustomFileSystemModel::tr("Path"), UICustomFileSystemModelColumn_Path);
615}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use