VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumSearchWidget.cpp

Last change on this file was 104226, checked in by vboxsync, 6 weeks ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in medium manager related classes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.6 KB
Line 
1/* $Id: UIMediumSearchWidget.cpp 104226 2024-04-08 12:07:43Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMediumSearchWidget class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QComboBox>
30#include <QHBoxLayout>
31#include <QLineEdit>
32#include <QPushButton>
33#include <QPainter>
34#include <QRegularExpression>
35
36/* GUI includes: */
37#include "QIToolButton.h"
38#include "QITreeWidget.h"
39#include "UIIconPool.h"
40#include "UIMediumItem.h"
41#include "UIMediumSearchWidget.h"
42#include "UISearchLineEdit.h"
43#include "UITranslationEventListener.h"
44
45#ifdef VBOX_WS_MAC
46# include "UIWindowMenuManager.h"
47#endif /* VBOX_WS_MAC */
48
49
50/*********************************************************************************************************************************
51* FilterByNameUUID definition/implementation. *
52*********************************************************************************************************************************/
53
54class FilterByNameUUID : public QITreeWidgetItemFilter
55{
56
57public:
58
59 FilterByNameUUID(UIMediumSearchWidget::SearchType enmSearchType, const QString &strSearchTerm)
60 : m_enmSearchType(enmSearchType)
61 , m_strSearchTerm(strSearchTerm){}
62 virtual ~FilterByNameUUID(){}
63 virtual bool operator()(QTreeWidgetItem *pItem) const RT_OVERRIDE RT_FINAL
64 {
65 if (!pItem || m_strSearchTerm.isEmpty())
66 return false;
67 if (pItem->type() != QITreeWidgetItem::ItemType)
68 return false;
69
70 UIMediumItem *pMediumItem = dynamic_cast<UIMediumItem*>(pItem);
71 if (!pMediumItem)
72 return false;
73 QString strValue;
74 if (m_enmSearchType == UIMediumSearchWidget::SearchByUUID)
75 strValue = pMediumItem->id().toString();
76 else if (m_enmSearchType == UIMediumSearchWidget::SearchByName)
77 strValue = pMediumItem->name();
78 else
79 return false;
80 QRegularExpression searchRegEx = QRegularExpression::fromWildcard(m_strSearchTerm, Qt::CaseInsensitive,
81 QRegularExpression::UnanchoredWildcardConversion);
82 if (strValue.contains(searchRegEx))
83 return true;
84 return false;
85 }
86
87private:
88
89 UIMediumSearchWidget::SearchType m_enmSearchType;
90 QString m_strSearchTerm;
91};
92
93
94/*********************************************************************************************************************************
95* UIMediumSearchWidget implementation . *
96*********************************************************************************************************************************/
97
98UIMediumSearchWidget::UIMediumSearchWidget(QWidget *pParent)
99 : QWidget(pParent)
100 , m_pSearchComboxBox(0)
101 , m_pSearchTermLineEdit(0)
102 , m_pShowNextMatchButton(0)
103 , m_pShowPreviousMatchButton(0)
104 , m_pTreeWidget(0)
105 , m_iScrollToIndex(-1)
106{
107 prepareWidgets();
108}
109
110void UIMediumSearchWidget::prepareWidgets()
111{
112 QHBoxLayout *pLayout = new QHBoxLayout;
113 setLayout(pLayout);
114 pLayout->setContentsMargins(0, 0, 0, 0);
115 pLayout->setSpacing(0);
116
117 m_pSearchComboxBox = new QComboBox;
118 if (m_pSearchComboxBox)
119 {
120 m_pSearchComboxBox->setEditable(false);
121 m_pSearchComboxBox->insertItem(SearchByName, "Search By Name");
122 m_pSearchComboxBox->insertItem(SearchByUUID, "Search By UUID");
123 connect(m_pSearchComboxBox, &QComboBox::currentIndexChanged,
124 this, &UIMediumSearchWidget::sigPerformSearch);
125 pLayout->addWidget(m_pSearchComboxBox);
126 }
127
128 m_pSearchTermLineEdit = new UISearchLineEdit;
129 if (m_pSearchTermLineEdit)
130 {
131 m_pSearchTermLineEdit->setClearButtonEnabled(false);
132 pLayout->addWidget(m_pSearchTermLineEdit);
133 connect(m_pSearchTermLineEdit, &QLineEdit::textChanged,
134 this, &UIMediumSearchWidget::sigPerformSearch);
135 }
136
137 m_pShowPreviousMatchButton = new QIToolButton;
138 if (m_pShowPreviousMatchButton)
139 {
140 m_pShowPreviousMatchButton->setIcon(UIIconPool::iconSet(":/log_viewer_search_backward_16px.png", ":/log_viewer_search_backward_disabled_16px.png"));
141 connect(m_pShowPreviousMatchButton, &QIToolButton::clicked, this, &UIMediumSearchWidget::sltShowPreviousMatchingItem);
142 pLayout->addWidget(m_pShowPreviousMatchButton);
143 }
144 m_pShowNextMatchButton = new QIToolButton;
145 if (m_pShowNextMatchButton)
146 {
147 m_pShowNextMatchButton->setIcon(UIIconPool::iconSet(":/log_viewer_search_forward_16px.png", ":/log_viewer_search_forward_disabled_16px.png"));
148 connect(m_pShowNextMatchButton, &QIToolButton::clicked, this, &UIMediumSearchWidget:: sltShowNextMatchingItem);
149 pLayout->addWidget(m_pShowNextMatchButton);
150 }
151
152 sltRetranslateUI();
153
154 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
155 this, &UIMediumSearchWidget::sltRetranslateUI);
156}
157
158UIMediumSearchWidget::SearchType UIMediumSearchWidget::searchType() const
159{
160 if (!m_pSearchComboxBox || m_pSearchComboxBox->currentIndex() >= static_cast<int>(SearchByMax))
161 return SearchByMax;
162 return static_cast<SearchType>(m_pSearchComboxBox->currentIndex());
163}
164
165QString UIMediumSearchWidget::searchTerm() const
166{
167 if (!m_pSearchTermLineEdit)
168 return QString();
169 return m_pSearchTermLineEdit->text();
170}
171
172void UIMediumSearchWidget::search(QITreeWidget* pTreeWidget, bool fGotoNext /* = true */)
173{
174 if (!pTreeWidget)
175 return;
176
177 m_pTreeWidget = pTreeWidget;
178 QList<QTreeWidgetItem*> allItems = pTreeWidget->filterItems(QITreeWidgetItemFilter());
179 markUnmarkItems(allItems, false);
180
181 m_matchedItemList = pTreeWidget->filterItems(FilterByNameUUID(searchType(), searchTerm()));
182 markUnmarkItems(m_matchedItemList, true);
183 if (!m_matchedItemList.isEmpty())
184 {
185 m_iScrollToIndex = -1;
186 if (fGotoNext)
187 goToNextPrevious(true);
188 }
189 else
190 m_iScrollToIndex = -1;
191 updateSearchLineEdit(m_matchedItemList.size(), m_iScrollToIndex);
192}
193
194void UIMediumSearchWidget::sltRetranslateUI()
195{
196 if (m_pSearchComboxBox)
197 {
198 m_pSearchComboxBox->setItemText(SearchByName, tr("Search By Name"));
199 m_pSearchComboxBox->setItemText(SearchByUUID, tr("Search By UUID"));
200 m_pSearchComboxBox->setToolTip(tr("Select the search type"));
201 }
202 if (m_pSearchTermLineEdit)
203 m_pSearchTermLineEdit->setToolTip(tr("Enter the search term and press Enter/Return"));
204 if (m_pShowPreviousMatchButton)
205 m_pShowPreviousMatchButton->setToolTip(tr("Show the previous item matching the search term"));
206 if (m_pShowNextMatchButton)
207 m_pShowNextMatchButton->setToolTip(tr("Show the next item matching the search term"));
208}
209
210void UIMediumSearchWidget::showEvent(QShowEvent *pEvent)
211{
212 if (m_pSearchTermLineEdit)
213 m_pSearchTermLineEdit->setFocus();
214 QWidget::showEvent(pEvent);
215}
216
217void UIMediumSearchWidget::markUnmarkItems(QList<QTreeWidgetItem*> &itemList, bool fMark)
218{
219 foreach (QTreeWidgetItem* pItem, itemList)
220 {
221 if (pItem->type() != QITreeWidgetItem::ItemType)
222 continue;
223 UIMediumItem *pMediumItem = static_cast<UIMediumItem*>(pItem);
224 if (!pMediumItem)
225 continue;
226 QFont font = pMediumItem->font(0);
227 font.setBold(fMark);
228 pMediumItem->setFont(0, font);
229
230 if (!fMark)
231 setUnderlineItemText(pMediumItem, false);
232 }
233}
234
235void UIMediumSearchWidget::setUnderlineItemText(QTreeWidgetItem* pItem, bool fUnderline)
236{
237 if (!pItem)
238 return;
239 QFont font = pItem->font(0);
240 font.setUnderline(fUnderline);
241 pItem->setFont(0, font);
242}
243
244void UIMediumSearchWidget::goToNextPrevious(bool fNext)
245{
246 if (!m_pTreeWidget || m_matchedItemList.isEmpty())
247 return;
248
249 if (m_iScrollToIndex >= 0 && m_iScrollToIndex < m_matchedItemList.size())
250 setUnderlineItemText(m_matchedItemList[m_iScrollToIndex], false);
251
252 if (fNext)
253 ++m_iScrollToIndex;
254 else
255 --m_iScrollToIndex;
256
257 if (m_iScrollToIndex >= m_matchedItemList.size())
258 m_iScrollToIndex = 0;
259 if (m_iScrollToIndex < 0)
260 m_iScrollToIndex = m_matchedItemList.size() - 1;
261
262 setUnderlineItemText(m_matchedItemList[m_iScrollToIndex], true);
263 m_pTreeWidget->scrollTo(m_pTreeWidget->itemIndex(m_matchedItemList[m_iScrollToIndex]), QAbstractItemView::PositionAtCenter);
264 updateSearchLineEdit(m_matchedItemList.size(), m_iScrollToIndex);
265}
266
267void UIMediumSearchWidget::sltShowNextMatchingItem()
268{
269 goToNextPrevious(true);
270}
271
272void UIMediumSearchWidget::sltShowPreviousMatchingItem()
273{
274 goToNextPrevious(false);
275}
276
277void UIMediumSearchWidget::updateSearchLineEdit(int iMatchCount, int iScrollToIndex)
278{
279 if (!m_pSearchTermLineEdit)
280 return;
281 m_pSearchTermLineEdit->setMatchCount(iMatchCount);
282 m_pSearchTermLineEdit->setScrollToIndex(iScrollToIndex);
283}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use