VirtualBox

Changeset 77723 in vbox


Ignore:
Timestamp:
Mar 15, 2019 12:52:07 PM (6 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9378. Implementing search resul navigation.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItem.cpp

    r77701 r77723  
    463463void UIChooserItem::makeSureItsVisible()
    464464{
    465     /* If item is not visible: */
     465    /* Get parrent item: */
     466    UIChooserItemGroup *pParentItem = parentItem()->toGroupItem();
     467    if (!pParentItem)
     468        return;
     469    /* If item is not visible. That is all the parent group(s) are opened (expanded): */
    466470    if (!isVisible())
    467471    {
    468         /* Get parrent item, assert if can't: */
    469         if (UIChooserItemGroup *pParentItem = parentItem()->toGroupItem())
    470         {
    471             /* We should make parent visible: */
    472             pParentItem->makeSureItsVisible();
    473             /* And make sure its opened: */
    474             if (pParentItem->isClosed())
    475                 pParentItem->open(false);
    476         }
    477     }
     472        /* We should make parent visible: */
     473        pParentItem->makeSureItsVisible();
     474        /* And make sure its opened: */
     475        if (pParentItem->isClosed())
     476            pParentItem->open(false);
     477    }
     478    /* Make sure we scroll to the item's rectangle: */
     479    pParentItem->makeSureItemIsVisible(this);
    478480}
    479481
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGroup.cpp

    r77654 r77723  
    142142{
    143143    return "UIChooserItemGroup";
     144}
     145
     146void UIChooserItemGroup::makeSureItemIsVisible(UIChooserItem *pItem)
     147{
     148    /* Make sure item exists: */
     149    AssertPtrReturnVoid(pItem);
     150
     151    /* Convert child rectangle to local coordinates for this group. This also
     152     * works for a child at any sub-level, doesn't necessary of this group. */
     153    const QPointF positionInScene = pItem->mapToScene(QPointF(0, 0));
     154    const QPointF positionInGroup = mapFromScene(positionInScene);
     155    const QRectF itemRectInGroup = QRectF(positionInGroup, pItem->size());
     156    m_pScrollArea->makeSureRectIsVisible(itemRectInGroup);
    144157}
    145158
     
    695708    /* Else call to base-class: */
    696709    return UIChooserItem::sizeHint(enmWhich, constraint);
    697 }
    698 
    699 void UIChooserItemGroup::makeSureItemIsVisible(UIChooserItem *pItem)
    700 {
    701     /* Make sure item exists: */
    702     AssertPtrReturnVoid(pItem);
    703 
    704     /* Convert child rectangle to local coordinates for this group. This also
    705      * works for a child at any sub-level, doesn't necessary of this group. */
    706     const QPointF positionInScene = pItem->mapToScene(QPointF(0, 0));
    707     const QPointF positionInGroup = mapFromScene(positionInScene);
    708     const QRectF itemRectInGroup = QRectF(positionInGroup, pItem->size());
    709     m_pScrollArea->makeSureRectIsVisible(itemRectInGroup);
    710710}
    711711
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGroup.h

    r77638 r77723  
    8686        /** Class-name used for drag&drop mime-data format. */
    8787        static QString className();
     88        /** Makes sure passed child @a pItem is visible. */
     89        virtual void makeSureItemIsVisible(UIChooserItem *pItem) /* override */;
    8890    /** @} */
    8991
     
    168170    /** @name Navigation stuff.
    169171      * @{ */
    170         /** Makes sure passed child @a pItem is visible. */
    171         virtual void makeSureItemIsVisible(UIChooserItem *pItem) /* override */;
    172 
    173172        /** Returns pixmap item representation. */
    174173        virtual QPixmap toPixmap() /* override */;
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserModel.cpp

    r77701 r77723  
    6868    , m_pContextMenuGroup(0)
    6969    , m_pContextMenuMachine(0)
     70    , m_iCurrentScrolledIndex(-1)
    7071    , m_pInvisibleRootNode(0)
    7172    , m_iScrollingTokenSize(30)
     
    131132{
    132133    return m_pScene;
     134}
     135
     136UIChooserView *UIChooserModel::view()
     137{
     138    if (!scene())
     139        return 0;
     140    UIChooserView *pChooserView = qobject_cast<UIChooserView*>(scene()->views()[0]);
     141    return pChooserView;
    133142}
    134143
     
    426435
    427436    /* If dialog is visible and item exists => make it visible as well: */
    428     if (scene()->views()[0]->window()->isVisible() && pItem)
    429         root()->makeSureItemIsVisible(pItem);
     437    if (view() && view()->window() && root())
     438        if (view()->window()->isVisible() && pItem)
     439            root()->makeSureItemIsVisible(pItem);
    430440}
    431441
     
    459469    /* Currently we perform the search only for machines. when this to be changed make sure the disabled flags
    460470       of the other item types are also managed correctly: */
     471
     472    QList<UIChooserNode*> allNodes = resetSearch();
     473    if (strSearchTerm.isEmpty())
     474        return;
     475
     476    m_pInvisibleRootNode->searchForNodes(strSearchTerm, iItemSearchFlags, m_searchResults);
     477
     478    foreach (UIChooserNode* pNode, allNodes)
     479    {
     480        if (!pNode)
     481            continue;
     482        pNode->setDisabled(!m_searchResults.contains(pNode));
     483    }
     484
     485    scrollToSearchResult(true);
     486}
     487
     488QList<UIChooserNode*> UIChooserModel::resetSearch()
     489{
    461490    QList<UIChooserNode*> allNodes;
    462491    /* Calling UIChooserNode::searchForNodes with an empty search string returns a list all nodes (of the whole treee) of the required type: */
    463     m_pInvisibleRootNode->searchForNodes(QString(), iItemSearchFlags, allNodes);
     492    m_pInvisibleRootNode->searchForNodes(QString(), UIChooserItemSearchFlag_Machine, allNodes);
    464493
    465494    /* Reset the disabled flag of the node items first. */
     
    470499        pNode->setDisabled(false);
    471500    }
    472 
    473     if (strSearchTerm.isEmpty())
    474         return;
    475 
    476     QList<UIChooserNode*> matchedNodes;
    477     m_pInvisibleRootNode->searchForNodes(strSearchTerm, iItemSearchFlags, matchedNodes);
    478 
    479     foreach (UIChooserNode* pNode, allNodes)
    480     {
    481         if (!pNode)
    482             continue;
    483         pNode->setDisabled(!matchedNodes.contains(pNode));
    484     }
     501    /* Reset the search result relate data: */
     502    m_searchResults.clear();
     503    m_iCurrentScrolledIndex = -1;
     504    return allNodes;
     505}
     506
     507void UIChooserModel::scrollToSearchResult(bool fIsNext)
     508{
     509    if (m_searchResults.isEmpty())
     510    {
     511        m_iCurrentScrolledIndex = -1;
     512        if (view())
     513            view()->setSearchResultsCount(m_searchResults.size(), m_iCurrentScrolledIndex);
     514        return;
     515    }
     516
     517    if (fIsNext)
     518    {
     519        if (++m_iCurrentScrolledIndex >= m_searchResults.size())
     520            m_iCurrentScrolledIndex = 0;
     521    }
     522    else
     523    {
     524        if (m_iCurrentScrolledIndex < 0)
     525            m_iCurrentScrolledIndex = m_searchResults.size() - 1;
     526    }
     527
     528    if (m_searchResults.at(m_iCurrentScrolledIndex))
     529    {
     530        UIChooserItem *pItem = m_searchResults.at(m_iCurrentScrolledIndex)->item();
     531        if (pItem)
     532        {
     533            pItem->makeSureItsVisible();
     534        }
     535    }
     536
     537
     538    /* Update the search widget's match count(s): */
     539    if (view())
     540        view()->setSearchResultsCount(m_searchResults.size(), m_iCurrentScrolledIndex);
     541
    485542}
    486543
     
    619676void UIChooserModel::updateLayout()
    620677{
     678    if (!view() || !root())
     679        return;
     680
    621681    /* Initialize variables: */
    622     const QSize viewportSize = scene()->views()[0]->size();
     682    const QSize viewportSize = view()->size();
    623683    const int iViewportWidth = viewportSize.width();
    624684    const int iViewportHeight = viewportSize.height();
     
    814874void UIChooserModel::sltShowHideSearchWidget()
    815875{
    816     UIChooserView *pChooserView = qobject_cast<UIChooserView*>(scene()->views()[0]);
     876    UIChooserView *pChooserView = view();
    817877    if (!pChooserView)
    818878        return;
     
    11821242
    11831243    /* Get view/scrollbar: */
    1184     QGraphicsView *pView = scene()->views()[0];
     1244    QGraphicsView *pView = view();
    11851245    QScrollBar *pVerticalScrollBar = pView->verticalScrollBar();
    11861246
     
    19472007    /* Install root as event-filter for scene view,
    19482008     * we need QEvent::Scroll events from it: */
    1949     root()->installEventFilterHelper(scene()->views()[0]);
     2009    root()->installEventFilterHelper(view());
    19502010}
    19512011
     
    20492109
    20502110    /* Get view: */
    2051     QGraphicsView *pView = scene()->views()[0];
     2111    QGraphicsView *pView = view();
    20522112
    20532113    /* Check scroll-area: */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserModel.h

    r77683 r77723  
    4242class UIChooserItem;
    4343class UIChooserNode;
     44class UIChooserView;
    4445class UIVirtualMachineItem;
    4546class CMachine;
     
    191192        /** Performs a search starting from the m_pInvisibleRootNode. */
    192193        void performSearch(const QString &strSearchTerm, int iItemSearchFlags);
     194        /** Clean the search result data members and disables item's visual effects. Also returns a list of
     195          * all nodes which may be utilized by the calling code. */
     196        QList<UIChooserNode*> resetSearch();
     197        void scrollToSearchResult(bool fIsNext);
    193198    /** @} */
    194199
     
    359364        /** Popups context-menu of certain @a enmType in specified @a point. */
    360365        void popupContextMenu(UIGraphicsSelectorContextMenuType enmType, QPoint point);
     366        /** Returns the reference of the first view of the scene(). */
     367        UIChooserView *view();
    361368    /** @} */
    362369
     
    464471    /** @} */
    465472
     473    /** @name Virtual Machine/Group search stuff.
     474      * @{ */
     475        /** Stores the results of the current search. */
     476        QList<UIChooserNode*> m_searchResults;
     477        /** Stores the index (within the m_searchResults) of the currently scrolled item. */
     478        int m_iCurrentScrolledIndex;
     479    /** @} */
     480
    466481    /** @name Children stuff.
    467482      * @{ */
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserSearchWidget.cpp

    r77683 r77723  
    2121/* GUI includes: */
    2222#include "QILineEdit.h"
     23#include "QIToolButton.h"
    2324#include "UIChooserDefs.h"
    2425#include "UIChooserSearchWidget.h"
     26#include "UIIconPool.h"
     27#include "UISearchLineEdit.h"
    2528
    2629UIChooserSearchWidget::UIChooserSearchWidget(QWidget *pParent)
     
    2831    , m_pLineEdit(0)
    2932    , m_pMainLayout(0)
    30 
     33    , m_pScrollToNextMatchButton(0)
     34    , m_pScrollToPreviousMatchButton(0)
    3135{
    3236    prepareWidgets();
    3337    prepareConnections();
     38}
     39
     40void UIChooserSearchWidget::setMatchCount(int iMatchCount)
     41{
     42    if (!m_pLineEdit)
     43        return;
     44    m_pLineEdit->setMatchCount(iMatchCount);
     45}
     46
     47void UIChooserSearchWidget::setScroolToIndex(int iScrollToIndex)
     48{
     49    if (!m_pLineEdit)
     50        return;
     51    m_pLineEdit->setScroolToIndex(iScrollToIndex);
    3452}
    3553
     
    4159    m_pMainLayout->setSpacing(2);
    4260    m_pMainLayout->setContentsMargins(0, 0, 0, 0);
    43     m_pLineEdit = new QILineEdit;
     61    m_pLineEdit = new UISearchLineEdit;
    4462    if (m_pLineEdit)
    4563    {
    4664        m_pMainLayout->addWidget(m_pLineEdit);
     65        m_pLineEdit->installEventFilter(this);
     66    }
     67
     68    m_pScrollToPreviousMatchButton = new QIToolButton;
     69    if (m_pScrollToPreviousMatchButton)
     70    {
     71        m_pScrollToPreviousMatchButton->setIcon(UIIconPool::iconSet(":/log_viewer_search_backward_16px.png", ":/log_viewer_search_backward_disabled_16px.png"));
     72        m_pMainLayout->addWidget(m_pScrollToPreviousMatchButton);
     73    }
     74    m_pScrollToNextMatchButton = new QIToolButton;
     75    if (m_pScrollToNextMatchButton)
     76    {
     77        m_pScrollToNextMatchButton->setIcon(UIIconPool::iconSet(":/log_viewer_search_forward_16px.png", ":/log_viewer_search_forward_disabled_16px.png"));
     78        m_pMainLayout->addWidget(m_pScrollToNextMatchButton);
    4779    }
    4880
     
    5789                this, &UIChooserSearchWidget::sltHandleSearchTermChange);
    5890    }
     91    if (m_pScrollToPreviousMatchButton)
     92        connect(m_pScrollToPreviousMatchButton, &QIToolButton::clicked, this, &UIChooserSearchWidget::sltHandleScroolToButtonClick);
     93    if (m_pScrollToNextMatchButton)
     94        connect(m_pScrollToNextMatchButton, &QIToolButton::clicked, this, &UIChooserSearchWidget::sltHandleScroolToButtonClick);
    5995}
    6096
     
    66102}
    67103
     104void UIChooserSearchWidget::hideEvent(QHideEvent *pEvent)
     105{
     106    Q_UNUSED(pEvent);
     107    if (m_pLineEdit)
     108        m_pLineEdit->clear();
     109}
     110
    68111void UIChooserSearchWidget::retranslateUi()
    69112{
     113}
     114
     115bool UIChooserSearchWidget::eventFilter(QObject *pWatched, QEvent *pEvent)
     116{
     117    Q_UNUSED(pWatched);
     118    if (pEvent->type() == QEvent::KeyPress)
     119    {
     120        QKeyEvent *pKeyEvent = dynamic_cast<QKeyEvent*>(pEvent);
     121        if (pKeyEvent)
     122        {
     123            if (pKeyEvent->key() == Qt::Key_Escape)
     124                emit sigToggleVisibility(false);
     125        }
     126    }
     127    return false;
    70128}
    71129
     
    74132    emit sigRedoSearch(strSearchTerm, UIChooserItemSearchFlag_Machine);
    75133}
     134
     135void UIChooserSearchWidget::sltHandleScroolToButtonClick()
     136{
     137    if (sender() == m_pScrollToNextMatchButton)
     138        emit sigScrollToMatch(true);
     139    else if (sender() == m_pScrollToPreviousMatchButton)
     140        emit sigScrollToMatch(false);
     141}
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserSearchWidget.h

    r77683 r77723  
    3131class QHBoxLayout;
    3232class QILineEdit;
     33class QIToolButton;
     34class UISearchLineEdit;
    3335
    3436/** QWidget extension used as virtual machine search widget in the VM Chooser-pane. */
     
    4042
    4143    void sigRedoSearch(const QString &strSearchTerm, int iItemSearchFlags);
     44    /** Is being signalled as next/prev tool buttons are pressed. @a fIsNext is true
     45      * for the next and false for the previous case. */
     46    void sigScrollToMatch(bool fIsNext);
     47    /** Is used for signalling show/hide event from this to parent. */
     48    void sigToggleVisibility(bool fIsVisible);
    4249
    4350public:
    4451
    4552    UIChooserSearchWidget(QWidget *pParent);
     53    void setMatchCount(int iMatchCount);
     54    void setScroolToIndex(int iScrollToIndex);
    4655
    4756protected:
    4857
    49     void showEvent(QShowEvent *pEvent);
     58    virtual void showEvent(QShowEvent *pEvent) /* override */;
     59    virtual void hideEvent(QHideEvent *pEvent) /* override */;
    5060    virtual void retranslateUi() /* override */;
     61    virtual bool eventFilter(QObject *pWatched, QEvent *pEvent) /* override */;
    5162
    5263public slots:
     
    5566
    5667    void sltHandleSearchTermChange(const QString &strSearchTerm);
     68    void sltHandleScroolToButtonClick();
    5769
    5870private:
     
    6173    void prepareConnections();
    6274
    63     QILineEdit  *m_pLineEdit;
    64     QHBoxLayout *m_pMainLayout;
     75    UISearchLineEdit  *m_pLineEdit;
     76    QHBoxLayout       *m_pMainLayout;
     77    QIToolButton      *m_pScrollToNextMatchButton;
     78    QIToolButton      *m_pScrollToPreviousMatchButton;
    6579};
    6680
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserView.cpp

    r77686 r77723  
    108108    m_pSearchWidget->setVisible(!m_pSearchWidget->isVisible());
    109109    if (m_pSearchWidget->isVisible())
    110         updateSearchWidget();
     110        updateSearchWidgetGeometry();
     111}
     112
     113void UIChooserView::setSearchResultsCount(int iTotalMacthCount, int iCurrentlyScrolledItemIndex)
     114{
     115    if (!m_pSearchWidget)
     116        return;
     117    m_pSearchWidget->setMatchCount(iTotalMacthCount);
     118    m_pSearchWidget->setScroolToIndex(iCurrentlyScrolledItemIndex);
    111119}
    112120
     
    135143    if (!pModel)
    136144        return;
    137 
    138145    pModel->performSearch(strSearchTerm, iItemSearchFlags);
     146}
     147
     148void UIChooserView::sltHandleScrollToSearchResult(bool fIsNext)
     149{
     150    UIChooserModel *pModel =  m_pChooser->model();
     151    if (!pModel)
     152        return;
     153    pModel->scrollToSearchResult(fIsNext);
     154}
     155
     156void UIChooserView::sltHandleSearchWidgetVisibilityToggle(bool fIsVisible)
     157{
     158    if (!m_pSearchWidget)
     159        return;
     160    if (m_pSearchWidget->isVisible() == fIsVisible)
     161        return;
     162    m_pSearchWidget->setVisible(fIsVisible);
     163    UIChooserModel *pModel =  m_pChooser->model();
     164    if (!pModel)
     165        return;
     166    pModel->resetSearch();
    139167}
    140168
     
    169197    connect(m_pSearchWidget, &UIChooserSearchWidget::sigRedoSearch,
    170198                this, &UIChooserView::sltRedoSearch);
     199    connect(m_pSearchWidget, &UIChooserSearchWidget::sigScrollToMatch,
     200                this, &UIChooserView::sltHandleScrollToSearchResult);
     201    connect(m_pSearchWidget, &UIChooserSearchWidget::sigToggleVisibility,
     202                this, &UIChooserView::sltHandleSearchWidgetVisibilityToggle);
    171203
    172204    /* Update scene-rect: */
     
    174206
    175207    /* Update the location and size of the search widget: */
    176     updateSearchWidget();
     208    updateSearchWidgetGeometry();
    177209
    178210    /* Apply language settings: */
     
    198230    /* Update scene-rect: */
    199231    updateSceneRect();
    200     updateSearchWidget();
     232    updateSearchWidgetGeometry();
    201233}
    202234
     
    206238}
    207239
    208 void UIChooserView::updateSearchWidget()
     240void UIChooserView::updateSearchWidgetGeometry()
    209241{
    210242    if (!m_pSearchWidget || !m_pSearchWidget->isVisible())
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserView.h

    r77683 r77723  
    5050        /** Returns the chooser reference. */
    5151        UIChooser *chooser() const { return m_pChooser; }
     52    /** @} */
     53
     54    /** @name Virtual Machine search stuff.
     55      * @{ */
    5256        /** Shows/hides machine search widget. */
    5357        void toggleSearchWidget();
     58        /** Updates the search widget's counts. */
     59        void setSearchResultsCount(int iTotalMacthCount, int iCurrentlyScrolledItemIndex);
    5460    /** @} */
    5561
     
    7581private slots:
    7682
     83    /** Is connected to search widget's signal for a new search. */
    7784    void sltRedoSearch(const QString &strSearchTerm, int iItemSearchFlags);
     85    /** Is connected to search widget's scroll to next/prev search result signal. */
     86    void sltHandleScrollToSearchResult(bool fIsNext);
     87    void sltHandleSearchWidgetVisibilityToggle(bool fIsVisible);
    7888
    7989private:
     
    91101        /** Updates scene rectangle. */
    92102        void updateSceneRect();
    93         /** Updates search widget's geometry. */
    94         void updateSearchWidget();
    95103    /** @} */
    96104
     105    /** @name Virtual Machine search stuff.
     106      * @{ */
     107        /** Updates search widget's geometry. */
     108        void updateSearchWidgetGeometry();
     109    /** @} */
    97110
    98111    /** @name General stuff.
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UISearchLineEdit.cpp

    r77702 r77723  
    3434    QLineEdit::paintEvent(pEvent);
    3535
    36     /* No search terms. no search. nothing to show here. mone along please: */
     36    /* No search terms. no search. nothing to show here: */
    3737    if (text().isEmpty())
    3838        return;
    3939
     40    /* Draw the total match count and the current scrolled item's index on the right hand side of the line edit: */
    4041    QPainter painter(this);
    4142    QFont pfont = font();
     
    4950    int iTopMargin = (height() - textSize.height()) / 2;
    5051    int iRightMargin = iTopMargin;
    51 
    5252
    5353    QColor fontColor(Qt::darkGray);
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UISearchLineEdit.h

    r77702 r77723  
    3232  * mostly used for entering a search term and then label show total number of matched items
    3333  * and currently selected, scrolled item. */
    34 class SHARED_LIBRARY_STUFF
    35 UISearchLineEdit : public QLineEdit
     34class SHARED_LIBRARY_STUFF UISearchLineEdit : public QLineEdit
    3635{
    3736
     
    5049private:
    5150
     51    /** Stores the total number of matched items. */
    5252    int m_iMatchCount;
     53    /** Stores the index of the currently scrolled/made-visible item withing the list of search results.
     54      * Must be smaller that or equal to m_iMatchCount. */
    5355    int m_iScrollToIndex;
    5456};
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