Changeset 71388 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Mar 20, 2018 10:16:28 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121352
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 4 edited
- 4 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r71360 r71388 406 406 src/runtime/guestctrl/UIGuestControlTreeItem.h \ 407 407 src/runtime/guestctrl/UIGuestControlWidget.h \ 408 src/runtime/guestctrl/UIGuestFileTable.h \ 409 src/runtime/guestctrl/UIHostFileTable.h \ 408 410 src/runtime/normal/UIKeyboardHandlerNormal.h \ 409 411 src/runtime/normal/UIMachineLogicNormal.h \ … … 752 754 src/runtime/guestctrl/UIGuestControlTreeItem.cpp \ 753 755 src/runtime/guestctrl/UIGuestControlWidget.cpp \ 756 src/runtime/guestctrl/UIGuestFileTable.cpp \ 757 src/runtime/guestctrl/UIHostFileTable.cpp \ 754 758 src/runtime/normal/UIKeyboardHandlerNormal.cpp \ 755 759 src/runtime/normal/UIMachineLogicNormal.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileManager.cpp
r71350 r71388 36 36 # include "UIIconPool.h" 37 37 # include "UIGuestControlFileManager.h" 38 # include "UIGuestControlFileTable.h" 38 # include "UIGuestFileTable.h" 39 # include "UIHostFileTable.h" 39 40 # include "UIGuestControlInterface.h" 40 41 # include "UIToolBar.h" … … 50 51 # include "CGuestSession.h" 51 52 # include "CGuestSessionStateChangedEvent.h" 52 53 54 55 56 57 58 53 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 59 60 54 61 55 class UIGuestSessionCreateWidget : public QIWithRetranslateUI<QWidget> -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.cpp
r71385 r71388 52 52 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 53 53 54 55 /*********************************************************************************************************************************56 * UIPathOperations definition. *57 *********************************************************************************************************************************/58 59 /** A collection of utility functions for so60 me path string manipulations */61 class UIPathOperations62 {63 public:64 static QString removeMultipleDelimiters(const QString &path);65 static QString removeTrailingDelimiters(const QString &path);66 static QString addStartDelimiter(const QString &path);67 68 static QString sanitize(const QString &path);69 /** Merge prefix and suffix by making sure they have a single '/' in between */70 static QString mergePaths(const QString &path, const QString &baseName);71 /** Returns the last part of the @p path. That is the filename or directory name without the path */72 static QString getObjectName(const QString &path);73 /** Remove the object name and return the path */74 static QString getPathExceptObjectName(const QString &path);75 /** Replace the last part of the @p previusPath with newBaseName */76 static QString constructNewItemPath(const QString &previousPath, const QString &newBaseName);77 78 static const QChar delimiter;79 };80 54 81 55 … … 1359 1333 } 1360 1334 1361 1362 /*********************************************************************************************************************************1363 * UIGuestFileTable implementation. *1364 *********************************************************************************************************************************/1365 1366 UIGuestFileTable::UIGuestFileTable(QWidget *pParent /*= 0*/)1367 :UIGuestControlFileTable(pParent)1368 {1369 retranslateUi();1370 }1371 1372 void UIGuestFileTable::initGuestFileTable(const CGuestSession &session)1373 {1374 if (!session.isOk())1375 return;1376 if (session.GetStatus() != KGuestSessionStatus_Started)1377 return;1378 m_comGuestSession = session;1379 1380 1381 initializeFileTree();1382 }1383 1384 void UIGuestFileTable::retranslateUi()1385 {1386 if (m_pLocationLabel)1387 m_pLocationLabel->setText(UIVMInformationDialog::tr("Guest System"));1388 UIGuestControlFileTable::retranslateUi();1389 }1390 1391 void UIGuestFileTable::readDirectory(const QString& strPath,1392 UIFileTableItem *parent, bool isStartDir /*= false*/)1393 1394 {1395 if (!parent)1396 return;1397 1398 CGuestDirectory directory;1399 QVector<KDirectoryOpenFlag> flag;1400 flag.push_back(KDirectoryOpenFlag_None);1401 1402 directory = m_comGuestSession.DirectoryOpen(strPath, /*aFilter*/ "", flag);1403 parent->setIsOpened(true);1404 if (directory.isOk())1405 {1406 CFsObjInfo fsInfo = directory.Read();1407 QMap<QString, UIFileTableItem*> directories;1408 QMap<QString, UIFileTableItem*> files;1409 1410 while (fsInfo.isOk())1411 {1412 QList<QVariant> data;1413 QDateTime changeTime = QDateTime::fromMSecsSinceEpoch(fsInfo.GetChangeTime()/1000000);1414 1415 data << fsInfo.GetName() << static_cast<qulonglong>(fsInfo.GetObjectSize()) << changeTime;1416 FileObjectType fsObjectType = fileType(fsInfo);1417 UIFileTableItem *item = new UIFileTableItem(data, parent, fsObjectType);1418 item->setPath(UIPathOperations::mergePaths(strPath, fsInfo.GetName()));1419 if (fsObjectType == FileObjectType_Directory)1420 {1421 directories.insert(fsInfo.GetName(), item);1422 item->setIsOpened(false);1423 }1424 else if(fsObjectType == FileObjectType_File)1425 {1426 files.insert(fsInfo.GetName(), item);1427 item->setIsOpened(false);1428 }1429 /** @todo Seems like our API is not able to detect symlinks: */1430 else if(fsObjectType == FileObjectType_SymLink)1431 {1432 files.insert(fsInfo.GetName(), item);1433 item->setIsOpened(false);1434 }1435 1436 fsInfo = directory.Read();1437 }1438 insertItemsToTree(directories, parent, true, isStartDir);1439 insertItemsToTree(files, parent, false, isStartDir);1440 updateCurrentLocationEdit(strPath);1441 }1442 directory.Close();1443 }1444 1445 void UIGuestFileTable::deleteByItem(UIFileTableItem *item)1446 {1447 if (!item)1448 return;1449 if (!m_comGuestSession.isOk())1450 return;1451 if (item->isUpDirectory())1452 return;1453 QVector<KDirectoryRemoveRecFlag> flags(KDirectoryRemoveRecFlag_ContentAndDir);1454 1455 if (item->isDirectory())1456 {1457 m_comGuestSession.DirectoryRemoveRecursive(item->path(), flags);1458 }1459 else1460 m_comGuestSession.FsObjRemove(item->path());1461 if (!m_comGuestSession.isOk())1462 emit sigLogOutput(QString(item->path()).append(" could not be deleted"));1463 1464 }1465 1466 void UIGuestFileTable::goToHomeDirectory()1467 {1468 if (m_comGuestSession.isNull())1469 return;1470 if (!m_pRootItem || m_pRootItem->childCount() <= 0)1471 return;1472 UIFileTableItem *startDirItem = m_pRootItem->child(0);1473 if (!startDirItem)1474 return;1475 1476 QString userHome = UIPathOperations::sanitize(m_comGuestSession.GetUserHome());1477 QList<QString> pathTrail = userHome.split(UIPathOperations::delimiter);1478 1479 goIntoDirectory(pathTrail);1480 }1481 1482 bool UIGuestFileTable::renameItem(UIFileTableItem *item, QString newBaseName)1483 {1484 1485 if (!item || item->isUpDirectory() || newBaseName.isEmpty() || !m_comGuestSession.isOk())1486 return false;1487 QString newPath = UIPathOperations::constructNewItemPath(item->path(), newBaseName);1488 QVector<KFsObjRenameFlag> aFlags(KFsObjRenameFlag_Replace);1489 1490 m_comGuestSession.FsObjRename(item->path(), newPath, aFlags);1491 if (!m_comGuestSession.isOk())1492 return false;1493 item->setPath(newPath);1494 return true;1495 }1496 1497 bool UIGuestFileTable::createDirectory(const QString &path, const QString &directoryName)1498 {1499 if (!m_comGuestSession.isOk())1500 return false;1501 1502 QString newDirectoryPath = UIPathOperations::mergePaths(path, directoryName);1503 QVector<KDirectoryCreateFlag> flags(KDirectoryCreateFlag_None);1504 1505 m_comGuestSession.DirectoryCreate(newDirectoryPath, 777/*aMode*/, flags);1506 if (!m_comGuestSession.isOk())1507 {1508 emit sigLogOutput(newDirectoryPath.append(" could not be created"));1509 return false;1510 }1511 emit sigLogOutput(newDirectoryPath.append(" has been created"));1512 return true;1513 }1514 1515 void UIGuestFileTable::copyGuestToHost(const QString& hostDestinationPath)1516 {1517 QStringList selectedPathList = selectedItemPathList();1518 for (int i = 0; i < selectedPathList.size(); ++i)1519 copyGuestToHost(selectedPathList.at(i), hostDestinationPath);1520 }1521 1522 void UIGuestFileTable::copyHostToGuest(const QStringList &hostSourcePathList)1523 {1524 for (int i = 0; i < hostSourcePathList.size(); ++i)1525 copyHostToGuest(hostSourcePathList.at(i), currentDirectoryPath());1526 }1527 1528 bool UIGuestFileTable::copyGuestToHost(const QString &guestSourcePath, const QString& hostDestinationPath)1529 {1530 if (m_comGuestSession.isNull())1531 return false;1532 1533 /* Currently API expects a path including a file name for file copy*/1534 CGuestFsObjInfo fileInfo = guestFsObjectInfo(guestSourcePath, m_comGuestSession);1535 KFsObjType objectType = fileInfo.GetType();1536 if (objectType == KFsObjType_File)1537 {1538 QVector<KFileCopyFlag> flags(KFileCopyFlag_FollowLinks);1539 /* API expects a full file path as destionation: */1540 QString destinatioFilePath = UIPathOperations::mergePaths(hostDestinationPath, UIPathOperations::getObjectName(guestSourcePath));1541 /** @todo listen to CProgress object to monitor copy operation: */1542 /*CProgress comProgress =*/ m_comGuestSession.FileCopyFromGuest(guestSourcePath, destinatioFilePath, flags);1543 1544 }1545 else if (objectType == KFsObjType_Directory)1546 {1547 QVector<KDirectoryCopyFlag> aFlags(KDirectoryCopyFlag_CopyIntoExisting);1548 /** @todo listen to CProgress object to monitor copy operation: */1549 /*CProgress comProgress = */ m_comGuestSession.DirectoryCopyFromGuest(guestSourcePath, hostDestinationPath, aFlags);1550 }1551 if (!m_comGuestSession.isOk())1552 return false;1553 return true;1554 }1555 1556 bool UIGuestFileTable::copyHostToGuest(const QString &hostSourcePath, const QString &guestDestinationPath)1557 {1558 if (m_comGuestSession.isNull())1559 return false;1560 QFileInfo hostFileInfo(hostSourcePath);1561 if (!hostFileInfo.exists())1562 return false;1563 1564 /* Currently API expects a path including a file name for file copy*/1565 if (hostFileInfo.isFile() || hostFileInfo.isSymLink())1566 {1567 QVector<KFileCopyFlag> flags(KFileCopyFlag_FollowLinks);1568 /* API expects a full file path as destionation: */1569 QString destinationFilePath = UIPathOperations::mergePaths(guestDestinationPath, UIPathOperations::getObjectName(hostSourcePath));1570 /** @todo listen to CProgress object to monitor copy operation: */1571 /*CProgress comProgress =*/ m_comGuestSession.FileCopyFromGuest(hostSourcePath, destinationFilePath, flags);1572 }1573 else if(hostFileInfo.isDir())1574 {1575 QVector<KDirectoryCopyFlag> aFlags(KDirectoryCopyFlag_CopyIntoExisting);1576 /** @todo listen to CProgress object to monitor copy operation: */1577 /*CProgress comProgress = */ m_comGuestSession.DirectoryCopyToGuest(hostSourcePath, guestDestinationPath, aFlags);1578 }1579 if (!m_comGuestSession.isOk())1580 return false;1581 return true;1582 }1583 1584 FileObjectType UIGuestFileTable::fileType(const CFsObjInfo &fsInfo)1585 {1586 if (fsInfo.isNull() || !fsInfo.isOk())1587 return FileObjectType_Unknown;1588 if (fsInfo.GetType() == KFsObjType_Directory)1589 return FileObjectType_Directory;1590 else if (fsInfo.GetType() == KFsObjType_File)1591 return FileObjectType_File;1592 else if (fsInfo.GetType() == KFsObjType_Symlink)1593 return FileObjectType_SymLink;1594 1595 return FileObjectType_Other;1596 }1597 1598 FileObjectType UIGuestFileTable::fileType(const CGuestFsObjInfo &fsInfo)1599 {1600 if (fsInfo.isNull() || !fsInfo.isOk())1601 return FileObjectType_Unknown;1602 if (fsInfo.GetType() == KFsObjType_Directory)1603 return FileObjectType_Directory;1604 else if (fsInfo.GetType() == KFsObjType_File)1605 return FileObjectType_File;1606 else if (fsInfo.GetType() == KFsObjType_Symlink)1607 return FileObjectType_SymLink;1608 1609 return FileObjectType_Other;1610 }1611 1612 1613 QString UIGuestFileTable::fsObjectPropertyString()1614 {1615 if (m_comGuestSession.isNull())1616 return QString();1617 1618 QStringList selectedObjects = selectedItemPathList();1619 if (selectedObjects.isEmpty())1620 return QString();1621 if (selectedObjects.size() == 1)1622 {1623 if (selectedObjects.at(0).isNull())1624 return QString();1625 CGuestFsObjInfo fileInfo = m_comGuestSession.FsObjQueryInfo(selectedObjects.at(0), true);1626 if (!m_comGuestSession.isOk())1627 return QString();1628 1629 QString propertyString;1630 /* Name: */1631 propertyString += "<b>Name:</b> " + UIPathOperations::getObjectName(fileInfo.GetName()) + "\n";1632 propertyString += "<br/>";1633 /* Size: */1634 propertyString += "<b>Size:</b> " + QString::number(fileInfo.GetObjectSize()) + QString(" bytes");1635 propertyString += "<br/>";1636 /* Type: */1637 propertyString += "<b>Type:</b> " + fileTypeString(fileType(fileInfo));1638 propertyString += "<br/>";1639 /* Creation Date: */1640 // LONG64 GetChangeTime() const;1641 propertyString += "<b>Created:</b> " + QDateTime::fromMSecsSinceEpoch(fileInfo.GetChangeTime()/1000000).toString();1642 propertyString += "<br/>";1643 /* Last Modification Date: */1644 propertyString += "<b>Modified:</b> " + QDateTime::fromMSecsSinceEpoch(fileInfo.GetModificationTime()/1000000).toString();1645 propertyString += "<br/>";1646 /* Owner: */1647 propertyString += "<b>Owner:</b> " + fileInfo.GetUserName();1648 return propertyString;1649 }1650 return QString();1651 }1652 1653 1654 /*********************************************************************************************************************************1655 * UIHostFileTable implementation. *1656 *********************************************************************************************************************************/1657 1658 UIHostFileTable::UIHostFileTable(QWidget *pParent /* = 0 */)1659 :UIGuestControlFileTable(pParent)1660 {1661 initializeFileTree();1662 retranslateUi();1663 }1664 1665 void UIHostFileTable::retranslateUi()1666 {1667 if (m_pLocationLabel)1668 m_pLocationLabel->setText(UIVMInformationDialog::tr("Host System"));1669 UIGuestControlFileTable::retranslateUi();1670 }1671 1672 void UIHostFileTable::readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir /*= false*/)1673 {1674 if (!parent)1675 return;1676 1677 QDir directory(strPath);1678 //directory.setFilter(QDir::NoDotAndDotDot);1679 parent->setIsOpened(true);1680 if (!directory.exists())1681 return;1682 QFileInfoList entries = directory.entryInfoList();1683 QMap<QString, UIFileTableItem*> directories;1684 QMap<QString, UIFileTableItem*> files;1685 1686 for (int i = 0; i < entries.size(); ++i)1687 {1688 const QFileInfo &fileInfo = entries.at(i);1689 1690 QList<QVariant> data;1691 data << fileInfo.fileName() << fileInfo.size() << fileInfo.lastModified();1692 UIFileTableItem *item = new UIFileTableItem(data, parent, fileType(fileInfo));1693 item->setPath(fileInfo.absoluteFilePath());1694 /* if the item is a symlink set the target path and1695 check the target if it is a directory: */1696 if (fileInfo.isSymLink())1697 {1698 item->setTargetPath(fileInfo.symLinkTarget());1699 item->setIsTargetADirectory(QFileInfo(fileInfo.symLinkTarget()).isDir());1700 }1701 if (fileInfo.isDir())1702 {1703 directories.insert(fileInfo.fileName(), item);1704 item->setIsOpened(false);1705 }1706 else1707 {1708 files.insert(fileInfo.fileName(), item);1709 item->setIsOpened(false);1710 }1711 }1712 insertItemsToTree(directories, parent, true, isStartDir);1713 insertItemsToTree(files, parent, false, isStartDir);1714 updateCurrentLocationEdit(strPath);1715 }1716 1717 void UIHostFileTable::deleteByItem(UIFileTableItem *item)1718 {1719 if (item->isUpDirectory())1720 return;1721 if (!item->isDirectory())1722 {1723 QDir itemToDelete;//(item->path());1724 itemToDelete.remove(item->path());1725 }1726 QDir itemToDelete(item->path());1727 itemToDelete.setFilter(QDir::NoDotAndDotDot);1728 /* Try to delete item recursively (in case of directories).1729 note that this is no good way of deleting big directory1730 trees. We need a better error reporting and a kind of progress1731 indicator: */1732 /** @todo replace this recursive delete by a better implementation: */1733 bool deleteSuccess = itemToDelete.removeRecursively();1734 1735 if (!deleteSuccess)1736 emit sigLogOutput(QString(item->path()).append(" could not be deleted"));1737 }1738 1739 void UIHostFileTable::goToHomeDirectory()1740 {1741 if (!m_pRootItem || m_pRootItem->childCount() <= 0)1742 return;1743 UIFileTableItem *startDirItem = m_pRootItem->child(0);1744 if (!startDirItem)1745 return;1746 1747 // UIFileTableItem *rootDirectoryItem1748 QDir homeDirectory(QDir::homePath());1749 QList<QString> pathTrail;//(QDir::rootPath());1750 do{1751 1752 pathTrail.push_front(homeDirectory.absolutePath());1753 homeDirectory.cdUp();1754 }while(!homeDirectory.isRoot());1755 1756 goIntoDirectory(pathTrail);1757 }1758 1759 bool UIHostFileTable::renameItem(UIFileTableItem *item, QString newBaseName)1760 {1761 if (!item || item->isUpDirectory() || newBaseName.isEmpty())1762 return false;1763 QString newPath = UIPathOperations::constructNewItemPath(item->path(), newBaseName);1764 QDir tempDir;1765 if (tempDir.rename(item->path(), newPath))1766 {1767 item->setPath(newPath);1768 return true;1769 }1770 return false;1771 }1772 1773 bool UIHostFileTable::createDirectory(const QString &path, const QString &directoryName)1774 {1775 QDir parentDir(path);1776 if (!parentDir.mkdir(directoryName))1777 {1778 emit sigLogOutput(UIPathOperations::mergePaths(path, directoryName).append(" could not be created"));1779 return false;1780 }1781 1782 return true;1783 }1784 1785 FileObjectType UIHostFileTable::fileType(const QFileInfo &fsInfo)1786 {1787 if (!fsInfo.exists())1788 return FileObjectType_Unknown;1789 /* first check if it is symlink becacuse for Qt1790 being smylin and directory/file is not mutually exclusive: */1791 if (fsInfo.isSymLink())1792 return FileObjectType_SymLink;1793 else if (fsInfo.isFile())1794 return FileObjectType_File;1795 else if (fsInfo.isDir())1796 return FileObjectType_Directory;1797 1798 return FileObjectType_Other;1799 }1800 1801 QString UIHostFileTable::fsObjectPropertyString()1802 {1803 QStringList selectedObjects = selectedItemPathList();1804 if (selectedObjects.isEmpty())1805 return QString();1806 if (selectedObjects.size() == 1)1807 {1808 if (selectedObjects.at(0).isNull())1809 return QString();1810 QFileInfo fileInfo(selectedObjects.at(0));1811 if (!fileInfo.exists())1812 return QString();1813 QString propertyString;1814 /* Name: */1815 propertyString += "<b>Name:</b> " + fileInfo.fileName() + "\n";1816 if (!fileInfo.suffix().isEmpty())1817 propertyString += "." + fileInfo.suffix();1818 propertyString += "<br/>";1819 /* Size: */1820 propertyString += "<b>Size:</b> " + QString::number(fileInfo.size()) + QString(" bytes");1821 propertyString += "<br/>";1822 /* Type: */1823 propertyString += "<b>Type:</b> " + fileTypeString(fileType(fileInfo));1824 propertyString += "<br/>";1825 /* Creation Date: */1826 propertyString += "<b>Created:</b> " + fileInfo.created().toString();1827 propertyString += "<br/>";1828 /* Last Modification Date: */1829 propertyString += "<b>Modified:</b> " + fileInfo.lastModified().toString();1830 propertyString += "<br/>";1831 /* Owner: */1832 propertyString += "<b>Owner:</b> " + fileInfo.owner();1833 1834 1835 return propertyString;1836 }1837 return QString();1838 }1839 1840 1335 #include "UIGuestControlFileTable.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.h
r71385 r71388 51 51 }; 52 52 53 /********************************************************************************************************************************* 54 * UIFileTableItem definition. * 55 *********************************************************************************************************************************/ 56 53 /** A collection of simple utility functions to manipulate path strings */ 54 class UIPathOperations 55 { 56 public: 57 static QString removeMultipleDelimiters(const QString &path); 58 static QString removeTrailingDelimiters(const QString &path); 59 static QString addStartDelimiter(const QString &path); 60 61 static QString sanitize(const QString &path); 62 /** Merge prefix and suffix by making sure they have a single '/' in between */ 63 static QString mergePaths(const QString &path, const QString &baseName); 64 /** Returns the last part of the @p path. That is the filename or directory name without the path */ 65 static QString getObjectName(const QString &path); 66 /** Remove the object name and return the path */ 67 static QString getPathExceptObjectName(const QString &path); 68 /** Replace the last part of the @p previusPath with newBaseName */ 69 static QString constructNewItemPath(const QString &previousPath, const QString &newBaseName); 70 71 static const QChar delimiter; 72 }; 73 74 /** A UIFileTableItem instance is a tree node representing a file object (file, directory, etc). The tree contructed 75 by these instances is the data source for the UIGuestControlFileModel */ 57 76 class UIFileTableItem 58 77 { … … 118 137 and a host version are derived from this base. Each of these children 119 138 populates the UIGuestControlFileModel by scanning the file system 120 differently. The file structre kept in this class as a tree and all 121 the interfacing is done thru this class.*/ 139 differently. The file structre kept in this class as a tree. */ 122 140 class UIGuestControlFileTable : public QIWithRetranslateUI<QWidget> 123 141 { … … 219 237 }; 220 238 221 /** This class scans the guest file system by using the VBox API222 and populates the UIGuestControlFileModel*/223 class UIGuestFileTable : public UIGuestControlFileTable224 {225 Q_OBJECT;226 227 public:228 229 UIGuestFileTable(QWidget *pParent = 0);230 void initGuestFileTable(const CGuestSession &session);231 void copyGuestToHost(const QString& hostDestinationPath);232 void copyHostToGuest(const QStringList &hostSourcePathList);233 234 protected:235 236 void retranslateUi() /* override */;237 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) /* override */;238 virtual void deleteByItem(UIFileTableItem *item) /* override */;239 virtual void goToHomeDirectory() /* override */;240 virtual bool renameItem(UIFileTableItem *item, QString newBaseName);241 virtual bool createDirectory(const QString &path, const QString &directoryName);242 virtual QString fsObjectPropertyString() /* override */;243 244 private:245 246 static FileObjectType fileType(const CFsObjInfo &fsInfo);247 static FileObjectType fileType(const CGuestFsObjInfo &fsInfo);248 249 bool copyGuestToHost(const QString &guestSourcePath, const QString& hostDestinationPath);250 bool copyHostToGuest(const QString& hostSourcePath, const QString &guestDestinationPath);251 252 mutable CGuestSession m_comGuestSession;253 254 };255 256 /** This class scans the host file system by using the Qt257 and populates the UIGuestControlFileModel*/258 class UIHostFileTable : public UIGuestControlFileTable259 {260 Q_OBJECT;261 262 public:263 264 UIHostFileTable(QWidget *pParent = 0);265 266 protected:267 268 static FileObjectType fileType(const QFileInfo &fsInfo);269 void retranslateUi() /* override */;270 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) /* override */;271 virtual void deleteByItem(UIFileTableItem *item) /* override */;272 virtual void goToHomeDirectory() /* override */;273 virtual bool renameItem(UIFileTableItem *item, QString newBaseName);274 virtual bool createDirectory(const QString &path, const QString &directoryName);275 virtual QString fsObjectPropertyString() /* override */;276 277 };278 279 239 #endif /* !___UIGuestControlFileTable_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestFileTable.cpp
r71385 r71388 21 21 22 22 /* Qt includes: */ 23 # include <QAction>23 // # include <QAction> 24 24 # include <QDateTime> 25 # include <QDir> 26 # include <QHeaderView> 27 # include <QItemDelegate> 28 # include <QGridLayout> 29 # include <QMenu> 30 # include <QTextEdit> 31 # include <QPushButton> 25 # include <QFileInfo> 32 26 33 27 /* GUI includes: */ 34 # include "QIDialog.h"35 # include "QIDialogButtonBox.h"36 28 # include "QILabel.h" 37 # include "QILineEdit.h" 38 # include "QIMessageBox.h" 39 # include "UIErrorString.h" 40 # include "UIIconPool.h" 41 # include "UIGuestControlFileTable.h" 42 # include "UIGuestControlFileModel.h" 43 # include "UIToolBar.h" 29 # include "UIGuestFileTable.h" 44 30 # include "UIVMInformationDialog.h" 45 31 … … 52 38 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 53 39 54 55 /*********************************************************************************************************************************56 * UIPathOperations definition. *57 *********************************************************************************************************************************/58 59 /** A collection of utility functions for so60 me path string manipulations */61 class UIPathOperations62 {63 public:64 static QString removeMultipleDelimiters(const QString &path);65 static QString removeTrailingDelimiters(const QString &path);66 static QString addStartDelimiter(const QString &path);67 68 static QString sanitize(const QString &path);69 /** Merge prefix and suffix by making sure they have a single '/' in between */70 static QString mergePaths(const QString &path, const QString &baseName);71 /** Returns the last part of the @p path. That is the filename or directory name without the path */72 static QString getObjectName(const QString &path);73 /** Remove the object name and return the path */74 static QString getPathExceptObjectName(const QString &path);75 /** Replace the last part of the @p previusPath with newBaseName */76 static QString constructNewItemPath(const QString &previousPath, const QString &newBaseName);77 78 static const QChar delimiter;79 };80 81 82 /*********************************************************************************************************************************83 * UIGuestControlFileView definition. *84 *********************************************************************************************************************************/85 86 /** Using QITableView causes the following problem when I click on the table items87 Qt WARNING: Cannot creat accessible child interface for object: UIGuestControlFileView.....88 so for now subclass QTableView */89 class UIGuestControlFileView : public QTableView90 {91 92 Q_OBJECT;93 94 signals:95 96 void sigGoUp();97 void sigGoHome();98 void sigRefresh();99 void sigRename();100 void sigCreateNewDirectory();101 void sigDelete();102 void sigCut();103 void sigCopy();104 void sigPaste();105 void sigShowProperties();106 107 void sigSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);108 109 public:110 111 UIGuestControlFileView(QWidget * parent = 0);112 bool hasSelection() const;113 114 protected:115 virtual void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected) /*override */;116 void contextMenuEvent(QContextMenuEvent *pEvent);117 };118 119 120 /*********************************************************************************************************************************121 * UIFileDelegate definition. *122 *********************************************************************************************************************************/123 /** A QItemDelegate child class to disable dashed lines drawn around selected cells in QTableViews */124 class UIFileDelegate : public QItemDelegate125 {126 127 Q_OBJECT;128 129 protected:130 virtual void drawFocus ( QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, const QRect & /*rect*/ ) const {}131 };132 133 134 /*********************************************************************************************************************************135 * UIFileStringInputDialog definition. *136 *********************************************************************************************************************************/137 138 /** A QIDialog child including a line edit whose text exposed when the dialog is accepted */139 class UIStringInputDialog : public QIDialog140 {141 142 Q_OBJECT;143 144 public:145 146 UIStringInputDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);147 QString getString() const;148 149 private:150 151 QILineEdit *m_pLineEdit;152 153 };154 155 /*********************************************************************************************************************************156 * UIPropertiesDialog definition. *157 *********************************************************************************************************************************/158 159 /** A QIDialog child to display properties of a file object */160 class UIPropertiesDialog : public QIDialog161 {162 163 Q_OBJECT;164 165 public:166 167 UIPropertiesDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);168 void setPropertyText(const QString &strProperty);169 170 private:171 172 QVBoxLayout *m_pMainLayout;173 QTextEdit *m_pInfoEdit;174 175 };176 177 178 /*********************************************************************************************************************************179 * UIPathOperations implementation. *180 *********************************************************************************************************************************/181 182 const QChar UIPathOperations::delimiter = QChar('/');183 184 QString UIPathOperations::removeMultipleDelimiters(const QString &path)185 {186 QString newPath(path);187 QString doubleDelimiter(2, delimiter);188 189 while (newPath.contains(doubleDelimiter) && !newPath.isEmpty())190 newPath = newPath.replace(doubleDelimiter, delimiter);191 return newPath;192 }193 194 QString UIPathOperations::removeTrailingDelimiters(const QString &path)195 {196 if (path.isNull() || path.isEmpty())197 return QString();198 QString newPath(path);199 /* Make sure for we dont have any trailing slashes: */200 while (newPath.length() > 1 && newPath.at(newPath.length() - 1) == UIPathOperations::delimiter)201 newPath.chop(1);202 return newPath;203 }204 205 QString UIPathOperations::addStartDelimiter(const QString &path)206 {207 if (path.isEmpty())208 return QString(path);209 QString newPath(path);210 if (newPath.at(0) != delimiter)211 newPath.insert(0, delimiter);212 return newPath;213 }214 215 QString UIPathOperations::sanitize(const QString &path)216 {217 return addStartDelimiter(removeTrailingDelimiters(removeMultipleDelimiters(path)));218 }219 220 QString UIPathOperations::mergePaths(const QString &path, const QString &baseName)221 {222 QString newBase(baseName);223 newBase = newBase.remove(delimiter);224 225 /* make sure we have one and only one trailing '/': */226 QString newPath(sanitize(path));227 if(newPath.isEmpty())228 newPath = delimiter;229 if(newPath.at(newPath.length() - 1) != delimiter)230 newPath += UIPathOperations::delimiter;231 newPath += newBase;232 return sanitize(newPath);233 }234 235 QString UIPathOperations::getObjectName(const QString &path)236 {237 if (path.length() <= 1)238 return QString(path);239 240 QString strTemp(sanitize(path));241 if (strTemp.length() < 2)242 return strTemp;243 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);244 if (lastSlashPosition == -1)245 return QString();246 return strTemp.right(strTemp.length() - lastSlashPosition - 1);247 }248 249 QString UIPathOperations::getPathExceptObjectName(const QString &path)250 {251 if (path.length() <= 1)252 return QString(path);253 254 QString strTemp(sanitize(path));255 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);256 if (lastSlashPosition == -1)257 return QString();258 return strTemp.left(lastSlashPosition + 1);259 }260 261 QString UIPathOperations::constructNewItemPath(const QString &previousPath, const QString &newBaseName)262 {263 if (previousPath.length() <= 1)264 return QString(previousPath);265 return sanitize(mergePaths(getPathExceptObjectName(previousPath), newBaseName));266 }267 268 269 /*********************************************************************************************************************************270 * UIGuestControlFileView implementation. *271 *********************************************************************************************************************************/272 273 UIGuestControlFileView::UIGuestControlFileView(QWidget * parent)274 :QTableView(parent)275 {276 }277 278 void UIGuestControlFileView::contextMenuEvent(QContextMenuEvent *pEvent)279 {280 bool selectionAvaible = hasSelection();281 282 QMenu *menu = new QMenu(this);283 if (!menu)284 return;285 286 QAction *pActionGoUp = menu->addAction(UIVMInformationDialog::tr("Go up"));287 if (pActionGoUp)288 {289 pActionGoUp->setIcon(UIIconPool::iconSet(QString(":/arrow_up_10px_x2.png")));290 connect(pActionGoUp, &QAction::triggered, this, &UIGuestControlFileView::sigGoUp);291 }292 QAction *pActionGoHome = menu->addAction(UIVMInformationDialog::tr("Go home"));293 if (pActionGoHome)294 {295 pActionGoHome->setIcon(UIIconPool::iconSet(QString(":/nw_24px.png")));296 connect(pActionGoHome, &QAction::triggered, this, &UIGuestControlFileView::sigGoHome);297 }298 299 QAction *pActionRefresh = menu->addAction(UIVMInformationDialog::tr("Refresh"));300 if (pActionRefresh)301 {302 pActionRefresh->setIcon(UIIconPool::iconSet(QString(":/refresh_22px.png")));303 connect(pActionRefresh, &QAction::triggered, this, &UIGuestControlFileView::sigRefresh);304 }305 306 menu->addSeparator();307 QAction *pActionDelete = menu->addAction(UIVMInformationDialog::tr("Delete"));308 if (pActionDelete)309 {310 pActionDelete->setIcon(UIIconPool::iconSet(QString(":/vm_delete_32px.png")));311 pActionDelete->setEnabled(selectionAvaible);312 connect(pActionDelete, &QAction::triggered, this, &UIGuestControlFileView::sigDelete);313 }314 315 QAction *pActionRename = menu->addAction(UIVMInformationDialog::tr("Rename"));316 if (pActionRename)317 {318 pActionRename->setIcon(UIIconPool::iconSet(QString(":/name_16px_x2.png")));319 pActionRename->setEnabled(selectionAvaible);320 pActionRename->setEnabled(selectionAvaible);321 connect(pActionRename, &QAction::triggered, this, &UIGuestControlFileView::sigRename);322 }323 324 QAction *pActionCreateNewDirectory = menu->addAction(UIVMInformationDialog::tr("Create New Directory"));325 if (pActionCreateNewDirectory)326 {327 pActionCreateNewDirectory->setIcon(UIIconPool::iconSet(QString(":/sf_add_16px.png")));328 connect(pActionCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileView::sigCreateNewDirectory);329 }330 331 QAction *pActionCopy = menu->addAction(UIVMInformationDialog::tr("Copy"));332 if (pActionCopy)333 {334 pActionCopy->setIcon(UIIconPool::iconSet(QString(":/fd_copy_22px.png")));335 pActionCopy->setEnabled(selectionAvaible);336 connect(pActionCopy, &QAction::triggered, this, &UIGuestControlFileView::sigCopy);337 }338 339 QAction *pActionCut = menu->addAction(UIVMInformationDialog::tr("Cut"));340 if (pActionCut)341 {342 pActionCut->setIcon(UIIconPool::iconSet(QString(":/fd_move_22px.png")));343 pActionCut->setEnabled(selectionAvaible);344 connect(pActionCut, &QAction::triggered, this, &UIGuestControlFileView::sigCut);345 }346 347 QAction *pActionPaste = menu->addAction(UIVMInformationDialog::tr("Paste"));348 if (pActionPaste)349 {350 pActionPaste->setIcon(UIIconPool::iconSet(QString(":/shared_clipboard_16px.png")));351 connect(pActionPaste, &QAction::triggered, this, &UIGuestControlFileView::sigPaste);352 }353 354 menu->addSeparator();355 QAction *pActionShowProperties = menu->addAction(UIVMInformationDialog::tr("Properties"));356 if (pActionShowProperties)357 {358 pActionShowProperties->setIcon(UIIconPool::iconSet(QString(":/session_info_32px.png")));359 pActionShowProperties->setEnabled(selectionAvaible);360 connect(pActionShowProperties, &QAction::triggered, this, &UIGuestControlFileView::sigShowProperties);361 }362 363 menu->exec(pEvent->globalPos());364 365 if (pActionGoUp)366 disconnect(pActionGoUp, &QAction::triggered, this, &UIGuestControlFileView::sigGoUp);367 if (pActionGoHome)368 disconnect(pActionGoHome, &QAction::triggered, this, &UIGuestControlFileView::sigGoHome);369 if (pActionRefresh)370 disconnect(pActionRefresh, &QAction::triggered, this, &UIGuestControlFileView::sigRefresh);371 if (pActionDelete)372 disconnect(pActionDelete, &QAction::triggered, this, &UIGuestControlFileView::sigDelete);373 if (pActionRename)374 disconnect(pActionRename, &QAction::triggered, this, &UIGuestControlFileView::sigRename);375 if (pActionCreateNewDirectory)376 disconnect(pActionCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileView::sigCreateNewDirectory);377 if (pActionCopy)378 disconnect(pActionCopy, &QAction::triggered, this, &UIGuestControlFileView::sigCopy);379 if (pActionCut)380 disconnect(pActionCut, &QAction::triggered, this, &UIGuestControlFileView::sigCut);381 if (pActionPaste)382 disconnect(pActionPaste, &QAction::triggered, this, &UIGuestControlFileView::sigPaste);383 if (pActionShowProperties)384 disconnect(pActionShowProperties, &QAction::triggered, this, &UIGuestControlFileView::sigShowProperties);385 386 delete menu;387 }388 389 bool UIGuestControlFileView::hasSelection() const390 {391 QItemSelectionModel *pSelectionModel = selectionModel();392 if (!pSelectionModel)393 return false;394 return pSelectionModel->hasSelection();395 }396 397 void UIGuestControlFileView::selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)398 {399 emit sigSelectionChanged(selected, deselected);400 QTableView::selectionChanged(selected, deselected);401 }402 403 404 /*********************************************************************************************************************************405 * UIFileStringInputDialog implementation. *406 *********************************************************************************************************************************/407 408 UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)409 :QIDialog(pParent, flags)410 {411 QVBoxLayout *layout = new QVBoxLayout(this);412 m_pLineEdit = new QILineEdit(this);413 layout->addWidget(m_pLineEdit);414 415 QIDialogButtonBox *pButtonBox =416 new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);417 layout->addWidget(pButtonBox);418 // {419 // /* Configure button-box: */420 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);421 connect(pButtonBox, &QIDialogButtonBox::rejected, this, &UIStringInputDialog::reject);422 423 }424 425 QString UIStringInputDialog::getString() const426 {427 if (!m_pLineEdit)428 return QString();429 return m_pLineEdit->text();430 }431 432 433 /*********************************************************************************************************************************434 * UIPropertiesDialog implementation. *435 *********************************************************************************************************************************/436 437 UIPropertiesDialog::UIPropertiesDialog(QWidget *pParent, Qt::WindowFlags flags)438 :QIDialog(pParent, flags)439 , m_pMainLayout(new QVBoxLayout)440 , m_pInfoEdit(new QTextEdit)441 {442 setLayout(m_pMainLayout);443 444 if (m_pMainLayout)445 m_pMainLayout->addWidget(m_pInfoEdit);446 if (m_pInfoEdit)447 {448 m_pInfoEdit->setReadOnly(true);449 m_pInfoEdit->setFrameStyle(QFrame::NoFrame);450 }451 QIDialogButtonBox *pButtonBox =452 new QIDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this);453 m_pMainLayout->addWidget(pButtonBox);454 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);455 }456 457 void UIPropertiesDialog::setPropertyText(const QString &strProperty)458 {459 if (!m_pInfoEdit)460 return;461 462 m_pInfoEdit->setText(strProperty);463 }464 465 466 /*********************************************************************************************************************************467 * UIFileTableItem implementation. *468 *********************************************************************************************************************************/469 470 471 UIFileTableItem::UIFileTableItem(const QList<QVariant> &data,472 UIFileTableItem *parent, FileObjectType type)473 : m_itemData(data)474 , m_parentItem(parent)475 , m_bIsOpened(false)476 , m_isTargetADirectory(false)477 , m_type(type)478 {479 }480 481 UIFileTableItem::~UIFileTableItem()482 {483 qDeleteAll(m_childItems);484 m_childItems.clear();485 }486 487 void UIFileTableItem::appendChild(UIFileTableItem *item)488 {489 if (!item)490 return;491 m_childItems.append(item);492 m_childMap.insert(item->path(), item);493 }494 495 UIFileTableItem *UIFileTableItem::child(int row) const496 {497 return m_childItems.value(row);498 }499 500 UIFileTableItem *UIFileTableItem::child(const QString &path) const501 {502 if (!m_childMap.contains(path))503 return 0;504 return m_childMap.value(path);505 }506 507 int UIFileTableItem::childCount() const508 {509 return m_childItems.count();510 }511 512 int UIFileTableItem::columnCount() const513 {514 return m_itemData.count();515 }516 517 QVariant UIFileTableItem::data(int column) const518 {519 return m_itemData.value(column);520 }521 522 void UIFileTableItem::setData(const QVariant &data, int index)523 {524 if (index >= m_itemData.length())525 return;526 m_itemData[index] = data;527 }528 529 UIFileTableItem *UIFileTableItem::parentItem()530 {531 return m_parentItem;532 }533 534 int UIFileTableItem::row() const535 {536 if (m_parentItem)537 return m_parentItem->m_childItems.indexOf(const_cast<UIFileTableItem*>(this));538 return 0;539 }540 541 bool UIFileTableItem::isDirectory() const542 {543 return m_type == FileObjectType_Directory;544 }545 546 bool UIFileTableItem::isSymLink() const547 {548 return m_type == FileObjectType_SymLink;549 }550 551 bool UIFileTableItem::isFile() const552 {553 return m_type == FileObjectType_File;554 }555 556 void UIFileTableItem::clearChildren()557 {558 qDeleteAll(m_childItems);559 m_childItems.clear();560 m_childMap.clear();561 }562 563 bool UIFileTableItem::isOpened() const564 {565 return m_bIsOpened;566 }567 568 void UIFileTableItem::setIsOpened(bool flag)569 {570 m_bIsOpened = flag;571 }572 573 const QString &UIFileTableItem::path() const574 {575 return m_strPath;576 }577 578 void UIFileTableItem::setPath(const QString &path)579 {580 if (path.isNull() || path.isEmpty())581 return;582 m_strPath = path;583 UIPathOperations::removeTrailingDelimiters(m_strPath);584 }585 586 bool UIFileTableItem::isUpDirectory() const587 {588 if (!isDirectory())589 return false;590 if (data(0) == QString(".."))591 return true;592 return false;593 }594 595 FileObjectType UIFileTableItem::type() const596 {597 return m_type;598 }599 600 const QString &UIFileTableItem::targetPath() const601 {602 return m_strTargetPath;603 }604 605 void UIFileTableItem::setTargetPath(const QString &path)606 {607 m_strTargetPath = path;608 }609 610 bool UIFileTableItem::isTargetADirectory() const611 {612 return m_isTargetADirectory;613 }614 615 void UIFileTableItem::setIsTargetADirectory(bool flag)616 {617 m_isTargetADirectory = flag;618 }619 620 621 /*********************************************************************************************************************************622 * UIGuestControlFileTable implementation. *623 *********************************************************************************************************************************/624 625 UIGuestControlFileTable::UIGuestControlFileTable(QWidget *pParent /* = 0 */)626 :QIWithRetranslateUI<QWidget>(pParent)627 , m_pRootItem(0)628 , m_pView(0)629 , m_pModel(0)630 , m_pLocationLabel(0)631 , m_pMainLayout(0)632 , m_pCurrentLocationEdit(0)633 , m_pToolBar(0)634 , m_pGoUp(0)635 , m_pGoHome(0)636 , m_pRefresh(0)637 , m_pDelete(0)638 , m_pRename(0)639 , m_pCreateNewDirectory(0)640 , m_pCopy(0)641 , m_pCut(0)642 , m_pPaste(0)643 , m_pShowProperties(0)644 645 {646 prepareObjects();647 prepareActions();648 }649 650 UIGuestControlFileTable::~UIGuestControlFileTable()651 {652 delete m_pRootItem;653 }654 655 void UIGuestControlFileTable::reset()656 {657 if (m_pModel)658 m_pModel->beginReset();659 delete m_pRootItem;660 m_pRootItem = 0;661 if (m_pModel)662 m_pModel->endReset();663 if (m_pCurrentLocationEdit)664 m_pCurrentLocationEdit->clear();665 }666 667 void UIGuestControlFileTable::emitLogOutput(const QString& strOutput)668 {669 emit sigLogOutput(strOutput);670 }671 672 void UIGuestControlFileTable::prepareObjects()673 {674 m_pMainLayout = new QGridLayout();675 if (!m_pMainLayout)676 return;677 m_pMainLayout->setSpacing(0);678 m_pMainLayout->setContentsMargins(0, 0, 0, 0);679 setLayout(m_pMainLayout);680 681 m_pToolBar = new UIToolBar;682 if (m_pToolBar)683 {684 m_pMainLayout->addWidget(m_pToolBar, 0, 0, 1, 5);685 }686 687 m_pLocationLabel = new QILabel;688 if (m_pLocationLabel)689 {690 m_pMainLayout->addWidget(m_pLocationLabel, 1, 0, 1, 1);691 }692 693 m_pCurrentLocationEdit = new QILineEdit;694 if (m_pCurrentLocationEdit)695 {696 m_pMainLayout->addWidget(m_pCurrentLocationEdit, 1, 1, 1, 4);697 m_pCurrentLocationEdit->setReadOnly(true);698 }699 700 m_pModel = new UIGuestControlFileModel(this);701 if (!m_pModel)702 return;703 704 705 m_pView = new UIGuestControlFileView;706 if (m_pView)707 {708 m_pView->setShowGrid(false);709 m_pView->setSelectionBehavior(QAbstractItemView::SelectRows);710 m_pView->verticalHeader()->setVisible(false);711 712 m_pMainLayout->addWidget(m_pView, 2, 0, 5, 5);713 m_pView->setModel(m_pModel);714 m_pView->setItemDelegate(new UIFileDelegate);715 m_pView->setEditTriggers(QAbstractItemView::NoEditTriggers);716 /* Minimize the row height: */717 m_pView->verticalHeader()->setDefaultSectionSize(m_pView->verticalHeader()->minimumSectionSize());718 /* Make the columns take all the avaible space: */719 //m_pView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);720 721 connect(m_pView, &UIGuestControlFileView::doubleClicked,722 this, &UIGuestControlFileTable::sltItemDoubleClicked);723 724 connect(m_pView, &UIGuestControlFileView::sigGoUp,725 this, &UIGuestControlFileTable::sltGoUp);726 connect(m_pView, &UIGuestControlFileView::sigGoHome,727 this, &UIGuestControlFileTable::sltGoHome);728 connect(m_pView, &UIGuestControlFileView::sigRefresh,729 this, &UIGuestControlFileTable::sltRefresh);730 connect(m_pView, &UIGuestControlFileView::sigDelete,731 this, &UIGuestControlFileTable::sltDelete);732 connect(m_pView, &UIGuestControlFileView::sigRename,733 this, &UIGuestControlFileTable::sltRename);734 connect(m_pView, &UIGuestControlFileView::sigCreateNewDirectory,735 this, &UIGuestControlFileTable::sltCreateNewDirectory);736 connect(m_pView, &UIGuestControlFileView::sigCopy,737 this, &UIGuestControlFileTable::sltCopy);738 connect(m_pView, &UIGuestControlFileView::sigCut,739 this, &UIGuestControlFileTable::sltCut);740 connect(m_pView, &UIGuestControlFileView::sigPaste,741 this, &UIGuestControlFileTable::sltPaste);742 connect(m_pView, &UIGuestControlFileView::sigShowProperties,743 this, &UIGuestControlFileTable::sltShowProperties);744 connect(m_pView, &UIGuestControlFileView::sigSelectionChanged,745 this, &UIGuestControlFileTable::sltSelectionChanged);746 747 }748 }749 750 void UIGuestControlFileTable::prepareActions()751 {752 if (!m_pToolBar)753 return;754 755 m_pGoUp = new QAction(this);756 if (m_pGoUp)757 {758 connect(m_pGoUp, &QAction::triggered, this, &UIGuestControlFileTable::sltGoUp);759 m_pGoUp->setIcon(UIIconPool::iconSet(QString(":/arrow_up_10px_x2.png")));760 m_pToolBar->addAction(m_pGoUp);761 }762 763 m_pGoHome = new QAction(this);764 if (m_pGoHome)765 {766 connect(m_pGoHome, &QAction::triggered, this, &UIGuestControlFileTable::sltGoHome);767 m_pGoHome->setIcon(UIIconPool::iconSet(QString(":/nw_24px.png")));768 m_pToolBar->addAction(m_pGoHome);769 }770 771 m_pRefresh = new QAction(this);772 if (m_pRefresh)773 {774 connect(m_pRefresh, &QAction::triggered, this, &UIGuestControlFileTable::sltRefresh);775 m_pRefresh->setIcon(UIIconPool::iconSet(QString(":/refresh_22px.png")));776 m_pToolBar->addAction(m_pRefresh);777 }778 779 m_pToolBar->addSeparator();780 781 m_pDelete = new QAction(this);782 if (m_pDelete)783 {784 connect(m_pDelete, &QAction::triggered, this, &UIGuestControlFileTable::sltDelete);785 m_pDelete->setIcon(UIIconPool::iconSet(QString(":/vm_delete_32px.png")));786 m_pToolBar->addAction(m_pDelete);787 m_selectionDependentActions.push_back(m_pDelete);788 }789 790 m_pRename = new QAction(this);791 if (m_pRename)792 {793 connect(m_pRename, &QAction::triggered, this, &UIGuestControlFileTable::sltRename);794 m_pRename->setIcon(UIIconPool::iconSet(QString(":/name_16px_x2.png")));795 m_pToolBar->addAction(m_pRename);796 m_selectionDependentActions.push_back(m_pRename);797 }798 799 m_pCreateNewDirectory = new QAction(this);800 if (m_pCreateNewDirectory)801 {802 connect(m_pCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileTable::sltCreateNewDirectory);803 m_pCreateNewDirectory->setIcon(UIIconPool::iconSet(QString(":/sf_add_16px.png")));804 m_pToolBar->addAction(m_pCreateNewDirectory);805 }806 807 m_pCopy = new QAction(this);808 if (m_pCopy)809 {810 m_pCopy->setIcon(UIIconPool::iconSet(QString(":/fd_copy_22px.png")));811 m_pToolBar->addAction(m_pCopy);812 connect(m_pCopy, &QAction::triggered, this, &UIGuestControlFileTable::sltCopy);813 m_selectionDependentActions.push_back(m_pCopy);814 }815 816 m_pCut = new QAction(this);817 if (m_pCut)818 {819 m_pCut->setIcon(UIIconPool::iconSet(QString(":/fd_move_22px.png")));820 m_pToolBar->addAction(m_pCut);821 connect(m_pCut, &QAction::triggered, this, &UIGuestControlFileTable::sltCut);822 m_selectionDependentActions.push_back(m_pCut);823 }824 825 m_pPaste = new QAction(this);826 if (m_pPaste)827 {828 m_pPaste->setIcon(UIIconPool::iconSet(QString(":/shared_clipboard_16px.png")));829 m_pToolBar->addAction(m_pPaste);830 connect(m_pPaste, &QAction::triggered, this, &UIGuestControlFileTable::sltPaste);831 m_pPaste->setEnabled(false);832 }833 834 m_pToolBar->addSeparator();835 836 m_pShowProperties = new QAction(this);837 {838 m_pShowProperties->setIcon(UIIconPool::iconSet(QString(":/session_info_32px.png")));839 m_pToolBar->addAction(m_pShowProperties);840 connect(m_pShowProperties, &QAction::triggered, this, &UIGuestControlFileTable::sltShowProperties);841 m_selectionDependentActions.push_back(m_pShowProperties);842 }843 844 disableSelectionDependentActions();845 }846 847 void UIGuestControlFileTable::updateCurrentLocationEdit(const QString& strLocation)848 {849 if (!m_pCurrentLocationEdit)850 return;851 m_pCurrentLocationEdit->setText(strLocation);852 }853 854 void UIGuestControlFileTable::changeLocation(const QModelIndex &index)855 {856 if (!index.isValid() || !m_pView)857 return;858 m_pView->setRootIndex(index);859 m_pView->clearSelection();860 861 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());862 if (item)863 {864 updateCurrentLocationEdit(item->path());865 }866 m_pModel->signalUpdate();867 }868 869 void UIGuestControlFileTable::initializeFileTree()870 {871 if (m_pRootItem)872 reset();873 874 QList<QVariant> headData;875 headData << "Name" << "Size" << "Change Time";876 m_pRootItem = new UIFileTableItem(headData, 0, FileObjectType_Directory);877 QList<QVariant> startDirData;878 startDirData << "/" << 4096 << QDateTime();879 UIFileTableItem* startItem = new UIFileTableItem(startDirData, m_pRootItem, FileObjectType_Directory);880 881 startItem->setPath("/");882 m_pRootItem->appendChild(startItem);883 884 startItem->setIsOpened(false);885 /* Read the root directory and get the list: */886 887 readDirectory("/", startItem, true);888 m_pView->setRootIndex(m_pModel->rootIndex());889 m_pModel->signalUpdate();890 891 }892 893 void UIGuestControlFileTable::insertItemsToTree(QMap<QString,UIFileTableItem*> &map,894 UIFileTableItem *parent, bool isDirectoryMap, bool isStartDir)895 {896 /* Make sure we have a ".." item within directories, and make sure it is not there for the start dir: */897 if (isDirectoryMap)898 {899 if (!map.contains("..") && !isStartDir)900 {901 QList<QVariant> data;902 data << ".." << 4096;903 UIFileTableItem *item = new UIFileTableItem(data, parent, FileObjectType_Directory);904 item->setIsOpened(false);905 map.insert("..", item);906 }907 else if (map.contains("..") && isStartDir)908 {909 map.remove("..");910 }911 }912 for (QMap<QString,UIFileTableItem*>::const_iterator iterator = map.begin();913 iterator != map.end(); ++iterator)914 {915 if (iterator.key() == "." || iterator.key().isEmpty())916 continue;917 parent->appendChild(iterator.value());918 }919 }920 921 void UIGuestControlFileTable::sltItemDoubleClicked(const QModelIndex &index)922 {923 if (!index.isValid() || !m_pModel || !m_pView)924 return;925 goIntoDirectory(index);926 }927 928 void UIGuestControlFileTable::sltGoUp()929 {930 if (!m_pView || !m_pModel)931 return;932 QModelIndex currentRoot = m_pView->rootIndex();933 if (!currentRoot.isValid())934 return;935 if (currentRoot != m_pModel->rootIndex())936 changeLocation(currentRoot.parent());937 }938 939 void UIGuestControlFileTable::sltGoHome()940 {941 goToHomeDirectory();942 }943 944 void UIGuestControlFileTable::sltRefresh()945 {946 refresh();947 }948 949 void UIGuestControlFileTable::goIntoDirectory(const QModelIndex &itemIndex)950 {951 if (!m_pModel)952 return;953 954 /* Make sure the colum is 0: */955 QModelIndex index = m_pModel->index(itemIndex.row(), 0, itemIndex.parent());956 if (!index.isValid())957 return;958 959 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());960 if (!item)961 return;962 963 /* check if we need to go up: */964 if (item->isUpDirectory())965 {966 QModelIndex parentIndex = m_pModel->parent(m_pModel->parent(index));967 if (parentIndex.isValid())968 changeLocation(parentIndex);969 return;970 }971 972 if (!item->isDirectory())973 return;974 if (!item->isOpened())975 readDirectory(item->path(),item);976 changeLocation(index);977 }978 979 void UIGuestControlFileTable::goIntoDirectory(const QList<QString> &pathTrail)980 {981 UIFileTableItem *parent = getStartDirectoryItem();982 983 for(int i = 0; i < pathTrail.size(); ++i)984 {985 if (!parent)986 return;987 /* Make sure parent is already opened: */988 if (!parent->isOpened())989 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());990 /* search the current path item among the parent's children: */991 UIFileTableItem *item = parent->child(pathTrail.at(i));992 if (!item)993 return;994 parent = item;995 }996 if (!parent)997 return;998 if (!parent->isOpened())999 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());1000 goIntoDirectory(parent);1001 }1002 1003 void UIGuestControlFileTable::goIntoDirectory(UIFileTableItem *item)1004 {1005 if (!item || !m_pModel)1006 return;1007 goIntoDirectory(m_pModel->index(item));1008 }1009 1010 UIFileTableItem* UIGuestControlFileTable::indexData(const QModelIndex &index) const1011 {1012 if (!index.isValid())1013 return 0;1014 return static_cast<UIFileTableItem*>(index.internalPointer());1015 }1016 1017 void UIGuestControlFileTable::refresh()1018 {1019 if (!m_pView || !m_pModel)1020 return;1021 QModelIndex currentIndex = m_pView->rootIndex();1022 1023 UIFileTableItem *treeItem = indexData(currentIndex);1024 if (!treeItem)1025 return;1026 bool isRootDir = (m_pModel->rootIndex() == currentIndex);1027 m_pModel->beginReset();1028 /* For now we clear the whole subtree (that isrecursively) which is an overkill: */1029 treeItem->clearChildren();1030 readDirectory(treeItem->path(), treeItem, isRootDir);1031 m_pModel->endReset();1032 m_pView->setRootIndex(currentIndex);1033 }1034 1035 void UIGuestControlFileTable::sltDelete()1036 {1037 if (!m_pView || !m_pModel)1038 return;1039 QItemSelectionModel *selectionModel = m_pView->selectionModel();1040 if (!selectionModel)1041 return;1042 1043 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1044 for(int i = 0; i < selectedItemIndices.size(); ++i)1045 {1046 deleteByIndex(selectedItemIndices.at(i));1047 }1048 /** @todo dont refresh here, just delete the rows and update the table view: */1049 refresh();1050 }1051 1052 void UIGuestControlFileTable::sltRename()1053 {1054 if (!m_pView)1055 return;1056 QItemSelectionModel *selectionModel = m_pView->selectionModel();1057 if (!selectionModel)1058 return;1059 1060 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1061 if (selectedItemIndices.size() == 0)1062 return;1063 UIFileTableItem *item = indexData(selectedItemIndices.at(0));1064 if (!item || item->isUpDirectory())1065 return;1066 m_pView->edit(selectedItemIndices.at(0));1067 }1068 1069 void UIGuestControlFileTable::sltCreateNewDirectory()1070 {1071 if (!m_pModel || !m_pView)1072 return;1073 QModelIndex currentIndex = m_pView->rootIndex();1074 if (!currentIndex.isValid())1075 return;1076 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentIndex.internalPointer());1077 if (!item)1078 return;1079 1080 QString newDirectoryName = getNewDirectoryName();1081 if (newDirectoryName.isEmpty())1082 return;1083 1084 if (createDirectory(item->path(), newDirectoryName))1085 {1086 /** @todo instead of refreshing here (an overkill) just add the1087 rows and update the tabel view: */1088 sltRefresh();1089 }1090 }1091 1092 void UIGuestControlFileTable::sltCopy()1093 {1094 1095 m_copyCutBuffer = selectedItemPathList();1096 if (!m_copyCutBuffer.isEmpty())1097 m_pPaste->setEnabled(true);1098 else1099 m_pPaste->setEnabled(false);1100 }1101 1102 void UIGuestControlFileTable::sltCut()1103 {1104 m_copyCutBuffer = selectedItemPathList();1105 if (!m_copyCutBuffer.isEmpty())1106 m_pPaste->setEnabled(true);1107 else1108 m_pPaste->setEnabled(false);1109 }1110 1111 void UIGuestControlFileTable::sltPaste()1112 {1113 // paste them1114 m_copyCutBuffer.clear();1115 m_pPaste->setEnabled(false);1116 }1117 1118 void UIGuestControlFileTable::sltShowProperties()1119 {1120 QString fsPropertyString = fsObjectPropertyString();1121 if (fsPropertyString.isEmpty())1122 return;1123 1124 UIPropertiesDialog *dialog = new UIPropertiesDialog();1125 if (!dialog)1126 return;1127 dialog->setWindowTitle("Properties");1128 dialog->setPropertyText(fsPropertyString);1129 dialog->execute();1130 }1131 1132 void UIGuestControlFileTable::sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)1133 {1134 /* Disable all the action that operate on some selection: */1135 if (!deselected.isEmpty() && selected.isEmpty())1136 disableSelectionDependentActions();1137 1138 /* Enable all the action that operate on some selection: */1139 if (deselected.isEmpty() && !selected.isEmpty())1140 enableSelectionDependentActions();1141 }1142 1143 void UIGuestControlFileTable::deleteByIndex(const QModelIndex &itemIndex)1144 {1145 UIFileTableItem *treeItem = indexData(itemIndex);1146 if (!treeItem)1147 return;1148 deleteByItem(treeItem);1149 }1150 1151 void UIGuestControlFileTable::retranslateUi()1152 {1153 if (m_pGoUp)1154 {1155 m_pGoUp->setText(UIVMInformationDialog::tr("Move one level up"));1156 m_pGoUp->setToolTip(UIVMInformationDialog::tr("Move one level up"));1157 m_pGoUp->setStatusTip(UIVMInformationDialog::tr("Move one level up"));1158 }1159 1160 if (m_pGoHome)1161 {1162 m_pGoHome->setText(UIVMInformationDialog::tr("Go to home directory"));1163 m_pGoHome->setToolTip(UIVMInformationDialog::tr("Go to home directory"));1164 m_pGoHome->setStatusTip(UIVMInformationDialog::tr("Go to home directory"));1165 }1166 1167 if (m_pRename)1168 {1169 m_pRename->setText(UIVMInformationDialog::tr("Rename the selected item"));1170 m_pRename->setToolTip(UIVMInformationDialog::tr("Rename the selected item"));1171 m_pRename->setStatusTip(UIVMInformationDialog::tr("Rename the selected item"));1172 }1173 1174 if (m_pRefresh)1175 {1176 m_pRefresh->setText(UIVMInformationDialog::tr("Refresh"));1177 m_pRefresh->setToolTip(UIVMInformationDialog::tr("Refresh the current directory"));1178 m_pRefresh->setStatusTip(UIVMInformationDialog::tr("Refresh the current directory"));1179 }1180 if (m_pDelete)1181 {1182 m_pDelete->setText(UIVMInformationDialog::tr("Delete"));1183 m_pDelete->setToolTip(UIVMInformationDialog::tr("Delete the selected item(s)"));1184 m_pDelete->setStatusTip(UIVMInformationDialog::tr("Delete the selected item(s)"));1185 }1186 1187 if (m_pCreateNewDirectory)1188 {1189 m_pCreateNewDirectory->setText(UIVMInformationDialog::tr("Create new directory"));1190 m_pCreateNewDirectory->setToolTip(UIVMInformationDialog::tr("Create new directory"));1191 m_pCreateNewDirectory->setStatusTip(UIVMInformationDialog::tr("Create new directory"));1192 }1193 1194 if (m_pCopy)1195 {1196 m_pCopy->setText(UIVMInformationDialog::tr("Copy the selected item"));1197 m_pCopy->setToolTip(UIVMInformationDialog::tr("Copy the selected item(s)"));1198 m_pCopy->setStatusTip(UIVMInformationDialog::tr("Copy the selected item(s)"));1199 1200 }1201 1202 if (m_pCut)1203 {1204 m_pCut->setText(UIVMInformationDialog::tr("Cut the selected item(s)"));1205 m_pCut->setToolTip(UIVMInformationDialog::tr("Cut the selected item(s)"));1206 m_pCut->setStatusTip(UIVMInformationDialog::tr("Cut the selected item(s)"));1207 1208 }1209 1210 if ( m_pPaste)1211 {1212 m_pPaste->setText(UIVMInformationDialog::tr("Paste the copied item(s)"));1213 m_pPaste->setToolTip(UIVMInformationDialog::tr("Paste the copied item(s)"));1214 m_pPaste->setStatusTip(UIVMInformationDialog::tr("Paste the copied item(s)"));1215 }1216 1217 if (m_pShowProperties)1218 {1219 m_pShowProperties->setText(UIVMInformationDialog::tr("Show the properties of the selected item(s)"));1220 m_pShowProperties->setToolTip(UIVMInformationDialog::tr("Show the properties of the selected item(s)"));1221 m_pShowProperties->setStatusTip(UIVMInformationDialog::tr("Show the properties of the selected item(s)"));1222 }1223 }1224 1225 1226 void UIGuestControlFileTable::keyPressEvent(QKeyEvent * pEvent)1227 {1228 /* Browse into directory with enter: */1229 if (pEvent->key() == Qt::Key_Enter || pEvent->key() == Qt::Key_Return)1230 {1231 if (m_pView && m_pModel)1232 {1233 /* Get the selected item. If there are 0 or more than 1 selection do nothing: */1234 QItemSelectionModel *selectionModel = m_pView->selectionModel();1235 if (selectionModel)1236 {1237 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1238 if (selectedItemIndices.size() == 1)1239 goIntoDirectory(selectedItemIndices.at(0));1240 }1241 }1242 }1243 else if (pEvent->key() == Qt::Key_Delete)1244 {1245 sltDelete();1246 }1247 QWidget::keyPressEvent(pEvent);1248 }1249 1250 UIFileTableItem *UIGuestControlFileTable::getStartDirectoryItem()1251 {1252 if (!m_pRootItem)1253 return 0;1254 if (m_pRootItem->childCount() <= 0)1255 return 0;1256 return m_pRootItem->child(0);1257 }1258 1259 1260 QString UIGuestControlFileTable::getNewDirectoryName()1261 {1262 UIStringInputDialog *dialog = new UIStringInputDialog();1263 if (dialog->execute())1264 {1265 QString strDialog = dialog->getString();1266 delete dialog;1267 return strDialog;1268 }1269 delete dialog;1270 return QString();1271 }1272 1273 QString UIGuestControlFileTable::currentDirectoryPath() const1274 {1275 if (!m_pView)1276 return QString();1277 QModelIndex currentRoot = m_pView->rootIndex();1278 if (!currentRoot.isValid())1279 return QString();1280 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentRoot.internalPointer());1281 if (!item)1282 return QString();1283 /* be paranoid: */1284 if (!item->isDirectory())1285 return QString();1286 return item->path();1287 }1288 1289 QStringList UIGuestControlFileTable::selectedItemPathList()1290 {1291 QItemSelectionModel *selectionModel = m_pView->selectionModel();1292 if (!selectionModel)1293 return QStringList();1294 1295 QStringList pathList;1296 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1297 for(int i = 0; i < selectedItemIndices.size(); ++i)1298 {1299 UIFileTableItem *item = static_cast<UIFileTableItem*>(selectedItemIndices.at(i).internalPointer());1300 if (!item)1301 continue;1302 pathList.push_back(item->path());1303 }1304 return pathList;1305 }1306 1307 CGuestFsObjInfo UIGuestControlFileTable::guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const1308 {1309 if (comGuestSession.isNull())1310 return CGuestFsObjInfo();1311 CGuestFsObjInfo comFsObjInfo = comGuestSession.FsObjQueryInfo(path, true /*aFollowSymlinks*/);1312 if (!comFsObjInfo.isOk())1313 return CGuestFsObjInfo();1314 return comFsObjInfo;1315 }1316 1317 void UIGuestControlFileTable::enableSelectionDependentActions()1318 {1319 for (int i = 0; i < m_selectionDependentActions.size(); ++i)1320 {1321 if (m_selectionDependentActions[i])1322 m_selectionDependentActions[i]->setEnabled(true);1323 }1324 }1325 1326 void UIGuestControlFileTable::disableSelectionDependentActions()1327 {1328 /* Disable all the action that operate on some selection: */1329 for (int i = 0; i < m_selectionDependentActions.size(); ++i)1330 {1331 if (m_selectionDependentActions[i])1332 m_selectionDependentActions[i]->setEnabled(false);1333 }1334 }1335 1336 QString UIGuestControlFileTable::fileTypeString(FileObjectType type)1337 {1338 QString strType("Unknown");1339 switch(type)1340 {1341 case FileObjectType_File:1342 strType = "File";1343 break;1344 case FileObjectType_Directory:1345 strType = "Directory";1346 break;1347 case FileObjectType_SymLink:1348 strType = "Symbolic Link";1349 break;1350 case FileObjectType_Other:1351 strType = "Other";1352 break;1353 1354 case FileObjectType_Unknown:1355 default:1356 break;1357 }1358 return strType;1359 }1360 1361 1362 /*********************************************************************************************************************************1363 * UIGuestFileTable implementation. *1364 *********************************************************************************************************************************/1365 40 1366 41 UIGuestFileTable::UIGuestFileTable(QWidget *pParent /*= 0*/) … … 1650 325 return QString(); 1651 326 } 1652 1653 1654 /*********************************************************************************************************************************1655 * UIHostFileTable implementation. *1656 *********************************************************************************************************************************/1657 1658 UIHostFileTable::UIHostFileTable(QWidget *pParent /* = 0 */)1659 :UIGuestControlFileTable(pParent)1660 {1661 initializeFileTree();1662 retranslateUi();1663 }1664 1665 void UIHostFileTable::retranslateUi()1666 {1667 if (m_pLocationLabel)1668 m_pLocationLabel->setText(UIVMInformationDialog::tr("Host System"));1669 UIGuestControlFileTable::retranslateUi();1670 }1671 1672 void UIHostFileTable::readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir /*= false*/)1673 {1674 if (!parent)1675 return;1676 1677 QDir directory(strPath);1678 //directory.setFilter(QDir::NoDotAndDotDot);1679 parent->setIsOpened(true);1680 if (!directory.exists())1681 return;1682 QFileInfoList entries = directory.entryInfoList();1683 QMap<QString, UIFileTableItem*> directories;1684 QMap<QString, UIFileTableItem*> files;1685 1686 for (int i = 0; i < entries.size(); ++i)1687 {1688 const QFileInfo &fileInfo = entries.at(i);1689 1690 QList<QVariant> data;1691 data << fileInfo.fileName() << fileInfo.size() << fileInfo.lastModified();1692 UIFileTableItem *item = new UIFileTableItem(data, parent, fileType(fileInfo));1693 item->setPath(fileInfo.absoluteFilePath());1694 /* if the item is a symlink set the target path and1695 check the target if it is a directory: */1696 if (fileInfo.isSymLink())1697 {1698 item->setTargetPath(fileInfo.symLinkTarget());1699 item->setIsTargetADirectory(QFileInfo(fileInfo.symLinkTarget()).isDir());1700 }1701 if (fileInfo.isDir())1702 {1703 directories.insert(fileInfo.fileName(), item);1704 item->setIsOpened(false);1705 }1706 else1707 {1708 files.insert(fileInfo.fileName(), item);1709 item->setIsOpened(false);1710 }1711 }1712 insertItemsToTree(directories, parent, true, isStartDir);1713 insertItemsToTree(files, parent, false, isStartDir);1714 updateCurrentLocationEdit(strPath);1715 }1716 1717 void UIHostFileTable::deleteByItem(UIFileTableItem *item)1718 {1719 if (item->isUpDirectory())1720 return;1721 if (!item->isDirectory())1722 {1723 QDir itemToDelete;//(item->path());1724 itemToDelete.remove(item->path());1725 }1726 QDir itemToDelete(item->path());1727 itemToDelete.setFilter(QDir::NoDotAndDotDot);1728 /* Try to delete item recursively (in case of directories).1729 note that this is no good way of deleting big directory1730 trees. We need a better error reporting and a kind of progress1731 indicator: */1732 /** @todo replace this recursive delete by a better implementation: */1733 bool deleteSuccess = itemToDelete.removeRecursively();1734 1735 if (!deleteSuccess)1736 emit sigLogOutput(QString(item->path()).append(" could not be deleted"));1737 }1738 1739 void UIHostFileTable::goToHomeDirectory()1740 {1741 if (!m_pRootItem || m_pRootItem->childCount() <= 0)1742 return;1743 UIFileTableItem *startDirItem = m_pRootItem->child(0);1744 if (!startDirItem)1745 return;1746 1747 // UIFileTableItem *rootDirectoryItem1748 QDir homeDirectory(QDir::homePath());1749 QList<QString> pathTrail;//(QDir::rootPath());1750 do{1751 1752 pathTrail.push_front(homeDirectory.absolutePath());1753 homeDirectory.cdUp();1754 }while(!homeDirectory.isRoot());1755 1756 goIntoDirectory(pathTrail);1757 }1758 1759 bool UIHostFileTable::renameItem(UIFileTableItem *item, QString newBaseName)1760 {1761 if (!item || item->isUpDirectory() || newBaseName.isEmpty())1762 return false;1763 QString newPath = UIPathOperations::constructNewItemPath(item->path(), newBaseName);1764 QDir tempDir;1765 if (tempDir.rename(item->path(), newPath))1766 {1767 item->setPath(newPath);1768 return true;1769 }1770 return false;1771 }1772 1773 bool UIHostFileTable::createDirectory(const QString &path, const QString &directoryName)1774 {1775 QDir parentDir(path);1776 if (!parentDir.mkdir(directoryName))1777 {1778 emit sigLogOutput(UIPathOperations::mergePaths(path, directoryName).append(" could not be created"));1779 return false;1780 }1781 1782 return true;1783 }1784 1785 FileObjectType UIHostFileTable::fileType(const QFileInfo &fsInfo)1786 {1787 if (!fsInfo.exists())1788 return FileObjectType_Unknown;1789 /* first check if it is symlink becacuse for Qt1790 being smylin and directory/file is not mutually exclusive: */1791 if (fsInfo.isSymLink())1792 return FileObjectType_SymLink;1793 else if (fsInfo.isFile())1794 return FileObjectType_File;1795 else if (fsInfo.isDir())1796 return FileObjectType_Directory;1797 1798 return FileObjectType_Other;1799 }1800 1801 QString UIHostFileTable::fsObjectPropertyString()1802 {1803 QStringList selectedObjects = selectedItemPathList();1804 if (selectedObjects.isEmpty())1805 return QString();1806 if (selectedObjects.size() == 1)1807 {1808 if (selectedObjects.at(0).isNull())1809 return QString();1810 QFileInfo fileInfo(selectedObjects.at(0));1811 if (!fileInfo.exists())1812 return QString();1813 QString propertyString;1814 /* Name: */1815 propertyString += "<b>Name:</b> " + fileInfo.fileName() + "\n";1816 if (!fileInfo.suffix().isEmpty())1817 propertyString += "." + fileInfo.suffix();1818 propertyString += "<br/>";1819 /* Size: */1820 propertyString += "<b>Size:</b> " + QString::number(fileInfo.size()) + QString(" bytes");1821 propertyString += "<br/>";1822 /* Type: */1823 propertyString += "<b>Type:</b> " + fileTypeString(fileType(fileInfo));1824 propertyString += "<br/>";1825 /* Creation Date: */1826 propertyString += "<b>Created:</b> " + fileInfo.created().toString();1827 propertyString += "<br/>";1828 /* Last Modification Date: */1829 propertyString += "<b>Modified:</b> " + fileInfo.lastModified().toString();1830 propertyString += "<br/>";1831 /* Owner: */1832 propertyString += "<b>Owner:</b> " + fileInfo.owner();1833 1834 1835 return propertyString;1836 }1837 return QString();1838 }1839 1840 #include "UIGuestControlFileTable.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestFileTable.h
r71385 r71388 16 16 */ 17 17 18 #ifndef ___UIGuestControlFileTable_h___ 19 #define ___UIGuestControlFileTable_h___ 20 21 /* Qt includes: */ 22 #include <QWidget> 18 #ifndef ___UIGuestTable_h___ 19 #define ___UIGuestTable_h___ 23 20 24 21 /* COM includes: */ … … 27 24 28 25 /* GUI includes: */ 29 #include "QITableView.h" 30 #include "QIWithRetranslateUI.h" 31 32 /* Forward declarations: */ 33 class QAction; 34 class QFileInfo; 35 class QILabel; 36 class QILineEdit; 37 class QGridLayout; 38 class UIFileTableItem; 39 class UIGuestControlFileModel; 40 class UIGuestControlFileView; 41 class UIToolBar; 42 43 enum FileObjectType 44 { 45 FileObjectType_File = 0, 46 FileObjectType_Directory, 47 FileObjectType_SymLink, 48 FileObjectType_Other, 49 FileObjectType_Unknown, 50 FileObjectType_Max 51 }; 52 53 /********************************************************************************************************************************* 54 * UIFileTableItem definition. * 55 *********************************************************************************************************************************/ 56 57 class UIFileTableItem 58 { 59 public: 60 61 explicit UIFileTableItem(const QList<QVariant> &data, 62 UIFileTableItem *parentItem, FileObjectType type); 63 ~UIFileTableItem(); 64 65 void appendChild(UIFileTableItem *child); 66 67 UIFileTableItem *child(int row) const; 68 /** Return a child (if possible) by path */ 69 UIFileTableItem *child(const QString &path) const; 70 int childCount() const; 71 int columnCount() const; 72 QVariant data(int column) const; 73 void setData(const QVariant &data, int index); 74 int row() const; 75 UIFileTableItem *parentItem(); 76 77 bool isDirectory() const; 78 bool isSymLink() const; 79 bool isFile() const; 80 81 bool isOpened() const; 82 void setIsOpened(bool flag); 83 84 const QString &path() const; 85 void setPath(const QString &path); 86 87 /** True if this is directory and name is ".." */ 88 bool isUpDirectory() const; 89 void clearChildren(); 90 91 FileObjectType type() const; 92 93 const QString &targetPath() const; 94 void setTargetPath(const QString &path); 95 96 bool isTargetADirectory() const; 97 void setIsTargetADirectory(bool flag); 98 99 private: 100 QList<UIFileTableItem*> m_childItems; 101 /** Used to find children by path */ 102 QMap<QString, UIFileTableItem*> m_childMap; 103 QList<QVariant> m_itemData; 104 UIFileTableItem *m_parentItem; 105 bool m_bIsOpened; 106 /** Full absolute path of the item. Without the trailing '/' */ 107 QString m_strPath; 108 /** If this is a symlink m_targetPath keeps the absolute path of the target */ 109 QString m_strTargetPath; 110 /** True if this is a symlink and the target is a directory */ 111 bool m_isTargetADirectory; 112 FileObjectType m_type; 113 114 }; 115 116 117 /** This class serves a base class for file table. Currently a guest version 118 and a host version are derived from this base. Each of these children 119 populates the UIGuestControlFileModel by scanning the file system 120 differently. The file structre kept in this class as a tree and all 121 the interfacing is done thru this class.*/ 122 class UIGuestControlFileTable : public QIWithRetranslateUI<QWidget> 123 { 124 Q_OBJECT; 125 126 signals: 127 128 void sigLogOutput(QString); 129 130 public: 131 132 UIGuestControlFileTable(QWidget *pParent = 0); 133 virtual ~UIGuestControlFileTable(); 134 /** Delete all the tree nodes */ 135 void reset(); 136 void emitLogOutput(const QString& strOutput); 137 /** Returns the path of the rootIndex */ 138 QString currentDirectoryPath() const; 139 /** Returns the paths of the selected items (if any) as a list */ 140 QStringList selectedItemPathList(); 141 virtual void refresh(); 142 143 protected: 144 145 void retranslateUi(); 146 void updateCurrentLocationEdit(const QString& strLocation); 147 void changeLocation(const QModelIndex &index); 148 void initializeFileTree(); 149 void insertItemsToTree(QMap<QString,UIFileTableItem*> &map, UIFileTableItem *parent, 150 bool isDirectoryMap, bool isStartDir); 151 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) = 0; 152 virtual void deleteByItem(UIFileTableItem *item) = 0; 153 virtual void goToHomeDirectory() = 0; 154 virtual bool renameItem(UIFileTableItem *item, QString newBaseName) = 0; 155 virtual bool createDirectory(const QString &path, const QString &directoryName) = 0; 156 virtual QString fsObjectPropertyString() = 0; 157 static QString fileTypeString(FileObjectType type); 158 void goIntoDirectory(const QModelIndex &itemIndex); 159 /** Follow the path trail, open directories as we go and descend */ 160 void goIntoDirectory(const QList<QString> &pathTrail); 161 /** Go into directory pointed by the @p item */ 162 void goIntoDirectory(UIFileTableItem *item); 163 UIFileTableItem* indexData(const QModelIndex &index) const; 164 void keyPressEvent(QKeyEvent * pEvent); 165 CGuestFsObjInfo guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const; 166 167 168 UIFileTableItem *m_pRootItem; 169 170 UIGuestControlFileView *m_pView; 171 UIGuestControlFileModel *m_pModel; 172 QILabel *m_pLocationLabel; 173 174 private slots: 175 176 void sltItemDoubleClicked(const QModelIndex &index); 177 void sltGoUp(); 178 void sltGoHome(); 179 void sltRefresh(); 180 void sltDelete(); 181 void sltRename(); 182 void sltCopy(); 183 void sltCut(); 184 void sltPaste(); 185 void sltShowProperties(); 186 void sltCreateNewDirectory(); 187 void sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); 188 189 private: 190 191 void prepareObjects(); 192 void prepareActions(); 193 void deleteByIndex(const QModelIndex &itemIndex); 194 /** Return the UIFileTableItem for path / which is a direct (and single) child of m_pRootItem */ 195 UIFileTableItem *getStartDirectoryItem(); 196 /** Shows a modal dialog with a line edit for user to enter a new directory name and return the entered string*/ 197 QString getNewDirectoryName(); 198 void enableSelectionDependentActions(); 199 void disableSelectionDependentActions(); 200 QGridLayout *m_pMainLayout; 201 QILineEdit *m_pCurrentLocationEdit; 202 UIToolBar *m_pToolBar; 203 QAction *m_pGoUp; 204 QAction *m_pGoHome; 205 QAction *m_pRefresh; 206 QAction *m_pDelete; 207 QAction *m_pRename; 208 QAction *m_pCreateNewDirectory; 209 QAction *m_pCopy; 210 QAction *m_pCut; 211 QAction *m_pPaste; 212 QAction *m_pShowProperties; 213 /** The vector of action which need some selection to work on like cut, copy etc. */ 214 QVector<QAction*> m_selectionDependentActions; 215 /** The absolue path list of the file objects which user has chosen to cut/copy. this 216 list will be cleaned after a paste operation or overwritten by a subsequent cut/copy */ 217 QStringList m_copyCutBuffer; 218 friend class UIGuestControlFileModel; 219 }; 26 #include "UIGuestControlFileTable.h" 220 27 221 28 /** This class scans the guest file system by using the VBox API … … 254 61 }; 255 62 256 /** This class scans the host file system by using the Qt257 and populates the UIGuestControlFileModel*/258 class UIHostFileTable : public UIGuestControlFileTable259 {260 Q_OBJECT;261 262 public:263 264 UIHostFileTable(QWidget *pParent = 0);265 266 protected:267 268 static FileObjectType fileType(const QFileInfo &fsInfo);269 void retranslateUi() /* override */;270 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) /* override */;271 virtual void deleteByItem(UIFileTableItem *item) /* override */;272 virtual void goToHomeDirectory() /* override */;273 virtual bool renameItem(UIFileTableItem *item, QString newBaseName);274 virtual bool createDirectory(const QString &path, const QString &directoryName);275 virtual QString fsObjectPropertyString() /* override */;276 277 };278 279 63 #endif /* !___UIGuestControlFileTable_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIHostFileTable.cpp
r71385 r71388 21 21 22 22 /* Qt includes: */ 23 # include <QAction>24 23 # include <QDateTime> 25 24 # include <QDir> 26 # include <QHeaderView>27 # include <QItemDelegate>28 # include <QGridLayout>29 # include <QMenu>30 # include <QTextEdit>31 # include <QPushButton>32 25 33 26 /* GUI includes: */ 34 # include "QIDialog.h"35 # include "QIDialogButtonBox.h"36 27 # include "QILabel.h" 37 # include "QILineEdit.h" 38 # include "QIMessageBox.h" 39 # include "UIErrorString.h" 40 # include "UIIconPool.h" 41 # include "UIGuestControlFileTable.h" 42 # include "UIGuestControlFileModel.h" 43 # include "UIToolBar.h" 28 # include "UIHostFileTable.h" 44 29 # include "UIVMInformationDialog.h" 45 46 /* COM includes: */47 # include "CFsObjInfo.h"48 # include "CGuestFsObjInfo.h"49 # include "CGuestDirectory.h"50 # include "CProgress.h"51 52 30 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 53 31 54 55 /*********************************************************************************************************************************56 * UIPathOperations definition. *57 *********************************************************************************************************************************/58 59 /** A collection of utility functions for so60 me path string manipulations */61 class UIPathOperations62 {63 public:64 static QString removeMultipleDelimiters(const QString &path);65 static QString removeTrailingDelimiters(const QString &path);66 static QString addStartDelimiter(const QString &path);67 68 static QString sanitize(const QString &path);69 /** Merge prefix and suffix by making sure they have a single '/' in between */70 static QString mergePaths(const QString &path, const QString &baseName);71 /** Returns the last part of the @p path. That is the filename or directory name without the path */72 static QString getObjectName(const QString &path);73 /** Remove the object name and return the path */74 static QString getPathExceptObjectName(const QString &path);75 /** Replace the last part of the @p previusPath with newBaseName */76 static QString constructNewItemPath(const QString &previousPath, const QString &newBaseName);77 78 static const QChar delimiter;79 };80 81 82 /*********************************************************************************************************************************83 * UIGuestControlFileView definition. *84 *********************************************************************************************************************************/85 86 /** Using QITableView causes the following problem when I click on the table items87 Qt WARNING: Cannot creat accessible child interface for object: UIGuestControlFileView.....88 so for now subclass QTableView */89 class UIGuestControlFileView : public QTableView90 {91 92 Q_OBJECT;93 94 signals:95 96 void sigGoUp();97 void sigGoHome();98 void sigRefresh();99 void sigRename();100 void sigCreateNewDirectory();101 void sigDelete();102 void sigCut();103 void sigCopy();104 void sigPaste();105 void sigShowProperties();106 107 void sigSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);108 109 public:110 111 UIGuestControlFileView(QWidget * parent = 0);112 bool hasSelection() const;113 114 protected:115 virtual void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected) /*override */;116 void contextMenuEvent(QContextMenuEvent *pEvent);117 };118 119 120 /*********************************************************************************************************************************121 * UIFileDelegate definition. *122 *********************************************************************************************************************************/123 /** A QItemDelegate child class to disable dashed lines drawn around selected cells in QTableViews */124 class UIFileDelegate : public QItemDelegate125 {126 127 Q_OBJECT;128 129 protected:130 virtual void drawFocus ( QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, const QRect & /*rect*/ ) const {}131 };132 133 134 /*********************************************************************************************************************************135 * UIFileStringInputDialog definition. *136 *********************************************************************************************************************************/137 138 /** A QIDialog child including a line edit whose text exposed when the dialog is accepted */139 class UIStringInputDialog : public QIDialog140 {141 142 Q_OBJECT;143 144 public:145 146 UIStringInputDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);147 QString getString() const;148 149 private:150 151 QILineEdit *m_pLineEdit;152 153 };154 155 /*********************************************************************************************************************************156 * UIPropertiesDialog definition. *157 *********************************************************************************************************************************/158 159 /** A QIDialog child to display properties of a file object */160 class UIPropertiesDialog : public QIDialog161 {162 163 Q_OBJECT;164 165 public:166 167 UIPropertiesDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);168 void setPropertyText(const QString &strProperty);169 170 private:171 172 QVBoxLayout *m_pMainLayout;173 QTextEdit *m_pInfoEdit;174 175 };176 177 178 /*********************************************************************************************************************************179 * UIPathOperations implementation. *180 *********************************************************************************************************************************/181 182 const QChar UIPathOperations::delimiter = QChar('/');183 184 QString UIPathOperations::removeMultipleDelimiters(const QString &path)185 {186 QString newPath(path);187 QString doubleDelimiter(2, delimiter);188 189 while (newPath.contains(doubleDelimiter) && !newPath.isEmpty())190 newPath = newPath.replace(doubleDelimiter, delimiter);191 return newPath;192 }193 194 QString UIPathOperations::removeTrailingDelimiters(const QString &path)195 {196 if (path.isNull() || path.isEmpty())197 return QString();198 QString newPath(path);199 /* Make sure for we dont have any trailing slashes: */200 while (newPath.length() > 1 && newPath.at(newPath.length() - 1) == UIPathOperations::delimiter)201 newPath.chop(1);202 return newPath;203 }204 205 QString UIPathOperations::addStartDelimiter(const QString &path)206 {207 if (path.isEmpty())208 return QString(path);209 QString newPath(path);210 if (newPath.at(0) != delimiter)211 newPath.insert(0, delimiter);212 return newPath;213 }214 215 QString UIPathOperations::sanitize(const QString &path)216 {217 return addStartDelimiter(removeTrailingDelimiters(removeMultipleDelimiters(path)));218 }219 220 QString UIPathOperations::mergePaths(const QString &path, const QString &baseName)221 {222 QString newBase(baseName);223 newBase = newBase.remove(delimiter);224 225 /* make sure we have one and only one trailing '/': */226 QString newPath(sanitize(path));227 if(newPath.isEmpty())228 newPath = delimiter;229 if(newPath.at(newPath.length() - 1) != delimiter)230 newPath += UIPathOperations::delimiter;231 newPath += newBase;232 return sanitize(newPath);233 }234 235 QString UIPathOperations::getObjectName(const QString &path)236 {237 if (path.length() <= 1)238 return QString(path);239 240 QString strTemp(sanitize(path));241 if (strTemp.length() < 2)242 return strTemp;243 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);244 if (lastSlashPosition == -1)245 return QString();246 return strTemp.right(strTemp.length() - lastSlashPosition - 1);247 }248 249 QString UIPathOperations::getPathExceptObjectName(const QString &path)250 {251 if (path.length() <= 1)252 return QString(path);253 254 QString strTemp(sanitize(path));255 int lastSlashPosition = strTemp.lastIndexOf(UIPathOperations::delimiter);256 if (lastSlashPosition == -1)257 return QString();258 return strTemp.left(lastSlashPosition + 1);259 }260 261 QString UIPathOperations::constructNewItemPath(const QString &previousPath, const QString &newBaseName)262 {263 if (previousPath.length() <= 1)264 return QString(previousPath);265 return sanitize(mergePaths(getPathExceptObjectName(previousPath), newBaseName));266 }267 268 269 /*********************************************************************************************************************************270 * UIGuestControlFileView implementation. *271 *********************************************************************************************************************************/272 273 UIGuestControlFileView::UIGuestControlFileView(QWidget * parent)274 :QTableView(parent)275 {276 }277 278 void UIGuestControlFileView::contextMenuEvent(QContextMenuEvent *pEvent)279 {280 bool selectionAvaible = hasSelection();281 282 QMenu *menu = new QMenu(this);283 if (!menu)284 return;285 286 QAction *pActionGoUp = menu->addAction(UIVMInformationDialog::tr("Go up"));287 if (pActionGoUp)288 {289 pActionGoUp->setIcon(UIIconPool::iconSet(QString(":/arrow_up_10px_x2.png")));290 connect(pActionGoUp, &QAction::triggered, this, &UIGuestControlFileView::sigGoUp);291 }292 QAction *pActionGoHome = menu->addAction(UIVMInformationDialog::tr("Go home"));293 if (pActionGoHome)294 {295 pActionGoHome->setIcon(UIIconPool::iconSet(QString(":/nw_24px.png")));296 connect(pActionGoHome, &QAction::triggered, this, &UIGuestControlFileView::sigGoHome);297 }298 299 QAction *pActionRefresh = menu->addAction(UIVMInformationDialog::tr("Refresh"));300 if (pActionRefresh)301 {302 pActionRefresh->setIcon(UIIconPool::iconSet(QString(":/refresh_22px.png")));303 connect(pActionRefresh, &QAction::triggered, this, &UIGuestControlFileView::sigRefresh);304 }305 306 menu->addSeparator();307 QAction *pActionDelete = menu->addAction(UIVMInformationDialog::tr("Delete"));308 if (pActionDelete)309 {310 pActionDelete->setIcon(UIIconPool::iconSet(QString(":/vm_delete_32px.png")));311 pActionDelete->setEnabled(selectionAvaible);312 connect(pActionDelete, &QAction::triggered, this, &UIGuestControlFileView::sigDelete);313 }314 315 QAction *pActionRename = menu->addAction(UIVMInformationDialog::tr("Rename"));316 if (pActionRename)317 {318 pActionRename->setIcon(UIIconPool::iconSet(QString(":/name_16px_x2.png")));319 pActionRename->setEnabled(selectionAvaible);320 pActionRename->setEnabled(selectionAvaible);321 connect(pActionRename, &QAction::triggered, this, &UIGuestControlFileView::sigRename);322 }323 324 QAction *pActionCreateNewDirectory = menu->addAction(UIVMInformationDialog::tr("Create New Directory"));325 if (pActionCreateNewDirectory)326 {327 pActionCreateNewDirectory->setIcon(UIIconPool::iconSet(QString(":/sf_add_16px.png")));328 connect(pActionCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileView::sigCreateNewDirectory);329 }330 331 QAction *pActionCopy = menu->addAction(UIVMInformationDialog::tr("Copy"));332 if (pActionCopy)333 {334 pActionCopy->setIcon(UIIconPool::iconSet(QString(":/fd_copy_22px.png")));335 pActionCopy->setEnabled(selectionAvaible);336 connect(pActionCopy, &QAction::triggered, this, &UIGuestControlFileView::sigCopy);337 }338 339 QAction *pActionCut = menu->addAction(UIVMInformationDialog::tr("Cut"));340 if (pActionCut)341 {342 pActionCut->setIcon(UIIconPool::iconSet(QString(":/fd_move_22px.png")));343 pActionCut->setEnabled(selectionAvaible);344 connect(pActionCut, &QAction::triggered, this, &UIGuestControlFileView::sigCut);345 }346 347 QAction *pActionPaste = menu->addAction(UIVMInformationDialog::tr("Paste"));348 if (pActionPaste)349 {350 pActionPaste->setIcon(UIIconPool::iconSet(QString(":/shared_clipboard_16px.png")));351 connect(pActionPaste, &QAction::triggered, this, &UIGuestControlFileView::sigPaste);352 }353 354 menu->addSeparator();355 QAction *pActionShowProperties = menu->addAction(UIVMInformationDialog::tr("Properties"));356 if (pActionShowProperties)357 {358 pActionShowProperties->setIcon(UIIconPool::iconSet(QString(":/session_info_32px.png")));359 pActionShowProperties->setEnabled(selectionAvaible);360 connect(pActionShowProperties, &QAction::triggered, this, &UIGuestControlFileView::sigShowProperties);361 }362 363 menu->exec(pEvent->globalPos());364 365 if (pActionGoUp)366 disconnect(pActionGoUp, &QAction::triggered, this, &UIGuestControlFileView::sigGoUp);367 if (pActionGoHome)368 disconnect(pActionGoHome, &QAction::triggered, this, &UIGuestControlFileView::sigGoHome);369 if (pActionRefresh)370 disconnect(pActionRefresh, &QAction::triggered, this, &UIGuestControlFileView::sigRefresh);371 if (pActionDelete)372 disconnect(pActionDelete, &QAction::triggered, this, &UIGuestControlFileView::sigDelete);373 if (pActionRename)374 disconnect(pActionRename, &QAction::triggered, this, &UIGuestControlFileView::sigRename);375 if (pActionCreateNewDirectory)376 disconnect(pActionCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileView::sigCreateNewDirectory);377 if (pActionCopy)378 disconnect(pActionCopy, &QAction::triggered, this, &UIGuestControlFileView::sigCopy);379 if (pActionCut)380 disconnect(pActionCut, &QAction::triggered, this, &UIGuestControlFileView::sigCut);381 if (pActionPaste)382 disconnect(pActionPaste, &QAction::triggered, this, &UIGuestControlFileView::sigPaste);383 if (pActionShowProperties)384 disconnect(pActionShowProperties, &QAction::triggered, this, &UIGuestControlFileView::sigShowProperties);385 386 delete menu;387 }388 389 bool UIGuestControlFileView::hasSelection() const390 {391 QItemSelectionModel *pSelectionModel = selectionModel();392 if (!pSelectionModel)393 return false;394 return pSelectionModel->hasSelection();395 }396 397 void UIGuestControlFileView::selectionChanged(const QItemSelection & selected, const QItemSelection & deselected)398 {399 emit sigSelectionChanged(selected, deselected);400 QTableView::selectionChanged(selected, deselected);401 }402 403 404 /*********************************************************************************************************************************405 * UIFileStringInputDialog implementation. *406 *********************************************************************************************************************************/407 408 UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)409 :QIDialog(pParent, flags)410 {411 QVBoxLayout *layout = new QVBoxLayout(this);412 m_pLineEdit = new QILineEdit(this);413 layout->addWidget(m_pLineEdit);414 415 QIDialogButtonBox *pButtonBox =416 new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);417 layout->addWidget(pButtonBox);418 // {419 // /* Configure button-box: */420 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);421 connect(pButtonBox, &QIDialogButtonBox::rejected, this, &UIStringInputDialog::reject);422 423 }424 425 QString UIStringInputDialog::getString() const426 {427 if (!m_pLineEdit)428 return QString();429 return m_pLineEdit->text();430 }431 432 433 /*********************************************************************************************************************************434 * UIPropertiesDialog implementation. *435 *********************************************************************************************************************************/436 437 UIPropertiesDialog::UIPropertiesDialog(QWidget *pParent, Qt::WindowFlags flags)438 :QIDialog(pParent, flags)439 , m_pMainLayout(new QVBoxLayout)440 , m_pInfoEdit(new QTextEdit)441 {442 setLayout(m_pMainLayout);443 444 if (m_pMainLayout)445 m_pMainLayout->addWidget(m_pInfoEdit);446 if (m_pInfoEdit)447 {448 m_pInfoEdit->setReadOnly(true);449 m_pInfoEdit->setFrameStyle(QFrame::NoFrame);450 }451 QIDialogButtonBox *pButtonBox =452 new QIDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this);453 m_pMainLayout->addWidget(pButtonBox);454 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);455 }456 457 void UIPropertiesDialog::setPropertyText(const QString &strProperty)458 {459 if (!m_pInfoEdit)460 return;461 462 m_pInfoEdit->setText(strProperty);463 }464 465 466 /*********************************************************************************************************************************467 * UIFileTableItem implementation. *468 *********************************************************************************************************************************/469 470 471 UIFileTableItem::UIFileTableItem(const QList<QVariant> &data,472 UIFileTableItem *parent, FileObjectType type)473 : m_itemData(data)474 , m_parentItem(parent)475 , m_bIsOpened(false)476 , m_isTargetADirectory(false)477 , m_type(type)478 {479 }480 481 UIFileTableItem::~UIFileTableItem()482 {483 qDeleteAll(m_childItems);484 m_childItems.clear();485 }486 487 void UIFileTableItem::appendChild(UIFileTableItem *item)488 {489 if (!item)490 return;491 m_childItems.append(item);492 m_childMap.insert(item->path(), item);493 }494 495 UIFileTableItem *UIFileTableItem::child(int row) const496 {497 return m_childItems.value(row);498 }499 500 UIFileTableItem *UIFileTableItem::child(const QString &path) const501 {502 if (!m_childMap.contains(path))503 return 0;504 return m_childMap.value(path);505 }506 507 int UIFileTableItem::childCount() const508 {509 return m_childItems.count();510 }511 512 int UIFileTableItem::columnCount() const513 {514 return m_itemData.count();515 }516 517 QVariant UIFileTableItem::data(int column) const518 {519 return m_itemData.value(column);520 }521 522 void UIFileTableItem::setData(const QVariant &data, int index)523 {524 if (index >= m_itemData.length())525 return;526 m_itemData[index] = data;527 }528 529 UIFileTableItem *UIFileTableItem::parentItem()530 {531 return m_parentItem;532 }533 534 int UIFileTableItem::row() const535 {536 if (m_parentItem)537 return m_parentItem->m_childItems.indexOf(const_cast<UIFileTableItem*>(this));538 return 0;539 }540 541 bool UIFileTableItem::isDirectory() const542 {543 return m_type == FileObjectType_Directory;544 }545 546 bool UIFileTableItem::isSymLink() const547 {548 return m_type == FileObjectType_SymLink;549 }550 551 bool UIFileTableItem::isFile() const552 {553 return m_type == FileObjectType_File;554 }555 556 void UIFileTableItem::clearChildren()557 {558 qDeleteAll(m_childItems);559 m_childItems.clear();560 m_childMap.clear();561 }562 563 bool UIFileTableItem::isOpened() const564 {565 return m_bIsOpened;566 }567 568 void UIFileTableItem::setIsOpened(bool flag)569 {570 m_bIsOpened = flag;571 }572 573 const QString &UIFileTableItem::path() const574 {575 return m_strPath;576 }577 578 void UIFileTableItem::setPath(const QString &path)579 {580 if (path.isNull() || path.isEmpty())581 return;582 m_strPath = path;583 UIPathOperations::removeTrailingDelimiters(m_strPath);584 }585 586 bool UIFileTableItem::isUpDirectory() const587 {588 if (!isDirectory())589 return false;590 if (data(0) == QString(".."))591 return true;592 return false;593 }594 595 FileObjectType UIFileTableItem::type() const596 {597 return m_type;598 }599 600 const QString &UIFileTableItem::targetPath() const601 {602 return m_strTargetPath;603 }604 605 void UIFileTableItem::setTargetPath(const QString &path)606 {607 m_strTargetPath = path;608 }609 610 bool UIFileTableItem::isTargetADirectory() const611 {612 return m_isTargetADirectory;613 }614 615 void UIFileTableItem::setIsTargetADirectory(bool flag)616 {617 m_isTargetADirectory = flag;618 }619 620 621 /*********************************************************************************************************************************622 * UIGuestControlFileTable implementation. *623 *********************************************************************************************************************************/624 625 UIGuestControlFileTable::UIGuestControlFileTable(QWidget *pParent /* = 0 */)626 :QIWithRetranslateUI<QWidget>(pParent)627 , m_pRootItem(0)628 , m_pView(0)629 , m_pModel(0)630 , m_pLocationLabel(0)631 , m_pMainLayout(0)632 , m_pCurrentLocationEdit(0)633 , m_pToolBar(0)634 , m_pGoUp(0)635 , m_pGoHome(0)636 , m_pRefresh(0)637 , m_pDelete(0)638 , m_pRename(0)639 , m_pCreateNewDirectory(0)640 , m_pCopy(0)641 , m_pCut(0)642 , m_pPaste(0)643 , m_pShowProperties(0)644 645 {646 prepareObjects();647 prepareActions();648 }649 650 UIGuestControlFileTable::~UIGuestControlFileTable()651 {652 delete m_pRootItem;653 }654 655 void UIGuestControlFileTable::reset()656 {657 if (m_pModel)658 m_pModel->beginReset();659 delete m_pRootItem;660 m_pRootItem = 0;661 if (m_pModel)662 m_pModel->endReset();663 if (m_pCurrentLocationEdit)664 m_pCurrentLocationEdit->clear();665 }666 667 void UIGuestControlFileTable::emitLogOutput(const QString& strOutput)668 {669 emit sigLogOutput(strOutput);670 }671 672 void UIGuestControlFileTable::prepareObjects()673 {674 m_pMainLayout = new QGridLayout();675 if (!m_pMainLayout)676 return;677 m_pMainLayout->setSpacing(0);678 m_pMainLayout->setContentsMargins(0, 0, 0, 0);679 setLayout(m_pMainLayout);680 681 m_pToolBar = new UIToolBar;682 if (m_pToolBar)683 {684 m_pMainLayout->addWidget(m_pToolBar, 0, 0, 1, 5);685 }686 687 m_pLocationLabel = new QILabel;688 if (m_pLocationLabel)689 {690 m_pMainLayout->addWidget(m_pLocationLabel, 1, 0, 1, 1);691 }692 693 m_pCurrentLocationEdit = new QILineEdit;694 if (m_pCurrentLocationEdit)695 {696 m_pMainLayout->addWidget(m_pCurrentLocationEdit, 1, 1, 1, 4);697 m_pCurrentLocationEdit->setReadOnly(true);698 }699 700 m_pModel = new UIGuestControlFileModel(this);701 if (!m_pModel)702 return;703 704 705 m_pView = new UIGuestControlFileView;706 if (m_pView)707 {708 m_pView->setShowGrid(false);709 m_pView->setSelectionBehavior(QAbstractItemView::SelectRows);710 m_pView->verticalHeader()->setVisible(false);711 712 m_pMainLayout->addWidget(m_pView, 2, 0, 5, 5);713 m_pView->setModel(m_pModel);714 m_pView->setItemDelegate(new UIFileDelegate);715 m_pView->setEditTriggers(QAbstractItemView::NoEditTriggers);716 /* Minimize the row height: */717 m_pView->verticalHeader()->setDefaultSectionSize(m_pView->verticalHeader()->minimumSectionSize());718 /* Make the columns take all the avaible space: */719 //m_pView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);720 721 connect(m_pView, &UIGuestControlFileView::doubleClicked,722 this, &UIGuestControlFileTable::sltItemDoubleClicked);723 724 connect(m_pView, &UIGuestControlFileView::sigGoUp,725 this, &UIGuestControlFileTable::sltGoUp);726 connect(m_pView, &UIGuestControlFileView::sigGoHome,727 this, &UIGuestControlFileTable::sltGoHome);728 connect(m_pView, &UIGuestControlFileView::sigRefresh,729 this, &UIGuestControlFileTable::sltRefresh);730 connect(m_pView, &UIGuestControlFileView::sigDelete,731 this, &UIGuestControlFileTable::sltDelete);732 connect(m_pView, &UIGuestControlFileView::sigRename,733 this, &UIGuestControlFileTable::sltRename);734 connect(m_pView, &UIGuestControlFileView::sigCreateNewDirectory,735 this, &UIGuestControlFileTable::sltCreateNewDirectory);736 connect(m_pView, &UIGuestControlFileView::sigCopy,737 this, &UIGuestControlFileTable::sltCopy);738 connect(m_pView, &UIGuestControlFileView::sigCut,739 this, &UIGuestControlFileTable::sltCut);740 connect(m_pView, &UIGuestControlFileView::sigPaste,741 this, &UIGuestControlFileTable::sltPaste);742 connect(m_pView, &UIGuestControlFileView::sigShowProperties,743 this, &UIGuestControlFileTable::sltShowProperties);744 connect(m_pView, &UIGuestControlFileView::sigSelectionChanged,745 this, &UIGuestControlFileTable::sltSelectionChanged);746 747 }748 }749 750 void UIGuestControlFileTable::prepareActions()751 {752 if (!m_pToolBar)753 return;754 755 m_pGoUp = new QAction(this);756 if (m_pGoUp)757 {758 connect(m_pGoUp, &QAction::triggered, this, &UIGuestControlFileTable::sltGoUp);759 m_pGoUp->setIcon(UIIconPool::iconSet(QString(":/arrow_up_10px_x2.png")));760 m_pToolBar->addAction(m_pGoUp);761 }762 763 m_pGoHome = new QAction(this);764 if (m_pGoHome)765 {766 connect(m_pGoHome, &QAction::triggered, this, &UIGuestControlFileTable::sltGoHome);767 m_pGoHome->setIcon(UIIconPool::iconSet(QString(":/nw_24px.png")));768 m_pToolBar->addAction(m_pGoHome);769 }770 771 m_pRefresh = new QAction(this);772 if (m_pRefresh)773 {774 connect(m_pRefresh, &QAction::triggered, this, &UIGuestControlFileTable::sltRefresh);775 m_pRefresh->setIcon(UIIconPool::iconSet(QString(":/refresh_22px.png")));776 m_pToolBar->addAction(m_pRefresh);777 }778 779 m_pToolBar->addSeparator();780 781 m_pDelete = new QAction(this);782 if (m_pDelete)783 {784 connect(m_pDelete, &QAction::triggered, this, &UIGuestControlFileTable::sltDelete);785 m_pDelete->setIcon(UIIconPool::iconSet(QString(":/vm_delete_32px.png")));786 m_pToolBar->addAction(m_pDelete);787 m_selectionDependentActions.push_back(m_pDelete);788 }789 790 m_pRename = new QAction(this);791 if (m_pRename)792 {793 connect(m_pRename, &QAction::triggered, this, &UIGuestControlFileTable::sltRename);794 m_pRename->setIcon(UIIconPool::iconSet(QString(":/name_16px_x2.png")));795 m_pToolBar->addAction(m_pRename);796 m_selectionDependentActions.push_back(m_pRename);797 }798 799 m_pCreateNewDirectory = new QAction(this);800 if (m_pCreateNewDirectory)801 {802 connect(m_pCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileTable::sltCreateNewDirectory);803 m_pCreateNewDirectory->setIcon(UIIconPool::iconSet(QString(":/sf_add_16px.png")));804 m_pToolBar->addAction(m_pCreateNewDirectory);805 }806 807 m_pCopy = new QAction(this);808 if (m_pCopy)809 {810 m_pCopy->setIcon(UIIconPool::iconSet(QString(":/fd_copy_22px.png")));811 m_pToolBar->addAction(m_pCopy);812 connect(m_pCopy, &QAction::triggered, this, &UIGuestControlFileTable::sltCopy);813 m_selectionDependentActions.push_back(m_pCopy);814 }815 816 m_pCut = new QAction(this);817 if (m_pCut)818 {819 m_pCut->setIcon(UIIconPool::iconSet(QString(":/fd_move_22px.png")));820 m_pToolBar->addAction(m_pCut);821 connect(m_pCut, &QAction::triggered, this, &UIGuestControlFileTable::sltCut);822 m_selectionDependentActions.push_back(m_pCut);823 }824 825 m_pPaste = new QAction(this);826 if (m_pPaste)827 {828 m_pPaste->setIcon(UIIconPool::iconSet(QString(":/shared_clipboard_16px.png")));829 m_pToolBar->addAction(m_pPaste);830 connect(m_pPaste, &QAction::triggered, this, &UIGuestControlFileTable::sltPaste);831 m_pPaste->setEnabled(false);832 }833 834 m_pToolBar->addSeparator();835 836 m_pShowProperties = new QAction(this);837 {838 m_pShowProperties->setIcon(UIIconPool::iconSet(QString(":/session_info_32px.png")));839 m_pToolBar->addAction(m_pShowProperties);840 connect(m_pShowProperties, &QAction::triggered, this, &UIGuestControlFileTable::sltShowProperties);841 m_selectionDependentActions.push_back(m_pShowProperties);842 }843 844 disableSelectionDependentActions();845 }846 847 void UIGuestControlFileTable::updateCurrentLocationEdit(const QString& strLocation)848 {849 if (!m_pCurrentLocationEdit)850 return;851 m_pCurrentLocationEdit->setText(strLocation);852 }853 854 void UIGuestControlFileTable::changeLocation(const QModelIndex &index)855 {856 if (!index.isValid() || !m_pView)857 return;858 m_pView->setRootIndex(index);859 m_pView->clearSelection();860 861 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());862 if (item)863 {864 updateCurrentLocationEdit(item->path());865 }866 m_pModel->signalUpdate();867 }868 869 void UIGuestControlFileTable::initializeFileTree()870 {871 if (m_pRootItem)872 reset();873 874 QList<QVariant> headData;875 headData << "Name" << "Size" << "Change Time";876 m_pRootItem = new UIFileTableItem(headData, 0, FileObjectType_Directory);877 QList<QVariant> startDirData;878 startDirData << "/" << 4096 << QDateTime();879 UIFileTableItem* startItem = new UIFileTableItem(startDirData, m_pRootItem, FileObjectType_Directory);880 881 startItem->setPath("/");882 m_pRootItem->appendChild(startItem);883 884 startItem->setIsOpened(false);885 /* Read the root directory and get the list: */886 887 readDirectory("/", startItem, true);888 m_pView->setRootIndex(m_pModel->rootIndex());889 m_pModel->signalUpdate();890 891 }892 893 void UIGuestControlFileTable::insertItemsToTree(QMap<QString,UIFileTableItem*> &map,894 UIFileTableItem *parent, bool isDirectoryMap, bool isStartDir)895 {896 /* Make sure we have a ".." item within directories, and make sure it is not there for the start dir: */897 if (isDirectoryMap)898 {899 if (!map.contains("..") && !isStartDir)900 {901 QList<QVariant> data;902 data << ".." << 4096;903 UIFileTableItem *item = new UIFileTableItem(data, parent, FileObjectType_Directory);904 item->setIsOpened(false);905 map.insert("..", item);906 }907 else if (map.contains("..") && isStartDir)908 {909 map.remove("..");910 }911 }912 for (QMap<QString,UIFileTableItem*>::const_iterator iterator = map.begin();913 iterator != map.end(); ++iterator)914 {915 if (iterator.key() == "." || iterator.key().isEmpty())916 continue;917 parent->appendChild(iterator.value());918 }919 }920 921 void UIGuestControlFileTable::sltItemDoubleClicked(const QModelIndex &index)922 {923 if (!index.isValid() || !m_pModel || !m_pView)924 return;925 goIntoDirectory(index);926 }927 928 void UIGuestControlFileTable::sltGoUp()929 {930 if (!m_pView || !m_pModel)931 return;932 QModelIndex currentRoot = m_pView->rootIndex();933 if (!currentRoot.isValid())934 return;935 if (currentRoot != m_pModel->rootIndex())936 changeLocation(currentRoot.parent());937 }938 939 void UIGuestControlFileTable::sltGoHome()940 {941 goToHomeDirectory();942 }943 944 void UIGuestControlFileTable::sltRefresh()945 {946 refresh();947 }948 949 void UIGuestControlFileTable::goIntoDirectory(const QModelIndex &itemIndex)950 {951 if (!m_pModel)952 return;953 954 /* Make sure the colum is 0: */955 QModelIndex index = m_pModel->index(itemIndex.row(), 0, itemIndex.parent());956 if (!index.isValid())957 return;958 959 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());960 if (!item)961 return;962 963 /* check if we need to go up: */964 if (item->isUpDirectory())965 {966 QModelIndex parentIndex = m_pModel->parent(m_pModel->parent(index));967 if (parentIndex.isValid())968 changeLocation(parentIndex);969 return;970 }971 972 if (!item->isDirectory())973 return;974 if (!item->isOpened())975 readDirectory(item->path(),item);976 changeLocation(index);977 }978 979 void UIGuestControlFileTable::goIntoDirectory(const QList<QString> &pathTrail)980 {981 UIFileTableItem *parent = getStartDirectoryItem();982 983 for(int i = 0; i < pathTrail.size(); ++i)984 {985 if (!parent)986 return;987 /* Make sure parent is already opened: */988 if (!parent->isOpened())989 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());990 /* search the current path item among the parent's children: */991 UIFileTableItem *item = parent->child(pathTrail.at(i));992 if (!item)993 return;994 parent = item;995 }996 if (!parent)997 return;998 if (!parent->isOpened())999 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());1000 goIntoDirectory(parent);1001 }1002 1003 void UIGuestControlFileTable::goIntoDirectory(UIFileTableItem *item)1004 {1005 if (!item || !m_pModel)1006 return;1007 goIntoDirectory(m_pModel->index(item));1008 }1009 1010 UIFileTableItem* UIGuestControlFileTable::indexData(const QModelIndex &index) const1011 {1012 if (!index.isValid())1013 return 0;1014 return static_cast<UIFileTableItem*>(index.internalPointer());1015 }1016 1017 void UIGuestControlFileTable::refresh()1018 {1019 if (!m_pView || !m_pModel)1020 return;1021 QModelIndex currentIndex = m_pView->rootIndex();1022 1023 UIFileTableItem *treeItem = indexData(currentIndex);1024 if (!treeItem)1025 return;1026 bool isRootDir = (m_pModel->rootIndex() == currentIndex);1027 m_pModel->beginReset();1028 /* For now we clear the whole subtree (that isrecursively) which is an overkill: */1029 treeItem->clearChildren();1030 readDirectory(treeItem->path(), treeItem, isRootDir);1031 m_pModel->endReset();1032 m_pView->setRootIndex(currentIndex);1033 }1034 1035 void UIGuestControlFileTable::sltDelete()1036 {1037 if (!m_pView || !m_pModel)1038 return;1039 QItemSelectionModel *selectionModel = m_pView->selectionModel();1040 if (!selectionModel)1041 return;1042 1043 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1044 for(int i = 0; i < selectedItemIndices.size(); ++i)1045 {1046 deleteByIndex(selectedItemIndices.at(i));1047 }1048 /** @todo dont refresh here, just delete the rows and update the table view: */1049 refresh();1050 }1051 1052 void UIGuestControlFileTable::sltRename()1053 {1054 if (!m_pView)1055 return;1056 QItemSelectionModel *selectionModel = m_pView->selectionModel();1057 if (!selectionModel)1058 return;1059 1060 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1061 if (selectedItemIndices.size() == 0)1062 return;1063 UIFileTableItem *item = indexData(selectedItemIndices.at(0));1064 if (!item || item->isUpDirectory())1065 return;1066 m_pView->edit(selectedItemIndices.at(0));1067 }1068 1069 void UIGuestControlFileTable::sltCreateNewDirectory()1070 {1071 if (!m_pModel || !m_pView)1072 return;1073 QModelIndex currentIndex = m_pView->rootIndex();1074 if (!currentIndex.isValid())1075 return;1076 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentIndex.internalPointer());1077 if (!item)1078 return;1079 1080 QString newDirectoryName = getNewDirectoryName();1081 if (newDirectoryName.isEmpty())1082 return;1083 1084 if (createDirectory(item->path(), newDirectoryName))1085 {1086 /** @todo instead of refreshing here (an overkill) just add the1087 rows and update the tabel view: */1088 sltRefresh();1089 }1090 }1091 1092 void UIGuestControlFileTable::sltCopy()1093 {1094 1095 m_copyCutBuffer = selectedItemPathList();1096 if (!m_copyCutBuffer.isEmpty())1097 m_pPaste->setEnabled(true);1098 else1099 m_pPaste->setEnabled(false);1100 }1101 1102 void UIGuestControlFileTable::sltCut()1103 {1104 m_copyCutBuffer = selectedItemPathList();1105 if (!m_copyCutBuffer.isEmpty())1106 m_pPaste->setEnabled(true);1107 else1108 m_pPaste->setEnabled(false);1109 }1110 1111 void UIGuestControlFileTable::sltPaste()1112 {1113 // paste them1114 m_copyCutBuffer.clear();1115 m_pPaste->setEnabled(false);1116 }1117 1118 void UIGuestControlFileTable::sltShowProperties()1119 {1120 QString fsPropertyString = fsObjectPropertyString();1121 if (fsPropertyString.isEmpty())1122 return;1123 1124 UIPropertiesDialog *dialog = new UIPropertiesDialog();1125 if (!dialog)1126 return;1127 dialog->setWindowTitle("Properties");1128 dialog->setPropertyText(fsPropertyString);1129 dialog->execute();1130 }1131 1132 void UIGuestControlFileTable::sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)1133 {1134 /* Disable all the action that operate on some selection: */1135 if (!deselected.isEmpty() && selected.isEmpty())1136 disableSelectionDependentActions();1137 1138 /* Enable all the action that operate on some selection: */1139 if (deselected.isEmpty() && !selected.isEmpty())1140 enableSelectionDependentActions();1141 }1142 1143 void UIGuestControlFileTable::deleteByIndex(const QModelIndex &itemIndex)1144 {1145 UIFileTableItem *treeItem = indexData(itemIndex);1146 if (!treeItem)1147 return;1148 deleteByItem(treeItem);1149 }1150 1151 void UIGuestControlFileTable::retranslateUi()1152 {1153 if (m_pGoUp)1154 {1155 m_pGoUp->setText(UIVMInformationDialog::tr("Move one level up"));1156 m_pGoUp->setToolTip(UIVMInformationDialog::tr("Move one level up"));1157 m_pGoUp->setStatusTip(UIVMInformationDialog::tr("Move one level up"));1158 }1159 1160 if (m_pGoHome)1161 {1162 m_pGoHome->setText(UIVMInformationDialog::tr("Go to home directory"));1163 m_pGoHome->setToolTip(UIVMInformationDialog::tr("Go to home directory"));1164 m_pGoHome->setStatusTip(UIVMInformationDialog::tr("Go to home directory"));1165 }1166 1167 if (m_pRename)1168 {1169 m_pRename->setText(UIVMInformationDialog::tr("Rename the selected item"));1170 m_pRename->setToolTip(UIVMInformationDialog::tr("Rename the selected item"));1171 m_pRename->setStatusTip(UIVMInformationDialog::tr("Rename the selected item"));1172 }1173 1174 if (m_pRefresh)1175 {1176 m_pRefresh->setText(UIVMInformationDialog::tr("Refresh"));1177 m_pRefresh->setToolTip(UIVMInformationDialog::tr("Refresh the current directory"));1178 m_pRefresh->setStatusTip(UIVMInformationDialog::tr("Refresh the current directory"));1179 }1180 if (m_pDelete)1181 {1182 m_pDelete->setText(UIVMInformationDialog::tr("Delete"));1183 m_pDelete->setToolTip(UIVMInformationDialog::tr("Delete the selected item(s)"));1184 m_pDelete->setStatusTip(UIVMInformationDialog::tr("Delete the selected item(s)"));1185 }1186 1187 if (m_pCreateNewDirectory)1188 {1189 m_pCreateNewDirectory->setText(UIVMInformationDialog::tr("Create new directory"));1190 m_pCreateNewDirectory->setToolTip(UIVMInformationDialog::tr("Create new directory"));1191 m_pCreateNewDirectory->setStatusTip(UIVMInformationDialog::tr("Create new directory"));1192 }1193 1194 if (m_pCopy)1195 {1196 m_pCopy->setText(UIVMInformationDialog::tr("Copy the selected item"));1197 m_pCopy->setToolTip(UIVMInformationDialog::tr("Copy the selected item(s)"));1198 m_pCopy->setStatusTip(UIVMInformationDialog::tr("Copy the selected item(s)"));1199 1200 }1201 1202 if (m_pCut)1203 {1204 m_pCut->setText(UIVMInformationDialog::tr("Cut the selected item(s)"));1205 m_pCut->setToolTip(UIVMInformationDialog::tr("Cut the selected item(s)"));1206 m_pCut->setStatusTip(UIVMInformationDialog::tr("Cut the selected item(s)"));1207 1208 }1209 1210 if ( m_pPaste)1211 {1212 m_pPaste->setText(UIVMInformationDialog::tr("Paste the copied item(s)"));1213 m_pPaste->setToolTip(UIVMInformationDialog::tr("Paste the copied item(s)"));1214 m_pPaste->setStatusTip(UIVMInformationDialog::tr("Paste the copied item(s)"));1215 }1216 1217 if (m_pShowProperties)1218 {1219 m_pShowProperties->setText(UIVMInformationDialog::tr("Show the properties of the selected item(s)"));1220 m_pShowProperties->setToolTip(UIVMInformationDialog::tr("Show the properties of the selected item(s)"));1221 m_pShowProperties->setStatusTip(UIVMInformationDialog::tr("Show the properties of the selected item(s)"));1222 }1223 }1224 1225 1226 void UIGuestControlFileTable::keyPressEvent(QKeyEvent * pEvent)1227 {1228 /* Browse into directory with enter: */1229 if (pEvent->key() == Qt::Key_Enter || pEvent->key() == Qt::Key_Return)1230 {1231 if (m_pView && m_pModel)1232 {1233 /* Get the selected item. If there are 0 or more than 1 selection do nothing: */1234 QItemSelectionModel *selectionModel = m_pView->selectionModel();1235 if (selectionModel)1236 {1237 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1238 if (selectedItemIndices.size() == 1)1239 goIntoDirectory(selectedItemIndices.at(0));1240 }1241 }1242 }1243 else if (pEvent->key() == Qt::Key_Delete)1244 {1245 sltDelete();1246 }1247 QWidget::keyPressEvent(pEvent);1248 }1249 1250 UIFileTableItem *UIGuestControlFileTable::getStartDirectoryItem()1251 {1252 if (!m_pRootItem)1253 return 0;1254 if (m_pRootItem->childCount() <= 0)1255 return 0;1256 return m_pRootItem->child(0);1257 }1258 1259 1260 QString UIGuestControlFileTable::getNewDirectoryName()1261 {1262 UIStringInputDialog *dialog = new UIStringInputDialog();1263 if (dialog->execute())1264 {1265 QString strDialog = dialog->getString();1266 delete dialog;1267 return strDialog;1268 }1269 delete dialog;1270 return QString();1271 }1272 1273 QString UIGuestControlFileTable::currentDirectoryPath() const1274 {1275 if (!m_pView)1276 return QString();1277 QModelIndex currentRoot = m_pView->rootIndex();1278 if (!currentRoot.isValid())1279 return QString();1280 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentRoot.internalPointer());1281 if (!item)1282 return QString();1283 /* be paranoid: */1284 if (!item->isDirectory())1285 return QString();1286 return item->path();1287 }1288 1289 QStringList UIGuestControlFileTable::selectedItemPathList()1290 {1291 QItemSelectionModel *selectionModel = m_pView->selectionModel();1292 if (!selectionModel)1293 return QStringList();1294 1295 QStringList pathList;1296 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1297 for(int i = 0; i < selectedItemIndices.size(); ++i)1298 {1299 UIFileTableItem *item = static_cast<UIFileTableItem*>(selectedItemIndices.at(i).internalPointer());1300 if (!item)1301 continue;1302 pathList.push_back(item->path());1303 }1304 return pathList;1305 }1306 1307 CGuestFsObjInfo UIGuestControlFileTable::guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const1308 {1309 if (comGuestSession.isNull())1310 return CGuestFsObjInfo();1311 CGuestFsObjInfo comFsObjInfo = comGuestSession.FsObjQueryInfo(path, true /*aFollowSymlinks*/);1312 if (!comFsObjInfo.isOk())1313 return CGuestFsObjInfo();1314 return comFsObjInfo;1315 }1316 1317 void UIGuestControlFileTable::enableSelectionDependentActions()1318 {1319 for (int i = 0; i < m_selectionDependentActions.size(); ++i)1320 {1321 if (m_selectionDependentActions[i])1322 m_selectionDependentActions[i]->setEnabled(true);1323 }1324 }1325 1326 void UIGuestControlFileTable::disableSelectionDependentActions()1327 {1328 /* Disable all the action that operate on some selection: */1329 for (int i = 0; i < m_selectionDependentActions.size(); ++i)1330 {1331 if (m_selectionDependentActions[i])1332 m_selectionDependentActions[i]->setEnabled(false);1333 }1334 }1335 1336 QString UIGuestControlFileTable::fileTypeString(FileObjectType type)1337 {1338 QString strType("Unknown");1339 switch(type)1340 {1341 case FileObjectType_File:1342 strType = "File";1343 break;1344 case FileObjectType_Directory:1345 strType = "Directory";1346 break;1347 case FileObjectType_SymLink:1348 strType = "Symbolic Link";1349 break;1350 case FileObjectType_Other:1351 strType = "Other";1352 break;1353 1354 case FileObjectType_Unknown:1355 default:1356 break;1357 }1358 return strType;1359 }1360 1361 1362 /*********************************************************************************************************************************1363 * UIGuestFileTable implementation. *1364 *********************************************************************************************************************************/1365 1366 UIGuestFileTable::UIGuestFileTable(QWidget *pParent /*= 0*/)1367 :UIGuestControlFileTable(pParent)1368 {1369 retranslateUi();1370 }1371 1372 void UIGuestFileTable::initGuestFileTable(const CGuestSession &session)1373 {1374 if (!session.isOk())1375 return;1376 if (session.GetStatus() != KGuestSessionStatus_Started)1377 return;1378 m_comGuestSession = session;1379 1380 1381 initializeFileTree();1382 }1383 1384 void UIGuestFileTable::retranslateUi()1385 {1386 if (m_pLocationLabel)1387 m_pLocationLabel->setText(UIVMInformationDialog::tr("Guest System"));1388 UIGuestControlFileTable::retranslateUi();1389 }1390 1391 void UIGuestFileTable::readDirectory(const QString& strPath,1392 UIFileTableItem *parent, bool isStartDir /*= false*/)1393 1394 {1395 if (!parent)1396 return;1397 1398 CGuestDirectory directory;1399 QVector<KDirectoryOpenFlag> flag;1400 flag.push_back(KDirectoryOpenFlag_None);1401 1402 directory = m_comGuestSession.DirectoryOpen(strPath, /*aFilter*/ "", flag);1403 parent->setIsOpened(true);1404 if (directory.isOk())1405 {1406 CFsObjInfo fsInfo = directory.Read();1407 QMap<QString, UIFileTableItem*> directories;1408 QMap<QString, UIFileTableItem*> files;1409 1410 while (fsInfo.isOk())1411 {1412 QList<QVariant> data;1413 QDateTime changeTime = QDateTime::fromMSecsSinceEpoch(fsInfo.GetChangeTime()/1000000);1414 1415 data << fsInfo.GetName() << static_cast<qulonglong>(fsInfo.GetObjectSize()) << changeTime;1416 FileObjectType fsObjectType = fileType(fsInfo);1417 UIFileTableItem *item = new UIFileTableItem(data, parent, fsObjectType);1418 item->setPath(UIPathOperations::mergePaths(strPath, fsInfo.GetName()));1419 if (fsObjectType == FileObjectType_Directory)1420 {1421 directories.insert(fsInfo.GetName(), item);1422 item->setIsOpened(false);1423 }1424 else if(fsObjectType == FileObjectType_File)1425 {1426 files.insert(fsInfo.GetName(), item);1427 item->setIsOpened(false);1428 }1429 /** @todo Seems like our API is not able to detect symlinks: */1430 else if(fsObjectType == FileObjectType_SymLink)1431 {1432 files.insert(fsInfo.GetName(), item);1433 item->setIsOpened(false);1434 }1435 1436 fsInfo = directory.Read();1437 }1438 insertItemsToTree(directories, parent, true, isStartDir);1439 insertItemsToTree(files, parent, false, isStartDir);1440 updateCurrentLocationEdit(strPath);1441 }1442 directory.Close();1443 }1444 1445 void UIGuestFileTable::deleteByItem(UIFileTableItem *item)1446 {1447 if (!item)1448 return;1449 if (!m_comGuestSession.isOk())1450 return;1451 if (item->isUpDirectory())1452 return;1453 QVector<KDirectoryRemoveRecFlag> flags(KDirectoryRemoveRecFlag_ContentAndDir);1454 1455 if (item->isDirectory())1456 {1457 m_comGuestSession.DirectoryRemoveRecursive(item->path(), flags);1458 }1459 else1460 m_comGuestSession.FsObjRemove(item->path());1461 if (!m_comGuestSession.isOk())1462 emit sigLogOutput(QString(item->path()).append(" could not be deleted"));1463 1464 }1465 1466 void UIGuestFileTable::goToHomeDirectory()1467 {1468 if (m_comGuestSession.isNull())1469 return;1470 if (!m_pRootItem || m_pRootItem->childCount() <= 0)1471 return;1472 UIFileTableItem *startDirItem = m_pRootItem->child(0);1473 if (!startDirItem)1474 return;1475 1476 QString userHome = UIPathOperations::sanitize(m_comGuestSession.GetUserHome());1477 QList<QString> pathTrail = userHome.split(UIPathOperations::delimiter);1478 1479 goIntoDirectory(pathTrail);1480 }1481 1482 bool UIGuestFileTable::renameItem(UIFileTableItem *item, QString newBaseName)1483 {1484 1485 if (!item || item->isUpDirectory() || newBaseName.isEmpty() || !m_comGuestSession.isOk())1486 return false;1487 QString newPath = UIPathOperations::constructNewItemPath(item->path(), newBaseName);1488 QVector<KFsObjRenameFlag> aFlags(KFsObjRenameFlag_Replace);1489 1490 m_comGuestSession.FsObjRename(item->path(), newPath, aFlags);1491 if (!m_comGuestSession.isOk())1492 return false;1493 item->setPath(newPath);1494 return true;1495 }1496 1497 bool UIGuestFileTable::createDirectory(const QString &path, const QString &directoryName)1498 {1499 if (!m_comGuestSession.isOk())1500 return false;1501 1502 QString newDirectoryPath = UIPathOperations::mergePaths(path, directoryName);1503 QVector<KDirectoryCreateFlag> flags(KDirectoryCreateFlag_None);1504 1505 m_comGuestSession.DirectoryCreate(newDirectoryPath, 777/*aMode*/, flags);1506 if (!m_comGuestSession.isOk())1507 {1508 emit sigLogOutput(newDirectoryPath.append(" could not be created"));1509 return false;1510 }1511 emit sigLogOutput(newDirectoryPath.append(" has been created"));1512 return true;1513 }1514 1515 void UIGuestFileTable::copyGuestToHost(const QString& hostDestinationPath)1516 {1517 QStringList selectedPathList = selectedItemPathList();1518 for (int i = 0; i < selectedPathList.size(); ++i)1519 copyGuestToHost(selectedPathList.at(i), hostDestinationPath);1520 }1521 1522 void UIGuestFileTable::copyHostToGuest(const QStringList &hostSourcePathList)1523 {1524 for (int i = 0; i < hostSourcePathList.size(); ++i)1525 copyHostToGuest(hostSourcePathList.at(i), currentDirectoryPath());1526 }1527 1528 bool UIGuestFileTable::copyGuestToHost(const QString &guestSourcePath, const QString& hostDestinationPath)1529 {1530 if (m_comGuestSession.isNull())1531 return false;1532 1533 /* Currently API expects a path including a file name for file copy*/1534 CGuestFsObjInfo fileInfo = guestFsObjectInfo(guestSourcePath, m_comGuestSession);1535 KFsObjType objectType = fileInfo.GetType();1536 if (objectType == KFsObjType_File)1537 {1538 QVector<KFileCopyFlag> flags(KFileCopyFlag_FollowLinks);1539 /* API expects a full file path as destionation: */1540 QString destinatioFilePath = UIPathOperations::mergePaths(hostDestinationPath, UIPathOperations::getObjectName(guestSourcePath));1541 /** @todo listen to CProgress object to monitor copy operation: */1542 /*CProgress comProgress =*/ m_comGuestSession.FileCopyFromGuest(guestSourcePath, destinatioFilePath, flags);1543 1544 }1545 else if (objectType == KFsObjType_Directory)1546 {1547 QVector<KDirectoryCopyFlag> aFlags(KDirectoryCopyFlag_CopyIntoExisting);1548 /** @todo listen to CProgress object to monitor copy operation: */1549 /*CProgress comProgress = */ m_comGuestSession.DirectoryCopyFromGuest(guestSourcePath, hostDestinationPath, aFlags);1550 }1551 if (!m_comGuestSession.isOk())1552 return false;1553 return true;1554 }1555 1556 bool UIGuestFileTable::copyHostToGuest(const QString &hostSourcePath, const QString &guestDestinationPath)1557 {1558 if (m_comGuestSession.isNull())1559 return false;1560 QFileInfo hostFileInfo(hostSourcePath);1561 if (!hostFileInfo.exists())1562 return false;1563 1564 /* Currently API expects a path including a file name for file copy*/1565 if (hostFileInfo.isFile() || hostFileInfo.isSymLink())1566 {1567 QVector<KFileCopyFlag> flags(KFileCopyFlag_FollowLinks);1568 /* API expects a full file path as destionation: */1569 QString destinationFilePath = UIPathOperations::mergePaths(guestDestinationPath, UIPathOperations::getObjectName(hostSourcePath));1570 /** @todo listen to CProgress object to monitor copy operation: */1571 /*CProgress comProgress =*/ m_comGuestSession.FileCopyFromGuest(hostSourcePath, destinationFilePath, flags);1572 }1573 else if(hostFileInfo.isDir())1574 {1575 QVector<KDirectoryCopyFlag> aFlags(KDirectoryCopyFlag_CopyIntoExisting);1576 /** @todo listen to CProgress object to monitor copy operation: */1577 /*CProgress comProgress = */ m_comGuestSession.DirectoryCopyToGuest(hostSourcePath, guestDestinationPath, aFlags);1578 }1579 if (!m_comGuestSession.isOk())1580 return false;1581 return true;1582 }1583 1584 FileObjectType UIGuestFileTable::fileType(const CFsObjInfo &fsInfo)1585 {1586 if (fsInfo.isNull() || !fsInfo.isOk())1587 return FileObjectType_Unknown;1588 if (fsInfo.GetType() == KFsObjType_Directory)1589 return FileObjectType_Directory;1590 else if (fsInfo.GetType() == KFsObjType_File)1591 return FileObjectType_File;1592 else if (fsInfo.GetType() == KFsObjType_Symlink)1593 return FileObjectType_SymLink;1594 1595 return FileObjectType_Other;1596 }1597 1598 FileObjectType UIGuestFileTable::fileType(const CGuestFsObjInfo &fsInfo)1599 {1600 if (fsInfo.isNull() || !fsInfo.isOk())1601 return FileObjectType_Unknown;1602 if (fsInfo.GetType() == KFsObjType_Directory)1603 return FileObjectType_Directory;1604 else if (fsInfo.GetType() == KFsObjType_File)1605 return FileObjectType_File;1606 else if (fsInfo.GetType() == KFsObjType_Symlink)1607 return FileObjectType_SymLink;1608 1609 return FileObjectType_Other;1610 }1611 1612 1613 QString UIGuestFileTable::fsObjectPropertyString()1614 {1615 if (m_comGuestSession.isNull())1616 return QString();1617 1618 QStringList selectedObjects = selectedItemPathList();1619 if (selectedObjects.isEmpty())1620 return QString();1621 if (selectedObjects.size() == 1)1622 {1623 if (selectedObjects.at(0).isNull())1624 return QString();1625 CGuestFsObjInfo fileInfo = m_comGuestSession.FsObjQueryInfo(selectedObjects.at(0), true);1626 if (!m_comGuestSession.isOk())1627 return QString();1628 1629 QString propertyString;1630 /* Name: */1631 propertyString += "<b>Name:</b> " + UIPathOperations::getObjectName(fileInfo.GetName()) + "\n";1632 propertyString += "<br/>";1633 /* Size: */1634 propertyString += "<b>Size:</b> " + QString::number(fileInfo.GetObjectSize()) + QString(" bytes");1635 propertyString += "<br/>";1636 /* Type: */1637 propertyString += "<b>Type:</b> " + fileTypeString(fileType(fileInfo));1638 propertyString += "<br/>";1639 /* Creation Date: */1640 // LONG64 GetChangeTime() const;1641 propertyString += "<b>Created:</b> " + QDateTime::fromMSecsSinceEpoch(fileInfo.GetChangeTime()/1000000).toString();1642 propertyString += "<br/>";1643 /* Last Modification Date: */1644 propertyString += "<b>Modified:</b> " + QDateTime::fromMSecsSinceEpoch(fileInfo.GetModificationTime()/1000000).toString();1645 propertyString += "<br/>";1646 /* Owner: */1647 propertyString += "<b>Owner:</b> " + fileInfo.GetUserName();1648 return propertyString;1649 }1650 return QString();1651 }1652 1653 1654 /*********************************************************************************************************************************1655 * UIHostFileTable implementation. *1656 *********************************************************************************************************************************/1657 32 1658 33 UIHostFileTable::UIHostFileTable(QWidget *pParent /* = 0 */) … … 1837 212 return QString(); 1838 213 } 1839 1840 #include "UIGuestControlFileTable.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIHostFileTable.h
r71385 r71388 16 16 */ 17 17 18 #ifndef ___UIGuestControlFileTable_h___ 19 #define ___UIGuestControlFileTable_h___ 20 21 /* Qt includes: */ 22 #include <QWidget> 23 24 /* COM includes: */ 25 #include "COMEnums.h" 26 #include "CGuestSession.h" 18 #ifndef ___UIHostFileTable_h___ 19 #define ___UIHostFileTable_h___ 27 20 28 21 /* GUI includes: */ 29 #include "QITableView.h" 30 #include "QIWithRetranslateUI.h" 31 32 /* Forward declarations: */ 33 class QAction; 34 class QFileInfo; 35 class QILabel; 36 class QILineEdit; 37 class QGridLayout; 38 class UIFileTableItem; 39 class UIGuestControlFileModel; 40 class UIGuestControlFileView; 41 class UIToolBar; 42 43 enum FileObjectType 44 { 45 FileObjectType_File = 0, 46 FileObjectType_Directory, 47 FileObjectType_SymLink, 48 FileObjectType_Other, 49 FileObjectType_Unknown, 50 FileObjectType_Max 51 }; 52 53 /********************************************************************************************************************************* 54 * UIFileTableItem definition. * 55 *********************************************************************************************************************************/ 56 57 class UIFileTableItem 58 { 59 public: 60 61 explicit UIFileTableItem(const QList<QVariant> &data, 62 UIFileTableItem *parentItem, FileObjectType type); 63 ~UIFileTableItem(); 64 65 void appendChild(UIFileTableItem *child); 66 67 UIFileTableItem *child(int row) const; 68 /** Return a child (if possible) by path */ 69 UIFileTableItem *child(const QString &path) const; 70 int childCount() const; 71 int columnCount() const; 72 QVariant data(int column) const; 73 void setData(const QVariant &data, int index); 74 int row() const; 75 UIFileTableItem *parentItem(); 76 77 bool isDirectory() const; 78 bool isSymLink() const; 79 bool isFile() const; 80 81 bool isOpened() const; 82 void setIsOpened(bool flag); 83 84 const QString &path() const; 85 void setPath(const QString &path); 86 87 /** True if this is directory and name is ".." */ 88 bool isUpDirectory() const; 89 void clearChildren(); 90 91 FileObjectType type() const; 92 93 const QString &targetPath() const; 94 void setTargetPath(const QString &path); 95 96 bool isTargetADirectory() const; 97 void setIsTargetADirectory(bool flag); 98 99 private: 100 QList<UIFileTableItem*> m_childItems; 101 /** Used to find children by path */ 102 QMap<QString, UIFileTableItem*> m_childMap; 103 QList<QVariant> m_itemData; 104 UIFileTableItem *m_parentItem; 105 bool m_bIsOpened; 106 /** Full absolute path of the item. Without the trailing '/' */ 107 QString m_strPath; 108 /** If this is a symlink m_targetPath keeps the absolute path of the target */ 109 QString m_strTargetPath; 110 /** True if this is a symlink and the target is a directory */ 111 bool m_isTargetADirectory; 112 FileObjectType m_type; 113 114 }; 115 116 117 /** This class serves a base class for file table. Currently a guest version 118 and a host version are derived from this base. Each of these children 119 populates the UIGuestControlFileModel by scanning the file system 120 differently. The file structre kept in this class as a tree and all 121 the interfacing is done thru this class.*/ 122 class UIGuestControlFileTable : public QIWithRetranslateUI<QWidget> 123 { 124 Q_OBJECT; 125 126 signals: 127 128 void sigLogOutput(QString); 129 130 public: 131 132 UIGuestControlFileTable(QWidget *pParent = 0); 133 virtual ~UIGuestControlFileTable(); 134 /** Delete all the tree nodes */ 135 void reset(); 136 void emitLogOutput(const QString& strOutput); 137 /** Returns the path of the rootIndex */ 138 QString currentDirectoryPath() const; 139 /** Returns the paths of the selected items (if any) as a list */ 140 QStringList selectedItemPathList(); 141 virtual void refresh(); 142 143 protected: 144 145 void retranslateUi(); 146 void updateCurrentLocationEdit(const QString& strLocation); 147 void changeLocation(const QModelIndex &index); 148 void initializeFileTree(); 149 void insertItemsToTree(QMap<QString,UIFileTableItem*> &map, UIFileTableItem *parent, 150 bool isDirectoryMap, bool isStartDir); 151 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) = 0; 152 virtual void deleteByItem(UIFileTableItem *item) = 0; 153 virtual void goToHomeDirectory() = 0; 154 virtual bool renameItem(UIFileTableItem *item, QString newBaseName) = 0; 155 virtual bool createDirectory(const QString &path, const QString &directoryName) = 0; 156 virtual QString fsObjectPropertyString() = 0; 157 static QString fileTypeString(FileObjectType type); 158 void goIntoDirectory(const QModelIndex &itemIndex); 159 /** Follow the path trail, open directories as we go and descend */ 160 void goIntoDirectory(const QList<QString> &pathTrail); 161 /** Go into directory pointed by the @p item */ 162 void goIntoDirectory(UIFileTableItem *item); 163 UIFileTableItem* indexData(const QModelIndex &index) const; 164 void keyPressEvent(QKeyEvent * pEvent); 165 CGuestFsObjInfo guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const; 166 167 168 UIFileTableItem *m_pRootItem; 169 170 UIGuestControlFileView *m_pView; 171 UIGuestControlFileModel *m_pModel; 172 QILabel *m_pLocationLabel; 173 174 private slots: 175 176 void sltItemDoubleClicked(const QModelIndex &index); 177 void sltGoUp(); 178 void sltGoHome(); 179 void sltRefresh(); 180 void sltDelete(); 181 void sltRename(); 182 void sltCopy(); 183 void sltCut(); 184 void sltPaste(); 185 void sltShowProperties(); 186 void sltCreateNewDirectory(); 187 void sltSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); 188 189 private: 190 191 void prepareObjects(); 192 void prepareActions(); 193 void deleteByIndex(const QModelIndex &itemIndex); 194 /** Return the UIFileTableItem for path / which is a direct (and single) child of m_pRootItem */ 195 UIFileTableItem *getStartDirectoryItem(); 196 /** Shows a modal dialog with a line edit for user to enter a new directory name and return the entered string*/ 197 QString getNewDirectoryName(); 198 void enableSelectionDependentActions(); 199 void disableSelectionDependentActions(); 200 QGridLayout *m_pMainLayout; 201 QILineEdit *m_pCurrentLocationEdit; 202 UIToolBar *m_pToolBar; 203 QAction *m_pGoUp; 204 QAction *m_pGoHome; 205 QAction *m_pRefresh; 206 QAction *m_pDelete; 207 QAction *m_pRename; 208 QAction *m_pCreateNewDirectory; 209 QAction *m_pCopy; 210 QAction *m_pCut; 211 QAction *m_pPaste; 212 QAction *m_pShowProperties; 213 /** The vector of action which need some selection to work on like cut, copy etc. */ 214 QVector<QAction*> m_selectionDependentActions; 215 /** The absolue path list of the file objects which user has chosen to cut/copy. this 216 list will be cleaned after a paste operation or overwritten by a subsequent cut/copy */ 217 QStringList m_copyCutBuffer; 218 friend class UIGuestControlFileModel; 219 }; 220 221 /** This class scans the guest file system by using the VBox API 222 and populates the UIGuestControlFileModel*/ 223 class UIGuestFileTable : public UIGuestControlFileTable 224 { 225 Q_OBJECT; 226 227 public: 228 229 UIGuestFileTable(QWidget *pParent = 0); 230 void initGuestFileTable(const CGuestSession &session); 231 void copyGuestToHost(const QString& hostDestinationPath); 232 void copyHostToGuest(const QStringList &hostSourcePathList); 233 234 protected: 235 236 void retranslateUi() /* override */; 237 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) /* override */; 238 virtual void deleteByItem(UIFileTableItem *item) /* override */; 239 virtual void goToHomeDirectory() /* override */; 240 virtual bool renameItem(UIFileTableItem *item, QString newBaseName); 241 virtual bool createDirectory(const QString &path, const QString &directoryName); 242 virtual QString fsObjectPropertyString() /* override */; 243 244 private: 245 246 static FileObjectType fileType(const CFsObjInfo &fsInfo); 247 static FileObjectType fileType(const CGuestFsObjInfo &fsInfo); 248 249 bool copyGuestToHost(const QString &guestSourcePath, const QString& hostDestinationPath); 250 bool copyHostToGuest(const QString& hostSourcePath, const QString &guestDestinationPath); 251 252 mutable CGuestSession m_comGuestSession; 253 254 }; 22 #include "UIGuestControlFileTable.h" 255 23 256 24 /** This class scans the host file system by using the Qt
Note:
See TracChangeset
for help on using the changeset viewer.