Changeset 70185 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Dec 18, 2017 10:32:04 AM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/converter/UIConverterBackendGlobal.cpp
r69500 r70185 873 873 case ToolTypeMachine_Details: strResult = "Details"; break; 874 874 case ToolTypeMachine_Snapshots: strResult = "Snapshots"; break; 875 case ToolTypeMachine_LogViewer: strResult = "LogViewer"; break; 875 876 default: 876 877 { … … 891 892 keys << "Details"; values << ToolTypeMachine_Details; 892 893 keys << "Snapshots"; values << ToolTypeMachine_Snapshots; 894 keys << "LogViewer"; values << ToolTypeMachine_LogViewer; 893 895 /* Invalid type for unknown words: */ 894 896 if (!keys.contains(strToolTypeMachine, Qt::CaseInsensitive)) -
trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h
r70113 r70185 640 640 ToolTypeMachine_Details, 641 641 ToolTypeMachine_Snapshots, 642 ToolTypeMachine_LogViewer 642 643 }; 643 644 Q_DECLARE_METATYPE(ToolTypeMachine); -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerDialog.cpp
r70165 r70185 41 41 # ifdef VBOX_WS_MAC 42 42 # include "VBoxUtils-darwin.h" 43 # endif 43 # endif /* VBOX_WS_MAC */ 44 44 45 45 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp
r70140 r70185 48 48 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 49 49 50 UIVMLogViewerWidget::UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent , const CMachine &machine)50 UIVMLogViewerWidget::UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */, const CMachine &machine /* = CMachine() */) 51 51 : QIWithRetranslateUI<QWidget>(pParent) 52 52 , m_fIsPolished(false) … … 73 73 int UIVMLogViewerWidget::defaultLogPageWidth() const 74 74 { 75 if (!m_pViewerContainer)75 if (!m_pViewerContainer) 76 76 return 0; 77 77 78 78 QWidget *pContainer = m_pViewerContainer->currentWidget(); 79 if (!pContainer)79 if (!pContainer) 80 80 return 0; 81 81 … … 111 111 m_logMap.clear(); 112 112 m_pViewerContainer->setEnabled(true); 113 /* Hide the container widget during updates to avoid flickering: */ 114 m_pViewerContainer->hide(); 113 115 while (m_pViewerContainer->count()) 114 116 { … … 118 120 } 119 121 120 bool isAnyLogPresent = false; 121 122 bool noLogsToShow = false; 123 QString strDummyTabText; 124 /* check if the machine is valid: */ 125 if (m_comMachine.isNull()) 126 { 127 noLogsToShow = true; 128 strDummyTabText = QString(tr("<p><b>No machine</b> is currently selected. Please select a " 129 "Virtual Machine to see its logs")); 130 } 131 /* If machine is valid and check if there are any log files and create viewer tabs: */ 132 else if (!createLogViewerPages()) 133 { 134 noLogsToShow = true; 135 strDummyTabText = QString(tr("<p>No log files found. Press the " 136 "<b>Refresh</b> button to rescan the log folder " 137 "<nobr><b>%1</b></nobr>.</p>")); 138 } 139 /* If the machine is not valid or has no log files show a single viewer tab: */ 140 if (noLogsToShow) 141 { 142 QPlainTextEdit *pDummyLog = createLogPage("VBox.log"); 143 pDummyLog->setWordWrapMode(QTextOption::WordWrap); 144 pDummyLog->appendHtml(strDummyTabText); 145 /* We don't want it to remain white: */ 146 QPalette pal = pDummyLog->palette(); 147 pal.setColor(QPalette::Base, pal.color(QPalette::Window)); 148 pDummyLog->setPalette(pal); 149 } 150 151 /* Show the first tab widget's page after the refresh: */ 152 m_pViewerContainer->setCurrentIndex(0); 153 154 /* Apply the filter settings: */ 155 m_pFilterPanel->applyFilter(); 156 157 /* Setup this connection after refresh to avoid initial signals during page creation: */ 158 connect(m_pViewerContainer, SIGNAL(currentChanged(int)), m_pFilterPanel, SLOT(applyFilter(int))); 159 160 /* Enable/Disable toolbar actions (except Refresh) & tab widget according log presence: */ 161 m_pActionFind->setEnabled(!noLogsToShow); 162 m_pActionFilter->setEnabled(!noLogsToShow); 163 m_pActionSave->setEnabled(!noLogsToShow); 164 m_pViewerContainer->setEnabled(!noLogsToShow); 165 m_pViewerContainer->show(); 166 } 167 168 void UIVMLogViewerWidget::sltSave() 169 { 170 if (m_comMachine.isNull()) 171 return; 172 /* Prepare "save as" dialog: */ 173 const QFileInfo fileInfo(m_book.at(m_pViewerContainer->currentIndex()).first); 174 /* Prepare default filename: */ 175 const QDateTime dtInfo = fileInfo.lastModified(); 176 const QString strDtString = dtInfo.toString("yyyy-MM-dd-hh-mm-ss"); 177 const QString strDefaultFileName = QString("%1-%2.log").arg(m_comMachine.GetName()).arg(strDtString); 178 const QString strDefaultFullName = QDir::toNativeSeparators(QDir::home().absolutePath() + "/" + strDefaultFileName); 179 180 const QString strNewFileName = QIFileDialog::getSaveFileName(strDefaultFullName, 181 "", 182 this, 183 tr("Save VirtualBox Log As"), 184 0 /* selected filter */, 185 true /* resolve symlinks */, 186 true /* confirm overwrite */); 187 /* Make sure file-name is not empty: */ 188 if (!strNewFileName.isEmpty()) 189 { 190 /* Delete the previous file if already exists as user already confirmed: */ 191 if (QFile::exists(strNewFileName)) 192 QFile::remove(strNewFileName); 193 /* Copy log into the file: */ 194 QFile::copy(m_comMachine.QueryLogFilename(m_pViewerContainer->currentIndex()), strNewFileName); 195 } 196 } 197 198 void UIVMLogViewerWidget::sltFilter() 199 { 200 /* Show/hide filter-panel: */ 201 m_pFilterPanel->isHidden() ? m_pFilterPanel->show() : m_pFilterPanel->hide(); 202 } 203 204 void UIVMLogViewerWidget::setMachine(const CMachine &machine) 205 { 206 if (machine == m_comMachine) 207 return; 208 m_comMachine = machine; 209 sltRefresh(); 210 } 211 212 void UIVMLogViewerWidget::prepare() 213 { 214 m_pMainLayout = new QVBoxLayout(this); 215 216 prepareActions(); 217 218 prepareToolBar(); 219 prepareMenu(); 220 221 /* Prepare widgets: */ 222 prepareWidgets(); 223 224 /* Reading log files: */ 225 sltRefresh(); 226 227 /* Loading language constants: */ 228 retranslateUi(); 229 } 230 231 void UIVMLogViewerWidget::prepareWidgets() 232 { 233 /* Configure layout: */ 234 layout()->setContentsMargins(0, 0, 0, 0); 235 #ifdef VBOX_WS_MAC 236 layout()->setSpacing(10); 237 #else 238 const int iS = qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2; 239 layout()->setSpacing(iS); 240 #endif 241 242 /* Create VM Log-Viewer container: */ 243 m_pViewerContainer = new QITabWidget(this); 244 AssertPtrReturnVoid(m_pViewerContainer); 245 { 246 /* Add VM Log-Viewer container to main-layout: */ 247 m_pMainLayout->insertWidget(1, m_pViewerContainer); 248 } 249 250 /* Create VM Log-Viewer search-panel: */ 251 m_pSearchPanel = new UIVMLogViewerSearchPanel(this, this); 252 AssertPtrReturnVoid(m_pSearchPanel); 253 { 254 /* Configure VM Log-Viewer search-panel: */ 255 installEventFilter(m_pSearchPanel); 256 m_pSearchPanel->hide(); 257 /* Add VM Log-Viewer search-panel to main-layout: */ 258 m_pMainLayout->insertWidget(2, m_pSearchPanel); 259 } 260 261 /* Create VM Log-Viewer filter-panel: */ 262 m_pFilterPanel = new UIVMLogViewerFilterPanel(this, this); 263 AssertPtrReturnVoid(m_pFilterPanel); 264 { 265 /* Configure VM Log-Viewer filter-panel: */ 266 installEventFilter(m_pFilterPanel); 267 m_pFilterPanel->hide(); 268 /* Add VM Log-Viewer filter-panel to main-layout: */ 269 m_pMainLayout->insertWidget(3, m_pFilterPanel); 270 } 271 } 272 273 void UIVMLogViewerWidget::prepareActions() 274 { 275 /* Create and configure 'Find' action: */ 276 m_pActionFind = new QAction(this); 277 AssertPtrReturnVoid(m_pActionFind); 278 { 279 m_pActionFind->setShortcut(QKeySequence("Ctrl+F")); 280 connect(m_pActionFind, &QAction::triggered, this, &UIVMLogViewerWidget::sltFind); 281 } 282 283 /* Create and configure 'Filter' action: */ 284 m_pActionFilter = new QAction(this); 285 AssertPtrReturnVoid(m_pActionFilter); 286 { 287 m_pActionFilter->setShortcut(QKeySequence("Ctrl+T")); 288 connect(m_pActionFilter, &QAction::triggered, this, &UIVMLogViewerWidget::sltFilter); 289 } 290 291 /* Create and configure 'Refresh' action: */ 292 m_pActionRefresh = new QAction(this); 293 AssertPtrReturnVoid(m_pActionRefresh); 294 { 295 m_pActionRefresh->setShortcut(QKeySequence("F5")); 296 connect(m_pActionRefresh, &QAction::triggered, this, &UIVMLogViewerWidget::sltRefresh); 297 } 298 299 /* Create and configure 'Save' action: */ 300 m_pActionSave = new QAction(this); 301 AssertPtrReturnVoid(m_pActionSave); 302 { 303 m_pActionSave->setShortcut(QKeySequence("Ctrl+S")); 304 connect(m_pActionSave, &QAction::triggered, this, &UIVMLogViewerWidget::sltSave); 305 } 306 307 /* Update action icons: */ 308 prepareActionIcons(); 309 } 310 311 void UIVMLogViewerWidget::prepareActionIcons() 312 { 313 QString strPrefix = "log_viewer"; 314 315 if (m_pActionFind) 316 m_pActionFind->setIcon(UIIconPool::iconSet(QString(":/%1_find_24px.png").arg(strPrefix), 317 QString(":/%1_find_disabled_24px.png").arg(strPrefix))); 318 319 if (m_pActionFilter) 320 m_pActionFilter->setIcon(UIIconPool::iconSet(QString(":/%1_filter_24px.png").arg(strPrefix), 321 QString(":/%1_filter_disabled_24px.png").arg(strPrefix))); 322 323 324 if (m_pActionRefresh) 325 m_pActionRefresh->setIcon(UIIconPool::iconSet(QString(":/%1_refresh_24px.png").arg(strPrefix), 326 QString(":/%1_refresh_disabled_24px.png").arg(strPrefix))); 327 328 329 if (m_pActionSave) 330 m_pActionSave->setIcon(UIIconPool::iconSet(QString(":/%1_save_24px.png").arg(strPrefix), 331 QString(":/%1_save_disabled_24px.png").arg(strPrefix))); 332 333 334 } 335 336 void UIVMLogViewerWidget::prepareToolBar() 337 { 338 /* Create toolbar: */ 339 m_pToolBar = new UIToolBar(parentWidget()); 340 AssertPtrReturnVoid(m_pToolBar); 341 { 342 /* Configure toolbar: */ 343 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.375); 344 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 345 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 346 /* Add toolbar actions: */ 347 if (m_pActionFind) 348 m_pToolBar->addAction(m_pActionFind); 349 350 if (m_pActionFilter) 351 m_pToolBar->addAction(m_pActionFilter); 352 353 if (m_pActionRefresh) 354 m_pToolBar->addAction(m_pActionRefresh); 355 356 if (m_pActionSave) 357 m_pToolBar->addAction(m_pActionSave); 358 359 #ifdef VBOX_WS_MAC 360 /* Check whether we are embedded into a stack: */ 361 if (m_enmEmbedding == EmbedTo_Stack) 362 { 363 /* Add into layout: */ 364 layout()->addWidget(m_pToolBar); 365 } 366 #else 367 /* Add into layout: */ 368 m_pMainLayout->insertWidget(0, m_pToolBar); 369 #endif 370 } 371 } 372 373 void UIVMLogViewerWidget::prepareMenu() 374 { 375 /* Create 'LogViewer' menu: */ 376 m_pMenu = new QMenu(this); 377 AssertPtrReturnVoid(m_pMenu); 378 { 379 if (m_pActionFind) 380 m_pMenu->addAction(m_pActionFind); 381 if (m_pActionFilter) 382 m_pMenu->addAction(m_pActionFilter); 383 if (m_pActionRefresh) 384 m_pMenu->addAction(m_pActionRefresh); 385 if (m_pActionSave) 386 m_pMenu->addAction(m_pActionSave); 387 } 388 } 389 390 void UIVMLogViewerWidget::cleanup() 391 { 392 } 393 394 void UIVMLogViewerWidget::retranslateUi() 395 { 396 if (m_pMenu) 397 { 398 m_pMenu->setTitle(tr("&Log Viewer")); 399 } 400 401 if (m_pActionFind) 402 { 403 m_pActionFind->setText(tr("&Find")); 404 m_pActionFind->setToolTip(tr("Find a string within the log")); 405 m_pActionFind->setStatusTip(tr("Find a string within the log")); 406 } 407 408 if (m_pActionFilter) 409 { 410 m_pActionFilter->setText(tr("&Filter")); 411 m_pActionFilter->setToolTip(tr("Filter the log wrt. the given string")); 412 m_pActionFilter->setStatusTip(tr("Filter the log wrt. the given string")); 413 } 414 415 if (m_pActionRefresh) 416 { 417 m_pActionRefresh->setText(tr("&Refresh")); 418 m_pActionRefresh->setToolTip(tr("Reload the log")); 419 m_pActionRefresh->setStatusTip(tr("Reload the log")); 420 } 421 422 if (m_pActionSave) 423 { 424 m_pActionSave->setText(tr("&Save...")); 425 m_pActionSave->setToolTip(tr("Save the log")); 426 m_pActionSave->setStatusTip(tr("Save the log")); 427 } 428 429 /* Translate toolbar: */ 430 #ifdef VBOX_WS_MAC 431 // WORKAROUND: 432 // There is a bug in Qt Cocoa which result in showing a "more arrow" when 433 // the necessary size of the toolbar is increased. Also for some languages 434 // the with doesn't match if the text increase. So manually adjust the size 435 // after changing the text. */ 436 if (m_pToolBar) 437 m_pToolBar->updateLayout(); 438 #endif 439 } 440 441 void UIVMLogViewerWidget::showEvent(QShowEvent *pEvent) 442 { 443 QWidget::showEvent(pEvent); 444 445 /* One may think that QWidget::polish() is the right place to do things 446 * below, but apparently, by the time when QWidget::polish() is called, 447 * the widget style & layout are not fully done, at least the minimum 448 * size hint is not properly calculated. Since this is sometimes necessary, 449 * we provide our own "polish" implementation: */ 450 451 if (m_fIsPolished) 452 return; 453 454 m_fIsPolished = true; 455 456 /* Make sure the log view widget has the focus: */ 457 QWidget *pCurrentLogPage = currentLogPage(); 458 if (pCurrentLogPage) 459 pCurrentLogPage->setFocus(); 460 } 461 462 void UIVMLogViewerWidget::keyPressEvent(QKeyEvent *pEvent) 463 { 464 /* Depending on key pressed: */ 465 switch (pEvent->key()) 466 { 467 /* Process key escape as VM Log Viewer close: */ 468 case Qt::Key_Escape: 469 { 470 return; 471 } 472 /* Process Back key as switch to previous tab: */ 473 case Qt::Key_Back: 474 { 475 if (m_pViewerContainer->currentIndex() > 0) 476 { 477 m_pViewerContainer->setCurrentIndex(m_pViewerContainer->currentIndex() - 1); 478 return; 479 } 480 break; 481 } 482 /* Process Forward key as switch to next tab: */ 483 case Qt::Key_Forward: 484 { 485 if (m_pViewerContainer->currentIndex() < m_pViewerContainer->count()) 486 { 487 m_pViewerContainer->setCurrentIndex(m_pViewerContainer->currentIndex() + 1); 488 return; 489 } 490 break; 491 } 492 default: 493 break; 494 } 495 QWidget::keyReleaseEvent(pEvent); 496 } 497 498 QPlainTextEdit* UIVMLogViewerWidget::currentLogPage() const 499 { 500 /* If viewer-container is enabled: */ 501 if (m_pViewerContainer->isEnabled()) 502 { 503 /* Get and return current log-page: */ 504 QWidget *pContainer = m_pViewerContainer->currentWidget(); 505 QPlainTextEdit *pBrowser = pContainer->findChild<QPlainTextEdit*>(); 506 Assert(pBrowser); 507 return pBrowser ? pBrowser : 0; 508 } 509 /* Return NULL by default: */ 510 return 0; 511 } 512 513 bool UIVMLogViewerWidget::createLogViewerPages() 514 { 515 if (m_comMachine.isNull()) 516 return false; 517 518 bool logsExists = false; 122 519 const CSystemProperties &sys = vboxGlobal().virtualBox().GetSystemProperties(); 123 520 unsigned cMaxLogs = sys.GetLogHistoryCount() + 1 /*VBox.log*/ + 1 /*VBoxHardening.log*/; /** @todo Add api for getting total possible log count! */ … … 153 550 /* Add the log-text to the map: */ 154 551 m_logMap[pLogViewer] = strText; 155 isAnyLogPresent= true;552 logsExists = true; 156 553 } 157 554 } 158 555 } 159 160 /* Create an empty log page if there are no logs at all: */ 161 if (!isAnyLogPresent) 162 { 163 QPlainTextEdit *pDummyLog = createLogPage("VBox.log"); 164 pDummyLog->setWordWrapMode(QTextOption::WordWrap); 165 pDummyLog->appendHtml(tr("<p>No log files found. Press the " 166 "<b>Refresh</b> button to rescan the log folder " 167 "<nobr><b>%1</b></nobr>.</p>") 168 .arg(m_comMachine.GetLogFolder())); 169 /* We don't want it to remain white: */ 170 QPalette pal = pDummyLog->palette(); 171 pal.setColor(QPalette::Base, pal.color(QPalette::Window)); 172 pDummyLog->setPalette(pal); 173 } 174 175 /* Show the first tab widget's page after the refresh: */ 176 m_pViewerContainer->setCurrentIndex(0); 177 178 /* Apply the filter settings: */ 179 m_pFilterPanel->applyFilter(); 180 181 /* Setup this connection after refresh to avoid initial signals during page creation: */ 182 connect(m_pViewerContainer, SIGNAL(currentChanged(int)), m_pFilterPanel, SLOT(applyFilter(int))); 183 184 /* Enable/Disable toolbar actions (except Refresh) & tab widget according log presence: */ 185 m_pActionFind->setEnabled(isAnyLogPresent); 186 m_pActionFilter->setEnabled(isAnyLogPresent); 187 m_pActionSave->setEnabled(isAnyLogPresent); 188 m_pViewerContainer->setEnabled(isAnyLogPresent); 189 } 190 191 void UIVMLogViewerWidget::sltSave() 192 { 193 /* Prepare "save as" dialog: */ 194 const QFileInfo fileInfo(m_book.at(m_pViewerContainer->currentIndex()).first); 195 /* Prepare default filename: */ 196 const QDateTime dtInfo = fileInfo.lastModified(); 197 const QString strDtString = dtInfo.toString("yyyy-MM-dd-hh-mm-ss"); 198 const QString strDefaultFileName = QString("%1-%2.log").arg(m_comMachine.GetName()).arg(strDtString); 199 const QString strDefaultFullName = QDir::toNativeSeparators(QDir::home().absolutePath() + "/" + strDefaultFileName); 200 /* Show "save as" dialog: */ 201 const QString strNewFileName = QIFileDialog::getSaveFileName(strDefaultFullName, 202 "", 203 this, 204 tr("Save VirtualBox Log As"), 205 0 /* selected filter */, 206 true /* resolve symlinks */, 207 true /* confirm overwrite */); 208 /* Make sure file-name is not empty: */ 209 if (!strNewFileName.isEmpty()) 210 { 211 /* Delete the previous file if already exists as user already confirmed: */ 212 if (QFile::exists(strNewFileName)) 213 QFile::remove(strNewFileName); 214 /* Copy log into the file: */ 215 QFile::copy(m_comMachine.QueryLogFilename(m_pViewerContainer->currentIndex()), strNewFileName); 216 } 217 } 218 219 void UIVMLogViewerWidget::sltFilter() 220 { 221 /* Show/hide filter-panel: */ 222 m_pFilterPanel->isHidden() ? m_pFilterPanel->show() : m_pFilterPanel->hide(); 223 } 224 225 void UIVMLogViewerWidget::prepare() 226 { 227 m_pMainLayout = new QVBoxLayout(this); 228 229 prepareActions(); 230 231 prepareToolBar(); 232 prepareMenu(); 233 234 /* Prepare widgets: */ 235 prepareWidgets(); 236 237 /* Reading log files: */ 238 sltRefresh(); 239 240 /* Loading language constants: */ 241 retranslateUi(); 242 } 243 244 void UIVMLogViewerWidget::prepareWidgets() 245 { 246 /* Configure layout: */ 247 layout()->setContentsMargins(0, 0, 0, 0); 248 #ifdef VBOX_WS_MAC 249 layout()->setSpacing(10); 250 #else 251 const int iS = qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2; 252 layout()->setSpacing(iS); 253 #endif 254 255 /* Create VM Log-Viewer container: */ 256 m_pViewerContainer = new QITabWidget(this); 257 AssertPtrReturnVoid(m_pViewerContainer); 258 { 259 /* Add VM Log-Viewer container to main-layout: */ 260 m_pMainLayout->insertWidget(1, m_pViewerContainer); 261 } 262 263 /* Create VM Log-Viewer search-panel: */ 264 m_pSearchPanel = new UIVMLogViewerSearchPanel(this, this); 265 AssertPtrReturnVoid(m_pSearchPanel); 266 { 267 /* Configure VM Log-Viewer search-panel: */ 268 installEventFilter(m_pSearchPanel); 269 m_pSearchPanel->hide(); 270 /* Add VM Log-Viewer search-panel to main-layout: */ 271 m_pMainLayout->insertWidget(2, m_pSearchPanel); 272 } 273 274 /* Create VM Log-Viewer filter-panel: */ 275 m_pFilterPanel = new UIVMLogViewerFilterPanel(this, this); 276 AssertPtrReturnVoid(m_pFilterPanel); 277 { 278 /* Configure VM Log-Viewer filter-panel: */ 279 installEventFilter(m_pFilterPanel); 280 m_pFilterPanel->hide(); 281 /* Add VM Log-Viewer filter-panel to main-layout: */ 282 m_pMainLayout->insertWidget(3, m_pFilterPanel); 283 } 284 } 285 286 void UIVMLogViewerWidget::prepareActions() 287 { 288 /* Create and configure 'Find' action: */ 289 m_pActionFind = new QAction(this); 290 AssertPtrReturnVoid(m_pActionFind); 291 { 292 m_pActionFind->setShortcut(QKeySequence("Ctrl+F")); 293 connect(m_pActionFind, &QAction::triggered, this, &UIVMLogViewerWidget::sltFind); 294 } 295 296 /* Create and configure 'Filter' action: */ 297 m_pActionFilter = new QAction(this); 298 AssertPtrReturnVoid(m_pActionFilter); 299 { 300 m_pActionFilter->setShortcut(QKeySequence("Ctrl+T")); 301 connect(m_pActionFilter, &QAction::triggered, this, &UIVMLogViewerWidget::sltFilter); 302 } 303 304 /* Create and configure 'Refresh' action: */ 305 m_pActionRefresh = new QAction(this); 306 AssertPtrReturnVoid(m_pActionRefresh); 307 { 308 m_pActionRefresh->setShortcut(QKeySequence("F5")); 309 connect(m_pActionRefresh, &QAction::triggered, this, &UIVMLogViewerWidget::sltRefresh); 310 } 311 312 /* Create and configure 'Save' action: */ 313 m_pActionSave = new QAction(this); 314 AssertPtrReturnVoid(m_pActionSave); 315 { 316 m_pActionSave->setShortcut(QKeySequence("Ctrl+S")); 317 connect(m_pActionSave, &QAction::triggered, this, &UIVMLogViewerWidget::sltSave); 318 } 319 320 /* Update action icons: */ 321 prepareActionIcons(); 322 } 323 324 void UIVMLogViewerWidget::prepareActionIcons() 325 { 326 QString strPrefix = "log_viewer"; 327 328 if (m_pActionFind) 329 m_pActionFind->setIcon(UIIconPool::iconSet(QString(":/%1_find_24px.png").arg(strPrefix), 330 QString(":/%1_find_disabled_24px.png").arg(strPrefix))); 331 332 if (m_pActionFilter) 333 m_pActionFilter->setIcon(UIIconPool::iconSet(QString(":/%1_filter_24px.png").arg(strPrefix), 334 QString(":/%1_filter_disabled_24px.png").arg(strPrefix))); 335 336 337 if (m_pActionRefresh) 338 m_pActionRefresh->setIcon(UIIconPool::iconSet(QString(":/%1_refresh_24px.png").arg(strPrefix), 339 QString(":/%1_refresh_disabled_24px.png").arg(strPrefix))); 340 341 342 if (m_pActionSave) 343 m_pActionSave->setIcon(UIIconPool::iconSet(QString(":/%1_save_24px.png").arg(strPrefix), 344 QString(":/%1_save_disabled_24px.png").arg(strPrefix))); 345 346 347 } 348 349 void UIVMLogViewerWidget::prepareToolBar() 350 { 351 /* Create toolbar: */ 352 m_pToolBar = new UIToolBar(parentWidget()); 353 AssertPtrReturnVoid(m_pToolBar); 354 { 355 /* Configure toolbar: */ 356 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.375); 357 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 358 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 359 /* Add toolbar actions: */ 360 if (m_pActionFind) 361 m_pToolBar->addAction(m_pActionFind); 362 363 if (m_pActionFilter) 364 m_pToolBar->addAction(m_pActionFilter); 365 366 if (m_pActionRefresh) 367 m_pToolBar->addAction(m_pActionRefresh); 368 369 if (m_pActionSave) 370 m_pToolBar->addAction(m_pActionSave); 371 372 #ifdef VBOX_WS_MAC 373 /* Check whether we are embedded into a stack: */ 374 if (m_enmEmbedding == EmbedTo_Stack) 375 { 376 /* Add into layout: */ 377 layout()->addWidget(m_pToolBar); 378 } 379 #else 380 /* Add into layout: */ 381 m_pMainLayout->insertWidget(0, m_pToolBar); 382 #endif 383 } 384 } 385 386 void UIVMLogViewerWidget::prepareMenu() 387 { 388 /* Create 'LogViewer' menu: */ 389 m_pMenu = new QMenu(this); 390 AssertPtrReturnVoid(m_pMenu); 391 { 392 if (m_pActionFind) 393 m_pMenu->addAction(m_pActionFind); 394 if (m_pActionFilter) 395 m_pMenu->addAction(m_pActionFilter); 396 if (m_pActionRefresh) 397 m_pMenu->addAction(m_pActionRefresh); 398 if (m_pActionSave) 399 m_pMenu->addAction(m_pActionSave); 400 } 401 } 402 403 void UIVMLogViewerWidget::cleanup() 404 { 405 } 406 407 void UIVMLogViewerWidget::retranslateUi() 408 { 409 if(m_pMenu) 410 { 411 m_pMenu->setTitle(tr("&Log Viewer")); 412 } 413 414 if (m_pActionFind) 415 { 416 m_pActionFind->setText(tr("&Find...")); 417 m_pActionFind->setToolTip(tr("Find a string within the log")); 418 m_pActionFind->setStatusTip(tr("Find a string within the log")); 419 } 420 421 if (m_pActionFilter) 422 { 423 m_pActionFilter->setText(tr("&Filter...")); 424 m_pActionFilter->setToolTip(tr("Filter the log wrt. the given string")); 425 m_pActionFilter->setStatusTip(tr("Filter the log wrt. the given string")); 426 } 427 428 if (m_pActionRefresh) 429 { 430 m_pActionRefresh->setText(tr("&Refresh...")); 431 m_pActionRefresh->setToolTip(tr("Reload the log")); 432 m_pActionRefresh->setStatusTip(tr("Reload the log")); 433 } 434 435 if (m_pActionSave) 436 { 437 m_pActionSave->setText(tr("&Save...")); 438 m_pActionSave->setToolTip(tr("Save the log")); 439 m_pActionSave->setStatusTip(tr("Save the log")); 440 } 441 442 /* Translate toolbar: */ 443 #ifdef VBOX_WS_MAC 444 // WORKAROUND: 445 // There is a bug in Qt Cocoa which result in showing a "more arrow" when 446 // the necessary size of the toolbar is increased. Also for some languages 447 // the with doesn't match if the text increase. So manually adjust the size 448 // after changing the text. */ 449 if (m_pToolBar) 450 m_pToolBar->updateLayout(); 451 #endif 452 } 453 454 void UIVMLogViewerWidget::showEvent(QShowEvent *pEvent) 455 { 456 QWidget::showEvent(pEvent); 457 458 /* One may think that QWidget::polish() is the right place to do things 459 * below, but apparently, by the time when QWidget::polish() is called, 460 * the widget style & layout are not fully done, at least the minimum 461 * size hint is not properly calculated. Since this is sometimes necessary, 462 * we provide our own "polish" implementation: */ 463 464 if (m_fIsPolished) 465 return; 466 467 m_fIsPolished = true; 468 469 /* Make sure the log view widget has the focus: */ 470 QWidget *pCurrentLogPage = currentLogPage(); 471 if (pCurrentLogPage) 472 pCurrentLogPage->setFocus(); 473 } 474 475 void UIVMLogViewerWidget::keyPressEvent(QKeyEvent *pEvent) 476 { 477 /* Depending on key pressed: */ 478 switch (pEvent->key()) 479 { 480 /* Process key escape as VM Log Viewer close: */ 481 case Qt::Key_Escape: 482 { 483 return; 484 } 485 /* Process Back key as switch to previous tab: */ 486 case Qt::Key_Back: 487 { 488 if (m_pViewerContainer->currentIndex() > 0) 489 { 490 m_pViewerContainer->setCurrentIndex(m_pViewerContainer->currentIndex() - 1); 491 return; 492 } 493 break; 494 } 495 /* Process Forward key as switch to next tab: */ 496 case Qt::Key_Forward: 497 { 498 if (m_pViewerContainer->currentIndex() < m_pViewerContainer->count()) 499 { 500 m_pViewerContainer->setCurrentIndex(m_pViewerContainer->currentIndex() + 1); 501 return; 502 } 503 break; 504 } 505 default: 506 break; 507 } 508 QWidget::keyReleaseEvent(pEvent); 509 } 510 511 QPlainTextEdit* UIVMLogViewerWidget::currentLogPage() const 512 { 513 /* If viewer-container is enabled: */ 514 if (m_pViewerContainer->isEnabled()) 515 { 516 /* Get and return current log-page: */ 517 QWidget *pContainer = m_pViewerContainer->currentWidget(); 518 QPlainTextEdit *pBrowser = pContainer->findChild<QPlainTextEdit*>(); 519 Assert(pBrowser); 520 return pBrowser ? pBrowser : 0; 521 } 522 /* Return NULL by default: */ 523 return 0; 556 return logsExists; 524 557 } 525 558 … … 562 595 return m_logMap[currentLogPage()]; 563 596 } 564 -
trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h
r70139 r70185 54 54 /** Constructs the VM Log-Viewer by passing @a pParent to QWidget base-class constructor. 55 55 * @param machine Specifies the machine for which VM Log-Viewer is requested. */ 56 UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent , const CMachine &machine);56 UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent = 0, const CMachine &machine = CMachine()); 57 57 /** Destructs the VM Log-Viewer. */ 58 58 ~UIVMLogViewerWidget(); … … 67 67 UIToolBar *toolbar() const { return m_pToolBar; } 68 68 #endif 69 70 /** Sets the machine whose logs to show. */ 71 void setMachine(const CMachine &machine); 69 72 70 73 protected: … … 120 123 const QString& currentLog(); 121 124 125 /** Attempts to read the logs through the API, returns true if there exists any logs, false otherwise. */ 126 bool createLogViewerPages(); 127 122 128 /** Holds whether the dialog is polished. */ 123 129 bool m_fIsPolished; -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.cpp
r69500 r70185 1021 1021 setName(QApplication::translate("UIActionPool", "&Snapshots")); 1022 1022 setStatusTip(QApplication::translate("UIActionPool", "Open the machine snapshots pane")); 1023 } 1024 }; 1025 1026 class UIActionSimpleToolsMachineLogViewer : public UIActionSimple 1027 { 1028 Q_OBJECT; 1029 1030 public: 1031 1032 UIActionSimpleToolsMachineLogViewer(UIActionPool *pParent) 1033 : UIActionSimple(pParent, 1034 ":/vm_show_logs_32px.png", ":/vm_show_logs_32px.png", 1035 ":/vm_show_logs_32px.png", ":/vm_show_logs_32px.png") {} 1036 1037 protected: 1038 1039 QString shortcutExtraDataID() const 1040 { 1041 return QString("ToolsMachineLogViewer"); 1042 } 1043 1044 void retranslateUi() 1045 { 1046 setName(QApplication::translate("UIActionPool", "&LogViewer")); 1047 setStatusTip(QApplication::translate("UIActionPool", "Open the machine logviewer pane")); 1023 1048 } 1024 1049 }; … … 1320 1345 m_pool[UIActionIndexST_M_Tools_M_Machine_S_Details] = new UIActionSimpleToolsMachineDetails(this); 1321 1346 m_pool[UIActionIndexST_M_Tools_M_Machine_S_Snapshots] = new UIActionSimpleToolsMachineSnapshots(this); 1347 m_pool[UIActionIndexST_M_Tools_M_Machine_S_LogViewer] = new UIActionSimpleToolsMachineLogViewer(this); 1322 1348 1323 1349 /* Global Tools actions: */ -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.h
r69500 r70185 97 97 UIActionIndexST_M_Tools_M_Machine_S_Details, 98 98 UIActionIndexST_M_Tools_M_Machine_S_Snapshots, 99 UIActionIndexST_M_Tools_M_Machine_S_LogViewer, 99 100 100 101 /* Global Tools actions: */ -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
r70147 r70185 159 159 mapActionsMachine[ToolTypeMachine_Details] = actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_Details); 160 160 mapActionsMachine[ToolTypeMachine_Snapshots] = actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_Snapshots); 161 mapActionsMachine[ToolTypeMachine_LogViewer] = actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer); 161 162 for (int i = m_orderMachine.size() - 1; i >= 0; --i) 162 163 if (m_orderMachine.at(i) != ToolTypeMachine_Invalid) … … 251 252 252 253 void UISelectorWindow::sltHandleChooserPaneIndexChange(bool fUpdateDetails /* = true */, 253 bool fUpdateSnapshots /* = true */) 254 bool fUpdateSnapshots /* = true */, 255 bool fUpdateLogViewer /* = true*/) 254 256 { 255 257 /* Get current item: */ … … 279 281 if (m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Snapshots)) 280 282 actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_Snapshots)->trigger(); 283 else 284 if (m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_LogViewer)) 285 actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer)->trigger(); 281 286 } 282 287 … … 285 290 && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Details)) 286 291 m_pPaneToolsMachine->setItems(currentItems()); 287 /* Update Snapshots-pane (if requested): */ 288 if ( fUpdateSnapshots 289 && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Snapshots)) 292 /* Update the Snapshots-pane or/and Logviewer-pane (if requested): */ 293 if (fUpdateSnapshots || fUpdateLogViewer) 290 294 m_pPaneToolsMachine->setMachine(pItem->machine()); 291 295 } … … 306 310 if (m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Details)) 307 311 m_pPaneToolsMachine->setItems(currentItems()); 308 /* Update Snapshots-pane (in any case): */ 309 if (m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Snapshots)) 310 m_pPaneToolsMachine->setMachine(CMachine()); 312 /* Update Snapshots-pane and Logviewer-pane (in any case): */ 313 m_pPaneToolsMachine->setMachine(CMachine()); 311 314 } 312 315 } … … 1141 1144 1142 1145 /* Make sure chosen item fetched: */ 1143 sltHandleChooserPaneIndexChange(false /* update details? */, false /* update snapshots? */ );1146 sltHandleChooserPaneIndexChange(false /* update details? */, false /* update snapshots? */, false /* update the logviewer? */); 1144 1147 } 1145 1148 … … 1170 1173 m_pPaneToolsMachine->setItems(currentItems()); 1171 1174 /* If that was 'Snapshot' => pass there current or null machine: */ 1172 if ( enmType == ToolTypeMachine_Snapshots 1173 && m_pPaneToolsMachine->isToolOpened(ToolTypeMachine_Snapshots)) 1175 if (enmType == ToolTypeMachine_Snapshots || enmType == ToolTypeMachine_LogViewer) 1174 1176 { 1175 1177 UIVMItem *pItem = currentItem(); … … 1226 1228 1227 1229 /* Make sure chosen item fetched: */ 1228 sltHandleChooserPaneIndexChange(false /* update details? */, false /* update snapshots? */ );1230 sltHandleChooserPaneIndexChange(false /* update details? */, false /* update snapshots? */, false /* update the logviewer? */); 1229 1231 1230 1232 #ifdef VBOX_WS_MAC … … 2430 2432 actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_Details)->setEnabled(isActionEnabled(UIActionIndexST_M_Tools_M_Machine_S_Details, items)); 2431 2433 actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_Snapshots)->setEnabled(isActionEnabled(UIActionIndexST_M_Tools_M_Machine_S_Snapshots, items)); 2434 actionPool()->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer)->setEnabled(isActionEnabled(UIActionIndexST_M_Tools_M_Machine_S_LogViewer, items)); 2432 2435 } 2433 2436 … … 2559 2562 case UIActionIndexST_M_Tools_M_Machine_S_Details: 2560 2563 case UIActionIndexST_M_Tools_M_Machine_S_Snapshots: 2564 case UIActionIndexST_M_Tools_M_Machine_S_LogViewer: 2561 2565 { 2562 2566 return pItem->accessible(); -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.h
r70029 r70185 93 93 * @param fUpdateSnapshots Brings whether tools should be updated. */ 94 94 void sltHandleChooserPaneIndexChange(bool fUpdateDetails = true, 95 bool fUpdateSnapshots = true); 95 bool fUpdateSnapshots = true, 96 bool fUpdateLogViewer = true); 96 97 97 98 /** Handles signal about medium-enumeration finished. */ -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIToolsPaneMachine.cpp
r69726 r70185 32 32 # include "UIToolsPaneMachine.h" 33 33 # include "UIVMItem.h" 34 # include "UIVMLogViewerWidget.h" 34 35 35 36 /* Other VBox includes: */ … … 47 48 , m_pPaneDetails(0) 48 49 , m_pPaneSnapshots(0) 50 , m_pPaneLogViewer(0) 49 51 { 50 52 /* Prepare: */ … … 141 143 break; 142 144 } 145 case ToolTypeMachine_LogViewer: 146 { 147 /* Create the Logviewer pane: */ 148 m_pPaneLogViewer = new UIVMLogViewerWidget(EmbedTo_Stack); 149 AssertPtrReturnVoid(m_pPaneLogViewer); 150 { 151 /* Configure pane: */ 152 m_pPaneLogViewer->setProperty("ToolType", QVariant::fromValue(ToolTypeMachine_LogViewer)); 153 154 /* Add into layout: */ 155 m_pLayout->addWidget(m_pPaneLogViewer); 156 m_pLayout->setCurrentWidget(m_pPaneLogViewer); 157 } 158 break; 159 } 143 160 default: 144 161 AssertFailedReturnVoid(); … … 164 181 case ToolTypeMachine_Details: m_pPaneDetails = 0; break; 165 182 case ToolTypeMachine_Snapshots: m_pPaneSnapshots = 0; break; 183 case ToolTypeMachine_LogViewer: m_pPaneLogViewer = 0; break; 166 184 default: break; 167 185 } … … 203 221 void UIToolsPaneMachine::setMachine(const CMachine &comMachine) 204 222 { 205 /* Update snapshots pane: */ 206 AssertPtrReturnVoid(m_pPaneSnapshots); 207 m_pPaneSnapshots->setMachine(comMachine); 223 /* Update snapshots pane is it is open: */ 224 if(isToolOpened(ToolTypeMachine_Snapshots)) 225 { 226 AssertPtrReturnVoid(m_pPaneSnapshots); 227 m_pPaneSnapshots->setMachine(comMachine); 228 } 229 /* Update logviewer pane is it is open: */ 230 if(isToolOpened(ToolTypeMachine_LogViewer)) 231 { 232 AssertPtrReturnVoid(m_pPaneLogViewer); 233 m_pPaneLogViewer->setMachine(comMachine); 234 } 208 235 } 209 236 … … 265 292 "<u>restore</u> (make current) and observe their properties. Allows to " 266 293 "<u>edit</u> snapshot attributes like <u>name</u> and <u>description</u>.")); 294 QAction *pAction3 = m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer); 295 m_pPaneDesktop->addToolDescription(pAction3, 296 tr("Tool to display virtual machine (VM) logs. ")); 267 297 } 268 298 } -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIToolsPaneMachine.h
r68304 r70185 33 33 class UIDesktopPane; 34 34 class UIGDetails; 35 class UIVMLogViewerWidget; 35 36 class UISnapshotPane; 36 37 class UIVMItem; … … 103 104 104 105 /** Holds the stacked-layout instance. */ 105 QStackedLayout *m_pLayout;106 QStackedLayout *m_pLayout; 106 107 /** Holds the Desktop pane instance. */ 107 UIDesktopPane *m_pPaneDesktop;108 UIDesktopPane *m_pPaneDesktop; 108 109 /** Holds the Details pane instance. */ 109 UIGDetails *m_pPaneDetails;110 UIGDetails *m_pPaneDetails; 110 111 /** Holds the Snapshots pane instance. */ 111 UISnapshotPane *m_pPaneSnapshots; 112 UISnapshotPane *m_pPaneSnapshots; 113 /** Holds the Logviewer pane instance. */ 114 UIVMLogViewerWidget *m_pPaneLogViewer; 112 115 }; 113 116 -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIToolsToolbar.cpp
r69260 r70185 219 219 m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_Snapshots) 220 220 ->setProperty("ToolTypeMachine", QVariant::fromValue(ToolTypeMachine_Snapshots)); 221 222 /* Add 'LogViewer' action: */ 223 pMenuMachine->addAction(m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer)); 224 connect(m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer), &UIAction::triggered, 225 this, &UIToolsToolbar::sltHandleOpenToolMachine); 226 m_pActionPool->action(UIActionIndexST_M_Tools_M_Machine_S_LogViewer) 227 ->setProperty("ToolTypeMachine", QVariant::fromValue(ToolTypeMachine_LogViewer)); 221 228 } 222 229
Note:
See TracChangeset
for help on using the changeset viewer.