VirtualBox

Changeset 71505 in vbox


Ignore:
Timestamp:
Mar 26, 2018 9:03:32 AM (7 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:6699 Move a recursive directory operation to a worker thread to avoid GUI freeze

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
8 edited

Legend:

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

    r71392 r71505  
    599599        src/runtime/guestctrl/UIGuestControlFileManager.cpp \
    600600        src/runtime/guestctrl/UIGuestControlFileTable.cpp \
    601         src/runtime/guestctrl/UIGuestControlWidget.cpp \
     601        src/runtime/guestctrl/UIHostFileTable.cpp \
    602602        src/selector/UIActionPoolSelector.cpp \
    603603        src/selector/UIDesktopPane.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileManager.cpp

    r71467 r71505  
    348348        m_pMainLayout->addWidget(m_pVerticalSplitter);
    349349        m_pVerticalSplitter->setOrientation(Qt::Vertical);
    350         m_pVerticalSplitter->setHandleWidth(2);
     350        m_pVerticalSplitter->setHandleWidth(4);
    351351    }
    352352
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.cpp

    r71467 r71505  
    128128};
    129129
    130 /*********************************************************************************************************************************
    131 *   UIPropertiesDialog definition.                                                                                          *
    132 *********************************************************************************************************************************/
    133 
    134 /** A QIDialog child to display properties of a file object */
    135 class UIPropertiesDialog : public QIDialog
    136 {
    137 
    138     Q_OBJECT;
    139 
    140 public:
    141 
    142     UIPropertiesDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);
    143     void setPropertyText(const QString &strProperty);
    144 
    145 private:
    146 
    147     QVBoxLayout    *m_pMainLayout;
    148     QTextEdit *m_pInfoEdit;
    149 
    150 };
    151 
    152130
    153131/*********************************************************************************************************************************
     
    452430    if (!m_pInfoEdit)
    453431        return;
    454 
    455     m_pInfoEdit->setText(strProperty);
    456 }
    457 
     432    m_strProperty = strProperty;
     433    m_pInfoEdit->setHtml(strProperty);
     434}
     435
     436void UIPropertiesDialog::addDirectoryStatistics(UIDirectoryStatistics directoryStatistics)
     437{
     438    if (!m_pInfoEdit)
     439        return;
     440    // QString propertyString = m_pInfoEdit->toHtml();
     441    // propertyString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");
     442    // if (directoryStatistics.m_totalSize >= UIGuestControlFileTable::m_iKiloByte)
     443    //     propertyString += " (" + UIGuestControlFileTable::humanReadableSize(directoryStatistics.m_totalSize) + ")";
     444    // propertyString += "<br/>";
     445    // propertyString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);
     446
     447    // m_pInfoEdit->setHtml(propertyString);
     448
     449    QString detailsString(m_strProperty);
     450    detailsString += "<br/>";
     451    detailsString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");
     452    if (directoryStatistics.m_totalSize >= UIGuestControlFileTable::m_iKiloByte)
     453        detailsString += " (" + UIGuestControlFileTable::humanReadableSize(directoryStatistics.m_totalSize) + ")";
     454    detailsString += "<br/>";
     455
     456    detailsString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);
     457
     458    m_pInfoEdit->setHtml(detailsString);
     459
     460}
    458461
    459462/*********************************************************************************************************************************
     
    635638*   UIGuestControlFileTable implementation.                                                                                      *
    636639*********************************************************************************************************************************/
    637 
     640const unsigned UIGuestControlFileTable::m_iKiloByte = 1000;
    638641UIGuestControlFileTable::UIGuestControlFileTable(QWidget *pParent /* = 0 */)
    639642    :QIWithRetranslateUI<QWidget>(pParent)
     
    642645    , m_pModel(0)
    643646    , m_pLocationLabel(0)
    644     , m_iKiloByte(1000)
    645647    , m_pCopy(0)
    646648    , m_pCut(0)
     
    11351137void UIGuestControlFileTable::sltShowProperties()
    11361138{
    1137     QString fsPropertyString = fsObjectPropertyString();
    1138     if (fsPropertyString.isEmpty())
    1139         return;
    1140 
    1141     UIPropertiesDialog *dialog = new UIPropertiesDialog();
    1142     if (!dialog)
    1143         return;
    1144     dialog->setWindowTitle("Properties");
    1145     dialog->setPropertyText(fsPropertyString);
    1146     dialog->execute();
     1139    showProperties();
    11471140}
    11481141
     
    13811374}
    13821375
    1383 QString UIGuestControlFileTable::humanReadableSize(ULONG64 size)
     1376/* static */ QString UIGuestControlFileTable::humanReadableSize(ULONG64 size)
    13841377{
    13851378    int i = 0;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestControlFileTable.h

    r71439 r71505  
    2727
    2828/* GUI includes: */
     29#include "QIDialog.h"
    2930#include "QITableView.h"
    3031#include "QIWithRetranslateUI.h"
     
    3334class QAction;
    3435class QFileInfo;
     36
    3537class QILabel;
    3638class QILineEdit;
    3739class QGridLayout;
     40class QTextEdit;
     41class QVBoxLayout;
    3842class UIFileTableItem;
    3943class UIGuestControlFileModel;
     
    4953    FileObjectType_Unknown,
    5054    FileObjectType_Max
     55};
     56
     57class UIDirectoryStatistics
     58{
     59public:
     60    UIDirectoryStatistics();
     61    ULONG64    m_totalSize;
     62    unsigned   m_uFileCount;
     63    unsigned   m_uDirectoryCount;
     64    unsigned   m_uSymlinkCount;
     65};
     66
     67Q_DECLARE_METATYPE(UIDirectoryStatistics);
     68
     69/** A QIDialog child to display properties of a file object */
     70class UIPropertiesDialog : public QIDialog
     71{
     72
     73    Q_OBJECT;
     74
     75public:
     76
     77    UIPropertiesDialog(QWidget *pParent = 0, Qt::WindowFlags flags = 0);
     78    void setPropertyText(const QString &strProperty);
     79    void addDirectoryStatistics(UIDirectoryStatistics statictics);
     80
     81private:
     82
     83    QVBoxLayout    *m_pMainLayout;
     84    QTextEdit *m_pInfoEdit;
     85    QString   m_strProperty;
    5186};
    5287
     
    144179};
    145180
    146 class UIDirectoryStatistics
    147 {
    148 public:
    149     UIDirectoryStatistics();
    150     ULONG64    m_totalSize;
    151     unsigned   m_uFileCount;
    152     unsigned   m_uDirectoryCount;
    153     unsigned   m_uSymlinkCount;
    154 };
    155181
    156182/** This class serves a base class for file table. Currently a guest version
     
    178204    QStringList selectedItemPathList();
    179205    virtual void refresh();
     206
     207    static const unsigned    m_iKiloByte;
     208    static QString humanReadableSize(ULONG64 size);
     209
    180210
    181211protected:
     
    193223    virtual bool createDirectory(const QString &path, const QString &directoryName) = 0;
    194224    virtual QString fsObjectPropertyString() = 0;
     225    virtual void  showProperties() = 0;
    195226    static QString fileTypeString(FileObjectType type);
    196227    void             goIntoDirectory(const QModelIndex &itemIndex);
     
    202233    void keyPressEvent(QKeyEvent * pEvent);
    203234    CGuestFsObjInfo guestFsObjectInfo(const QString& path, CGuestSession &comGuestSession) const;
    204     QString humanReadableSize(ULONG64 size);
    205235
    206236    UIFileTableItem         *m_pRootItem;
     
    209239    UIGuestControlFileModel *m_pModel;
    210240    QILabel                 *m_pLocationLabel;
    211     const unsigned           m_iKiloByte;
    212241    QAction                 *m_pCopy;
    213242    QAction                 *m_pCut;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestFileTable.cpp

    r71467 r71505  
    329329    return QString();
    330330}
     331
     332void UIGuestFileTable::showProperties()
     333{
     334    QString fsPropertyString = fsObjectPropertyString();
     335    if (fsPropertyString.isEmpty())
     336        return;
     337
     338    UIPropertiesDialog *dialog = new UIPropertiesDialog();
     339    if (!dialog)
     340        return;
     341    dialog->setWindowTitle("Properties");
     342    dialog->setPropertyText(fsPropertyString);
     343    dialog->execute();
     344    delete dialog;
     345}
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIGuestFileTable.h

    r71388 r71505  
    4848    virtual bool createDirectory(const QString &path, const QString &directoryName);
    4949    virtual QString fsObjectPropertyString() /* override */;
    50 
     50    virtual void  showProperties() /* override */;
    5151private:
    5252
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIHostFileTable.cpp

    r71467 r71505  
    2424# include <QDateTime>
    2525# include <QDir>
     26# include <QMutex>
     27# include <QThread>
    2628
    2729/* GUI includes: */
     
    3234
    3335
     36/*********************************************************************************************************************************
     37*   UIHostDirectoryDiskUsageComputer definition.                                                                                 *
     38*********************************************************************************************************************************/
     39
     40/** Open directories recursively and sum the disk usage. Don't block the GUI thread while doing this */
     41class UIHostDirectoryDiskUsageComputer : public QThread
     42{
     43    Q_OBJECT;
     44
     45signals:
     46
     47    void sigResultUpdated(UIDirectoryStatistics, QString);
     48
     49public:
     50
     51    UIHostDirectoryDiskUsageComputer(QObject *parent, QString strStartPath);
     52    void stopRecursion();
     53
     54private:
     55
     56    /** Read the directory with the path @p path recursively and collect #of objects and
     57        total size */
     58    void directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics);
     59    void                  run();
     60    QString               m_strStartPath;
     61    UIDirectoryStatistics m_resultStatistics;
     62    bool                  m_bContinueRunning;
     63    QMutex                m_mutex;
     64};
     65
     66
     67/*********************************************************************************************************************************
     68*   UIHostDirectoryDiskUsageComputer implementation.                                                                             *
     69*********************************************************************************************************************************/
     70
     71UIHostDirectoryDiskUsageComputer::UIHostDirectoryDiskUsageComputer(QObject *parent, QString strStartPath)
     72    :QThread(parent)
     73    , m_strStartPath(strStartPath)
     74    , m_bContinueRunning(true)
     75{
     76}
     77
     78void UIHostDirectoryDiskUsageComputer::run()
     79{
     80    directoryStatisticsRecursive(m_strStartPath, m_resultStatistics);
     81}
     82
     83/** @todo Move the following function to a worker thread as it may take atbitrarly long time */
     84void UIHostDirectoryDiskUsageComputer::directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics)
     85{
     86    QDir dir(path);
     87    if (!dir.exists())
     88        return;
     89
     90    if (!m_bContinueRunning)
     91        return;
     92
     93    sigResultUpdated(statistics, path);
     94
     95    QFileInfoList entryList = dir.entryInfoList();
     96    for (int i = 0; i < entryList.size(); ++i)
     97    {
     98        const QFileInfo &entryInfo = entryList.at(i);
     99        if (entryInfo.baseName().isEmpty() || entryInfo.baseName() == "." || entryInfo.baseName() == "..")
     100            continue;
     101        statistics.m_totalSize += entryInfo.size();
     102        if (entryInfo.isSymLink())
     103            statistics.m_uSymlinkCount++;
     104        else if(entryInfo.isFile())
     105            statistics.m_uFileCount++;
     106        else if (entryInfo.isDir())
     107        {
     108            statistics.m_uDirectoryCount++;
     109            directoryStatisticsRecursive(entryInfo.absoluteFilePath(), statistics);
     110        }
     111    }
     112}
     113
     114void UIHostDirectoryDiskUsageComputer::stopRecursion()
     115{
     116    m_mutex.lock();
     117    m_bContinueRunning = false;
     118    m_mutex.unlock();
     119
     120}
     121
     122
     123/*********************************************************************************************************************************
     124*   UIHostFileTable implementation.                                                                                              *
     125*********************************************************************************************************************************/
     126
    34127UIHostFileTable::UIHostFileTable(QWidget *pParent /* = 0 */)
    35128    :UIGuestControlFileTable(pParent)
     129    , m_pPropertiesDialog(0)
    36130{
    37131    initializeFileTree();
     
    219313        propertyString += "<b>Owner:</b> " + fileInfo.owner();
    220314
    221         if (fileInfo.isDir())
    222         {
    223             propertyString += "<br/>";
    224             UIDirectoryStatistics directoryStatistics;
    225             directoryStatisticsRecursive(fileInfo.absoluteFilePath(), directoryStatistics);
    226             propertyString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");
    227             if (directoryStatistics.m_totalSize >= m_iKiloByte)
    228                 propertyString += " (" + humanReadableSize(directoryStatistics.m_totalSize) + ")";
    229             propertyString += "<br/>";
    230             propertyString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);
    231 
    232         }
     315        // if (fileInfo.isDir())
     316        // {
     317        //     propertyString += "<br/>";
     318        //     UIDirectoryStatistics directoryStatistics;
     319        //     directoryStatisticsRecursive(fileInfo.absoluteFilePath(), directoryStatistics);
     320        //     propertyString += "<b>Total Size:</b> " + QString::number(directoryStatistics.m_totalSize) + QString(" bytes");
     321        //     if (directoryStatistics.m_totalSize >= m_iKiloByte)
     322        //         propertyString += " (" + humanReadableSize(directoryStatistics.m_totalSize) + ")";
     323        //     propertyString += "<br/>";
     324        //     propertyString += "<b>File Count:</b> " + QString::number(directoryStatistics.m_uFileCount);
     325        // }
    233326        return propertyString;
    234327    }
     
    236329}
    237330
    238 /** @todo Move the following function to a worker thread as it may take atbitrarly long time */
    239 void UIHostFileTable::directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics)
    240 {
    241     QDir dir(path);
    242     if (!dir.exists())
    243         return;
    244 
    245     QFileInfoList entryList = dir.entryInfoList();
    246     for (int i = 0; i < entryList.size(); ++i)
    247     {
    248         const QFileInfo &entryInfo = entryList.at(i);
    249         if (entryInfo.baseName().isEmpty() || entryInfo.baseName() == "." || entryInfo.baseName() == "..")
    250             continue;
    251         statistics.m_totalSize += entryInfo.size();
    252         if (entryInfo.isSymLink())
    253             statistics.m_uSymlinkCount++;
    254         else if(entryInfo.isFile())
    255             statistics.m_uFileCount++;
    256         else if (entryInfo.isDir())
    257         {
    258             statistics.m_uDirectoryCount++;
    259             directoryStatisticsRecursive(entryInfo.absoluteFilePath(), statistics);
    260         }
    261     }
    262 }
     331void  UIHostFileTable::showProperties()
     332{
     333    qRegisterMetaType<UIDirectoryStatistics>();
     334    QString fsPropertyString = fsObjectPropertyString();
     335    if (fsPropertyString.isEmpty())
     336        return;
     337
     338    m_pPropertiesDialog = new UIPropertiesDialog();
     339    if (!m_pPropertiesDialog)
     340        return;
     341
     342    UIHostDirectoryDiskUsageComputer *directoryThread = 0;
     343
     344    QStringList selectedObjects = selectedItemPathList();
     345    if (selectedObjects.size() == 1)
     346    {
     347        QFileInfo fileInfo(selectedObjects.at(0));
     348        if (fileInfo.exists() && fileInfo.isDir())
     349        {
     350            directoryThread = new UIHostDirectoryDiskUsageComputer(this, fileInfo.absoluteFilePath());
     351            if (directoryThread)
     352            {
     353                connect(directoryThread, &UIHostDirectoryDiskUsageComputer::sigResultUpdated,
     354                        this, &UIHostFileTable::sltReceiveDirectoryStatistics/*, Qt::DirectConnection*/);
     355                directoryThread->start();
     356            }
     357
     358        }
     359    }
     360    m_pPropertiesDialog->setWindowTitle("Properties");
     361    m_pPropertiesDialog->setPropertyText(fsPropertyString);
     362    m_pPropertiesDialog->execute();
     363    if (directoryThread)
     364    {
     365        if (directoryThread->isRunning())
     366        {
     367            directoryThread->stopRecursion();
     368            //directoryThread->wait();
     369        }
     370        disconnect(directoryThread, &UIHostDirectoryDiskUsageComputer::sigResultUpdated,
     371                this, &UIHostFileTable::sltReceiveDirectoryStatistics/*, Qt::DirectConnection*/);
     372        //delete directoryThread;
     373    }
     374    delete m_pPropertiesDialog;
     375    m_pPropertiesDialog = 0;
     376}
     377
     378void UIHostFileTable::sltReceiveDirectoryStatistics(UIDirectoryStatistics statistics, QString path)
     379{
     380    if (!m_pPropertiesDialog)
     381        return;
     382    m_pPropertiesDialog->addDirectoryStatistics(statistics);
     383}
     384
     385#include "UIHostFileTable.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/guestctrl/UIHostFileTable.h

    r71421 r71505  
    4242    virtual bool createDirectory(const QString &path, const QString &directoryName);
    4343    virtual QString fsObjectPropertyString() /* override */;
     44    virtual void  showProperties() /* override */;
     45
     46private slots:
     47
     48    void sltReceiveDirectoryStatistics(UIDirectoryStatistics statictics, QString path);
    4449
    4550private:
    4651
    47     /** Read the directory with the path @p path recursively and collect #of objects and
    48         total size */
    49     void directoryStatisticsRecursive(const QString &path, UIDirectoryStatistics &statistics);
    5052    void prepareActions();
    5153
     54    UIPropertiesDialog *m_pPropertiesDialog;
    5255};
    5356
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