VirtualBox

Changeset 100283 in vbox


Ignore:
Timestamp:
Jun 26, 2023 6:28:18 AM (21 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
157998
Message:

FE/Qt: bugref:9080. Some refactoring around file table navigation widget. It will be used in VISO dialog as well.

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

Legend:

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

    r100155 r100283  
    953953        src/widgets/UIAddDiskEncryptionPasswordDialog.h \
    954954        src/widgets/UIFilePathSelector.h \
     955        src/widgets/UIFileTableNavigationWidget.h \
    955956        src/widgets/UIFilmContainer.h \
    956957        src/widgets/UIMediaComboBox.h \
     
    10881089        src/settings/machine/UIMachineSettingsSerial.cpp \
    10891090        src/widgets/UIAddDiskEncryptionPasswordDialog.cpp \
     1091        src/widgets/UIFileTableNavigationWidget.cpp \
    10901092        src/widgets/UIFilmContainer.cpp \
    10911093        src/widgets/UIPortForwardingTable.cpp \
     
    15371539        src/widgets/UIAddDiskEncryptionPasswordDialog.cpp \
    15381540        src/widgets/UIFilePathSelector.cpp \
     1541        src/widgets/UIFileTableNavigationWidget.cpp \
    15391542        src/widgets/UIFilmContainer.cpp \
    15401543        src/widgets/UIMediaComboBox.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerTable.cpp

    r100269 r100283  
    2828/* Qt includes: */
    2929#include <QAction>
    30 #include <QComboBox>
    3130#include <QCheckBox>
    32 #include <QDir>
    3331#include <QHBoxLayout>
    3432#include <QHeaderView>
    3533#include <QItemDelegate>
    3634#include <QGridLayout>
    37 #include <QStackedWidget>
    3835#include <QTextEdit>
    3936
     
    4441#include "QILineEdit.h"
    4542#include "QIToolBar.h"
    46 #include "QIToolButton.h"
    4743#include "UIActionPool.h"
    4844#include "UICommon.h"
     
    5046#include "UIErrorString.h"
    5147#include "UIFileManager.h"
    52 #include "UIFileManagerGuestTable.h"
    5348#include "UIFileManagerTable.h"
     49#include "UIFileTableNavigationWidget.h"
    5450#include "UIIconPool.h"
    5551#include "UIPathOperations.h"
     
    6460
    6561/*********************************************************************************************************************************
    66 *   UIFileManagerHistoryComboBox definition.                                                                                     *
    67 *********************************************************************************************************************************/
    68 /** A QCombo extension used as location history list in the UIFileManagerNavigationWidget. */
    69 class UIFileManagerHistoryComboBox : public QComboBox
    70 {
    71     Q_OBJECT;
    72 
    73 signals:
    74 
    75     void  sigHidePopup();
    76 
    77 public:
    78 
    79     UIFileManagerHistoryComboBox(QWidget *pParent = 0);
    80     /** Emit sigHidePopup as the popup is hidded. */
    81     virtual void hidePopup() RT_OVERRIDE;
    82 };
    83 
    84 
    85 /*********************************************************************************************************************************
    86 *   UIFileManagerBreadCrumbs definition.                                                                                         *
    87 *********************************************************************************************************************************/
    88 /** A QLabel extension. It shows the current path as text and hightligts the folder name
    89   *  as the mouse hovers over it. Clicking on the highlighted folder name make the file table to
    90   *  navigate to that folder. */
    91 class UIFileManagerBreadCrumbs : public QLabel
    92 {
    93     Q_OBJECT;
    94 
    95 public:
    96 
    97     UIFileManagerBreadCrumbs(QWidget *pParent = 0);
    98     void setPath(const QString &strPath);
    99     void setPathSeparator(const QChar &separator);
    100 
    101 protected:
    102 
    103     virtual void resizeEvent(QResizeEvent *pEvent) RT_OVERRIDE;
    104 
    105 private:
    106 
    107     QString m_strPath;
    108     QChar   m_pathSeparator;
    109 };
    110 
    111 
    112 /*********************************************************************************************************************************
    113 *   UIFileManagerNavigationWidget definition.                                                                                    *
    114 *********************************************************************************************************************************/
    115 /** UIFileManagerNavigationWidget contains a UIFileManagerBreadCrumbs, QComboBox for history and a QToolButton.
    116   * basically it is a container for these mentioned widgets. */
    117 class UIFileManagerNavigationWidget : public QWidget
    118 {
    119     Q_OBJECT;
    120 
    121 signals:
    122 
    123     void sigPathChanged(const QString &strPath);
    124 
    125 public:
    126 
    127     UIFileManagerNavigationWidget(QWidget *pParent = 0);
    128     void setPath(const QString &strLocation);
    129     void reset();
    130     void setPathSeparator(const QChar &separator);
    131     bool eventFilter(QObject *pObject, QEvent *pEvent) override;
    132 
    133 private slots:
    134     void sltHandleSwitch();
    135     /* Makes sure that we switch to breadcrumbs widget as soon as the combo box popup is hidden. */
    136     void sltHandleHidePopup();
    137     void sltHandlePathChange(const QString &strPath);
    138     void sltAddressLineEdited();
    139 
    140 private:
    141 
    142     enum StackedWidgets
    143     {
    144         StackedWidgets_History = 0,
    145         StackedWidgets_BreadCrumbs,
    146         StackedWidgets_AddressLine
    147     };
    148 
    149     void prepare();
    150 
    151     QStackedWidget               *m_pContainer;
    152     UIFileManagerBreadCrumbs     *m_pBreadCrumbs;
    153     UIFileManagerHistoryComboBox *m_pHistoryComboBox;
    154     QLineEdit                    *m_pAddressLineEdit;
    155     QToolButton                  *m_pSwitchButton;
    156     QChar                         m_pathSeparator;
    157     /* With non-native separators. */
    158     QString                       m_strCurrentPath;
    159 };
    160 
    161 
    162 /*********************************************************************************************************************************
    16362*   UIGuestControlFileView definition.                                                                                           *
    16463*********************************************************************************************************************************/
     
    255154    QILabel   *m_pQuestionLabel;
    256155};
    257 
    258 
    259 /*********************************************************************************************************************************
    260 *   UIFileManagerHistoryComboBox implementation.                                                                                 *
    261 *********************************************************************************************************************************/
    262 
    263 UIFileManagerHistoryComboBox::UIFileManagerHistoryComboBox(QWidget *pParent /* = 0 */)
    264     :QComboBox(pParent)
    265 {
    266 
    267 }
    268 
    269 void UIFileManagerHistoryComboBox::hidePopup()
    270 {
    271     QComboBox::hidePopup();
    272     emit sigHidePopup();
    273 }
    274 
    275 
    276 /*********************************************************************************************************************************
    277 *   UIFileManagerNavigationWidget implementation.                                                                                *
    278 *********************************************************************************************************************************/
    279 
    280 UIFileManagerNavigationWidget::UIFileManagerNavigationWidget(QWidget *pParent /* = 0 */)
    281     :QWidget(pParent)
    282     , m_pContainer(0)
    283     , m_pBreadCrumbs(0)
    284     , m_pHistoryComboBox(0)
    285     , m_pAddressLineEdit(0)
    286     , m_pSwitchButton(0)
    287     , m_pathSeparator('/')
    288 {
    289     prepare();
    290 }
    291 
    292 void UIFileManagerNavigationWidget::setPath(const QString &strLocation)
    293 {
    294     if (m_strCurrentPath == QDir::fromNativeSeparators(strLocation))
    295         return;
    296 
    297     m_strCurrentPath = QDir::fromNativeSeparators(strLocation);
    298 
    299     if (m_pBreadCrumbs)
    300         m_pBreadCrumbs->setPath(strLocation);
    301 
    302     if (m_pHistoryComboBox)
    303     {
    304         QString strNativeLocation(strLocation);
    305         strNativeLocation.replace('/', m_pathSeparator);
    306         int itemIndex = m_pHistoryComboBox->findText(strNativeLocation,
    307                                                       Qt::MatchExactly | Qt::MatchCaseSensitive);
    308         if (itemIndex == -1)
    309         {
    310             m_pHistoryComboBox->insertItem(m_pHistoryComboBox->count(), strNativeLocation);
    311             itemIndex = m_pHistoryComboBox->count() - 1;
    312         }
    313         m_pHistoryComboBox->setCurrentIndex(itemIndex);
    314     }
    315 }
    316 
    317 void UIFileManagerNavigationWidget::reset()
    318 {
    319     if (m_pHistoryComboBox)
    320     {
    321         m_pHistoryComboBox->blockSignals(true);
    322         m_pHistoryComboBox->clear();
    323         m_pHistoryComboBox->blockSignals(false);
    324     }
    325 
    326     if (m_pBreadCrumbs)
    327         m_pBreadCrumbs->setPath(QString());
    328 }
    329 
    330 void UIFileManagerNavigationWidget::setPathSeparator(const QChar &separator)
    331 {
    332     m_pathSeparator = separator;
    333     if (m_pBreadCrumbs)
    334         m_pBreadCrumbs->setPathSeparator(m_pathSeparator);
    335 }
    336 
    337 void UIFileManagerNavigationWidget::prepare()
    338 {
    339     QHBoxLayout *pLayout = new QHBoxLayout;
    340     if (!pLayout)
    341         return;
    342     pLayout->setSpacing(0);
    343     pLayout->setContentsMargins(0, 0, 0, 0);
    344 
    345     m_pContainer = new QStackedWidget;
    346     if (m_pContainer)
    347     {
    348         m_pBreadCrumbs = new UIFileManagerBreadCrumbs;
    349         m_pHistoryComboBox = new UIFileManagerHistoryComboBox;
    350         m_pAddressLineEdit = new QLineEdit;
    351         if (m_pBreadCrumbs && m_pHistoryComboBox)
    352         {
    353             m_pBreadCrumbs->setIndent(0.5 * qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin));
    354             m_pBreadCrumbs->installEventFilter(this);
    355             m_pAddressLineEdit->installEventFilter(this);
    356             connect(m_pBreadCrumbs, &UIFileManagerBreadCrumbs::linkActivated,
    357                     this, &UIFileManagerNavigationWidget::sltHandlePathChange);
    358             connect(m_pHistoryComboBox, &UIFileManagerHistoryComboBox::sigHidePopup,
    359                     this, &UIFileManagerNavigationWidget::sltHandleHidePopup);
    360             connect(m_pHistoryComboBox, &UIFileManagerHistoryComboBox::currentTextChanged,
    361                     this, &UIFileManagerNavigationWidget::sltHandlePathChange);
    362             connect(m_pAddressLineEdit, &QLineEdit::returnPressed,
    363                     this, &UIFileManagerNavigationWidget::sltAddressLineEdited);
    364             m_pContainer->insertWidget(StackedWidgets_BreadCrumbs, m_pBreadCrumbs);
    365             m_pContainer->insertWidget(StackedWidgets_History, m_pHistoryComboBox);
    366             m_pContainer->insertWidget(StackedWidgets_AddressLine, m_pAddressLineEdit);
    367             m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
    368         }
    369         pLayout->addWidget(m_pContainer);
    370     }
    371 
    372     m_pSwitchButton = new QToolButton;
    373     if (m_pSwitchButton)
    374     {
    375         QStyle *pStyle = QApplication::style();
    376         QIcon buttonIcon;
    377         if (pStyle)
    378         {
    379             buttonIcon = pStyle->standardIcon(QStyle::SP_TitleBarUnshadeButton);
    380             m_pSwitchButton->setIcon(buttonIcon);
    381         }
    382         pLayout->addWidget(m_pSwitchButton);
    383         connect(m_pSwitchButton, &QToolButton::clicked,
    384                 this, &UIFileManagerNavigationWidget::sltHandleSwitch);
    385     }
    386     setLayout(pLayout);
    387 }
    388 
    389 bool UIFileManagerNavigationWidget::eventFilter(QObject *pObject, QEvent *pEvent)
    390 {
    391     if (pObject == m_pBreadCrumbs && pEvent && pEvent->type() == QEvent::MouseButtonDblClick)
    392     {
    393         m_pContainer->setCurrentIndex(StackedWidgets_AddressLine);
    394         m_pAddressLineEdit->setText(QDir::toNativeSeparators(m_strCurrentPath));
    395         m_pAddressLineEdit->setFocus();
    396 
    397     }
    398     else if(pObject == m_pAddressLineEdit && pEvent && pEvent->type() == QEvent::FocusOut)
    399         m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
    400 
    401     return QWidget::eventFilter(pObject, pEvent);
    402 }
    403 
    404 void UIFileManagerNavigationWidget::sltHandleHidePopup()
    405 {
    406     m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
    407 }
    408 
    409 void UIFileManagerNavigationWidget::sltHandlePathChange(const QString &strPath)
    410 {
    411     emit sigPathChanged(QDir::fromNativeSeparators(strPath));
    412 }
    413 
    414 void UIFileManagerNavigationWidget::sltHandleSwitch()
    415 {
    416     if (m_pContainer->currentIndex() == StackedWidgets_BreadCrumbs)
    417     {
    418         m_pContainer->setCurrentIndex(StackedWidgets_History);
    419         m_pHistoryComboBox->showPopup();
    420     }
    421     else
    422     {
    423         m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
    424         m_pHistoryComboBox->hidePopup();
    425     }
    426 }
    427 
    428 void UIFileManagerNavigationWidget::sltAddressLineEdited()
    429 {
    430     sigPathChanged(QDir::fromNativeSeparators(m_pAddressLineEdit->text()));
    431 }
    432 
    433 
    434 /*********************************************************************************************************************************
    435 *   UIFileManagerBreadCrumbs implementation.                                                                                     *
    436 *********************************************************************************************************************************/
    437 
    438 UIFileManagerBreadCrumbs::UIFileManagerBreadCrumbs(QWidget *pParent /* = 0 */)
    439     :QLabel(pParent)
    440     , m_pathSeparator('/')
    441 {
    442     float fFontMult = 1.f;
    443     QFont mFont = font();
    444     if (mFont.pixelSize() == -1)
    445         mFont.setPointSize(fFontMult * mFont.pointSize());
    446     else
    447         mFont.setPixelSize(fFontMult * mFont.pixelSize());
    448     setFont(mFont);
    449 
    450     setFrameShape(QFrame::Box);
    451     setLineWidth(1);
    452     setAutoFillBackground(true);
    453     QPalette pal = QApplication::palette();
    454     pal.setColor(QPalette::Active, QPalette::Window, pal.color(QPalette::Active, QPalette::Base));
    455     setPalette(pal);
    456     /* Allow the label become smaller than the current text. calling setpath in resizeEvent truncated the text anyway: */
    457     setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    458 }
    459 
    460 void UIFileManagerBreadCrumbs::setPath(const QString &strPath)
    461 {
    462     m_strPath = strPath;
    463 
    464     const QChar separator('/');
    465     clear();
    466 
    467     if (strPath.isEmpty())
    468         return;
    469 
    470     QStringList folderList = UIPathOperations::pathTrail(strPath);
    471     folderList.push_front(separator);
    472 
    473     QString strLabelText;
    474     QVector<QString> strPathUpto;
    475     strPathUpto.resize(folderList.size());
    476 
    477     for (int i = 0; i < folderList.size(); ++i)
    478     {
    479         QString strFolder = UIPathOperations::removeTrailingDelimiters(folderList.at(i));
    480         if (i != 0)
    481             strPathUpto[i] = strPathUpto[i - 1];
    482         if (i == 0 || i == folderList.size() - 1)
    483             strPathUpto[i].append(QString("%1").arg(strFolder));
    484         else
    485             strPathUpto[i].append(QString("%1%2").arg(strFolder).arg(separator));
    486     }
    487 
    488     int iWidth = 0;
    489     for (int i = folderList.size() - 1; i >= 0; --i)
    490     {
    491         QString strFolder = UIPathOperations::removeTrailingDelimiters(folderList.at(i)).replace('/', m_pathSeparator);
    492         QString strWord = QString("<a href=\"%1\" style=\"color:black;text-decoration:none;\">%2</a>").arg(strPathUpto[i]).arg(strFolder);
    493 
    494         if (i < folderList.size() - 1)
    495         {
    496 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    497             iWidth += fontMetrics().horizontalAdvance(" > ");
    498 #else
    499             iWidth += fontMetrics().width(" > ");
    500 #endif
    501             strWord.append("<b> > </b>");
    502         }
    503 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    504         iWidth += fontMetrics().horizontalAdvance(strFolder);
    505 #else
    506         iWidth += fontMetrics().width(strFolder);
    507 #endif
    508 
    509         if (iWidth < width())
    510             strLabelText.prepend(strWord);
    511     }
    512     setText(strLabelText);
    513 }
    514 
    515 void UIFileManagerBreadCrumbs::setPathSeparator(const QChar &separator)
    516 {
    517     m_pathSeparator = separator;
    518 }
    519 
    520 void UIFileManagerBreadCrumbs::resizeEvent(QResizeEvent *pEvent)
    521 {
    522     /* Truncate the text the way we want: */
    523     setPath(m_strPath);
    524     QLabel::resizeEvent(pEvent);
    525 }
    526156
    527157
     
    816446    }
    817447
    818     m_pNavigationWidget = new UIFileManagerNavigationWidget;
     448    m_pNavigationWidget = new UIFileTableNavigationWidget;
    819449    if (m_pNavigationWidget)
    820450    {
    821451        m_pNavigationWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
    822         connect(m_pNavigationWidget, &UIFileManagerNavigationWidget::sigPathChanged,
     452        connect(m_pNavigationWidget, &UIFileTableNavigationWidget::sigPathChanged,
    823453                this, &UIFileManagerTable::sltHandleNavigationWidgetPathChange);
    824454        m_pMainLayout->addWidget(m_pNavigationWidget, 1, 1, 1, 6);
  • trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerTable.h

    r98103 r100283  
    5151class QAction;
    5252class QFileInfo;
    53 class QComboBox;
    5453class QILabel;
    5554class QILineEdit;
    5655class QGridLayout;
    5756class QSortFilterProxyModel;
    58 class QStackedWidget;
    5957class QTextEdit;
    6058class QHBoxLayout;
     
    6462class UICustomFileSystemModel;
    6563class UICustomFileSystemProxyModel;
    66 class UIFileManagerNavigationWidget;
     64class UIFileTableNavigationWidget;
    6765class UIGuestControlFileView;
    6866class QIToolBar;
     
    310308    UICustomFileSystemProxyModel  *m_pProxyModel;
    311309    /** Contains m_pBreadCrumbsWidget and m_pLocationComboBox. */
    312     UIFileManagerNavigationWidget *m_pNavigationWidget;
     310    UIFileTableNavigationWidget  *m_pNavigationWidget;
    313311
    314312    QILineEdit      *m_pSearchLineEdit;
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIFileTableNavigationWidget.cpp

    r100244 r100283  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIsearchLineEdit class definitions.
     3 * VBox Qt GUI - UIFileTableNavigationWidget class definitions.
    44 */
    55
     
    2626 */
    2727
    28 /* Qt includes */
     28/* Qt includes: */
    2929#include <QApplication>
    30 #include <QPainter>
     30#include <QComboBox>
     31#include <QDir>
     32#include <QFont>
     33#include <QHBoxLayout>
     34#include <QLabel>
     35#include <QLineEdit>
     36#include <QStackedWidget>
     37#include <QToolButton>
    3138
    3239/* GUI includes: */
    33 #include "UISearchLineEdit.h"
    34 
    35 UISearchLineEdit::UISearchLineEdit(QWidget *pParent /* = 0 */)
    36     :QLineEdit(pParent)
    37     , m_iMatchCount(0)
    38     , m_iScrollToIndex(-1)
    39     , m_fMark(true)
    40     , m_unmarkColor(palette().color(QPalette::Base))
    41     , m_markColor(QColor(m_unmarkColor.red(),
    42                          0.7 * m_unmarkColor.green(),
    43                          0.7 * m_unmarkColor.blue()))
    44 {
    45 }
    46 
    47 void UISearchLineEdit::paintEvent(QPaintEvent *pEvent)
    48 {
    49     QLineEdit::paintEvent(pEvent);
    50 
    51     /* No search terms. no search. nothing to show here: */
    52     if (text().isEmpty())
    53     {
    54         colorBackground(false);
     40#include "UIFileTableNavigationWidget.h"
     41#include "UIPathOperations.h"
     42
     43/* Other VBox includes: */
     44#include <iprt/cdefs.h>
     45
     46
     47/*********************************************************************************************************************************
     48*   UIFileManagerHistoryComboBox definition.                                                                                     *
     49*********************************************************************************************************************************/
     50/** A QCombo extension used as location history list in the UIFileTableNavigationWidget. */
     51class UIFileManagerHistoryComboBox : public QComboBox
     52{
     53    Q_OBJECT;
     54
     55signals:
     56
     57    void  sigHidePopup();
     58
     59public:
     60
     61    UIFileManagerHistoryComboBox(QWidget *pParent = 0);
     62    /** Emit sigHidePopup as the popup is hidded. */
     63    virtual void hidePopup() RT_OVERRIDE;
     64};
     65
     66
     67/*********************************************************************************************************************************
     68*   UIFileManagerBreadCrumbs definition.                                                                                         *
     69*********************************************************************************************************************************/
     70/** A QLabel extension. It shows the current path as text and hightligts the folder name
     71  *  as the mouse hovers over it. Clicking on the highlighted folder name make the file table to
     72  *  navigate to that folder. */
     73class UIFileManagerBreadCrumbs : public QLabel
     74{
     75    Q_OBJECT;
     76
     77public:
     78
     79    UIFileManagerBreadCrumbs(QWidget *pParent = 0);
     80    void setPath(const QString &strPath);
     81    void setPathSeparator(const QChar &separator);
     82
     83protected:
     84
     85    virtual void resizeEvent(QResizeEvent *pEvent) RT_OVERRIDE;
     86
     87private:
     88
     89    QString m_strPath;
     90    QChar   m_pathSeparator;
     91};
     92
     93
     94/*********************************************************************************************************************************
     95*   UIFileManagerHistoryComboBox implementation.                                                                                 *
     96*********************************************************************************************************************************/
     97
     98UIFileManagerHistoryComboBox::UIFileManagerHistoryComboBox(QWidget *pParent /* = 0 */)
     99    :QComboBox(pParent)
     100{
     101
     102}
     103
     104void UIFileManagerHistoryComboBox::hidePopup()
     105{
     106    QComboBox::hidePopup();
     107    emit sigHidePopup();
     108}
     109
     110
     111/*********************************************************************************************************************************
     112*   UIFileManagerBreadCrumbs implementation.                                                                                     *
     113*********************************************************************************************************************************/
     114
     115UIFileManagerBreadCrumbs::UIFileManagerBreadCrumbs(QWidget *pParent /* = 0 */)
     116    :QLabel(pParent)
     117    , m_pathSeparator('/')
     118{
     119    float fFontMult = 1.f;
     120    QFont mFont = font();
     121    if (mFont.pixelSize() == -1)
     122        mFont.setPointSize(fFontMult * mFont.pointSize());
     123    else
     124        mFont.setPixelSize(fFontMult * mFont.pixelSize());
     125    setFont(mFont);
     126
     127    setFrameShape(QFrame::Box);
     128    setLineWidth(1);
     129    setAutoFillBackground(true);
     130    QPalette pal = QApplication::palette();
     131    pal.setColor(QPalette::Active, QPalette::Window, pal.color(QPalette::Active, QPalette::Base));
     132    setPalette(pal);
     133    /* Allow the label become smaller than the current text. calling setpath in resizeEvent truncated the text anyway: */
     134    setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
     135}
     136
     137void UIFileManagerBreadCrumbs::setPath(const QString &strPath)
     138{
     139    m_strPath = strPath;
     140
     141    const QChar separator('/');
     142    clear();
     143
     144    if (strPath.isEmpty())
    55145        return;
    56     }
    57     /* Draw the total match count and the current scrolled item's index on the right hand side of the line edit: */
    58     QPainter painter(this);
    59     QFont pfont = font();
    60     QString strText = QString("%1/%2").arg(QString::number(m_iScrollToIndex + 1)).arg(QString::number(m_iMatchCount));
     146
     147    QStringList folderList = UIPathOperations::pathTrail(strPath);
     148    folderList.push_front(separator);
     149
     150    QString strLabelText;
     151    QVector<QString> strPathUpto;
     152    strPathUpto.resize(folderList.size());
     153
     154    for (int i = 0; i < folderList.size(); ++i)
     155    {
     156        QString strFolder = UIPathOperations::removeTrailingDelimiters(folderList.at(i));
     157        if (i != 0)
     158            strPathUpto[i] = strPathUpto[i - 1];
     159        if (i == 0 || i == folderList.size() - 1)
     160            strPathUpto[i].append(QString("%1").arg(strFolder));
     161        else
     162            strPathUpto[i].append(QString("%1%2").arg(strFolder).arg(separator));
     163    }
     164
     165    int iWidth = 0;
     166    for (int i = folderList.size() - 1; i >= 0; --i)
     167    {
     168        QString strFolder = UIPathOperations::removeTrailingDelimiters(folderList.at(i)).replace('/', m_pathSeparator);
     169        QString strWord = QString("<a href=\"%1\" style=\"color:black;text-decoration:none;\">%2</a>").arg(strPathUpto[i]).arg(strFolder);
     170
     171        if (i < folderList.size() - 1)
     172        {
    61173#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
    62     QSize textSize(QApplication::fontMetrics().horizontalAdvance(strText),
    63                    QApplication::fontMetrics().height());
     174            iWidth += fontMetrics().horizontalAdvance(" > ");
    64175#else
    65     QSize textSize(QApplication::fontMetrics().width(strText),
    66                    QApplication::fontMetrics().height());
     176            iWidth += fontMetrics().width(" > ");
    67177#endif
    68 
    69     /* Dont draw anything if we dont have enough space: */
    70     if (textSize.width() > 0.5 * width())
     178            strWord.append("<b> > </b>");
     179        }
     180#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
     181        iWidth += fontMetrics().horizontalAdvance(strFolder);
     182#else
     183        iWidth += fontMetrics().width(strFolder);
     184#endif
     185
     186        if (iWidth < width())
     187            strLabelText.prepend(strWord);
     188    }
     189    setText(strLabelText);
     190}
     191
     192void UIFileManagerBreadCrumbs::setPathSeparator(const QChar &separator)
     193{
     194    m_pathSeparator = separator;
     195}
     196
     197void UIFileManagerBreadCrumbs::resizeEvent(QResizeEvent *pEvent)
     198{
     199    /* Truncate the text the way we want: */
     200    setPath(m_strPath);
     201    QLabel::resizeEvent(pEvent);
     202}
     203
     204
     205/*********************************************************************************************************************************
     206*   UIFileTableNavigationWidget implementation.                                                                                  *
     207*********************************************************************************************************************************/
     208
     209UIFileTableNavigationWidget::UIFileTableNavigationWidget(QWidget *pParent /* = 0 */)
     210    :QWidget(pParent)
     211    , m_pContainer(0)
     212    , m_pBreadCrumbs(0)
     213    , m_pHistoryComboBox(0)
     214    , m_pAddressLineEdit(0)
     215    , m_pSwitchButton(0)
     216    , m_pathSeparator('/')
     217{
     218    prepare();
     219}
     220
     221void UIFileTableNavigationWidget::setPath(const QString &strLocation)
     222{
     223    if (m_strCurrentPath == QDir::fromNativeSeparators(strLocation))
    71224        return;
    72     int iTopMargin = (height() - textSize.height()) / 2;
    73     int iRightMargin = iTopMargin;
    74 
    75     QColor fontColor(Qt::black);
    76     painter.setPen(fontColor);
    77     painter.setFont(pfont);
    78 
    79     painter.drawText(QRect(width() - textSize.width() - iRightMargin, iTopMargin, textSize.width(), textSize.height()),
    80                      Qt::AlignCenter | Qt::AlignVCenter, strText);
    81     colorBackground(m_iMatchCount == 0);
    82 }
    83 
    84 void UISearchLineEdit::setMatchCount(int iMatchCount)
    85 {
    86     if (m_iMatchCount == iMatchCount)
     225
     226    m_strCurrentPath = QDir::fromNativeSeparators(strLocation);
     227
     228    if (m_pBreadCrumbs)
     229        m_pBreadCrumbs->setPath(strLocation);
     230
     231    if (m_pHistoryComboBox)
     232    {
     233        QString strNativeLocation(strLocation);
     234        strNativeLocation.replace('/', m_pathSeparator);
     235        int itemIndex = m_pHistoryComboBox->findText(strNativeLocation,
     236                                                      Qt::MatchExactly | Qt::MatchCaseSensitive);
     237        if (itemIndex == -1)
     238        {
     239            m_pHistoryComboBox->insertItem(m_pHistoryComboBox->count(), strNativeLocation);
     240            itemIndex = m_pHistoryComboBox->count() - 1;
     241        }
     242        m_pHistoryComboBox->setCurrentIndex(itemIndex);
     243    }
     244}
     245
     246void UIFileTableNavigationWidget::reset()
     247{
     248    if (m_pHistoryComboBox)
     249    {
     250        m_pHistoryComboBox->blockSignals(true);
     251        m_pHistoryComboBox->clear();
     252        m_pHistoryComboBox->blockSignals(false);
     253    }
     254
     255    if (m_pBreadCrumbs)
     256        m_pBreadCrumbs->setPath(QString());
     257}
     258
     259void UIFileTableNavigationWidget::setPathSeparator(const QChar &separator)
     260{
     261    m_pathSeparator = separator;
     262    if (m_pBreadCrumbs)
     263        m_pBreadCrumbs->setPathSeparator(m_pathSeparator);
     264}
     265
     266void UIFileTableNavigationWidget::prepare()
     267{
     268    QHBoxLayout *pLayout = new QHBoxLayout;
     269    if (!pLayout)
    87270        return;
    88     m_iMatchCount = iMatchCount;
    89     repaint();
    90 }
    91 
    92 void UISearchLineEdit::setScrollToIndex(int iScrollToIndex)
    93 {
    94     if (m_iScrollToIndex == iScrollToIndex)
    95         return;
    96     m_iScrollToIndex = iScrollToIndex;
    97     repaint();
    98 }
    99 
    100 void UISearchLineEdit::reset()
    101 {
    102     clear();
    103     m_iMatchCount = 0;
    104     m_iScrollToIndex = 0;
    105     colorBackground(false);
    106 }
    107 
    108 void UISearchLineEdit::colorBackground(bool fWarning)
    109 {
    110     QPalette mPalette = QApplication::palette();
    111     /** Make sure we reset color. */
    112     if (!fWarning || !m_fMark)
    113     {
    114         mPalette.setColor(QPalette::Base, m_unmarkColor);
    115         setPalette(mPalette);
    116         return;
    117     }
    118 
    119     if (m_fMark && fWarning)
    120     {
    121         mPalette.setColor(QPalette::Base, m_markColor);
    122         setPalette(mPalette);
    123         return;
    124     }
    125 }
     271    pLayout->setSpacing(0);
     272    pLayout->setContentsMargins(0, 0, 0, 0);
     273
     274    m_pContainer = new QStackedWidget;
     275    if (m_pContainer)
     276    {
     277        m_pBreadCrumbs = new UIFileManagerBreadCrumbs;
     278        m_pHistoryComboBox = new UIFileManagerHistoryComboBox;
     279        m_pAddressLineEdit = new QLineEdit;
     280        if (m_pBreadCrumbs && m_pHistoryComboBox)
     281        {
     282            m_pBreadCrumbs->setIndent(0.5 * qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin));
     283            m_pBreadCrumbs->installEventFilter(this);
     284            m_pAddressLineEdit->installEventFilter(this);
     285            connect(m_pBreadCrumbs, &UIFileManagerBreadCrumbs::linkActivated,
     286                    this, &UIFileTableNavigationWidget::sltHandlePathChange);
     287            connect(m_pHistoryComboBox, &UIFileManagerHistoryComboBox::sigHidePopup,
     288                    this, &UIFileTableNavigationWidget::sltHandleHidePopup);
     289            connect(m_pHistoryComboBox, &UIFileManagerHistoryComboBox::currentTextChanged,
     290                    this, &UIFileTableNavigationWidget::sltHandlePathChange);
     291            connect(m_pAddressLineEdit, &QLineEdit::returnPressed,
     292                    this, &UIFileTableNavigationWidget::sltAddressLineEdited);
     293            m_pContainer->insertWidget(StackedWidgets_BreadCrumbs, m_pBreadCrumbs);
     294            m_pContainer->insertWidget(StackedWidgets_History, m_pHistoryComboBox);
     295            m_pContainer->insertWidget(StackedWidgets_AddressLine, m_pAddressLineEdit);
     296            m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
     297        }
     298        pLayout->addWidget(m_pContainer);
     299    }
     300
     301    m_pSwitchButton = new QToolButton;
     302    if (m_pSwitchButton)
     303    {
     304        QStyle *pStyle = QApplication::style();
     305        QIcon buttonIcon;
     306        if (pStyle)
     307        {
     308            buttonIcon = pStyle->standardIcon(QStyle::SP_TitleBarUnshadeButton);
     309            m_pSwitchButton->setIcon(buttonIcon);
     310        }
     311        pLayout->addWidget(m_pSwitchButton);
     312        connect(m_pSwitchButton, &QToolButton::clicked,
     313                this, &UIFileTableNavigationWidget::sltHandleSwitch);
     314    }
     315    setLayout(pLayout);
     316}
     317
     318bool UIFileTableNavigationWidget::eventFilter(QObject *pObject, QEvent *pEvent)
     319{
     320    if (pObject == m_pBreadCrumbs && pEvent && pEvent->type() == QEvent::MouseButtonDblClick)
     321    {
     322        m_pContainer->setCurrentIndex(StackedWidgets_AddressLine);
     323        m_pAddressLineEdit->setText(QDir::toNativeSeparators(m_strCurrentPath));
     324        m_pAddressLineEdit->setFocus();
     325
     326    }
     327    else if(pObject == m_pAddressLineEdit && pEvent && pEvent->type() == QEvent::FocusOut)
     328        m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
     329
     330    return QWidget::eventFilter(pObject, pEvent);
     331}
     332
     333void UIFileTableNavigationWidget::sltHandleHidePopup()
     334{
     335    m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
     336}
     337
     338void UIFileTableNavigationWidget::sltHandlePathChange(const QString &strPath)
     339{
     340    emit sigPathChanged(QDir::fromNativeSeparators(strPath));
     341}
     342
     343void UIFileTableNavigationWidget::sltHandleSwitch()
     344{
     345    if (m_pContainer->currentIndex() == StackedWidgets_BreadCrumbs)
     346    {
     347        m_pContainer->setCurrentIndex(StackedWidgets_History);
     348        m_pHistoryComboBox->showPopup();
     349    }
     350    else
     351    {
     352        m_pContainer->setCurrentIndex(StackedWidgets_BreadCrumbs);
     353        m_pHistoryComboBox->hidePopup();
     354    }
     355}
     356
     357void UIFileTableNavigationWidget::sltAddressLineEdited()
     358{
     359    sigPathChanged(QDir::fromNativeSeparators(m_pAddressLineEdit->text()));
     360}
     361
     362#include "UIFileTableNavigationWidget.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIFileTableNavigationWidget.h

    r100244 r100283  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UISearchLineEdit class declaration.
     3 * VBox Qt GUI - UIFileTableNavigationWidget class declaration.
    44 */
    55
     
    2626 */
    2727
    28 #ifndef FEQT_INCLUDED_SRC_widgets_UISearchLineEdit_h
    29 #define FEQT_INCLUDED_SRC_widgets_UISearchLineEdit_h
     28#ifndef FEQT_INCLUDED_SRC_widgets_UIFileTableNavigationWidget_h
     29#define FEQT_INCLUDED_SRC_widgets_UIFileTableNavigationWidget_h
    3030#ifndef RT_WITHOUT_PRAGMA_ONCE
    3131# pragma once
     
    3333
    3434
    35 /* Qt includes */
    36 #include <QLineEdit>
     35/* Qt includes: */
     36#include <QWidget>
    3737
    38 /* GUI includes: */
    39 #include "UILibraryDefs.h"
     38/* Forward declarations: */
     39class QLineEdit;
     40class QStackedWidget;
     41class QToolButton;
     42class UIFileManagerBreadCrumbs;
     43class UIFileManagerHistoryComboBox;
    4044
    41 /** A QLineEdit extension with an overlay label drawn on the right hand side of it.
    42   * mostly used for entering a search term and then label show total number of matched items
    43   * and currently selected, scrolled item. */
    44 class SHARED_LIBRARY_STUFF UISearchLineEdit : public QLineEdit
     45/** UIFileTableNavigationWidget contains a UIFileManagerBreadCrumbs, QComboBox for history and a QToolButton.
     46  * basically it is a container for these mentioned widgets. */
     47class UIFileTableNavigationWidget : public QWidget
    4548{
     49    Q_OBJECT;
    4650
    47     Q_OBJECT;
     51signals:
     52
     53    void sigPathChanged(const QString &strPath);
    4854
    4955public:
    5056
    51     UISearchLineEdit(QWidget *pParent = 0);
    52     void setMatchCount(int iMatchCount);
    53     void setScrollToIndex(int iScrollToIndex);
     57    UIFileTableNavigationWidget(QWidget *pParent = 0);
     58    void setPath(const QString &strLocation);
    5459    void reset();
     60    void setPathSeparator(const QChar &separator);
     61    bool eventFilter(QObject *pObject, QEvent *pEvent) override;
    5562
    56 protected:
    57 
    58     virtual void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE;
     63private slots:
     64    void sltHandleSwitch();
     65    /* Makes sure that we switch to breadcrumbs widget as soon as the combo box popup is hidden. */
     66    void sltHandleHidePopup();
     67    void sltHandlePathChange(const QString &strPath);
     68    void sltAddressLineEdited();
    5969
    6070private:
    6171
    62     void colorBackground(bool fWarning);
     72    enum StackedWidgets
     73    {
     74        StackedWidgets_History = 0,
     75        StackedWidgets_BreadCrumbs,
     76        StackedWidgets_AddressLine
     77    };
    6378
    64     /** Stores the total number of matched items. */
    65     int  m_iMatchCount;
    66     /** Stores the index of the currently scrolled/made-visible item withing the list of search results.
    67       * Must be smaller that or equal to m_iMatchCount. */
    68     int  m_iScrollToIndex;
    69     /** When true we color line edit background with a more reddish color. */
    70     bool m_fMark;
    71     QColor m_unmarkColor;
    72     QColor m_markColor;
     79    void prepare();
     80
     81    QStackedWidget               *m_pContainer;
     82    UIFileManagerBreadCrumbs     *m_pBreadCrumbs;
     83    UIFileManagerHistoryComboBox *m_pHistoryComboBox;
     84    QLineEdit                    *m_pAddressLineEdit;
     85    QToolButton                  *m_pSwitchButton;
     86    QChar                         m_pathSeparator;
     87    /* With non-native separators. */
     88    QString                       m_strCurrentPath;
    7389};
    7490
    75 #endif /* !FEQT_INCLUDED_SRC_widgets_UISearchLineEdit_h */
     91
     92#endif /* !FEQT_INCLUDED_SRC_widgets_UIFileTableNavigationWidget_h */
Note: See TracChangeset for help on using the changeset viewer.

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