VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIGuestControlFileTable.cpp@ 75184

Last change on this file since 75184 was 75184, checked in by vboxsync, 6 years ago

FE/Qt: bugref:6699. Several modifications to file manager

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 48.7 KB
Line 
1/* $Id: UIGuestControlFileTable.cpp 75184 2018-10-30 15:07:55Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIGuestControlFileTable class implementation.
4 */
5
6/*
7 * Copyright (C) 2016-2017 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#ifdef VBOX_WITH_PRECOMPILED_HEADERS
19# include <precomp.h>
20#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
21
22/* Qt includes: */
23# include <QAction>
24# include <QComboBox>
25# include <QDateTime>
26# include <QDir>
27# include <QHeaderView>
28# include <QItemDelegate>
29# include <QGridLayout>
30# include <QMenu>
31# include <QSortFilterProxyModel>
32# include <QTextEdit>
33# include <QPushButton>
34
35/* GUI includes: */
36# include "QIDialog.h"
37# include "QIDialogButtonBox.h"
38# include "QILabel.h"
39# include "QILineEdit.h"
40# include "QIMessageBox.h"
41# include "UIActionPool.h"
42# include "UIErrorString.h"
43# include "UIGuestFileTable.h"
44# include "UIIconPool.h"
45# include "UIGuestControlFileTable.h"
46# include "UIGuestControlFileModel.h"
47# include "UIToolBar.h"
48
49/* COM includes: */
50# include "CFsObjInfo.h"
51# include "CGuestFsObjInfo.h"
52# include "CGuestDirectory.h"
53# include "CProgress.h"
54
55#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
56
57
58
59/*********************************************************************************************************************************
60* UIGuestControlFileView definition. *
61*********************************************************************************************************************************/
62
63/** Using QITableView causes the following problem when I click on the table items
64 Qt WARNING: Cannot creat accessible child interface for object: UIGuestControlFileView.....
65 so for now subclass QTableView */
66class UIGuestControlFileView : public QTableView
67{
68
69 Q_OBJECT;
70
71signals:
72
73 void sigGoUp();
74 void sigGoHome();
75 void sigRefresh();
76 void sigRename();
77 void sigCreateNewDirectory();
78 void sigDelete();
79 void sigCut();
80 void sigCopy();
81 void sigPaste();
82 void sigShowProperties();
83 void sigSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
84
85public:
86
87 UIGuestControlFileView(QWidget * parent = 0);
88 bool hasSelection() const;
89
90protected:
91
92 virtual void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected) /*override */;
93 void contextMenuEvent(QContextMenuEvent *pEvent);
94
95private:
96
97 void configure();
98 QWidget *m_pParent;
99};
100
101
102/*********************************************************************************************************************************
103* UIFileDelegate definition. *
104*********************************************************************************************************************************/
105/** A QItemDelegate child class to disable dashed lines drawn around selected cells in QTableViews */
106class UIFileDelegate : public QItemDelegate
107{
108
109 Q_OBJECT;
110
111protected:
112 virtual void drawFocus ( QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, const QRect & /*rect*/ ) const {}
113};
114
115
116/*********************************************************************************************************************************
117* UIFileStringInputDialog definition. *
118*********************************************************************************************************************************/
119
120/** A QIDialog child including a line edit whose text exposed when the dialog is accepted */
121class UIStringInputDialog : public QIDialog
122{
123
124 Q_OBJECT;
125
126public:
127
128 UIStringInputDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);
129 QString getString() const;
130
131private:
132
133 QILineEdit *m_pLineEdit;
134
135};
136
137
138/*********************************************************************************************************************************
139* UIHostDirectoryDiskUsageComputer implementation. *
140*********************************************************************************************************************************/
141
142UIDirectoryDiskUsageComputer::UIDirectoryDiskUsageComputer(QObject *parent, QStringList pathList)
143 :QThread(parent)
144 , m_pathList(pathList)
145 , m_fOkToContinue(true)
146{
147}
148
149void UIDirectoryDiskUsageComputer::run()
150{
151 for (int i = 0; i < m_pathList.size(); ++i)
152 directoryStatisticsRecursive(m_pathList[i], m_resultStatistics);
153}
154
155void UIDirectoryDiskUsageComputer::stopRecursion()
156{
157 m_mutex.lock();
158 m_fOkToContinue = false;
159 m_mutex.unlock();
160}
161
162bool UIDirectoryDiskUsageComputer::isOkToContinue() const
163{
164 return m_fOkToContinue;
165}
166
167
168/*********************************************************************************************************************************
169* UIPathOperations implementation. *
170*********************************************************************************************************************************/
171
172const QChar UIPathOperations::delimiter = QChar('/');
173const QChar UIPathOperations::dosDelimiter = QChar('\\');
174
175/* static */ QString UIPathOperations::removeMultipleDelimiters(const QString &path)
176{
177 QString newPath(path);
178 QString doubleDelimiter(2, delimiter);
179
180 while (newPath.contains(doubleDelimiter) && !newPath.isEmpty())
181 newPath = newPath.replace(doubleDelimiter, delimiter);
182 return newPath;
183}
184
185/* static */ QString UIPathOperations::removeTrailingDelimiters(const QString &path)
186{
187 if (path.isNull() || path.isEmpty())
188 return QString();
189 QString newPath(path);
190 /* Make sure for we dont have any trailing delimiters: */
191 while (newPath.length() > 1 && newPath.at(newPath.length() - 1) == UIPathOperations::delimiter)
192 newPath.chop(1);
193 return newPath;
194}
195
196/* static */ QString UIPathOperations::addTrailingDelimiters(const QString &path)
197{
198 if (path.isNull() || path.isEmpty())
199 return QString();
200 QString newPath(path);
201 while (newPath.length() > 1 && newPath.at(newPath.length() - 1) != UIPathOperations::delimiter)
202 newPath += UIPathOperations::delimiter;
203 return newPath;
204}
205
206/* static */ QString UIPathOperations::addStartDelimiter(const QString &path)
207{
208 if (path.isEmpty())
209 return QString(path);
210 QString newPath(path);
211
212 if (doesPathStartWithDriveLetter(newPath))
213 {
214 if (newPath.at(newPath.length() - 1) != delimiter)
215 newPath += delimiter;
216 return newPath;
217 }
218 if (newPath.at(0) != delimiter)
219 newPath.insert(0, delimiter);
220 return newPath;
221}
222
223/* static */ QString UIPathOperations::sanitize(const QString &path)
224{
225 //return addStartDelimiter(removeTrailingDelimiters(removeMultipleDelimiters(path)));
226 QString newPath = addStartDelimiter(removeTrailingDelimiters(removeMultipleDelimiters(path))).replace(dosDelimiter, delimiter);
227 return newPath;
228}
229
230/* static */ QString UIPathOperations::mergePaths(const QString &path, const QString &baseName)
231{
232 QString newBase(baseName);
233 newBase = newBase.remove(delimiter);
234
235 /* make sure we have one and only one trailing '/': */
236 QString newPath(sanitize(path));
237 if(newPath.isEmpty())
238 newPath = delimiter;
239 if(newPath.at(newPath.length() - 1) != delimiter)
240 newPath += UIPathOperations::delimiter;
241 newPath += newBase;
242 return sanitize(newPath);
243}
244
245/* static */ QString UIPathOperations::getObjectName(const QString &path)
246{
247 if (path.length() <= 1)
248 return QString(path);
249
250 QString strTemp(sanitize(path));
251 if (strTemp.length() < 2)
252 return strTemp;
253 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);
254 if (lastSlashPosition == -1)
255 return QString();
256 return strTemp.right(strTemp.length() - lastSlashPosition - 1);
257}
258
259/* static */ QString UIPathOperations::getPathExceptObjectName(const QString &path)
260{
261 if (path.length() <= 1)
262 return QString(path);
263
264 QString strTemp(sanitize(path));
265 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);
266 if (lastSlashPosition == -1)
267 return QString();
268 return strTemp.left(lastSlashPosition + 1);
269}
270
271/* static */ QString UIPathOperations::constructNewItemPath(const QString &previousPath, const QString &newBaseName)
272{
273 if (previousPath.length() <= 1)
274 return QString(previousPath);
275 return sanitize(mergePaths(getPathExceptObjectName(previousPath), newBaseName));
276}
277
278/* static */ QStringList UIPathOperations::pathTrail(const QString &path)
279{
280 QStringList pathList = path.split(UIPathOperations::delimiter, QString::SkipEmptyParts);
281 if (!pathList.isEmpty() && doesPathStartWithDriveLetter(pathList[0]))
282 {
283 pathList[0] = addTrailingDelimiters(pathList[0]);
284 }
285 return pathList;
286}
287
288/* static */ bool UIPathOperations::doesPathStartWithDriveLetter(const QString &path)
289{
290 if (path.length() < 2)
291 return false;
292 /* search for ':' with the path: */
293 if (!path[0].isLetter())
294 return false;
295 if (path[1] != ':')
296 return false;
297 return true;
298}
299
300
301/*********************************************************************************************************************************
302* UIGuestControlFileView implementation. *
303*********************************************************************************************************************************/
304
305UIGuestControlFileView::UIGuestControlFileView(QWidget *parent)
306 :QTableView(parent)
307 , m_pParent(parent)
308{
309 configure();
310}
311
312void UIGuestControlFileView::configure()
313{
314 setShowGrid(false);
315 setSelectionBehavior(QAbstractItemView::SelectRows);
316 verticalHeader()->setVisible(false);
317 setEditTriggers(QAbstractItemView::NoEditTriggers);
318 /* Minimize the row height: */
319 verticalHeader()->setDefaultSectionSize(verticalHeader()->minimumSectionSize());
320 setAlternatingRowColors(true);
321 installEventFilter(m_pParent);
322}
323
324void UIGuestControlFileView::contextMenuEvent(QContextMenuEvent *pEvent)
325{
326 bool selectionAvaible = hasSelection();
327
328 QMenu *menu = new QMenu(this);
329 if (!menu)
330 return;
331
332 QAction *pActionGoUp = menu->addAction(QApplication::translate("UIGuestControlFileManager","Go up"));
333 if (pActionGoUp)
334 {
335 pActionGoUp->setIcon(UIIconPool::iconSet(QString(":/arrow_up_10px_x2.png")));
336 connect(pActionGoUp, &QAction::triggered, this, &UIGuestControlFileView::sigGoUp);
337 }
338 QAction *pActionGoHome = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Go home"));
339 if (pActionGoHome)
340 {
341 pActionGoHome->setIcon(UIIconPool::iconSet(QString(":/nw_24px.png")));
342 connect(pActionGoHome, &QAction::triggered, this, &UIGuestControlFileView::sigGoHome);
343 }
344
345 QAction *pActionRefresh = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Refresh"));
346 if (pActionRefresh)
347 {
348 pActionRefresh->setIcon(UIIconPool::iconSet(QString(":/refresh_24px.png")));
349 connect(pActionRefresh, &QAction::triggered, this, &UIGuestControlFileView::sigRefresh);
350 }
351
352 menu->addSeparator();
353 QAction *pActionDelete = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Delete"));
354 if (pActionDelete)
355 {
356 pActionDelete->setIcon(UIIconPool::iconSet(QString(":/vm_delete_32px.png")));
357 pActionDelete->setEnabled(selectionAvaible);
358 connect(pActionDelete, &QAction::triggered, this, &UIGuestControlFileView::sigDelete);
359 }
360
361 QAction *pActionRename = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Rename"));
362 if (pActionRename)
363 {
364 pActionRename->setIcon(UIIconPool::iconSet(QString(":/name_16px_x2.png")));
365 pActionRename->setEnabled(selectionAvaible);
366 pActionRename->setEnabled(selectionAvaible);
367 connect(pActionRename, &QAction::triggered, this, &UIGuestControlFileView::sigRename);
368 }
369
370 QAction *pActionCreateNewDirectory = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Create New Directory"));
371 if (pActionCreateNewDirectory)
372 {
373 pActionCreateNewDirectory->setIcon(UIIconPool::iconSet(QString(":/sf_add_16px.png")));
374 connect(pActionCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileView::sigCreateNewDirectory);
375 }
376
377 QAction *pActionCopy = 0;
378 QAction *pActionCut = 0;
379 QAction *pActionPaste = 0;
380
381 bool isGuestFileTable = qobject_cast<UIGuestFileTable*>(parent());
382
383 if (isGuestFileTable)
384 {
385 pActionCopy = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Copy"));
386 if (pActionCopy)
387 {
388 pActionCopy->setIcon(UIIconPool::iconSet(QString(":/fd_copy_32px.png")));
389 pActionCopy->setEnabled(selectionAvaible);
390 connect(pActionCopy, &QAction::triggered, this, &UIGuestControlFileView::sigCopy);
391 }
392
393 pActionCut = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Cut"));
394 if (pActionCut)
395 {
396 pActionCut->setIcon(UIIconPool::iconSet(QString(":/fd_move_32px.png")));
397 pActionCut->setEnabled(selectionAvaible);
398 connect(pActionCut, &QAction::triggered, this, &UIGuestControlFileView::sigCut);
399 }
400
401 pActionPaste = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Paste"));
402 if (pActionPaste)
403 {
404 pActionPaste->setIcon(UIIconPool::iconSet(QString(":/shared_clipboard_16px.png")));
405 connect(pActionPaste, &QAction::triggered, this, &UIGuestControlFileView::sigPaste);
406 }
407 }
408
409 menu->addSeparator();
410 QAction *pActionShowProperties = menu->addAction(QApplication::translate("UIGuestControlFileManager", "Properties"));
411 if (pActionShowProperties)
412 {
413 pActionShowProperties->setIcon(UIIconPool::iconSet(QString(":/session_info_32px.png")));
414 pActionShowProperties->setEnabled(selectionAvaible);
415 connect(pActionShowProperties, &QAction::triggered, this, &UIGuestControlFileView::sigShowProperties);
416 }
417
418 menu->exec(pEvent->globalPos());
419
420 if (pActionGoUp)
421 disconnect(pActionGoUp, &QAction::triggered, this, &UIGuestControlFileView::sigGoUp);
422 if (pActionGoHome)
423 disconnect(pActionGoHome, &QAction::triggered, this, &UIGuestControlFileView::sigGoHome);
424 if (pActionRefresh)
425 disconnect(pActionRefresh, &QAction::triggered, this, &UIGuestControlFileView::sigRefresh);
426 if (pActionDelete)
427 disconnect(pActionDelete, &QAction::triggered, this, &UIGuestControlFileView::sigDelete);
428 if (pActionRename)
429 disconnect(pActionRename, &QAction::triggered, this, &UIGuestControlFileView::sigRename);
430 if (pActionCreateNewDirectory)
431 disconnect(pActionCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileView::sigCreateNewDirectory);
432 if (isGuestFileTable)
433 {
434 if (pActionCopy)
435 disconnect(pActionCopy, &QAction::triggered, this, &UIGuestControlFileView::sigCopy);
436 if (pActionCut)
437 disconnect(pActionCut, &QAction::triggered, this, &UIGuestControlFileView::sigCut);
438 if (pActionPaste)
439 disconnect(pActionPaste, &QAction::triggered, this, &UIGuestControlFileView::sigPaste);
440 }
441 if (pActionShowProperties)
442 disconnect(pActionShowProperties, &QAction::triggered, this, &UIGuestControlFileView::sigShowProperties);
443
444 delete menu;
445}
446
447bool UIGuestControlFileView::hasSelection() const
448{
449 QItemSelectionModel *pSelectionModel = selectionModel();
450 if (!pSelectionModel)
451 return false;
452 return pSelectionModel->hasSelection();
453}
454
455void UIGuestControlFileView::selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
456{
457 emit sigSelectionChanged(selected, deselected);
458 QTableView::selectionChanged(selected, deselected);
459}
460
461
462/*********************************************************************************************************************************
463* UIFileStringInputDialog implementation. *
464*********************************************************************************************************************************/
465
466UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)
467 :QIDialog(pParent, flags)
468{
469 QVBoxLayout *layout = new QVBoxLayout(this);
470 m_pLineEdit = new QILineEdit(this);
471 layout->addWidget(m_pLineEdit);
472
473 QIDialogButtonBox *pButtonBox =
474 new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
475 layout->addWidget(pButtonBox);
476 // {
477 // /* Configure button-box: */
478 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);
479 connect(pButtonBox, &QIDialogButtonBox::rejected, this, &UIStringInputDialog::reject);
480
481}
482
483QString UIStringInputDialog::getString() const
484{
485 if (!m_pLineEdit)
486 return QString();
487 return m_pLineEdit->text();
488}
489
490
491/*********************************************************************************************************************************
492* UIPropertiesDialog implementation. *
493*********************************************************************************************************************************/
494
495UIPropertiesDialog::UIPropertiesDialog(QWidget *pParent, Qt::WindowFlags flags)
496 :QIDialog(pParent, flags)
497 , m_pMainLayout(new QVBoxLayout)
498 , m_pInfoEdit(new QTextEdit)
499{
500 setLayout(m_pMainLayout);
501
502 if (m_pMainLayout)
503 m_pMainLayout->addWidget(m_pInfoEdit);
504 if (m_pInfoEdit)
505 {
506 m_pInfoEdit->setReadOnly(true);
507 m_pInfoEdit->setFrameStyle(QFrame::NoFrame);
508 }
509 QIDialogButtonBox *pButtonBox =
510 new QIDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this);
511 m_pMainLayout->addWidget(pButtonBox);
512 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);
513}
514
515void UIPropertiesDialog::setPropertyText(const QString &strProperty)
516{
517 if (!m_pInfoEdit)
518 return;
519 m_strProperty = strProperty;
520 m_pInfoEdit->setHtml(strProperty);
521}
522
523void UIPropertiesDialog::addDirectoryStatistics(UIDirectoryStatistics directoryStatistics)
524{
525 if (!m_pInfoEdit)
526 return;
527 // QString propertyString = m_pInfoEdit->toHtml();
528 // propertyString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");
529 // if (directoryStatistics.m_totalSize >= UIGuestControlFileTable::m_iKiloByte)
530 // propertyString += " (" + UIGuestControlFileTable::humanReadableSize(directoryStatistics.m_totalSize) + ")";
531 // propertyString += "<br/>";
532 // propertyString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);
533
534 // m_pInfoEdit->setHtml(propertyString);
535
536 QString detailsString(m_strProperty);
537 detailsString += "<br/>";
538 detailsString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");
539 if (directoryStatistics.m_totalSize >= UIGuestControlFileTable::m_iKiloByte)
540 detailsString += " (" + UIGuestControlFileTable::humanReadableSize(directoryStatistics.m_totalSize) + ")";
541 detailsString += "<br/>";
542
543 detailsString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);
544
545 m_pInfoEdit->setHtml(detailsString);
546
547}
548
549/*********************************************************************************************************************************
550* UIDirectoryStatistics implementation.
551 *
552*********************************************************************************************************************************/
553
554UIDirectoryStatistics::UIDirectoryStatistics()
555 : m_totalSize(0)
556 , m_uFileCount(0)
557 , m_uDirectoryCount(0)
558 , m_uSymlinkCount(0)
559{
560}
561
562
563/*********************************************************************************************************************************
564* UIFileTableItem implementation. *
565*********************************************************************************************************************************/
566
567UIFileTableItem::UIFileTableItem(const QList<QVariant> &data,
568 UIFileTableItem *parent, FileObjectType type)
569 : m_itemData(data)
570 , m_parentItem(parent)
571 , m_bIsOpened(false)
572 , m_isTargetADirectory(false)
573 , m_type(type)
574 , m_isDriveItem(false)
575{
576}
577
578UIFileTableItem::~UIFileTableItem()
579{
580 qDeleteAll(m_childItems);
581 m_childItems.clear();
582}
583
584void UIFileTableItem::appendChild(UIFileTableItem *item)
585{
586 if (!item)
587 return;
588 m_childItems.append(item);
589
590 m_childMap.insert(item->name(), item);
591}
592
593UIFileTableItem *UIFileTableItem::child(int row) const
594{
595 return m_childItems.value(row);
596}
597
598UIFileTableItem *UIFileTableItem::child(const QString &path) const
599{
600 if (!m_childMap.contains(path))
601 return 0;
602 return m_childMap.value(path);
603}
604
605int UIFileTableItem::childCount() const
606{
607 return m_childItems.count();
608}
609
610int UIFileTableItem::columnCount() const
611{
612 return m_itemData.count();
613}
614
615QVariant UIFileTableItem::data(int column) const
616{
617 return m_itemData.value(column);
618}
619
620QString UIFileTableItem::name() const
621{
622 if (m_itemData.isEmpty() || !m_itemData[0].canConvert(QMetaType::QString))
623 return QString();
624 return m_itemData[0].toString();
625}
626
627void UIFileTableItem::setData(const QVariant &data, int index)
628{
629 if (index >= m_itemData.length())
630 return;
631 m_itemData[index] = data;
632}
633
634UIFileTableItem *UIFileTableItem::parentItem()
635{
636 return m_parentItem;
637}
638
639int UIFileTableItem::row() const
640{
641 if (m_parentItem)
642 return m_parentItem->m_childItems.indexOf(const_cast<UIFileTableItem*>(this));
643 return 0;
644}
645
646bool UIFileTableItem::isDirectory() const
647{
648 return m_type == FileObjectType_Directory;
649}
650
651bool UIFileTableItem::isSymLink() const
652{
653 return m_type == FileObjectType_SymLink;
654}
655
656bool UIFileTableItem::isFile() const
657{
658 return m_type == FileObjectType_File;
659}
660
661void UIFileTableItem::clearChildren()
662{
663 qDeleteAll(m_childItems);
664 m_childItems.clear();
665 m_childMap.clear();
666}
667
668bool UIFileTableItem::isOpened() const
669{
670 return m_bIsOpened;
671}
672
673void UIFileTableItem::setIsOpened(bool flag)
674{
675 m_bIsOpened = flag;
676}
677
678const QString &UIFileTableItem::path() const
679{
680 return m_strPath;
681}
682
683void UIFileTableItem::setPath(const QString &path)
684{
685 if (path.isNull() || path.isEmpty())
686 return;
687 m_strPath = path;
688 UIPathOperations::removeTrailingDelimiters(m_strPath);
689}
690
691bool UIFileTableItem::isUpDirectory() const
692{
693 if (!isDirectory())
694 return false;
695 if (data(0) == UIGuestControlFileModel::strUpDirectoryString)
696 return true;
697 return false;
698}
699
700FileObjectType UIFileTableItem::type() const
701{
702 return m_type;
703}
704
705const QString &UIFileTableItem::targetPath() const
706{
707 return m_strTargetPath;
708}
709
710void UIFileTableItem::setTargetPath(const QString &path)
711{
712 m_strTargetPath = path;
713}
714
715bool UIFileTableItem::isTargetADirectory() const
716{
717 return m_isTargetADirectory;
718}
719
720void UIFileTableItem::setIsTargetADirectory(bool flag)
721{
722 m_isTargetADirectory = flag;
723}
724
725void UIFileTableItem::setIsDriveItem(bool flag)
726{
727 m_isDriveItem = flag;
728}
729
730bool UIFileTableItem::isDriveItem() const
731{
732 return m_isDriveItem;
733}
734
735
736/*********************************************************************************************************************************
737* UIGuestControlFileTable implementation. *
738*********************************************************************************************************************************/
739const unsigned UIGuestControlFileTable::m_iKiloByte = 1000;
740UIGuestControlFileTable::UIGuestControlFileTable(UIActionPool *pActionPool, QWidget *pParent /* = 0 */)
741 :QIWithRetranslateUI<QWidget>(pParent)
742 , m_pRootItem(0)
743 , m_pLocationLabel(0)
744 , m_pPropertiesDialog(0)
745 , m_pActionPool(pActionPool)
746 , m_pToolBar(0)
747 , m_pModel(0)
748 , m_pView(0)
749 , m_pProxyModel(0)
750 , m_pMainLayout(0)
751 , m_pLocationComboBox(0)
752{
753 prepareObjects();
754}
755
756UIGuestControlFileTable::~UIGuestControlFileTable()
757{
758 delete m_pRootItem;
759}
760
761void UIGuestControlFileTable::reset()
762{
763 if (m_pModel)
764 m_pModel->beginReset();
765 delete m_pRootItem;
766 m_pRootItem = 0;
767 if (m_pModel)
768 m_pModel->endReset();
769 if (m_pLocationComboBox)
770 {
771 disconnect(m_pLocationComboBox, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),
772 this, &UIGuestControlFileTable::sltLocationComboCurrentChange);
773 m_pLocationComboBox->clear();
774 connect(m_pLocationComboBox, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),
775 this, &UIGuestControlFileTable::sltLocationComboCurrentChange);
776 }
777}
778
779void UIGuestControlFileTable::emitLogOutput(const QString& strOutput)
780{
781 emit sigLogOutput(strOutput);
782}
783
784void UIGuestControlFileTable::prepareObjects()
785{
786 m_pMainLayout = new QGridLayout();
787 if (!m_pMainLayout)
788 return;
789 m_pMainLayout->setSpacing(0);
790 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
791 setLayout(m_pMainLayout);
792
793 m_pToolBar = new UIToolBar;
794 if (m_pToolBar)
795 {
796 m_pMainLayout->addWidget(m_pToolBar, 0, 0, 1, 5);
797 }
798
799 m_pLocationLabel = new QILabel;
800 if (m_pLocationLabel)
801 {
802 m_pMainLayout->addWidget(m_pLocationLabel, 1, 0, 1, 1);
803 }
804
805 m_pLocationComboBox = new QComboBox;
806 if (m_pLocationComboBox)
807 {
808 m_pMainLayout->addWidget(m_pLocationComboBox, 1, 1, 1, 4);
809 m_pLocationComboBox->setEditable(false);
810 connect(m_pLocationComboBox, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),
811 this, &UIGuestControlFileTable::sltLocationComboCurrentChange);
812 }
813
814
815 m_pModel = new UIGuestControlFileModel(this);
816 if (!m_pModel)
817 return;
818
819 m_pProxyModel = new UIGuestControlFileProxyModel(this);
820 if (!m_pProxyModel)
821 return;
822 m_pProxyModel->setSourceModel(m_pModel);
823
824 m_pView = new UIGuestControlFileView(this);
825 if (m_pView)
826 {
827 m_pMainLayout->addWidget(m_pView, 2, 0, 5, 5);
828 m_pView->setModel(m_pProxyModel);
829 m_pView->setItemDelegate(new UIFileDelegate);
830 m_pView->setSortingEnabled(true);
831 m_pView->sortByColumn(0, Qt::AscendingOrder);
832
833 connect(m_pView, &UIGuestControlFileView::doubleClicked,
834 this, &UIGuestControlFileTable::sltItemDoubleClicked);
835 connect(m_pView, &UIGuestControlFileView::clicked,
836 this, &UIGuestControlFileTable::sltItemClicked);
837 connect(m_pView, &UIGuestControlFileView::sigGoUp,
838 this, &UIGuestControlFileTable::sltGoUp);
839 connect(m_pView, &UIGuestControlFileView::sigGoHome,
840 this, &UIGuestControlFileTable::sltGoHome);
841 connect(m_pView, &UIGuestControlFileView::sigRefresh,
842 this, &UIGuestControlFileTable::sltRefresh);
843 connect(m_pView, &UIGuestControlFileView::sigDelete,
844 this, &UIGuestControlFileTable::sltDelete);
845 connect(m_pView, &UIGuestControlFileView::sigRename,
846 this, &UIGuestControlFileTable::sltRename);
847 connect(m_pView, &UIGuestControlFileView::sigCreateNewDirectory,
848 this, &UIGuestControlFileTable::sltCreateNewDirectory);
849 connect(m_pView, &UIGuestControlFileView::sigCopy,
850 this, &UIGuestControlFileTable::sltCopy);
851 connect(m_pView, &UIGuestControlFileView::sigCut,
852 this, &UIGuestControlFileTable::sltCut);
853 connect(m_pView, &UIGuestControlFileView::sigPaste,
854 this, &UIGuestControlFileTable::sltPaste);
855 connect(m_pView, &UIGuestControlFileView::sigShowProperties,
856 this, &UIGuestControlFileTable::sltShowProperties);
857 connect(m_pView, &UIGuestControlFileView::sigSelectionChanged,
858 this, &UIGuestControlFileTable::sltSelectionChanged);
859
860 }
861 m_pSearchLineEdit = new QILineEdit;
862 if (m_pSearchLineEdit)
863 {
864 m_pMainLayout->addWidget(m_pSearchLineEdit, 8, 0, 1, 5);
865 m_pSearchLineEdit->hide();
866 m_pSearchLineEdit->setClearButtonEnabled(true);
867 connect(m_pSearchLineEdit, &QLineEdit::textChanged,
868 this, &UIGuestControlFileTable::sltSearchTextChanged);
869 }
870}
871
872void UIGuestControlFileTable::updateCurrentLocationEdit(const QString& strLocation)
873{
874 if (!m_pLocationComboBox)
875 return;
876 int itemIndex = m_pLocationComboBox->findText(strLocation,
877 Qt::MatchExactly | Qt::MatchCaseSensitive);
878 if (itemIndex == -1)
879 {
880 m_pLocationComboBox->insertItem(m_pLocationComboBox->count(), strLocation);
881 itemIndex = m_pLocationComboBox->count() - 1;
882 }
883 m_pLocationComboBox->setCurrentIndex(itemIndex);
884}
885
886void UIGuestControlFileTable::changeLocation(const QModelIndex &index)
887{
888 if (!index.isValid() || !m_pView)
889 return;
890 m_pView->setRootIndex(m_pProxyModel->mapFromSource(index));
891 m_pView->clearSelection();
892
893 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());
894 if (item)
895 {
896 updateCurrentLocationEdit(item->path());
897 }
898 /** @todo check if we really need this and if not remove it */
899 //m_pModel->signalUpdate();
900}
901
902void UIGuestControlFileTable::initializeFileTree()
903{
904 if (m_pRootItem)
905 reset();
906
907 /* Root item: */
908 const QString startPath("/");
909 QList<QVariant> headData;
910 headData << "Name" << "Size" << "Change Time" << "Owner" << "Permissions";
911 m_pRootItem = new UIFileTableItem(headData, 0, FileObjectType_Directory);
912 QList<QVariant> startDirData;
913 startDirData << startPath << 4096 << QDateTime() << "" << "";
914 UIFileTableItem* startItem = new UIFileTableItem(startDirData, m_pRootItem, FileObjectType_Directory);
915
916 startItem->setPath(startPath);
917 m_pRootItem->appendChild(startItem);
918 startItem->setIsOpened(false);
919 populateStartDirectory(startItem);
920
921 m_pModel->signalUpdate();
922 updateCurrentLocationEdit(startPath);
923 m_pView->setRootIndex(m_pProxyModel->mapFromSource(m_pModel->rootIndex()));
924}
925
926void UIGuestControlFileTable::populateStartDirectory(UIFileTableItem *startItem)
927{
928 determineDriveLetters();
929 if (m_driveLetterList.isEmpty())
930 {
931 /* Read the root directory and get the list: */
932 readDirectory(startItem->path(), startItem, true);
933 }
934 else
935 {
936 for (int i = 0; i < m_driveLetterList.size(); ++i)
937 {
938 QList<QVariant> data;
939
940 data << m_driveLetterList[i] << 4096 << QDateTime() << "";
941 UIFileTableItem* driveItem = new UIFileTableItem(data, startItem, FileObjectType_Directory);
942 driveItem->setPath(m_driveLetterList[i]);
943 startItem->appendChild(driveItem);
944 driveItem->setIsOpened(false);
945 driveItem->setIsDriveItem(true);
946 startItem->setIsOpened(true);
947 }
948 }
949}
950
951void UIGuestControlFileTable::insertItemsToTree(QMap<QString,UIFileTableItem*> &map,
952 UIFileTableItem *parent, bool isDirectoryMap, bool isStartDir)
953{
954 if (parent)
955
956 /* Make sure we have an item representing up directory, and make sure it is not there for the start dir: */
957 if (isDirectoryMap)
958 {
959 if (!map.contains(UIGuestControlFileModel::strUpDirectoryString) && !isStartDir)
960 {
961 QList<QVariant> data;
962 data << UIGuestControlFileModel::strUpDirectoryString << 4096 << "";
963 UIFileTableItem *item = new UIFileTableItem(data, parent, FileObjectType_Directory);
964 item->setIsOpened(false);
965 map.insert(UIGuestControlFileModel::strUpDirectoryString, item);
966 }
967 else if (map.contains(UIGuestControlFileModel::strUpDirectoryString) && isStartDir)
968 {
969 map.remove(UIGuestControlFileModel::strUpDirectoryString);
970 }
971 }
972 for (QMap<QString,UIFileTableItem*>::const_iterator iterator = map.begin();
973 iterator != map.end(); ++iterator)
974 {
975 if (iterator.key() == "." || iterator.key().isEmpty())
976 continue;
977 parent->appendChild(iterator.value());
978 }
979}
980
981void UIGuestControlFileTable::sltItemDoubleClicked(const QModelIndex &index)
982{
983 if (!index.isValid() || !m_pModel || !m_pView)
984 return;
985 QModelIndex nIndex = m_pProxyModel ? m_pProxyModel->mapToSource(index) : index;
986 goIntoDirectory(nIndex);
987}
988
989void UIGuestControlFileTable::sltItemClicked(const QModelIndex &index)
990{
991 Q_UNUSED(index);
992 disableSelectionSearch();
993}
994
995void UIGuestControlFileTable::sltGoUp()
996{
997 if (!m_pView || !m_pModel)
998 return;
999 QModelIndex currentRoot = currentRootIndex();
1000
1001 if (!currentRoot.isValid())
1002 return;
1003 if (currentRoot != m_pModel->rootIndex())
1004 {
1005 QModelIndex parentIndex = currentRoot.parent();
1006 if (parentIndex.isValid())
1007 {
1008 changeLocation(currentRoot.parent());
1009 m_pView->selectRow(currentRoot.row());
1010 }
1011 }
1012}
1013
1014void UIGuestControlFileTable::sltGoHome()
1015{
1016 goToHomeDirectory();
1017}
1018
1019void UIGuestControlFileTable::sltRefresh()
1020{
1021 refresh();
1022}
1023
1024void UIGuestControlFileTable::goIntoDirectory(const QModelIndex &itemIndex)
1025{
1026 if (!m_pModel)
1027 return;
1028
1029 /* Make sure the colum is 0: */
1030 QModelIndex index = m_pModel->index(itemIndex.row(), 0, itemIndex.parent());
1031 if (!index.isValid())
1032 return;
1033
1034 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());
1035 if (!item)
1036 return;
1037
1038 /* check if we need to go up: */
1039 if (item->isUpDirectory())
1040 {
1041 QModelIndex parentIndex = m_pModel->parent(m_pModel->parent(index));
1042 if (parentIndex.isValid())
1043 changeLocation(parentIndex);
1044 return;
1045 }
1046
1047 if (!item->isDirectory())
1048 return;
1049 if (!item->isOpened())
1050 readDirectory(item->path(),item);
1051 changeLocation(index);
1052}
1053
1054void UIGuestControlFileTable::goIntoDirectory(const QStringList &pathTrail)
1055{
1056 UIFileTableItem *parent = getStartDirectoryItem();
1057
1058 for(int i = 0; i < pathTrail.size(); ++i)
1059 {
1060 if (!parent)
1061 return;
1062 /* Make sure parent is already opened: */
1063 if (!parent->isOpened())
1064 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());
1065 /* search the current path item among the parent's children: */
1066 UIFileTableItem *item = parent->child(pathTrail.at(i));
1067 if (!item)
1068 return;
1069 parent = item;
1070 }
1071 if (!parent)
1072 return;
1073 if (!parent->isOpened())
1074 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());
1075 goIntoDirectory(parent);
1076}
1077
1078void UIGuestControlFileTable::goIntoDirectory(UIFileTableItem *item)
1079{
1080 if (!item || !m_pModel)
1081 return;
1082 goIntoDirectory(m_pModel->index(item));
1083}
1084
1085UIFileTableItem* UIGuestControlFileTable::indexData(const QModelIndex &index) const
1086{
1087 if (!index.isValid())
1088 return 0;
1089 return static_cast<UIFileTableItem*>(index.internalPointer());
1090}
1091
1092void UIGuestControlFileTable::refresh()
1093{
1094 if (!m_pView || !m_pModel)
1095 return;
1096 QModelIndex currentIndex = currentRootIndex();
1097
1098 UIFileTableItem *treeItem = indexData(currentIndex);
1099 if (!treeItem)
1100 return;
1101 bool isRootDir = (m_pModel->rootIndex() == currentIndex);
1102 m_pModel->beginReset();
1103 /* For now we clear the whole subtree (that isrecursively) which is an overkill: */
1104 treeItem->clearChildren();
1105 if (isRootDir)
1106 populateStartDirectory(treeItem);
1107 else
1108 readDirectory(treeItem->path(), treeItem, isRootDir);
1109 m_pModel->endReset();
1110 m_pView->setRootIndex(m_pProxyModel->mapFromSource(currentIndex));
1111 setSelectionDependentActionsEnabled(m_pView->hasSelection());
1112}
1113
1114void UIGuestControlFileTable::sltDelete()
1115{
1116 if (!m_pView || !m_pModel)
1117 return;
1118 QItemSelectionModel *selectionModel = m_pView->selectionModel();
1119 if (!selectionModel)
1120 return;
1121
1122 QModelIndexList selectedItemIndices = selectionModel->selectedRows();
1123 for(int i = 0; i < selectedItemIndices.size(); ++i)
1124 {
1125 QModelIndex index =
1126 m_pProxyModel ? m_pProxyModel->mapToSource(selectedItemIndices.at(i)) : selectedItemIndices.at(i);
1127 deleteByIndex(index);
1128 }
1129 /** @todo dont refresh here, just delete the rows and update the table view: */
1130 refresh();
1131}
1132
1133void UIGuestControlFileTable::sltRename()
1134{
1135 if (!m_pView)
1136 return;
1137 QItemSelectionModel *selectionModel = m_pView->selectionModel();
1138 if (!selectionModel)
1139 return;
1140
1141 QModelIndexList selectedItemIndices = selectionModel->selectedRows();
1142 if (selectedItemIndices.size() == 0)
1143 return;
1144 QModelIndex modelIndex =
1145 m_pProxyModel ? m_pProxyModel->mapToSource(selectedItemIndices.at(0)) : selectedItemIndices.at(0);
1146 UIFileTableItem *item = indexData(modelIndex);
1147 if (!item || item->isUpDirectory())
1148 return;
1149 m_pView->edit(selectedItemIndices.at(0));
1150}
1151
1152void UIGuestControlFileTable::sltCreateNewDirectory()
1153{
1154 if (!m_pModel || !m_pView)
1155 return;
1156 QModelIndex currentIndex = currentRootIndex();
1157 if (!currentIndex.isValid())
1158 return;
1159 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentIndex.internalPointer());
1160 if (!item)
1161 return;
1162
1163 QString newDirectoryName = getNewDirectoryName();
1164 if (newDirectoryName.isEmpty())
1165 return;
1166
1167 if (createDirectory(item->path(), newDirectoryName))
1168 {
1169 /** @todo instead of refreshing here (an overkill) just add the
1170 rows and update the tabel view: */
1171 sltRefresh();
1172 }
1173}
1174
1175void UIGuestControlFileTable::sltCopy()
1176{
1177
1178 m_copyCutBuffer = selectedItemPathList();
1179 // if (!m_copyCutBuffer.isEmpty())
1180 // m_pPaste->setEnabled(true);
1181 // else
1182 // m_pPaste->setEnabled(false);
1183}
1184
1185void UIGuestControlFileTable::sltCut()
1186{
1187 m_copyCutBuffer = selectedItemPathList();
1188 // if (!m_copyCutBuffer.isEmpty())
1189 // m_pPaste->setEnabled(true);
1190 // else
1191 // m_pPaste->setEnabled(false);
1192}
1193
1194void UIGuestControlFileTable::sltPaste()
1195{
1196 // paste them
1197 m_copyCutBuffer.clear();
1198 //m_pPaste->setEnabled(false);
1199}
1200
1201void UIGuestControlFileTable::sltShowProperties()
1202{
1203 showProperties();
1204}
1205
1206void UIGuestControlFileTable::sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
1207{
1208 Q_UNUSED(selected);
1209 Q_UNUSED(deselected);
1210 setSelectionDependentActionsEnabled(m_pView->hasSelection());
1211}
1212
1213void UIGuestControlFileTable::sltLocationComboCurrentChange(const QString &strLocation)
1214{
1215 QString comboLocation(UIPathOperations::sanitize(strLocation));
1216 if (comboLocation == currentDirectoryPath())
1217 return;
1218 goIntoDirectory(UIPathOperations::pathTrail(comboLocation));
1219}
1220
1221void UIGuestControlFileTable::sltSelectAll()
1222{
1223 if (!m_pModel || !m_pView)
1224 return;
1225 m_pView->selectAll();
1226 deSelectUpDirectoryItem();
1227}
1228
1229void UIGuestControlFileTable::sltInvertSelection()
1230{
1231 setSelectionForAll(QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
1232 deSelectUpDirectoryItem();
1233}
1234
1235void UIGuestControlFileTable::sltSearchTextChanged(const QString &strText)
1236{
1237 performSelectionSearch(strText);
1238}
1239
1240void UIGuestControlFileTable::deSelectUpDirectoryItem()
1241{
1242 if (!m_pView)
1243 return;
1244 QItemSelectionModel *pSelectionModel = m_pView->selectionModel();
1245 if (!pSelectionModel)
1246 return;
1247 QModelIndex currentRoot = currentRootIndex();
1248 if (!currentRoot.isValid())
1249 return;
1250
1251 /* Make sure that "up directory item" (if exists) is deselected: */
1252 for (int i = 0; i < m_pModel->rowCount(currentRoot); ++i)
1253 {
1254 QModelIndex index = m_pModel->index(i, 0, currentRoot);
1255 if (!index.isValid())
1256 continue;
1257
1258 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());
1259 if (item && item->isUpDirectory())
1260 {
1261 QModelIndex indexToDeselect = m_pProxyModel ? m_pProxyModel->mapFromSource(index) : index;
1262 pSelectionModel->select(indexToDeselect, QItemSelectionModel::Deselect | QItemSelectionModel::Rows);
1263 }
1264 }
1265}
1266
1267void UIGuestControlFileTable::setSelectionForAll(QItemSelectionModel::SelectionFlags flags)
1268{
1269 if (!m_pView)
1270 return;
1271 QItemSelectionModel *pSelectionModel = m_pView->selectionModel();
1272 if (!pSelectionModel)
1273 return;
1274 QModelIndex currentRoot = currentRootIndex();
1275 if (!currentRoot.isValid())
1276 return;
1277
1278 for (int i = 0; i < m_pModel->rowCount(currentRoot); ++i)
1279 {
1280 QModelIndex index = m_pModel->index(i, 0, currentRoot);
1281 if (!index.isValid())
1282 continue;
1283 QModelIndex indexToSelect = m_pProxyModel ? m_pProxyModel->mapFromSource(index) : index;
1284 pSelectionModel->select(indexToSelect, flags);
1285 }
1286}
1287
1288void UIGuestControlFileTable::setSelection(const QModelIndex &indexInProxyModel)
1289{
1290 if (!m_pView)
1291 return;
1292 QItemSelectionModel *selectionModel = m_pView->selectionModel();
1293 if (!selectionModel)
1294 return;
1295 selectionModel->select(indexInProxyModel, QItemSelectionModel::Current | QItemSelectionModel::Rows | QItemSelectionModel::Select);
1296 m_pView->scrollTo(indexInProxyModel, QAbstractItemView::EnsureVisible);
1297}
1298
1299void UIGuestControlFileTable::deleteByIndex(const QModelIndex &itemIndex)
1300{
1301 UIFileTableItem *treeItem = indexData(itemIndex);
1302 if (!treeItem)
1303 return;
1304 deleteByItem(treeItem);
1305}
1306
1307void UIGuestControlFileTable::retranslateUi()
1308{
1309}
1310
1311bool UIGuestControlFileTable::eventFilter(QObject *pObject, QEvent *pEvent) /* override */
1312{
1313 Q_UNUSED(pObject);
1314 if (pEvent->type() == QEvent::KeyPress)
1315 {
1316 QKeyEvent *pKeyEvent = dynamic_cast<QKeyEvent*>(pEvent);
1317 if (pKeyEvent)
1318 {
1319 if (pKeyEvent->key() == Qt::Key_Enter || pKeyEvent->key() == Qt::Key_Return)
1320 {
1321 if (m_pView && m_pModel)
1322 {
1323 /* Get the selected item. If there are 0 or more than 1 selection do nothing: */
1324 QItemSelectionModel *selectionModel = m_pView->selectionModel();
1325 if (selectionModel)
1326 {
1327 QModelIndexList selectedItemIndices = selectionModel->selectedRows();
1328 if (selectedItemIndices.size() == 1 && m_pModel)
1329 goIntoDirectory( m_pProxyModel->mapToSource(selectedItemIndices.at(0)));
1330 }
1331 }
1332 return true;
1333 }
1334 else if (pKeyEvent->key() == Qt::Key_Delete)
1335 {
1336 sltDelete();
1337 return true;
1338 }
1339 else if (pKeyEvent->key() == Qt::Key_Backspace)
1340 {
1341 sltGoUp();
1342 return true;
1343 }
1344 else if (pKeyEvent->text().length() == 1 && pKeyEvent->text().at(0).unicode() <= 127)
1345 {
1346 if (m_pSearchLineEdit)
1347 {
1348 m_pSearchLineEdit->show();
1349 QString strText = m_pSearchLineEdit->text();
1350 strText.append(pKeyEvent->text());
1351 m_pSearchLineEdit->setText(strText);
1352 }
1353 }
1354 }
1355 }
1356
1357 return false;
1358}
1359
1360UIFileTableItem *UIGuestControlFileTable::getStartDirectoryItem()
1361{
1362 if (!m_pRootItem)
1363 return 0;
1364 if (m_pRootItem->childCount() <= 0)
1365 return 0;
1366 return m_pRootItem->child(0);
1367}
1368
1369
1370QString UIGuestControlFileTable::getNewDirectoryName()
1371{
1372 UIStringInputDialog *dialog = new UIStringInputDialog();
1373 if (dialog->execute())
1374 {
1375 QString strDialog = dialog->getString();
1376 delete dialog;
1377 return strDialog;
1378 }
1379 delete dialog;
1380 return QString();
1381}
1382
1383QString UIGuestControlFileTable::currentDirectoryPath() const
1384{
1385 if (!m_pView)
1386 return QString();
1387 QModelIndex currentRoot = currentRootIndex();
1388 if (!currentRoot.isValid())
1389 return QString();
1390 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentRoot.internalPointer());
1391 if (!item)
1392 return QString();
1393 /* be paranoid: */
1394 if (!item->isDirectory())
1395 return QString();
1396 return item->path();
1397}
1398
1399QStringList UIGuestControlFileTable::selectedItemPathList()
1400{
1401 QItemSelectionModel *selectionModel = m_pView->selectionModel();
1402 if (!selectionModel)
1403 return QStringList();
1404
1405 QStringList pathList;
1406 QModelIndexList selectedItemIndices = selectionModel->selectedRows();
1407 for(int i = 0; i < selectedItemIndices.size(); ++i)
1408 {
1409 QModelIndex index =
1410 m_pProxyModel ? m_pProxyModel->mapToSource(selectedItemIndices.at(i)) : selectedItemIndices.at(i);
1411 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());
1412 if (!item)
1413 continue;
1414 pathList.push_back(item->path());
1415 }
1416 return pathList;
1417}
1418
1419CGuestFsObjInfo UIGuestControlFileTable::guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const
1420{
1421 if (comGuestSession.isNull())
1422 return CGuestFsObjInfo();
1423 CGuestFsObjInfo comFsObjInfo = comGuestSession.FsObjQueryInfo(path, true /*aFollowSymlinks*/);
1424 if (!comFsObjInfo.isOk())
1425 return CGuestFsObjInfo();
1426 return comFsObjInfo;
1427}
1428
1429void UIGuestControlFileTable::setSelectionDependentActionsEnabled(bool fIsEnabled)
1430{
1431 foreach (QAction *pAction, m_selectionDependentActions)
1432 {
1433 pAction->setEnabled(fIsEnabled);
1434 }
1435}
1436
1437QString UIGuestControlFileTable::fileTypeString(FileObjectType type)
1438{
1439 QString strType("Unknown");
1440 switch(type)
1441 {
1442 case FileObjectType_File:
1443 strType = "File";
1444 break;
1445 case FileObjectType_Directory:
1446 strType = "Directory";
1447 break;
1448 case FileObjectType_SymLink:
1449 strType = "Symbolic Link";
1450 break;
1451 case FileObjectType_Other:
1452 strType = "Other";
1453 break;
1454
1455 case FileObjectType_Unknown:
1456 default:
1457 break;
1458 }
1459 return strType;
1460}
1461
1462/* static */ QString UIGuestControlFileTable::humanReadableSize(ULONG64 size)
1463{
1464 int i = 0;
1465 double dSize = size;
1466 const char* units[] = {" B", " kB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"};
1467 while (size > m_iKiloByte) {
1468 size /= m_iKiloByte;
1469 dSize /= (double) m_iKiloByte;
1470 i++;
1471 }
1472 if (i > 8)
1473 return QString();
1474
1475 QString strResult(QString::number(dSize, 'f', 2));
1476 strResult += units[i];
1477 return strResult;
1478}
1479
1480void UIGuestControlFileTable::sltReceiveDirectoryStatistics(UIDirectoryStatistics statistics)
1481{
1482 if (!m_pPropertiesDialog)
1483 return;
1484 m_pPropertiesDialog->addDirectoryStatistics(statistics);
1485}
1486
1487QModelIndex UIGuestControlFileTable::currentRootIndex() const
1488{
1489 if (!m_pView)
1490 return QModelIndex();
1491 if (!m_pProxyModel)
1492 return m_pView->rootIndex();
1493 return m_pProxyModel->mapToSource(m_pView->rootIndex());
1494}
1495
1496void UIGuestControlFileTable::performSelectionSearch(const QString &strSearchText)
1497{
1498 if (!m_pProxyModel | !m_pView || strSearchText.isEmpty())
1499 return;
1500
1501 int rowCount = m_pProxyModel->rowCount(m_pView->rootIndex());
1502 UIFileTableItem *pFoundItem = 0;
1503 QModelIndex index;
1504 for (int i = 0; i < rowCount && !pFoundItem; ++i)
1505 {
1506 index = m_pProxyModel->index(i, 0, m_pView->rootIndex());
1507 if (!index.isValid())
1508 continue;
1509 pFoundItem = static_cast<UIFileTableItem*>(m_pProxyModel->mapToSource(index).internalPointer());
1510 if (!pFoundItem)
1511 continue;
1512 const QString &strName = pFoundItem->name();
1513 if (!strName.startsWith(m_pSearchLineEdit->text(), Qt::CaseInsensitive))
1514 pFoundItem = 0;
1515 }
1516 if (pFoundItem)
1517 {
1518 /* Deselect anything that is already selected: */
1519 m_pView->clearSelection();
1520 setSelection(index);
1521 }
1522}
1523
1524void UIGuestControlFileTable::disableSelectionSearch()
1525{
1526 if (!m_pSearchLineEdit)
1527 return;
1528 m_pSearchLineEdit->blockSignals(true);
1529 m_pSearchLineEdit->clear();
1530 m_pSearchLineEdit->hide();
1531 m_pSearchLineEdit->blockSignals(false);
1532}
1533#include "UIGuestControlFileTable.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