Changeset 77455 in vbox
- Timestamp:
- Feb 25, 2019 10:55:14 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 129028
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r77432 r77455 1050 1050 src/manager/details/UIDetailsView.cpp \ 1051 1051 src/manager/details/UIDetailsItem.cpp \ 1052 src/manager/details/UIDetailsGenerator.cpp \ 1052 1053 src/manager/details/UIDetailsGroup.cpp \ 1053 1054 src/manager/details/UIDetailsSet.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIDetailsElements.cpp
r77428 r77455 23 23 /* GUI includes: */ 24 24 #include "UIDetailsElements.h" 25 #include "UIDetailsGenerator.h" 25 26 #include "UIDetailsModel.h" 26 27 #include "UIMachinePreview.h" … … 50 51 #include "CMedium.h" 51 52 52 53 53 UIDetailsUpdateTask::UIDetailsUpdateTask(const CMachine &machine) 54 54 : UITask(UITask::Type_DetailsPopulation) … … 229 229 return; 230 230 231 /* Prepare table: */ 232 UITextTable table; 233 234 /* Gather information: */ 235 if (comMachine.GetAccessible()) 236 { 237 /* Name: */ 238 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_Name) 239 table << UITextTableLine(QApplication::translate("UIDetails", "Name", "details (general)"), comMachine.GetName()); 240 241 /* Operating system: */ 242 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_OS) 243 table << UITextTableLine(QApplication::translate("UIDetails", "Operating System", "details (general)"), 244 vboxGlobal().vmGuestOSTypeDescription(comMachine.GetOSTypeId())); 245 246 /* Settings file location: */ 247 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_Location) 248 table << UITextTableLine(QApplication::translate("UIDetails", "Settings File Location", "details (general)"), 249 QDir::toNativeSeparators(QFileInfo(comMachine.GetSettingsFilePath()).absolutePath())); 250 251 /* Groups: */ 252 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_Groups) 253 { 254 QStringList groups = comMachine.GetGroups().toList(); 255 /* Do not show groups for machine which is in root group only: */ 256 if (groups.size() == 1) 257 groups.removeAll("/"); 258 /* If group list still not empty: */ 259 if (!groups.isEmpty()) 260 { 261 /* For every group: */ 262 for (int i = 0; i < groups.size(); ++i) 263 { 264 /* Trim first '/' symbol: */ 265 QString &strGroup = groups[i]; 266 if (strGroup.startsWith("/") && strGroup != "/") 267 strGroup.remove(0, 1); 268 } 269 table << UITextTableLine(QApplication::translate("UIDetails", "Groups", "details (general)"), groups.join(", ")); 270 } 271 } 272 } 273 else 274 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 275 276 /* Save the table as property: */ 231 /* Generate the table: */ 232 UITextTable table = UIDetailsGenerator::generateMachineInformationGeneral(comMachine, m_fOptions); 277 233 setProperty("table", QVariant::fromValue(table)); 278 234 } … … 292 248 293 249 /* Prepare table: */ 294 UITextTable table; 295 296 /* Gather information: */ 297 if (comMachine.GetAccessible()) 298 { 299 /* Base memory: */ 300 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_RAM) 301 table << UITextTableLine(QApplication::translate("UIDetails", "Base Memory", "details (system)"), 302 QApplication::translate("UIDetails", "%1 MB", "details").arg(comMachine.GetMemorySize())); 303 304 /* Processors: */ 305 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_CPUCount) 306 { 307 const int cCPU = comMachine.GetCPUCount(); 308 if (cCPU > 1) 309 table << UITextTableLine(QApplication::translate("UIDetails", "Processors", "details (system)"), 310 QString::number(cCPU)); 311 } 312 313 /* Execution cap: */ 314 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_CPUExecutionCap) 315 { 316 const int iCPUExecutionCap = comMachine.GetCPUExecutionCap(); 317 if (iCPUExecutionCap < 100) 318 table << UITextTableLine(QApplication::translate("UIDetails", "Execution Cap", "details (system)"), 319 QApplication::translate("UIDetails", "%1%", "details").arg(iCPUExecutionCap)); 320 } 321 322 /* Boot order: */ 323 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_BootOrder) 324 { 325 QStringList bootOrder; 326 for (ulong i = 1; i <= vboxGlobal().virtualBox().GetSystemProperties().GetMaxBootPosition(); ++i) 327 { 328 const KDeviceType enmDeviceType = comMachine.GetBootOrder(i); 329 if (enmDeviceType == KDeviceType_Null) 330 continue; 331 bootOrder << gpConverter->toString(enmDeviceType); 332 } 333 if (bootOrder.isEmpty()) 334 bootOrder << gpConverter->toString(KDeviceType_Null); 335 table << UITextTableLine(QApplication::translate("UIDetails", "Boot Order", "details (system)"), bootOrder.join(", ")); 336 } 337 338 /* Chipset type: */ 339 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_ChipsetType) 340 { 341 const KChipsetType enmChipsetType = comMachine.GetChipsetType(); 342 if (enmChipsetType == KChipsetType_ICH9) 343 table << UITextTableLine(QApplication::translate("UIDetails", "Chipset Type", "details (system)"), 344 gpConverter->toString(enmChipsetType)); 345 } 346 347 /* EFI: */ 348 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_Firmware) 349 { 350 switch (comMachine.GetFirmwareType()) 351 { 352 case KFirmwareType_EFI: 353 case KFirmwareType_EFI32: 354 case KFirmwareType_EFI64: 355 case KFirmwareType_EFIDUAL: 356 { 357 table << UITextTableLine(QApplication::translate("UIDetails", "EFI", "details (system)"), 358 QApplication::translate("UIDetails", "Enabled", "details (system/EFI)")); 359 break; 360 } 361 default: 362 { 363 // For NLS purpose: 364 QApplication::translate("UIDetails", "Disabled", "details (system/EFI)"); 365 break; 366 } 367 } 368 } 369 370 /* Acceleration: */ 371 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_Acceleration) 372 { 373 QStringList acceleration; 374 if (vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx)) 375 { 376 /* VT-x/AMD-V: */ 377 if (comMachine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled)) 378 { 379 acceleration << QApplication::translate("UIDetails", "VT-x/AMD-V", "details (system)"); 380 /* Nested Paging (only when hw virt is enabled): */ 381 if (comMachine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging)) 382 acceleration << QApplication::translate("UIDetails", "Nested Paging", "details (system)"); 383 } 384 } 385 /* PAE/NX: */ 386 if (comMachine.GetCPUProperty(KCPUPropertyType_PAE)) 387 acceleration << QApplication::translate("UIDetails", "PAE/NX", "details (system)"); 388 /* Paravirtualization provider: */ 389 switch (comMachine.GetEffectiveParavirtProvider()) 390 { 391 case KParavirtProvider_Minimal: acceleration << QApplication::translate("UIDetails", "Minimal Paravirtualization", "details (system)"); break; 392 case KParavirtProvider_HyperV: acceleration << QApplication::translate("UIDetails", "Hyper-V Paravirtualization", "details (system)"); break; 393 case KParavirtProvider_KVM: acceleration << QApplication::translate("UIDetails", "KVM Paravirtualization", "details (system)"); break; 394 default: break; 395 } 396 if (!acceleration.isEmpty()) 397 table << UITextTableLine(QApplication::translate("UIDetails", "Acceleration", "details (system)"), 398 acceleration.join(", ")); 399 } 400 } 401 else 402 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), 403 QString()); 404 250 UITextTable table = UIDetailsGenerator::generateMachineInformationSystem(comMachine, m_fOptions); 405 251 /* Save the table as property: */ 406 252 setProperty("table", QVariant::fromValue(table)); … … 421 267 422 268 /* Prepare table: */ 423 UITextTable table; 424 425 /* Gather information: */ 426 if (comMachine.GetAccessible()) 427 { 428 /* Video memory: */ 429 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_VRAM) 430 table << UITextTableLine(QApplication::translate("UIDetails", "Video Memory", "details (display)"), 431 QApplication::translate("UIDetails", "%1 MB", "details").arg(comMachine.GetVRAMSize())); 432 433 /* Screens: */ 434 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_ScreenCount) 435 { 436 const int cGuestScreens = comMachine.GetMonitorCount(); 437 if (cGuestScreens > 1) 438 table << UITextTableLine(QApplication::translate("UIDetails", "Screens", "details (display)"), 439 QString::number(cGuestScreens)); 440 } 441 442 /* Scale-factor: */ 443 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_ScaleFactor) 444 { 445 const QString strScaleFactor = comMachine.GetExtraData(UIExtraDataDefs::GUI_ScaleFactor); 446 { 447 /* Try to convert loaded data to double: */ 448 bool fOk = false; 449 double dValue = strScaleFactor.toDouble(&fOk); 450 /* Invent the default value: */ 451 if (!fOk || !dValue) 452 dValue = 1.0; 453 /* Append information: */ 454 if (dValue != 1.0) 455 table << UITextTableLine(QApplication::translate("UIDetails", "Scale-factor", "details (display)"), 456 QString::number(dValue, 'f', 2)); 457 } 458 } 459 460 /* Graphics Controller: */ 461 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_GraphicsController) 462 table << UITextTableLine(QApplication::translate("UIDetails", "Graphics Controller", "details (display)"), 463 gpConverter->toString(comMachine.GetGraphicsControllerType())); 464 465 /* Acceleration: */ 466 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_Acceleration) 467 { 468 QStringList acceleration; 469 #ifdef VBOX_WITH_VIDEOHWACCEL 470 /* 2D acceleration: */ 471 if (comMachine.GetAccelerate2DVideoEnabled()) 472 acceleration << QApplication::translate("UIDetails", "2D Video", "details (display)"); 473 #endif 474 /* 3D acceleration: */ 475 if (comMachine.GetAccelerate3DEnabled()) 476 acceleration << QApplication::translate("UIDetails", "3D", "details (display)"); 477 if (!acceleration.isEmpty()) 478 table << UITextTableLine(QApplication::translate("UIDetails", "Acceleration", "details (display)"), 479 acceleration.join(", ")); 480 } 481 482 /* Remote desktop server: */ 483 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_VRDE) 484 { 485 const CVRDEServer comServer = comMachine.GetVRDEServer(); 486 if (!comServer.isNull()) 487 { 488 if (comServer.GetEnabled()) 489 table << UITextTableLine(QApplication::translate("UIDetails", "Remote Desktop Server Port", "details (display/vrde)"), 490 comServer.GetVRDEProperty("TCP/Ports")); 491 else 492 table << UITextTableLine(QApplication::translate("UIDetails", "Remote Desktop Server", "details (display/vrde)"), 493 QApplication::translate("UIDetails", "Disabled", "details (display/vrde/VRDE server)")); 494 } 495 } 496 497 /* Recording: */ 498 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_Recording) 499 { 500 CRecordingSettings comRecordingSettings = comMachine.GetRecordingSettings(); 501 if (comRecordingSettings.GetEnabled()) 502 { 503 /* For now all screens have the same config: */ 504 const CRecordingScreenSettings comRecordingScreen0Settings = comRecordingSettings.GetScreenSettings(0); 505 506 /** @todo r=andy Refine these texts (wrt audio and/or video). */ 507 table << UITextTableLine(QApplication::translate("UIDetails", "Recording File", "details (display/recording)"), 508 comRecordingScreen0Settings.GetFilename()); 509 table << UITextTableLine(QApplication::translate("UIDetails", "Recording Attributes", "details (display/recording)"), 510 QApplication::translate("UIDetails", "Frame Size: %1x%2, Frame Rate: %3fps, Bit Rate: %4kbps") 511 .arg(comRecordingScreen0Settings.GetVideoWidth()).arg(comRecordingScreen0Settings.GetVideoHeight()) 512 .arg(comRecordingScreen0Settings.GetVideoFPS()).arg(comRecordingScreen0Settings.GetVideoRate())); 513 } 514 else 515 { 516 table << UITextTableLine(QApplication::translate("UIDetails", "Recording", "details (display/recording)"), 517 QApplication::translate("UIDetails", "Disabled", "details (display/recording)")); 518 } 519 } 520 } 521 else 522 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 269 UITextTable table = UIDetailsGenerator::generateMachineInformationDisplay(comMachine, m_fOptions); 523 270 524 271 /* Save the table as property: */ … … 540 287 541 288 /* Prepare table: */ 542 UITextTable table; 543 544 /* Gather information: */ 545 if (comMachine.GetAccessible()) 546 { 547 /* Iterate over all the machine controllers: */ 548 foreach (const CStorageController &comController, comMachine.GetStorageControllers()) 549 { 550 /* Add controller information: */ 551 const QString strControllerName = QApplication::translate("UIMachineSettingsStorage", "Controller: %1"); 552 table << UITextTableLine(strControllerName.arg(comController.GetName()), QString()); 553 /* Populate map (its sorted!): */ 554 QMap<StorageSlot, QString> attachmentsMap; 555 foreach (const CMediumAttachment &attachment, comMachine.GetMediumAttachmentsOfController(comController.GetName())) 556 { 557 /* Acquire device type first of all: */ 558 const KDeviceType enmDeviceType = attachment.GetType(); 559 560 /* Ignore restricted device types: */ 561 if ( ( !(m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeStorage_HardDisks) 562 && enmDeviceType == KDeviceType_HardDisk) 563 || ( !(m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeStorage_OpticalDevices) 564 && enmDeviceType == KDeviceType_DVD) 565 || ( !(m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeStorage_FloppyDevices) 566 && enmDeviceType == KDeviceType_Floppy)) 567 continue; 568 569 /* Prepare current storage slot: */ 570 const StorageSlot attachmentSlot(comController.GetBus(), attachment.GetPort(), attachment.GetDevice()); 571 AssertMsg(comController.isOk(), 572 ("Unable to acquire controller data: %s\n", 573 UIErrorString::formatRC(comController.lastRC()).toUtf8().constData())); 574 if (!comController.isOk()) 575 continue; 576 577 /* Prepare attachment information: */ 578 QString strAttachmentInfo = vboxGlobal().details(attachment.GetMedium(), false, false); 579 /* That hack makes sure 'Inaccessible' word is always bold: */ 580 { // hack 581 const QString strInaccessibleString(VBoxGlobal::tr("Inaccessible", "medium")); 582 const QString strBoldInaccessibleString(QString("<b>%1</b>").arg(strInaccessibleString)); 583 strAttachmentInfo.replace(strInaccessibleString, strBoldInaccessibleString); 584 } // hack 585 586 /* Append 'device slot name' with 'device type name' for optical devices only: */ 587 QString strDeviceType = enmDeviceType == KDeviceType_DVD 588 ? QApplication::translate("UIDetails", "[Optical Drive]", "details (storage)") 589 : QString(); 590 if (!strDeviceType.isNull()) 591 strDeviceType.append(' '); 592 593 /* Insert that attachment information into the map: */ 594 if (!strAttachmentInfo.isNull()) 595 { 596 /* Configure hovering anchors: */ 597 const QString strAnchorType = enmDeviceType == KDeviceType_DVD || enmDeviceType == KDeviceType_Floppy ? QString("mount") : 598 enmDeviceType == KDeviceType_HardDisk ? QString("attach") : QString(); 599 const CMedium medium = attachment.GetMedium(); 600 const QString strMediumLocation = medium.isNull() ? QString() : medium.GetLocation(); 601 attachmentsMap.insert(attachmentSlot, 602 QString("<a href=#%1,%2,%3,%4>%5</a>") 603 .arg(strAnchorType, 604 comController.GetName(), 605 gpConverter->toString(attachmentSlot), 606 strMediumLocation, 607 strDeviceType + strAttachmentInfo)); 608 } 609 } 610 611 /* Iterate over the sorted map: */ 612 const QList<StorageSlot> storageSlots = attachmentsMap.keys(); 613 const QList<QString> storageInfo = attachmentsMap.values(); 614 for (int i = 0; i < storageSlots.size(); ++i) 615 table << UITextTableLine(QString(" ") + gpConverter->toString(storageSlots[i]), storageInfo[i]); 616 } 617 if (table.isEmpty()) 618 table << UITextTableLine(QApplication::translate("UIDetails", "Not Attached", "details (storage)"), QString()); 619 } 620 else 621 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 289 UITextTable table = UIDetailsGenerator::generateMachineInformationStorage(comMachine, m_fOptions); 622 290 623 291 /* Save the table as property: */ … … 639 307 640 308 /* Prepare table: */ 641 UITextTable table; 642 643 /* Gather information: */ 644 if (comMachine.GetAccessible()) 645 { 646 const CAudioAdapter comAudio = comMachine.GetAudioAdapter(); 647 if (comAudio.GetEnabled()) 648 { 649 /* Host driver: */ 650 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeAudio_Driver) 651 table << UITextTableLine(QApplication::translate("UIDetails", "Host Driver", "details (audio)"), 652 gpConverter->toString(comAudio.GetAudioDriver())); 653 654 /* Controller: */ 655 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeAudio_Controller) 656 table << UITextTableLine(QApplication::translate("UIDetails", "Controller", "details (audio)"), 657 gpConverter->toString(comAudio.GetAudioController())); 658 659 #ifdef VBOX_WITH_AUDIO_INOUT_INFO 660 /* Audio I/O: */ 661 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeAudio_IO) 662 { 663 table << UITextTableLine(QApplication::translate("UIDetails", "Audio Input", "details (audio)"), 664 comAudio.GetEnabledIn() ? 665 QApplication::translate("UIDetails", "Enabled", "details (audio/input)") : 666 QApplication::translate("UIDetails", "Disabled", "details (audio/input)")); 667 table << UITextTableLine(QApplication::translate("UIDetails", "Audio Output", "details (audio)"), 668 comAudio.GetEnabledOut() ? 669 QApplication::translate("UIDetails", "Enabled", "details (audio/output)") : 670 QApplication::translate("UIDetails", "Disabled", "details (audio/output)")); 671 } 672 #endif /* VBOX_WITH_AUDIO_INOUT_INFO */ 673 } 674 else 675 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (audio)"), 676 QString()); 677 } 678 else 679 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), 680 QString()); 309 UITextTable table = UIDetailsGenerator::generateMachineInformationAudio(comMachine, m_fOptions); 310 681 311 682 312 /* Save the table as property: */ … … 689 319 } 690 320 691 692 321 void UIDetailsUpdateTaskNetwork::run() 693 322 { … … 698 327 699 328 /* Prepare table: */ 700 UITextTable table; 701 702 /* Gather information: */ 703 if (comMachine.GetAccessible()) 704 { 705 /* Iterate over all the adapters: */ 706 const ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(comMachine.GetChipsetType()); 707 for (ulong uSlot = 0; uSlot < uCount; ++uSlot) 708 { 709 const CNetworkAdapter comAdapter = comMachine.GetNetworkAdapter(uSlot); 710 711 /* Skip disabled adapters: */ 712 if (!comAdapter.GetEnabled()) 713 continue; 714 715 /* Gather adapter information: */ 716 const KNetworkAttachmentType enmType = comAdapter.GetAttachmentType(); 717 const QString strAttachmentTemplate = gpConverter->toString(comAdapter.GetAdapterType()).replace(QRegExp("\\s\\(.+\\)"), " (%1)"); 718 QString strAttachmentType; 719 switch (enmType) 720 { 721 case KNetworkAttachmentType_Bridged: 722 { 723 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_BridgetAdapter) 724 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Bridged Adapter, %1", "details (network)") 725 .arg(comAdapter.GetBridgedInterface())); 726 break; 727 } 728 case KNetworkAttachmentType_Internal: 729 { 730 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_InternalNetwork) 731 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Internal Network, '%1'", "details (network)") 732 .arg(comAdapter.GetInternalNetwork())); 733 break; 734 } 735 case KNetworkAttachmentType_HostOnly: 736 { 737 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_HostOnlyAdapter) 738 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Host-only Adapter, '%1'", "details (network)") 739 .arg(comAdapter.GetHostOnlyInterface())); 740 break; 741 } 742 case KNetworkAttachmentType_Generic: 743 { 744 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_GenericDriver) 745 { 746 const QString strGenericDriverProperties(summarizeGenericProperties(comAdapter)); 747 strAttachmentType = strGenericDriverProperties.isNull() ? 748 strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Generic Driver, '%1'", "details (network)") 749 .arg(comAdapter.GetGenericDriver())) : 750 strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Generic Driver, '%1' { %2 }", "details (network)") 751 .arg(comAdapter.GetGenericDriver(), strGenericDriverProperties)); 752 } 753 break; 754 } 755 case KNetworkAttachmentType_NATNetwork: 756 { 757 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_NAT) 758 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "NAT Network, '%1'", "details (network)") 759 .arg(comAdapter.GetNATNetwork())); 760 break; 761 } 762 default: 763 { 764 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_NotAttached) 765 strAttachmentType = strAttachmentTemplate.arg(gpConverter->toString(enmType)); 766 break; 767 } 768 } 769 if (!strAttachmentType.isNull()) 770 table << UITextTableLine(QApplication::translate("UIDetails", "Adapter %1", "details (network)").arg(comAdapter.GetSlot() + 1), strAttachmentType); 771 } 772 if (table.isEmpty()) 773 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (network/adapter)"), QString()); 774 } 775 else 776 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 329 UITextTable table = UIDetailsGenerator::generateMachineInformationNetwork(comMachine, m_fOptions); 777 330 778 331 /* Save the table as property: */ … … 785 338 } 786 339 787 /* static */788 QString UIDetailsUpdateTaskNetwork::summarizeGenericProperties(const CNetworkAdapter &adapter)789 {790 QVector<QString> names;791 QVector<QString> props;792 props = adapter.GetProperties(QString(), names);793 QString strResult;794 for (int i = 0; i < names.size(); ++i)795 {796 strResult += names[i] + "=" + props[i];797 if (i < names.size() - 1)798 strResult += ", ";799 }800 return strResult;801 }802 803 804 340 void UIDetailsUpdateTaskSerial::run() 805 341 { … … 810 346 811 347 /* Prepare table: */ 812 UITextTable table; 813 814 /* Gather information: */ 815 if (comMachine.GetAccessible()) 816 { 817 /* Iterate over all the ports: */ 818 const ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetSerialPortCount(); 819 for (ulong uSlot = 0; uSlot < uCount; ++uSlot) 820 { 821 const CSerialPort comPort = comMachine.GetSerialPort(uSlot); 822 823 /* Skip disabled adapters: */ 824 if (!comPort.GetEnabled()) 825 continue; 826 827 /* Gather port information: */ 828 const KPortMode enmMode = comPort.GetHostMode(); 829 const QString strModeTemplate = vboxGlobal().toCOMPortName(comPort.GetIRQ(), comPort.GetIOBase()) + ", "; 830 QString strModeType; 831 switch (enmMode) 832 { 833 case KPortMode_HostPipe: 834 { 835 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_HostPipe) 836 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 837 break; 838 } 839 case KPortMode_HostDevice: 840 { 841 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_HostDevice) 842 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 843 break; 844 } 845 case KPortMode_RawFile: 846 { 847 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_RawFile) 848 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 849 break; 850 } 851 case KPortMode_TCP: 852 { 853 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_TCP) 854 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 855 break; 856 } 857 default: 858 { 859 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_Disconnected) 860 strModeType = strModeTemplate + gpConverter->toString(enmMode); 861 break; 862 } 863 } 864 if (!strModeType.isNull()) 865 table << UITextTableLine(QApplication::translate("UIDetails", "Port %1", "details (serial)").arg(comPort.GetSlot() + 1), strModeType); 866 } 867 if (table.isEmpty()) 868 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (serial)"), QString()); 869 } 870 else 871 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 872 348 UITextTable table = UIDetailsGenerator::generateMachineInformationSerial(comMachine, m_fOptions); 873 349 /* Save the table as property: */ 874 350 setProperty("table", QVariant::fromValue(table)); … … 880 356 } 881 357 882 883 358 void UIDetailsUpdateTaskUSB::run() 884 359 { … … 889 364 890 365 /* Prepare table: */ 891 UITextTable table; 892 893 /* Gather information: */ 894 if (comMachine.GetAccessible()) 895 { 896 /* Iterate over all the USB filters: */ 897 const CUSBDeviceFilters comFilterObject = comMachine.GetUSBDeviceFilters(); 898 if (!comFilterObject.isNull() && comMachine.GetUSBProxyAvailable()) 899 { 900 const CUSBControllerVector controllers = comMachine.GetUSBControllers(); 901 if (!controllers.isEmpty()) 902 { 903 /* USB controllers: */ 904 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUsb_Controller) 905 { 906 QStringList controllersReadable; 907 foreach (const CUSBController &comController, controllers) 908 controllersReadable << gpConverter->toString(comController.GetType()); 909 table << UITextTableLine(QApplication::translate("UIDetails", "USB Controller", "details (usb)"), 910 controllersReadable.join(", ")); 911 } 912 913 /* Device filters: */ 914 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUsb_DeviceFilters) 915 { 916 const CUSBDeviceFilterVector filters = comFilterObject.GetDeviceFilters(); 917 uint uActive = 0; 918 for (int i = 0; i < filters.size(); ++i) 919 if (filters.at(i).GetActive()) 920 ++uActive; 921 table << UITextTableLine(QApplication::translate("UIDetails", "Device Filters", "details (usb)"), 922 QApplication::translate("UIDetails", "%1 (%2 active)", "details (usb)").arg(filters.size()).arg(uActive)); 923 } 924 } 925 else 926 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (usb)"), QString()); 927 } 928 else 929 table << UITextTableLine(QApplication::translate("UIDetails", "USB Controller Inaccessible", "details (usb)"), QString()); 930 } 931 else 932 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 366 UITextTable table = UIDetailsGenerator::generateMachineInformationUSB(comMachine, m_fOptions); 933 367 934 368 /* Save the table as property: */ … … 950 384 951 385 /* Prepare table: */ 952 UITextTable table; 953 954 /* Gather information: */ 955 if (comMachine.GetAccessible()) 956 { 957 /* Summary: */ 958 const ulong uCount = comMachine.GetSharedFolders().size(); 959 if (uCount > 0) 960 table << UITextTableLine(QApplication::translate("UIDetails", "Shared Folders", "details (shared folders)"), QString::number(uCount)); 961 else 962 table << UITextTableLine(QApplication::translate("UIDetails", "None", "details (shared folders)"), QString()); 963 } 964 else 965 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 386 UITextTable table = UIDetailsGenerator::generateMachineInformationSharedFolders(comMachine, m_fOptions); 966 387 967 388 /* Save the table as property: */ … … 983 404 984 405 /* Prepare table: */ 985 UITextTable table; 986 987 /* Gather information: */ 988 if (comMachine.GetAccessible()) 989 { 990 #ifndef VBOX_WS_MAC 991 /* Menu-bar: */ 992 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface_MenuBar) 993 { 994 const QString strMenubarEnabled = comMachine.GetExtraData(UIExtraDataDefs::GUI_MenuBar_Enabled); 995 /* Try to convert loaded data to bool: */ 996 const bool fEnabled = !( strMenubarEnabled.compare("false", Qt::CaseInsensitive) == 0 997 || strMenubarEnabled.compare("no", Qt::CaseInsensitive) == 0 998 || strMenubarEnabled.compare("off", Qt::CaseInsensitive) == 0 999 || strMenubarEnabled == "0"); 1000 /* Append information: */ 1001 table << UITextTableLine(QApplication::translate("UIDetails", "Menu-bar", "details (user interface)"), 1002 fEnabled ? QApplication::translate("UIDetails", "Enabled", "details (user interface/menu-bar)") 1003 : QApplication::translate("UIDetails", "Disabled", "details (user interface/menu-bar)")); 1004 } 1005 #endif /* !VBOX_WS_MAC */ 1006 1007 /* Status-bar: */ 1008 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface_StatusBar) 1009 { 1010 const QString strStatusbarEnabled = comMachine.GetExtraData(UIExtraDataDefs::GUI_StatusBar_Enabled); 1011 /* Try to convert loaded data to bool: */ 1012 const bool fEnabled = !( strStatusbarEnabled.compare("false", Qt::CaseInsensitive) == 0 1013 || strStatusbarEnabled.compare("no", Qt::CaseInsensitive) == 0 1014 || strStatusbarEnabled.compare("off", Qt::CaseInsensitive) == 0 1015 || strStatusbarEnabled == "0"); 1016 /* Append information: */ 1017 table << UITextTableLine(QApplication::translate("UIDetails", "Status-bar", "details (user interface)"), 1018 fEnabled ? QApplication::translate("UIDetails", "Enabled", "details (user interface/status-bar)") 1019 : QApplication::translate("UIDetails", "Disabled", "details (user interface/status-bar)")); 1020 } 1021 1022 #ifndef VBOX_WS_MAC 1023 /* Mini-toolbar: */ 1024 if (m_fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface_MiniToolbar) 1025 { 1026 const QString strMiniToolbarEnabled = comMachine.GetExtraData(UIExtraDataDefs::GUI_ShowMiniToolBar); 1027 /* Try to convert loaded data to bool: */ 1028 const bool fEnabled = !( strMiniToolbarEnabled.compare("false", Qt::CaseInsensitive) == 0 1029 || strMiniToolbarEnabled.compare("no", Qt::CaseInsensitive) == 0 1030 || strMiniToolbarEnabled.compare("off", Qt::CaseInsensitive) == 0 1031 || strMiniToolbarEnabled == "0"); 1032 /* Append information: */ 1033 if (fEnabled) 1034 { 1035 /* Get mini-toolbar position: */ 1036 const QString strMiniToolbarPosition = comMachine.GetExtraData(UIExtraDataDefs::GUI_MiniToolBarAlignment); 1037 { 1038 /* Try to convert loaded data to alignment: */ 1039 switch (gpConverter->fromInternalString<MiniToolbarAlignment>(strMiniToolbarPosition)) 1040 { 1041 /* Append information: */ 1042 case MiniToolbarAlignment_Top: 1043 table << UITextTableLine(QApplication::translate("UIDetails", "Mini-toolbar Position", "details (user interface)"), 1044 QApplication::translate("UIDetails", "Top", "details (user interface/mini-toolbar position)")); 1045 break; 1046 /* Append information: */ 1047 case MiniToolbarAlignment_Bottom: 1048 table << UITextTableLine(QApplication::translate("UIDetails", "Mini-toolbar Position", "details (user interface)"), 1049 QApplication::translate("UIDetails", "Bottom", "details (user interface/mini-toolbar position)")); 1050 break; 1051 } 1052 } 1053 } 1054 /* Append information: */ 1055 else 1056 table << UITextTableLine(QApplication::translate("UIDetails", "Mini-toolbar", "details (user interface)"), 1057 QApplication::translate("UIDetails", "Disabled", "details (user interface/mini-toolbar)")); 1058 } 1059 #endif /* !VBOX_WS_MAC */ 1060 } 1061 else 1062 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 406 UITextTable table = UIDetailsGenerator::generateMachineInformationUI(comMachine, m_fOptions); 1063 407 1064 408 /* Save the table as property: */ … … 1080 424 1081 425 /* Prepare table: */ 1082 UITextTable table; 1083 1084 /* Gather information: */ 1085 if (comMachine.GetAccessible()) 1086 { 1087 /* Summary: */ 1088 const QString strDescription = comMachine.GetDescription(); 1089 if (!strDescription.isEmpty()) 1090 table << UITextTableLine(strDescription, QString()); 1091 else 1092 table << UITextTableLine(QApplication::translate("UIDetails", "None", "details (description)"), QString()); 1093 } 1094 else 1095 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 426 UITextTable table = UIDetailsGenerator::generateMachineInformationDetails(comMachine, m_fOptions); 1096 427 1097 428 /* Save the table as property: */ -
trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIDetailsGenerator.cpp
r77435 r77455 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIDetails Element classimplementation.3 * VBox Qt GUI - UIDetailsGenerator implementation. 4 4 */ 5 5 … … 17 17 18 18 /* Qt includes: */ 19 #include <QGraphicsSceneMouseEvent> 20 #include <QGraphicsView> 21 #include <QPropertyAnimation> 22 #include <QSignalTransition> 23 #include <QStateMachine> 24 #include <QStyleOptionGraphicsItem> 19 #include <QDir> 25 20 26 21 /* GUI includes: */ 27 #include "UI ActionPool.h"22 #include "UIDetailsGenerator.h" 28 23 #include "UIConverter.h" 29 #include "UIDetailsElement.h" 30 #include "UIDetailsSet.h" 31 #include "UIDetailsModel.h" 32 #include "UIExtraDataManager.h" 33 #include "UIGraphicsRotatorButton.h" 34 #include "UIGraphicsTextPane.h" 35 #include "UIIconPool.h" 36 #include "UIVirtualBoxManager.h" 24 #include "UIErrorString.h" 25 #include "UIInformationItem.h" 37 26 #include "VBoxGlobal.h" 38 27 39 40 UIDetailsElement::UIDetailsElement(UIDetailsSet *pParent, DetailsElementType enmType, bool fOpened) 41 : UIDetailsItem(pParent) 42 , m_pSet(pParent) 43 , m_enmType(enmType) 44 #ifdef VBOX_WS_MAC 45 , m_iDefaultToneStart(145) 46 , m_iDefaultToneFinal(155) 47 , m_iHoverToneStart(115) 48 , m_iHoverToneFinal(125) 49 #else 50 , m_iDefaultToneStart(160) 51 , m_iDefaultToneFinal(190) 52 , m_iHoverToneStart(160) 53 , m_iHoverToneFinal(190) 28 /* COM includes: */ 29 #include "COMEnums.h" 30 #include "CMachine.h" 31 #include "CSystemProperties.h" 32 #include "CVRDEServer.h" 33 #include "CStorageController.h" 34 #include "CMediumAttachment.h" 35 #include "CAudioAdapter.h" 36 #include "CRecordingSettings.h" 37 #include "CRecordingScreenSettings.h" 38 #include "CNetworkAdapter.h" 39 #include "CSerialPort.h" 40 #include "CUSBController.h" 41 #include "CUSBDeviceFilters.h" 42 #include "CUSBDeviceFilter.h" 43 #include "CSharedFolder.h" 44 45 UITextTable UIDetailsGenerator::generateMachineInformationGeneral(CMachine &comMachine, 46 const UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral &fOptions) 47 { 48 UITextTable table; 49 50 if (comMachine.isNull()) 51 return table; 52 53 if (!comMachine.GetAccessible()) 54 { 55 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 56 return table; 57 } 58 59 /* Gather information: */ 60 /* Name: */ 61 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_Name) 62 table << UITextTableLine(QApplication::translate("UIDetails", "Name", "details (general)"), comMachine.GetName()); 63 64 /* Operating system: */ 65 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_OS) 66 table << UITextTableLine(QApplication::translate("UIDetails", "Operating System", "details (general)"), 67 vboxGlobal().vmGuestOSTypeDescription(comMachine.GetOSTypeId())); 68 69 /* Settings file location: */ 70 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_Location) 71 table << UITextTableLine(QApplication::translate("UIDetails", "Settings File Location", "details (general)"), 72 QDir::toNativeSeparators(QFileInfo(comMachine.GetSettingsFilePath()).absolutePath())); 73 74 /* Groups: */ 75 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral_Groups) 76 { 77 QStringList groups = comMachine.GetGroups().toList(); 78 /* Do not show groups for machine which is in root group only: */ 79 if (groups.size() == 1) 80 groups.removeAll("/"); 81 /* If group list still not empty: */ 82 if (!groups.isEmpty()) 83 { 84 /* For every group: */ 85 for (int i = 0; i < groups.size(); ++i) 86 { 87 /* Trim first '/' symbol: */ 88 QString &strGroup = groups[i]; 89 if (strGroup.startsWith("/") && strGroup != "/") 90 strGroup.remove(0, 1); 91 } 92 table << UITextTableLine(QApplication::translate("UIDetails", "Groups", "details (general)"), groups.join(", ")); 93 } 94 } 95 return table; 96 } 97 98 UITextTable UIDetailsGenerator::generateMachineInformationSystem(CMachine &comMachine, 99 const UIExtraDataMetaDefs::DetailsElementOptionTypeSystem &fOptions) 100 { 101 UITextTable table; 102 if (comMachine.isNull()) 103 return table; 104 105 if (!comMachine.GetAccessible()) 106 { 107 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 108 return table; 109 } 110 111 /* Base memory: */ 112 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_RAM) 113 table << UITextTableLine(QApplication::translate("UIDetails", "Base Memory", "details (system)"), 114 QApplication::translate("UIDetails", "%1 MB", "details").arg(comMachine.GetMemorySize())); 115 116 /* Processors: */ 117 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_CPUCount) 118 { 119 const int cCPU = comMachine.GetCPUCount(); 120 if (cCPU > 1) 121 table << UITextTableLine(QApplication::translate("UIDetails", "Processors", "details (system)"), 122 QString::number(cCPU)); 123 } 124 125 /* Execution cap: */ 126 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_CPUExecutionCap) 127 { 128 const int iCPUExecutionCap = comMachine.GetCPUExecutionCap(); 129 if (iCPUExecutionCap < 100) 130 table << UITextTableLine(QApplication::translate("UIDetails", "Execution Cap", "details (system)"), 131 QApplication::translate("UIDetails", "%1%", "details").arg(iCPUExecutionCap)); 132 } 133 134 /* Boot order: */ 135 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_BootOrder) 136 { 137 QStringList bootOrder; 138 for (ulong i = 1; i <= vboxGlobal().virtualBox().GetSystemProperties().GetMaxBootPosition(); ++i) 139 { 140 const KDeviceType enmDeviceType = comMachine.GetBootOrder(i); 141 if (enmDeviceType == KDeviceType_Null) 142 continue; 143 bootOrder << gpConverter->toString(enmDeviceType); 144 } 145 if (bootOrder.isEmpty()) 146 bootOrder << gpConverter->toString(KDeviceType_Null); 147 table << UITextTableLine(QApplication::translate("UIDetails", "Boot Order", "details (system)"), bootOrder.join(", ")); 148 } 149 150 /* Chipset type: */ 151 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_ChipsetType) 152 { 153 const KChipsetType enmChipsetType = comMachine.GetChipsetType(); 154 if (enmChipsetType == KChipsetType_ICH9) 155 table << UITextTableLine(QApplication::translate("UIDetails", "Chipset Type", "details (system)"), 156 gpConverter->toString(enmChipsetType)); 157 } 158 159 /* EFI: */ 160 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_Firmware) 161 { 162 switch (comMachine.GetFirmwareType()) 163 { 164 case KFirmwareType_EFI: 165 case KFirmwareType_EFI32: 166 case KFirmwareType_EFI64: 167 case KFirmwareType_EFIDUAL: 168 { 169 table << UITextTableLine(QApplication::translate("UIDetails", "EFI", "details (system)"), 170 QApplication::translate("UIDetails", "Enabled", "details (system/EFI)")); 171 break; 172 } 173 default: 174 { 175 // For NLS purpose: 176 QApplication::translate("UIDetails", "Disabled", "details (system/EFI)"); 177 break; 178 } 179 } 180 } 181 182 /* Acceleration: */ 183 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSystem_Acceleration) 184 { 185 QStringList acceleration; 186 if (vboxGlobal().virtualBox().GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx)) 187 { 188 /* VT-x/AMD-V: */ 189 if (comMachine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled)) 190 { 191 acceleration << QApplication::translate("UIDetails", "VT-x/AMD-V", "details (system)"); 192 /* Nested Paging (only when hw virt is enabled): */ 193 if (comMachine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging)) 194 acceleration << QApplication::translate("UIDetails", "Nested Paging", "details (system)"); 195 } 196 } 197 /* PAE/NX: */ 198 if (comMachine.GetCPUProperty(KCPUPropertyType_PAE)) 199 acceleration << QApplication::translate("UIDetails", "PAE/NX", "details (system)"); 200 /* Paravirtualization provider: */ 201 switch (comMachine.GetEffectiveParavirtProvider()) 202 { 203 case KParavirtProvider_Minimal: acceleration << QApplication::translate("UIDetails", "Minimal Paravirtualization", "details (system)"); break; 204 case KParavirtProvider_HyperV: acceleration << QApplication::translate("UIDetails", "Hyper-V Paravirtualization", "details (system)"); break; 205 case KParavirtProvider_KVM: acceleration << QApplication::translate("UIDetails", "KVM Paravirtualization", "details (system)"); break; 206 default: break; 207 } 208 if (!acceleration.isEmpty()) 209 table << UITextTableLine(QApplication::translate("UIDetails", "Acceleration", "details (system)"), 210 acceleration.join(", ")); 211 } 212 return table; 213 } 214 215 216 UITextTable UIDetailsGenerator::generateMachineInformationDisplay(CMachine &comMachine, 217 const UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay &fOptions) 218 { 219 UITextTable table; 220 221 if (comMachine.isNull()) 222 return table; 223 224 if (!comMachine.GetAccessible()) 225 { 226 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 227 return table; 228 } 229 230 /* Video memory: */ 231 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_VRAM) 232 table << UITextTableLine(QApplication::translate("UIDetails", "Video Memory", "details (display)"), 233 QApplication::translate("UIDetails", "%1 MB", "details").arg(comMachine.GetVRAMSize())); 234 235 /* Screens: */ 236 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_ScreenCount) 237 { 238 const int cGuestScreens = comMachine.GetMonitorCount(); 239 if (cGuestScreens > 1) 240 table << UITextTableLine(QApplication::translate("UIDetails", "Screens", "details (display)"), 241 QString::number(cGuestScreens)); 242 } 243 244 /* Scale-factor: */ 245 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_ScaleFactor) 246 { 247 const QString strScaleFactor = comMachine.GetExtraData(UIExtraDataDefs::GUI_ScaleFactor); 248 { 249 /* Try to convert loaded data to double: */ 250 bool fOk = false; 251 double dValue = strScaleFactor.toDouble(&fOk); 252 /* Invent the default value: */ 253 if (!fOk || !dValue) 254 dValue = 1.0; 255 /* Append information: */ 256 if (dValue != 1.0) 257 table << UITextTableLine(QApplication::translate("UIDetails", "Scale-factor", "details (display)"), 258 QString::number(dValue, 'f', 2)); 259 } 260 } 261 262 /* Graphics Controller: */ 263 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_GraphicsController) 264 table << UITextTableLine(QApplication::translate("UIDetails", "Graphics Controller", "details (display)"), 265 gpConverter->toString(comMachine.GetGraphicsControllerType())); 266 267 /* Acceleration: */ 268 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_Acceleration) 269 { 270 QStringList acceleration; 271 #ifdef VBOX_WITH_VIDEOHWACCEL 272 /* 2D acceleration: */ 273 if (comMachine.GetAccelerate2DVideoEnabled()) 274 acceleration << QApplication::translate("UIDetails", "2D Video", "details (display)"); 54 275 #endif 55 , m_fHovered(false) 56 , m_fNameHovered(false) 57 , m_pHoveringMachine(0) 58 , m_pHoveringAnimationForward(0) 59 , m_pHoveringAnimationBackward(0) 60 , m_iAnimationDuration(300) 61 , m_iDefaultValue(0) 62 , m_iHoveredValue(255) 63 , m_iAnimatedValue(m_iDefaultValue) 64 , m_pButton(0) 65 , m_fClosed(!fOpened) 66 , m_fAnimationRunning(false) 67 , m_iAdditionalHeight(0) 68 , m_pTextPane(0) 69 , m_iMinimumHeaderWidth(0) 70 , m_iMinimumHeaderHeight(0) 71 { 72 /* Prepare element: */ 73 prepareElement(); 74 /* Prepare button: */ 75 prepareButton(); 76 /* Prepare text-pane: */ 77 prepareTextPane(); 78 79 /* Setup size-policy: */ 80 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); 81 82 /* Add item to the parent: */ 83 AssertMsg(parentItem(), ("No parent set for details element!")); 84 parentItem()->addItem(this); 85 } 86 87 UIDetailsElement::~UIDetailsElement() 88 { 89 /* Remove item from the parent: */ 90 AssertMsg(parentItem(), ("No parent set for details element!")); 91 parentItem()->removeItem(this); 92 } 93 94 void UIDetailsElement::setText(const UITextTable &text) 95 { 96 /* Pass text to text-pane: */ 97 m_pTextPane->setText(text); 98 } 99 100 UITextTable &UIDetailsElement::text() const 101 { 102 /* Retrieve text from text-pane: */ 103 return m_pTextPane->text(); 104 } 105 106 void UIDetailsElement::close(bool fAnimated /* = true */) 107 { 108 m_pButton->setToggled(false, fAnimated); 109 } 110 111 void UIDetailsElement::open(bool fAnimated /* = true */) 112 { 113 m_pButton->setToggled(true, fAnimated); 114 } 115 116 void UIDetailsElement::markAnimationFinished() 117 { 118 /* Mark animation as non-running: */ 119 m_fAnimationRunning = false; 120 121 /* Recursively update size-hint: */ 122 updateGeometry(); 123 /* Repaint: */ 124 update(); 125 } 126 127 void UIDetailsElement::updateAppearance() 128 { 129 /* Reset name hover state: */ 130 m_fNameHovered = false; 131 updateNameHoverLink(); 132 133 /* Update anchor role restrictions: */ 134 ConfigurationAccessLevel cal = m_pSet->configurationAccessLevel(); 135 m_pTextPane->setAnchorRoleRestricted("#mount", cal == ConfigurationAccessLevel_Null); 136 m_pTextPane->setAnchorRoleRestricted("#attach", cal != ConfigurationAccessLevel_Full); 137 } 138 139 int UIDetailsElement::minimumWidthHint() const 140 { 141 /* Prepare variables: */ 142 int iMargin = data(ElementData_Margin).toInt(); 143 int iMinimumWidthHint = 0; 144 145 /* Maximum width: */ 146 iMinimumWidthHint = qMax(m_iMinimumHeaderWidth, (int)m_pTextPane->minimumSizeHint().width()); 147 148 /* And 4 margins: 2 left and 2 right: */ 149 iMinimumWidthHint += 4 * iMargin; 150 151 /* Return result: */ 152 return iMinimumWidthHint; 153 } 154 155 int UIDetailsElement::minimumHeightHint() const 156 { 157 return minimumHeightHintForElement(m_fClosed); 158 } 159 160 void UIDetailsElement::showEvent(QShowEvent *pEvent) 161 { 162 /* Call to base-class: */ 163 UIDetailsItem::showEvent(pEvent); 164 165 /* Update icon: */ 166 updateIcon(); 167 } 168 169 void UIDetailsElement::resizeEvent(QGraphicsSceneResizeEvent*) 170 { 171 /* Update layout: */ 172 updateLayout(); 173 } 174 175 void UIDetailsElement::hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) 176 { 177 /* Update hover state: */ 178 if (!m_fHovered) 179 { 180 m_fHovered = true; 181 emit sigHoverEnter(); 182 } 183 184 /* Update name-hover state: */ 185 handleHoverEvent(pEvent); 186 } 187 188 void UIDetailsElement::hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) 189 { 190 /* Update hover state: */ 191 if (m_fHovered) 192 { 193 m_fHovered = false; 194 emit sigHoverLeave(); 195 } 196 197 /* Update name-hover state: */ 198 handleHoverEvent(pEvent); 199 } 200 201 void UIDetailsElement::mousePressEvent(QGraphicsSceneMouseEvent *pEvent) 202 { 203 /* Only for hovered header: */ 204 if (!m_fNameHovered) 205 return; 206 207 /* Process link click: */ 208 pEvent->accept(); 209 QString strCategory; 210 if (m_enmType >= DetailsElementType_General && 211 m_enmType < DetailsElementType_Description) 212 strCategory = QString("#%1").arg(gpConverter->toInternalString(m_enmType)); 213 else if (m_enmType == DetailsElementType_Description) 214 strCategory = QString("#%1%%mTeDescription").arg(gpConverter->toInternalString(m_enmType)); 215 emit sigLinkClicked(strCategory, QString(), machine().GetId()); 216 } 217 218 void UIDetailsElement::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *pEvent) 219 { 220 /* Only for left-button: */ 221 if (pEvent->button() != Qt::LeftButton) 222 return; 223 224 /* Process left-button double-click: */ 225 emit sigToggleElement(m_enmType, isClosed()); 226 } 227 228 void UIDetailsElement::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *) 229 { 230 /* Update button visibility: */ 231 updateButtonVisibility(); 232 233 /* Paint background: */ 234 paintBackground(pPainter, pOptions); 235 /* Paint frame: */ 236 paintFrame(pPainter, pOptions); 237 /* Paint element info: */ 238 paintElementInfo(pPainter, pOptions); 239 } 240 241 QString UIDetailsElement::description() const 242 { 243 return tr("%1 details", "like 'General details' or 'Storage details'").arg(m_strName); 244 } 245 246 const CMachine &UIDetailsElement::machine() 247 { 248 return m_pSet->machine(); 249 } 250 251 void UIDetailsElement::setName(const QString &strName) 252 { 253 /* Cache name: */ 254 m_strName = strName; 255 QFontMetrics fm(m_nameFont, model()->paintDevice()); 256 m_nameSize = QSize(fm.width(m_strName), fm.height()); 257 258 /* Update linked values: */ 259 updateMinimumHeaderWidth(); 260 updateMinimumHeaderHeight(); 261 } 262 263 void UIDetailsElement::setAdditionalHeight(int iAdditionalHeight) 264 { 265 /* Cache new value: */ 266 m_iAdditionalHeight = iAdditionalHeight; 267 /* Update layout: */ 268 updateLayout(); 269 /* Repaint: */ 270 update(); 271 } 272 273 QVariant UIDetailsElement::data(int iKey) const 274 { 275 /* Provide other members with required data: */ 276 switch (iKey) 277 { 278 /* Hints: */ 279 case ElementData_Margin: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4; 280 case ElementData_Spacing: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2; 281 /* Default: */ 282 default: break; 283 } 284 return QVariant(); 285 } 286 287 void UIDetailsElement::addItem(UIDetailsItem*) 288 { 289 AssertMsgFailed(("Details element do NOT support children!")); 290 } 291 292 void UIDetailsElement::removeItem(UIDetailsItem*) 293 { 294 AssertMsgFailed(("Details element do NOT support children!")); 295 } 296 297 QList<UIDetailsItem*> UIDetailsElement::items(UIDetailsItemType) const 298 { 299 AssertMsgFailed(("Details element do NOT support children!")); 300 return QList<UIDetailsItem*>(); 301 } 302 303 bool UIDetailsElement::hasItems(UIDetailsItemType) const 304 { 305 AssertMsgFailed(("Details element do NOT support children!")); 306 return false; 307 } 308 309 void UIDetailsElement::clearItems(UIDetailsItemType) 310 { 311 AssertMsgFailed(("Details element do NOT support children!")); 312 } 313 314 void UIDetailsElement::updateLayout() 315 { 316 /* Prepare variables: */ 317 QSize size = geometry().size().toSize(); 318 int iMargin = data(ElementData_Margin).toInt(); 319 320 /* Layout button: */ 321 int iButtonWidth = m_buttonSize.width(); 322 int iButtonHeight = m_buttonSize.height(); 323 int iButtonX = size.width() - 2 * iMargin - iButtonWidth; 324 int iButtonY = iButtonHeight == m_iMinimumHeaderHeight ? iMargin : 325 iMargin + (m_iMinimumHeaderHeight - iButtonHeight) / 2; 326 m_pButton->setPos(iButtonX, iButtonY); 327 328 /* If closed: */ 329 if (isClosed()) 330 { 331 /* Hide text-pane if still visible: */ 332 if (m_pTextPane->isVisible()) 333 m_pTextPane->hide(); 334 } 335 /* If opened: */ 276 /* 3D acceleration: */ 277 if (comMachine.GetAccelerate3DEnabled()) 278 acceleration << QApplication::translate("UIDetails", "3D", "details (display)"); 279 if (!acceleration.isEmpty()) 280 table << UITextTableLine(QApplication::translate("UIDetails", "Acceleration", "details (display)"), 281 acceleration.join(", ")); 282 } 283 284 /* Remote desktop server: */ 285 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_VRDE) 286 { 287 const CVRDEServer comServer = comMachine.GetVRDEServer(); 288 if (!comServer.isNull()) 289 { 290 if (comServer.GetEnabled()) 291 table << UITextTableLine(QApplication::translate("UIDetails", "Remote Desktop Server Port", "details (display/vrde)"), 292 comServer.GetVRDEProperty("TCP/Ports")); 293 else 294 table << UITextTableLine(QApplication::translate("UIDetails", "Remote Desktop Server", "details (display/vrde)"), 295 QApplication::translate("UIDetails", "Disabled", "details (display/vrde/VRDE server)")); 296 } 297 } 298 299 /* Recording: */ 300 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay_Recording) 301 { 302 CRecordingSettings comRecordingSettings = comMachine.GetRecordingSettings(); 303 if (comRecordingSettings.GetEnabled()) 304 { 305 /* For now all screens have the same config: */ 306 const CRecordingScreenSettings comRecordingScreen0Settings = comRecordingSettings.GetScreenSettings(0); 307 308 /** @todo r=andy Refine these texts (wrt audio and/or video). */ 309 table << UITextTableLine(QApplication::translate("UIDetails", "Recording File", "details (display/recording)"), 310 comRecordingScreen0Settings.GetFilename()); 311 table << UITextTableLine(QApplication::translate("UIDetails", "Recording Attributes", "details (display/recording)"), 312 QApplication::translate("UIDetails", "Frame Size: %1x%2, Frame Rate: %3fps, Bit Rate: %4kbps") 313 .arg(comRecordingScreen0Settings.GetVideoWidth()).arg(comRecordingScreen0Settings.GetVideoHeight()) 314 .arg(comRecordingScreen0Settings.GetVideoFPS()).arg(comRecordingScreen0Settings.GetVideoRate())); 315 } 316 else 317 { 318 table << UITextTableLine(QApplication::translate("UIDetails", "Recording", "details (display/recording)"), 319 QApplication::translate("UIDetails", "Disabled", "details (display/recording)")); 320 } 321 } 322 return table; 323 } 324 325 UITextTable UIDetailsGenerator::generateMachineInformationStorage(CMachine &comMachine, 326 const UIExtraDataMetaDefs::DetailsElementOptionTypeStorage &fOptions) 327 { 328 UITextTable table; 329 330 if (comMachine.isNull()) 331 return table; 332 333 if (!comMachine.GetAccessible()) 334 { 335 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 336 return table; 337 } 338 339 /* Iterate over all the machine controllers: */ 340 foreach (const CStorageController &comController, comMachine.GetStorageControllers()) 341 { 342 /* Add controller information: */ 343 const QString strControllerName = QApplication::translate("UIMachineSettingsStorage", "Controller: %1"); 344 table << UITextTableLine(strControllerName.arg(comController.GetName()), QString()); 345 /* Populate map (its sorted!): */ 346 QMap<StorageSlot, QString> attachmentsMap; 347 foreach (const CMediumAttachment &attachment, comMachine.GetMediumAttachmentsOfController(comController.GetName())) 348 { 349 /* Acquire device type first of all: */ 350 const KDeviceType enmDeviceType = attachment.GetType(); 351 352 /* Ignore restricted device types: */ 353 if ( ( !(fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeStorage_HardDisks) 354 && enmDeviceType == KDeviceType_HardDisk) 355 || ( !(fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeStorage_OpticalDevices) 356 && enmDeviceType == KDeviceType_DVD) 357 || ( !(fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeStorage_FloppyDevices) 358 && enmDeviceType == KDeviceType_Floppy)) 359 continue; 360 361 /* Prepare current storage slot: */ 362 const StorageSlot attachmentSlot(comController.GetBus(), attachment.GetPort(), attachment.GetDevice()); 363 AssertMsg(comController.isOk(), 364 ("Unable to acquire controller data: %s\n", 365 UIErrorString::formatRC(comController.lastRC()).toUtf8().constData())); 366 if (!comController.isOk()) 367 continue; 368 369 /* Prepare attachment information: */ 370 QString strAttachmentInfo = vboxGlobal().details(attachment.GetMedium(), false, false); 371 /* That hack makes sure 'Inaccessible' word is always bold: */ 372 { // hack 373 const QString strInaccessibleString(VBoxGlobal::tr("Inaccessible", "medium")); 374 const QString strBoldInaccessibleString(QString("<b>%1</b>").arg(strInaccessibleString)); 375 strAttachmentInfo.replace(strInaccessibleString, strBoldInaccessibleString); 376 } // hack 377 378 /* Append 'device slot name' with 'device type name' for optical devices only: */ 379 QString strDeviceType = enmDeviceType == KDeviceType_DVD 380 ? QApplication::translate("UIDetails", "[Optical Drive]", "details (storage)") 381 : QString(); 382 if (!strDeviceType.isNull()) 383 strDeviceType.append(' '); 384 385 /* Insert that attachment information into the map: */ 386 if (!strAttachmentInfo.isNull()) 387 { 388 /* Configure hovering anchors: */ 389 const QString strAnchorType = enmDeviceType == KDeviceType_DVD || enmDeviceType == KDeviceType_Floppy ? QString("mount") : 390 enmDeviceType == KDeviceType_HardDisk ? QString("attach") : QString(); 391 const CMedium medium = attachment.GetMedium(); 392 const QString strMediumLocation = medium.isNull() ? QString() : medium.GetLocation(); 393 attachmentsMap.insert(attachmentSlot, 394 QString("<a href=#%1,%2,%3,%4>%5</a>") 395 .arg(strAnchorType, 396 comController.GetName(), 397 gpConverter->toString(attachmentSlot), 398 strMediumLocation, 399 strDeviceType + strAttachmentInfo)); 400 } 401 } 402 403 /* Iterate over the sorted map: */ 404 const QList<StorageSlot> storageSlots = attachmentsMap.keys(); 405 const QList<QString> storageInfo = attachmentsMap.values(); 406 for (int i = 0; i < storageSlots.size(); ++i) 407 table << UITextTableLine(QString(" ") + gpConverter->toString(storageSlots[i]), storageInfo[i]); 408 } 409 if (table.isEmpty()) 410 table << UITextTableLine(QApplication::translate("UIDetails", "Not Attached", "details (storage)"), QString()); 411 412 return table; 413 } 414 415 416 UITextTable UIDetailsGenerator::generateMachineInformationAudio(CMachine &comMachine, 417 const UIExtraDataMetaDefs::DetailsElementOptionTypeAudio &fOptions) 418 { 419 420 UITextTable table; 421 422 if (comMachine.isNull()) 423 return table; 424 425 if (!comMachine.GetAccessible()) 426 { 427 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 428 return table; 429 } 430 431 const CAudioAdapter comAudio = comMachine.GetAudioAdapter(); 432 if (comAudio.GetEnabled()) 433 { 434 /* Host driver: */ 435 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeAudio_Driver) 436 table << UITextTableLine(QApplication::translate("UIDetails", "Host Driver", "details (audio)"), 437 gpConverter->toString(comAudio.GetAudioDriver())); 438 439 /* Controller: */ 440 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeAudio_Controller) 441 table << UITextTableLine(QApplication::translate("UIDetails", "Controller", "details (audio)"), 442 gpConverter->toString(comAudio.GetAudioController())); 443 444 #ifdef VBOX_WITH_AUDIO_INOUT_INFO 445 /* Audio I/O: */ 446 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeAudio_IO) 447 { 448 table << UITextTableLine(QApplication::translate("UIDetails", "Audio Input", "details (audio)"), 449 comAudio.GetEnabledIn() ? 450 QApplication::translate("UIDetails", "Enabled", "details (audio/input)") : 451 QApplication::translate("UIDetails", "Disabled", "details (audio/input)")); 452 table << UITextTableLine(QApplication::translate("UIDetails", "Audio Output", "details (audio)"), 453 comAudio.GetEnabledOut() ? 454 QApplication::translate("UIDetails", "Enabled", "details (audio/output)") : 455 QApplication::translate("UIDetails", "Disabled", "details (audio/output)")); 456 } 457 #endif /* VBOX_WITH_AUDIO_INOUT_INFO */ 458 } 336 459 else 337 { 338 /* Layout text-pane: */ 339 int iTextPaneX = 2 * iMargin; 340 int iTextPaneY = iMargin + m_iMinimumHeaderHeight + 2 * iMargin; 341 m_pTextPane->setPos(iTextPaneX, iTextPaneY); 342 m_pTextPane->resize(size.width() - 4 * iMargin, 343 size.height() - 4 * iMargin - m_iMinimumHeaderHeight); 344 /* Show text-pane if still invisible and animation finished: */ 345 if (!m_pTextPane->isVisible() && !isAnimationRunning()) 346 m_pTextPane->show(); 347 } 348 } 349 350 int UIDetailsElement::minimumHeightHintForElement(bool fClosed) const 351 { 352 /* Prepare variables: */ 353 int iMargin = data(ElementData_Margin).toInt(); 354 int iMinimumHeightHint = 0; 355 356 /* Two margins: */ 357 iMinimumHeightHint += 2 * iMargin; 358 359 /* Header height: */ 360 iMinimumHeightHint += m_iMinimumHeaderHeight; 361 362 /* Element is opened? */ 363 if (!fClosed) 364 { 365 /* Add text height: */ 366 if (!m_pTextPane->isEmpty()) 367 iMinimumHeightHint += 2 * iMargin + (int)m_pTextPane->minimumSizeHint().height(); 368 } 369 370 /* Additional height during animation: */ 371 if (m_fAnimationRunning) 372 iMinimumHeightHint += m_iAdditionalHeight; 373 374 /* Return value: */ 375 return iMinimumHeightHint; 376 } 377 378 void UIDetailsElement::sltHandleWindowRemapped() 379 { 380 /* Update icon: */ 381 updateIcon(); 382 } 383 384 void UIDetailsElement::sltToggleButtonClicked() 385 { 386 emit sigToggleElement(m_enmType, isClosed()); 387 } 388 389 void UIDetailsElement::sltElementToggleStart() 390 { 391 /* Mark animation running: */ 392 m_fAnimationRunning = true; 393 394 /* Setup animation: */ 395 updateAnimationParameters(); 396 397 /* Invert toggle-state: */ 398 m_fClosed = !m_fClosed; 399 } 400 401 void UIDetailsElement::sltElementToggleFinish(bool fToggled) 402 { 403 /* Update toggle-state: */ 404 m_fClosed = !fToggled; 405 406 /* Notify about finishing: */ 407 emit sigToggleElementFinished(); 408 } 409 410 void UIDetailsElement::sltHandleAnchorClicked(const QString &strAnchor) 411 { 412 /* Current anchor role: */ 413 const QString strRole = strAnchor.section(',', 0, 0); 414 const QString strData = strAnchor.section(',', 1); 415 416 /* Handle known anchor roles: */ 417 if ( strRole == "#mount" // Optical and floppy attachments.. 418 || strRole == "#attach" // Hard-drive attachments.. 419 ) 420 { 421 /* Prepare storage-menu: */ 422 UIMenu menu; 423 menu.setShowToolTip(true); 424 425 /* Storage-controller name: */ 426 QString strControllerName = strData.section(',', 0, 0); 427 /* Storage-slot: */ 428 StorageSlot storageSlot = gpConverter->fromString<StorageSlot>(strData.section(',', 1)); 429 430 /* Fill storage-menu: */ 431 vboxGlobal().prepareStorageMenu(menu, this, SLOT(sltMountStorageMedium()), 432 machine(), strControllerName, storageSlot); 433 434 /* Exec menu: */ 435 menu.exec(QCursor::pos()); 436 } 437 } 438 439 void UIDetailsElement::sltMountStorageMedium() 440 { 441 /* Sender action: */ 442 QAction *pAction = qobject_cast<QAction*>(sender()); 443 AssertMsgReturnVoid(pAction, ("This slot should only be called by menu action!\n")); 444 445 /* Current mount-target: */ 446 const UIMediumTarget target = pAction->data().value<UIMediumTarget>(); 447 448 /* Update current machine mount-target: */ 449 vboxGlobal().updateMachineStorage(machine(), target); 450 } 451 452 void UIDetailsElement::prepareElement() 453 { 454 /* Initialization: */ 455 m_nameFont = font(); 456 m_nameFont.setWeight(QFont::Bold); 457 m_textFont = font(); 458 459 /* Update icon: */ 460 updateIcon(); 461 462 /* Create hovering animation machine: */ 463 m_pHoveringMachine = new QStateMachine(this); 464 if (m_pHoveringMachine) 465 { 466 /* Create 'default' state: */ 467 QState *pStateDefault = new QState(m_pHoveringMachine); 468 /* Create 'hovered' state: */ 469 QState *pStateHovered = new QState(m_pHoveringMachine); 470 471 /* Configure 'default' state: */ 472 if (pStateDefault) 473 { 474 /* When we entering default state => we assigning animatedValue to m_iDefaultValue: */ 475 pStateDefault->assignProperty(this, "animatedValue", m_iDefaultValue); 476 477 /* Add state transition: */ 478 QSignalTransition *pDefaultToHovered = pStateDefault->addTransition(this, SIGNAL(sigHoverEnter()), pStateHovered); 479 if (pDefaultToHovered) 460 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (audio)"), 461 QString()); 462 return table; 463 } 464 465 QString summarizeGenericProperties(const CNetworkAdapter &adapter) 466 { 467 QVector<QString> names; 468 QVector<QString> props; 469 props = adapter.GetProperties(QString(), names); 470 QString strResult; 471 for (int i = 0; i < names.size(); ++i) 472 { 473 strResult += names[i] + "=" + props[i]; 474 if (i < names.size() - 1) 475 strResult += ", "; 476 } 477 return strResult; 478 } 479 480 UITextTable UIDetailsGenerator::generateMachineInformationNetwork(CMachine &comMachine, 481 const UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork &fOptions) 482 { 483 UITextTable table; 484 485 if (comMachine.isNull()) 486 return table; 487 488 if (!comMachine.GetAccessible()) 489 { 490 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 491 return table; 492 } 493 494 /* Iterate over all the adapters: */ 495 const ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(comMachine.GetChipsetType()); 496 for (ulong uSlot = 0; uSlot < uCount; ++uSlot) 497 { 498 const CNetworkAdapter comAdapter = comMachine.GetNetworkAdapter(uSlot); 499 500 /* Skip disabled adapters: */ 501 if (!comAdapter.GetEnabled()) 502 continue; 503 504 /* Gather adapter information: */ 505 const KNetworkAttachmentType enmType = comAdapter.GetAttachmentType(); 506 const QString strAttachmentTemplate = gpConverter->toString(comAdapter.GetAdapterType()).replace(QRegExp("\\s\\(.+\\)"), " (%1)"); 507 QString strAttachmentType; 508 switch (enmType) 509 { 510 case KNetworkAttachmentType_Bridged: 511 { 512 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_BridgetAdapter) 513 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Bridged Adapter, %1", "details (network)") 514 .arg(comAdapter.GetBridgedInterface())); 515 break; 516 } 517 case KNetworkAttachmentType_Internal: 518 { 519 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_InternalNetwork) 520 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Internal Network, '%1'", "details (network)") 521 .arg(comAdapter.GetInternalNetwork())); 522 break; 523 } 524 case KNetworkAttachmentType_HostOnly: 525 { 526 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_HostOnlyAdapter) 527 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Host-only Adapter, '%1'", "details (network)") 528 .arg(comAdapter.GetHostOnlyInterface())); 529 break; 530 } 531 case KNetworkAttachmentType_Generic: 532 { 533 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_GenericDriver) 534 { 535 const QString strGenericDriverProperties(summarizeGenericProperties(comAdapter)); 536 strAttachmentType = strGenericDriverProperties.isNull() ? 537 strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Generic Driver, '%1'", "details (network)") 538 .arg(comAdapter.GetGenericDriver())) : 539 strAttachmentTemplate.arg(QApplication::translate("UIDetails", "Generic Driver, '%1' { %2 }", "details (network)") 540 .arg(comAdapter.GetGenericDriver(), strGenericDriverProperties)); 541 } 542 break; 543 } 544 case KNetworkAttachmentType_NATNetwork: 545 { 546 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_NAT) 547 strAttachmentType = strAttachmentTemplate.arg(QApplication::translate("UIDetails", "NAT Network, '%1'", "details (network)") 548 .arg(comAdapter.GetNATNetwork())); 549 break; 550 } 551 default: 552 { 553 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork_NotAttached) 554 strAttachmentType = strAttachmentTemplate.arg(gpConverter->toString(enmType)); 555 break; 556 } 557 } 558 if (!strAttachmentType.isNull()) 559 table << UITextTableLine(QApplication::translate("UIDetails", "Adapter %1", "details (network)").arg(comAdapter.GetSlot() + 1), strAttachmentType); 560 } 561 if (table.isEmpty()) 562 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (network/adapter)"), QString()); 563 564 return table; 565 } 566 567 UITextTable UIDetailsGenerator::generateMachineInformationSerial(CMachine &comMachine, 568 const UIExtraDataMetaDefs::DetailsElementOptionTypeSerial &fOptions) 569 { 570 UITextTable table; 571 572 if (comMachine.isNull()) 573 return table; 574 575 if (!comMachine.GetAccessible()) 576 { 577 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 578 return table; 579 } 580 581 582 /* Iterate over all the ports: */ 583 const ulong uCount = vboxGlobal().virtualBox().GetSystemProperties().GetSerialPortCount(); 584 for (ulong uSlot = 0; uSlot < uCount; ++uSlot) 585 { 586 const CSerialPort comPort = comMachine.GetSerialPort(uSlot); 587 588 /* Skip disabled adapters: */ 589 if (!comPort.GetEnabled()) 590 continue; 591 592 /* Gather port information: */ 593 const KPortMode enmMode = comPort.GetHostMode(); 594 const QString strModeTemplate = vboxGlobal().toCOMPortName(comPort.GetIRQ(), comPort.GetIOBase()) + ", "; 595 QString strModeType; 596 switch (enmMode) 597 { 598 case KPortMode_HostPipe: 599 { 600 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_HostPipe) 601 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 602 break; 603 } 604 case KPortMode_HostDevice: 605 { 606 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_HostDevice) 607 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 608 break; 609 } 610 case KPortMode_RawFile: 611 { 612 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_RawFile) 613 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 614 break; 615 } 616 case KPortMode_TCP: 617 { 618 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_TCP) 619 strModeType = strModeTemplate + QString("%1 (%2)").arg(gpConverter->toString(enmMode)).arg(QDir::toNativeSeparators(comPort.GetPath())); 620 break; 621 } 622 default: 623 { 624 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeSerial_Disconnected) 625 strModeType = strModeTemplate + gpConverter->toString(enmMode); 626 break; 627 } 628 } 629 if (!strModeType.isNull()) 630 table << UITextTableLine(QApplication::translate("UIDetails", "Port %1", "details (serial)").arg(comPort.GetSlot() + 1), strModeType); 631 } 632 if (table.isEmpty()) 633 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (serial)"), QString()); 634 635 return table; 636 } 637 638 UITextTable UIDetailsGenerator::generateMachineInformationUSB(CMachine &comMachine, 639 const UIExtraDataMetaDefs::DetailsElementOptionTypeUsb &fOptions) 640 { 641 642 UITextTable table; 643 644 if (comMachine.isNull()) 645 return table; 646 647 if (!comMachine.GetAccessible()) 648 { 649 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 650 return table; 651 } 652 /* Iterate over all the USB filters: */ 653 const CUSBDeviceFilters comFilterObject = comMachine.GetUSBDeviceFilters(); 654 if (!comFilterObject.isNull() && comMachine.GetUSBProxyAvailable()) 655 { 656 const CUSBControllerVector controllers = comMachine.GetUSBControllers(); 657 if (!controllers.isEmpty()) 658 { 659 /* USB controllers: */ 660 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUsb_Controller) 480 661 { 481 /* Create forward animation: */ 482 m_pHoveringAnimationForward = new QPropertyAnimation(this, "animatedValue", this); 483 if (m_pHoveringAnimationForward) 484 { 485 m_pHoveringAnimationForward->setDuration(m_iAnimationDuration); 486 m_pHoveringAnimationForward->setStartValue(m_iDefaultValue); 487 m_pHoveringAnimationForward->setEndValue(m_iHoveredValue); 488 489 /* Add to transition: */ 490 pDefaultToHovered->addAnimation(m_pHoveringAnimationForward); 491 } 662 QStringList controllersReadable; 663 foreach (const CUSBController &comController, controllers) 664 controllersReadable << gpConverter->toString(comController.GetType()); 665 table << UITextTableLine(QApplication::translate("UIDetails", "USB Controller", "details (usb)"), 666 controllersReadable.join(", ")); 492 667 } 493 } 494 495 /* Configure 'hovered' state: */ 496 if (pStateHovered) 497 { 498 /* When we entering hovered state => we assigning animatedValue to m_iHoveredValue: */ 499 pStateHovered->assignProperty(this, "animatedValue", m_iHoveredValue); 500 501 /* Add state transition: */ 502 QSignalTransition *pHoveredToDefault = pStateHovered->addTransition(this, SIGNAL(sigHoverLeave()), pStateDefault); 503 if (pHoveredToDefault) 668 669 /* Device filters: */ 670 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUsb_DeviceFilters) 504 671 { 505 /* Create backward animation: */ 506 m_pHoveringAnimationBackward = new QPropertyAnimation(this, "animatedValue", this); 507 if (m_pHoveringAnimationBackward) 508 { 509 m_pHoveringAnimationBackward->setDuration(m_iAnimationDuration); 510 m_pHoveringAnimationBackward->setStartValue(m_iHoveredValue); 511 m_pHoveringAnimationBackward->setEndValue(m_iDefaultValue); 512 513 /* Add to transition: */ 514 pHoveredToDefault->addAnimation(m_pHoveringAnimationBackward); 515 } 672 const CUSBDeviceFilterVector filters = comFilterObject.GetDeviceFilters(); 673 uint uActive = 0; 674 for (int i = 0; i < filters.size(); ++i) 675 if (filters.at(i).GetActive()) 676 ++uActive; 677 table << UITextTableLine(QApplication::translate("UIDetails", "Device Filters", "details (usb)"), 678 QApplication::translate("UIDetails", "%1 (%2 active)", "details (usb)").arg(filters.size()).arg(uActive)); 516 679 } 517 680 } 518 519 /* Initial state is 'default': */ 520 m_pHoveringMachine->setInitialState(pStateDefault); 521 /* Start state-machine: */ 522 m_pHoveringMachine->start(); 523 } 524 525 /* Configure connections: */ 526 connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped, 527 this, &UIDetailsElement::sltHandleWindowRemapped); 528 connect(this, SIGNAL(sigToggleElement(DetailsElementType, bool)), 529 model(), SLOT(sltToggleElements(DetailsElementType, bool))); 530 connect(this, SIGNAL(sigLinkClicked(const QString&, const QString&, const QUuid &)), 531 model(), SIGNAL(sigLinkClicked(const QString&, const QString&, const QUuid &))); 532 } 533 534 void UIDetailsElement::prepareButton() 535 { 536 /* Setup toggle-button: */ 537 m_pButton = new UIGraphicsRotatorButton(this, "additionalHeight", !m_fClosed, true /* reflected */); 538 m_pButton->setAutoHandleButtonClick(false); 539 connect(m_pButton, SIGNAL(sigButtonClicked()), this, SLOT(sltToggleButtonClicked())); 540 connect(m_pButton, SIGNAL(sigRotationStart()), this, SLOT(sltElementToggleStart())); 541 connect(m_pButton, SIGNAL(sigRotationFinish(bool)), this, SLOT(sltElementToggleFinish(bool))); 542 m_buttonSize = m_pButton->minimumSizeHint().toSize(); 543 } 544 545 void UIDetailsElement::prepareTextPane() 546 { 547 /* Create text-pane: */ 548 m_pTextPane = new UIGraphicsTextPane(this, model()->paintDevice()); 549 connect(m_pTextPane, SIGNAL(sigGeometryChanged()), this, SLOT(sltUpdateGeometry())); 550 connect(m_pTextPane, SIGNAL(sigAnchorClicked(const QString&)), this, SLOT(sltHandleAnchorClicked(const QString&))); 551 } 552 553 void UIDetailsElement::updateIcon() 554 { 555 /* Prepare whole icon first of all: */ 556 const QIcon icon = gpConverter->toIcon(elementType()); 557 558 /* Cache icon: */ 559 if (icon.isNull()) 560 { 561 /* No icon provided: */ 562 m_pixmapSize = QSize(); 563 m_pixmap = QPixmap(); 681 else 682 table << UITextTableLine(QApplication::translate("UIDetails", "Disabled", "details (usb)"), QString()); 564 683 } 565 684 else 566 { 567 /* Determine default icon size: */ 568 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 569 m_pixmapSize = QSize(iIconMetric, iIconMetric); 570 /* Acquire the icon of corresponding size (taking top-level widget DPI into account): */ 571 m_pixmap = icon.pixmap(gpManager->windowHandle(), m_pixmapSize); 572 } 573 574 /* Update linked values: */ 575 updateMinimumHeaderWidth(); 576 updateMinimumHeaderHeight(); 577 } 578 579 void UIDetailsElement::handleHoverEvent(QGraphicsSceneHoverEvent *pEvent) 580 { 581 /* Not for 'preview' element type: */ 582 if (m_enmType == DetailsElementType_Preview) 583 return; 584 585 /* Prepare variables: */ 586 int iMargin = data(ElementData_Margin).toInt(); 587 int iSpacing = data(ElementData_Spacing).toInt(); 588 int iNameHeight = m_nameSize.height(); 589 int iElementNameX = 2 * iMargin + m_pixmapSize.width() + iSpacing; 590 int iElementNameY = iNameHeight == m_iMinimumHeaderHeight ? 591 iMargin : iMargin + (m_iMinimumHeaderHeight - iNameHeight) / 2; 592 593 /* Simulate hyperlink hovering: */ 594 QPoint point = pEvent->pos().toPoint(); 595 bool fNameHovered = QRect(QPoint(iElementNameX, iElementNameY), m_nameSize).contains(point); 596 if ( m_pSet->configurationAccessLevel() != ConfigurationAccessLevel_Null 597 && m_fNameHovered != fNameHovered) 598 { 599 m_fNameHovered = fNameHovered; 600 updateNameHoverLink(); 601 } 602 } 603 604 void UIDetailsElement::updateNameHoverLink() 605 { 606 if (m_fNameHovered) 607 VBoxGlobal::setCursor(this, Qt::PointingHandCursor); 685 table << UITextTableLine(QApplication::translate("UIDetails", "USB Controller Inaccessible", "details (usb)"), QString()); 686 687 return table; 688 } 689 690 UITextTable UIDetailsGenerator::generateMachineInformationSharedFolders(CMachine &comMachine, 691 const UIExtraDataMetaDefs::DetailsElementOptionTypeSharedFolders &fOptions) 692 { 693 (void)fOptions; 694 UITextTable table; 695 696 if (comMachine.isNull()) 697 return table; 698 699 if (!comMachine.GetAccessible()) 700 { 701 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 702 return table; 703 } 704 /* Summary: */ 705 const ulong uCount = comMachine.GetSharedFolders().size(); 706 if (uCount > 0) 707 table << UITextTableLine(QApplication::translate("UIDetails", "Shared Folders", "details (shared folders)"), QString::number(uCount)); 608 708 else 609 VBoxGlobal::unsetCursor(this); 610 update(); 611 } 612 613 void UIDetailsElement::updateAnimationParameters() 614 { 615 /* Recalculate animation parameters: */ 616 int iOpenedHeight = minimumHeightHintForElement(false); 617 int iClosedHeight = minimumHeightHintForElement(true); 618 int iAdditionalHeight = iOpenedHeight - iClosedHeight; 619 if (m_fClosed) 620 m_iAdditionalHeight = 0; 709 table << UITextTableLine(QApplication::translate("UIDetails", "None", "details (shared folders)"), QString()); 710 711 return table; 712 } 713 714 UITextTable UIDetailsGenerator::generateMachineInformationUI(CMachine &comMachine, 715 const UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface &fOptions) 716 { 717 UITextTable table; 718 719 if (comMachine.isNull()) 720 return table; 721 722 if (!comMachine.GetAccessible()) 723 { 724 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 725 return table; 726 } 727 /* Gather information: */ 728 #ifndef VBOX_WS_MAC 729 /* Menu-bar: */ 730 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface_MenuBar) 731 { 732 const QString strMenubarEnabled = comMachine.GetExtraData(UIExtraDataDefs::GUI_MenuBar_Enabled); 733 /* Try to convert loaded data to bool: */ 734 const bool fEnabled = !( strMenubarEnabled.compare("false", Qt::CaseInsensitive) == 0 735 || strMenubarEnabled.compare("no", Qt::CaseInsensitive) == 0 736 || strMenubarEnabled.compare("off", Qt::CaseInsensitive) == 0 737 || strMenubarEnabled == "0"); 738 /* Append information: */ 739 table << UITextTableLine(QApplication::translate("UIDetails", "Menu-bar", "details (user interface)"), 740 fEnabled ? QApplication::translate("UIDetails", "Enabled", "details (user interface/menu-bar)") 741 : QApplication::translate("UIDetails", "Disabled", "details (user interface/menu-bar)")); 742 } 743 #endif /* !VBOX_WS_MAC */ 744 745 /* Status-bar: */ 746 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface_StatusBar) 747 { 748 const QString strStatusbarEnabled = comMachine.GetExtraData(UIExtraDataDefs::GUI_StatusBar_Enabled); 749 /* Try to convert loaded data to bool: */ 750 const bool fEnabled = !( strStatusbarEnabled.compare("false", Qt::CaseInsensitive) == 0 751 || strStatusbarEnabled.compare("no", Qt::CaseInsensitive) == 0 752 || strStatusbarEnabled.compare("off", Qt::CaseInsensitive) == 0 753 || strStatusbarEnabled == "0"); 754 /* Append information: */ 755 table << UITextTableLine(QApplication::translate("UIDetails", "Status-bar", "details (user interface)"), 756 fEnabled ? QApplication::translate("UIDetails", "Enabled", "details (user interface/status-bar)") 757 : QApplication::translate("UIDetails", "Disabled", "details (user interface/status-bar)")); 758 } 759 760 #ifndef VBOX_WS_MAC 761 /* Mini-toolbar: */ 762 if (fOptions & UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface_MiniToolbar) 763 { 764 const QString strMiniToolbarEnabled = comMachine.GetExtraData(UIExtraDataDefs::GUI_ShowMiniToolBar); 765 /* Try to convert loaded data to bool: */ 766 const bool fEnabled = !( strMiniToolbarEnabled.compare("false", Qt::CaseInsensitive) == 0 767 || strMiniToolbarEnabled.compare("no", Qt::CaseInsensitive) == 0 768 || strMiniToolbarEnabled.compare("off", Qt::CaseInsensitive) == 0 769 || strMiniToolbarEnabled == "0"); 770 /* Append information: */ 771 if (fEnabled) 772 { 773 /* Get mini-toolbar position: */ 774 const QString strMiniToolbarPosition = comMachine.GetExtraData(UIExtraDataDefs::GUI_MiniToolBarAlignment); 775 { 776 /* Try to convert loaded data to alignment: */ 777 switch (gpConverter->fromInternalString<MiniToolbarAlignment>(strMiniToolbarPosition)) 778 { 779 /* Append information: */ 780 case MiniToolbarAlignment_Top: 781 table << UITextTableLine(QApplication::translate("UIDetails", "Mini-toolbar Position", "details (user interface)"), 782 QApplication::translate("UIDetails", "Top", "details (user interface/mini-toolbar position)")); 783 break; 784 /* Append information: */ 785 case MiniToolbarAlignment_Bottom: 786 table << UITextTableLine(QApplication::translate("UIDetails", "Mini-toolbar Position", "details (user interface)"), 787 QApplication::translate("UIDetails", "Bottom", "details (user interface/mini-toolbar position)")); 788 break; 789 } 790 } 791 } 792 /* Append information: */ 793 else 794 table << UITextTableLine(QApplication::translate("UIDetails", "Mini-toolbar", "details (user interface)"), 795 QApplication::translate("UIDetails", "Disabled", "details (user interface/mini-toolbar)")); 796 } 797 #endif /* !VBOX_WS_MAC */ 798 return table; 799 } 800 801 UITextTable UIDetailsGenerator::generateMachineInformationDetails(CMachine &comMachine, 802 const UIExtraDataMetaDefs::DetailsElementOptionTypeDescription &fOptions) 803 { 804 (void)fOptions; 805 UITextTable table; 806 807 if (comMachine.isNull()) 808 return table; 809 810 if (!comMachine.GetAccessible()) 811 { 812 table << UITextTableLine(QApplication::translate("UIDetails", "Information Inaccessible", "details"), QString()); 813 return table; 814 } 815 816 /* Gather information: */ 817 /* Summary: */ 818 const QString strDescription = comMachine.GetDescription(); 819 if (!strDescription.isEmpty()) 820 table << UITextTableLine(strDescription, QString()); 621 821 else 622 m_iAdditionalHeight = iAdditionalHeight; 623 m_pButton->setAnimationRange(0, iAdditionalHeight); 624 } 625 626 void UIDetailsElement::updateButtonVisibility() 627 { 628 if (m_fHovered && !m_pButton->isVisible()) 629 m_pButton->show(); 630 else if (!m_fHovered && m_pButton->isVisible()) 631 m_pButton->hide(); 632 } 633 634 void UIDetailsElement::updateMinimumHeaderWidth() 635 { 636 /* Prepare variables: */ 637 int iSpacing = data(ElementData_Spacing).toInt(); 638 639 /* Update minimum-header-width: */ 640 m_iMinimumHeaderWidth = m_pixmapSize.width() + 641 iSpacing + m_nameSize.width() + 642 iSpacing + m_buttonSize.width(); 643 } 644 645 void UIDetailsElement::updateMinimumHeaderHeight() 646 { 647 /* Update minimum-header-height: */ 648 m_iMinimumHeaderHeight = qMax(m_pixmapSize.height(), m_nameSize.height()); 649 m_iMinimumHeaderHeight = qMax(m_iMinimumHeaderHeight, m_buttonSize.height()); 650 } 651 652 void UIDetailsElement::paintBackground(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions) const 653 { 654 /* Save painter: */ 655 pPainter->save(); 656 657 /* Prepare variables: */ 658 const int iMargin = data(ElementData_Margin).toInt(); 659 const int iHeadHeight = 2 * iMargin + m_iMinimumHeaderHeight; 660 const QRect optionRect = pOptions->rect; 661 const QRect headRect = QRect(optionRect.topLeft(), QSize(optionRect.width(), iHeadHeight)); 662 const QRect fullRect = m_fAnimationRunning 663 ? QRect(optionRect.topLeft(), QSize(optionRect.width(), iHeadHeight + m_iAdditionalHeight)) 664 : optionRect; 665 666 /* Acquire palette: */ 667 const QPalette pal = palette(); 668 669 /* Paint default background: */ 670 const QColor defaultColor = pal.color(QPalette::Active, QPalette::Mid); 671 const QColor dcTone1 = defaultColor.lighter(m_iDefaultToneFinal); 672 const QColor dcTone2 = defaultColor.lighter(m_iDefaultToneStart); 673 QLinearGradient gradientDefault(fullRect.topLeft(), fullRect.bottomLeft()); 674 gradientDefault.setColorAt(0, dcTone1); 675 gradientDefault.setColorAt(1, dcTone2); 676 pPainter->fillRect(fullRect, gradientDefault); 677 678 /* If element is hovered: */ 679 if (m_fHovered) 680 { 681 /* Paint hovered background: */ 682 const QColor hoveredColor = pal.color(QPalette::Active, QPalette::Highlight); 683 QColor hcTone1 = hoveredColor.lighter(m_iHoverToneFinal); 684 QColor hcTone2 = hoveredColor.lighter(m_iHoverToneStart); 685 hcTone1.setAlpha(m_iAnimatedValue); 686 hcTone2.setAlpha(m_iAnimatedValue); 687 QLinearGradient gradientHovered(headRect.topLeft(), headRect.bottomLeft()); 688 gradientHovered.setColorAt(0, hcTone1); 689 gradientHovered.setColorAt(1, hcTone2); 690 pPainter->fillRect(headRect, gradientHovered); 691 } 692 693 /* Restore painter: */ 694 pPainter->restore(); 695 } 696 697 void UIDetailsElement::paintFrame(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions) const 698 { 699 /* Save painter: */ 700 pPainter->save(); 701 702 /* Prepare variables: */ 703 const int iMargin = data(ElementData_Margin).toInt(); 704 const int iHeadHeight = 2 * iMargin + m_iMinimumHeaderHeight; 705 const QRect optionRect = pOptions->rect; 706 const QRect rectangle = m_fAnimationRunning 707 ? QRect(optionRect.topLeft(), QSize(optionRect.width(), iHeadHeight + m_iAdditionalHeight)) 708 : optionRect; 709 710 /* Paint frame: */ 711 const QColor strokeColor = palette().color(QPalette::Active, QPalette::Mid).lighter(m_iDefaultToneStart); 712 QPen pen(strokeColor); 713 pen.setWidth(0); 714 pPainter->setPen(pen); 715 pPainter->drawLine(rectangle.topLeft(), rectangle.topRight()); 716 pPainter->drawLine(rectangle.bottomLeft(), rectangle.bottomRight()); 717 pPainter->drawLine(rectangle.topLeft(), rectangle.bottomLeft()); 718 pPainter->drawLine(rectangle.topRight(), rectangle.bottomRight()); 719 720 /* Restore painter: */ 721 pPainter->restore(); 722 } 723 724 void UIDetailsElement::paintElementInfo(QPainter *pPainter, const QStyleOptionGraphicsItem *) const 725 { 726 /* Initialize some necessary variables: */ 727 const int iMargin = data(ElementData_Margin).toInt(); 728 const int iSpacing = data(ElementData_Spacing).toInt(); 729 730 /* Calculate attributes: */ 731 const int iPixmapHeight = m_pixmapSize.height(); 732 const int iNameHeight = m_nameSize.height(); 733 const int iMaximumHeight = qMax(iPixmapHeight, iNameHeight); 734 735 /* Prepare color: */ 736 const QPalette pal = palette(); 737 const QColor buttonTextColor = pal.color(QPalette::Active, QPalette::ButtonText); 738 const QColor linkTextColor = pal.color(QPalette::Active, QPalette::Link); 739 740 /* Paint pixmap: */ 741 int iElementPixmapX = 2 * iMargin; 742 int iElementPixmapY = iPixmapHeight == iMaximumHeight ? 743 iMargin : iMargin + (iMaximumHeight - iPixmapHeight) / 2; 744 paintPixmap(/* Painter: */ 745 pPainter, 746 /* Rectangle to paint in: */ 747 QRect(QPoint(iElementPixmapX, iElementPixmapY), m_pixmapSize), 748 /* Pixmap to paint: */ 749 m_pixmap); 750 751 /* Paint name: */ 752 int iMachineNameX = iElementPixmapX + 753 m_pixmapSize.width() + 754 iSpacing; 755 int iMachineNameY = iNameHeight == iMaximumHeight ? 756 iMargin : iMargin + (iMaximumHeight - iNameHeight) / 2; 757 paintText(/* Painter: */ 758 pPainter, 759 /* Rectangle to paint in: */ 760 QPoint(iMachineNameX, iMachineNameY), 761 /* Font to paint text: */ 762 m_nameFont, 763 /* Paint device: */ 764 model()->paintDevice(), 765 /* Text to paint: */ 766 m_strName, 767 /* Name hovered? */ 768 m_fNameHovered ? linkTextColor : buttonTextColor); 769 } 770 771 /* static */ 772 void UIDetailsElement::paintPixmap(QPainter *pPainter, const QRect &rect, const QPixmap &pixmap) 773 { 774 pPainter->drawPixmap(rect, pixmap); 775 } 776 777 /* static */ 778 void UIDetailsElement::paintText(QPainter *pPainter, QPoint point, 779 const QFont &font, QPaintDevice *pPaintDevice, 780 const QString &strText, const QColor &color) 781 { 782 /* Prepare variables: */ 783 QFontMetrics fm(font, pPaintDevice); 784 point += QPoint(0, fm.ascent()); 785 786 /* Draw text: */ 787 pPainter->save(); 788 pPainter->setFont(font); 789 pPainter->setPen(color); 790 pPainter->drawText(point, strText); 791 pPainter->restore(); 792 } 822 table << UITextTableLine(QApplication::translate("UIDetails", "None", "details (description)"), QString()); 823 824 return table; 825 } -
trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIDetailsGenerator.h
r77435 r77455 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIDetails Element classdeclaration.3 * VBox Qt GUI - UIDetailsGenerator declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_manager_details_UIDetails Element_h19 #define FEQT_INCLUDED_SRC_manager_details_UIDetails Element_h18 #ifndef FEQT_INCLUDED_SRC_manager_details_UIDetailsGenerator_h 19 #define FEQT_INCLUDED_SRC_manager_details_UIDetailsGenerator_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 /* Qt includes: */25 #include <QIcon>26 27 24 /* GUI includes: */ 28 #include "UIDetailsItem.h"29 25 #include "UIExtraDataDefs.h" 30 26 #include "UITextTable.h" 31 27 32 /* Forward declarations: */33 class QPropertyAnimation;34 class QStateMachine;35 class QTextLayout;36 class UIDetailsSet;37 class UIGraphicsRotatorButton;38 class UIGraphicsTextPane;39 28 class CMachine; 40 29 41 30 42 /** UIDetailsItem extension implementing element item. */ 43 class UIDetailsElement : public UIDetailsItem 31 namespace UIDetailsGenerator 44 32 { 45 Q_OBJECT; 46 Q_PROPERTY(int animatedValue READ animatedValue WRITE setAnimatedValue); 47 Q_PROPERTY(int additionalHeight READ additionalHeight WRITE setAdditionalHeight); 33 UITextTable generateMachineInformationGeneral(CMachine &comMachine, 34 const UIExtraDataMetaDefs::DetailsElementOptionTypeGeneral &fOptions); 48 35 49 signals: 36 UITextTable generateMachineInformationSystem(CMachine &comMachine, 37 const UIExtraDataMetaDefs::DetailsElementOptionTypeSystem &fOptions); 50 38 51 /** @name Item stuff. 52 * @{ */ 53 /** Notifies about hover enter. */ 54 void sigHoverEnter(); 55 /** Notifies about hover leave. */ 56 void sigHoverLeave(); 39 UITextTable generateMachineInformationDisplay(CMachine &comMachine, 40 const UIExtraDataMetaDefs::DetailsElementOptionTypeDisplay &fOptions); 57 41 58 /** Notifies about @a enmType element @a fToggled. */ 59 void sigToggleElement(DetailsElementType enmType, bool fToggled); 60 /** Notifies about element toggle finished. */ 61 void sigToggleElementFinished(); 42 UITextTable generateMachineInformationStorage(CMachine &comMachine, 43 const UIExtraDataMetaDefs::DetailsElementOptionTypeStorage &fOptions); 62 44 63 /** Notifies about element link clicked. 64 * @param strCategory Brings the link category. 65 * @param strControl Brings the wanted settings control. 66 * @param uId Brings the ID. */ 67 void sigLinkClicked(const QString &strCategory, const QString &strControl, const QUuid &uId); 68 /** @} */ 45 UITextTable generateMachineInformationAudio(CMachine &comMachine, 46 const UIExtraDataMetaDefs::DetailsElementOptionTypeAudio &fOptions); 69 47 70 public: 48 UITextTable generateMachineInformationNetwork(CMachine &comMachine, 49 const UIExtraDataMetaDefs::DetailsElementOptionTypeNetwork &fOptions); 71 50 72 /** RTTI item type. */73 enum { Type = UIDetailsItemType_Element };51 UITextTable generateMachineInformationSerial(CMachine &comMachine, 52 const UIExtraDataMetaDefs::DetailsElementOptionTypeSerial &fOptions); 74 53 75 /** Constructs element item, passing pParent to the base-class. 76 * @param enmType Brings element type. 77 * @param fOpened Brings whether element is opened. */ 78 UIDetailsElement(UIDetailsSet *pParent, DetailsElementType enmType, bool fOpened); 79 /** Destructs element item. */ 80 virtual ~UIDetailsElement() /* override */; 54 UITextTable generateMachineInformationUSB(CMachine &comMachine, 55 const UIExtraDataMetaDefs::DetailsElementOptionTypeUsb &fOptions); 81 56 82 /** @name Item stuff. 83 * @{ */ 84 /** Returns element type. */ 85 DetailsElementType elementType() const { return m_enmType; } 57 UITextTable generateMachineInformationSharedFolders(CMachine &comMachine, 58 const UIExtraDataMetaDefs::DetailsElementOptionTypeSharedFolders &fOptions); 86 59 87 /** Defines the @a text table as the passed one. */ 88 void setText(const UITextTable &text); 89 /** Returns the reference to the text table. */ 90 UITextTable &text() const; 60 UITextTable generateMachineInformationUI(CMachine &comMachine, 61 const UIExtraDataMetaDefs::DetailsElementOptionTypeUserInterface &fOptions); 91 62 92 /** Closes group in @a fAnimated way if requested. */ 93 void close(bool fAnimated = true); 94 /** Returns whether group is closed. */ 95 bool isClosed() const { return m_fClosed; } 63 UITextTable generateMachineInformationDetails(CMachine &comMachine, 64 const UIExtraDataMetaDefs::DetailsElementOptionTypeDescription &fOptions); 65 } 96 66 97 /** Opens group in @a fAnimated way if requested. */ 98 void open(bool fAnimated = true); 99 /** Returns whether group is opened. */ 100 bool isOpened() const { return !m_fClosed; } 101 102 /** Returns whether toggle animation is running. */ 103 bool isAnimationRunning() const { return m_fAnimationRunning; } 104 /** Marks animation finished. */ 105 void markAnimationFinished(); 106 107 /** Updates element appearance. */ 108 virtual void updateAppearance(); 109 /** @} */ 110 111 /** @name Layout stuff. 112 * @{ */ 113 /** Returns minimum width-hint. */ 114 virtual int minimumWidthHint() const /* override */; 115 /** Returns minimum height-hint. */ 116 virtual int minimumHeightHint() const /* override */; 117 /** @} */ 118 119 protected: 120 121 /** Data field types. */ 122 enum ElementData 123 { 124 /* Hints: */ 125 ElementData_Margin, 126 ElementData_Spacing 127 }; 128 129 /** @name Event-handling stuff. 130 * @{ */ 131 /** Handles show @a pEvent. */ 132 virtual void showEvent(QShowEvent *pEvent) /* override */; 133 134 /** This event handler is delivered after the widget has been resized. */ 135 virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */; 136 137 /** Handles hover enter @a event. */ 138 virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */; 139 /** Handles hover leave @a event. */ 140 virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *pEvent) /* override */; 141 142 /** Handles mouse press @a event. */ 143 virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent) /* override */; 144 /** Handles mouse double-click @a event. */ 145 virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *pEvent) /* override */; 146 147 /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */ 148 virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */; 149 /** @} */ 150 151 /** @name Item stuff. 152 * @{ */ 153 /** Returns RTTI item type. */ 154 virtual int type() const /* override */ { return Type; } 155 156 /** Returns the description of the item. */ 157 virtual QString description() const /* override */; 158 159 /** Returns cached machine reference. */ 160 const CMachine &machine(); 161 162 /** Defines element @a strName. */ 163 void setName(const QString &strName); 164 165 /** Defines @a iAdditionalHeight during toggle animation. */ 166 void setAdditionalHeight(int iAdditionalHeight); 167 /** Returns additional height during toggle animation. */ 168 int additionalHeight() const { return m_iAdditionalHeight; } 169 /** Returns toggle button instance. */ 170 UIGraphicsRotatorButton *button() const { return m_pButton; } 171 172 /** Returns abstractly stored data value for certain @a iKey. */ 173 QVariant data(int iKey) const; 174 /** @} */ 175 176 /** @name Children stuff. 177 * @{ */ 178 /** Adds child @a pItem. */ 179 virtual void addItem(UIDetailsItem *pItem) /* override */; 180 /** Removes child @a pItem. */ 181 virtual void removeItem(UIDetailsItem *pItem) /* override */; 182 183 /** Returns children items of certain @a enmType. */ 184 virtual QList<UIDetailsItem*> items(UIDetailsItemType enmType) const /* override */; 185 /** Returns whether there are children items of certain @a enmType. */ 186 virtual bool hasItems(UIDetailsItemType enmType) const /* override */; 187 /** Clears children items of certain @a enmType. */ 188 virtual void clearItems(UIDetailsItemType enmType) /* override */; 189 /** @} */ 190 191 /** @name Layout stuff. 192 * @{ */ 193 /** Updates layout. */ 194 virtual void updateLayout() /* override */; 195 196 /** Returns minimum width-hint for @a fClosed element. */ 197 virtual int minimumHeightHintForElement(bool fClosed) const; 198 199 /** Returns minimum header width. */ 200 int minimumHeaderWidth() const { return m_iMinimumHeaderWidth; } 201 /** Returns minimum header height. */ 202 int minimumHeaderHeight() const { return m_iMinimumHeaderHeight; } 203 /** @} */ 204 205 private slots: 206 207 /** @name Item stuff. 208 * @{ */ 209 /** Handles top-level window remaps. */ 210 void sltHandleWindowRemapped(); 211 212 /** Handles toggle button click. */ 213 void sltToggleButtonClicked(); 214 /** Handles toggle start. */ 215 void sltElementToggleStart(); 216 /** Handles toggle finish. */ 217 void sltElementToggleFinish(bool fToggled); 218 219 /** Handles children anchor clicks. */ 220 void sltHandleAnchorClicked(const QString &strAnchor); 221 /** @} */ 222 223 /** @name Layout stuff. 224 * @{ */ 225 /** Handles children geometry changes. */ 226 void sltUpdateGeometry() { updateGeometry(); } 227 /** @} */ 228 229 /** @name Move to sub-class. 230 * @{ */ 231 /** Handles mount storage medium requests. */ 232 void sltMountStorageMedium(); 233 /** @} */ 234 235 private: 236 237 /** @name Prepare/cleanup cascade. 238 * @{ */ 239 /** Prepares element. */ 240 void prepareElement(); 241 /** Prepares toggle button. */ 242 void prepareButton(); 243 /** Prepares text pane. */ 244 void prepareTextPane(); 245 /** @} */ 246 247 /** @name Item stuff. 248 * @{ */ 249 /** Updates icon. */ 250 void updateIcon(); 251 252 /** Defines animated @a iValue. */ 253 void setAnimatedValue(int iValue) { m_iAnimatedValue = iValue; update(); } 254 /** Returns animated value. */ 255 int animatedValue() const { return m_iAnimatedValue; } 256 257 /** Handles any kind of hover @a pEvent. */ 258 void handleHoverEvent(QGraphicsSceneHoverEvent *pEvent); 259 /** Updates hovered link. */ 260 void updateNameHoverLink(); 261 262 /** Updates animation parameters. */ 263 void updateAnimationParameters(); 264 /** Updates toggle button visibility. */ 265 void updateButtonVisibility(); 266 /** @} */ 267 268 /** @name Layout stuff. 269 * @{ */ 270 /** Updates minimum header width. */ 271 void updateMinimumHeaderWidth(); 272 /** Updates minimum header height. */ 273 void updateMinimumHeaderHeight(); 274 /** @} */ 275 276 /** @name Painting stuff. 277 * @{ */ 278 /** Paints background using specified @a pPainter and certain @a pOptions. */ 279 void paintBackground(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions) const; 280 /** Paints frame using passed @a pPainter and certain @a pOptions. */ 281 void paintFrame(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions) const; 282 /** Paints element info using specified @a pPainter and certain @a pOptions. */ 283 void paintElementInfo(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions) const; 284 285 /** Paints @a pixmap using passed @a pPainter and spified @a rect. */ 286 static void paintPixmap(QPainter *pPainter, const QRect &rect, const QPixmap &pixmap); 287 /** Paints @a strText using passed @a pPainter, @a font, @a color, @a pPaintDevice and spified @a point. */ 288 static void paintText(QPainter *pPainter, QPoint point, 289 const QFont &font, QPaintDevice *pPaintDevice, 290 const QString &strText, const QColor &color); 291 /** @} */ 292 293 /** @name Item stuff. 294 * @{ */ 295 /** Holds the parent reference. */ 296 UIDetailsSet *m_pSet; 297 /** Holds the element type. */ 298 DetailsElementType m_enmType; 299 300 /** Holds the element pixmap. */ 301 QPixmap m_pixmap; 302 /** Holds the element name. */ 303 QString m_strName; 304 305 /** Holds the name font. */ 306 QFont m_nameFont; 307 /** Holds the text font. */ 308 QFont m_textFont; 309 310 /** Holds the start default tone. */ 311 int m_iDefaultToneStart; 312 /** Holds the final default tone. */ 313 int m_iDefaultToneFinal; 314 /** Holds the start hover tone. */ 315 int m_iHoverToneStart; 316 /** Holds the final hover tone. */ 317 int m_iHoverToneFinal; 318 319 /** Holds whether element is hovered. */ 320 bool m_fHovered; 321 /** Holds whether element name is hovered. */ 322 bool m_fNameHovered; 323 /** Holds the hovering animation machine instance. */ 324 QStateMachine *m_pHoveringMachine; 325 /** Holds the forward hovering animation instance. */ 326 QPropertyAnimation *m_pHoveringAnimationForward; 327 /** Holds the backward hovering animation instance. */ 328 QPropertyAnimation *m_pHoveringAnimationBackward; 329 /** Holds the animation duration. */ 330 int m_iAnimationDuration; 331 /** Holds the default animation value. */ 332 int m_iDefaultValue; 333 /** Holds the hovered animation value. */ 334 int m_iHoveredValue; 335 /** Holds the animated value. */ 336 int m_iAnimatedValue; 337 338 /** Holds the toggle button instance. */ 339 UIGraphicsRotatorButton *m_pButton; 340 /** Holds whether element is closed. */ 341 bool m_fClosed; 342 /** Holds whether animation is running. */ 343 bool m_fAnimationRunning; 344 /** Holds the additional height. */ 345 int m_iAdditionalHeight; 346 347 /** Holds the graphics text pane instance. */ 348 UIGraphicsTextPane *m_pTextPane; 349 /** @} */ 350 351 /** @name Layout stuff. 352 * @{ */ 353 /** Holds the pixmap size. */ 354 QSize m_pixmapSize; 355 /** Holds the name size. */ 356 QSize m_nameSize; 357 /** Holds the button size. */ 358 QSize m_buttonSize; 359 360 /** Holds minimum header width. */ 361 int m_iMinimumHeaderWidth; 362 /** Holds minimum header height. */ 363 int m_iMinimumHeaderHeight; 364 /** @} */ 365 }; 366 367 #endif /* !FEQT_INCLUDED_SRC_manager_details_UIDetailsElement_h */ 67 #endif /* !FEQT_INCLUDED_SRC_manager_details_UIDetailsGenerator_h */
Note:
See TracChangeset
for help on using the changeset viewer.