Changeset 76329 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Dec 21, 2018 7:43:48 AM (6 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 6 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r76297 r76329 867 867 src/guestctrl/UIGuestProcessControlWidget.h \ 868 868 src/guestctrl/UIFileManagerHostTable.h \ 869 src/guestctrl/UIPathOperations.h \ 869 870 src/runtime/normal/UIKeyboardHandlerNormal.h \ 870 871 src/runtime/normal/UIMachineLogicNormal.h \ … … 1023 1024 src/guestctrl/UIGuestProcessControlWidget.h \ 1024 1025 src/guestctrl/UIFileManagerHostTable.h \ 1026 src/guestctrl/UIPathOperations.h \ 1025 1027 src/runtime/normal/UIKeyboardHandlerNormal.h \ 1026 1028 src/runtime/normal/UIMachineLogicNormal.h \ … … 1596 1598 src/guestctrl/UIGuestProcessControlWidget.cpp \ 1597 1599 src/guestctrl/UIFileManagerHostTable.cpp \ 1600 src/guestctrl/UIPathOperations.cpp \ 1598 1601 src/runtime/normal/UIKeyboardHandlerNormal.cpp \ 1599 1602 src/runtime/normal/UIMachineLogicNormal.cpp \ … … 1775 1778 src/guestctrl/UIGuestProcessControlDialog.cpp \ 1776 1779 src/guestctrl/UIFileManagerHostTable.cpp \ 1780 src/guestctrl/UIPathOperations.cpp \ 1777 1781 src/runtime/normal/UIKeyboardHandlerNormal.cpp \ 1778 1782 src/runtime/normal/UIMachineLogicNormal.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UICustomFileSystemModel.cpp
r76312 r76329 27 27 # include "UIErrorString.h" 28 28 # include "UICustomFileSystemModel.h" 29 # include "UI FileManagerTable.h"29 # include "UIPathOperations.h" 30 30 # include "VBoxGlobal.h" 31 31 -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerGuestTable.cpp
r76309 r76329 33 33 # include "UIFileManagerGuestTable.h" 34 34 # include "UIMessageCenter.h" 35 # include "UIPathOperations.h" 35 36 # include "UIToolBar.h" 36 37 -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerHostTable.cpp
r76309 r76329 31 31 # include "UICustomFileSystemModel.h" 32 32 # include "UIFileManagerHostTable.h" 33 # include "UIPathOperations.h" 33 34 # include "UIToolBar.h" 34 35 -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerTable.cpp
r76312 r76329 42 42 # include "VBoxGlobal.h" 43 43 # include "UIActionPool.h" 44 # include "UICustomFileSystemModel.h" 44 45 # include "UIErrorString.h" 45 46 # include "UIFileManagerGuestTable.h" 46 # include "UIIconPool.h"47 47 # include "UIFileManagerTable.h" 48 48 # include "UIFileManager.h" 49 # include "UICustomFileSystemModel.h" 49 # include "UIIconPool.h" 50 # include "UIPathOperations.h" 50 51 # include "UIToolBar.h" 51 52 … … 181 182 { 182 183 return m_fOkToContinue; 183 }184 185 186 /*********************************************************************************************************************************187 * UIPathOperations implementation. *188 *********************************************************************************************************************************/189 190 const QChar UIPathOperations::delimiter = QChar('/');191 const QChar UIPathOperations::dosDelimiter = QChar('\\');192 193 /* static */ QString UIPathOperations::removeMultipleDelimiters(const QString &path)194 {195 QString newPath(path);196 QString doubleDelimiter(2, delimiter);197 198 while (newPath.contains(doubleDelimiter) && !newPath.isEmpty())199 newPath = newPath.replace(doubleDelimiter, delimiter);200 return newPath;201 }202 203 /* static */ QString UIPathOperations::removeTrailingDelimiters(const QString &path)204 {205 if (path.isNull() || path.isEmpty())206 return QString();207 QString newPath(path);208 /* Make sure for we dont have any trailing delimiters: */209 while (newPath.length() > 1 && newPath.at(newPath.length() - 1) == UIPathOperations::delimiter)210 newPath.chop(1);211 return newPath;212 }213 214 /* static */ QString UIPathOperations::addTrailingDelimiters(const QString &path)215 {216 if (path.isNull() || path.isEmpty())217 return QString();218 QString newPath(path);219 while (newPath.length() > 1 && newPath.at(newPath.length() - 1) != UIPathOperations::delimiter)220 newPath += UIPathOperations::delimiter;221 return newPath;222 }223 224 /* static */ QString UIPathOperations::addStartDelimiter(const QString &path)225 {226 if (path.isEmpty())227 return QString(path);228 QString newPath(path);229 230 if (doesPathStartWithDriveLetter(newPath))231 {232 if (newPath.at(newPath.length() - 1) != delimiter)233 newPath += delimiter;234 return newPath;235 }236 if (newPath.at(0) != delimiter)237 newPath.insert(0, delimiter);238 return newPath;239 }240 241 /* static */ QString UIPathOperations::sanitize(const QString &path)242 {243 //return addStartDelimiter(removeTrailingDelimiters(removeMultipleDelimiters(path)));244 QString newPath = addStartDelimiter(removeTrailingDelimiters(removeMultipleDelimiters(path))).replace(dosDelimiter, delimiter);245 return newPath;246 }247 248 /* static */ QString UIPathOperations::mergePaths(const QString &path, const QString &baseName)249 {250 QString newBase(baseName);251 newBase = newBase.remove(delimiter);252 253 /* make sure we have one and only one trailing '/': */254 QString newPath(sanitize(path));255 if(newPath.isEmpty())256 newPath = delimiter;257 if(newPath.at(newPath.length() - 1) != delimiter)258 newPath += UIPathOperations::delimiter;259 newPath += newBase;260 return sanitize(newPath);261 }262 263 /* static */ QString UIPathOperations::getObjectName(const QString &path)264 {265 if (path.length() <= 1)266 return QString(path);267 268 QString strTemp(sanitize(path));269 if (strTemp.length() < 2)270 return strTemp;271 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);272 if (lastSlashPosition == -1)273 return QString();274 return strTemp.right(strTemp.length() - lastSlashPosition - 1);275 }276 277 /* static */ QString UIPathOperations::getPathExceptObjectName(const QString &path)278 {279 if (path.length() <= 1)280 return QString(path);281 282 QString strTemp(sanitize(path));283 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);284 if (lastSlashPosition == -1)285 return QString();286 return strTemp.left(lastSlashPosition + 1);287 }288 289 /* static */ QString UIPathOperations::constructNewItemPath(const QString &previousPath, const QString &newBaseName)290 {291 if (previousPath.length() <= 1)292 return QString(previousPath);293 return sanitize(mergePaths(getPathExceptObjectName(previousPath), newBaseName));294 }295 296 /* static */ QStringList UIPathOperations::pathTrail(const QString &path)297 {298 QStringList pathList = path.split(UIPathOperations::delimiter, QString::SkipEmptyParts);299 if (!pathList.isEmpty() && doesPathStartWithDriveLetter(pathList[0]))300 {301 pathList[0] = addTrailingDelimiters(pathList[0]);302 }303 return pathList;304 }305 306 /* static */ bool UIPathOperations::doesPathStartWithDriveLetter(const QString &path)307 {308 if (path.length() < 2)309 return false;310 /* search for ':' with the path: */311 if (!path[0].isLetter())312 return false;313 if (path[1] != ':')314 return false;315 return true;316 184 } 317 185 -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerTable.h
r76312 r76329 116 116 private: 117 117 118 QVBoxLayout 119 QTextEdit *m_pInfoEdit;120 QString m_strProperty;118 QVBoxLayout *m_pMainLayout; 119 QTextEdit *m_pInfoEdit; 120 QString m_strProperty; 121 121 }; 122 122 123 /** A collection of simple utility functions to manipulate path strings */124 class UIPathOperations125 {126 public:127 static QString removeMultipleDelimiters(const QString &path);128 static QString removeTrailingDelimiters(const QString &path);129 static QString addTrailingDelimiters(const QString &path);130 static QString addStartDelimiter(const QString &path);131 132 static QString sanitize(const QString &path);133 /** Merges prefix and suffix by making sure they have a single '/' in between */134 static QString mergePaths(const QString &path, const QString &baseName);135 /** Returns the last part of the @p path. That is the filename or directory name without the path */136 static QString getObjectName(const QString &path);137 /** Removes the object name and return the path */138 static QString getPathExceptObjectName(const QString &path);139 /** Replaces the last part of the @p previusPath with newBaseName */140 static QString constructNewItemPath(const QString &previousPath, const QString &newBaseName);141 /** Splits the path and return it as a QStringList, top most being the 0th element. No delimiters */142 static QStringList pathTrail(const QString &path);143 static const QChar delimiter;144 static const QChar dosDelimiter;145 146 /** Tries to determine if the path starts with DOS style drive letters. */147 static bool doesPathStartWithDriveLetter(const QString &path);148 149 };150 123 151 124 /** This class serves a base class for file table. Currently a guest version -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIPathOperations.cpp
r76312 r76329 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI FileManagerTableclass implementation.3 * VBox Qt GUI - UIPathOperations class implementation. 4 4 */ 5 5 … … 21 21 22 22 /* Qt includes: */ 23 # include <QAction> 24 # include <QComboBox> 25 # include <QCheckBox> 26 # include <QDateTime> 27 # include <QDir> 28 # include <QHeaderView> 29 # include <QItemDelegate> 30 # include <QGridLayout> 31 # include <QMenu> 32 # include <QSortFilterProxyModel> 33 # include <QTextEdit> 34 # include <QPushButton> 23 # include <QList> 35 24 36 25 /* GUI includes: */ 37 # include "QIDialog.h" 38 # include "QIDialogButtonBox.h" 39 # include "QILabel.h" 40 # include "QILineEdit.h" 41 # include "QIMessageBox.h" 42 # include "VBoxGlobal.h" 43 # include "UIActionPool.h" 44 # include "UIErrorString.h" 45 # include "UIFileManagerGuestTable.h" 46 # include "UIIconPool.h" 47 # include "UIFileManagerTable.h" 48 # include "UIFileManager.h" 49 # include "UICustomFileSystemModel.h" 50 # include "UIToolBar.h" 51 52 /* COM includes: */ 53 # include "CFsObjInfo.h" 54 # include "CGuestFsObjInfo.h" 55 # include "CGuestDirectory.h" 56 # include "CProgress.h" 26 # include "UIPathOperations.h" 57 27 58 28 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 59 60 61 62 /*********************************************************************************************************************************63 * UIGuestControlFileView definition. *64 *********************************************************************************************************************************/65 66 /** Using QITableView causes the following problem when I click on the table items67 Qt WARNING: Cannot creat accessible child interface for object: UIGuestControlFileView.....68 so for now subclass QTableView */69 class UIGuestControlFileView : public QTableView70 {71 72 Q_OBJECT;73 74 signals:75 76 void sigSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);77 78 public:79 80 UIGuestControlFileView(QWidget * parent = 0);81 bool hasSelection() const;82 83 protected:84 85 virtual void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected) /*override */;86 87 private:88 89 void configure();90 QWidget *m_pParent;91 };92 93 94 /*********************************************************************************************************************************95 * UIFileDelegate definition. *96 *********************************************************************************************************************************/97 /** A QItemDelegate child class to disable dashed lines drawn around selected cells in QTableViews */98 class UIFileDelegate : public QItemDelegate99 {100 101 Q_OBJECT;102 103 protected:104 105 virtual void drawFocus ( QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, const QRect & /*rect*/ ) const {}106 107 };108 109 110 /*********************************************************************************************************************************111 * UStringInputDialog definition. *112 *********************************************************************************************************************************/113 114 /** A QIDialog child including a line edit whose text exposed when the dialog is accepted */115 class UIStringInputDialog : public QIDialog116 {117 118 Q_OBJECT;119 120 public:121 122 UIStringInputDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);123 QString getString() const;124 125 private:126 127 QILineEdit *m_pLineEdit;128 129 };130 131 132 /*********************************************************************************************************************************133 * UIFileDeleteConfirmationDialog definition. *134 *********************************************************************************************************************************/135 136 /** A QIDialog child including a line edit whose text exposed when the dialog is accepted */137 class UIFileDeleteConfirmationDialog : public QIDialog138 {139 140 Q_OBJECT;141 142 public:143 144 UIFileDeleteConfirmationDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);145 /** Returns whether m_pAskNextTimeCheckBox is checked or not. */146 bool askDeleteConfirmationNextTime() const;147 148 private:149 150 QCheckBox *m_pAskNextTimeCheckBox;151 QILabel *m_pQuestionLabel;152 153 };154 155 156 /*********************************************************************************************************************************157 * UIHostDirectoryDiskUsageComputer implementation. *158 *********************************************************************************************************************************/159 160 UIDirectoryDiskUsageComputer::UIDirectoryDiskUsageComputer(QObject *parent, QStringList pathList)161 :QThread(parent)162 , m_pathList(pathList)163 , m_fOkToContinue(true)164 {165 }166 167 void UIDirectoryDiskUsageComputer::run()168 {169 for (int i = 0; i < m_pathList.size(); ++i)170 directoryStatisticsRecursive(m_pathList[i], m_resultStatistics);171 }172 173 void UIDirectoryDiskUsageComputer::stopRecursion()174 {175 m_mutex.lock();176 m_fOkToContinue = false;177 m_mutex.unlock();178 }179 180 bool UIDirectoryDiskUsageComputer::isOkToContinue() const181 {182 return m_fOkToContinue;183 }184 185 186 /*********************************************************************************************************************************187 * UIPathOperations implementation. *188 *********************************************************************************************************************************/189 29 190 30 const QChar UIPathOperations::delimiter = QChar('/'); … … 315 155 return true; 316 156 } 317 318 319 /*********************************************************************************************************************************320 * UIGuestControlFileView implementation. *321 *********************************************************************************************************************************/322 323 UIGuestControlFileView::UIGuestControlFileView(QWidget *parent)324 :QTableView(parent)325 , m_pParent(parent)326 {327 configure();328 }329 330 void UIGuestControlFileView::configure()331 {332 setContextMenuPolicy(Qt::CustomContextMenu);333 setShowGrid(false);334 setSelectionBehavior(QAbstractItemView::SelectRows);335 verticalHeader()->setVisible(false);336 setEditTriggers(QAbstractItemView::NoEditTriggers);337 /* Minimize the row height: */338 verticalHeader()->setDefaultSectionSize(verticalHeader()->minimumSectionSize());339 setAlternatingRowColors(true);340 installEventFilter(m_pParent);341 }342 343 bool UIGuestControlFileView::hasSelection() const344 {345 QItemSelectionModel *pSelectionModel = selectionModel();346 if (!pSelectionModel)347 return false;348 return pSelectionModel->hasSelection();349 }350 351 void UIGuestControlFileView::selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)352 {353 emit sigSelectionChanged(selected, deselected);354 QTableView::selectionChanged(selected, deselected);355 }356 357 358 /*********************************************************************************************************************************359 * UIFileStringInputDialog implementation. *360 *********************************************************************************************************************************/361 362 UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)363 :QIDialog(pParent, flags)364 {365 QVBoxLayout *layout = new QVBoxLayout(this);366 m_pLineEdit = new QILineEdit(this);367 layout->addWidget(m_pLineEdit);368 369 QIDialogButtonBox *pButtonBox =370 new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);371 layout->addWidget(pButtonBox);372 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);373 connect(pButtonBox, &QIDialogButtonBox::rejected, this, &UIStringInputDialog::reject);374 }375 376 QString UIStringInputDialog::getString() const377 {378 if (!m_pLineEdit)379 return QString();380 return m_pLineEdit->text();381 }382 383 384 /*********************************************************************************************************************************385 * UIPropertiesDialog implementation. *386 *********************************************************************************************************************************/387 388 UIPropertiesDialog::UIPropertiesDialog(QWidget *pParent, Qt::WindowFlags flags)389 :QIDialog(pParent, flags)390 , m_pMainLayout(new QVBoxLayout)391 , m_pInfoEdit(new QTextEdit)392 {393 setLayout(m_pMainLayout);394 395 if (m_pMainLayout)396 m_pMainLayout->addWidget(m_pInfoEdit);397 if (m_pInfoEdit)398 {399 m_pInfoEdit->setReadOnly(true);400 m_pInfoEdit->setFrameStyle(QFrame::NoFrame);401 }402 QIDialogButtonBox *pButtonBox =403 new QIDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this);404 m_pMainLayout->addWidget(pButtonBox);405 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);406 }407 408 void UIPropertiesDialog::setPropertyText(const QString &strProperty)409 {410 if (!m_pInfoEdit)411 return;412 m_strProperty = strProperty;413 m_pInfoEdit->setHtml(strProperty);414 }415 416 void UIPropertiesDialog::addDirectoryStatistics(UIDirectoryStatistics directoryStatistics)417 {418 if (!m_pInfoEdit)419 return;420 // QString propertyString = m_pInfoEdit->toHtml();421 // propertyString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");422 // if (directoryStatistics.m_totalSize >= UIFileManagerTable::m_iKiloByte)423 // propertyString += " (" + UIFileManagerTable::humanReadableSize(directoryStatistics.m_totalSize) + ")";424 // propertyString += "<br/>";425 // propertyString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);426 427 // m_pInfoEdit->setHtml(propertyString);428 429 QString detailsString(m_strProperty);430 detailsString += "<br/>";431 detailsString += "<b>" + UIFileManager::tr("Total Size") + "</b> " +432 QString::number(directoryStatistics.m_totalSize) + UIFileManager::tr(" bytes");433 if (directoryStatistics.m_totalSize >= UIFileManagerTable::m_iKiloByte)434 detailsString += " (" + UIFileManagerTable::humanReadableSize(directoryStatistics.m_totalSize) + ")";435 detailsString += "<br/>";436 437 detailsString += "<b>" + UIFileManager::tr("File Count") + ":</b> " +438 QString::number(directoryStatistics.m_uFileCount);439 440 m_pInfoEdit->setHtml(detailsString);441 }442 443 444 /*********************************************************************************************************************************445 * UIDirectoryStatistics implementation. *446 *********************************************************************************************************************************/447 448 UIDirectoryStatistics::UIDirectoryStatistics()449 : m_totalSize(0)450 , m_uFileCount(0)451 , m_uDirectoryCount(0)452 , m_uSymlinkCount(0)453 {454 }455 456 /*********************************************************************************************************************************457 +* UIFileDeleteConfirmationDialog implementation. *458 +*********************************************************************************************************************************/459 460 UIFileDeleteConfirmationDialog::UIFileDeleteConfirmationDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)461 :QIDialog(pParent, flags)462 , m_pAskNextTimeCheckBox(0)463 , m_pQuestionLabel(0)464 {465 QVBoxLayout *pLayout = new QVBoxLayout(this);466 467 m_pQuestionLabel = new QILabel;468 if (m_pQuestionLabel)469 {470 pLayout->addWidget(m_pQuestionLabel);471 m_pQuestionLabel->setText(UIFileManager::tr("Delete the selected file(s) and/or folder(s)"));472 }473 474 QIDialogButtonBox *pButtonBox =475 new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);476 if (pButtonBox)477 {478 pLayout->addWidget(pButtonBox, 0, Qt::AlignCenter);479 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);480 connect(pButtonBox, &QIDialogButtonBox::rejected, this, &UIStringInputDialog::reject);481 }482 483 m_pAskNextTimeCheckBox = new QCheckBox;484 485 if (m_pAskNextTimeCheckBox)486 {487 UIFileManagerOptions *pFileManagerOptions = UIFileManagerOptions::instance();488 if (pFileManagerOptions)489 m_pAskNextTimeCheckBox->setChecked(pFileManagerOptions->bAskDeleteConfirmation);490 491 pLayout->addWidget(m_pAskNextTimeCheckBox);492 m_pAskNextTimeCheckBox->setText(UIFileManager::tr("Ask for this confirmation next time"));493 m_pAskNextTimeCheckBox->setToolTip(UIFileManager::tr("Delete confirmation can be "494 "disabled/enabled also from the Options panel."));495 }496 }497 498 bool UIFileDeleteConfirmationDialog::askDeleteConfirmationNextTime() const499 {500 if (!m_pAskNextTimeCheckBox)501 return true;502 return m_pAskNextTimeCheckBox->isChecked();503 }504 505 506 /*********************************************************************************************************************************507 * UIFileManagerTable implementation. *508 *********************************************************************************************************************************/509 const unsigned UIFileManagerTable::m_iKiloByte = 1024; /**< Our kilo bytes are a power of two! (bird) */510 UIFileManagerTable::UIFileManagerTable(UIActionPool *pActionPool, QWidget *pParent /* = 0 */)511 :QIWithRetranslateUI<QWidget>(pParent)512 , m_eFileOperationType(FileOperationType_None)513 , m_pLocationLabel(0)514 , m_pPropertiesDialog(0)515 , m_pActionPool(pActionPool)516 , m_pToolBar(0)517 , m_pModel(0)518 , m_pView(0)519 , m_pProxyModel(0)520 , m_pMainLayout(0)521 , m_pLocationComboBox(0)522 , m_pWarningLabel(0)523 {524 prepareObjects();525 }526 527 UIFileManagerTable::~UIFileManagerTable()528 {529 }530 531 void UIFileManagerTable::reset()532 {533 if (m_pModel)534 m_pModel->reset();535 536 if (m_pLocationComboBox)537 {538 disconnect(m_pLocationComboBox, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),539 this, &UIFileManagerTable::sltLocationComboCurrentChange);540 m_pLocationComboBox->clear();541 connect(m_pLocationComboBox, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),542 this, &UIFileManagerTable::sltLocationComboCurrentChange);543 }544 }545 546 void UIFileManagerTable::emitLogOutput(const QString& strOutput, FileManagerLogType eLogType)547 {548 emit sigLogOutput(strOutput, eLogType);549 }550 551 void UIFileManagerTable::prepareObjects()552 {553 m_pMainLayout = new QGridLayout();554 if (!m_pMainLayout)555 return;556 m_pMainLayout->setSpacing(0);557 m_pMainLayout->setContentsMargins(0, 0, 0, 0);558 setLayout(m_pMainLayout);559 560 m_pToolBar = new UIToolBar;561 if (m_pToolBar)562 {563 m_pMainLayout->addWidget(m_pToolBar, 0, 0, 1, 5);564 }565 566 m_pLocationLabel = new QILabel;567 if (m_pLocationLabel)568 {569 m_pMainLayout->addWidget(m_pLocationLabel, 1, 0, 1, 1);570 }571 572 m_pLocationComboBox = new QComboBox;573 if (m_pLocationComboBox)574 {575 m_pMainLayout->addWidget(m_pLocationComboBox, 1, 1, 1, 4);576 m_pLocationComboBox->setEditable(false);577 connect(m_pLocationComboBox, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),578 this, &UIFileManagerTable::sltLocationComboCurrentChange);579 }580 581 582 m_pModel = new UICustomFileSystemModel(this);583 if (!m_pModel)584 return;585 connect(m_pModel, &UICustomFileSystemModel::sigItemRenamed,586 this, &UIFileManagerTable::sltHandleItemRenameAttempt);587 588 m_pProxyModel = new UICustomFileSystemProxyModel(this);589 if (!m_pProxyModel)590 return;591 m_pProxyModel->setSourceModel(m_pModel);592 593 m_pView = new UIGuestControlFileView(this);594 if (m_pView)595 {596 m_pMainLayout->addWidget(m_pView, 2, 0, 5, 5);597 598 QHeaderView *pHorizontalHeader = m_pView->horizontalHeader();599 if (pHorizontalHeader)600 pHorizontalHeader->setHighlightSections(false);601 602 m_pView->setModel(m_pProxyModel);603 m_pView->setItemDelegate(new UIFileDelegate);604 m_pView->setSortingEnabled(true);605 m_pView->sortByColumn(0, Qt::AscendingOrder);606 607 connect(m_pView, &UIGuestControlFileView::doubleClicked,608 this, &UIFileManagerTable::sltItemDoubleClicked);609 connect(m_pView, &UIGuestControlFileView::clicked,610 this, &UIFileManagerTable::sltItemClicked);611 connect(m_pView, &UIGuestControlFileView::sigSelectionChanged,612 this, &UIFileManagerTable::sltSelectionChanged);613 connect(m_pView, &UIGuestControlFileView::customContextMenuRequested,614 this, &UIFileManagerTable::sltCreateFileViewContextMenu);615 616 }617 m_pWarningLabel = new QILabel(this);618 if (m_pWarningLabel)619 {620 m_pMainLayout->addWidget(m_pWarningLabel, 2, 0, 5, 5);621 QFont labelFont = m_pWarningLabel->font();622 float fSizeMultiplier = 2.5;623 if (labelFont.pointSize() != -1)624 labelFont.setPointSize(fSizeMultiplier * labelFont.pointSize());625 else626 labelFont.setPixelSize(fSizeMultiplier * labelFont.pixelSize());627 labelFont.setBold(true);628 m_pWarningLabel->setFont(labelFont);629 m_pWarningLabel->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);630 m_pWarningLabel->setWordWrap(true);631 }632 m_pWarningLabel->setVisible(!isEnabled());633 m_pView->setVisible(isEnabled());634 635 m_pSearchLineEdit = new QILineEdit;636 if (m_pSearchLineEdit)637 {638 m_pMainLayout->addWidget(m_pSearchLineEdit, 8, 0, 1, 5);639 m_pSearchLineEdit->hide();640 m_pSearchLineEdit->setClearButtonEnabled(true);641 connect(m_pSearchLineEdit, &QLineEdit::textChanged,642 this, &UIFileManagerTable::sltSearchTextChanged);643 }644 optionsUpdated();645 }646 647 void UIFileManagerTable::updateCurrentLocationEdit(const QString& strLocation)648 {649 if (!m_pLocationComboBox)650 return;651 int itemIndex = m_pLocationComboBox->findText(strLocation,652 Qt::MatchExactly | Qt::MatchCaseSensitive);653 if (itemIndex == -1)654 {655 m_pLocationComboBox->insertItem(m_pLocationComboBox->count(), strLocation);656 itemIndex = m_pLocationComboBox->count() - 1;657 }658 m_pLocationComboBox->setCurrentIndex(itemIndex);659 }660 661 void UIFileManagerTable::changeLocation(const QModelIndex &index)662 {663 if (!index.isValid() || !m_pView)664 return;665 m_pView->setRootIndex(m_pProxyModel->mapFromSource(index));666 m_pView->clearSelection();667 668 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());669 if (item)670 {671 updateCurrentLocationEdit(item->path());672 }673 /** @todo check if we really need this and if not remove it */674 //m_pModel->signalUpdate();675 }676 677 void UIFileManagerTable::initializeFileTree()678 {679 if (m_pModel)680 m_pModel->reset();681 if (!rootItem())682 return;683 684 const QString startPath("/");685 UIFileTableItem* startItem = new UIFileTableItem(createTreeItemData(startPath, 4096, QDateTime(),686 "" /* owner */, "" /* permissions */),687 rootItem(), KFsObjType_Directory);688 startItem->setPath(startPath);689 rootItem()->appendChild(startItem);690 startItem->setIsOpened(false);691 populateStartDirectory(startItem);692 693 m_pModel->signalUpdate();694 updateCurrentLocationEdit(startPath);695 m_pView->setRootIndex(m_pProxyModel->mapFromSource(m_pModel->rootIndex()));696 }697 698 void UIFileManagerTable::populateStartDirectory(UIFileTableItem *startItem)699 {700 determineDriveLetters();701 if (m_driveLetterList.isEmpty())702 {703 /* Read the root directory and get the list: */704 readDirectory(startItem->path(), startItem, true);705 }706 else707 {708 for (int i = 0; i < m_driveLetterList.size(); ++i)709 {710 UIFileTableItem* driveItem = new UIFileTableItem(createTreeItemData(m_driveLetterList[i], 4096,711 QDateTime(), QString(), QString()),712 startItem, KFsObjType_Directory);713 driveItem->setPath(m_driveLetterList[i]);714 startItem->appendChild(driveItem);715 driveItem->setIsOpened(false);716 driveItem->setIsDriveItem(true);717 startItem->setIsOpened(true);718 }719 }720 }721 722 void UIFileManagerTable::insertItemsToTree(QMap<QString,UIFileTableItem*> &map,723 UIFileTableItem *parent, bool isDirectoryMap, bool isStartDir)724 {725 if (parent)726 727 /* Make sure we have an item representing up directory, and make sure it is not there for the start dir: */728 if (isDirectoryMap)729 {730 if (!map.contains(UICustomFileSystemModel::strUpDirectoryString) && !isStartDir)731 {732 QVector<QVariant> data;733 UIFileTableItem *item = new UIFileTableItem(createTreeItemData(UICustomFileSystemModel::strUpDirectoryString, 4096,734 QDateTime(), QString(), QString())735 , parent, KFsObjType_Directory);736 item->setIsOpened(false);737 map.insert(UICustomFileSystemModel::strUpDirectoryString, item);738 }739 else if (map.contains(UICustomFileSystemModel::strUpDirectoryString) && isStartDir)740 {741 map.remove(UICustomFileSystemModel::strUpDirectoryString);742 }743 }744 for (QMap<QString,UIFileTableItem*>::const_iterator iterator = map.begin();745 iterator != map.end(); ++iterator)746 {747 if (iterator.key() == "." || iterator.key().isEmpty())748 continue;749 parent->appendChild(iterator.value());750 }751 }752 753 void UIFileManagerTable::sltItemDoubleClicked(const QModelIndex &index)754 {755 if (!index.isValid() || !m_pModel || !m_pView)756 return;757 QModelIndex nIndex = m_pProxyModel ? m_pProxyModel->mapToSource(index) : index;758 goIntoDirectory(nIndex);759 }760 761 void UIFileManagerTable::sltItemClicked(const QModelIndex &index)762 {763 Q_UNUSED(index);764 disableSelectionSearch();765 }766 767 void UIFileManagerTable::sltGoUp()768 {769 if (!m_pView || !m_pModel)770 return;771 QModelIndex currentRoot = currentRootIndex();772 773 if (!currentRoot.isValid())774 return;775 if (currentRoot != m_pModel->rootIndex())776 {777 QModelIndex parentIndex = currentRoot.parent();778 if (parentIndex.isValid())779 {780 changeLocation(currentRoot.parent());781 m_pView->selectRow(currentRoot.row());782 }783 }784 }785 786 void UIFileManagerTable::sltGoHome()787 {788 goToHomeDirectory();789 }790 791 void UIFileManagerTable::sltRefresh()792 {793 refresh();794 }795 796 void UIFileManagerTable::goIntoDirectory(const QModelIndex &itemIndex)797 {798 if (!m_pModel)799 return;800 801 /* Make sure the colum is 0: */802 QModelIndex index = m_pModel->index(itemIndex.row(), 0, itemIndex.parent());803 if (!index.isValid())804 return;805 806 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());807 if (!item)808 return;809 810 /* check if we need to go up: */811 if (item->isUpDirectory())812 {813 QModelIndex parentIndex = m_pModel->parent(m_pModel->parent(index));814 if (parentIndex.isValid())815 changeLocation(parentIndex);816 return;817 }818 819 if (item->isDirectory() || item->isSymLinkToADirectory())820 {821 if (!item->isOpened())822 readDirectory(item->path(),item);823 changeLocation(index);824 }825 }826 827 void UIFileManagerTable::goIntoDirectory(const QStringList &pathTrail)828 {829 UIFileTableItem *parent = getStartDirectoryItem();830 831 for(int i = 0; i < pathTrail.size(); ++i)832 {833 if (!parent)834 return;835 /* Make sure parent is already opened: */836 if (!parent->isOpened())837 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());838 /* search the current path item among the parent's children: */839 UIFileTableItem *item = parent->child(pathTrail.at(i));840 if (!item)841 return;842 parent = item;843 }844 if (!parent)845 return;846 if (!parent->isOpened())847 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());848 goIntoDirectory(parent);849 }850 851 void UIFileManagerTable::goIntoDirectory(UIFileTableItem *item)852 {853 if (!item || !m_pModel)854 return;855 goIntoDirectory(m_pModel->index(item));856 }857 858 UIFileTableItem* UIFileManagerTable::indexData(const QModelIndex &index) const859 {860 if (!index.isValid())861 return 0;862 return static_cast<UIFileTableItem*>(index.internalPointer());863 }864 865 void UIFileManagerTable::refresh()866 {867 if (!m_pView || !m_pModel)868 return;869 QModelIndex currentIndex = currentRootIndex();870 871 UIFileTableItem *treeItem = indexData(currentIndex);872 if (!treeItem)873 return;874 bool isRootDir = (m_pModel->rootIndex() == currentIndex);875 m_pModel->beginReset();876 /* For now we clear the whole subtree (that isrecursively) which is an overkill: */877 treeItem->clearChildren();878 if (isRootDir)879 populateStartDirectory(treeItem);880 else881 readDirectory(treeItem->path(), treeItem, isRootDir);882 m_pModel->endReset();883 m_pView->setRootIndex(m_pProxyModel->mapFromSource(currentIndex));884 setSelectionDependentActionsEnabled(m_pView->hasSelection());885 }886 887 void UIFileManagerTable::relist()888 {889 if (!m_pProxyModel)890 return;891 m_pProxyModel->invalidate();892 }893 894 void UIFileManagerTable::sltDelete()895 {896 if (!checkIfDeleteOK())897 return;898 899 if (!m_pView || !m_pModel)900 return;901 902 if (!m_pView || !m_pModel)903 return;904 QItemSelectionModel *selectionModel = m_pView->selectionModel();905 if (!selectionModel)906 return;907 908 QModelIndexList selectedItemIndices = selectionModel->selectedRows();909 for(int i = 0; i < selectedItemIndices.size(); ++i)910 {911 QModelIndex index =912 m_pProxyModel ? m_pProxyModel->mapToSource(selectedItemIndices.at(i)) : selectedItemIndices.at(i);913 deleteByIndex(index);914 }915 /** @todo dont refresh here, just delete the rows and update the table view: */916 refresh();917 }918 919 void UIFileManagerTable::sltRename()920 {921 if (!m_pView || !m_pModel)922 return;923 QItemSelectionModel *selectionModel = m_pView->selectionModel();924 if (!selectionModel)925 return;926 927 QModelIndexList selectedItemIndices = selectionModel->selectedRows();928 if (selectedItemIndices.size() == 0)929 return;930 QModelIndex modelIndex =931 m_pProxyModel ? m_pProxyModel->mapToSource(selectedItemIndices.at(0)) : selectedItemIndices.at(0);932 UIFileTableItem *item = indexData(modelIndex);933 if (!item || item->isUpDirectory())934 return;935 m_pView->edit(selectedItemIndices.at(0));936 }937 938 void UIFileManagerTable::sltCreateNewDirectory()939 {940 if (!m_pModel || !m_pView)941 return;942 QModelIndex currentIndex = currentRootIndex();943 if (!currentIndex.isValid())944 return;945 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentIndex.internalPointer());946 if (!item)947 return;948 949 QString newDirectoryName = getNewDirectoryName();950 if (newDirectoryName.isEmpty())951 return;952 953 if (createDirectory(item->path(), newDirectoryName))954 {955 /** @todo instead of refreshing here (an overkill) just add the956 rows and update the tabel view: */957 sltRefresh();958 }959 }960 961 void UIFileManagerTable::sltCopy()962 {963 m_copyCutBuffer = selectedItemPathList();964 m_eFileOperationType = FileOperationType_Copy;965 setPasteActionEnabled(true);966 }967 968 void UIFileManagerTable::sltCut()969 {970 m_copyCutBuffer = selectedItemPathList();971 m_eFileOperationType = FileOperationType_Cut;972 setPasteActionEnabled(true);973 }974 975 void UIFileManagerTable::sltPaste()976 {977 m_copyCutBuffer.clear();978 979 m_eFileOperationType = FileOperationType_None;980 setPasteActionEnabled(false);981 }982 983 void UIFileManagerTable::sltShowProperties()984 {985 showProperties();986 }987 988 void UIFileManagerTable::sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)989 {990 Q_UNUSED(selected);991 Q_UNUSED(deselected);992 setSelectionDependentActionsEnabled(m_pView->hasSelection());993 }994 995 void UIFileManagerTable::sltLocationComboCurrentChange(const QString &strLocation)996 {997 QString comboLocation(UIPathOperations::sanitize(strLocation));998 if (comboLocation == currentDirectoryPath())999 return;1000 goIntoDirectory(UIPathOperations::pathTrail(comboLocation));1001 }1002 1003 void UIFileManagerTable::sltSelectAll()1004 {1005 if (!m_pModel || !m_pView)1006 return;1007 m_pView->selectAll();1008 deSelectUpDirectoryItem();1009 }1010 1011 void UIFileManagerTable::sltInvertSelection()1012 {1013 setSelectionForAll(QItemSelectionModel::Toggle | QItemSelectionModel::Rows);1014 deSelectUpDirectoryItem();1015 }1016 1017 void UIFileManagerTable::sltSearchTextChanged(const QString &strText)1018 {1019 performSelectionSearch(strText);1020 }1021 1022 void UIFileManagerTable::sltHandleItemRenameAttempt(UIFileTableItem *pItem, QString strOldName, QString strNewName)1023 {1024 if (!pItem)1025 return;1026 /* Attempt to chage item name in the file system: */1027 if (!renameItem(pItem, strNewName))1028 {1029 /* Restore the previous name. relist the view: */1030 pItem->setData(strOldName, static_cast<int>(UICustomFileSystemModelColumn_Name));1031 relist();1032 sigLogOutput(QString(pItem->path()).append(" could not be renamed"), FileManagerLogType_Error);1033 }1034 }1035 1036 1037 void UIFileManagerTable::sltCreateFileViewContextMenu(const QPoint &point)1038 {1039 QWidget *pSender = qobject_cast<QWidget*>(sender());1040 if (!pSender)1041 return;1042 createFileViewContextMenu(pSender, point);1043 }1044 1045 void UIFileManagerTable::deSelectUpDirectoryItem()1046 {1047 if (!m_pView)1048 return;1049 QItemSelectionModel *pSelectionModel = m_pView->selectionModel();1050 if (!pSelectionModel)1051 return;1052 QModelIndex currentRoot = currentRootIndex();1053 if (!currentRoot.isValid())1054 return;1055 1056 /* Make sure that "up directory item" (if exists) is deselected: */1057 for (int i = 0; i < m_pModel->rowCount(currentRoot); ++i)1058 {1059 QModelIndex index = m_pModel->index(i, 0, currentRoot);1060 if (!index.isValid())1061 continue;1062 1063 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());1064 if (item && item->isUpDirectory())1065 {1066 QModelIndex indexToDeselect = m_pProxyModel ? m_pProxyModel->mapFromSource(index) : index;1067 pSelectionModel->select(indexToDeselect, QItemSelectionModel::Deselect | QItemSelectionModel::Rows);1068 }1069 }1070 }1071 1072 void UIFileManagerTable::setSelectionForAll(QItemSelectionModel::SelectionFlags flags)1073 {1074 if (!m_pView)1075 return;1076 QItemSelectionModel *pSelectionModel = m_pView->selectionModel();1077 if (!pSelectionModel)1078 return;1079 QModelIndex currentRoot = currentRootIndex();1080 if (!currentRoot.isValid())1081 return;1082 1083 for (int i = 0; i < m_pModel->rowCount(currentRoot); ++i)1084 {1085 QModelIndex index = m_pModel->index(i, 0, currentRoot);1086 if (!index.isValid())1087 continue;1088 QModelIndex indexToSelect = m_pProxyModel ? m_pProxyModel->mapFromSource(index) : index;1089 pSelectionModel->select(indexToSelect, flags);1090 }1091 }1092 1093 void UIFileManagerTable::setSelection(const QModelIndex &indexInProxyModel)1094 {1095 if (!m_pView)1096 return;1097 QItemSelectionModel *selectionModel = m_pView->selectionModel();1098 if (!selectionModel)1099 return;1100 selectionModel->select(indexInProxyModel, QItemSelectionModel::Current | QItemSelectionModel::Rows | QItemSelectionModel::Select);1101 m_pView->scrollTo(indexInProxyModel, QAbstractItemView::EnsureVisible);1102 }1103 1104 void UIFileManagerTable::deleteByIndex(const QModelIndex &itemIndex)1105 {1106 UIFileTableItem *treeItem = indexData(itemIndex);1107 if (!treeItem)1108 return;1109 deleteByItem(treeItem);1110 }1111 1112 void UIFileManagerTable::retranslateUi()1113 {1114 UIFileTableItem *pRootItem = rootItem();1115 if (pRootItem)1116 {1117 pRootItem->setData(UIFileManager::tr("Name"), UICustomFileSystemModelColumn_Name);1118 pRootItem->setData(UIFileManager::tr("Size"), UICustomFileSystemModelColumn_Size);1119 pRootItem->setData(UIFileManager::tr("Change Time"), UICustomFileSystemModelColumn_ChangeTime);1120 pRootItem->setData(UIFileManager::tr("Owner"), UICustomFileSystemModelColumn_Owner);1121 pRootItem->setData(UIFileManager::tr("Permissions"), UICustomFileSystemModelColumn_Permissions);1122 }1123 if (m_pWarningLabel)1124 m_pWarningLabel->setText(UIFileManager::tr("No Guest Session"));1125 }1126 1127 bool UIFileManagerTable::eventFilter(QObject *pObject, QEvent *pEvent) /* override */1128 {1129 Q_UNUSED(pObject);1130 if (pEvent->type() == QEvent::KeyPress)1131 {1132 QKeyEvent *pKeyEvent = dynamic_cast<QKeyEvent*>(pEvent);1133 if (pKeyEvent)1134 {1135 if (pKeyEvent->key() == Qt::Key_Enter || pKeyEvent->key() == Qt::Key_Return)1136 {1137 if (m_pView && m_pModel)1138 {1139 /* Get the selected item. If there are 0 or more than 1 selection do nothing: */1140 QItemSelectionModel *selectionModel = m_pView->selectionModel();1141 if (selectionModel)1142 {1143 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1144 if (selectedItemIndices.size() == 1 && m_pModel)1145 goIntoDirectory( m_pProxyModel->mapToSource(selectedItemIndices.at(0)));1146 }1147 }1148 return true;1149 }1150 else if (pKeyEvent->key() == Qt::Key_Delete)1151 {1152 sltDelete();1153 return true;1154 }1155 else if (pKeyEvent->key() == Qt::Key_Backspace)1156 {1157 sltGoUp();1158 return true;1159 }1160 else if (pKeyEvent->text().length() == 1 &&1161 (pKeyEvent->text().at(0).isDigit() ||1162 pKeyEvent->text().at(0).isLetter()))1163 {1164 if (m_pSearchLineEdit)1165 {1166 m_pSearchLineEdit->show();1167 QString strText = m_pSearchLineEdit->text();1168 strText.append(pKeyEvent->text());1169 m_pSearchLineEdit->setText(strText);1170 }1171 }1172 else if (pKeyEvent->key() == Qt::Key_Tab)1173 {1174 return true;1175 }1176 }/* if (pKeyEvent) */1177 }/* if (pEvent->type() == QEvent::KeyPress) */1178 else if (pEvent->type() == QEvent::FocusOut)1179 {1180 disableSelectionSearch();1181 }1182 /* Dont hold up the @pEvent but rather send it to the target @pObject: */1183 return false;1184 }1185 1186 UIFileTableItem *UIFileManagerTable::getStartDirectoryItem()1187 {1188 UIFileTableItem* pRootItem = rootItem();1189 if (!pRootItem)1190 return 0;1191 if (pRootItem->childCount() <= 0)1192 return 0;1193 return pRootItem->child(0);1194 }1195 1196 1197 QString UIFileManagerTable::getNewDirectoryName()1198 {1199 UIStringInputDialog *dialog = new UIStringInputDialog();1200 if (dialog->execute())1201 {1202 QString strDialog = dialog->getString();1203 delete dialog;1204 return strDialog;1205 }1206 delete dialog;1207 return QString();1208 }1209 1210 QString UIFileManagerTable::currentDirectoryPath() const1211 {1212 if (!m_pView)1213 return QString();1214 QModelIndex currentRoot = currentRootIndex();1215 if (!currentRoot.isValid())1216 return QString();1217 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentRoot.internalPointer());1218 if (!item)1219 return QString();1220 /* be paranoid: */1221 if (!item->isDirectory())1222 return QString();1223 return item->path();1224 }1225 1226 QStringList UIFileManagerTable::selectedItemPathList()1227 {1228 QItemSelectionModel *selectionModel = m_pView->selectionModel();1229 if (!selectionModel)1230 return QStringList();1231 1232 QStringList pathList;1233 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1234 for(int i = 0; i < selectedItemIndices.size(); ++i)1235 {1236 QModelIndex index =1237 m_pProxyModel ? m_pProxyModel->mapToSource(selectedItemIndices.at(i)) : selectedItemIndices.at(i);1238 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());1239 if (!item)1240 continue;1241 pathList.push_back(item->path());1242 }1243 return pathList;1244 }1245 1246 CGuestFsObjInfo UIFileManagerTable::guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const1247 {1248 if (comGuestSession.isNull())1249 return CGuestFsObjInfo();1250 CGuestFsObjInfo comFsObjInfo = comGuestSession.FsObjQueryInfo(path, true /*aFollowSymlinks*/);1251 if (!comFsObjInfo.isOk())1252 return CGuestFsObjInfo();1253 return comFsObjInfo;1254 }1255 1256 void UIFileManagerTable::setSelectionDependentActionsEnabled(bool fIsEnabled)1257 {1258 foreach (QAction *pAction, m_selectionDependentActions)1259 {1260 pAction->setEnabled(fIsEnabled);1261 }1262 }1263 1264 QVector<QVariant> UIFileManagerTable::createTreeItemData(const QString &strName, ULONG64 size, const QDateTime &changeTime,1265 const QString &strOwner, const QString &strPermissions)1266 {1267 QVector<QVariant> data;1268 data.resize(UICustomFileSystemModelColumn_Max);1269 data[UICustomFileSystemModelColumn_Name] = strName;1270 data[UICustomFileSystemModelColumn_Size] = (qulonglong)size;1271 data[UICustomFileSystemModelColumn_ChangeTime] = changeTime;1272 data[UICustomFileSystemModelColumn_Owner] = strOwner;1273 data[UICustomFileSystemModelColumn_Permissions] = strPermissions;1274 return data;1275 }1276 1277 UIFileTableItem* UIFileManagerTable::rootItem()1278 {1279 if (!m_pModel)1280 return 0;1281 return m_pModel->rootItem();1282 }1283 1284 bool UIFileManagerTable::event(QEvent *pEvent)1285 {1286 if (pEvent->type() == QEvent::EnabledChange)1287 {1288 m_pWarningLabel->setVisible(!isEnabled());1289 m_pView->setVisible(isEnabled());1290 retranslateUi();1291 }1292 return QIWithRetranslateUI<QWidget>::event(pEvent);1293 }1294 1295 QString UIFileManagerTable::fileTypeString(KFsObjType type)1296 {1297 QString strType = UIFileManager::tr("Unknown");1298 switch (type)1299 {1300 case KFsObjType_File:1301 strType = UIFileManager::tr("File");1302 break;1303 case KFsObjType_Directory:1304 strType = UIFileManager::tr("Directory");1305 break;1306 case KFsObjType_Symlink:1307 strType = UIFileManager::tr("Symbolic Link");1308 break;1309 case KFsObjType_Unknown:1310 default:1311 strType = UIFileManager::tr("Unknown");1312 break;1313 }1314 return strType;1315 }1316 1317 /* static */ QString UIFileManagerTable::humanReadableSize(ULONG64 size)1318 {1319 return vboxGlobal().formatSize(size);1320 }1321 1322 void UIFileManagerTable::optionsUpdated()1323 {1324 UIFileManagerOptions *pOptions = UIFileManagerOptions::instance();1325 if (pOptions)1326 {1327 if (m_pProxyModel)1328 m_pProxyModel->setListDirectoriesOnTop(pOptions->bListDirectoriesOnTop);1329 if (m_pModel)1330 m_pModel->setShowHumanReadableSizes(pOptions->bShowHumanReadableSizes);1331 }1332 relist();1333 }1334 1335 1336 void UIFileManagerTable::sltReceiveDirectoryStatistics(UIDirectoryStatistics statistics)1337 {1338 if (!m_pPropertiesDialog)1339 return;1340 m_pPropertiesDialog->addDirectoryStatistics(statistics);1341 }1342 1343 QModelIndex UIFileManagerTable::currentRootIndex() const1344 {1345 if (!m_pView)1346 return QModelIndex();1347 if (!m_pProxyModel)1348 return m_pView->rootIndex();1349 return m_pProxyModel->mapToSource(m_pView->rootIndex());1350 }1351 1352 void UIFileManagerTable::performSelectionSearch(const QString &strSearchText)1353 {1354 if (!m_pProxyModel | !m_pView || strSearchText.isEmpty())1355 return;1356 1357 int rowCount = m_pProxyModel->rowCount(m_pView->rootIndex());1358 UIFileTableItem *pFoundItem = 0;1359 QModelIndex index;1360 for (int i = 0; i < rowCount && !pFoundItem; ++i)1361 {1362 index = m_pProxyModel->index(i, 0, m_pView->rootIndex());1363 if (!index.isValid())1364 continue;1365 pFoundItem = static_cast<UIFileTableItem*>(m_pProxyModel->mapToSource(index).internalPointer());1366 if (!pFoundItem)1367 continue;1368 const QString &strName = pFoundItem->name();1369 if (!strName.startsWith(m_pSearchLineEdit->text(), Qt::CaseInsensitive))1370 pFoundItem = 0;1371 }1372 if (pFoundItem)1373 {1374 /* Deselect anything that is already selected: */1375 m_pView->clearSelection();1376 setSelection(index);1377 }1378 }1379 1380 void UIFileManagerTable::disableSelectionSearch()1381 {1382 if (!m_pSearchLineEdit)1383 return;1384 m_pSearchLineEdit->blockSignals(true);1385 m_pSearchLineEdit->clear();1386 m_pSearchLineEdit->hide();1387 m_pSearchLineEdit->blockSignals(false);1388 }1389 1390 bool UIFileManagerTable::checkIfDeleteOK()1391 {1392 UIFileManagerOptions *pFileManagerOptions = UIFileManagerOptions::instance();1393 if (!pFileManagerOptions)1394 return true;1395 if (!pFileManagerOptions->bAskDeleteConfirmation)1396 return true;1397 UIFileDeleteConfirmationDialog *pDialog =1398 new UIFileDeleteConfirmationDialog(this);1399 1400 bool fContinueWithDelete = (pDialog->execute() == QDialog::Accepted);1401 bool bAskNextTime = pDialog->askDeleteConfirmationNextTime();1402 1403 /* Update the file manager options only if it is necessary: */1404 if (pFileManagerOptions->bAskDeleteConfirmation != bAskNextTime)1405 {1406 pFileManagerOptions->bAskDeleteConfirmation = bAskNextTime;1407 /* Notify file manager options panel so that the check box there is updated: */1408 emit sigDeleteConfirmationOptionChanged();1409 }1410 1411 delete pDialog;1412 1413 return fContinueWithDelete;1414 1415 }1416 1417 #include "UIFileManagerTable.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIPathOperations.h
r76312 r76329 16 16 */ 17 17 18 #ifndef ___UI FileManagerTable_h___19 #define ___UI FileManagerTable_h___18 #ifndef ___UIPathOperations_h___ 19 #define ___UIPathOperations_h___ 20 20 21 21 /* Qt includes: */ 22 #include <QItemSelectionModel> 23 #include <QMutex> 24 #include <QThread> 25 #include <QWidget> 22 #include <QString> 26 23 27 /* COM includes: */28 #include "COMEnums.h"29 #include "CGuestSession.h"30 31 /* GUI includes: */32 #include "QIDialog.h"33 #include "QITableView.h"34 #include "QIWithRetranslateUI.h"35 #include "UIGuestControlDefs.h"36 37 /* Forward declarations: */38 class QAction;39 class QFileInfo;40 class QComboBox;41 class QILabel;42 class QILineEdit;43 class QGridLayout;44 class QSortFilterProxyModel;45 class QTextEdit;46 class QVBoxLayout;47 class UIActionPool;48 class UIFileTableItem;49 class UICustomFileSystemModel;50 class UICustomFileSystemProxyModel;51 class UIGuestControlFileView;52 class UIToolBar;53 54 /** A simple struck to store some statictics for a directory. Mainly used by UIDirectoryDiskUsageComputer instances. */55 class UIDirectoryStatistics56 {57 public:58 UIDirectoryStatistics();59 ULONG64 m_totalSize;60 unsigned m_uFileCount;61 unsigned m_uDirectoryCount;62 unsigned m_uSymlinkCount;63 };64 65 Q_DECLARE_METATYPE(UIDirectoryStatistics);66 67 68 /** Examines the paths in @p strStartPath and collects some staticstics from them recursively (in case directories)69 * Runs on a worker thread to avoid GUI freezes. UIGuestFileTable and UIHostFileTable uses specialized children70 * of this class since the calls made on file objects are different. */71 class UIDirectoryDiskUsageComputer : public QThread72 {73 Q_OBJECT;74 75 signals:76 77 void sigResultUpdated(UIDirectoryStatistics);78 79 public:80 81 UIDirectoryDiskUsageComputer(QObject *parent, QStringList strStartPath);82 /** Sets the m_fOkToContinue to false. This results an early termination83 * of the directoryStatisticsRecursive member function. */84 void stopRecursion();85 86 protected:87 88 /** Read the directory with the path @p path recursively and collect #of objects and total size */89 virtual void directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics) = 0;90 virtual void run() /* override */;91 /** Returns the m_fOkToContinue flag */92 bool isOkToContinue() const;93 /** Stores a list of paths whose statistics are accumulated, can be file, directory etc: */94 QStringList m_pathList;95 UIDirectoryStatistics m_resultStatistics;96 QMutex m_mutex;97 98 private:99 100 bool m_fOkToContinue;101 };102 103 104 /** A QIDialog child to display properties of a file object */105 class UIPropertiesDialog : public QIDialog106 {107 108 Q_OBJECT;109 110 public:111 112 UIPropertiesDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);113 void setPropertyText(const QString &strProperty);114 void addDirectoryStatistics(UIDirectoryStatistics statictics);115 116 private:117 118 QVBoxLayout *m_pMainLayout;119 QTextEdit *m_pInfoEdit;120 QString m_strProperty;121 };122 24 123 25 /** A collection of simple utility functions to manipulate path strings */ … … 129 31 static QString addTrailingDelimiters(const QString &path); 130 32 static QString addStartDelimiter(const QString &path); 131 132 33 static QString sanitize(const QString &path); 133 34 /** Merges prefix and suffix by making sure they have a single '/' in between */ … … 143 44 static const QChar delimiter; 144 45 static const QChar dosDelimiter; 145 146 46 /** Tries to determine if the path starts with DOS style drive letters. */ 147 47 static bool doesPathStartWithDriveLetter(const QString &path); … … 149 49 }; 150 50 151 /** This class serves a base class for file table. Currently a guest version 152 * and a host version are derived from this base. Each of these children 153 * populates the UICustomFileSystemModel by scanning the file system 154 * differently. The file structre kept in this class as a tree. */ 155 class UIFileManagerTable : public QIWithRetranslateUI<QWidget> 156 { 157 Q_OBJECT; 158 159 signals: 160 161 void sigLogOutput(QString strLog, FileManagerLogType eLogType); 162 void sigDeleteConfirmationOptionChanged(); 163 164 public: 165 166 UIFileManagerTable(UIActionPool *pActionPool, QWidget *pParent = 0); 167 virtual ~UIFileManagerTable(); 168 /** Deletes all the tree nodes */ 169 void reset(); 170 void emitLogOutput(const QString& strOutput, FileManagerLogType eLogType); 171 /** Returns the path of the rootIndex */ 172 QString currentDirectoryPath() const; 173 /** Returns the paths of the selected items (if any) as a list */ 174 QStringList selectedItemPathList(); 175 virtual void refresh(); 176 static const unsigned m_iKiloByte; 177 static QString humanReadableSize(ULONG64 size); 178 /** Peroforms whatever is necessary after a UIFileManagerOptions change. */ 179 void optionsUpdated(); 180 181 public slots: 182 183 void sltReceiveDirectoryStatistics(UIDirectoryStatistics statictics); 184 void sltCreateNewDirectory(); 185 /* index is passed by the item view and represents the double clicked object's 'proxy' model index */ 186 void sltItemDoubleClicked(const QModelIndex &index); 187 void sltItemClicked(const QModelIndex &index); 188 void sltGoUp(); 189 void sltGoHome(); 190 void sltRefresh(); 191 void sltDelete(); 192 /** Calls the edit on the data item over m_pView. This causes setData(..) call on the model. After setting 193 * user entered text as the name of the item m_pModel signals. This signal is handled by sltHandleItemRenameAttempt which 194 * tries to rename the corresponding file object by calling renameItem(...). If this rename fails the old name of the 195 * model item is restored and view is refreshed by sltHandleItemRenameAttempt. */ 196 void sltRename(); 197 void sltCopy(); 198 void sltCut(); 199 void sltPaste(); 200 void sltShowProperties(); 201 void sltSelectAll(); 202 void sltInvertSelection(); 203 204 protected: 205 206 /** This enum is used when performing a gueest-to-guest or host-to-host 207 * file operations. Paths of source file objects are kept in a single buffer 208 * and a flag to determine if it is a cut or copy operation is needed */ 209 enum FileOperationType 210 { 211 FileOperationType_Copy, 212 FileOperationType_Cut, 213 FileOperationType_None, 214 FileOperationType_Max 215 }; 216 217 void retranslateUi(); 218 void updateCurrentLocationEdit(const QString& strLocation); 219 /* @p index is for model not for 'proxy' model */ 220 void changeLocation(const QModelIndex &index); 221 void initializeFileTree(); 222 void insertItemsToTree(QMap<QString,UIFileTableItem*> &map, UIFileTableItem *parent, 223 bool isDirectoryMap, bool isStartDir); 224 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) = 0; 225 virtual void deleteByItem(UIFileTableItem *item) = 0; 226 virtual void deleteByPath(const QStringList &pathList) = 0; 227 virtual void goToHomeDirectory() = 0; 228 virtual bool renameItem(UIFileTableItem *item, QString newBaseName) = 0; 229 virtual bool createDirectory(const QString &path, const QString &directoryName) = 0; 230 virtual QString fsObjectPropertyString() = 0; 231 virtual void showProperties() = 0; 232 /** For non-windows system does nothing and for windows systems populates m_driveLetterList with 233 * drive letters */ 234 virtual void determineDriveLetters() = 0; 235 virtual void prepareToolbar() = 0; 236 virtual void createFileViewContextMenu(const QWidget *pWidget, const QPoint &point) = 0; 237 virtual bool event(QEvent *pEvent) /* override */; 238 239 /** @name Copy/Cut guest-to-guest (host-to-host) stuff. 240 * @{ */ 241 /** Disable/enable paste action depending on the m_eFileOperationType. */ 242 virtual void setPasteActionEnabled(bool fEnabled) = 0; 243 virtual void pasteCutCopiedObjects() = 0; 244 /** stores the type of the pending guest-to-guest (host-to-host) file operation. */ 245 FileOperationType m_eFileOperationType; 246 /** @} */ 247 248 QString fileTypeString(KFsObjType type); 249 /* @p item index is item location in model not in 'proxy' model */ 250 void goIntoDirectory(const QModelIndex &itemIndex); 251 /** Follows the path trail, opens directories as it descends */ 252 void goIntoDirectory(const QStringList &pathTrail); 253 /** Goes into directory pointed by the @p item */ 254 void goIntoDirectory(UIFileTableItem *item); 255 UIFileTableItem* indexData(const QModelIndex &index) const; 256 bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */; 257 CGuestFsObjInfo guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const; 258 void setSelectionDependentActionsEnabled(bool fIsEnabled); 259 /** Creates a QList out of the parameters wrt. UICustomFileSystemModelColumn enum */ 260 QVector<QVariant> createTreeItemData(const QString &strName, ULONG64 size, const QDateTime &changeTime, 261 const QString &strOwner, const QString &strPermissions); 262 UIFileTableItem* rootItem(); 263 264 265 QILabel *m_pLocationLabel; 266 UIPropertiesDialog *m_pPropertiesDialog; 267 UIActionPool *m_pActionPool; 268 UIToolBar *m_pToolBar; 269 270 /** Stores the drive letters the file system has (for windows system). For non-windows 271 * systems this is empty and for windows system it should at least contain C:/ */ 272 QStringList m_driveLetterList; 273 /** The set of actions which need some selection to work on. Like cut, copy etc. */ 274 QSet<QAction*> m_selectionDependentActions; 275 /** The absolue path list of the file objects which user has chosen to cut/copy. this 276 * list will be cleaned after a paste operation or overwritten by a subsequent cut/copy. 277 * Currently only used by the guest side. */ 278 QStringList m_copyCutBuffer; 279 280 private slots: 281 282 void sltCreateFileViewContextMenu(const QPoint &point); 283 void sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); 284 void sltLocationComboCurrentChange(const QString &strLocation); 285 void sltSearchTextChanged(const QString &strText); 286 /** m_pModel signals when an tree item is renamed. we try to apply this rename to the file system. 287 * if the file system rename fails we restore the old name of the item. See the comment of 288 * sltRename() for more details. */ 289 void sltHandleItemRenameAttempt(UIFileTableItem *pItem, QString strOldName, QString strNewName); 290 291 private: 292 293 void relist(); 294 void prepareObjects(); 295 /** @p itemIndex is assumed to be 'model' index not 'proxy model' index */ 296 void deleteByIndex(const QModelIndex &itemIndex); 297 /** Returns the UIFileTableItem for path / which is a direct (and single) child of m_pRootItem */ 298 UIFileTableItem *getStartDirectoryItem(); 299 /** Shows a modal dialog with a line edit for user to enter a new directory name and return the entered string*/ 300 QString getNewDirectoryName(); 301 void deSelectUpDirectoryItem(); 302 void setSelectionForAll(QItemSelectionModel::SelectionFlags flags); 303 void setSelection(const QModelIndex &indexInProxyModel); 304 /** The start directory requires a special attention since on file systems with drive letters 305 * drive letter are direct children of the start directory. On other systems start directory is '/' */ 306 void populateStartDirectory(UIFileTableItem *startItem); 307 /** Root index of the m_pModel */ 308 QModelIndex currentRootIndex() const; 309 /* Searches the content of m_pSearchLineEdit within the current items' names and selects the item if found. */ 310 void performSelectionSearch(const QString &strSearchText); 311 /** Clears the m_pSearchLineEdit and hides it. */ 312 void disableSelectionSearch(); 313 /** Checks if delete confirmation dialog is shown and users choice. Returns true 314 * if deletion can continue */ 315 bool checkIfDeleteOK(); 316 317 UICustomFileSystemModel *m_pModel; 318 UIGuestControlFileView *m_pView; 319 UICustomFileSystemProxyModel *m_pProxyModel; 320 321 QGridLayout *m_pMainLayout; 322 QComboBox *m_pLocationComboBox; 323 QILineEdit *m_pSearchLineEdit; 324 QILabel *m_pWarningLabel; 325 326 friend class UICustomFileSystemModel; 327 }; 328 329 #endif /* !___UIFileManagerTable_h___ */ 51 #endif /* !___UIPathOperations_h___ */
Note:
See TracChangeset
for help on using the changeset viewer.