Changeset 71271 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Mar 8, 2018 12:21:53 PM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 3 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r71270 r71271 378 378 src/runtime/guestctrl/UIGuestControlConsole.h \ 379 379 src/runtime/guestctrl/UIGuestControlFileManager.h \ 380 src/runtime/guestctrl/UIGuestControlFileModel.h \ 380 381 src/runtime/guestctrl/UIGuestControlFileTable.h \ 381 382 src/runtime/guestctrl/UIGuestControlInterface.h \ … … 712 713 src/runtime/guestctrl/UIGuestControlConsole.cpp \ 713 714 src/runtime/guestctrl/UIGuestControlFileManager.cpp \ 715 src/runtime/guestctrl/UIGuestControlFileModel.cpp \ 714 716 src/runtime/guestctrl/UIGuestControlFileTable.cpp \ 715 717 src/runtime/guestctrl/UIGuestControlInterface.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileModel.cpp
r71270 r71271 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIGuestControlFile Tableclass implementation.3 * VBox Qt GUI - UIGuestControlFileModel class implementation. 4 4 */ 5 5 … … 21 21 22 22 /* Qt includes: */ 23 # include <QAction>24 23 # include <QDateTime> 25 # include <QDir>26 24 # include <QHeaderView> 27 # include <QItemDelegate>28 # include <QGridLayout>29 # include <QPushButton>30 25 31 26 /* GUI includes: */ 32 # include "QIDialog.h"33 # include "QIDialogButtonBox.h"34 # include "QILabel.h"35 # include "QILineEdit.h"36 27 # include "UIErrorString.h" 37 # include "UI IconPool.h"28 # include "UIGuestControlFileModel.h" 38 29 # include "UIGuestControlFileTable.h" 39 # include "UIToolBar.h" 40 # include "UIVMInformationDialog.h" 41 42 /* COM includes: */ 43 # include "CFsObjInfo.h" 44 # include "CGuestDirectory.h" 45 # include "CProgress.h" 30 46 31 47 32 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 48 33 49 50 /*********************************************************************************************************************************51 * UIFileDelegate definition. *52 *********************************************************************************************************************************/53 /** A QItemDelegate child class to disable dashed lines drawn around selected cells in QTableViews */54 class UIFileDelegate : public QItemDelegate55 {56 57 Q_OBJECT;58 59 protected:60 virtual void drawFocus ( QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, const QRect & /*rect*/ ) const {}61 };62 63 64 /*********************************************************************************************************************************65 * UIFileStringInputDialog definition. *66 *********************************************************************************************************************************/67 /** A QIDialog child including a line edit whose text exposed when the dialog is accepted */68 class UIStringInputDialog : public QIDialog69 {70 71 Q_OBJECT;72 73 public:74 75 UIStringInputDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);76 QString getString() const;77 78 private:79 80 QILineEdit *m_pLineEdit;81 82 // virtual void accept() /* override */;83 // virtual void reject() /* override */;84 85 };86 87 88 89 /*********************************************************************************************************************************90 * UIFileTableItem definition. *91 *********************************************************************************************************************************/92 93 class UIFileTableItem94 {95 public:96 explicit UIFileTableItem(const QList<QVariant> &data, bool isDirectory, UIFileTableItem *parentItem);97 ~UIFileTableItem();98 99 void appendChild(UIFileTableItem *child);100 101 UIFileTableItem *child(int row) const;102 /** Return a child (if possible) by path */103 UIFileTableItem *child(const QString &path) const;104 int childCount() const;105 int columnCount() const;106 QVariant data(int column) const;107 void setData(const QVariant &data, int index);108 int row() const;109 UIFileTableItem *parentItem();110 111 bool isDirectory() const;112 bool isOpened() const;113 void setIsOpened(bool flag);114 115 const QString &path() const;116 void setPath(const QString &path);117 /** Merge prefix and suffix by making sure they have a single '/' in between */118 void setPath(const QString &prexix, const QString &suffix);119 120 /** True if this is directory and name is ".." */121 bool isUpDirectory() const;122 void clearChildren();123 124 private:125 QList<UIFileTableItem*> m_childItems;126 /** Used to find children by path */127 QMap<QString, UIFileTableItem*> m_childMap;128 QList<QVariant> m_itemData;129 UIFileTableItem *m_parentItem;130 bool m_bIsDirectory;131 bool m_bIsOpened;132 /** Full absolute path of the item. Without the trailing '/' */133 QString m_strPath;134 /** For directories base name is the name of the lowest level directory135 in strPath. eg. for 'm_strPath = /opt/qt5.6/examples' 'm_strBaseName = examples'136 for files it is the name of the file */137 QString m_strBaseName;138 };139 140 141 /*********************************************************************************************************************************142 * UIFileStringInputDialog implementation. *143 *********************************************************************************************************************************/144 UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)145 :QIDialog(pParent, flags)146 {147 QVBoxLayout *layout = new QVBoxLayout(this);148 m_pLineEdit = new QILineEdit(this);149 layout->addWidget(m_pLineEdit);150 151 QIDialogButtonBox *pButtonBox =152 new QIDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);153 layout->addWidget(pButtonBox);154 // {155 // /* Configure button-box: */156 connect(pButtonBox, &QIDialogButtonBox::accepted, this, &UIStringInputDialog::accept);157 connect(pButtonBox, &QIDialogButtonBox::rejected, this, &UIStringInputDialog::reject);158 159 }160 161 QString UIStringInputDialog::getString() const162 {163 if (!m_pLineEdit)164 return QString();165 return m_pLineEdit->text();166 }167 168 169 /*********************************************************************************************************************************170 * UIFileTableItem implementation. *171 *********************************************************************************************************************************/172 173 174 UIFileTableItem::UIFileTableItem(const QList<QVariant> &data, bool isDirectory, UIFileTableItem *parent)175 : m_itemData(data)176 , m_parentItem(parent)177 , m_bIsDirectory(isDirectory)178 , m_bIsOpened(false)179 {180 181 }182 183 UIFileTableItem::~UIFileTableItem()184 {185 qDeleteAll(m_childItems);186 m_childItems.clear();187 }188 189 void UIFileTableItem::appendChild(UIFileTableItem *item)190 {191 if (!item)192 return;193 m_childItems.append(item);194 m_childMap.insert(item->path(), item);195 }196 197 UIFileTableItem *UIFileTableItem::child(int row) const198 {199 return m_childItems.value(row);200 }201 202 UIFileTableItem *UIFileTableItem::child(const QString &path) const203 {204 if (!m_childMap.contains(path))205 return 0;206 return m_childMap.value(path);207 }208 209 int UIFileTableItem::childCount() const210 {211 return m_childItems.count();212 }213 214 int UIFileTableItem::columnCount() const215 {216 return m_itemData.count();217 }218 219 QVariant UIFileTableItem::data(int column) const220 {221 return m_itemData.value(column);222 }223 224 void UIFileTableItem::setData(const QVariant &data, int index)225 {226 if (index >= m_itemData.length())227 return;228 m_itemData[index] = data;229 }230 231 UIFileTableItem *UIFileTableItem::parentItem()232 {233 return m_parentItem;234 }235 236 int UIFileTableItem::row() const237 {238 if (m_parentItem)239 return m_parentItem->m_childItems.indexOf(const_cast<UIFileTableItem*>(this));240 241 return 0;242 }243 244 bool UIFileTableItem::isDirectory() const245 {246 return m_bIsDirectory;247 }248 249 void UIFileTableItem::clearChildren()250 {251 qDeleteAll(m_childItems);252 m_childItems.clear();253 m_childMap.clear();254 }255 256 bool UIFileTableItem::isOpened() const257 {258 return m_bIsOpened;259 }260 261 void UIFileTableItem::setIsOpened(bool flag)262 {263 m_bIsOpened = flag;264 }265 266 const QString &UIFileTableItem::path() const267 {268 return m_strPath;269 }270 271 void UIFileTableItem::setPath(const QString &path)272 {273 if (path.isNull() || path.isEmpty())274 return;275 m_strPath = path;276 /* Make sure for we dont have any trailing slashes: */277 if (m_strPath.length() > 1 && m_strPath.at(m_strPath.length() - 1) == QChar('/'))278 m_strPath.chop(1);279 }280 281 void UIFileTableItem::setPath(const QString &prefix, const QString &suffix)282 {283 if (prefix.isEmpty())284 return;285 QString newPath(prefix);286 /* Make sure we have a trailing '/' in @p prefix: */287 if (prefix.at(newPath.length() - 1) != QChar('/'))288 newPath += "/";289 newPath += suffix;290 setPath(newPath);291 }292 293 bool UIFileTableItem::isUpDirectory() const294 {295 if (!m_bIsDirectory)296 return false;297 if (data(0) == QString(".."))298 return true;299 return false;300 }301 302 303 /*********************************************************************************************************************************304 * UIGuestControlFileModel implementation. *305 *********************************************************************************************************************************/306 34 307 35 UIGuestControlFileModel::UIGuestControlFileModel(QObject *parent) … … 521 249 return true; 522 250 } 523 524 525 /*********************************************************************************************************************************526 * UIGuestControlFileTable implementation. *527 *********************************************************************************************************************************/528 529 UIGuestControlFileTable::UIGuestControlFileTable(QWidget *pParent /* = 0 */)530 :QIWithRetranslateUI<QWidget>(pParent)531 , m_pRootItem(0)532 , m_pView(0)533 , m_pModel(0)534 , m_pTree(0)535 , m_pLocationLabel(0)536 , m_pGoHome(0)537 , m_pMainLayout(0)538 , m_pCurrentLocationEdit(0)539 , m_pToolBar(0)540 , m_pGoUp(0)541 , m_pRefresh(0)542 , m_pDelete(0)543 , m_pRename(0)544 , m_pCreateNewDirectory(0)545 , m_pCopy(0)546 , m_pCut(0)547 , m_pPaste(0)548 549 {550 prepareObjects();551 prepareActions();552 }553 554 UIGuestControlFileTable::~UIGuestControlFileTable()555 {556 delete m_pRootItem;557 }558 559 void UIGuestControlFileTable::reset()560 {561 if (m_pModel)562 m_pModel->beginReset();563 delete m_pRootItem;564 m_pRootItem = 0;565 if (m_pModel)566 m_pModel->endReset();567 if (m_pCurrentLocationEdit)568 m_pCurrentLocationEdit->clear();569 }570 571 void UIGuestControlFileTable::emitLogOutput(const QString& strOutput)572 {573 emit sigLogOutput(strOutput);574 }575 576 void UIGuestControlFileTable::prepareObjects()577 {578 m_pMainLayout = new QGridLayout();579 if (!m_pMainLayout)580 return;581 m_pMainLayout->setSpacing(0);582 m_pMainLayout->setContentsMargins(0, 0, 0, 0);583 setLayout(m_pMainLayout);584 585 m_pToolBar = new UIToolBar;586 if (m_pToolBar)587 {588 m_pMainLayout->addWidget(m_pToolBar, 0, 0, 1, 5);589 }590 591 m_pLocationLabel = new QILabel;592 if (m_pLocationLabel)593 {594 m_pMainLayout->addWidget(m_pLocationLabel, 1, 0, 1, 1);595 }596 597 m_pCurrentLocationEdit = new QILineEdit;598 if (m_pCurrentLocationEdit)599 {600 m_pMainLayout->addWidget(m_pCurrentLocationEdit, 1, 1, 1, 4);601 m_pCurrentLocationEdit->setReadOnly(true);602 }603 604 m_pModel = new UIGuestControlFileModel(this);605 if (!m_pModel)606 return;607 608 609 m_pView = new QTableView;610 if (m_pView)611 {612 m_pView->setShowGrid(false);613 m_pView->setSelectionBehavior(QAbstractItemView::SelectRows);614 m_pView->verticalHeader()->setVisible(false);615 616 m_pMainLayout->addWidget(m_pView, 2, 0, 5, 5);617 m_pView->setModel(m_pModel);618 m_pView->setItemDelegate(new UIFileDelegate);619 m_pView->setEditTriggers(QAbstractItemView::NoEditTriggers);620 /* Minimize the row height: */621 m_pView->verticalHeader()->setDefaultSectionSize(m_pView->verticalHeader()->minimumSectionSize());622 /* Make the columns take all the avaible space: */623 m_pView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);624 625 connect(m_pView, &QTableView::doubleClicked,626 this, &UIGuestControlFileTable::sltItemDoubleClicked);627 628 }629 }630 631 void UIGuestControlFileTable::prepareActions()632 {633 if (!m_pToolBar)634 return;635 636 m_pGoUp = new QAction(this);637 if (m_pGoUp)638 {639 connect(m_pGoUp, &QAction::triggered, this, &UIGuestControlFileTable::sltGoUp);640 m_pGoUp->setIcon(UIIconPool::iconSet(QString(":/arrow_up_10px_x2.png")));641 m_pToolBar->addAction(m_pGoUp);642 }643 644 m_pGoHome = new QAction(this);645 if (m_pGoHome)646 {647 connect(m_pGoHome, &QAction::triggered, this, &UIGuestControlFileTable::sltGoHome);648 m_pGoHome->setIcon(UIIconPool::iconSet(QString(":/nw_24px.png")));649 m_pToolBar->addAction(m_pGoHome);650 }651 652 m_pRefresh = new QAction(this);653 if (m_pRefresh)654 {655 connect(m_pRefresh, &QAction::triggered, this, &UIGuestControlFileTable::sltRefresh);656 m_pRefresh->setIcon(UIIconPool::iconSet(QString(":/refresh_22px.png")));657 m_pToolBar->addAction(m_pRefresh);658 }659 660 m_pToolBar->addSeparator();661 662 m_pDelete = new QAction(this);663 if (m_pDelete)664 {665 connect(m_pDelete, &QAction::triggered, this, &UIGuestControlFileTable::sltDelete);666 m_pDelete->setIcon(UIIconPool::iconSet(QString(":/vm_delete_32px.png")));667 m_pToolBar->addAction(m_pDelete);668 }669 670 m_pRename = new QAction(this);671 if (m_pRename)672 {673 connect(m_pRename, &QAction::triggered, this, &UIGuestControlFileTable::sltRename);674 m_pRename->setIcon(UIIconPool::iconSet(QString(":/name_16px_x2.png")));675 m_pToolBar->addAction(m_pRename);676 }677 678 m_pCreateNewDirectory = new QAction(this);679 if (m_pCreateNewDirectory)680 {681 connect(m_pCreateNewDirectory, &QAction::triggered, this, &UIGuestControlFileTable::sltCreateNewDirectory);682 m_pCreateNewDirectory->setIcon(UIIconPool::iconSet(QString(":/sf_32px.png")));683 m_pToolBar->addAction(m_pCreateNewDirectory);684 }685 686 m_pCopy = new QAction(this);687 if (m_pCopy)688 {689 m_pCopy->setIcon(UIIconPool::iconSet(QString(":/fd_copy_22px.png")));690 m_pToolBar->addAction(m_pCopy);691 m_pCopy->setEnabled(false);692 }693 694 m_pCut = new QAction(this);695 if (m_pCut)696 {697 m_pCut->setIcon(UIIconPool::iconSet(QString(":/fd_move_22px.png")));698 m_pToolBar->addAction(m_pCut);699 m_pCut->setEnabled(false);700 }701 702 m_pPaste = new QAction(this);703 if (m_pPaste)704 {705 m_pPaste->setIcon(UIIconPool::iconSet(QString(":/shared_clipboard_16px.png")));706 m_pToolBar->addAction(m_pPaste);707 m_pPaste->setEnabled(false);708 }709 }710 711 void UIGuestControlFileTable::updateCurrentLocationEdit(const QString& strLocation)712 {713 if (!m_pCurrentLocationEdit)714 return;715 m_pCurrentLocationEdit->setText(strLocation);716 }717 718 void UIGuestControlFileTable::changeLocation(const QModelIndex &index)719 {720 if (!index.isValid() || !m_pView)721 return;722 m_pView->setRootIndex(index);723 m_pView->clearSelection();724 725 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());726 if (item)727 {728 updateCurrentLocationEdit(item->path());729 }730 m_pModel->signalUpdate();731 }732 733 void UIGuestControlFileTable::initializeFileTree()734 {735 if (m_pRootItem)736 reset();737 738 QList<QVariant> headData;739 headData << "Name" << "Size" << "Change Time";740 m_pRootItem = new UIFileTableItem(headData, true, 0);741 742 QList<QVariant> startDirData;743 startDirData << "/" << 4096 << QDateTime();744 UIFileTableItem* startItem = new UIFileTableItem(startDirData, true, m_pRootItem);745 startItem->setPath("/");746 m_pRootItem->appendChild(startItem);747 748 startItem->setIsOpened(false);749 /* Read the root directory and get the list: */750 751 readDirectory("/", startItem, true);752 m_pView->setRootIndex(m_pModel->rootIndex());753 m_pModel->signalUpdate();754 755 }756 757 void UIGuestControlFileTable::insertItemsToTree(QMap<QString,UIFileTableItem*> &map,758 UIFileTableItem *parent, bool isDirectoryMap, bool isStartDir)759 {760 /* Make sure we have a ".." item within directories, and make sure it does not include for the start dir: */761 if (isDirectoryMap)762 {763 if (!map.contains("..") && !isStartDir)764 {765 QList<QVariant> data;766 data << ".." << 4096;767 UIFileTableItem *item = new UIFileTableItem(data, isDirectoryMap, parent);768 item->setIsOpened(false);769 map.insert("..", item);770 }771 else if (map.contains("..") && isStartDir)772 {773 map.remove("..");774 }775 }776 for (QMap<QString,UIFileTableItem*>::const_iterator iterator = map.begin();777 iterator != map.end(); ++iterator)778 {779 if (iterator.key() == "." || iterator.key().isEmpty())780 continue;781 parent->appendChild(iterator.value());782 }783 }784 785 void UIGuestControlFileTable::sltItemDoubleClicked(const QModelIndex &index)786 {787 if (!index.isValid() || !m_pModel || !m_pView)788 return;789 goIntoDirectory(index);790 }791 792 void UIGuestControlFileTable::sltGoUp()793 {794 if (!m_pView || !m_pModel)795 return;796 QModelIndex currentRoot = m_pView->rootIndex();797 if (!currentRoot.isValid())798 return;799 if (currentRoot != m_pModel->rootIndex())800 changeLocation(currentRoot.parent());801 }802 803 void UIGuestControlFileTable::sltGoHome()804 {805 goToHomeDirectory();806 }807 808 void UIGuestControlFileTable::sltRefresh()809 {810 refresh();811 }812 813 void UIGuestControlFileTable::goIntoDirectory(const QModelIndex &itemIndex)814 {815 UIFileTableItem *item = static_cast<UIFileTableItem*>(itemIndex.internalPointer());816 if (!item)817 return;818 819 /* check if we need to go up: */820 if (item->isUpDirectory())821 {822 QModelIndex parentIndex = m_pModel->parent(m_pModel->parent(itemIndex));823 if (parentIndex.isValid())824 changeLocation(parentIndex);825 return;826 }827 828 if (!item->isDirectory())829 return;830 if (!item->isOpened())831 readDirectory(item->path(),item);832 changeLocation(itemIndex);833 }834 835 void UIGuestControlFileTable::goIntoDirectory(const QVector<QString> &pathTrail)836 {837 UIFileTableItem *parent = getStartDirectoryItem();838 839 for(int i = 0; i < pathTrail.size(); ++i)840 {841 if (!parent)842 return;843 /* Make sure parent is already opened: */844 if (!parent->isOpened())845 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());846 /* search the current path item among the parent's children: */847 UIFileTableItem *item = parent->child(pathTrail.at(i));848 if (!item)849 return;850 parent = item;851 }852 if (!parent)853 return;854 if (!parent->isOpened())855 readDirectory(parent->path(), parent, parent == getStartDirectoryItem());856 goIntoDirectory(parent);857 }858 859 void UIGuestControlFileTable::goIntoDirectory(UIFileTableItem *item)860 {861 if (!item || !m_pModel)862 return;863 goIntoDirectory(m_pModel->index(item));864 }865 866 UIFileTableItem* UIGuestControlFileTable::indexData(const QModelIndex &index) const867 {868 if (!index.isValid())869 return 0;870 return static_cast<UIFileTableItem*>(index.internalPointer());871 }872 873 void UIGuestControlFileTable::refresh()874 {875 if (!m_pView || !m_pModel)876 return;877 QModelIndex currentIndex = m_pView->rootIndex();878 879 UIFileTableItem *treeItem = indexData(currentIndex);880 if (!treeItem)881 return;882 bool isRootDir = (m_pModel->rootIndex() == currentIndex);883 m_pModel->beginReset();884 /* For now we clear the whole subtree (that isrecursively) which is an overkill: */885 treeItem->clearChildren();886 readDirectory(treeItem->path(), treeItem, isRootDir);887 m_pModel->endReset();888 m_pView->setRootIndex(currentIndex);889 }890 891 void UIGuestControlFileTable::sltDelete()892 {893 if (!m_pView || !m_pModel)894 return;895 QItemSelectionModel *selectionModel = m_pView->selectionModel();896 if (!selectionModel)897 return;898 899 QModelIndexList selectedItemIndices = selectionModel->selectedRows();900 for(int i = 0; i < selectedItemIndices.size(); ++i)901 {902 deleteByIndex(selectedItemIndices.at(i));903 }904 /** @todo dont refresh here, just delete the rows and update the table view: */905 refresh();906 }907 908 void UIGuestControlFileTable::sltRename()909 {910 if (!m_pView)911 return;912 QItemSelectionModel *selectionModel = m_pView->selectionModel();913 if (!selectionModel)914 return;915 916 QModelIndexList selectedItemIndices = selectionModel->selectedRows();917 if (selectedItemIndices.size() == 0)918 return;919 UIFileTableItem *item = indexData(selectedItemIndices.at(0));920 if (!item || item->isUpDirectory())921 return;922 m_pView->edit(selectedItemIndices.at(0));923 }924 925 void UIGuestControlFileTable::sltCreateNewDirectory()926 {927 if (!m_pModel || !m_pView)928 return;929 QModelIndex currentIndex = m_pView->rootIndex();930 if (!currentIndex.isValid())931 return;932 UIFileTableItem *item = static_cast<UIFileTableItem*>(currentIndex.internalPointer());933 if (!item)934 return;935 936 QString newDirectoryName = getNewDirectoryName();937 if (newDirectoryName.isEmpty())938 return;939 940 if (createDirectory(item->path(), newDirectoryName))941 {942 /** @todo instead of refreshing here (an overkill) just add the943 rows and update the tabel view: */944 sltRefresh();945 }946 947 }948 949 950 void UIGuestControlFileTable::deleteByIndex(const QModelIndex &itemIndex)951 {952 UIFileTableItem *treeItem = indexData(itemIndex);953 if (!treeItem)954 return;955 deleteByItem(treeItem);956 }957 958 void UIGuestControlFileTable::retranslateUi()959 {960 if (m_pGoUp)961 {962 m_pGoUp->setText(UIVMInformationDialog::tr("Move one level up"));963 m_pGoUp->setToolTip(UIVMInformationDialog::tr("Move one level up"));964 m_pGoUp->setStatusTip(UIVMInformationDialog::tr("Move one level up"));965 }966 967 if (m_pGoHome)968 {969 m_pGoHome->setText(UIVMInformationDialog::tr("Go to home directory"));970 m_pGoHome->setToolTip(UIVMInformationDialog::tr("Go to home directory"));971 m_pGoHome->setStatusTip(UIVMInformationDialog::tr("Go to home directory"));972 }973 974 if (m_pRename)975 {976 m_pRename->setText(UIVMInformationDialog::tr("Rename the selected item"));977 m_pRename->setToolTip(UIVMInformationDialog::tr("Rename the selected item"));978 m_pRename->setStatusTip(UIVMInformationDialog::tr("Rename the selected item"));979 }980 981 if (m_pRefresh)982 {983 m_pRefresh->setText(UIVMInformationDialog::tr("Refresh"));984 m_pRefresh->setToolTip(UIVMInformationDialog::tr("Refresh the current directory"));985 m_pRefresh->setStatusTip(UIVMInformationDialog::tr("Refresh the current directory"));986 }987 if (m_pDelete)988 {989 m_pDelete->setText(UIVMInformationDialog::tr("Delete"));990 m_pDelete->setToolTip(UIVMInformationDialog::tr("Delete the selected item(s)"));991 m_pDelete->setStatusTip(UIVMInformationDialog::tr("Delete the selected item(s)"));992 }993 994 if (m_pCreateNewDirectory)995 {996 m_pCreateNewDirectory->setText(UIVMInformationDialog::tr("Create a new directory"));997 m_pCreateNewDirectory->setToolTip(UIVMInformationDialog::tr("Create a new directory"));998 m_pCreateNewDirectory->setStatusTip(UIVMInformationDialog::tr("Create a new directory"));999 1000 }1001 1002 if (m_pCopy)1003 {1004 m_pCopy->setText(UIVMInformationDialog::tr("Copy the selected item"));1005 m_pCopy->setToolTip(UIVMInformationDialog::tr("Copy the selected item(s)"));1006 m_pCopy->setStatusTip(UIVMInformationDialog::tr("Copy the selected item(s)"));1007 1008 }1009 1010 if (m_pCut)1011 {1012 m_pCut->setText(UIVMInformationDialog::tr("Cut the selected item(s)"));1013 m_pCut->setToolTip(UIVMInformationDialog::tr("Cut the selected item(s)"));1014 m_pCut->setStatusTip(UIVMInformationDialog::tr("Cut the selected item(s)"));1015 1016 }1017 1018 if ( m_pPaste)1019 {1020 m_pPaste->setText(UIVMInformationDialog::tr("Paste the copied item(s)"));1021 m_pPaste->setToolTip(UIVMInformationDialog::tr("Paste the copied item(s)"));1022 m_pPaste->setStatusTip(UIVMInformationDialog::tr("Paste the copied item(s)"));1023 }1024 }1025 1026 1027 void UIGuestControlFileTable::keyPressEvent(QKeyEvent * pEvent)1028 {1029 /* Browse into directory with enter: */1030 if (pEvent->key() == Qt::Key_Enter || pEvent->key() == Qt::Key_Return)1031 {1032 if (m_pView && m_pModel)1033 {1034 /* Get the selected item. If there are 0 or more than 1 selection do nothing: */1035 QItemSelectionModel *selectionModel = m_pView->selectionModel();1036 if (selectionModel)1037 {1038 QModelIndexList selectedItemIndices = selectionModel->selectedRows();1039 if (selectedItemIndices.size() == 1)1040 goIntoDirectory(selectedItemIndices.at(0));1041 }1042 }1043 }1044 else if (pEvent->key() == Qt::Key_Delete)1045 {1046 sltDelete();1047 }1048 QWidget::keyPressEvent(pEvent);1049 }1050 1051 UIFileTableItem *UIGuestControlFileTable::getStartDirectoryItem()1052 {1053 if (!m_pRootItem)1054 return 0;1055 if (m_pRootItem->childCount() <= 0)1056 return 0;1057 return m_pRootItem->child(0);1058 }1059 1060 QString UIGuestControlFileTable::constructNewItemPath(const QString &previousPath, const QString &newBaseName)1061 {1062 if (newBaseName.isEmpty() || previousPath.length() <= 1)1063 return QString();1064 1065 QStringList pathList = previousPath.split('/', QString::SkipEmptyParts);1066 QString newPath("/");1067 for(int i = 0; i < pathList.size() - 1; ++i)1068 {1069 newPath += (pathList.at(i) + "/");1070 }1071 newPath += newBaseName;1072 return newPath;1073 }1074 1075 QString UIGuestControlFileTable::mergePaths(const QString &path, const QString &baseName)1076 {1077 QString newPath(path);1078 /* make sure we have a trailing '/': */1079 if (newPath.at(newPath.length() - 1) != QChar('/'))1080 newPath += QChar('/');1081 newPath += baseName;1082 return newPath;1083 }1084 1085 QString UIGuestControlFileTable::getNewDirectoryName()1086 {1087 UIStringInputDialog *dialog = new UIStringInputDialog();1088 if (dialog->execute())1089 {1090 QString strDialog = dialog->getString();1091 delete dialog;1092 return strDialog;1093 }1094 delete dialog;1095 return QString();1096 }1097 1098 1099 /*********************************************************************************************************************************1100 * UIGuestFileTable implementation. *1101 *********************************************************************************************************************************/1102 1103 UIGuestFileTable::UIGuestFileTable(QWidget *pParent /*= 0*/)1104 :UIGuestControlFileTable(pParent)1105 {1106 configureObjects();1107 retranslateUi();1108 }1109 1110 void UIGuestFileTable::initGuestFileTable(const CGuestSession &session)1111 {1112 if (!session.isOk())1113 return;1114 if (session.GetStatus() != KGuestSessionStatus_Started)1115 return;1116 m_comGuestSession = session;1117 1118 1119 initializeFileTree();1120 }1121 1122 void UIGuestFileTable::retranslateUi()1123 {1124 if (m_pLocationLabel)1125 m_pLocationLabel->setText(UIVMInformationDialog::tr("Guest System"));1126 UIGuestControlFileTable::retranslateUi();1127 }1128 1129 void UIGuestFileTable::readDirectory(const QString& strPath,1130 UIFileTableItem *parent, bool isStartDir /*= false*/)1131 1132 {1133 if (!parent)1134 return;1135 1136 CGuestDirectory directory;1137 QVector<KDirectoryOpenFlag> flag;1138 flag.push_back(KDirectoryOpenFlag_None);1139 1140 directory = m_comGuestSession.DirectoryOpen(strPath, /*aFilter*/ "", flag);1141 parent->setIsOpened(true);1142 1143 if (directory.isOk())1144 {1145 CFsObjInfo fsInfo = directory.Read();1146 QMap<QString, UIFileTableItem*> directories;1147 QMap<QString, UIFileTableItem*> files;1148 1149 while (fsInfo.isOk())1150 {1151 QList<QVariant> data;1152 QDateTime changeTime = QDateTime::fromMSecsSinceEpoch(fsInfo.GetChangeTime()/1000000);1153 1154 data << fsInfo.GetName() << static_cast<qulonglong>(fsInfo.GetObjectSize()) << changeTime;1155 bool isDirectory = (fsInfo.GetType() == KFsObjType_Directory);1156 UIFileTableItem *item = new UIFileTableItem(data, isDirectory, parent);1157 item->setPath(strPath, fsInfo.GetName());1158 if (isDirectory)1159 {1160 directories.insert(fsInfo.GetName(), item);1161 item->setIsOpened(false);1162 }1163 else1164 {1165 files.insert(fsInfo.GetName(), item);1166 item->setIsOpened(false);1167 }1168 fsInfo = directory.Read();1169 }1170 insertItemsToTree(directories, parent, true, isStartDir);1171 insertItemsToTree(files, parent, false, isStartDir);1172 updateCurrentLocationEdit(strPath);1173 }1174 }1175 1176 void UIGuestFileTable::deleteByItem(UIFileTableItem *item)1177 {1178 if (!item)1179 return;1180 if (!m_comGuestSession.isOk())1181 return;1182 if (item->isUpDirectory())1183 return;1184 QVector<KDirectoryRemoveRecFlag> flags(KDirectoryRemoveRecFlag_ContentAndDir);1185 1186 if (item->isDirectory())1187 {1188 m_comGuestSession.DirectoryRemoveRecursive(item->path(), flags);1189 }1190 else1191 m_comGuestSession.FsObjRemove(item->path());1192 if (!m_comGuestSession.isOk())1193 emit sigLogOutput(QString(item->path()).append(" could not be deleted"));1194 1195 }1196 1197 void UIGuestFileTable::goToHomeDirectory()1198 {1199 /** @todo not implemented in guest control yet: */1200 }1201 1202 bool UIGuestFileTable::renameItem(UIFileTableItem *item, QString newBaseName)1203 {1204 1205 if (!item || item->isUpDirectory() || newBaseName.isEmpty() || !m_comGuestSession.isOk())1206 return false;1207 QString newPath = constructNewItemPath(item->path(), newBaseName);1208 QVector<KFsObjRenameFlag> aFlags(KFsObjRenameFlag_Replace);1209 1210 m_comGuestSession.FsObjRename(item->path(), newPath, aFlags);1211 if (m_comGuestSession.isOk())1212 return false;1213 return true;1214 }1215 1216 void UIGuestFileTable::configureObjects()1217 {1218 if (m_pGoHome)1219 m_pGoHome->setEnabled(false);1220 }1221 1222 bool UIGuestFileTable::createDirectory(const QString &path, const QString &directoryName)1223 {1224 if (!m_comGuestSession.isOk())1225 return false;1226 1227 QString newDirectoryPath = mergePaths(path, directoryName);1228 QVector<KDirectoryCreateFlag> flags(KDirectoryCreateFlag_None);1229 1230 m_comGuestSession.DirectoryCreate(newDirectoryPath, 777/*aMode*/, flags);1231 if (!m_comGuestSession.isOk())1232 {1233 emit sigLogOutput(newDirectoryPath.append(" could not be created"));1234 return false;1235 }1236 emit sigLogOutput(newDirectoryPath.append(" has been created"));1237 return true;1238 }1239 1240 1241 /*********************************************************************************************************************************1242 * UIHostFileTable implementation. *1243 *********************************************************************************************************************************/1244 1245 UIHostFileTable::UIHostFileTable(QWidget *pParent /* = 0 */)1246 :UIGuestControlFileTable(pParent)1247 {1248 initializeFileTree();1249 retranslateUi();1250 }1251 1252 void UIHostFileTable::retranslateUi()1253 {1254 if (m_pLocationLabel)1255 m_pLocationLabel->setText(UIVMInformationDialog::tr("Host System"));1256 UIGuestControlFileTable::retranslateUi();1257 }1258 1259 void UIHostFileTable::readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir /*= false*/)1260 {1261 if (!parent)1262 return;1263 1264 QDir directory(strPath);1265 //directory.setFilter(QDir::NoDotAndDotDot);1266 parent->setIsOpened(true);1267 if (!directory.exists())1268 return;1269 QFileInfoList entries = directory.entryInfoList();1270 QMap<QString, UIFileTableItem*> directories;1271 QMap<QString, UIFileTableItem*> files;1272 1273 for (int i = 0; i < entries.size(); ++i)1274 {1275 const QFileInfo &fileInfo = entries.at(i);1276 QList<QVariant> data;1277 data << fileInfo.baseName() << fileInfo.size() << fileInfo.lastModified();1278 UIFileTableItem *item = new UIFileTableItem(data, fileInfo.isDir(), parent);1279 item->setPath(fileInfo.absoluteFilePath());1280 if (fileInfo.isDir())1281 {1282 directories.insert(fileInfo.baseName(), item);1283 item->setIsOpened(false);1284 }1285 else1286 {1287 files.insert(fileInfo.baseName(), item);1288 item->setIsOpened(false);1289 }1290 1291 }1292 insertItemsToTree(directories, parent, true, isStartDir);1293 insertItemsToTree(files, parent, false, isStartDir);1294 updateCurrentLocationEdit(strPath);1295 }1296 1297 void UIHostFileTable::deleteByItem(UIFileTableItem *item)1298 {1299 if (!item->isDirectory())1300 {1301 QDir itemToDelete;//(item->path());1302 itemToDelete.remove(item->path());1303 }1304 QDir itemToDelete(item->path());1305 itemToDelete.setFilter(QDir::NoDotAndDotDot);1306 /* Try to delete item recursively (in case of directories).1307 note that this is no good way of deleting big directory1308 trees. We need a better error reporting and a kind of progress1309 indicator: */1310 /** @todo replace this recursive delete by a better implementation: */1311 bool deleteSuccess = itemToDelete.removeRecursively();1312 1313 if (!deleteSuccess)1314 emit sigLogOutput(QString(item->path()).append(" could not be deleted"));1315 }1316 1317 void UIHostFileTable::goToHomeDirectory()1318 {1319 if (!m_pRootItem || m_pRootItem->childCount() <= 0)1320 return;1321 UIFileTableItem *startDirItem = m_pRootItem->child(0);1322 if (!startDirItem)1323 return;1324 1325 // UIFileTableItem *rootDirectoryItem1326 QDir homeDirectory(QDir::homePath());1327 QVector<QString> pathTrail;//(QDir::rootPath());1328 do{1329 1330 pathTrail.push_front(homeDirectory.absolutePath());1331 homeDirectory.cdUp();1332 }while(!homeDirectory.isRoot());1333 1334 goIntoDirectory(pathTrail);1335 }1336 1337 bool UIHostFileTable::renameItem(UIFileTableItem *item, QString newBaseName)1338 {1339 if (!item || item->isUpDirectory() || newBaseName.isEmpty())1340 return false;1341 QString newPath = constructNewItemPath(item->path(), newBaseName);1342 QDir a;1343 return a.rename(item->path(), newPath);1344 }1345 1346 bool UIHostFileTable::createDirectory(const QString &path, const QString &directoryName)1347 {1348 QDir parentDir(path);1349 if (!parentDir.mkdir(directoryName))1350 {1351 emit sigLogOutput(mergePaths(path, directoryName).append(" could not be created"));1352 return false;1353 }1354 1355 return true;1356 }1357 1358 #include "UIGuestControlFileTable.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileModel.h
r71270 r71271 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIGuestControlFile Tableclass declaration.3 * VBox Qt GUI - UIGuestControlFileModel class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef ___UIGuestControlFile Table_h___19 #define ___UIGuestControlFile Table_h___18 #ifndef ___UIGuestControlFileModel_h___ 19 #define ___UIGuestControlFileModel_h___ 20 20 21 21 /* Qt includes: */ 22 22 #include <QAbstractItemModel> 23 #include <QTreeView>24 #include <QWidget>25 26 /* COM includes: */27 #include "COMEnums.h"28 #include "CGuestSession.h"29 23 30 24 /* GUI includes: */ 31 25 #include "QITableView.h" 32 #include "QIWithRetranslateUI.h"33 26 34 27 /* Forward declarations: */ 35 class QAction;36 class QILabel;37 class QILineEdit;38 class QGridLayout;39 28 class UIFileTableItem; 40 29 class UIGuestControlFileTable; 41 class UIToolBar;42 30 43 31 /** UIGuestControlFileModel serves as the model for a file structure. … … 82 70 }; 83 71 84 /** This class serves a base class for file table. Currently a guest version85 and a host version are derived from this base. Each of these children86 populates the UIGuestControlFileModel by scanning the file system87 differently. The file structre kept in this class as a tree and all88 the interfacing is done thru this class.*/89 class UIGuestControlFileTable : public QIWithRetranslateUI<QWidget>90 {91 Q_OBJECT;92 72 93 signals: 94 95 void sigLogOutput(QString); 96 97 public: 98 99 UIGuestControlFileTable(QWidget *pParent = 0); 100 virtual ~UIGuestControlFileTable(); 101 /** Delete all the tree nodes */ 102 void reset(); 103 void emitLogOutput(const QString& strOutput); 104 105 protected: 106 107 void retranslateUi(); 108 void updateCurrentLocationEdit(const QString& strLocation); 109 void changeLocation(const QModelIndex &index); 110 void initializeFileTree(); 111 void insertItemsToTree(QMap<QString,UIFileTableItem*> &map, UIFileTableItem *parent, 112 bool isDirectoryMap, bool isStartDir); 113 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) = 0; 114 virtual void refresh(); 115 virtual void deleteByItem(UIFileTableItem *item) = 0; 116 virtual void goToHomeDirectory() = 0; 117 virtual bool renameItem(UIFileTableItem *item, QString newBaseName) = 0; 118 virtual bool createDirectory(const QString &path, const QString &directoryName) = 0; 119 void goIntoDirectory(const QModelIndex &itemIndex); 120 /** Follow the path trail, open directories as we go and descend */ 121 void goIntoDirectory(const QVector<QString> &pathTrail); 122 /** Go into directory pointed by the @p item */ 123 void goIntoDirectory(UIFileTableItem *item); 124 UIFileTableItem* indexData(const QModelIndex &index) const; 125 void keyPressEvent(QKeyEvent * pEvent); 126 127 /** Replace the last part of the @p previusPath with newBaseName */ 128 QString constructNewItemPath(const QString &previousPath, const QString &newBaseName); 129 QString mergePaths(const QString &Path, const QString &baseName); 130 131 UIFileTableItem *m_pRootItem; 132 133 /** Using QITableView causes the following problem when I click on the table items 134 Qt WARNING: Cannot creat accessible child interface for object: UIGuestControlFileView..... 135 so for now subclass QTableView */ 136 QTableView *m_pView; 137 UIGuestControlFileModel *m_pModel; 138 QTreeView *m_pTree; 139 QILabel *m_pLocationLabel; 140 QAction *m_pGoHome; 141 protected slots: 142 143 void sltItemDoubleClicked(const QModelIndex &index); 144 void sltGoUp(); 145 void sltGoHome(); 146 void sltRefresh(); 147 void sltDelete(); 148 void sltRename(); 149 void sltCreateNewDirectory(); 150 151 private: 152 153 void prepareObjects(); 154 void prepareActions(); 155 void deleteByIndex(const QModelIndex &itemIndex); 156 /** Return the UIFileTableItem for path / which is a direct (and single) child of m_pRootItem */ 157 UIFileTableItem *getStartDirectoryItem(); 158 /** Shows a modal dialog with a line edit for user to enter a new directory name and return the entered string*/ 159 QString getNewDirectoryName(); 160 QGridLayout *m_pMainLayout; 161 QILineEdit *m_pCurrentLocationEdit; 162 UIToolBar *m_pToolBar; 163 QAction *m_pGoUp; 164 165 QAction *m_pRefresh; 166 QAction *m_pDelete; 167 QAction *m_pRename; 168 QAction *m_pCreateNewDirectory; 169 170 QAction *m_pCopy; 171 QAction *m_pCut; 172 QAction *m_pPaste; 173 174 friend class UIGuestControlFileModel; 175 }; 176 177 /** This class scans the guest file system by using the VBox API 178 and populates the UIGuestControlFileModel*/ 179 class UIGuestFileTable : public UIGuestControlFileTable 180 { 181 Q_OBJECT; 182 183 public: 184 185 UIGuestFileTable(QWidget *pParent = 0); 186 void initGuestFileTable(const CGuestSession &session); 187 188 protected: 189 190 void retranslateUi() /* override */; 191 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) /* override */; 192 virtual void deleteByItem(UIFileTableItem *item) /* override */; 193 virtual void goToHomeDirectory() /* override */; 194 virtual bool renameItem(UIFileTableItem *item, QString newBaseName); 195 virtual bool createDirectory(const QString &path, const QString &directoryName); 196 197 private: 198 199 void configureObjects(); 200 CGuestSession m_comGuestSession; 201 202 }; 203 204 /** This class scans the host file system by using the Qt 205 and populates the UIGuestControlFileModel*/ 206 class UIHostFileTable : public UIGuestControlFileTable 207 { 208 Q_OBJECT; 209 210 public: 211 212 UIHostFileTable(QWidget *pParent = 0); 213 214 protected: 215 216 void retranslateUi() /* override */; 217 virtual void readDirectory(const QString& strPath, UIFileTableItem *parent, bool isStartDir = false) /* override */; 218 virtual void deleteByItem(UIFileTableItem *item) /* override */; 219 virtual void goToHomeDirectory() /* override */; 220 virtual bool renameItem(UIFileTableItem *item, QString newBaseName); 221 virtual bool createDirectory(const QString &path, const QString &directoryName); 222 }; 223 224 #endif /* !___UIGuestControlFileTable_h___ */ 73 #endif /* !___UIGuestControlFileModel_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.cpp
r71269 r71271 37 37 # include "UIIconPool.h" 38 38 # include "UIGuestControlFileTable.h" 39 # include "UIGuestControlFileModel.h" 39 40 # include "UIToolBar.h" 40 41 # include "UIVMInformationDialog.h" … … 65 66 * UIFileStringInputDialog definition. * 66 67 *********************************************************************************************************************************/ 68 67 69 /** A QIDialog child including a line edit whose text exposed when the dialog is accepted */ 68 70 class UIStringInputDialog : public QIDialog … … 84 86 85 87 }; 86 87 88 89 /*********************************************************************************************************************************90 * UIFileTableItem definition. *91 *********************************************************************************************************************************/92 93 class UIFileTableItem94 {95 public:96 explicit UIFileTableItem(const QList<QVariant> &data, bool isDirectory, UIFileTableItem *parentItem);97 ~UIFileTableItem();98 99 void appendChild(UIFileTableItem *child);100 101 UIFileTableItem *child(int row) const;102 /** Return a child (if possible) by path */103 UIFileTableItem *child(const QString &path) const;104 int childCount() const;105 int columnCount() const;106 QVariant data(int column) const;107 void setData(const QVariant &data, int index);108 int row() const;109 UIFileTableItem *parentItem();110 111 bool isDirectory() const;112 bool isOpened() const;113 void setIsOpened(bool flag);114 115 const QString &path() const;116 void setPath(const QString &path);117 /** Merge prefix and suffix by making sure they have a single '/' in between */118 void setPath(const QString &prexix, const QString &suffix);119 120 /** True if this is directory and name is ".." */121 bool isUpDirectory() const;122 void clearChildren();123 124 private:125 QList<UIFileTableItem*> m_childItems;126 /** Used to find children by path */127 QMap<QString, UIFileTableItem*> m_childMap;128 QList<QVariant> m_itemData;129 UIFileTableItem *m_parentItem;130 bool m_bIsDirectory;131 bool m_bIsOpened;132 /** Full absolute path of the item. Without the trailing '/' */133 QString m_strPath;134 /** For directories base name is the name of the lowest level directory135 in strPath. eg. for 'm_strPath = /opt/qt5.6/examples' 'm_strBaseName = examples'136 for files it is the name of the file */137 QString m_strBaseName;138 };139 140 88 141 89 /********************************************************************************************************************************* 142 90 * UIFileStringInputDialog implementation. * 143 91 *********************************************************************************************************************************/ 92 144 93 UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */) 145 94 :QIDialog(pParent, flags) … … 166 115 } 167 116 168 169 117 /********************************************************************************************************************************* 170 118 * UIFileTableItem implementation. * … … 302 250 303 251 /********************************************************************************************************************************* 304 * UIGuestControlFileModel implementation. *305 *********************************************************************************************************************************/306 307 UIGuestControlFileModel::UIGuestControlFileModel(QObject *parent)308 : QAbstractItemModel(parent)309 , m_pParent(qobject_cast<UIGuestControlFileTable*>(parent))310 {311 QList<QVariant> rootData;312 // rootData << "Title" << "Summary";313 // rootItem = new UIFileTableItem(rootData);314 }315 316 UIFileTableItem* UIGuestControlFileModel::rootItem() const317 {318 if (!m_pParent)319 return 0;320 return m_pParent->m_pRootItem;321 }322 323 UIGuestControlFileModel::~UIGuestControlFileModel()324 {}325 326 int UIGuestControlFileModel::columnCount(const QModelIndex &parent) const327 {328 if (parent.isValid())329 return static_cast<UIFileTableItem*>(parent.internalPointer())->columnCount();330 else331 {332 if (!rootItem())333 return 0;334 else335 return rootItem()->columnCount();336 }337 }338 339 bool UIGuestControlFileModel::setData(const QModelIndex &index, const QVariant &value, int role)340 {341 if (index.isValid() && role == Qt::EditRole)342 {343 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());344 if (!item || !m_pParent)345 return false;346 if (m_pParent->renameItem(item, value.toString()))347 {348 item->setData(value, index.column());349 emit dataChanged(index, index);350 }351 else352 {353 if (m_pParent)354 m_pParent->emitLogOutput(QString(item->path()).append(" could not be renamed"));355 }356 return true;357 }358 return false;359 }360 361 QVariant UIGuestControlFileModel::data(const QModelIndex &index, int role) const362 {363 if (!index.isValid())364 return QVariant();365 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());366 if (!item)367 return QVariant();368 369 if (role == Qt::DisplayRole || role == Qt::EditRole)370 {371 /* dont show anything but the name for up directories: */372 if (item->isUpDirectory() && index.column() != 0)373 return QVariant();374 /* Format date/time column: */375 if (item->data(index.column()).canConvert(QMetaType::QDateTime))376 {377 QDateTime dateTime = item->data(index.column()).toDateTime();378 if (dateTime.isValid())379 return dateTime.toString("dd.MM.yyyy hh:mm:ss");380 }381 return item->data(index.column());382 }383 384 if (role == Qt::DecorationRole && index.column() == 0)385 {386 if (item->isDirectory())387 {388 if (item->isUpDirectory())389 return QIcon(":/arrow_up_10px_x2.png");390 else391 return QIcon(":/sf_32px.png");392 }393 else394 return QIcon(":/vm_open_filemanager_16px");395 }396 397 return QVariant();398 }399 400 Qt::ItemFlags UIGuestControlFileModel::flags(const QModelIndex &index) const401 {402 if (!index.isValid())403 return 0;404 UIFileTableItem *item = static_cast<UIFileTableItem*>(index.internalPointer());405 if (!item)406 return QAbstractItemModel::flags(index);407 408 if (!item->isUpDirectory() && index.column() == 0)409 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;410 return QAbstractItemModel::flags(index);411 }412 413 QVariant UIGuestControlFileModel::headerData(int section, Qt::Orientation orientation,414 int role) const415 {416 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)417 {418 if (!rootItem())419 return QVariant();420 else421 return rootItem()->data(section);422 }423 return QVariant();424 }425 426 QModelIndex UIGuestControlFileModel::index(UIFileTableItem* item)427 {428 if (!item)429 return QModelIndex();430 return createIndex(item->row(), 0, item);431 }432 433 QModelIndex UIGuestControlFileModel::index(int row, int column, const QModelIndex &parent)434 const435 {436 if (!hasIndex(row, column, parent))437 return QModelIndex();438 439 UIFileTableItem *parentItem;440 441 if (!parent.isValid())442 parentItem = rootItem();443 else444 parentItem = static_cast<UIFileTableItem*>(parent.internalPointer());445 if (!parentItem)446 return QModelIndex();447 448 UIFileTableItem *childItem = parentItem->child(row);449 if (childItem)450 return createIndex(row, column, childItem);451 else452 return QModelIndex();453 }454 455 456 QModelIndex UIGuestControlFileModel::parent(const QModelIndex &index) const457 {458 if (!index.isValid())459 return QModelIndex();460 461 UIFileTableItem *childItem = static_cast<UIFileTableItem*>(index.internalPointer());462 UIFileTableItem *parentItem = childItem->parentItem();463 464 if (parentItem == rootItem())465 return QModelIndex();466 467 return createIndex(parentItem->row(), 0, parentItem);468 }469 470 int UIGuestControlFileModel::rowCount(const QModelIndex &parent) const471 {472 if (parent.column() > 0)473 return 0;474 UIFileTableItem *parentItem = 0;475 if (!parent.isValid())476 parentItem = rootItem();477 else478 parentItem = static_cast<UIFileTableItem*>(parent.internalPointer());479 if (!parentItem)480 return 0;481 return parentItem->childCount();482 }483 484 void UIGuestControlFileModel::signalUpdate()485 {486 emit layoutChanged();487 }488 489 QModelIndex UIGuestControlFileModel::rootIndex() const490 {491 if (!rootItem())492 return QModelIndex();493 return createIndex(rootItem()->child(0)->row(), 0,494 rootItem()->child(0));495 }496 497 void UIGuestControlFileModel::beginReset()498 {499 beginResetModel();500 }501 502 void UIGuestControlFileModel::endReset()503 {504 endResetModel();505 }506 507 bool UIGuestControlFileModel::insertRows(int position, int rows, const QModelIndex &parent)508 {509 UIFileTableItem *parentItem = static_cast<UIFileTableItem*>(parent.internalPointer());510 511 if (!parentItem)512 return false;513 beginInsertRows(parent, position, position + rows -1);514 515 QList<QVariant> data;516 data << "New Item" << 0 << QDateTime::currentDateTime();517 UIFileTableItem *newItem = new UIFileTableItem(data, true, parentItem);518 parentItem->appendChild(newItem);519 endInsertRows();520 521 return true;522 }523 524 525 /*********************************************************************************************************************************526 252 * UIGuestControlFileTable implementation. * 527 253 *********************************************************************************************************************************/ … … 532 258 , m_pView(0) 533 259 , m_pModel(0) 534 , m_pTree(0)535 260 , m_pLocationLabel(0) 536 261 , m_pGoHome(0) -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.h
r71269 r71271 20 20 21 21 /* Qt includes: */ 22 #include <QAbstractItemModel>23 #include <QTreeView>24 22 #include <QWidget> 25 23 … … 38 36 class QGridLayout; 39 37 class UIFileTableItem; 38 class UIGuestControlFileModel; 40 39 class UIGuestControlFileTable; 41 40 class UIToolBar; 42 41 43 /** UIGuestControlFileModel serves as the model for a file structure. 44 it supports a tree level hierarchy which can be displayed with 45 QTableView and/or QTreeView. Note the file structure data is not 46 kept by the model but rather by the containing widget which also servers 47 as the interface to functionality this model provides.*/ 48 class UIGuestControlFileModel : public QAbstractItemModel 49 { 50 51 Q_OBJECT; 52 53 public: 54 55 explicit UIGuestControlFileModel(QObject *parent = 0); 56 ~UIGuestControlFileModel(); 57 58 QVariant data(const QModelIndex &index, int role) const /* override */; 59 bool setData(const QModelIndex &index, const QVariant &value, int role); 60 61 Qt::ItemFlags flags(const QModelIndex &index) const /* override */; 62 QVariant headerData(int section, Qt::Orientation orientation, 63 int role = Qt::DisplayRole) const /* override */; 64 QModelIndex index(int row, int column, 65 const QModelIndex &parent = QModelIndex()) const /* override */; 66 QModelIndex index(UIFileTableItem* item); 67 QModelIndex parent(const QModelIndex &index) const /* override */; 68 int rowCount(const QModelIndex &parent = QModelIndex()) const /* override */; 69 int columnCount(const QModelIndex &parent = QModelIndex()) const /* override */; 70 void signalUpdate(); 71 QModelIndex rootIndex() const; 72 void beginReset(); 73 void endReset(); 74 bool insertRows(int position, int rows, const QModelIndex &parent); 42 /********************************************************************************************************************************* 43 * UIFileTableItem definition. * 44 *********************************************************************************************************************************/ 45 46 class UIFileTableItem 47 { 48 public: 49 explicit UIFileTableItem(const QList<QVariant> &data, bool isDirectory, UIFileTableItem *parentItem); 50 ~UIFileTableItem(); 51 52 void appendChild(UIFileTableItem *child); 53 54 UIFileTableItem *child(int row) const; 55 /** Return a child (if possible) by path */ 56 UIFileTableItem *child(const QString &path) const; 57 int childCount() const; 58 int columnCount() const; 59 QVariant data(int column) const; 60 void setData(const QVariant &data, int index); 61 int row() const; 62 UIFileTableItem *parentItem(); 63 64 bool isDirectory() const; 65 bool isOpened() const; 66 void setIsOpened(bool flag); 67 68 const QString &path() const; 69 void setPath(const QString &path); 70 /** Merge prefix and suffix by making sure they have a single '/' in between */ 71 void setPath(const QString &prexix, const QString &suffix); 72 73 /** True if this is directory and name is ".." */ 74 bool isUpDirectory() const; 75 void clearChildren(); 75 76 76 77 private: 77 78 UIFileTableItem* rootItem() const; 79 void setupModelData(const QStringList &lines, UIFileTableItem *parent); 80 UIGuestControlFileTable* m_pParent; 81 UIFileTableItem *m_pRootItem; 78 QList<UIFileTableItem*> m_childItems; 79 /** Used to find children by path */ 80 QMap<QString, UIFileTableItem*> m_childMap; 81 QList<QVariant> m_itemData; 82 UIFileTableItem *m_parentItem; 83 bool m_bIsDirectory; 84 bool m_bIsOpened; 85 /** Full absolute path of the item. Without the trailing '/' */ 86 QString m_strPath; 87 /** For directories base name is the name of the lowest level directory 88 in strPath. eg. for 'm_strPath = /opt/qt5.6/examples' 'm_strBaseName = examples' 89 for files it is the name of the file */ 90 QString m_strBaseName; 82 91 }; 83 92 … … 136 145 QTableView *m_pView; 137 146 UIGuestControlFileModel *m_pModel; 138 QTreeView *m_pTree;139 147 QILabel *m_pLocationLabel; 140 148 QAction *m_pGoHome;
Note:
See TracChangeset
for help on using the changeset viewer.