VirtualBox

Ignore:
Timestamp:
Mar 8, 2018 12:21:53 PM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:6699 Factor out 'file item model' class

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r71270 r71271  
    378378        src/runtime/guestctrl/UIGuestControlConsole.h \
    379379        src/runtime/guestctrl/UIGuestControlFileManager.h \
     380        src/runtime/guestctrl/UIGuestControlFileModel.h \
    380381        src/runtime/guestctrl/UIGuestControlFileTable.h \
    381382        src/runtime/guestctrl/UIGuestControlInterface.h \
     
    712713        src/runtime/guestctrl/UIGuestControlConsole.cpp \
    713714        src/runtime/guestctrl/UIGuestControlFileManager.cpp \
     715        src/runtime/guestctrl/UIGuestControlFileModel.cpp \
    714716        src/runtime/guestctrl/UIGuestControlFileTable.cpp \
    715717        src/runtime/guestctrl/UIGuestControlInterface.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileModel.cpp

    r71270 r71271  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIGuestControlFileTable class implementation.
     3 * VBox Qt GUI - UIGuestControlFileModel class implementation.
    44 */
    55
     
    2121
    2222/* Qt includes: */
    23 # include <QAction>
    2423# include <QDateTime>
    25 # include <QDir>
    2624# include <QHeaderView>
    27 # include <QItemDelegate>
    28 # include <QGridLayout>
    29 # include <QPushButton>
    3025
    3126/* GUI includes: */
    32 # include "QIDialog.h"
    33 # include "QIDialogButtonBox.h"
    34 # include "QILabel.h"
    35 # include "QILineEdit.h"
    3627# include "UIErrorString.h"
    37 # include "UIIconPool.h"
     28# include "UIGuestControlFileModel.h"
    3829# 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
    4631
    4732#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    4833
    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 QItemDelegate
    55 {
    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 QIDialog
    69 {
    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 UIFileTableItem
    94 {
    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 directory
    135         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() const
    162 {
    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) const
    198 {
    199     return m_childItems.value(row);
    200 }
    201 
    202 UIFileTableItem *UIFileTableItem::child(const QString &path) const
    203 {
    204     if (!m_childMap.contains(path))
    205         return 0;
    206     return m_childMap.value(path);
    207 }
    208 
    209 int UIFileTableItem::childCount() const
    210 {
    211     return m_childItems.count();
    212 }
    213 
    214 int UIFileTableItem::columnCount() const
    215 {
    216     return m_itemData.count();
    217 }
    218 
    219 QVariant UIFileTableItem::data(int column) const
    220 {
    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() const
    237 {
    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() const
    245 {
    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() const
    257 {
    258     return m_bIsOpened;
    259 }
    260 
    261 void UIFileTableItem::setIsOpened(bool flag)
    262 {
    263     m_bIsOpened = flag;
    264 }
    265 
    266 const QString  &UIFileTableItem::path() const
    267 {
    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() const
    294 {
    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 *********************************************************************************************************************************/
    30634
    30735UIGuestControlFileModel::UIGuestControlFileModel(QObject *parent)
     
    521249    return true;
    522250}
    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) const
    867 {
    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 the
    943            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             else
    1164             {
    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     else
    1191         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         else
    1286         {
    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 directory
    1308        trees. We need a better error reporting and a kind of progress
    1309        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 *rootDirectoryItem
    1326     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  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIGuestControlFileTable class declaration.
     3 * VBox Qt GUI - UIGuestControlFileModel class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIGuestControlFileTable_h___
    19 #define ___UIGuestControlFileTable_h___
     18#ifndef ___UIGuestControlFileModel_h___
     19#define ___UIGuestControlFileModel_h___
    2020
    2121/* Qt includes: */
    2222#include <QAbstractItemModel>
    23 #include <QTreeView>
    24 #include <QWidget>
    25 
    26 /* COM includes: */
    27 #include "COMEnums.h"
    28 #include "CGuestSession.h"
    2923
    3024/* GUI includes: */
    3125#include "QITableView.h"
    32 #include "QIWithRetranslateUI.h"
    3326
    3427/* Forward declarations: */
    35 class QAction;
    36 class QILabel;
    37 class QILineEdit;
    38 class QGridLayout;
    3928class UIFileTableItem;
    4029class UIGuestControlFileTable;
    41 class UIToolBar;
    4230
    4331/** UIGuestControlFileModel serves as the model for a file structure.
     
    8270};
    8371
    84 /** This class serves a base class for file table. Currently a guest version
    85     and a host version are derived from this base. Each of these children
    86     populates the UIGuestControlFileModel by scanning the file system
    87     differently. The file structre kept in this class as a tree and all
    88     the interfacing is done thru this class.*/
    89 class UIGuestControlFileTable : public QIWithRetranslateUI<QWidget>
    90 {
    91     Q_OBJECT;
    9272
    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  
    3737# include "UIIconPool.h"
    3838# include "UIGuestControlFileTable.h"
     39# include "UIGuestControlFileModel.h"
    3940# include "UIToolBar.h"
    4041# include "UIVMInformationDialog.h"
     
    6566*   UIFileStringInputDialog definition.                                                                                          *
    6667*********************************************************************************************************************************/
     68
    6769/** A QIDialog child including a line edit whose text exposed when the dialog is accepted */
    6870class UIStringInputDialog : public QIDialog
     
    8486
    8587};
    86 
    87 
    88 
    89 /*********************************************************************************************************************************
    90 *   UIFileTableItem definition.                                                                                                  *
    91 *********************************************************************************************************************************/
    92 
    93 class UIFileTableItem
    94 {
    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 directory
    135         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 
    14088
    14189/*********************************************************************************************************************************
    14290*   UIFileStringInputDialog implementation.                                                                                      *
    14391*********************************************************************************************************************************/
     92
    14493UIStringInputDialog::UIStringInputDialog(QWidget *pParent /* = 0 */, Qt::WindowFlags flags /* = 0 */)
    14594    :QIDialog(pParent, flags)
     
    166115}
    167116
    168 
    169117/*********************************************************************************************************************************
    170118*   UIFileTableItem implementation.                                                                                              *
     
    302250
    303251/*********************************************************************************************************************************
    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() const
    317 {
    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) const
    327 {
    328     if (parent.isValid())
    329         return static_cast<UIFileTableItem*>(parent.internalPointer())->columnCount();
    330     else
    331     {
    332         if (!rootItem())
    333             return 0;
    334         else
    335             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         else
    352         {
    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) const
    362 {
    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             else
    391                 return QIcon(":/sf_32px.png");
    392         }
    393         else
    394             return QIcon(":/vm_open_filemanager_16px");
    395     }
    396 
    397     return QVariant();
    398 }
    399 
    400 Qt::ItemFlags UIGuestControlFileModel::flags(const QModelIndex &index) const
    401 {
    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) const
    415 {
    416     if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    417     {
    418         if (!rootItem())
    419             return QVariant();
    420         else
    421             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             const
    435 {
    436     if (!hasIndex(row, column, parent))
    437         return QModelIndex();
    438 
    439     UIFileTableItem *parentItem;
    440 
    441     if (!parent.isValid())
    442         parentItem = rootItem();
    443     else
    444         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     else
    452         return QModelIndex();
    453 }
    454 
    455 
    456 QModelIndex UIGuestControlFileModel::parent(const QModelIndex &index) const
    457 {
    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) const
    471 {
    472     if (parent.column() > 0)
    473         return 0;
    474     UIFileTableItem *parentItem = 0;
    475     if (!parent.isValid())
    476         parentItem = rootItem();
    477     else
    478         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() const
    490 {
    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 /*********************************************************************************************************************************
    526252*   UIGuestControlFileTable implementation.                                                                                      *
    527253*********************************************************************************************************************************/
     
    532258    , m_pView(0)
    533259    , m_pModel(0)
    534     , m_pTree(0)
    535260    , m_pLocationLabel(0)
    536261    , m_pGoHome(0)
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.h

    r71269 r71271  
    2020
    2121/* Qt includes: */
    22 #include <QAbstractItemModel>
    23 #include <QTreeView>
    2422#include <QWidget>
    2523
     
    3836class QGridLayout;
    3937class UIFileTableItem;
     38class UIGuestControlFileModel;
    4039class UIGuestControlFileTable;
    4140class UIToolBar;
    4241
    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
     46class UIFileTableItem
     47{
     48public:
     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();
    7576
    7677private:
    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;
    8291};
    8392
     
    136145    QTableView              *m_pView;
    137146    UIGuestControlFileModel *m_pModel;
    138     QTreeView               *m_pTree;
    139147    QILabel                 *m_pLocationLabel;
    140148    QAction                  *m_pGoHome;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette