- Timestamp:
- Oct 2, 2023 11:48:39 AM (17 months ago)
- svn:sync-xref-src-repo-rev:
- 159327
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r101278 r101327 925 925 src/settings/editors/UIRecordingSettingsEditor.h \ 926 926 src/settings/editors/UIScaleFactorEditor.h \ 927 src/settings/editors/UISerialSettingsEditor.h \ 927 928 src/settings/editors/UISharedClipboardEditor.h \ 928 929 src/settings/editors/UISharedFolderDetailsEditor.h \ … … 1513 1514 src/settings/editors/UIRecordingSettingsEditor.cpp \ 1514 1515 src/settings/editors/UIScaleFactorEditor.cpp \ 1516 src/settings/editors/UISerialSettingsEditor.cpp \ 1515 1517 src/settings/editors/UISharedClipboardEditor.cpp \ 1516 1518 src/settings/editors/UISharedFolderDetailsEditor.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISerialSettingsEditor.cpp
r101325 r101327 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MachineSettingsSerialclass implementation.3 * VBox Qt GUI - UISerialSettingsEditor class implementation. 4 4 */ 5 5 … … 33 33 #include <QLabel> 34 34 #include <QLineEdit> 35 #include <QRegularExpressionValidator>36 35 37 36 /* GUI includes: */ 38 #include "QITabWidget.h"39 37 #include "QIWidgetValidator.h" 40 38 #include "UICommon.h" 41 39 #include "UIConverter.h" 42 #include "UIErrorString.h" 43 #include "UIMachineSettingsSerial.h" 44 #include "UITranslator.h" 40 #include "UISerialSettingsEditor.h" 45 41 46 42 /* COM includes: */ 47 #include "CPlatformProperties.h" 48 #include "CSerialPort.h" 49 50 51 /** Machine settings: Serial Port tab data structure. */ 52 struct UIDataSettingsMachineSerialPort 53 { 54 /** Constructs data. */ 55 UIDataSettingsMachineSerialPort() 56 : m_iSlot(-1) 57 , m_fPortEnabled(false) 58 , m_uIRQ(0) 59 , m_uIOAddress(0) 60 , m_hostMode(KPortMode_Disconnected) 61 , m_fServer(false) 62 , m_strPath(QString()) 63 {} 64 65 /** Returns whether the @a other passed data is equal to this one. */ 66 bool equal(const UIDataSettingsMachineSerialPort &other) const 67 { 68 return true 69 && (m_iSlot == other.m_iSlot) 70 && (m_fPortEnabled == other.m_fPortEnabled) 71 && (m_uIRQ == other.m_uIRQ) 72 && (m_uIOAddress == other.m_uIOAddress) 73 && (m_hostMode == other.m_hostMode) 74 && (m_fServer == other.m_fServer) 75 && (m_strPath == other.m_strPath) 76 ; 77 } 78 79 /** Returns whether the @a other passed data is equal to this one. */ 80 bool operator==(const UIDataSettingsMachineSerialPort &other) const { return equal(other); } 81 /** Returns whether the @a other passed data is different from this one. */ 82 bool operator!=(const UIDataSettingsMachineSerialPort &other) const { return !equal(other); } 83 84 /** Holds the serial port slot number. */ 85 int m_iSlot; 86 /** Holds whether the serial port is enabled. */ 87 bool m_fPortEnabled; 88 /** Holds the serial port IRQ. */ 89 ulong m_uIRQ; 90 /** Holds the serial port IO address. */ 91 ulong m_uIOAddress; 92 /** Holds the serial port host mode. */ 93 KPortMode m_hostMode; 94 /** Holds whether the serial port is server. */ 95 bool m_fServer; 96 /** Holds the serial port path. */ 97 QString m_strPath; 98 }; 99 100 101 /** Machine settings: Serial page data structure. */ 102 struct UIDataSettingsMachineSerial 103 { 104 /** Constructs data. */ 105 UIDataSettingsMachineSerial() {} 106 107 /** Returns whether the @a other passed data is equal to this one. */ 108 bool operator==(const UIDataSettingsMachineSerial & /* other */) const { return true; } 109 /** Returns whether the @a other passed data is different from this one. */ 110 bool operator!=(const UIDataSettingsMachineSerial & /* other */) const { return false; } 111 }; 112 113 114 /** Machine settings: Serial Port tab. */ 115 class UIMachineSettingsSerial : public QIWithRetranslateUI<QWidget> 116 { 117 Q_OBJECT; 118 119 signals: 120 121 /** Notifies about port changed. */ 122 void sigPortChanged(); 123 /** Notifies about path changed. */ 124 void sigPathChanged(); 125 /** Notifies about validity changed. */ 126 void sigValidityChanged(); 127 128 public: 129 130 /** Constructs tab passing @a pParent to the base-class. */ 131 UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent); 132 133 /** Loads port data from @a portCache. */ 134 void getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache); 135 /** Saves port data to @a portCache. */ 136 void putPortDataToCache(UISettingsCacheMachineSerialPort &portCache); 137 138 /** Performs validation, updates @a messages list if something is wrong. */ 139 bool validate(QList<UIValidationMessage> &messages); 140 141 /** Configures tab order according to passed @a pWidget. */ 142 QWidget *setOrderAfter(QWidget *pWidget); 143 144 /** Returns tab title. */ 145 QString tabTitle() const; 146 /** Returns whether port is enabled. */ 147 bool isPortEnabled() const; 148 /** Returns IRQ. */ 149 QString irq() const; 150 /** Returns IO address. */ 151 QString ioAddress() const; 152 /** Returns path. */ 153 QString path() const; 154 155 /** Performs tab polishing. */ 156 void polishTab(); 157 158 protected: 159 160 /** Handles translation event. */ 161 void retranslateUi(); 162 163 private slots: 164 165 /** Handles port availability being toggled to @a fOn. */ 166 void sltHandlePortAvailabilityToggled(bool fOn); 167 /** Handles port standard @a strOption being activated. */ 168 void sltHandlePortStandardOptionActivated(const QString &strOption); 169 /** Handles port mode change to item with certain @a iIndex. */ 170 void sltHandlePortModeChange(int iIndex); 171 172 private: 173 174 /** Prepares all. */ 175 void prepare(); 176 /** Prepares widgets. */ 177 void prepareWidgets(); 178 /** Prepares connections. */ 179 void prepareConnections(); 180 181 /** Populates combo-boxes. */ 182 void populateComboboxes(); 183 184 /** Holds the parent page reference. */ 185 UIMachineSettingsSerialPage *m_pParent; 186 187 /** Holds the port slot number. */ 188 int m_iSlot; 189 /** Holds the port mode. */ 190 KPortMode m_enmPortMode; 191 192 /** @name Widgets 193 * @{ */ 194 /** Holds the port check-box instance. */ 195 QCheckBox *m_pCheckBoxPort; 196 /** Holds the port settings widget instance. */ 197 QWidget *m_pWidgetPortSettings; 198 /** Holds the number label instance. */ 199 QLabel *m_pLabelNumber; 200 /** Holds the number combo instance. */ 201 QComboBox *m_pComboNumber; 202 /** Holds the IRQ label instance. */ 203 QLabel *m_pLabelIRQ; 204 /** Holds the IRQ editor instance. */ 205 QLineEdit *m_pLineEditIRQ; 206 /** Holds the IO address label instance. */ 207 QLabel *m_pLabelIOAddress; 208 /** Holds the IO address editor instance. */ 209 QLineEdit *m_pLineEditIOAddress; 210 /** Holds the mode label instance. */ 211 QLabel *m_pLabelMode; 212 /** Holds the mode combo instance. */ 213 QComboBox *m_pComboMode; 214 /** Holds the pipe check-box instance. */ 215 QCheckBox *m_pCheckBoxPipe; 216 /** Holds the path label instance. */ 217 QLabel *m_pLabelPath; 218 /** Holds the path editor instance. */ 219 QLineEdit *m_pEditorPath; 220 /** @} */ 221 }; 222 223 224 /********************************************************************************************************************************* 225 * Class UIMachineSettingsSerial implementation. * 226 *********************************************************************************************************************************/ 227 228 UIMachineSettingsSerial::UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent) 229 : QIWithRetranslateUI<QWidget>(0) 230 , m_pParent(pParent) 231 , m_iSlot(-1) 232 , m_enmPortMode(KPortMode_Max) 43 #include "CSystemProperties.h" 44 45 46 UISerialSettingsEditor::UISerialSettingsEditor(QWidget *pParent /* = 0 */) 47 : UIEditor(pParent) 48 , m_enmPortMode(KPortMode_Disconnected) 233 49 , m_pCheckBoxPort(0) 234 50 , m_pWidgetPortSettings(0) … … 248 64 } 249 65 250 void UIMachineSettingsSerial::getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache) 251 { 252 /* Get old data: */ 253 const UIDataSettingsMachineSerialPort &oldPortData = portCache.base(); 254 255 /* Load port number: */ 256 m_iSlot = oldPortData.m_iSlot; 257 258 /* Load port data: */ 66 void UISerialSettingsEditor::setPortOptionsAvailable(bool fAvailable) 67 { 259 68 if (m_pCheckBoxPort) 260 m_pCheckBoxPort->setChecked(oldPortData.m_fPortEnabled); 69 m_pCheckBoxPort->setEnabled(fAvailable); 70 if (m_pLabelNumber) 71 m_pLabelNumber->setEnabled(fAvailable); 261 72 if (m_pComboNumber) 262 m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(oldPortData.m_uIRQ, oldPortData.m_uIOAddress))); 73 m_pComboNumber->setEnabled(fAvailable); 74 } 75 76 void UISerialSettingsEditor::setPortEnabled(bool fEnabled) 77 { 78 if (m_pCheckBoxPort) 79 { 80 const bool fIssueUpdateAnyway = m_pCheckBoxPort->isChecked() == fEnabled; 81 m_pCheckBoxPort->setChecked(fEnabled); 82 if (fIssueUpdateAnyway) 83 sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked()); 84 } 85 } 86 87 bool UISerialSettingsEditor::isPortEnabled() const 88 { 89 return m_pCheckBoxPort ? m_pCheckBoxPort->isChecked() : false; 90 } 91 92 void UISerialSettingsEditor::setIRQAndIOAddressOptionsAvailable(bool fAvailable) 93 { 94 if (m_pLabelIRQ) 95 m_pLabelIRQ->setEnabled(fAvailable); 263 96 if (m_pLineEditIRQ) 264 m_pLineEditIRQ->setText(QString::number(oldPortData.m_uIRQ)); 97 m_pLineEditIRQ->setEnabled(fAvailable); 98 if (m_pLabelIOAddress) 99 m_pLabelIOAddress->setEnabled(fAvailable); 265 100 if (m_pLineEditIOAddress) 266 m_pLineEditIOAddress->setText("0x" + QString::number(oldPortData.m_uIOAddress, 16).toUpper()); 267 m_enmPortMode = oldPortData.m_hostMode; 101 m_pLineEditIOAddress->setEnabled(fAvailable); 102 } 103 104 void UISerialSettingsEditor::setPortByIRQAndIOAddress(ulong uIRQ, ulong uIOAddress) 105 { 106 if (m_pComboNumber) 107 m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(uIRQ, uIOAddress))); 108 } 109 110 bool UISerialSettingsEditor::isPortStandardOne() const 111 { 112 ulong uIRQ, uIOAddress; 113 return m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false; 114 } 115 116 void UISerialSettingsEditor::setIRQ(ulong uIRQ) 117 { 118 if (m_pLineEditIRQ) 119 m_pLineEditIRQ->setText(QString::number(uIRQ)); 120 } 121 122 ulong UISerialSettingsEditor::irq() const 123 { 124 return m_pLineEditIRQ ? m_pLineEditIRQ->text().toULong(NULL, 0) : 0; 125 } 126 127 void UISerialSettingsEditor::setIOAddress(ulong uIOAddress) 128 { 129 if (m_pLineEditIOAddress) 130 m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper()); 131 } 132 133 ulong UISerialSettingsEditor::ioAddress() const 134 { 135 return m_pLineEditIOAddress ? m_pLineEditIOAddress->text().toULong(NULL, 0) : 0; 136 } 137 138 void UISerialSettingsEditor::setHostModeOptionsAvailable(bool fAvailable) 139 { 140 if (m_pLabelMode) 141 m_pLabelMode->setEnabled(fAvailable); 142 if (m_pComboMode) 143 m_pComboMode->setEnabled(fAvailable); 144 } 145 146 void UISerialSettingsEditor::setHostMode(KPortMode enmMode) 147 { 148 m_enmPortMode = enmMode; 149 populateCombo(); 150 } 151 152 KPortMode UISerialSettingsEditor::hostMode() const 153 { 154 return m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : m_enmPortMode; 155 } 156 157 void UISerialSettingsEditor::setPipeOptionsAvailable(bool fAvailable) 158 { 268 159 if (m_pCheckBoxPipe) 269 m_pCheckBoxPipe->setChecked(!oldPortData.m_fServer); 160 m_pCheckBoxPipe->setEnabled(fAvailable); 161 } 162 163 void UISerialSettingsEditor::setServerEnabled(bool fEnabled) 164 { 165 if (m_pCheckBoxPipe) 166 m_pCheckBoxPipe->setChecked(!fEnabled); 167 } 168 169 bool UISerialSettingsEditor::isServerEnabled() const 170 { 171 return m_pCheckBoxPipe ? !m_pCheckBoxPipe->isChecked() : true; 172 } 173 174 void UISerialSettingsEditor::setPathOptionsAvailable(bool fAvailable) 175 { 176 if (m_pLabelPath) 177 m_pLabelPath->setEnabled(fAvailable); 270 178 if (m_pEditorPath) 271 m_pEditorPath->setText(oldPortData.m_strPath); 272 273 /* Repopulate combo-boxes content: */ 274 populateComboboxes(); 275 /* Ensure everything is up-to-date */ 276 if (m_pCheckBoxPort) 277 sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked()); 278 } 279 280 void UIMachineSettingsSerial::putPortDataToCache(UISettingsCacheMachineSerialPort &portCache) 281 { 282 /* Prepare new data: */ 283 UIDataSettingsMachineSerialPort newPortData; 284 285 /* Save port number: */ 286 newPortData.m_iSlot = m_iSlot; 287 288 /* Save port data: */ 289 if (m_pCheckBoxPort) 290 newPortData.m_fPortEnabled = m_pCheckBoxPort->isChecked(); 291 if (m_pLineEditIRQ) 292 newPortData.m_uIRQ = m_pLineEditIRQ->text().toULong(NULL, 0); 293 if (m_pLineEditIOAddress) 294 newPortData.m_uIOAddress = m_pLineEditIOAddress->text().toULong(NULL, 0); 295 if (m_pCheckBoxPipe) 296 newPortData.m_fServer = !m_pCheckBoxPipe->isChecked(); 297 if (m_pComboMode) 298 newPortData.m_hostMode = m_pComboMode->currentData().value<KPortMode>(); 179 m_pEditorPath->setEnabled(fAvailable); 180 } 181 182 void UISerialSettingsEditor::setPath(const QString &strPath) 183 { 299 184 if (m_pEditorPath) 300 newPortData.m_strPath = QDir::toNativeSeparators(m_pEditorPath->text()); 301 302 /* Cache new data: */ 303 portCache.cacheCurrentData(newPortData); 304 } 305 306 bool UIMachineSettingsSerial::validate(QList<UIValidationMessage> &messages) 307 { 308 /* Pass by default: */ 309 bool fPass = true; 310 311 /* Prepare message: */ 312 UIValidationMessage message; 313 message.first = UITranslator::removeAccelMark(tabTitle()); 314 315 if ( m_pCheckBoxPort 316 && m_pCheckBoxPort->isChecked()) 317 { 318 /* Check the port attribute emptiness & uniqueness: */ 319 const QString strIRQ = m_pLineEditIRQ ? m_pLineEditIRQ->text() : QString(); 320 const QString strIOAddress = m_pLineEditIOAddress ? m_pLineEditIOAddress->text() : QString(); 321 const QPair<QString, QString> port = qMakePair(strIRQ, strIOAddress); 322 323 if (strIRQ.isEmpty()) 324 { 325 message.second << UIMachineSettingsSerial::tr("No IRQ is currently specified."); 326 fPass = false; 327 } 328 if (strIOAddress.isEmpty()) 329 { 330 message.second << UIMachineSettingsSerial::tr("No I/O port is currently specified."); 331 fPass = false; 332 } 333 if ( !strIRQ.isEmpty() 334 && !strIOAddress.isEmpty()) 335 { 336 QVector<QPair<QString, QString> > ports; 337 if (m_pParent) 338 { 339 ports = m_pParent->ports(); 340 ports.removeAt(m_iSlot); 341 } 342 if (ports.contains(port)) 343 { 344 message.second << UIMachineSettingsSerial::tr("Two or more ports have the same settings."); 345 fPass = false; 346 } 347 } 348 349 const KPortMode enmMode = m_pComboMode->currentData().value<KPortMode>(); 350 if (enmMode != KPortMode_Disconnected) 351 { 352 const QString strPath(m_pEditorPath->text()); 353 354 if (strPath.isEmpty()) 355 { 356 message.second << UIMachineSettingsSerial::tr("No port path is currently specified."); 357 fPass = false; 358 } 359 else 360 { 361 QVector<QString> paths; 362 if (m_pParent) 363 { 364 paths = m_pParent->paths(); 365 paths.removeAt(m_iSlot); 366 } 367 if (paths.contains(strPath)) 368 { 369 message.second << UIMachineSettingsSerial::tr("There are currently duplicate port paths specified."); 370 fPass = false; 371 } 372 } 373 } 374 } 375 376 /* Serialize message: */ 377 if (!message.second.isEmpty()) 378 messages << message; 379 380 /* Return result: */ 381 return fPass; 382 } 383 384 QWidget *UIMachineSettingsSerial::setOrderAfter(QWidget *pWidget) 385 { 386 setTabOrder(pWidget, m_pCheckBoxPort); 387 setTabOrder(m_pCheckBoxPort, m_pComboNumber); 388 setTabOrder(m_pComboNumber, m_pLineEditIRQ); 389 setTabOrder(m_pLineEditIRQ, m_pLineEditIOAddress); 390 setTabOrder(m_pLineEditIOAddress, m_pComboMode); 391 setTabOrder(m_pComboMode, m_pCheckBoxPipe); 392 setTabOrder(m_pCheckBoxPipe, m_pEditorPath); 393 return m_pEditorPath; 394 } 395 396 QString UIMachineSettingsSerial::tabTitle() const 397 { 398 return QString(tr("Port %1", "serial ports")).arg(QString("&%1").arg(m_iSlot + 1)); 399 } 400 401 bool UIMachineSettingsSerial::isPortEnabled() const 402 { 403 return m_pCheckBoxPort->isChecked(); 404 } 405 406 QString UIMachineSettingsSerial::irq() const 407 { 408 return m_pLineEditIRQ->text(); 409 } 410 411 QString UIMachineSettingsSerial::ioAddress() const 412 { 413 return m_pLineEditIOAddress->text(); 414 } 415 416 QString UIMachineSettingsSerial::path() const 417 { 418 return m_pEditorPath->text(); 419 } 420 421 void UIMachineSettingsSerial::polishTab() 422 { 423 /* Sanity check: */ 424 if (!m_pParent) 425 return; 426 427 /* Polish port page: */ 428 ulong uIRQ, uIOAddress; 429 const bool fStd = m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false; 430 const KPortMode enmMode = m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : KPortMode_Max; 431 if (m_pCheckBoxPort) 432 m_pCheckBoxPort->setEnabled(m_pParent->isMachineOffline()); 433 if (m_pLabelNumber) 434 m_pLabelNumber->setEnabled(m_pParent->isMachineOffline()); 435 if (m_pComboNumber) 436 m_pComboNumber->setEnabled(m_pParent->isMachineOffline()); 437 if (m_pLabelIRQ) 438 m_pLabelIRQ->setEnabled(m_pParent->isMachineOffline()); 439 if (m_pLineEditIRQ) 440 m_pLineEditIRQ->setEnabled(!fStd && m_pParent->isMachineOffline()); 441 if (m_pLabelIOAddress) 442 m_pLabelIOAddress->setEnabled(m_pParent->isMachineOffline()); 443 if (m_pLineEditIOAddress) 444 m_pLineEditIOAddress->setEnabled(!fStd && m_pParent->isMachineOffline()); 445 if (m_pLabelMode) 446 m_pLabelMode->setEnabled(m_pParent->isMachineOffline()); 447 if (m_pComboMode) 448 m_pComboMode->setEnabled(m_pParent->isMachineOffline()); 449 if (m_pCheckBoxPipe) 450 m_pCheckBoxPipe->setEnabled( (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP) 451 && m_pParent->isMachineOffline()); 452 if (m_pLabelPath) 453 m_pLabelPath->setEnabled( enmMode != KPortMode_Disconnected 454 && m_pParent->isMachineOffline()); 455 if (m_pEditorPath) 456 m_pEditorPath->setEnabled( enmMode != KPortMode_Disconnected 457 && m_pParent->isMachineOffline()); 458 } 459 460 void UIMachineSettingsSerial::retranslateUi() 185 m_pEditorPath->setText(strPath); 186 } 187 188 QString UISerialSettingsEditor::path() const 189 { 190 return m_pEditorPath ? QDir::toNativeSeparators(m_pEditorPath->text()) : QString(); 191 } 192 193 void UISerialSettingsEditor::retranslateUi() 461 194 { 462 195 if (m_pCheckBoxPort) … … 507 240 508 241 /* Translate combo-boxes content: */ 509 populateCombo boxes();510 } 511 512 void UI MachineSettingsSerial::sltHandlePortAvailabilityToggled(bool fOn)242 populateCombo(); 243 } 244 245 void UISerialSettingsEditor::sltHandlePortAvailabilityToggled(bool fOn) 513 246 { 514 247 /* Update availability: */ 515 m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked()); 248 if (m_pWidgetPortSettings && m_pCheckBoxPort) 249 m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked()); 516 250 if (fOn) 517 251 { 518 sltHandlePortStandardOptionActivated(m_pComboNumber->currentText()); 519 sltHandlePortModeChange(m_pComboMode->currentIndex()); 520 } 521 522 /* Notify port/path changed: */ 523 emit sigPortChanged(); 524 emit sigPathChanged(); 525 } 526 527 void UIMachineSettingsSerial::sltHandlePortStandardOptionActivated(const QString &strText) 252 if (m_pComboNumber) 253 sltHandleStandardPortOptionActivated(m_pComboNumber->currentText()); 254 if (m_pComboMode) 255 sltHandleModeChange(m_pComboMode->currentIndex()); 256 } 257 258 /* Notify about port availability changed: */ 259 emit sigPortAvailabilityChanged(); 260 } 261 262 void UISerialSettingsEditor::sltHandleStandardPortOptionActivated(const QString &strText) 528 263 { 529 264 /* Update availability: */ 530 265 ulong uIRQ, uIOAddress; 531 266 bool fStd = UITranslator::toCOMPortNumbers(strText, uIRQ, uIOAddress); 532 m_pLineEditIRQ->setEnabled(!fStd); 533 m_pLineEditIOAddress->setEnabled(!fStd); 267 if (m_pLineEditIRQ) 268 m_pLineEditIRQ->setEnabled(!fStd); 269 if (m_pLineEditIOAddress) 270 m_pLineEditIOAddress->setEnabled(!fStd); 534 271 if (fStd) 535 272 { 536 m_pLineEditIRQ->setText(QString::number(uIRQ)); 537 m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper()); 538 } 539 540 /* Notify validity changed: */ 541 emit sigValidityChanged(); 542 } 543 544 void UIMachineSettingsSerial::sltHandlePortModeChange(int iIndex) 273 if (m_pLineEditIRQ) 274 m_pLineEditIRQ->setText(QString::number(uIRQ)); 275 if (m_pLineEditIOAddress) 276 m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper()); 277 } 278 279 /* Notify about standard port option changed: */ 280 emit sigStandardPortOptionChanged(); 281 } 282 283 void UISerialSettingsEditor::sltHandleModeChange(int iIndex) 545 284 { 546 285 /* Update availability: */ 547 const KPortMode enmMode = m_pComboMode->itemData(iIndex).value<KPortMode>(); 548 m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP); 549 m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected); 550 m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected); 551 552 /* Notify validity changed: */ 553 emit sigValidityChanged(); 554 } 555 556 void UIMachineSettingsSerial::prepare() 286 const KPortMode enmMode = m_pComboMode ? m_pComboMode->itemData(iIndex).value<KPortMode>() : m_enmPortMode; 287 if (m_pCheckBoxPipe) 288 m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP); 289 if (m_pEditorPath) 290 m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected); 291 if (m_pLabelPath) 292 m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected); 293 294 /* Notify about mode changed: */ 295 emit sigModeChanged(); 296 } 297 298 void UISerialSettingsEditor::prepare() 557 299 { 558 300 /* Prepare everything: */ … … 564 306 } 565 307 566 void UI MachineSettingsSerial::prepareWidgets()308 void UISerialSettingsEditor::prepareWidgets() 567 309 { 568 310 /* Prepare main layout: */ … … 691 433 } 692 434 693 void UI MachineSettingsSerial::prepareConnections()435 void UISerialSettingsEditor::prepareConnections() 694 436 { 695 437 if (m_pCheckBoxPort) 696 connect(m_pCheckBoxPort, &QCheckBox::toggled, this, &UIMachineSettingsSerial::sltHandlePortAvailabilityToggled); 438 connect(m_pCheckBoxPort, &QCheckBox::toggled, 439 this, &UISerialSettingsEditor::sltHandlePortAvailabilityToggled); 697 440 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 698 441 if (m_pComboNumber) 699 442 connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::textActivated), 700 this, &UI MachineSettingsSerial::sltHandlePortStandardOptionActivated);443 this, &UISerialSettingsEditor::sltHandleStandardPortOptionActivated); 701 444 #else 702 445 if (m_pComboNumber) 703 446 connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::activated), 704 this, &UI MachineSettingsSerial::sltHandlePortStandardOptionActivated);447 this, &UISerialSettingsEditor::sltHandleStandardPortOptionActivated); 705 448 #endif 706 449 if (m_pLineEditIRQ) 707 connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UI MachineSettingsSerial::sigPortChanged);450 connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UISerialSettingsEditor::sigPortIRQChanged); 708 451 if (m_pLineEditIOAddress) 709 connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UI MachineSettingsSerial::sigPortChanged);452 connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UISerialSettingsEditor::sigPortIOAddressChanged); 710 453 if (m_pComboMode) 711 454 connect(m_pComboMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), 712 this, &UI MachineSettingsSerial::sltHandlePortModeChange);455 this, &UISerialSettingsEditor::sltHandleModeChange); 713 456 if (m_pEditorPath) 714 connect(m_pEditorPath, &QLineEdit::textChanged, this, &UI MachineSettingsSerial::sigPathChanged);715 } 716 717 void UI MachineSettingsSerial::populateComboboxes()718 { 719 /* Port mode: */720 { 721 /* Clear the portmode combo-box: */457 connect(m_pEditorPath, &QLineEdit::textChanged, this, &UISerialSettingsEditor::sigPathChanged); 458 } 459 460 void UISerialSettingsEditor::populateCombo() 461 { 462 if (m_pComboMode) 463 { 464 /* Clear the mode combo-box: */ 722 465 m_pComboMode->clear(); 723 466 … … 739 482 } 740 483 741 /* Choose requested portmode: */484 /* Choose requested mode: */ 742 485 const int iIndex = m_pComboMode->findData(QVariant::fromValue(m_enmPortMode)); 743 486 m_pComboMode->setCurrentIndex(iIndex != -1 ? iIndex : 0); 744 487 } 745 488 } 746 747 748 /*********************************************************************************************************************************749 * Class UIMachineSettingsSerialPage implementation. *750 *********************************************************************************************************************************/751 752 UIMachineSettingsSerialPage::UIMachineSettingsSerialPage()753 : m_pCache(0)754 , m_pTabWidget(0)755 {756 prepare();757 }758 759 UIMachineSettingsSerialPage::~UIMachineSettingsSerialPage()760 {761 cleanup();762 }763 764 bool UIMachineSettingsSerialPage::changed() const765 {766 return m_pCache ? m_pCache->wasChanged() : false;767 }768 769 void UIMachineSettingsSerialPage::loadToCacheFrom(QVariant &data)770 {771 /* Sanity check: */772 if ( !m_pCache773 || !m_pTabWidget)774 return;775 776 /* Fetch data to machine: */777 UISettingsPageMachine::fetchData(data);778 779 /* Clear cache initially: */780 m_pCache->clear();781 782 /* Cache lists: */783 refreshPorts();784 refreshPaths();785 786 /* Prepare old data: */787 UIDataSettingsMachineSerial oldSerialData;788 789 /* For each serial port: */790 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)791 {792 /* Prepare old data: */793 UIDataSettingsMachineSerialPort oldPortData;794 795 /* Check whether port is valid: */796 const CSerialPort &comPort = m_machine.GetSerialPort(iSlot);797 if (!comPort.isNull())798 {799 /* Gather old data: */800 oldPortData.m_iSlot = iSlot;801 oldPortData.m_fPortEnabled = comPort.GetEnabled();802 oldPortData.m_uIRQ = comPort.GetIRQ();803 oldPortData.m_uIOAddress = comPort.GetIOAddress();804 oldPortData.m_hostMode = comPort.GetHostMode();805 oldPortData.m_fServer = comPort.GetServer();806 oldPortData.m_strPath = comPort.GetPath();807 }808 809 /* Cache old data: */810 m_pCache->child(iSlot).cacheInitialData(oldPortData);811 }812 813 /* Cache old data: */814 m_pCache->cacheInitialData(oldSerialData);815 816 /* Upload machine to data: */817 UISettingsPageMachine::uploadData(data);818 }819 820 void UIMachineSettingsSerialPage::getFromCache()821 {822 /* Sanity check: */823 if ( !m_pCache824 || !m_pTabWidget)825 return;826 827 /* Setup tab order: */828 AssertPtrReturnVoid(firstWidget());829 setTabOrder(firstWidget(), m_pTabWidget->focusProxy());830 QWidget *pLastFocusWidget = m_pTabWidget->focusProxy();831 832 /* For each port: */833 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)834 {835 /* Get port page: */836 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));837 AssertPtrReturnVoid(pTab);838 839 /* Load old data from cache: */840 pTab->getPortDataFromCache(m_pCache->child(iSlot));841 842 /* Setup tab order: */843 pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget);844 }845 846 /* Apply language settings: */847 retranslateUi();848 849 /* Polish page finally: */850 polishPage();851 852 /* Revalidate: */853 revalidate();854 }855 856 void UIMachineSettingsSerialPage::putToCache()857 {858 /* Sanity check: */859 if ( !m_pCache860 || !m_pTabWidget)861 return;862 863 /* Prepare new data: */864 UIDataSettingsMachineSerial newSerialData;865 866 /* For each port: */867 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)868 {869 /* Getting port page: */870 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));871 AssertPtrReturnVoid(pTab);872 873 /* Gather new data: */874 pTab->putPortDataToCache(m_pCache->child(iSlot));875 }876 877 /* Cache new data: */878 m_pCache->cacheCurrentData(newSerialData);879 }880 881 void UIMachineSettingsSerialPage::saveFromCacheTo(QVariant &data)882 {883 /* Fetch data to machine: */884 UISettingsPageMachine::fetchData(data);885 886 /* Update data and failing state: */887 setFailed(!saveData());888 889 /* Upload machine to data: */890 UISettingsPageMachine::uploadData(data);891 }892 893 bool UIMachineSettingsSerialPage::validate(QList<UIValidationMessage> &messages)894 {895 /* Sanity check: */896 if (!m_pTabWidget)897 return false;898 899 /* Pass by default: */900 bool fValid = true;901 902 /* Delegate validation to adapter tabs: */903 for (int iIndex = 0; iIndex < m_pTabWidget->count(); ++iIndex)904 {905 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iIndex));906 AssertPtrReturn(pTab, false);907 if (!pTab->validate(messages))908 fValid = false;909 }910 911 /* Return result: */912 return fValid;913 }914 915 void UIMachineSettingsSerialPage::retranslateUi()916 {917 /* Sanity check: */918 if (!m_pTabWidget)919 return;920 921 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)922 {923 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));924 AssertPtrReturnVoid(pTab);925 m_pTabWidget->setTabText(iSlot, pTab->tabTitle());926 }927 }928 929 void UIMachineSettingsSerialPage::polishPage()930 {931 /* Sanity check: */932 if ( !m_pCache933 || !m_pTabWidget)934 return;935 936 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)937 {938 m_pTabWidget->setTabEnabled(iSlot,939 isMachineOffline() ||940 (isMachineInValidMode() &&941 m_pCache->childCount() > iSlot &&942 m_pCache->child(iSlot).base().m_fPortEnabled));943 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));944 AssertPtrReturnVoid(pTab);945 pTab->polishTab();946 }947 }948 949 void UIMachineSettingsSerialPage::sltHandlePortChange()950 {951 refreshPorts();952 revalidate();953 }954 955 void UIMachineSettingsSerialPage::sltHandlePathChange()956 {957 refreshPaths();958 revalidate();959 }960 961 void UIMachineSettingsSerialPage::prepare()962 {963 /* Prepare cache: */964 m_pCache = new UISettingsCacheMachineSerial;965 AssertPtrReturnVoid(m_pCache);966 967 /* Create main layout: */968 QVBoxLayout *pLayoutMain = new QVBoxLayout(this);969 if (pLayoutMain)970 {971 /* Creating tab-widget: */972 m_pTabWidget = new QITabWidget;973 if (m_pTabWidget)974 {975 /* How many ports to display: */976 const ulong uCount = uiCommon().virtualBox().GetPlatformProperties(KPlatformArchitecture_x86).GetSerialPortCount();977 978 /* Create corresponding port tabs: */979 for (ulong uSlot = 0; uSlot < uCount; ++uSlot)980 {981 /* Create port tab: */982 UIMachineSettingsSerial *pTab = new UIMachineSettingsSerial(this);983 if (pTab)984 {985 /* Tab connections: */986 connect(pTab, &UIMachineSettingsSerial::sigPortChanged,987 this, &UIMachineSettingsSerialPage::sltHandlePortChange);988 connect(pTab, &UIMachineSettingsSerial::sigPathChanged,989 this, &UIMachineSettingsSerialPage::sltHandlePathChange);990 connect(pTab, &UIMachineSettingsSerial::sigValidityChanged,991 this, &UIMachineSettingsSerialPage::revalidate);992 993 /* Add tab into tab-widget: */994 m_pTabWidget->addTab(pTab, pTab->tabTitle());995 }996 }997 998 /* Add tab-widget into layout: */999 pLayoutMain->addWidget(m_pTabWidget);1000 }1001 }1002 }1003 1004 void UIMachineSettingsSerialPage::cleanup()1005 {1006 /* Cleanup cache: */1007 delete m_pCache;1008 m_pCache = 0;1009 }1010 1011 void UIMachineSettingsSerialPage::refreshPorts()1012 {1013 /* Sanity check: */1014 if (!m_pTabWidget)1015 return;1016 1017 /* Reload port list: */1018 m_ports.clear();1019 m_ports.resize(m_pTabWidget->count());1020 /* Append port list with data from all the tabs: */1021 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)1022 {1023 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));1024 AssertPtrReturnVoid(pTab);1025 m_ports[iSlot] = pTab->isPortEnabled() ? qMakePair(pTab->irq(), pTab->ioAddress()) : qMakePair(QString(), QString());1026 }1027 }1028 1029 void UIMachineSettingsSerialPage::refreshPaths()1030 {1031 /* Sanity check: */1032 if (!m_pTabWidget)1033 return;1034 1035 /* Reload path list: */1036 m_paths.clear();1037 m_paths.resize(m_pTabWidget->count());1038 /* Append path list with data from all the tabs: */1039 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot)1040 {1041 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot));1042 AssertPtrReturnVoid(pTab);1043 m_paths[iSlot] = pTab->isPortEnabled() ? pTab->path() : QString();1044 }1045 }1046 1047 bool UIMachineSettingsSerialPage::saveData()1048 {1049 /* Sanity check: */1050 if ( !m_pCache1051 || !m_pTabWidget)1052 return false;1053 1054 /* Prepare result: */1055 bool fSuccess = true;1056 /* Save serial settings from cache: */1057 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged())1058 {1059 /* For each port: */1060 for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot)1061 fSuccess = savePortData(iSlot);1062 }1063 /* Return result: */1064 return fSuccess;1065 }1066 1067 bool UIMachineSettingsSerialPage::savePortData(int iSlot)1068 {1069 /* Sanity check: */1070 if (!m_pCache)1071 return false;1072 1073 /* Prepare result: */1074 bool fSuccess = true;1075 /* Save adapter settings from cache: */1076 if (fSuccess && m_pCache->child(iSlot).wasChanged())1077 {1078 /* Get old data from cache: */1079 const UIDataSettingsMachineSerialPort &oldPortData = m_pCache->child(iSlot).base();1080 /* Get new data from cache: */1081 const UIDataSettingsMachineSerialPort &newPortData = m_pCache->child(iSlot).data();1082 1083 /* Get serial port for further activities: */1084 CSerialPort comPort = m_machine.GetSerialPort(iSlot);1085 fSuccess = m_machine.isOk() && comPort.isNotNull();1086 1087 /* Show error message if necessary: */1088 if (!fSuccess)1089 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));1090 else1091 {1092 // This *must* be first.1093 // If the requested host mode is changed to disconnected we should do it first.1094 // That allows to automatically fulfill the requirements for some of the settings below.1095 /* Save port host mode: */1096 if ( fSuccess && isMachineOffline()1097 && newPortData.m_hostMode != oldPortData.m_hostMode1098 && newPortData.m_hostMode == KPortMode_Disconnected)1099 {1100 comPort.SetHostMode(newPortData.m_hostMode);1101 fSuccess = comPort.isOk();1102 }1103 /* Save whether the port is enabled: */1104 if (fSuccess && isMachineOffline() && newPortData.m_fPortEnabled != oldPortData.m_fPortEnabled)1105 {1106 comPort.SetEnabled(newPortData.m_fPortEnabled);1107 fSuccess = comPort.isOk();1108 }1109 /* Save port IRQ: */1110 if (fSuccess && isMachineOffline() && newPortData.m_uIRQ != oldPortData.m_uIRQ)1111 {1112 comPort.SetIRQ(newPortData.m_uIRQ);1113 fSuccess = comPort.isOk();1114 }1115 /* Save port IO address: */1116 if (fSuccess && isMachineOffline() && newPortData.m_uIOAddress != oldPortData.m_uIOAddress)1117 {1118 comPort.SetIOAddress(newPortData.m_uIOAddress);1119 fSuccess = comPort.isOk();1120 }1121 /* Save whether the port is server: */1122 if (fSuccess && isMachineOffline() && newPortData.m_fServer != oldPortData.m_fServer)1123 {1124 comPort.SetServer(newPortData.m_fServer);1125 fSuccess = comPort.isOk();1126 }1127 /* Save port path: */1128 if (fSuccess && isMachineOffline() && newPortData.m_strPath != oldPortData.m_strPath)1129 {1130 comPort.SetPath(newPortData.m_strPath);1131 fSuccess = comPort.isOk();1132 }1133 // This *must* be last.1134 // The host mode will be changed to disconnected if some of the necessary1135 // settings above will not meet the requirements for the selected mode.1136 /* Save port host mode: */1137 if ( fSuccess && isMachineOffline()1138 && newPortData.m_hostMode != oldPortData.m_hostMode1139 && newPortData.m_hostMode != KPortMode_Disconnected)1140 {1141 comPort.SetHostMode(newPortData.m_hostMode);1142 fSuccess = comPort.isOk();1143 }1144 1145 /* Show error message if necessary: */1146 if (!fSuccess)1147 notifyOperationProgressError(UIErrorString::formatErrorInfo(comPort));1148 }1149 }1150 /* Return result: */1151 return fSuccess;1152 }1153 1154 # include "UIMachineSettingsSerial.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISerialSettingsEditor.h
r101325 r101327 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MachineSettingsSerial class implementation.3 * VBox Qt GUI - UISerialSettingsEditor class declaration. 4 4 */ 5 5 … … 26 26 */ 27 27 28 /* Qt includes: */ 29 #include <QCheckBox> 30 #include <QComboBox> 31 #include <QDir> 32 #include <QGridLayout> 33 #include <QLabel> 34 #include <QLineEdit> 35 #include <QRegularExpressionValidator> 28 #ifndef FEQT_INCLUDED_SRC_settings_editors_UISerialSettingsEditor_h 29 #define FEQT_INCLUDED_SRC_settings_editors_UISerialSettingsEditor_h 30 #ifndef RT_WITHOUT_PRAGMA_ONCE 31 # pragma once 32 #endif 36 33 37 34 /* GUI includes: */ 38 #include "QITabWidget.h" 39 #include "QIWidgetValidator.h" 40 #include "UICommon.h" 41 #include "UIConverter.h" 42 #include "UIErrorString.h" 43 #include "UIMachineSettingsSerial.h" 44 #include "UITranslator.h" 35 #include "UIEditor.h" 45 36 46 /* COM includes: */ 47 #include "CPlatformProperties.h" 48 #include "CSerialPort.h" 37 /* Forward declarations: */ 38 class QCheckBox; 39 class QComboBox; 40 class QLabel; 41 class QLineEdit; 49 42 50 51 /** Machine settings: Serial Port tab data structure. */ 52 struct UIDataSettingsMachineSerialPort 53 { 54 /** Constructs data. */ 55 UIDataSettingsMachineSerialPort() 56 : m_iSlot(-1) 57 , m_fPortEnabled(false) 58 , m_uIRQ(0) 59 , m_uIOAddress(0) 60 , m_hostMode(KPortMode_Disconnected) 61 , m_fServer(false) 62 , m_strPath(QString()) 63 {} 64 65 /** Returns whether the @a other passed data is equal to this one. */ 66 bool equal(const UIDataSettingsMachineSerialPort &other) const 67 { 68 return true 69 && (m_iSlot == other.m_iSlot) 70 && (m_fPortEnabled == other.m_fPortEnabled) 71 && (m_uIRQ == other.m_uIRQ) 72 && (m_uIOAddress == other.m_uIOAddress) 73 && (m_hostMode == other.m_hostMode) 74 && (m_fServer == other.m_fServer) 75 && (m_strPath == other.m_strPath) 76 ; 77 } 78 79 /** Returns whether the @a other passed data is equal to this one. */ 80 bool operator==(const UIDataSettingsMachineSerialPort &other) const { return equal(other); } 81 /** Returns whether the @a other passed data is different from this one. */ 82 bool operator!=(const UIDataSettingsMachineSerialPort &other) const { return !equal(other); } 83 84 /** Holds the serial port slot number. */ 85 int m_iSlot; 86 /** Holds whether the serial port is enabled. */ 87 bool m_fPortEnabled; 88 /** Holds the serial port IRQ. */ 89 ulong m_uIRQ; 90 /** Holds the serial port IO address. */ 91 ulong m_uIOAddress; 92 /** Holds the serial port host mode. */ 93 KPortMode m_hostMode; 94 /** Holds whether the serial port is server. */ 95 bool m_fServer; 96 /** Holds the serial port path. */ 97 QString m_strPath; 98 }; 99 100 101 /** Machine settings: Serial page data structure. */ 102 struct UIDataSettingsMachineSerial 103 { 104 /** Constructs data. */ 105 UIDataSettingsMachineSerial() {} 106 107 /** Returns whether the @a other passed data is equal to this one. */ 108 bool operator==(const UIDataSettingsMachineSerial & /* other */) const { return true; } 109 /** Returns whether the @a other passed data is different from this one. */ 110 bool operator!=(const UIDataSettingsMachineSerial & /* other */) const { return false; } 111 }; 112 113 114 /** Machine settings: Serial Port tab. */ 115 class UIMachineSettingsSerial : public QIWithRetranslateUI<QWidget> 43 /** UIEditor sub-class used as a serial settings editor. */ 44 class SHARED_LIBRARY_STUFF UISerialSettingsEditor : public UIEditor 116 45 { 117 46 Q_OBJECT; … … 119 48 signals: 120 49 121 /** Notifies about port changed. */ 122 void sigPortChanged(); 123 /** Notifies about path changed. */ 50 /** Notifies listeners about port availability changed. */ 51 void sigPortAvailabilityChanged(); 52 53 /** Notifies listeners about standard port option changed. */ 54 void sigStandardPortOptionChanged(); 55 56 /** Notifies listeners about port IRQ changed. */ 57 void sigPortIRQChanged(); 58 /** Notifies listeners about port IO address changed. */ 59 void sigPortIOAddressChanged(); 60 61 /** Notifies listeners about mode changed. */ 62 void sigModeChanged(); 63 /** Notifies listeners about path changed. */ 124 64 void sigPathChanged(); 125 /** Notifies about validity changed. */126 void sigValidityChanged();127 65 128 66 public: 129 67 130 /** Constructs tabpassing @a pParent to the base-class. */131 UI MachineSettingsSerial(UIMachineSettingsSerialPage *pParent);68 /** Constructs editor passing @a pParent to the base-class. */ 69 UISerialSettingsEditor(QWidget *pParent = 0); 132 70 133 /** Loads port data from @a portCache. */ 134 void getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache); 135 /** Saves port data to @a portCache. */ 136 void putPortDataToCache(UISettingsCacheMachineSerialPort &portCache); 71 /** Defines whether port options @a fAvailable. */ 72 void setPortOptionsAvailable(bool fAvailable); 73 /** Defines whether port @a fEnabled. */ 74 void setPortEnabled(bool fEnabled); 75 /** Returns whether port enabled. */ 76 bool isPortEnabled() const; 137 77 138 /** Performs validation, updates @a messages list if something is wrong. */ 139 bool validate(QList<UIValidationMessage> &messages); 78 /** Defines whether port IRQ and IO address options @a fAvailable. */ 79 void setIRQAndIOAddressOptionsAvailable(bool fAvailable); 80 /** Sets standard port on the basis of passed uIRQ and uIOAddress. */ 81 void setPortByIRQAndIOAddress(ulong uIRQ, ulong uIOAddress); 82 /** Returns whether current port is standard one. */ 83 bool isPortStandardOne() const; 84 /** Defines port @a uIRQ. */ 85 void setIRQ(ulong uIRQ); 86 /** Returns port IRQ. */ 87 ulong irq() const; 88 /** Defines port @a uIOAddress. */ 89 void setIOAddress(ulong uIOAddress); 90 /** Returns port IO address. */ 91 ulong ioAddress() const; 140 92 141 /** Configures tab order according to passed @a pWidget. */ 142 QWidget *setOrderAfter(QWidget *pWidget); 93 /** Defines whether host mode options @a fAvailable. */ 94 void setHostModeOptionsAvailable(bool fAvailable); 95 /** Defines host @a enmMode. */ 96 void setHostMode(KPortMode enmMode); 97 /** Returns host mode. */ 98 KPortMode hostMode() const; 143 99 144 /** Returns tab title. */ 145 QString tabTitle() const; 146 /** Returns whether port is enabled. */ 147 bool isPortEnabled() const; 148 /** Returns IRQ. */ 149 QString irq() const; 150 /** Returns IO address. */ 151 QString ioAddress() const; 100 /** Defines whether pipe options @a fAvailable. */ 101 void setPipeOptionsAvailable(bool fAvailable); 102 /** Defines whether server @a fEnabled. */ 103 void setServerEnabled(bool fEnabled); 104 /** Returns whether server enabled. */ 105 bool isServerEnabled() const; 106 107 /** Defines whether path options @a fAvailable. */ 108 void setPathOptionsAvailable(bool fAvailable); 109 /** Defines @a strPath. */ 110 void setPath(const QString &strPath); 152 111 /** Returns path. */ 153 112 QString path() const; 154 155 /** Performs tab polishing. */156 void polishTab();157 113 158 114 protected: 159 115 160 116 /** Handles translation event. */ 161 v oid retranslateUi();117 virtual void retranslateUi() RT_OVERRIDE; 162 118 163 119 private slots: … … 165 121 /** Handles port availability being toggled to @a fOn. */ 166 122 void sltHandlePortAvailabilityToggled(bool fOn); 167 /** Handles port standard @a strOption being activated. */ 168 void sltHandlePortStandardOptionActivated(const QString &strOption); 169 /** Handles port mode change to item with certain @a iIndex. */ 170 void sltHandlePortModeChange(int iIndex); 123 124 /** Handles standard port @a strOption being activated. */ 125 void sltHandleStandardPortOptionActivated(const QString &strOption); 126 127 /** Handles mode change to item with certain @a iIndex. */ 128 void sltHandleModeChange(int iIndex); 171 129 172 130 private: … … 179 137 void prepareConnections(); 180 138 181 /** Populates combo -boxes. */182 void populateCombo boxes();139 /** Populates combo. */ 140 void populateCombo(); 183 141 184 /** Holds the parent page reference. */ 185 UIMachineSettingsSerialPage *m_pParent; 186 187 /** Holds the port slot number. */ 188 int m_iSlot; 189 /** Holds the port mode. */ 142 /** Holds the mode. */ 190 143 KPortMode m_enmPortMode; 191 144 … … 221 174 }; 222 175 223 224 /********************************************************************************************************************************* 225 * Class UIMachineSettingsSerial implementation. * 226 *********************************************************************************************************************************/ 227 228 UIMachineSettingsSerial::UIMachineSettingsSerial(UIMachineSettingsSerialPage *pParent) 229 : QIWithRetranslateUI<QWidget>(0) 230 , m_pParent(pParent) 231 , m_iSlot(-1) 232 , m_enmPortMode(KPortMode_Max) 233 , m_pCheckBoxPort(0) 234 , m_pWidgetPortSettings(0) 235 , m_pLabelNumber(0) 236 , m_pComboNumber(0) 237 , m_pLabelIRQ(0) 238 , m_pLineEditIRQ(0) 239 , m_pLabelIOAddress(0) 240 , m_pLineEditIOAddress(0) 241 , m_pLabelMode(0) 242 , m_pComboMode(0) 243 , m_pCheckBoxPipe(0) 244 , m_pLabelPath(0) 245 , m_pEditorPath(0) 246 { 247 prepare(); 248 } 249 250 void UIMachineSettingsSerial::getPortDataFromCache(const UISettingsCacheMachineSerialPort &portCache) 251 { 252 /* Get old data: */ 253 const UIDataSettingsMachineSerialPort &oldPortData = portCache.base(); 254 255 /* Load port number: */ 256 m_iSlot = oldPortData.m_iSlot; 257 258 /* Load port data: */ 259 if (m_pCheckBoxPort) 260 m_pCheckBoxPort->setChecked(oldPortData.m_fPortEnabled); 261 if (m_pComboNumber) 262 m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(oldPortData.m_uIRQ, oldPortData.m_uIOAddress))); 263 if (m_pLineEditIRQ) 264 m_pLineEditIRQ->setText(QString::number(oldPortData.m_uIRQ)); 265 if (m_pLineEditIOAddress) 266 m_pLineEditIOAddress->setText("0x" + QString::number(oldPortData.m_uIOAddress, 16).toUpper()); 267 m_enmPortMode = oldPortData.m_hostMode; 268 if (m_pCheckBoxPipe) 269 m_pCheckBoxPipe->setChecked(!oldPortData.m_fServer); 270 if (m_pEditorPath) 271 m_pEditorPath->setText(oldPortData.m_strPath); 272 273 /* Repopulate combo-boxes content: */ 274 populateComboboxes(); 275 /* Ensure everything is up-to-date */ 276 if (m_pCheckBoxPort) 277 sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked()); 278 } 279 280 void UIMachineSettingsSerial::putPortDataToCache(UISettingsCacheMachineSerialPort &portCache) 281 { 282 /* Prepare new data: */ 283 UIDataSettingsMachineSerialPort newPortData; 284 285 /* Save port number: */ 286 newPortData.m_iSlot = m_iSlot; 287 288 /* Save port data: */ 289 if (m_pCheckBoxPort) 290 newPortData.m_fPortEnabled = m_pCheckBoxPort->isChecked(); 291 if (m_pLineEditIRQ) 292 newPortData.m_uIRQ = m_pLineEditIRQ->text().toULong(NULL, 0); 293 if (m_pLineEditIOAddress) 294 newPortData.m_uIOAddress = m_pLineEditIOAddress->text().toULong(NULL, 0); 295 if (m_pCheckBoxPipe) 296 newPortData.m_fServer = !m_pCheckBoxPipe->isChecked(); 297 if (m_pComboMode) 298 newPortData.m_hostMode = m_pComboMode->currentData().value<KPortMode>(); 299 if (m_pEditorPath) 300 newPortData.m_strPath = QDir::toNativeSeparators(m_pEditorPath->text()); 301 302 /* Cache new data: */ 303 portCache.cacheCurrentData(newPortData); 304 } 305 306 bool UIMachineSettingsSerial::validate(QList<UIValidationMessage> &messages) 307 { 308 /* Pass by default: */ 309 bool fPass = true; 310 311 /* Prepare message: */ 312 UIValidationMessage message; 313 message.first = UITranslator::removeAccelMark(tabTitle()); 314 315 if ( m_pCheckBoxPort 316 && m_pCheckBoxPort->isChecked()) 317 { 318 /* Check the port attribute emptiness & uniqueness: */ 319 const QString strIRQ = m_pLineEditIRQ ? m_pLineEditIRQ->text() : QString(); 320 const QString strIOAddress = m_pLineEditIOAddress ? m_pLineEditIOAddress->text() : QString(); 321 const QPair<QString, QString> port = qMakePair(strIRQ, strIOAddress); 322 323 if (strIRQ.isEmpty()) 324 { 325 message.second << UIMachineSettingsSerial::tr("No IRQ is currently specified."); 326 fPass = false; 327 } 328 if (strIOAddress.isEmpty()) 329 { 330 message.second << UIMachineSettingsSerial::tr("No I/O port is currently specified."); 331 fPass = false; 332 } 333 if ( !strIRQ.isEmpty() 334 && !strIOAddress.isEmpty()) 335 { 336 QVector<QPair<QString, QString> > ports; 337 if (m_pParent) 338 { 339 ports = m_pParent->ports(); 340 ports.removeAt(m_iSlot); 341 } 342 if (ports.contains(port)) 343 { 344 message.second << UIMachineSettingsSerial::tr("Two or more ports have the same settings."); 345 fPass = false; 346 } 347 } 348 349 const KPortMode enmMode = m_pComboMode->currentData().value<KPortMode>(); 350 if (enmMode != KPortMode_Disconnected) 351 { 352 const QString strPath(m_pEditorPath->text()); 353 354 if (strPath.isEmpty()) 355 { 356 message.second << UIMachineSettingsSerial::tr("No port path is currently specified."); 357 fPass = false; 358 } 359 else 360 { 361 QVector<QString> paths; 362 if (m_pParent) 363 { 364 paths = m_pParent->paths(); 365 paths.removeAt(m_iSlot); 366 } 367 if (paths.contains(strPath)) 368 { 369 message.second << UIMachineSettingsSerial::tr("There are currently duplicate port paths specified."); 370 fPass = false; 371 } 372 } 373 } 374 } 375 376 /* Serialize message: */ 377 if (!message.second.isEmpty()) 378 messages << message; 379 380 /* Return result: */ 381 return fPass; 382 } 383 384 QWidget *UIMachineSettingsSerial::setOrderAfter(QWidget *pWidget) 385 { 386 setTabOrder(pWidget, m_pCheckBoxPort); 387 setTabOrder(m_pCheckBoxPort, m_pComboNumber); 388 setTabOrder(m_pComboNumber, m_pLineEditIRQ); 389 setTabOrder(m_pLineEditIRQ, m_pLineEditIOAddress); 390 setTabOrder(m_pLineEditIOAddress, m_pComboMode); 391 setTabOrder(m_pComboMode, m_pCheckBoxPipe); 392 setTabOrder(m_pCheckBoxPipe, m_pEditorPath); 393 return m_pEditorPath; 394 } 395 396 QString UIMachineSettingsSerial::tabTitle() const 397 { 398 return QString(tr("Port %1", "serial ports")).arg(QString("&%1").arg(m_iSlot + 1)); 399 } 400 401 bool UIMachineSettingsSerial::isPortEnabled() const 402 { 403 return m_pCheckBoxPort->isChecked(); 404 } 405 406 QString UIMachineSettingsSerial::irq() const 407 { 408 return m_pLineEditIRQ->text(); 409 } 410 411 QString UIMachineSettingsSerial::ioAddress() const 412 { 413 return m_pLineEditIOAddress->text(); 414 } 415 416 QString UIMachineSettingsSerial::path() const 417 { 418 return m_pEditorPath->text(); 419 } 420 421 void UIMachineSettingsSerial::polishTab() 422 { 423 /* Sanity check: */ 424 if (!m_pParent) 425 return; 426 427 /* Polish port page: */ 428 ulong uIRQ, uIOAddress; 429 const bool fStd = m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false; 430 const KPortMode enmMode = m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : KPortMode_Max; 431 if (m_pCheckBoxPort) 432 m_pCheckBoxPort->setEnabled(m_pParent->isMachineOffline()); 433 if (m_pLabelNumber) 434 m_pLabelNumber->setEnabled(m_pParent->isMachineOffline()); 435 if (m_pComboNumber) 436 m_pComboNumber->setEnabled(m_pParent->isMachineOffline()); 437 if (m_pLabelIRQ) 438 m_pLabelIRQ->setEnabled(m_pParent->isMachineOffline()); 439 if (m_pLineEditIRQ) 440 m_pLineEditIRQ->setEnabled(!fStd && m_pParent->isMachineOffline()); 441 if (m_pLabelIOAddress) 442 m_pLabelIOAddress->setEnabled(m_pParent->isMachineOffline()); 443 if (m_pLineEditIOAddress) 444 m_pLineEditIOAddress->setEnabled(!fStd && m_pParent->isMachineOffline()); 445 if (m_pLabelMode) 446 m_pLabelMode->setEnabled(m_pParent->isMachineOffline()); 447 if (m_pComboMode) 448 m_pComboMode->setEnabled(m_pParent->isMachineOffline()); 449 if (m_pCheckBoxPipe) 450 m_pCheckBoxPipe->setEnabled( (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP) 451 && m_pParent->isMachineOffline()); 452 if (m_pLabelPath) 453 m_pLabelPath->setEnabled( enmMode != KPortMode_Disconnected 454 && m_pParent->isMachineOffline()); 455 if (m_pEditorPath) 456 m_pEditorPath->setEnabled( enmMode != KPortMode_Disconnected 457 && m_pParent->isMachineOffline()); 458 } 459 460 void UIMachineSettingsSerial::retranslateUi() 461 { 462 if (m_pCheckBoxPort) 463 { 464 m_pCheckBoxPort->setText(tr("&Enable Serial Port")); 465 m_pCheckBoxPort->setToolTip(tr("When checked, enables the given serial port of the virtual machine.")); 466 } 467 if (m_pLabelNumber) 468 m_pLabelNumber->setText(tr("Port &Number:")); 469 if (m_pComboNumber) 470 { 471 m_pComboNumber->setItemText(m_pComboNumber->count() - 1, UITranslator::toCOMPortName(0, 0)); 472 m_pComboNumber->setToolTip(tr("Selects the serial port number. You can choose one of the standard serial ports or select " 473 "User-defined and specify port parameters manually.")); 474 } 475 if (m_pLabelIRQ) 476 m_pLabelIRQ->setText(tr("&IRQ:")); 477 if (m_pLineEditIRQ) 478 m_pLineEditIRQ->setToolTip(tr("Holds the IRQ number of this serial port. This should be a whole number between " 479 "<tt>0</tt> and <tt>255</tt>. Values greater than <tt>15</tt> may only be used if the " 480 "I/O APIC setting is enabled for this virtual machine.")); 481 if (m_pLabelIOAddress) 482 m_pLabelIOAddress->setText(tr("I/O Po&rt:")); 483 if (m_pLineEditIOAddress) 484 m_pLineEditIOAddress->setToolTip(tr("Holds the base I/O port address of this serial port. Valid values are integer numbers " 485 "in range from <tt>0</tt> to <tt>0xFFFF</tt>.")); 486 if (m_pLabelMode) 487 m_pLabelMode->setText(tr("Port &Mode:")); 488 if (m_pComboMode) 489 m_pComboMode->setToolTip(tr("Selects the working mode of this serial port. If you select Disconnected, the guest " 490 "OS will detect the serial port but will not be able to operate it.")); 491 if (m_pCheckBoxPipe) 492 { 493 m_pCheckBoxPipe->setText(tr("&Connect to existing pipe/socket")); 494 m_pCheckBoxPipe->setToolTip(tr("When checked, the virtual machine will assume that the pipe or socket specified in the " 495 "Path/Address field exists and try to use it. Otherwise, the pipe or socket will " 496 "be created by the virtual machine when it starts.")); 497 } 498 if (m_pLabelPath) 499 m_pLabelPath->setText(tr("&Path/Address:")); 500 if (m_pEditorPath) 501 m_pEditorPath->setToolTip(tr("In Host Pipe mode: Holds the path to the serial port's pipe on the host. " 502 "Examples: \"\\\\.\\pipe\\myvbox\" or \"/tmp/myvbox\", for Windows and UNIX-like systems " 503 "respectively. In Host Device mode: Holds the host serial device name. " 504 "Examples: \"COM1\" or \"/dev/ttyS0\". In Raw File mode: Holds the file-path " 505 "on the host system, where the serial output will be dumped. In TCP mode: " 506 "Holds the TCP \"port\" when in server mode, or \"hostname:port\" when in client mode.")); 507 508 /* Translate combo-boxes content: */ 509 populateComboboxes(); 510 } 511 512 void UIMachineSettingsSerial::sltHandlePortAvailabilityToggled(bool fOn) 513 { 514 /* Update availability: */ 515 m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked()); 516 if (fOn) 517 { 518 sltHandlePortStandardOptionActivated(m_pComboNumber->currentText()); 519 sltHandlePortModeChange(m_pComboMode->currentIndex()); 520 } 521 522 /* Notify port/path changed: */ 523 emit sigPortChanged(); 524 emit sigPathChanged(); 525 } 526 527 void UIMachineSettingsSerial::sltHandlePortStandardOptionActivated(const QString &strText) 528 { 529 /* Update availability: */ 530 ulong uIRQ, uIOAddress; 531 bool fStd = UITranslator::toCOMPortNumbers(strText, uIRQ, uIOAddress); 532 m_pLineEditIRQ->setEnabled(!fStd); 533 m_pLineEditIOAddress->setEnabled(!fStd); 534 if (fStd) 535 { 536 m_pLineEditIRQ->setText(QString::number(uIRQ)); 537 m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper()); 538 } 539 540 /* Notify validity changed: */ 541 emit sigValidityChanged(); 542 } 543 544 void UIMachineSettingsSerial::sltHandlePortModeChange(int iIndex) 545 { 546 /* Update availability: */ 547 const KPortMode enmMode = m_pComboMode->itemData(iIndex).value<KPortMode>(); 548 m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP); 549 m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected); 550 m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected); 551 552 /* Notify validity changed: */ 553 emit sigValidityChanged(); 554 } 555 556 void UIMachineSettingsSerial::prepare() 557 { 558 /* Prepare everything: */ 559 prepareWidgets(); 560 prepareConnections(); 561 562 /* Apply language settings: */ 563 retranslateUi(); 564 } 565 566 void UIMachineSettingsSerial::prepareWidgets() 567 { 568 /* Prepare main layout: */ 569 QGridLayout *pLayoutMain = new QGridLayout(this); 570 if (pLayoutMain) 571 { 572 pLayoutMain->setRowStretch(2, 1); 573 574 /* Prepare port check-box: */ 575 m_pCheckBoxPort = new QCheckBox(this); 576 if (m_pCheckBoxPort) 577 pLayoutMain->addWidget(m_pCheckBoxPort, 0, 0, 1, 2); 578 579 /* Prepare 20-px shifting spacer: */ 580 QSpacerItem *pSpacerItem = new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum); 581 if (pSpacerItem) 582 pLayoutMain->addItem(pSpacerItem, 1, 0); 583 584 /* Prepare adapter settings widget: */ 585 m_pWidgetPortSettings = new QWidget(this); 586 if (m_pWidgetPortSettings) 587 { 588 /* Prepare adapter settings widget layout: */ 589 QGridLayout *pLayoutPortSettings = new QGridLayout(m_pWidgetPortSettings); 590 if (pLayoutPortSettings) 591 { 592 pLayoutPortSettings->setContentsMargins(0, 0, 0, 0); 593 pLayoutPortSettings->setColumnStretch(6, 1); 594 595 /* Prepare number label: */ 596 m_pLabelNumber = new QLabel(m_pWidgetPortSettings); 597 if (m_pLabelNumber) 598 { 599 m_pLabelNumber->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 600 pLayoutPortSettings->addWidget(m_pLabelNumber, 0, 0); 601 } 602 /* Prepare number combo: */ 603 m_pComboNumber = new QComboBox(m_pWidgetPortSettings); 604 if (m_pComboNumber) 605 { 606 if (m_pLabelNumber) 607 m_pLabelNumber->setBuddy(m_pComboNumber); 608 m_pComboNumber->insertItem(0, UITranslator::toCOMPortName(0, 0)); 609 m_pComboNumber->insertItems(0, UITranslator::COMPortNames()); 610 pLayoutPortSettings->addWidget(m_pComboNumber, 0, 1); 611 } 612 /* Prepare IRQ label: */ 613 m_pLabelIRQ = new QLabel(m_pWidgetPortSettings); 614 if (m_pLabelIRQ) 615 pLayoutPortSettings->addWidget(m_pLabelIRQ, 0, 2); 616 /* Prepare IRQ label: */ 617 m_pLineEditIRQ = new QLineEdit(m_pWidgetPortSettings); 618 if (m_pLineEditIRQ) 619 { 620 if (m_pLabelIRQ) 621 m_pLabelIRQ->setBuddy(m_pLineEditIRQ); 622 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) 623 m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().horizontalAdvance("8888")); 624 #else 625 m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().width("8888")); 626 #endif 627 m_pLineEditIRQ->setValidator(new QIULongValidator(0, 255, this)); 628 pLayoutPortSettings->addWidget(m_pLineEditIRQ, 0, 3); 629 } 630 /* Prepare IO address label: */ 631 m_pLabelIOAddress = new QLabel(m_pWidgetPortSettings); 632 if (m_pLabelIOAddress) 633 pLayoutPortSettings->addWidget(m_pLabelIOAddress, 0, 4); 634 /* Prepare IO address label: */ 635 m_pLineEditIOAddress = new QLineEdit(m_pWidgetPortSettings); 636 if (m_pLineEditIOAddress) 637 { 638 if (m_pLabelIOAddress) 639 m_pLabelIOAddress->setBuddy(m_pLineEditIOAddress); 640 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) 641 m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().horizontalAdvance("8888888")); 642 #else 643 m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().width("8888888")); 644 #endif 645 m_pLineEditIOAddress->setValidator(new QIULongValidator(0, 0xFFFF, this)); 646 pLayoutPortSettings->addWidget(m_pLineEditIOAddress, 0, 5); 647 } 648 649 /* Prepare mode label: */ 650 m_pLabelMode = new QLabel(m_pWidgetPortSettings); 651 if (m_pLabelMode) 652 { 653 m_pLabelMode->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 654 pLayoutPortSettings->addWidget(m_pLabelMode, 1, 0); 655 } 656 /* Prepare mode combo: */ 657 m_pComboMode = new QComboBox(m_pWidgetPortSettings); 658 if (m_pComboMode) 659 { 660 if (m_pLabelMode) 661 m_pLabelMode->setBuddy(m_pComboMode); 662 pLayoutPortSettings->addWidget(m_pComboMode, 1, 1); 663 } 664 665 /* Prepare pipe check-box: */ 666 m_pCheckBoxPipe = new QCheckBox(m_pWidgetPortSettings); 667 if (m_pCheckBoxPipe) 668 pLayoutPortSettings->addWidget(m_pCheckBoxPipe, 2, 1, 1, 5); 669 670 /* Prepare path label: */ 671 m_pLabelPath = new QLabel(m_pWidgetPortSettings); 672 if (m_pLabelPath) 673 { 674 m_pLabelPath->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 675 pLayoutPortSettings->addWidget(m_pLabelPath, 3, 0); 676 } 677 /* Prepare path editor: */ 678 m_pEditorPath = new QLineEdit(m_pWidgetPortSettings); 679 if (m_pEditorPath) 680 { 681 if (m_pLabelPath) 682 m_pLabelPath->setBuddy(m_pEditorPath); 683 m_pEditorPath->setValidator(new QRegularExpressionValidator(QRegularExpression(".+"), this)); 684 pLayoutPortSettings->addWidget(m_pEditorPath, 3, 1, 1, 6); 685 } 686 } 687 688 pLayoutMain->addWidget(m_pWidgetPortSettings, 1, 1); 689 } 690 } 691 } 692 693 void UIMachineSettingsSerial::prepareConnections() 694 { 695 if (m_pCheckBoxPort) 696 connect(m_pCheckBoxPort, &QCheckBox::toggled, this, &UIMachineSettingsSerial::sltHandlePortAvailabilityToggled); 697 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 698 if (m_pComboNumber) 699 connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::textActivated), 700 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated); 701 #else 702 if (m_pComboNumber) 703 connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::activated), 704 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated); 705 #endif 706 if (m_pLineEditIRQ) 707 connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged); 708 if (m_pLineEditIOAddress) 709 connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged); 710 if (m_pComboMode) 711 connect(m_pComboMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), 712 this, &UIMachineSettingsSerial::sltHandlePortModeChange); 713 if (m_pEditorPath) 714 connect(m_pEditorPath, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPathChanged); 715 } 716 717 void UIMachineSettingsSerial::populateComboboxes() 718 { 719 /* Port mode: */ 720 { 721 /* Clear the port mode combo-box: */ 722 m_pComboMode->clear(); 723 724 /* Load currently supported port moded: */ 725 CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties(); 726 QVector<KPortMode> supportedModes = comProperties.GetSupportedPortModes(); 727 /* Take currently requested mode into account if it's sane: */ 728 if (!supportedModes.contains(m_enmPortMode) && m_enmPortMode != KPortMode_Max) 729 supportedModes.prepend(m_enmPortMode); 730 731 /* Populate port modes: */ 732 int iPortModeIndex = 0; 733 foreach (const KPortMode &enmMode, supportedModes) 734 { 735 m_pComboMode->insertItem(iPortModeIndex, gpConverter->toString(enmMode)); 736 m_pComboMode->setItemData(iPortModeIndex, QVariant::fromValue(enmMode)); 737 m_pComboMode->setItemData(iPortModeIndex, m_pComboMode->itemText(iPortModeIndex), Qt::ToolTipRole); 738 ++iPortModeIndex; 739 } 740 741 /* Choose requested port mode: */ 742 const int iIndex = m_pComboMode->findData(QVariant::fromValue(m_enmPortMode)); 743 m_pComboMode->setCurrentIndex(iIndex != -1 ? iIndex : 0); 744 } 745 } 746 747 748 /********************************************************************************************************************************* 749 * Class UIMachineSettingsSerialPage implementation. * 750 *********************************************************************************************************************************/ 751 752 UIMachineSettingsSerialPage::UIMachineSettingsSerialPage() 753 : m_pCache(0) 754 , m_pTabWidget(0) 755 { 756 prepare(); 757 } 758 759 UIMachineSettingsSerialPage::~UIMachineSettingsSerialPage() 760 { 761 cleanup(); 762 } 763 764 bool UIMachineSettingsSerialPage::changed() const 765 { 766 return m_pCache ? m_pCache->wasChanged() : false; 767 } 768 769 void UIMachineSettingsSerialPage::loadToCacheFrom(QVariant &data) 770 { 771 /* Sanity check: */ 772 if ( !m_pCache 773 || !m_pTabWidget) 774 return; 775 776 /* Fetch data to machine: */ 777 UISettingsPageMachine::fetchData(data); 778 779 /* Clear cache initially: */ 780 m_pCache->clear(); 781 782 /* Cache lists: */ 783 refreshPorts(); 784 refreshPaths(); 785 786 /* Prepare old data: */ 787 UIDataSettingsMachineSerial oldSerialData; 788 789 /* For each serial port: */ 790 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 791 { 792 /* Prepare old data: */ 793 UIDataSettingsMachineSerialPort oldPortData; 794 795 /* Check whether port is valid: */ 796 const CSerialPort &comPort = m_machine.GetSerialPort(iSlot); 797 if (!comPort.isNull()) 798 { 799 /* Gather old data: */ 800 oldPortData.m_iSlot = iSlot; 801 oldPortData.m_fPortEnabled = comPort.GetEnabled(); 802 oldPortData.m_uIRQ = comPort.GetIRQ(); 803 oldPortData.m_uIOAddress = comPort.GetIOAddress(); 804 oldPortData.m_hostMode = comPort.GetHostMode(); 805 oldPortData.m_fServer = comPort.GetServer(); 806 oldPortData.m_strPath = comPort.GetPath(); 807 } 808 809 /* Cache old data: */ 810 m_pCache->child(iSlot).cacheInitialData(oldPortData); 811 } 812 813 /* Cache old data: */ 814 m_pCache->cacheInitialData(oldSerialData); 815 816 /* Upload machine to data: */ 817 UISettingsPageMachine::uploadData(data); 818 } 819 820 void UIMachineSettingsSerialPage::getFromCache() 821 { 822 /* Sanity check: */ 823 if ( !m_pCache 824 || !m_pTabWidget) 825 return; 826 827 /* Setup tab order: */ 828 AssertPtrReturnVoid(firstWidget()); 829 setTabOrder(firstWidget(), m_pTabWidget->focusProxy()); 830 QWidget *pLastFocusWidget = m_pTabWidget->focusProxy(); 831 832 /* For each port: */ 833 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 834 { 835 /* Get port page: */ 836 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot)); 837 AssertPtrReturnVoid(pTab); 838 839 /* Load old data from cache: */ 840 pTab->getPortDataFromCache(m_pCache->child(iSlot)); 841 842 /* Setup tab order: */ 843 pLastFocusWidget = pTab->setOrderAfter(pLastFocusWidget); 844 } 845 846 /* Apply language settings: */ 847 retranslateUi(); 848 849 /* Polish page finally: */ 850 polishPage(); 851 852 /* Revalidate: */ 853 revalidate(); 854 } 855 856 void UIMachineSettingsSerialPage::putToCache() 857 { 858 /* Sanity check: */ 859 if ( !m_pCache 860 || !m_pTabWidget) 861 return; 862 863 /* Prepare new data: */ 864 UIDataSettingsMachineSerial newSerialData; 865 866 /* For each port: */ 867 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 868 { 869 /* Getting port page: */ 870 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot)); 871 AssertPtrReturnVoid(pTab); 872 873 /* Gather new data: */ 874 pTab->putPortDataToCache(m_pCache->child(iSlot)); 875 } 876 877 /* Cache new data: */ 878 m_pCache->cacheCurrentData(newSerialData); 879 } 880 881 void UIMachineSettingsSerialPage::saveFromCacheTo(QVariant &data) 882 { 883 /* Fetch data to machine: */ 884 UISettingsPageMachine::fetchData(data); 885 886 /* Update data and failing state: */ 887 setFailed(!saveData()); 888 889 /* Upload machine to data: */ 890 UISettingsPageMachine::uploadData(data); 891 } 892 893 bool UIMachineSettingsSerialPage::validate(QList<UIValidationMessage> &messages) 894 { 895 /* Sanity check: */ 896 if (!m_pTabWidget) 897 return false; 898 899 /* Pass by default: */ 900 bool fValid = true; 901 902 /* Delegate validation to adapter tabs: */ 903 for (int iIndex = 0; iIndex < m_pTabWidget->count(); ++iIndex) 904 { 905 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iIndex)); 906 AssertPtrReturn(pTab, false); 907 if (!pTab->validate(messages)) 908 fValid = false; 909 } 910 911 /* Return result: */ 912 return fValid; 913 } 914 915 void UIMachineSettingsSerialPage::retranslateUi() 916 { 917 /* Sanity check: */ 918 if (!m_pTabWidget) 919 return; 920 921 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 922 { 923 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot)); 924 AssertPtrReturnVoid(pTab); 925 m_pTabWidget->setTabText(iSlot, pTab->tabTitle()); 926 } 927 } 928 929 void UIMachineSettingsSerialPage::polishPage() 930 { 931 /* Sanity check: */ 932 if ( !m_pCache 933 || !m_pTabWidget) 934 return; 935 936 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 937 { 938 m_pTabWidget->setTabEnabled(iSlot, 939 isMachineOffline() || 940 (isMachineInValidMode() && 941 m_pCache->childCount() > iSlot && 942 m_pCache->child(iSlot).base().m_fPortEnabled)); 943 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot)); 944 AssertPtrReturnVoid(pTab); 945 pTab->polishTab(); 946 } 947 } 948 949 void UIMachineSettingsSerialPage::sltHandlePortChange() 950 { 951 refreshPorts(); 952 revalidate(); 953 } 954 955 void UIMachineSettingsSerialPage::sltHandlePathChange() 956 { 957 refreshPaths(); 958 revalidate(); 959 } 960 961 void UIMachineSettingsSerialPage::prepare() 962 { 963 /* Prepare cache: */ 964 m_pCache = new UISettingsCacheMachineSerial; 965 AssertPtrReturnVoid(m_pCache); 966 967 /* Create main layout: */ 968 QVBoxLayout *pLayoutMain = new QVBoxLayout(this); 969 if (pLayoutMain) 970 { 971 /* Creating tab-widget: */ 972 m_pTabWidget = new QITabWidget; 973 if (m_pTabWidget) 974 { 975 /* How many ports to display: */ 976 const ulong uCount = uiCommon().virtualBox().GetPlatformProperties(KPlatformArchitecture_x86).GetSerialPortCount(); 977 978 /* Create corresponding port tabs: */ 979 for (ulong uSlot = 0; uSlot < uCount; ++uSlot) 980 { 981 /* Create port tab: */ 982 UIMachineSettingsSerial *pTab = new UIMachineSettingsSerial(this); 983 if (pTab) 984 { 985 /* Tab connections: */ 986 connect(pTab, &UIMachineSettingsSerial::sigPortChanged, 987 this, &UIMachineSettingsSerialPage::sltHandlePortChange); 988 connect(pTab, &UIMachineSettingsSerial::sigPathChanged, 989 this, &UIMachineSettingsSerialPage::sltHandlePathChange); 990 connect(pTab, &UIMachineSettingsSerial::sigValidityChanged, 991 this, &UIMachineSettingsSerialPage::revalidate); 992 993 /* Add tab into tab-widget: */ 994 m_pTabWidget->addTab(pTab, pTab->tabTitle()); 995 } 996 } 997 998 /* Add tab-widget into layout: */ 999 pLayoutMain->addWidget(m_pTabWidget); 1000 } 1001 } 1002 } 1003 1004 void UIMachineSettingsSerialPage::cleanup() 1005 { 1006 /* Cleanup cache: */ 1007 delete m_pCache; 1008 m_pCache = 0; 1009 } 1010 1011 void UIMachineSettingsSerialPage::refreshPorts() 1012 { 1013 /* Sanity check: */ 1014 if (!m_pTabWidget) 1015 return; 1016 1017 /* Reload port list: */ 1018 m_ports.clear(); 1019 m_ports.resize(m_pTabWidget->count()); 1020 /* Append port list with data from all the tabs: */ 1021 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 1022 { 1023 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot)); 1024 AssertPtrReturnVoid(pTab); 1025 m_ports[iSlot] = pTab->isPortEnabled() ? qMakePair(pTab->irq(), pTab->ioAddress()) : qMakePair(QString(), QString()); 1026 } 1027 } 1028 1029 void UIMachineSettingsSerialPage::refreshPaths() 1030 { 1031 /* Sanity check: */ 1032 if (!m_pTabWidget) 1033 return; 1034 1035 /* Reload path list: */ 1036 m_paths.clear(); 1037 m_paths.resize(m_pTabWidget->count()); 1038 /* Append path list with data from all the tabs: */ 1039 for (int iSlot = 0; iSlot < m_pTabWidget->count(); ++iSlot) 1040 { 1041 UIMachineSettingsSerial *pTab = qobject_cast<UIMachineSettingsSerial*>(m_pTabWidget->widget(iSlot)); 1042 AssertPtrReturnVoid(pTab); 1043 m_paths[iSlot] = pTab->isPortEnabled() ? pTab->path() : QString(); 1044 } 1045 } 1046 1047 bool UIMachineSettingsSerialPage::saveData() 1048 { 1049 /* Sanity check: */ 1050 if ( !m_pCache 1051 || !m_pTabWidget) 1052 return false; 1053 1054 /* Prepare result: */ 1055 bool fSuccess = true; 1056 /* Save serial settings from cache: */ 1057 if (fSuccess && isMachineInValidMode() && m_pCache->wasChanged()) 1058 { 1059 /* For each port: */ 1060 for (int iSlot = 0; fSuccess && iSlot < m_pTabWidget->count(); ++iSlot) 1061 fSuccess = savePortData(iSlot); 1062 } 1063 /* Return result: */ 1064 return fSuccess; 1065 } 1066 1067 bool UIMachineSettingsSerialPage::savePortData(int iSlot) 1068 { 1069 /* Sanity check: */ 1070 if (!m_pCache) 1071 return false; 1072 1073 /* Prepare result: */ 1074 bool fSuccess = true; 1075 /* Save adapter settings from cache: */ 1076 if (fSuccess && m_pCache->child(iSlot).wasChanged()) 1077 { 1078 /* Get old data from cache: */ 1079 const UIDataSettingsMachineSerialPort &oldPortData = m_pCache->child(iSlot).base(); 1080 /* Get new data from cache: */ 1081 const UIDataSettingsMachineSerialPort &newPortData = m_pCache->child(iSlot).data(); 1082 1083 /* Get serial port for further activities: */ 1084 CSerialPort comPort = m_machine.GetSerialPort(iSlot); 1085 fSuccess = m_machine.isOk() && comPort.isNotNull(); 1086 1087 /* Show error message if necessary: */ 1088 if (!fSuccess) 1089 notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine)); 1090 else 1091 { 1092 // This *must* be first. 1093 // If the requested host mode is changed to disconnected we should do it first. 1094 // That allows to automatically fulfill the requirements for some of the settings below. 1095 /* Save port host mode: */ 1096 if ( fSuccess && isMachineOffline() 1097 && newPortData.m_hostMode != oldPortData.m_hostMode 1098 && newPortData.m_hostMode == KPortMode_Disconnected) 1099 { 1100 comPort.SetHostMode(newPortData.m_hostMode); 1101 fSuccess = comPort.isOk(); 1102 } 1103 /* Save whether the port is enabled: */ 1104 if (fSuccess && isMachineOffline() && newPortData.m_fPortEnabled != oldPortData.m_fPortEnabled) 1105 { 1106 comPort.SetEnabled(newPortData.m_fPortEnabled); 1107 fSuccess = comPort.isOk(); 1108 } 1109 /* Save port IRQ: */ 1110 if (fSuccess && isMachineOffline() && newPortData.m_uIRQ != oldPortData.m_uIRQ) 1111 { 1112 comPort.SetIRQ(newPortData.m_uIRQ); 1113 fSuccess = comPort.isOk(); 1114 } 1115 /* Save port IO address: */ 1116 if (fSuccess && isMachineOffline() && newPortData.m_uIOAddress != oldPortData.m_uIOAddress) 1117 { 1118 comPort.SetIOAddress(newPortData.m_uIOAddress); 1119 fSuccess = comPort.isOk(); 1120 } 1121 /* Save whether the port is server: */ 1122 if (fSuccess && isMachineOffline() && newPortData.m_fServer != oldPortData.m_fServer) 1123 { 1124 comPort.SetServer(newPortData.m_fServer); 1125 fSuccess = comPort.isOk(); 1126 } 1127 /* Save port path: */ 1128 if (fSuccess && isMachineOffline() && newPortData.m_strPath != oldPortData.m_strPath) 1129 { 1130 comPort.SetPath(newPortData.m_strPath); 1131 fSuccess = comPort.isOk(); 1132 } 1133 // This *must* be last. 1134 // The host mode will be changed to disconnected if some of the necessary 1135 // settings above will not meet the requirements for the selected mode. 1136 /* Save port host mode: */ 1137 if ( fSuccess && isMachineOffline() 1138 && newPortData.m_hostMode != oldPortData.m_hostMode 1139 && newPortData.m_hostMode != KPortMode_Disconnected) 1140 { 1141 comPort.SetHostMode(newPortData.m_hostMode); 1142 fSuccess = comPort.isOk(); 1143 } 1144 1145 /* Show error message if necessary: */ 1146 if (!fSuccess) 1147 notifyOperationProgressError(UIErrorString::formatErrorInfo(comPort)); 1148 } 1149 } 1150 /* Return result: */ 1151 return fSuccess; 1152 } 1153 1154 # include "UIMachineSettingsSerial.moc" 176 #endif /* !FEQT_INCLUDED_SRC_settings_editors_UISerialSettingsEditor_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSerial.cpp
r101325 r101327 27 27 28 28 /* Qt includes: */ 29 #include <QCheckBox> 30 #include <QComboBox> 31 #include <QDir> 32 #include <QGridLayout> 33 #include <QLabel> 34 #include <QLineEdit> 35 #include <QRegularExpressionValidator> 29 #include <QVBoxLayout> 36 30 37 31 /* GUI includes: */ 38 32 #include "QITabWidget.h" 39 #include "QIWidgetValidator.h"40 33 #include "UICommon.h" 41 #include "UIConverter.h"42 34 #include "UIErrorString.h" 43 35 #include "UIMachineSettingsSerial.h" 36 #include "UISerialSettingsEditor.h" 44 37 #include "UITranslator.h" 45 38 … … 121 114 /** Notifies about port changed. */ 122 115 void sigPortChanged(); 116 123 117 /** Notifies about path changed. */ 124 118 void sigPathChanged(); 119 125 120 /** Notifies about validity changed. */ 126 121 void sigValidityChanged(); … … 159 154 160 155 /** Handles translation event. */ 161 void retranslateUi(); 162 163 private slots: 164 165 /** Handles port availability being toggled to @a fOn. */ 166 void sltHandlePortAvailabilityToggled(bool fOn); 167 /** Handles port standard @a strOption being activated. */ 168 void sltHandlePortStandardOptionActivated(const QString &strOption); 169 /** Handles port mode change to item with certain @a iIndex. */ 170 void sltHandlePortModeChange(int iIndex); 156 void retranslateUi() {} 171 157 172 158 private: … … 179 165 void prepareConnections(); 180 166 181 /** Populates combo-boxes. */182 void populateComboboxes();183 184 167 /** Holds the parent page reference. */ 185 168 UIMachineSettingsSerialPage *m_pParent; 186 169 187 170 /** Holds the port slot number. */ 188 int m_iSlot; 189 /** Holds the port mode. */ 190 KPortMode m_enmPortMode; 191 192 /** @name Widgets 193 * @{ */ 194 /** Holds the port check-box instance. */ 195 QCheckBox *m_pCheckBoxPort; 196 /** Holds the port settings widget instance. */ 197 QWidget *m_pWidgetPortSettings; 198 /** Holds the number label instance. */ 199 QLabel *m_pLabelNumber; 200 /** Holds the number combo instance. */ 201 QComboBox *m_pComboNumber; 202 /** Holds the IRQ label instance. */ 203 QLabel *m_pLabelIRQ; 204 /** Holds the IRQ editor instance. */ 205 QLineEdit *m_pLineEditIRQ; 206 /** Holds the IO address label instance. */ 207 QLabel *m_pLabelIOAddress; 208 /** Holds the IO address editor instance. */ 209 QLineEdit *m_pLineEditIOAddress; 210 /** Holds the mode label instance. */ 211 QLabel *m_pLabelMode; 212 /** Holds the mode combo instance. */ 213 QComboBox *m_pComboMode; 214 /** Holds the pipe check-box instance. */ 215 QCheckBox *m_pCheckBoxPipe; 216 /** Holds the path label instance. */ 217 QLabel *m_pLabelPath; 218 /** Holds the path editor instance. */ 219 QLineEdit *m_pEditorPath; 220 /** @} */ 171 int m_iSlot; 172 173 /** Holds the serial settings editor instance. */ 174 UISerialSettingsEditor *m_pEditorSerialSettings; 221 175 }; 222 176 … … 230 184 , m_pParent(pParent) 231 185 , m_iSlot(-1) 232 , m_enmPortMode(KPortMode_Max) 233 , m_pCheckBoxPort(0) 234 , m_pWidgetPortSettings(0) 235 , m_pLabelNumber(0) 236 , m_pComboNumber(0) 237 , m_pLabelIRQ(0) 238 , m_pLineEditIRQ(0) 239 , m_pLabelIOAddress(0) 240 , m_pLineEditIOAddress(0) 241 , m_pLabelMode(0) 242 , m_pComboMode(0) 243 , m_pCheckBoxPipe(0) 244 , m_pLabelPath(0) 245 , m_pEditorPath(0) 186 , m_pEditorSerialSettings(0) 246 187 { 247 188 prepare(); … … 256 197 m_iSlot = oldPortData.m_iSlot; 257 198 258 /* Load port data: */ 259 if (m_pCheckBoxPort) 260 m_pCheckBoxPort->setChecked(oldPortData.m_fPortEnabled); 261 if (m_pComboNumber) 262 m_pComboNumber->setCurrentIndex(m_pComboNumber->findText(UITranslator::toCOMPortName(oldPortData.m_uIRQ, oldPortData.m_uIOAddress))); 263 if (m_pLineEditIRQ) 264 m_pLineEditIRQ->setText(QString::number(oldPortData.m_uIRQ)); 265 if (m_pLineEditIOAddress) 266 m_pLineEditIOAddress->setText("0x" + QString::number(oldPortData.m_uIOAddress, 16).toUpper()); 267 m_enmPortMode = oldPortData.m_hostMode; 268 if (m_pCheckBoxPipe) 269 m_pCheckBoxPipe->setChecked(!oldPortData.m_fServer); 270 if (m_pEditorPath) 271 m_pEditorPath->setText(oldPortData.m_strPath); 272 273 /* Repopulate combo-boxes content: */ 274 populateComboboxes(); 275 /* Ensure everything is up-to-date */ 276 if (m_pCheckBoxPort) 277 sltHandlePortAvailabilityToggled(m_pCheckBoxPort->isChecked()); 199 if (m_pEditorSerialSettings) 200 { 201 /* Load port data: */ 202 m_pEditorSerialSettings->setPortByIRQAndIOAddress(oldPortData.m_uIRQ, oldPortData.m_uIOAddress); 203 m_pEditorSerialSettings->setIRQ(oldPortData.m_uIRQ); 204 m_pEditorSerialSettings->setIOAddress(oldPortData.m_uIOAddress); 205 m_pEditorSerialSettings->setHostMode(oldPortData.m_hostMode); 206 m_pEditorSerialSettings->setServerEnabled(oldPortData.m_fServer); 207 m_pEditorSerialSettings->setPath(oldPortData.m_strPath); 208 // Should be done in th end to finalize availability: 209 m_pEditorSerialSettings->setPortEnabled(oldPortData.m_fPortEnabled); 210 } 278 211 } 279 212 … … 286 219 newPortData.m_iSlot = m_iSlot; 287 220 288 /* Save port data: */ 289 if (m_pCheckBoxPort) 290 newPortData.m_fPortEnabled = m_pCheckBoxPort->isChecked(); 291 if (m_pLineEditIRQ) 292 newPortData.m_uIRQ = m_pLineEditIRQ->text().toULong(NULL, 0); 293 if (m_pLineEditIOAddress) 294 newPortData.m_uIOAddress = m_pLineEditIOAddress->text().toULong(NULL, 0); 295 if (m_pCheckBoxPipe) 296 newPortData.m_fServer = !m_pCheckBoxPipe->isChecked(); 297 if (m_pComboMode) 298 newPortData.m_hostMode = m_pComboMode->currentData().value<KPortMode>(); 299 if (m_pEditorPath) 300 newPortData.m_strPath = QDir::toNativeSeparators(m_pEditorPath->text()); 221 if (m_pEditorSerialSettings) 222 { 223 /* Save port data: */ 224 newPortData.m_fPortEnabled = m_pEditorSerialSettings->isPortEnabled(); 225 newPortData.m_uIRQ = m_pEditorSerialSettings->irq(); 226 newPortData.m_uIOAddress = m_pEditorSerialSettings->ioAddress(); 227 newPortData.m_fServer = m_pEditorSerialSettings->isServerEnabled(); 228 newPortData.m_hostMode = m_pEditorSerialSettings->hostMode(); 229 newPortData.m_strPath = m_pEditorSerialSettings->path(); 230 } 301 231 302 232 /* Cache new data: */ … … 313 243 message.first = UITranslator::removeAccelMark(tabTitle()); 314 244 315 if ( m_pCheckBoxPort 316 && m_pCheckBoxPort->isChecked()) 245 /* Validate enabled port only: */ 246 if ( m_pEditorSerialSettings 247 && m_pEditorSerialSettings->isPortEnabled()) 317 248 { 318 249 /* Check the port attribute emptiness & uniqueness: */ 319 const QString strIRQ = m_pLineEditIRQ ? m_pLineEditIRQ->text() : QString();320 const QString strIOAddress = m_pLineEditIOAddress ? m_pLineEditIOAddress->text() : QString();250 const QString strIRQ = irq(); 251 const QString strIOAddress = ioAddress(); 321 252 const QPair<QString, QString> port = qMakePair(strIRQ, strIOAddress); 322 253 … … 347 278 } 348 279 349 const KPortMode enmMode = m_p ComboMode->currentData().value<KPortMode>();280 const KPortMode enmMode = m_pEditorSerialSettings->hostMode(); 350 281 if (enmMode != KPortMode_Disconnected) 351 282 { 352 const QString strPath (m_pEditorPath->text());283 const QString strPath = m_pEditorSerialSettings->path(); 353 284 354 285 if (strPath.isEmpty()) … … 384 315 QWidget *UIMachineSettingsSerial::setOrderAfter(QWidget *pWidget) 385 316 { 386 setTabOrder(pWidget, m_pCheckBoxPort); 387 setTabOrder(m_pCheckBoxPort, m_pComboNumber); 388 setTabOrder(m_pComboNumber, m_pLineEditIRQ); 389 setTabOrder(m_pLineEditIRQ, m_pLineEditIOAddress); 390 setTabOrder(m_pLineEditIOAddress, m_pComboMode); 391 setTabOrder(m_pComboMode, m_pCheckBoxPipe); 392 setTabOrder(m_pCheckBoxPipe, m_pEditorPath); 393 return m_pEditorPath; 317 setTabOrder(pWidget, m_pEditorSerialSettings); 318 return m_pEditorSerialSettings; 394 319 } 395 320 … … 401 326 bool UIMachineSettingsSerial::isPortEnabled() const 402 327 { 403 return m_p CheckBoxPort->isChecked();328 return m_pEditorSerialSettings->isPortEnabled(); 404 329 } 405 330 406 331 QString UIMachineSettingsSerial::irq() const 407 332 { 408 return m_pLineEditIRQ->text();333 return QString::number(m_pEditorSerialSettings->irq()); 409 334 } 410 335 411 336 QString UIMachineSettingsSerial::ioAddress() const 412 337 { 413 return m_pLineEditIOAddress->text();338 return QString::number(m_pEditorSerialSettings->ioAddress()); 414 339 } 415 340 416 341 QString UIMachineSettingsSerial::path() const 417 342 { 418 return m_pEditor Path->text();343 return m_pEditorSerialSettings->path(); 419 344 } 420 345 421 346 void UIMachineSettingsSerial::polishTab() 422 347 { 423 /* Sanity check: */ 424 if (!m_pParent) 425 return; 426 427 /* Polish port page: */ 428 ulong uIRQ, uIOAddress; 429 const bool fStd = m_pComboNumber ? UITranslator::toCOMPortNumbers(m_pComboNumber->currentText(), uIRQ, uIOAddress) : false; 430 const KPortMode enmMode = m_pComboMode ? m_pComboMode->currentData().value<KPortMode>() : KPortMode_Max; 431 if (m_pCheckBoxPort) 432 m_pCheckBoxPort->setEnabled(m_pParent->isMachineOffline()); 433 if (m_pLabelNumber) 434 m_pLabelNumber->setEnabled(m_pParent->isMachineOffline()); 435 if (m_pComboNumber) 436 m_pComboNumber->setEnabled(m_pParent->isMachineOffline()); 437 if (m_pLabelIRQ) 438 m_pLabelIRQ->setEnabled(m_pParent->isMachineOffline()); 439 if (m_pLineEditIRQ) 440 m_pLineEditIRQ->setEnabled(!fStd && m_pParent->isMachineOffline()); 441 if (m_pLabelIOAddress) 442 m_pLabelIOAddress->setEnabled(m_pParent->isMachineOffline()); 443 if (m_pLineEditIOAddress) 444 m_pLineEditIOAddress->setEnabled(!fStd && m_pParent->isMachineOffline()); 445 if (m_pLabelMode) 446 m_pLabelMode->setEnabled(m_pParent->isMachineOffline()); 447 if (m_pComboMode) 448 m_pComboMode->setEnabled(m_pParent->isMachineOffline()); 449 if (m_pCheckBoxPipe) 450 m_pCheckBoxPipe->setEnabled( (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP) 451 && m_pParent->isMachineOffline()); 452 if (m_pLabelPath) 453 m_pLabelPath->setEnabled( enmMode != KPortMode_Disconnected 454 && m_pParent->isMachineOffline()); 455 if (m_pEditorPath) 456 m_pEditorPath->setEnabled( enmMode != KPortMode_Disconnected 457 && m_pParent->isMachineOffline()); 458 } 459 460 void UIMachineSettingsSerial::retranslateUi() 461 { 462 if (m_pCheckBoxPort) 463 { 464 m_pCheckBoxPort->setText(tr("&Enable Serial Port")); 465 m_pCheckBoxPort->setToolTip(tr("When checked, enables the given serial port of the virtual machine.")); 466 } 467 if (m_pLabelNumber) 468 m_pLabelNumber->setText(tr("Port &Number:")); 469 if (m_pComboNumber) 470 { 471 m_pComboNumber->setItemText(m_pComboNumber->count() - 1, UITranslator::toCOMPortName(0, 0)); 472 m_pComboNumber->setToolTip(tr("Selects the serial port number. You can choose one of the standard serial ports or select " 473 "User-defined and specify port parameters manually.")); 474 } 475 if (m_pLabelIRQ) 476 m_pLabelIRQ->setText(tr("&IRQ:")); 477 if (m_pLineEditIRQ) 478 m_pLineEditIRQ->setToolTip(tr("Holds the IRQ number of this serial port. This should be a whole number between " 479 "<tt>0</tt> and <tt>255</tt>. Values greater than <tt>15</tt> may only be used if the " 480 "I/O APIC setting is enabled for this virtual machine.")); 481 if (m_pLabelIOAddress) 482 m_pLabelIOAddress->setText(tr("I/O Po&rt:")); 483 if (m_pLineEditIOAddress) 484 m_pLineEditIOAddress->setToolTip(tr("Holds the base I/O port address of this serial port. Valid values are integer numbers " 485 "in range from <tt>0</tt> to <tt>0xFFFF</tt>.")); 486 if (m_pLabelMode) 487 m_pLabelMode->setText(tr("Port &Mode:")); 488 if (m_pComboMode) 489 m_pComboMode->setToolTip(tr("Selects the working mode of this serial port. If you select Disconnected, the guest " 490 "OS will detect the serial port but will not be able to operate it.")); 491 if (m_pCheckBoxPipe) 492 { 493 m_pCheckBoxPipe->setText(tr("&Connect to existing pipe/socket")); 494 m_pCheckBoxPipe->setToolTip(tr("When checked, the virtual machine will assume that the pipe or socket specified in the " 495 "Path/Address field exists and try to use it. Otherwise, the pipe or socket will " 496 "be created by the virtual machine when it starts.")); 497 } 498 if (m_pLabelPath) 499 m_pLabelPath->setText(tr("&Path/Address:")); 500 if (m_pEditorPath) 501 m_pEditorPath->setToolTip(tr("In Host Pipe mode: Holds the path to the serial port's pipe on the host. " 502 "Examples: \"\\\\.\\pipe\\myvbox\" or \"/tmp/myvbox\", for Windows and UNIX-like systems " 503 "respectively. In Host Device mode: Holds the host serial device name. " 504 "Examples: \"COM1\" or \"/dev/ttyS0\". In Raw File mode: Holds the file-path " 505 "on the host system, where the serial output will be dumped. In TCP mode: " 506 "Holds the TCP \"port\" when in server mode, or \"hostname:port\" when in client mode.")); 507 508 /* Translate combo-boxes content: */ 509 populateComboboxes(); 510 } 511 512 void UIMachineSettingsSerial::sltHandlePortAvailabilityToggled(bool fOn) 513 { 514 /* Update availability: */ 515 m_pWidgetPortSettings->setEnabled(m_pCheckBoxPort->isChecked()); 516 if (fOn) 517 { 518 sltHandlePortStandardOptionActivated(m_pComboNumber->currentText()); 519 sltHandlePortModeChange(m_pComboMode->currentIndex()); 520 } 521 522 /* Notify port/path changed: */ 523 emit sigPortChanged(); 524 emit sigPathChanged(); 525 } 526 527 void UIMachineSettingsSerial::sltHandlePortStandardOptionActivated(const QString &strText) 528 { 529 /* Update availability: */ 530 ulong uIRQ, uIOAddress; 531 bool fStd = UITranslator::toCOMPortNumbers(strText, uIRQ, uIOAddress); 532 m_pLineEditIRQ->setEnabled(!fStd); 533 m_pLineEditIOAddress->setEnabled(!fStd); 534 if (fStd) 535 { 536 m_pLineEditIRQ->setText(QString::number(uIRQ)); 537 m_pLineEditIOAddress->setText("0x" + QString::number(uIOAddress, 16).toUpper()); 538 } 539 540 /* Notify validity changed: */ 541 emit sigValidityChanged(); 542 } 543 544 void UIMachineSettingsSerial::sltHandlePortModeChange(int iIndex) 545 { 546 /* Update availability: */ 547 const KPortMode enmMode = m_pComboMode->itemData(iIndex).value<KPortMode>(); 548 m_pCheckBoxPipe->setEnabled(enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP); 549 m_pEditorPath->setEnabled(enmMode != KPortMode_Disconnected); 550 m_pLabelPath->setEnabled(enmMode != KPortMode_Disconnected); 551 552 /* Notify validity changed: */ 553 emit sigValidityChanged(); 348 if ( m_pEditorSerialSettings 349 && m_pParent) 350 { 351 /* Polish port page: */ 352 const bool fStd = m_pEditorSerialSettings->isPortStandardOne(); 353 const KPortMode enmMode = m_pEditorSerialSettings->hostMode(); 354 m_pEditorSerialSettings->setPortOptionsAvailable(m_pParent->isMachineOffline()); 355 m_pEditorSerialSettings->setIRQAndIOAddressOptionsAvailable(!fStd && m_pParent->isMachineOffline()); 356 m_pEditorSerialSettings->setHostModeOptionsAvailable(m_pParent->isMachineOffline()); 357 m_pEditorSerialSettings->setPipeOptionsAvailable( (enmMode == KPortMode_HostPipe || enmMode == KPortMode_TCP) 358 && m_pParent->isMachineOffline()); 359 m_pEditorSerialSettings->setPathOptionsAvailable( enmMode != KPortMode_Disconnected 360 && m_pParent->isMachineOffline()); 361 } 554 362 } 555 363 … … 567 375 { 568 376 /* Prepare main layout: */ 569 QGridLayout *pLayoutMain = new QGridLayout(this); 570 if (pLayoutMain) 571 { 572 pLayoutMain->setRowStretch(2, 1); 573 574 /* Prepare port check-box: */ 575 m_pCheckBoxPort = new QCheckBox(this); 576 if (m_pCheckBoxPort) 577 pLayoutMain->addWidget(m_pCheckBoxPort, 0, 0, 1, 2); 578 579 /* Prepare 20-px shifting spacer: */ 580 QSpacerItem *pSpacerItem = new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Minimum); 581 if (pSpacerItem) 582 pLayoutMain->addItem(pSpacerItem, 1, 0); 583 584 /* Prepare adapter settings widget: */ 585 m_pWidgetPortSettings = new QWidget(this); 586 if (m_pWidgetPortSettings) 587 { 588 /* Prepare adapter settings widget layout: */ 589 QGridLayout *pLayoutPortSettings = new QGridLayout(m_pWidgetPortSettings); 590 if (pLayoutPortSettings) 591 { 592 pLayoutPortSettings->setContentsMargins(0, 0, 0, 0); 593 pLayoutPortSettings->setColumnStretch(6, 1); 594 595 /* Prepare number label: */ 596 m_pLabelNumber = new QLabel(m_pWidgetPortSettings); 597 if (m_pLabelNumber) 598 { 599 m_pLabelNumber->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 600 pLayoutPortSettings->addWidget(m_pLabelNumber, 0, 0); 601 } 602 /* Prepare number combo: */ 603 m_pComboNumber = new QComboBox(m_pWidgetPortSettings); 604 if (m_pComboNumber) 605 { 606 if (m_pLabelNumber) 607 m_pLabelNumber->setBuddy(m_pComboNumber); 608 m_pComboNumber->insertItem(0, UITranslator::toCOMPortName(0, 0)); 609 m_pComboNumber->insertItems(0, UITranslator::COMPortNames()); 610 pLayoutPortSettings->addWidget(m_pComboNumber, 0, 1); 611 } 612 /* Prepare IRQ label: */ 613 m_pLabelIRQ = new QLabel(m_pWidgetPortSettings); 614 if (m_pLabelIRQ) 615 pLayoutPortSettings->addWidget(m_pLabelIRQ, 0, 2); 616 /* Prepare IRQ label: */ 617 m_pLineEditIRQ = new QLineEdit(m_pWidgetPortSettings); 618 if (m_pLineEditIRQ) 619 { 620 if (m_pLabelIRQ) 621 m_pLabelIRQ->setBuddy(m_pLineEditIRQ); 622 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) 623 m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().horizontalAdvance("8888")); 624 #else 625 m_pLineEditIRQ->setFixedWidth(m_pLineEditIRQ->fontMetrics().width("8888")); 626 #endif 627 m_pLineEditIRQ->setValidator(new QIULongValidator(0, 255, this)); 628 pLayoutPortSettings->addWidget(m_pLineEditIRQ, 0, 3); 629 } 630 /* Prepare IO address label: */ 631 m_pLabelIOAddress = new QLabel(m_pWidgetPortSettings); 632 if (m_pLabelIOAddress) 633 pLayoutPortSettings->addWidget(m_pLabelIOAddress, 0, 4); 634 /* Prepare IO address label: */ 635 m_pLineEditIOAddress = new QLineEdit(m_pWidgetPortSettings); 636 if (m_pLineEditIOAddress) 637 { 638 if (m_pLabelIOAddress) 639 m_pLabelIOAddress->setBuddy(m_pLineEditIOAddress); 640 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0) 641 m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().horizontalAdvance("8888888")); 642 #else 643 m_pLineEditIOAddress->setFixedWidth(m_pLineEditIOAddress->fontMetrics().width("8888888")); 644 #endif 645 m_pLineEditIOAddress->setValidator(new QIULongValidator(0, 0xFFFF, this)); 646 pLayoutPortSettings->addWidget(m_pLineEditIOAddress, 0, 5); 647 } 648 649 /* Prepare mode label: */ 650 m_pLabelMode = new QLabel(m_pWidgetPortSettings); 651 if (m_pLabelMode) 652 { 653 m_pLabelMode->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 654 pLayoutPortSettings->addWidget(m_pLabelMode, 1, 0); 655 } 656 /* Prepare mode combo: */ 657 m_pComboMode = new QComboBox(m_pWidgetPortSettings); 658 if (m_pComboMode) 659 { 660 if (m_pLabelMode) 661 m_pLabelMode->setBuddy(m_pComboMode); 662 pLayoutPortSettings->addWidget(m_pComboMode, 1, 1); 663 } 664 665 /* Prepare pipe check-box: */ 666 m_pCheckBoxPipe = new QCheckBox(m_pWidgetPortSettings); 667 if (m_pCheckBoxPipe) 668 pLayoutPortSettings->addWidget(m_pCheckBoxPipe, 2, 1, 1, 5); 669 670 /* Prepare path label: */ 671 m_pLabelPath = new QLabel(m_pWidgetPortSettings); 672 if (m_pLabelPath) 673 { 674 m_pLabelPath->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 675 pLayoutPortSettings->addWidget(m_pLabelPath, 3, 0); 676 } 677 /* Prepare path editor: */ 678 m_pEditorPath = new QLineEdit(m_pWidgetPortSettings); 679 if (m_pEditorPath) 680 { 681 if (m_pLabelPath) 682 m_pLabelPath->setBuddy(m_pEditorPath); 683 m_pEditorPath->setValidator(new QRegularExpressionValidator(QRegularExpression(".+"), this)); 684 pLayoutPortSettings->addWidget(m_pEditorPath, 3, 1, 1, 6); 685 } 686 } 687 688 pLayoutMain->addWidget(m_pWidgetPortSettings, 1, 1); 689 } 377 QVBoxLayout *pLayout = new QVBoxLayout(this); 378 if (pLayout) 379 { 380 /* Prepare settings editor: */ 381 m_pEditorSerialSettings = new UISerialSettingsEditor(this); 382 if (m_pEditorSerialSettings) 383 pLayout->addWidget(m_pEditorSerialSettings); 384 385 pLayout->addStretch(); 690 386 } 691 387 } … … 693 389 void UIMachineSettingsSerial::prepareConnections() 694 390 { 695 if (m_pCheckBoxPort) 696 connect(m_pCheckBoxPort, &QCheckBox::toggled, this, &UIMachineSettingsSerial::sltHandlePortAvailabilityToggled); 697 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 698 if (m_pComboNumber) 699 connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::textActivated), 700 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated); 701 #else 702 if (m_pComboNumber) 703 connect(m_pComboNumber, static_cast<void(QComboBox::*)(const QString&)>(&QComboBox::activated), 704 this, &UIMachineSettingsSerial::sltHandlePortStandardOptionActivated); 705 #endif 706 if (m_pLineEditIRQ) 707 connect(m_pLineEditIRQ, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged); 708 if (m_pLineEditIOAddress) 709 connect(m_pLineEditIOAddress, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPortChanged); 710 if (m_pComboMode) 711 connect(m_pComboMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated), 712 this, &UIMachineSettingsSerial::sltHandlePortModeChange); 713 if (m_pEditorPath) 714 connect(m_pEditorPath, &QLineEdit::textChanged, this, &UIMachineSettingsSerial::sigPathChanged); 715 } 716 717 void UIMachineSettingsSerial::populateComboboxes() 718 { 719 /* Port mode: */ 720 { 721 /* Clear the port mode combo-box: */ 722 m_pComboMode->clear(); 723 724 /* Load currently supported port moded: */ 725 CSystemProperties comProperties = uiCommon().virtualBox().GetSystemProperties(); 726 QVector<KPortMode> supportedModes = comProperties.GetSupportedPortModes(); 727 /* Take currently requested mode into account if it's sane: */ 728 if (!supportedModes.contains(m_enmPortMode) && m_enmPortMode != KPortMode_Max) 729 supportedModes.prepend(m_enmPortMode); 730 731 /* Populate port modes: */ 732 int iPortModeIndex = 0; 733 foreach (const KPortMode &enmMode, supportedModes) 734 { 735 m_pComboMode->insertItem(iPortModeIndex, gpConverter->toString(enmMode)); 736 m_pComboMode->setItemData(iPortModeIndex, QVariant::fromValue(enmMode)); 737 m_pComboMode->setItemData(iPortModeIndex, m_pComboMode->itemText(iPortModeIndex), Qt::ToolTipRole); 738 ++iPortModeIndex; 739 } 740 741 /* Choose requested port mode: */ 742 const int iIndex = m_pComboMode->findData(QVariant::fromValue(m_enmPortMode)); 743 m_pComboMode->setCurrentIndex(iIndex != -1 ? iIndex : 0); 391 if (m_pEditorSerialSettings) 392 { 393 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortAvailabilityChanged, 394 this, &UIMachineSettingsSerial::sigPortChanged); 395 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortAvailabilityChanged, 396 this, &UIMachineSettingsSerial::sigPathChanged); 397 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigStandardPortOptionChanged, 398 this, &UIMachineSettingsSerial::sigValidityChanged); 399 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortIRQChanged, 400 this, &UIMachineSettingsSerial::sigPortChanged); 401 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPortIOAddressChanged, 402 this, &UIMachineSettingsSerial::sigPortChanged); 403 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigModeChanged, 404 this, &UIMachineSettingsSerial::sigValidityChanged); 405 connect(m_pEditorSerialSettings, &UISerialSettingsEditor::sigPathChanged, 406 this, &UIMachineSettingsSerial::sigPathChanged); 744 407 } 745 408 }
Note:
See TracChangeset
for help on using the changeset viewer.