Changeset 70487 in vbox
- Timestamp:
- Jan 8, 2018 8:04:54 PM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 5 edited
- 2 copied
-
Makefile.kmk (modified) (2 diffs)
-
src/logviewer/UIVMLogViewerBookmarksPanel.cpp (copied) (copied from trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp ) (9 diffs)
-
src/logviewer/UIVMLogViewerBookmarksPanel.h (copied) (copied from trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.h ) (6 diffs)
-
src/logviewer/UIVMLogViewerFilterPanel.cpp (modified) (1 diff)
-
src/logviewer/UIVMLogViewerWidget.cpp (modified) (28 diffs)
-
src/logviewer/UIVMLogViewerWidget.h (modified) (6 diffs)
-
src/medium/UIMediumManager.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r70466 r70487 335 335 src/hostnetwork/UIHostNetworkDetailsWidget.h \ 336 336 src/hostnetwork/UIHostNetworkManager.h \ 337 src/logviewer/UIVMLogViewerBookmarksPanel.h \ 337 338 src/logviewer/UIVMLogViewerDialog.h \ 338 339 src/logviewer/UIVMLogViewerFilterPanel.h \ … … 651 652 src/hostnetwork/UIHostNetworkManager.cpp \ 652 653 src/hostnetwork/UIHostNetworkUtils.cpp \ 654 src/logviewer/UIVMLogViewerBookmarksPanel.cpp \ 653 655 src/logviewer/UIVMLogViewerDialog.cpp \ 654 656 src/logviewer/UIVMLogViewerFilterPanel.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.cpp
r70474 r70487 21 21 22 22 /* Qt includes: */ 23 # include <QButtonGroup>24 23 # include <QComboBox> 25 # include <QFrame>26 24 # include <QHBoxLayout> 27 25 # if defined(RT_OS_SOLARIS) … … 34 32 # include <QTextCursor> 35 33 # include <QToolButton> 36 # include <QRadioButton>37 34 # include <QScrollArea> 38 35 … … 40 37 # include "UIIconPool.h" 41 38 # include "UISpecialControls.h" 42 # include "UIVMLogViewer FilterPanel.h"39 # include "UIVMLogViewerBookmarksPanel.h" 43 40 # include "UIVMLogViewerWidget.h" 44 41 # ifdef VBOX_WS_MAC … … 47 44 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 48 45 49 /* UIVMFilterLineEdit class is used to display and modify the list of filter terms.50 the terms are displayed as words with spaces in between and it is possible to51 remove these terms one by one by selecting them or completely by the clearAll button52 located on the right side of the line edit: */53 class UIVMFilterLineEdit : public QLineEdit54 {55 Q_OBJECT;56 46 57 signals: 58 59 void sigFilterTermRemoved(QString removedString); 60 void sigClearAll(); 61 62 public: 63 64 UIVMFilterLineEdit(QWidget *parent = 0) 65 :QLineEdit(parent) 66 , m_pRemoveTermButton(0) 67 { 68 setReadOnly(true); 69 home(false); 70 createButtons(); 71 } 72 73 void addFilterTerm(const QString& filterTermString) 74 { 75 if (text().isEmpty()) 76 insert(filterTermString); 77 else 78 { 79 QString newString(filterTermString); 80 insert(newString.prepend(' ')); 81 } 82 } 83 84 void clearAll() 85 { 86 if (text().isEmpty()) 87 return; 88 sltClearAll(); 89 } 90 91 protected: 92 93 /* Overload the mouseXXXEvent to control how selection is done: */ 94 virtual void mouseDoubleClickEvent(QMouseEvent *){} 95 virtual void mouseMoveEvent(QMouseEvent *){} 96 virtual void mousePressEvent(QMouseEvent * event) 97 { 98 /* Simulate double mouse click to select a word with a single click: */ 99 QLineEdit::mouseDoubleClickEvent(event); 100 } 101 102 virtual void mouseReleaseEvent(QMouseEvent *){} 103 virtual void paintEvent(QPaintEvent *event) 104 { 105 QLineEdit::paintEvent(event); 106 int clearButtonSize = height(); 107 m_pClearAllButton->setGeometry(width() - clearButtonSize, 0, clearButtonSize, clearButtonSize); 108 /* If we have a selected term move the m_pRemoveTermButton to the end of the 109 or start of the word (depending on the location of the word within line edit itself: */ 110 if (hasSelectedText()) 111 { 112 m_pRemoveTermButton->show(); 113 int buttonY = 0.5 * (height() - 16); 114 int buttonSize = 16; 115 int charWidth = fontMetrics().width('x'); 116 int buttonLeft = cursorRect().right() - 0.5 * charWidth; 117 /* If buttonLeft is in far left of the line edit, move the 118 button to left side of the selected word: */ 119 if (buttonLeft + buttonSize >= width() - clearButtonSize) 120 { 121 int selectionWidth = charWidth * selectedText().length(); 122 buttonLeft -= (selectionWidth + buttonSize); 123 } 124 m_pRemoveTermButton->setGeometry(buttonLeft, buttonY, buttonSize, buttonSize); 125 } 126 else 127 m_pRemoveTermButton->hide(); 128 } 129 130 private slots: 131 132 /* Nofifies the listeners that selected word (filter term) has been removed: */ 133 void sltRemoveFilterTerm() 134 { 135 if (!hasSelectedText()) 136 return; 137 emit sigFilterTermRemoved(selectedText()); 138 /* Remove the string from text() including the trailing space: */ 139 setText(text().remove(selectionStart(), selectedText().length()+1)); 140 } 141 142 /* The whole content is removed. Listeners are notified: */ 143 void sltClearAll() 144 { 145 /* Check if we have some text to avoid recursive calls: */ 146 if (text().isEmpty()) 147 return; 148 149 clear(); 150 emit sigClearAll(); 151 } 152 153 private: 154 155 void createButtons() 156 { 157 m_pRemoveTermButton = new QToolButton(this); 158 AssertReturnVoid(m_pRemoveTermButton); 159 m_pRemoveTermButton->setIcon(m_pRemoveTermButton->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); 160 m_pRemoveTermButton->hide(); 161 162 m_pClearAllButton = new QToolButton(this); 163 AssertReturnVoid(m_pClearAllButton); 164 m_pClearAllButton->setIcon(m_pRemoveTermButton->style()->standardIcon(QStyle::SP_LineEditClearButton)); 165 166 connect(m_pRemoveTermButton, &QToolButton::clicked, this, &UIVMFilterLineEdit::sltRemoveFilterTerm); 167 connect(m_pClearAllButton, &QToolButton::clicked, this, &UIVMFilterLineEdit::sltClearAll); 168 } 169 170 QToolButton *m_pRemoveTermButton; 171 QToolButton *m_pClearAllButton; 172 }; 173 174 UIVMLogViewerFilterPanel::UIVMLogViewerFilterPanel(QWidget *pParent, UIVMLogViewerWidget *pViewer) 47 UIVMLogViewerBookmarksPanel::UIVMLogViewerBookmarksPanel(QWidget *pParent, UIVMLogViewerWidget *pViewer) 175 48 : QIWithRetranslateUI<QWidget>(pParent) 49 , m_iMaxBookmarkTextLength(60) 176 50 , m_pViewer(pViewer) 177 51 , m_pMainLayout(0) 178 52 , m_pCloseButton(0) 179 , m_pFilterLabel(0) 180 , m_pFilterComboBox(0) 181 , m_pButtonGroup(0) 182 , m_pAndRadioButton(0) 183 , m_pOrRadioButton(0) 184 , m_pRadioButtonContainer(0) 185 , m_pAddFilterTermButton(0) 186 , m_eFilterOperatorButton(AndButton) 187 , m_pFilterTermsLineEdit(0) 188 , m_pResultLabel(0) 189 , m_iUnfilteredLineCount(0) 190 , m_iFilteredLineCount(0) 53 , m_pBookmarksComboBox(0) 191 54 { 192 55 prepare(); 193 56 } 194 57 195 void UIVMLogViewer FilterPanel::applyFilter(const int iCurrentIndex /* = 0 */)58 void UIVMLogViewerBookmarksPanel::update() 196 59 { 197 Q_UNUSED(iCurrentIndex); 198 filter(); 199 retranslateUi(); 60 if(!m_pBookmarksComboBox) 61 return; 62 const QVector<QPair<int, QString> > *bookmarkVector = m_pViewer->currentBookmarkVector(); 63 if(!bookmarkVector) 64 return; 65 66 m_pBookmarksComboBox->clear(); 67 QStringList bList; 68 for(int i = 0; i < bookmarkVector->size(); ++i) 69 { 70 QString strItem = QString("BookMark %1 at Line %2: %3").arg(QString::number(i)). 71 arg(QString::number(bookmarkVector->at(i).first)).arg(bookmarkVector->at(i).second); 72 73 if(strItem.length() > m_iMaxBookmarkTextLength) 74 { 75 strItem.resize(m_iMaxBookmarkTextLength); 76 strItem.replace(m_iMaxBookmarkTextLength, 3, QString("...")); 77 } 78 bList << strItem; 79 } 80 m_pBookmarksComboBox->addItems(bList); 200 81 } 201 82 202 void UIVMLogViewer FilterPanel::filter()83 void UIVMLogViewerBookmarksPanel::setBookmarkIndex(int index) 203 84 { 204 QPlainTextEdit *pCurrentPage = m_pViewer->currentLogPage(); 205 AssertReturnVoid(pCurrentPage); 206 const QString& strInputText = m_pViewer->currentLog(); 207 m_iUnfilteredLineCount = 0; 208 m_iFilteredLineCount = 0; 209 if (strInputText.isNull()) 85 if (!m_pBookmarksComboBox) 210 86 return; 211 QTextDocument *document = pCurrentPage->document(); 212 if (!document) 87 if (index >= m_pBookmarksComboBox->count()) 213 88 return; 214 QStringList stringLines = strInputText.split("\n"); 215 m_iUnfilteredLineCount = stringLines.size(); 216 if (m_filterTermList.empty()) 217 { 218 document->setPlainText(strInputText); 219 emit sigFilterApplied(); 220 m_iFilteredLineCount = document->lineCount(); 221 return; 222 } 223 224 /* Prepare filter-data: */ 225 QString strFilteredText; 226 int count = 0; 227 for (int lineIdx = 0; lineIdx < stringLines.size(); ++lineIdx) 228 { 229 const QString& currentLineString = stringLines[lineIdx]; 230 if (currentLineString.isEmpty()) 231 continue; 232 if (applyFilterTermsToString(currentLineString)) 233 { 234 strFilteredText.append(currentLineString).append("\n"); 235 ++count; 236 } 237 } 238 239 document->setPlainText(strFilteredText); 240 m_iFilteredLineCount = document->lineCount(); 241 242 /* Move the cursor position to end: */ 243 QTextCursor cursor = pCurrentPage->textCursor(); 244 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); 245 pCurrentPage->setTextCursor(cursor); 246 247 emit sigFilterApplied(); 89 m_pBookmarksComboBox->setCurrentIndex(index); 248 90 } 249 91 250 251 bool UIVMLogViewerFilterPanel::applyFilterTermsToString(const QString& string) 252 { 253 /* Number of the filter terms contained with the @p string: */ 254 int hitCount = 0; 255 for (int i = 0; i < m_filterTermList.size(); ++i) 256 { 257 const QRegExp rxFilterExp(m_filterTermList.at(i), Qt::CaseInsensitive); 258 /* Disregard empty and invalid filter terms: */ 259 if (rxFilterExp.isEmpty() || !rxFilterExp.isValid()) 260 continue; 261 262 if (string.contains(rxFilterExp)) 263 { 264 ++hitCount; 265 /* Early return */ 266 if (m_eFilterOperatorButton == OrButton) 267 return true; 268 } 269 270 /* Early return */ 271 if (!string.contains(rxFilterExp) && m_eFilterOperatorButton == AndButton ) 272 return false; 273 } 274 /* All the terms are found within the @p string. To catch AND case: */ 275 if (hitCount == m_filterTermList.size()) 276 return true; 277 return false; 278 } 279 280 281 void UIVMLogViewerFilterPanel::sltAddFilterTerm() 282 { 283 if (!m_pFilterComboBox) 284 return; 285 if (m_pFilterComboBox->currentText().isEmpty()) 286 return; 287 288 /* Continue only if the term is new. */ 289 if (m_filterTermList.contains(m_pFilterComboBox->currentText())) 290 return; 291 m_filterTermList.push_back(m_pFilterComboBox->currentText()); 292 293 /* Add the new filter term to line edit: */ 294 if (m_pFilterTermsLineEdit) 295 m_pFilterTermsLineEdit->addFilterTerm(m_pFilterComboBox->currentText()); 296 297 /* Clear the content of the combo box: */ 298 m_pFilterComboBox->setCurrentText(QString()); 299 applyFilter(); 300 } 301 302 void UIVMLogViewerFilterPanel::sltClearFilterTerms() 303 { 304 if (m_filterTermList.empty()) 305 return; 306 m_filterTermList.clear(); 307 applyFilter(); 308 if (m_pFilterTermsLineEdit) 309 m_pFilterTermsLineEdit->clearAll(); 310 } 311 312 void UIVMLogViewerFilterPanel::sltOperatorButtonChanged(int buttonId) 313 { 314 if (buttonId < 0 || buttonId >= ButtonEnd) 315 return; 316 m_eFilterOperatorButton = static_cast<FilterOperatorButton>(buttonId); 317 applyFilter(); 318 } 319 320 void UIVMLogViewerFilterPanel::sltRemoveFilterTerm(const QString &termString) 321 { 322 QStringList newList; 323 for (QStringList::iterator iterator = m_filterTermList.begin(); 324 iterator != m_filterTermList.end(); ++iterator) 325 { 326 if ((*iterator) != termString) 327 newList.push_back(*iterator); 328 } 329 m_filterTermList = newList; 330 applyFilter(); 331 } 332 333 void UIVMLogViewerFilterPanel::prepare() 92 void UIVMLogViewerBookmarksPanel::prepare() 334 93 { 335 94 prepareWidgets(); … … 338 97 } 339 98 340 void UIVMLogViewer FilterPanel::prepareWidgets()99 void UIVMLogViewerBookmarksPanel::prepareWidgets() 341 100 { 342 101 m_pMainLayout = new QHBoxLayout(this); … … 347 106 m_pCloseButton = new UIMiniCancelButton(this); 348 107 AssertPtrReturnVoid(m_pCloseButton); 349 m_pMainLayout->addWidget(m_pCloseButton );108 m_pMainLayout->addWidget(m_pCloseButton, 0, Qt::AlignLeft); 350 109 351 prepareRadioButtonGroup(); 110 m_pBookmarksComboBox = new QComboBox(this); 111 QFontMetrics fontMetrics = m_pBookmarksComboBox->fontMetrics(); 112 AssertPtrReturnVoid(m_pBookmarksComboBox); 113 m_pBookmarksComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); 114 m_pBookmarksComboBox->setMaximumWidth(fontMetrics.width('a') * (m_iMaxBookmarkTextLength + 2)); 115 printf("max max %d\n", fontMetrics.width('a') * (m_iMaxBookmarkTextLength + 2)); 116 m_pMainLayout->addWidget(m_pBookmarksComboBox, 2, Qt::AlignLeft); 352 117 353 m_pFilterComboBox = new QComboBox(this);354 AssertPtrReturnVoid(m_pFilterComboBox);355 {356 m_pFilterComboBox->setEditable(true);357 QStringList strFilterPresets;358 strFilterPresets << "" << "GUI" << "NAT" << "AHCI" << "VD" << "Audio" << "VUSB" << "SUP" << "PGM" << "HDA"359 << "HM" << "VMM" << "GIM" << "CPUM";360 strFilterPresets.sort();361 m_pFilterComboBox->addItems(strFilterPresets);362 m_pMainLayout->addWidget(m_pFilterComboBox,1);363 }364 365 m_pAddFilterTermButton = new QPushButton(this);366 AssertPtrReturnVoid(m_pAddFilterTermButton);367 {368 m_pAddFilterTermButton->setIcon(UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_ArrowForward, this));369 m_pMainLayout->addWidget(m_pAddFilterTermButton,0);370 }371 372 m_pFilterTermsLineEdit = new UIVMFilterLineEdit(this);373 AssertPtrReturnVoid(m_pFilterTermsLineEdit);374 {375 m_pMainLayout->addWidget(m_pFilterTermsLineEdit, 4);376 m_pFilterTermsLineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum /*vertical */);377 }378 379 m_pResultLabel = new QLabel(this);380 AssertPtrReturnVoid(m_pResultLabel);381 {382 m_pMainLayout->addWidget(m_pResultLabel,0);383 }384 /* Create filter-label: */385 // m_pFilterLabel = new QLabel(this);386 // AssertPtrReturnVoid(m_pFilterLabel);387 // {388 // /* Configure filter-label: */389 // m_pFilterLabel->setBuddy(m_pFilterComboBox);390 // #ifdef VBOX_DARWIN_USE_NATIVE_CONTROLS391 // QFont font = m_pFilterLabel->font();392 // font.setPointSize(::darwinSmallFontSize());393 // m_pFilterLabel->setFont(font);394 // #endif /* VBOX_DARWIN_USE_NATIVE_CONTROLS */395 // /* Add filter-label to main-layout: */396 // m_pMainLayout->addWidget(m_pFilterLabel);397 // }398 118 } 399 119 400 void UIVMLogViewer FilterPanel::prepareRadioButtonGroup()120 void UIVMLogViewerBookmarksPanel::prepareConnections() 401 121 { 402 m_pButtonGroup = new QButtonGroup(this); 403 AssertPtrReturnVoid(m_pButtonGroup); 122 connect(m_pCloseButton, &UIMiniCancelButton::clicked, this, &UIVMLogViewerBookmarksPanel::hide); 404 123 405 m_pRadioButtonContainer = new QFrame(this);406 m_pRadioButtonContainer->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);407 AssertPtrReturnVoid(m_pRadioButtonContainer);408 409 QHBoxLayout* containerLayout = (new QHBoxLayout(m_pRadioButtonContainer));410 AssertPtrReturnVoid(containerLayout);411 containerLayout->setContentsMargins(0, 0, 0, 0);412 containerLayout->setSpacing(0);413 414 m_pAndRadioButton = new QRadioButton(this);415 m_pOrRadioButton = new QRadioButton(this);416 AssertPtrReturnVoid(m_pAndRadioButton);417 AssertPtrReturnVoid(m_pOrRadioButton);418 419 m_pButtonGroup->addButton(m_pAndRadioButton, static_cast<int>(AndButton));420 m_pButtonGroup->addButton(m_pOrRadioButton, static_cast<int>(OrButton));421 m_pOrRadioButton->setText("Or");422 m_pAndRadioButton->setText("And");423 m_pOrRadioButton->setChecked(true);424 m_eFilterOperatorButton = OrButton;425 426 containerLayout->addWidget(m_pOrRadioButton);427 containerLayout->addWidget(m_pAndRadioButton);428 m_pMainLayout->addWidget(m_pRadioButtonContainer);429 }430 431 void UIVMLogViewerFilterPanel::prepareConnections()432 {433 connect(m_pCloseButton, &UIMiniCancelButton::clicked, this, &UIVMLogViewerFilterPanel::hide);434 connect(m_pAddFilterTermButton, &QPushButton::clicked, this, &UIVMLogViewerFilterPanel::sltAddFilterTerm);435 connect(m_pButtonGroup, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),436 this, &UIVMLogViewerFilterPanel::sltOperatorButtonChanged);437 connect(m_pFilterComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),438 this, &UIVMLogViewerFilterPanel::sltAddFilterTerm);439 connect(m_pFilterTermsLineEdit, &UIVMFilterLineEdit::sigFilterTermRemoved,440 this, &UIVMLogViewerFilterPanel::sltRemoveFilterTerm);441 connect(m_pFilterTermsLineEdit, &UIVMFilterLineEdit::sigClearAll,442 this, &UIVMLogViewerFilterPanel::sltClearFilterTerms);443 124 } 444 125 445 126 446 void UIVMLogViewer FilterPanel::retranslateUi()127 void UIVMLogViewerBookmarksPanel::retranslateUi() 447 128 { 448 129 m_pCloseButton->setToolTip(UIVMLogViewerWidget::tr("Close the search panel.")); 449 m_pFilterComboBox->setToolTip(UIVMLogViewerWidget::tr("Enter filtering string here."));450 m_pAddFilterTermButton->setToolTip(UIVMLogViewerWidget::tr("Add filter term."));451 m_pResultLabel->setText(UIVMLogViewerWidget::tr("Showing %1/%2").arg(m_iFilteredLineCount).arg(m_iUnfilteredLineCount));452 m_pFilterTermsLineEdit->setToolTip(UIVMLogViewerWidget::tr("The filter terms list. Select one to remove or click the button on the right side to remove them all."));453 m_pRadioButtonContainer->setToolTip(UIVMLogViewerWidget::tr("The type of boolean operator for filter operation."));454 130 } 455 131 456 bool UIVMLogViewer FilterPanel::eventFilter(QObject *pObject, QEvent *pEvent)132 bool UIVMLogViewerBookmarksPanel::eventFilter(QObject *pObject, QEvent *pEvent) 457 133 { 458 134 /* Depending on event-type: */ … … 462 138 case QEvent::KeyPress: 463 139 { 464 /* Cast to corresponding key press event: */465 QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(pEvent);466 467 /* Handle Ctrl+T key combination as a shortcut to focus search field: */468 if (pKeyEvent->QInputEvent::modifiers() == Qt::ControlModifier &&469 pKeyEvent->key() == Qt::Key_T)470 {471 if (m_pViewer->currentLogPage())472 {473 if (isHidden())474 show();475 m_pFilterComboBox->setFocus();476 return true;477 }478 }479 else if (pKeyEvent->key() == Qt::Key_Return && m_pFilterComboBox && m_pFilterComboBox->hasFocus())480 sltAddFilterTerm();481 482 140 break; 483 141 } … … 490 148 491 149 /** Handles the Qt show @a pEvent. */ 492 void UIVMLogViewer FilterPanel::showEvent(QShowEvent *pEvent)150 void UIVMLogViewerBookmarksPanel::showEvent(QShowEvent *pEvent) 493 151 { 494 152 /* Call to base-class: */ 495 153 QWidget::showEvent(pEvent); 496 /* Set focus to combo-box: */497 m_pFilterComboBox->setFocus();498 154 } 499 155 500 156 /** Handles the Qt hide @a pEvent. */ 501 void UIVMLogViewer FilterPanel::hideEvent(QHideEvent *pEvent)157 void UIVMLogViewerBookmarksPanel::hideEvent(QHideEvent *pEvent) 502 158 { 503 159 /* Get focused widget: */ … … 510 166 QWidget::hideEvent(pEvent); 511 167 } 512 513 #include "UIVMLogViewerFilterPanel.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerBookmarksPanel.h
r70474 r70487 16 16 */ 17 17 18 #ifndef ___UIVMLogViewer FilterPanel_h___19 #define ___UIVMLogViewer FilterPanel_h___18 #ifndef ___UIVMLogViewerBookmarksPanel_h___ 19 #define ___UIVMLogViewerBookmarksPanel_h___ 20 20 21 21 /* Qt includes: */ … … 26 26 27 27 /* Forward declarations: */ 28 class QButtonGroup;29 28 class QComboBox; 30 class QFrame;31 29 class QHBoxLayout; 32 30 class QLabel; 33 31 class QLineEdit; 34 32 class QPushButton; 35 class QRadioButton;36 33 class UIVMFilterLineEdit; 37 34 class UIMiniCancelButton; … … 40 37 41 38 /** QWidget extension 42 * providing GUI for filter panel in VM Log Viewer. */ 43 class UIVMLogViewerFilterPanel : public QIWithRetranslateUI<QWidget> 39 * providing GUI for bookmark management. Show a list of bookmarks currently set 40 for displayed log page. It has controls to navigate and clear bookmarks. */ 41 class UIVMLogViewerBookmarksPanel : public QIWithRetranslateUI<QWidget> 44 42 { 45 43 Q_OBJECT; … … 47 45 signals: 48 46 49 /* Notifies listeners that the filter has been applied. */50 void sigFilterApplied();51 52 47 public: 53 48 54 /** Constructs the filter-panel by passing @a pParent to the QWidget base-class constructor. 55 * @param pViewer Specifies reference to the VM Log-Viewer this filter-panel belongs to. */ 56 UIVMLogViewerFilterPanel(QWidget *pParent, UIVMLogViewerWidget *pViewer); 49 UIVMLogViewerBookmarksPanel(QWidget *pParent, UIVMLogViewerWidget *pViewer); 50 51 /* Adds a single bookmark to an existing list of bookmarks. Possibly called 52 by UIVMLogViewerWidget when user adds a bookmark thru context menu etc. */ 53 void addBookmark(const QPair<int, QString> &newBookmark); 54 /* Clear the bookmark list and show this list instead. Probably done after 55 user switches to another log page tab etc. */ 56 void setBookmarksList(const QVector<QPair<int, QString> > &bookmarkList); 57 void update(); 58 /* @a index is the index of the curent bookmark. */ 59 void setBookmarkIndex(int index); 57 60 58 61 public slots: 59 62 60 /** Applies filter settings and filters the current log-page.61 * @param iCurrentIndex Specifies index of current log-page, but it is actually not used in the method. */62 void applyFilter(const int iCurrentIndex = 0);63 63 64 64 private slots: 65 65 66 /** Adds the new filter term and reapplies the filter. */67 void sltAddFilterTerm();68 /** Clear all the filter terms and reset the filtering. */69 void sltClearFilterTerms();70 /** Executes the necessary code to handle filter's boolean operator change ('And', 'Or'). */71 void sltOperatorButtonChanged(int buttonId);72 void sltRemoveFilterTerm(const QString &termString);73 66 74 67 private: 75 68 76 enum FilterOperatorButton{77 AndButton = 0,78 OrButton,79 ButtonEnd80 };81 82 /** Prepares filter-panel. */83 69 void prepare(); 84 70 void prepareWidgets(); 85 void prepareRadioButtonGroup();86 71 void prepareConnections(); 87 72 … … 96 81 void hideEvent(QHideEvent *pEvent); 97 82 98 bool applyFilterTermsToString(const QString& string); 99 void filter(); 100 101 /** Holds the reference to VM Log-Viewer this filter-panel belongs to. */ 83 const int m_iMaxBookmarkTextLength; 84 /** Holds the reference to VM Log-Viewer this panel belongs to. */ 102 85 UIVMLogViewerWidget *m_pViewer; 103 86 /** Holds the instance of main-layout we create. */ … … 105 88 /** Holds the instance of close-button we create. */ 106 89 UIMiniCancelButton *m_pCloseButton; 107 /** Holds the instance of filter-label we create. */ 108 QLabel *m_pFilterLabel; 109 /** Holds instance of filter combo-box we create. */ 110 QComboBox *m_pFilterComboBox; 90 QComboBox *m_pBookmarksComboBox; 111 91 112 QButtonGroup *m_pButtonGroup;113 QRadioButton *m_pAndRadioButton;114 QRadioButton *m_pOrRadioButton;115 QFrame *m_pRadioButtonContainer;116 QPushButton *m_pAddFilterTermButton;117 QStringList m_filterTermList;118 FilterOperatorButton m_eFilterOperatorButton;119 UIVMFilterLineEdit *m_pFilterTermsLineEdit;120 QLabel *m_pResultLabel;121 int m_iUnfilteredLineCount;122 int m_iFilteredLineCount;123 92 }; 124 93 125 #endif /* !___UIVMLogViewer FilterPanel_h___ */94 #endif /* !___UIVMLogViewerBookmarksPanel_h___ */ -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp
r70474 r70487 204 204 QPlainTextEdit *pCurrentPage = m_pViewer->currentLogPage(); 205 205 AssertReturnVoid(pCurrentPage); 206 const QString &strInputText = m_pViewer->currentLog();206 const QString* strInputText = m_pViewer->currentLog(); 207 207 m_iUnfilteredLineCount = 0; 208 208 m_iFilteredLineCount = 0; 209 if ( strInputText.isNull())209 if (!strInputText || strInputText->isNull()) 210 210 return; 211 211 QTextDocument *document = pCurrentPage->document(); 212 212 if (!document) 213 213 return; 214 QStringList stringLines = strInputText .split("\n");214 QStringList stringLines = strInputText->split("\n"); 215 215 m_iUnfilteredLineCount = stringLines.size(); 216 216 if (m_filterTermList.empty()) 217 217 { 218 document->setPlainText( strInputText);218 document->setPlainText(*strInputText); 219 219 emit sigFilterApplied(); 220 220 m_iFilteredLineCount = document->lineCount(); -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp
r70476 r70487 30 30 # include <QPlainTextEdit> 31 31 # include <QScrollBar> 32 # include <QTextBlock> 32 33 33 34 /* GUI includes: */ … … 38 39 # include "UIMessageCenter.h" 39 40 # include "UIVMLogViewerWidget.h" 41 # include "UIVMLogViewerBookmarksPanel.h" 40 42 # include "UIVMLogViewerFilterPanel.h" 41 43 # include "UIVMLogViewerSearchPanel.h" … … 48 50 49 51 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 52 50 53 51 54 /** We use a modified scrollbar style for our QPlainTextEdits to get the … … 116 119 }; 117 120 121 /* Sub-class QPlainTextEdit for some addtional context menu items: */ 122 class UIVMLogViewerTextEdit : public QPlainTextEdit 123 { 124 Q_OBJECT; 125 126 signals: 127 128 void sigContextMenuBookmarkAction(LogBookmark bookmark); 129 130 public: 131 UIVMLogViewerTextEdit(QWidget* parent = 0, const QString& logFileName = QString()) 132 :QPlainTextEdit(parent), 133 m_logFileName(logFileName) 134 { 135 //setStyleSheet("background-color: rgba(240, 240, 240, 75%) "); 136 } 137 138 const QString& logFileName() const 139 { 140 return m_logFileName; 141 } 142 143 protected: 144 145 void contextMenuEvent(QContextMenuEvent *pEvent) 146 { 147 QMenu *menu = createStandardContextMenu(); 148 QAction *pAction = menu->addAction(tr("Bookmark")); 149 QTextBlock block = cursorForPosition(pEvent->pos()).block(); 150 m_iContextMenuBookmark.first = block.firstLineNumber(); 151 m_iContextMenuBookmark.second = block.text(); 152 153 if(pAction) 154 connect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark); 155 156 menu->exec(pEvent->globalPos()); 157 158 if(pAction) 159 disconnect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark); 160 161 delete menu; 162 } 163 164 virtual void mousePressEvent(QMouseEvent *pEvent) 165 { 166 QPlainTextEdit::mousePressEvent(pEvent); 167 } 168 169 private slots: 170 /// remove 171 void sltBookmark() 172 { 173 emit sigContextMenuBookmarkAction(m_iContextMenuBookmark); 174 } 175 176 private: 177 178 /* Line number and text at the context menu position */ 179 LogBookmark m_iContextMenuBookmark; 180 /* Name of the log file this text edit created to show. */ 181 QString m_logFileName; 182 }; 183 118 184 UIVMLogViewerWidget::UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */, const CMachine &machine /* = CMachine() */) 119 185 : QIWithRetranslateUI<QWidget>(pParent) … … 122 188 , m_pViewerContainer(0) 123 189 , m_iCurrentTabIndex(-1) 190 , m_pSearchPanel(0) 191 , m_pFilterPanel(0) 192 , m_pBookmarksPanel(0) 124 193 , m_pMainLayout(0) 125 194 , m_enmEmbedding(enmEmbedding) … … 129 198 , m_pActionRefresh(0) 130 199 , m_pActionSave(0) 200 , m_pActionBookmark(0) 131 201 , m_pMenu(0) 132 202 { … … 166 236 } 167 237 168 void UIVMLogViewerWidget::sltFind() 169 { 238 void UIVMLogViewerWidget::sltShowHideSearchPanel() 239 { 240 if(!m_pSearchPanel) 241 return; 170 242 /* Show/hide search-panel: */ 171 243 m_pSearchPanel->isHidden() ? m_pSearchPanel->show() : m_pSearchPanel->hide(); … … 178 250 disconnect(m_pViewerContainer, &QITabWidget::currentChanged, this, &UIVMLogViewerWidget::sltTabIndexChange); 179 251 180 /* Clearing old data if any: */181 m_book.clear();182 252 m_logMap.clear(); 183 253 m_pViewerContainer->setEnabled(true); … … 226 296 227 297 /* Apply the filter settings: */ 228 m_pFilterPanel->applyFilter(); 298 if(m_pFilterPanel) 299 m_pFilterPanel->applyFilter(); 229 300 230 301 /* Setup this connection after refresh to avoid initial signals during page creation: */ … … 238 309 m_pActionFilter->setEnabled(!noLogsToShow); 239 310 m_pActionSave->setEnabled(!noLogsToShow); 311 m_pActionBookmark->setEnabled(!noLogsToShow); 240 312 m_pViewerContainer->setEnabled(!noLogsToShow); 241 313 m_pViewerContainer->show(); … … 248 320 if (m_comMachine.isNull()) 249 321 return; 322 UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage()); 323 if(!logPage) 324 return; 250 325 /* Prepare "save as" dialog: */ 251 const QFileInfo fileInfo( m_book.at(m_pViewerContainer->currentIndex()).first);326 const QFileInfo fileInfo(logPage->logFileName()); 252 327 /* Prepare default filename: */ 253 328 const QDateTime dtInfo = fileInfo.lastModified(); … … 274 349 } 275 350 276 void UIVMLogViewerWidget::sltFilter() 277 { 351 void UIVMLogViewerWidget::sltShowHideFilterPanel() 352 { 353 if(!m_pFilterPanel) 354 return; 278 355 /* Show/hide filter-panel: */ 279 356 m_pFilterPanel->isHidden() ? m_pFilterPanel->show() : m_pFilterPanel->hide(); … … 305 382 } 306 383 307 void UIVMLogViewerWidget:: 308 sltFilterApplied() 384 void UIVMLogViewerWidget::sltFilterApplied() 309 385 { 310 386 /* Reapply the search to get highlighting etc. correctly */ 311 387 if (m_pSearchPanel && m_pSearchPanel->isVisible()) 312 388 m_pSearchPanel->refresh(); 389 } 390 391 void UIVMLogViewerWidget::sltShowHideBookmarkPanel() 392 { 393 if(!m_pBookmarksPanel) 394 return; 395 m_pBookmarksPanel->isHidden() ? m_pBookmarksPanel->show() : m_pBookmarksPanel->hide(); 396 } 397 398 void UIVMLogViewerWidget::sltCreateBookmarkAtCurrent() 399 { 400 if(!currentLogPage()) 401 return; 402 QWidget* viewport = currentLogPage()->viewport(); 403 if (!viewport) 404 return; 405 QPoint point(0.5 * viewport->width(), 0.5 * viewport->height()); 406 QTextBlock block = currentLogPage()->cursorForPosition(point).block(); 407 LogBookmark bookmark; 408 bookmark.first = block.firstLineNumber(); 409 bookmark.second = block.text(); 410 sltCreateBookmarkAtLine(bookmark); 411 } 412 413 void UIVMLogViewerWidget::sltCreateBookmarkAtLine(LogBookmark bookmark) 414 { 415 QVector<LogBookmark> *pBookmarkVector = currentBookmarkVector(); 416 if(!pBookmarkVector) 417 return; 418 pBookmarkVector->push_back(bookmark); 419 if(m_pBookmarksPanel) 420 { 421 m_pBookmarksPanel->update(); 422 m_pBookmarksPanel->setBookmarkIndex(pBookmarkVector->size() - 1); 423 } 313 424 } 314 425 … … 384 495 this, &UIVMLogViewerWidget::sltFilterApplied); 385 496 } 497 498 m_pBookmarksPanel = new UIVMLogViewerBookmarksPanel(this, this); 499 AssertPtrReturnVoid(m_pBookmarksPanel); 500 { 501 installEventFilter(m_pBookmarksPanel); 502 m_pBookmarksPanel->hide(); 503 m_pMainLayout->insertWidget(4, m_pBookmarksPanel); 504 } 386 505 } 387 506 … … 393 512 { 394 513 m_pActionFind->setShortcut(QKeySequence("Ctrl+F")); 395 connect(m_pActionFind, &QAction::triggered, this, &UIVMLogViewerWidget::sltFind); 514 m_pActionFind->setCheckable(true); 515 connect(m_pActionFind, &QAction::triggered, this, &UIVMLogViewerWidget::sltShowHideSearchPanel); 396 516 } 397 517 … … 401 521 { 402 522 m_pActionFilter->setShortcut(QKeySequence("Ctrl+T")); 403 connect(m_pActionFilter, &QAction::triggered, this, &UIVMLogViewerWidget::sltFilter); 523 m_pActionFilter->setCheckable(true); 524 connect(m_pActionFilter, &QAction::triggered, this, &UIVMLogViewerWidget::sltShowHideFilterPanel); 404 525 } 405 526 … … 419 540 already assigned to another action in the selector UI: */ 420 541 if (m_enmEmbedding == EmbedTo_Dialog) 421 {422 542 m_pActionSave->setShortcut(QKeySequence("Ctrl+S")); 423 connect(m_pActionSave, &QAction::triggered, this, &UIVMLogViewerWidget::sltSave); 424 } 543 connect(m_pActionSave, &QAction::triggered, this, &UIVMLogViewerWidget::sltSave); 544 } 545 546 /* Create and configure 'Bookmark' action: */ 547 m_pActionBookmark = new QAction(this); 548 AssertPtrReturnVoid(m_pActionBookmark); 549 { 550 /* tie Ctrl+D to save only if we show this in a dialog since Ctrl+D is 551 already assigned to another action in the selector UI: */ 552 if (m_enmEmbedding == EmbedTo_Dialog) 553 m_pActionBookmark->setShortcut(QKeySequence("Ctrl+D")); 554 m_pActionBookmark->setCheckable(true); 555 connect(m_pActionBookmark, &QAction::triggered, this, &UIVMLogViewerWidget::sltShowHideBookmarkPanel); 425 556 } 426 557 … … 451 582 QString(":/%1_save_disabled_24px.png").arg(strPrefix))); 452 583 453 584 if (m_pActionBookmark) 585 m_pActionBookmark->setIcon(UIIconPool::iconSet(QString(":/%1_bookmark_24px.png").arg(strPrefix), 586 QString(":/%1_bookmark_disabled_24px.png").arg(strPrefix))); 454 587 } 455 588 … … 476 609 if (m_pActionSave) 477 610 m_pToolBar->addAction(m_pActionSave); 611 612 if (m_pActionBookmark) 613 m_pToolBar->addAction(m_pActionBookmark); 478 614 479 615 #ifdef VBOX_WS_MAC … … 505 641 if (m_pActionSave) 506 642 m_pMenu->addAction(m_pActionSave); 643 if (m_pActionBookmark) 644 m_pMenu->addAction(m_pActionBookmark); 645 507 646 } 508 647 } … … 545 684 m_pActionSave->setToolTip(tr("Save the log")); 546 685 m_pActionSave->setStatusTip(tr("Save the log")); 686 } 687 688 if (m_pActionBookmark) 689 { 690 m_pActionBookmark->setText(tr("&Bookmark...")); 691 m_pActionBookmark->setToolTip(tr("Bookmark the line")); 692 m_pActionBookmark->setStatusTip(tr("Bookmark the line")); 547 693 } 548 694 … … 616 762 } 617 763 764 const QString* UIVMLogViewerWidget::currentLog() 765 { 766 if(!currentLogPage()) 767 return 0; 768 return &(m_logMap[currentLogPage()]); 769 } 770 618 771 QPlainTextEdit* UIVMLogViewerWidget::currentLogPage() const 619 772 { … … 630 783 return 0; 631 784 } 785 786 const QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector() const 787 { 788 UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage()); 789 if(!logPage) 790 return 0; 791 QString logFileName = logPage->logFileName(); 792 if(logFileName.isEmpty()) 793 return 0; 794 795 return &(m_bookmarkMap[logFileName]); 796 } 797 798 QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector() 799 { 800 UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage()); 801 if(!logPage) 802 return 0; 803 QString logFileName = logPage->logFileName(); 804 if(logFileName.isEmpty()) 805 return 0; 806 807 return &(m_bookmarkMap[logFileName]); 808 } 809 632 810 633 811 QPlainTextEdit* UIVMLogViewerWidget::logPage(int pIndex) const … … 671 849 { 672 850 /* Create a log viewer page and append the read text to it: */ 673 QPlainTextEdit *pLogViewer = createLogPage( QFileInfo(strFileName).fileName());851 QPlainTextEdit *pLogViewer = createLogPage(strFileName); 674 852 pLogViewer->setPlainText(strText); 675 853 /* Move the cursor position to end: */ … … 677 855 cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); 678 856 pLogViewer->setTextCursor(cursor); 679 /* Add the actual file name and the QPlainTextEdit containing the content to a list: */680 m_book << qMakePair(strFileName, pLogViewer);681 857 /* Add the log-text to the map: */ 682 858 m_logMap[pLogViewer] = strText; … … 688 864 } 689 865 690 QPlainTextEdit* UIVMLogViewerWidget::createLogPage(const QString &str Name)866 QPlainTextEdit* UIVMLogViewerWidget::createLogPage(const QString &strFileName) 691 867 { 692 868 /* Create page-container: */ … … 698 874 AssertPtrReturn(pPageLayout, 0); 699 875 /* Create Log-Viewer: */ 700 QPlainTextEdit *pLogViewer = new QPlainTextEdit(pPageContainer); 876 UIVMLogViewerTextEdit *pLogViewer = new UIVMLogViewerTextEdit(pPageContainer, strFileName); 877 connect(pLogViewer, &UIVMLogViewerTextEdit::sigContextMenuBookmarkAction, 878 this, &UIVMLogViewerWidget::sltCreateBookmarkAtLine); 701 879 702 880 AssertPtrReturn(pLogViewer, 0); … … 722 900 } 723 901 /* Add page-container to viewer-container: */ 724 m_pViewerContainer->addTab(pPageContainer, strName);902 m_pViewerContainer->addTab(pPageContainer, QFileInfo(strFileName).fileName()); 725 903 return pLogViewer; 726 904 } 727 }728 729 const QString& UIVMLogViewerWidget::currentLog()730 {731 return m_logMap[currentLogPage()];732 905 } 733 906 -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h
r70308 r70487 37 37 class QVBoxLayout; 38 38 class UIToolBar; 39 class UIVMLogViewerBookmarksPanel; 39 40 class UIVMLogViewerFilterPanel; 40 41 class UIVMLogViewerSearchPanel; 41 42 42 43 /* Type definitions: */ 43 typedef QPair<QString, QPlainTextEdit*> LogPage; 44 typedef QList<LogPage> LogBook; 44 /** value is the content of the log file */ 45 45 typedef QMap<QPlainTextEdit*, QString> VMLogMap; 46 /** first is line number, second is block text */ 47 typedef QPair<int, QString> LogBookmark; 48 /** key is log file name, value is a vector of bookmarks. */ 49 typedef QMap<QString, QVector<LogBookmark> > BookmarkMap; 50 46 51 47 52 /** QIMainWindow extension … … 78 83 private slots: 79 84 80 /** Handles search action triggering. */81 void sltFind();82 85 /** Handles refresh action triggering. */ 83 86 void sltRefresh(); 84 87 /** Handles save action triggering. */ 85 88 void sltSave(); 86 /** Handles filter action triggering. */ 87 void sltFilter(); 89 90 void sltShowHideFilterPanel(); 91 void sltShowHideSearchPanel(); 92 void sltShowHideBookmarkPanel(); 88 93 89 94 /** Handles the search result highlight changes. */ 90 95 void sltSearchResultHighLigting(); 91 92 96 /** Handles the tab change of the logviewer. */ 93 97 void sltTabIndexChange(int tabIndex); 94 95 98 void sltFilterApplied(); 99 /* create a bookmark out of line number and block text. */ 100 void sltCreateBookmarkAtLine(QPair<int, QString> bookmark); 101 /* Determines the (middle) line number of the visible text and calls sltCreateBookmarkAtLine. */ 102 void sltCreateBookmarkAtCurrent(); 103 96 104 97 105 private: … … 129 137 /** Returns the newly created log-page using @a strPage filename. */ 130 138 QPlainTextEdit* createLogPage(const QString &strPage); 131 /** Returns the content of current log- page. */132 const QString ¤tLog();139 /** Returns the content of current log-file as it is read. */ 140 const QString* currentLog(); 133 141 134 142 /** Attempts to read the logs through the API, returns true if there exists any logs, false otherwise. */ … … 138 146 void resetHighlighthing(); 139 147 148 /** Returns the vector of bookmarks for the current log page */ 149 QVector<LogBookmark>* currentBookmarkVector(); 150 const QVector<LogBookmark>* currentBookmarkVector() const; 151 140 152 /** Holds whether the dialog is polished. */ 141 153 bool m_fIsPolished; … … 152 164 /** Holds the instance of search-panel. */ 153 165 UIVMLogViewerSearchPanel *m_pSearchPanel; 154 155 /** Holds the list of log-pages. */156 LogBook m_book;157 158 166 /** Holds the instance of filter panel. */ 159 167 UIVMLogViewerFilterPanel *m_pFilterPanel; 160 161 /** Holds the list of log-content. */ 162 VMLogMap m_logMap; 168 UIVMLogViewerBookmarksPanel *m_pBookmarksPanel; 169 170 /** Holds the list of log file content. */ 171 VMLogMap m_logMap; 172 mutable BookmarkMap m_bookmarkMap; 163 173 164 174 QVBoxLayout *m_pMainLayout; … … 179 189 /** Holds the Save action instance. */ 180 190 QAction *m_pActionSave; 191 /** Holds the Bookmark action instance. */ 192 QAction *m_pActionBookmark; 193 181 194 /** Holds the menu object instance. */ 182 195 QMenu *m_pMenu; 183 196 /** @} */ 184 197 198 friend class UIVMLogViewerBookmarksPanel; 199 friend class UIVMLogViewerFilterPanel; 185 200 friend class UIVMLogViewerSearchPanel; 186 friend class UIVMLogViewerFilterPanel;187 201 }; 188 202 -
trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumManager.cpp
r69821 r70487 2468 2468 return qobject_cast<UIMediumManagerWidget*>(QIManagerDialog::widget()); 2469 2469 } 2470
Note:
See TracChangeset
for help on using the changeset viewer.

