diff --git a/samples/blackgui/infowindow.cpp b/samples/blackgui/infowindow.cpp index 04b8788c7..755fa0d80 100644 --- a/samples/blackgui/infowindow.cpp +++ b/samples/blackgui/infowindow.cpp @@ -16,10 +16,7 @@ CInfoWindow::CInfoWindow(QWidget *parent) : /* * Destructor */ -CInfoWindow::~CInfoWindow() -{ - delete ui; -} +CInfoWindow::~CInfoWindow() { } /* * Info message for some time diff --git a/samples/blackgui/infowindow.h b/samples/blackgui/infowindow.h index 5305e2ee0..57ce69b3a 100644 --- a/samples/blackgui/infowindow.h +++ b/samples/blackgui/infowindow.h @@ -7,10 +7,11 @@ #define SAMPLE_INFOWINDOW_H #include +#include namespace Ui { -class InfoWindow; + class InfoWindow; } class CInfoWindow : public QWizardPage @@ -37,7 +38,7 @@ public: void setInfoMessage(const QString &message, int displayTimeMs = 4000); private: - Ui::InfoWindow *ui; + QScopedPointer ui; }; #endif // guard diff --git a/samples/blackgui/introwindow.cpp b/samples/blackgui/introwindow.cpp index 4a57f6955..d678f2287 100644 --- a/samples/blackgui/introwindow.cpp +++ b/samples/blackgui/introwindow.cpp @@ -17,10 +17,7 @@ CIntroWindow::CIntroWindow(QWidget *parent) : /* * Destructor */ -CIntroWindow::~CIntroWindow() -{ - delete ui; -} +CIntroWindow::~CIntroWindow() { } /* * Window mode @@ -52,9 +49,12 @@ GuiModes::CoreMode CIntroWindow::getCoreMode() const void CIntroWindow::buttonClicked() const { QObject *sender = QObject::sender(); - if (sender == this->ui->pb_ModelDb) { + if (sender == this->ui->pb_ModelDb) + { QDesktopServices::openUrl(QUrl("http://vatrep.vatsim-germany.org/page/index.php", QUrl::TolerantMode)); - } else if (sender == this->ui->pb_WebSite) { + } + else if (sender == this->ui->pb_WebSite) + { QDesktopServices::openUrl(QUrl("https://dev.vatsim-germany.org/", QUrl::TolerantMode)); } } diff --git a/samples/blackgui/introwindow.h b/samples/blackgui/introwindow.h index baf904bfc..031b5df31 100644 --- a/samples/blackgui/introwindow.h +++ b/samples/blackgui/introwindow.h @@ -8,11 +8,11 @@ #include "guimodeenums.h" #include - +#include namespace Ui { -class CIntroWindow; + class CIntroWindow; } class CIntroWindow : public QDialog @@ -50,7 +50,7 @@ private slots: void buttonClicked() const; private: - Ui::CIntroWindow *ui; + QScopedPointer ui; }; #endif // guard diff --git a/samples/blackgui/mainwindow.cpp b/samples/blackgui/mainwindow.cpp index 81aa8cfd3..2787ee2ac 100644 --- a/samples/blackgui/mainwindow.cpp +++ b/samples/blackgui/mainwindow.cpp @@ -27,10 +27,7 @@ MainWindow::MainWindow(GuiModes::WindowMode windowMode, QWidget *parent) : m_dBusConnection("dummy"), m_coreRuntime(nullptr), m_atcListOnline(nullptr), m_atcListBooked(nullptr), m_trafficServerList(nullptr), m_aircraftsInRange(nullptr), - m_contextApplication(nullptr), - m_contextNetwork(nullptr), m_contextVoice(nullptr), - m_contextSettings(nullptr), - m_ownAircraft(), m_voiceRoomCom1(), m_voiceRoomCom2(), + m_contextApplication(nullptr), m_contextNetwork(nullptr), m_contextVoice(nullptr), m_contextSettings(nullptr), m_timerUpdateAtcStationsOnline(nullptr), m_timerUpdateAircraftsInRange(nullptr), m_timerCollectedCockpitUpdates(nullptr), m_timerContextWatchdog(nullptr), m_contextMenuAudio(nullptr) @@ -48,11 +45,7 @@ MainWindow::MainWindow(GuiModes::WindowMode windowMode, QWidget *parent) : /* * Destructor */ -MainWindow::~MainWindow() -{ - this->gracefulShutdown(); - delete ui; -} +MainWindow::~MainWindow() {} /* * Graceful shutdown @@ -61,37 +54,44 @@ void MainWindow::gracefulShutdown() { if (!this->m_init) return; this->m_init = false; + if (this->m_infoWindow) + { + this->m_infoWindow->close(); + this->m_infoWindow = nullptr; + } // if we have a context, we shut some things down if (this->m_contextNetworkAvailable) { - this->m_contextNetwork->disconnectFromNetwork(); - } - - if (this->m_contextVoiceAvailable) - { - this->m_contextVoice->leaveAllVoiceRooms(); + if (this->m_contextNetwork->isConnected()) + { + if (this->m_contextVoiceAvailable) + { + this->m_contextVoice->leaveAllVoiceRooms(); + } + this->m_contextNetwork->disconnectFromNetwork(); + } } if (this->m_timerUpdateAircraftsInRange) { - this->m_timerUpdateAircraftsInRange->disconnect(this); this->m_timerUpdateAircraftsInRange->stop(); + this->m_timerUpdateAircraftsInRange->disconnect(this); } if (this->m_timerUpdateAtcStationsOnline) { - this->m_timerUpdateAtcStationsOnline->disconnect(this); this->m_timerUpdateAtcStationsOnline->stop(); + this->m_timerUpdateAtcStationsOnline->disconnect(this); } if (this->m_timerContextWatchdog) { - this->m_timerContextWatchdog->disconnect(this); this->m_timerContextWatchdog->stop(); + this->m_timerContextWatchdog->disconnect(this); } if (this->m_timerCollectedCockpitUpdates) { - this->m_timerCollectedCockpitUpdates->disconnect(this); this->m_timerCollectedCockpitUpdates->stop(); + this->m_timerCollectedCockpitUpdates->disconnect(this); } } @@ -228,6 +228,8 @@ void MainWindow::displayStatusMessage(const CStatusMessage &message) { this->ui->sb_MainStatusBar->showMessage(message.getMessage(), 3000); this->ui->te_StatusMessages->insertPlainText(message.toQString(true).append("\n")); + if (message.getSeverity() == CStatusMessage::SeverityError) this->displayOverlayInfo(message); + } /* @@ -393,7 +395,9 @@ void MainWindow::changeWindowOpacity(int opacity) return; } qreal o = opacity / 100.0; + o = o < 0.3 ? 0.3 : o; QWidget::setWindowOpacity(o); + this->ui->hs_SettingsGuiOpacity->setValue(o * 100.0); } /* @@ -416,3 +420,12 @@ void MainWindow::displayOverlayInfo(const QString &message) this->m_infoWindow->setInfoMessage(message); } } + +/* + * Info window by + */ +void MainWindow::displayOverlayInfo(const CStatusMessage &message) +{ + this->displayOverlayInfo(message.getMessage()); + // further code goes here, such as marking errors as red ... +} diff --git a/samples/blackgui/mainwindow.h b/samples/blackgui/mainwindow.h index 4190e87ff..06f097cbb 100644 --- a/samples/blackgui/mainwindow.h +++ b/samples/blackgui/mainwindow.h @@ -10,22 +10,22 @@ #pragma push_macro("interface") #undef interface -#include -#include -#include -#include -#include "blackgui/atcstationlistmodel.h" -#include "blackgui/serverlistmodel.h" -#include "blackgui/aircraftlistmodel.h" -#include "blackmisc/statusmessage.h" -#include "blackmisc/nwtextmessage.h" +#include "infowindow.h" +#include "guimodeenums.h" #include "blackcore/context_voice.h" #include "blackcore/context_network_interface.h" #include "blackcore/context_settings_interface.h" #include "blackcore/context_application_interface.h" #include "blackcore/coreruntime.h" -#include "infowindow.h" -#include "guimodeenums.h" +#include "blackgui/atcstationlistmodel.h" +#include "blackgui/serverlistmodel.h" +#include "blackgui/aircraftlistmodel.h" +#include "blackmisc/statusmessage.h" +#include "blackmisc/nwtextmessage.h" +#include +#include +#include +#include namespace Ui { @@ -97,7 +97,7 @@ protected: }; private: - Ui::MainWindow *ui; + QScopedPointer ui; CInfoWindow *m_infoWindow; bool m_init; GuiModes::WindowMode m_windowMode; @@ -106,7 +106,7 @@ private: bool m_contextNetworkAvailable; bool m_contextVoiceAvailable; QDBusConnection m_dBusConnection; - BlackCore::CCoreRuntime *m_coreRuntime; /*!< runtime, if working with local core */ + QScopedPointer m_coreRuntime; /*!< runtime, if working with local core */ BlackGui::CAtcListModel *m_atcListOnline; BlackGui::CAtcListModel *m_atcListBooked; BlackGui::CServerListModel *m_trafficServerList; @@ -130,6 +130,7 @@ private: QPixmap m_resPixmapVoiceMuted; QPoint m_dragPosition; /*!< position, if moving is handled with frameless window */ QMenu *m_contextMenuAudio; /*! Audio context menu */ + QString m_transponderResetValue; /*! Temp. storage of XPdr mode to reset, req. until timer allows singleShoot with Lambdas */ /*! * \brief GUI status update @@ -233,6 +234,12 @@ private: */ void displayOverlayInfo(const QString &message = ""); + /*! + * \brief Overlay info by status message + * \param message + */ + void displayOverlayInfo(const BlackMisc::CStatusMessage &message); + /*! * \brief Is given main page selected? * \param mainPage @@ -415,14 +422,9 @@ private slots: void audioDeviceSelected(int index); /*! - * \brief Reset transponder to standby + * \brief Reset transponder to Standby / Charly */ - void resetTransponderModerToStandby(); - - /*! - * \brief Reset transponder to Charly - */ - void resetTransponderModerToCharly(); + void resetTransponderMode(); /*! * \brief Override voice room (allows to set an arbitrary voice room for testing purposes) diff --git a/samples/blackgui/mainwindow_cockpit.cpp b/samples/blackgui/mainwindow_cockpit.cpp index 0e41eb04a..c82812a22 100644 --- a/samples/blackgui/mainwindow_cockpit.cpp +++ b/samples/blackgui/mainwindow_cockpit.cpp @@ -40,7 +40,16 @@ void MainWindow::cockpitValuesChanged() else if (sender == this->ui->pb_CockpitIdent) { // trigger the real button - this->ui->cb_CockpitTransponderMode->setCurrentText("I"); + if (this->ui->cb_CockpitTransponderMode->currentText() == "I") + { + this->ui->pb_CockpitIdent->setStyleSheet(""); + this->resetTransponderMode(); + } + else + { + this->ui->pb_CockpitIdent->setStyleSheet("background: red"); + this->ui->cb_CockpitTransponderMode->setCurrentText("I"); // trigger real button and whole process + } return; } @@ -138,19 +147,16 @@ void MainWindow::updateCockpitFromContext() } /* - * Reset transponder mode to Standby + * Reset transponder mode to Standby / Charly */ -void MainWindow::resetTransponderModerToStandby() +void MainWindow::resetTransponderMode() { - this->ui->cb_CockpitTransponderMode->setCurrentText("S"); -} - -/* - * Reset transponder mode to Standby - */ -void MainWindow::resetTransponderModerToCharly() -{ - this->ui->cb_CockpitTransponderMode->setCurrentText("C"); + this->ui->pb_CockpitIdent->setStyleSheet(""); + if (this->ui->cb_CockpitTransponderMode->currentText() == "I") + { + // only reset if still "I" + this->ui->cb_CockpitTransponderMode->setCurrentText(this->m_transponderResetValue); + } } /* @@ -185,10 +191,16 @@ void MainWindow::sendCockpitUpdates() { // ident shall be sent for some time, then reset transponder.setTransponderMode(CTransponder::StateIdent); + this->ui->pb_CockpitIdent->setStyleSheet("background: red"); if (this->m_ownAircraft.getTransponderMode() == CTransponder::ModeS) - QTimer::singleShot(5000, this, SLOT(resetTransponderModerToStandby())); + { + this->m_transponderResetValue = "S"; + } else - QTimer::singleShot(5000, this, SLOT(resetTransponderModerToCharly())); + { + this->m_transponderResetValue = "C"; + } + QTimer::singleShot(5000, this, SLOT(resetTransponderMode())); } // @@ -199,7 +211,6 @@ void MainWindow::sendCockpitUpdates() com2.setFrequencyActiveMHz(this->ui->ds_CockpitCom2Active->value()); com2.setFrequencyStandbyMHz(this->ui->ds_CockpitCom2Standby->value()); - // // Send to context // diff --git a/samples/blackgui/mainwindow_init.cpp b/samples/blackgui/mainwindow_init.cpp index d3549bd70..0878f8ad8 100644 --- a/samples/blackgui/mainwindow_init.cpp +++ b/samples/blackgui/mainwindow_init.cpp @@ -96,7 +96,7 @@ void MainWindow::init(GuiModes::CoreMode coreMode) } else { - this->m_coreRuntime = new CCoreRuntime(false, this); + this->m_coreRuntime.reset(new CCoreRuntime(false, this)); this->m_contextNetwork = this->m_coreRuntime->getIContextNetwork(); this->m_contextVoice = this->m_coreRuntime->getIContextVoice(); this->m_contextSettings = this->m_coreRuntime->getIContextSettings(); @@ -114,44 +114,18 @@ void MainWindow::init(GuiModes::CoreMode coreMode) this->m_resPixmapVoiceHigh = QPixmap(":/blackgui/icons/audiovolumehigh.png"); this->m_resPixmapVoiceMuted = QPixmap(":/blackgui/icons/audiovolumemuted.png"); - // relay status messages + // signal / slots bool connect; - connect = this->connect(this->m_contextNetwork, SIGNAL(statusMessage(BlackMisc::CStatusMessage)), - this, SLOT(displayStatusMessage(BlackMisc::CStatusMessage))); - Q_ASSERT_X(connect, "init", "cannot connect status message"); - - connect = this->connect(this->m_contextNetwork, SIGNAL(connectionTerminated()), - this, SLOT(connectionTerminated())); - Q_ASSERT_X(connect, "init", "cannot connect terminating"); - - connect = this->connect(this->m_contextNetwork, SIGNAL(connectionStatusChanged(uint, uint)), - this, SLOT(connectionStatusChanged(uint, uint))); - Q_ASSERT_X(connect, "init", "cannot connect change connection status"); - - connect = this->connect(this->m_contextSettings, SIGNAL(changedNetworkSettings()), - this, SLOT(changedNetworkSettings())); - Q_ASSERT_X(connect, "init", "cannot connect change network status"); - - connect = this->connect(this->m_contextNetwork, SIGNAL(textMessagesReceived(BlackMisc::Network::CTextMessageList)), - this, SLOT(appendTextMessagesToGui(BlackMisc::Network::CTextMessageList))); - Q_ASSERT_X(connect, "init", "cannot connect text message received"); - - connect = this->connect(this->m_timerUpdateAircraftsInRange, SIGNAL(timeout()), - this, SLOT(timerBasedUpdates())); - Q_ASSERT_X(connect, "init", "cannot connect timer"); - - connect = this->connect(this->m_timerUpdateAtcStationsOnline, SIGNAL(timeout()), - this, SLOT(timerBasedUpdates())); - Q_ASSERT_X(connect, "init", "cannot connect timer"); - - connect = this->connect(this->m_timerContextWatchdog, SIGNAL(timeout()), - this, SLOT(timerBasedUpdates())); - Q_ASSERT_X(connect, "init", "cannot connect timer (watchdog)"); - - connect = this->connect(this->m_timerCollectedCockpitUpdates, SIGNAL(timeout()), - this, SLOT(sendCockpitUpdates())); - Q_ASSERT_X(connect, "init", "cannot connect timer (cockpit updates)"); - Q_UNUSED(connect); + this->connect(this->m_contextNetwork, &IContextNetwork::statusMessage, this, &MainWindow::displayStatusMessage); + this->connect(this->m_contextNetwork, &IContextNetwork::connectionTerminated, this, &MainWindow::connectionTerminated); + this->connect(this->m_contextNetwork, &IContextNetwork::connectionStatusChanged, this, &MainWindow::connectionStatusChanged); + this->connect(this->m_contextSettings, &IContextSettings::changedNetworkSettings, this, &MainWindow::changedNetworkSettings); + connect = this->connect(this->m_contextNetwork, SIGNAL(textMessagesReceived(BlackMisc::Network::CTextMessageList)), this, SLOT(appendTextMessagesToGui(BlackMisc::Network::CTextMessageList))); + Q_ASSERT(connect); + this->connect(this->m_timerUpdateAircraftsInRange, &QTimer::timeout, this, &MainWindow::timerBasedUpdates); + this->connect(this->m_timerUpdateAtcStationsOnline, &QTimer::timeout, this, &MainWindow::timerBasedUpdates); + this->connect(this->m_timerContextWatchdog, &QTimer::timeout, this, &MainWindow::timerBasedUpdates); + this->connect(this->m_timerCollectedCockpitUpdates, &QTimer::timeout, this, &MainWindow::sendCockpitUpdates); // start timers this->m_timerUpdateAircraftsInRange->start(10 * 1000); @@ -210,8 +184,10 @@ void MainWindow::initGuiSignals() Q_ASSERT(connected); connected = this->connect(this->ui->pb_MainWeather, SIGNAL(released()), this, SLOT(setMainPage())); Q_ASSERT(connected); - this->connect(this->ui->pb_MainKeypadOpacity050, &QPushButton::clicked, this, &MainWindow::changeWindowOpacity); - this->connect(this->ui->pb_MainKeypadOpacity100, &QPushButton::clicked, this, &MainWindow::changeWindowOpacity); + connected = this->connect(this->ui->pb_MainKeypadOpacity050, SIGNAL(clicked()), this, SLOT(changeWindowOpacity())); + Q_ASSERT(connected); + connected = this->connect(this->ui->pb_MainKeypadOpacity100, SIGNAL(clicked()), this, SLOT(changeWindowOpacity())); + Q_ASSERT(connected); // Sound buttons this->connect(this->ui->pb_SoundMute, &QPushButton::clicked, this, &MainWindow::audioVolumes); diff --git a/src/blackcore/context_network.cpp b/src/blackcore/context_network.cpp index 1cd3ead81..a7c246459 100644 --- a/src/blackcore/context_network.cpp +++ b/src/blackcore/context_network.cpp @@ -248,7 +248,8 @@ namespace BlackCore // send as message QString m("connection status changed "); m.append(this->m_network->connectionStatusToString(from)).append(" ").append(this->m_network->connectionStatusToString(to)); - msgs.push_back(CStatusMessage(CStatusMessage::TypeTrafficNetwork, CStatusMessage::SeverityInfo, m)); + msgs.push_back(CStatusMessage(CStatusMessage::TypeTrafficNetwork, + to == INetwork::DisconnectedError ? CStatusMessage::SeverityError : CStatusMessage::SeverityInfo, m)); emit this->statusMessage(msgs[0]); // send as own signal diff --git a/src/blackcore/context_settings.cpp b/src/blackcore/context_settings.cpp index fa2fe0f97..5372d8297 100644 --- a/src/blackcore/context_settings.cpp +++ b/src/blackcore/context_settings.cpp @@ -22,14 +22,12 @@ namespace BlackCore // create some dummy settings // this would actually be reading the settings from disk .. - this->m_settingsNetwork.setCurrentNetworkServer( - CServer("Testserver", "Client project testserver", "vatsim-germany.org", 6809, - CUser("guest", "Guest Client project", "", "guest"))); + this->m_settingsNetwork.setCurrentNetworkServer(CServer("Testserver", "Client project testserver", "vatsim-germany.org", 6809, CUser("guest", "Guest Client project", "", "guest"))); this->m_settingsNetwork.addTrafficNetworkServer(this->m_settingsNetwork.getCurrentNetworkServer()); - this->m_settingsNetwork.addTrafficNetworkServer( - CServer("Europe C2", "Real VATSIM Server", "88.198.19.202", 6809, - CUser("vatsimid", "Black Client", "", "vatsimpw")) - ); + this->m_settingsNetwork.addTrafficNetworkServer(CServer("Europe C2", "VATSIM Server", "88.198.19.202", 6809, CUser("vatsimid", "Black Client", "", "vatsimpw"))); + this->m_settingsNetwork.addTrafficNetworkServer(CServer("Europe CC", "VATSIM Server", "5.9.155.43", 6809, CUser("vatsimid", "Black Client", "", "vatsimpw"))); + this->m_settingsNetwork.addTrafficNetworkServer(CServer("UK", "VATSIM Server", "109.169.48.148", 6809, CUser("vatsimid", "Black Client", "", "vatsimpw"))); + this->m_settingsNetwork.addTrafficNetworkServer(CServer("USA-W", "VATSIM Server", "64.151.108.52", 6809, CUser("vatsimid", "Black Client", "", "vatsimpw"))); } /* diff --git a/src/blackcore/network_vatlib.cpp b/src/blackcore/network_vatlib.cpp index dc459c37c..ad02f9bc8 100644 --- a/src/blackcore/network_vatlib.cpp +++ b/src/blackcore/network_vatlib.cpp @@ -120,7 +120,7 @@ namespace BlackCore { try { - if (m_net->IsValid() && m_net->IsSessionExists()) + if (m_net->IsValid() && m_net->IsSessionExists() && isConnected()) { if (this->m_loginMode == LoginAsObserver) { @@ -271,6 +271,10 @@ namespace BlackCore info); } m_net->ConnectAndLogon(); + if (! m_updateTimer.isActive()) + { + m_updateTimer.start(c_updateIntervalMsec); + } } catch (...) { @@ -283,6 +287,7 @@ namespace BlackCore { try { + m_updateTimer.stop(); m_net->LogoffAndDisconnect(c_logoffTimeoutSec); } catch (...) { exceptionDispatcher(Q_FUNC_INFO); } @@ -297,21 +302,11 @@ namespace BlackCore { m_ownAircraft.setPosition(position); m_ownAircraft.setAltitude(altitude); - - if (! m_updateTimer.isActive()) - { - m_updateTimer.start(c_updateIntervalMsec); - } } void CNetworkVatlib::setOwnAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &situation) { m_ownAircraft.setSituation(situation); - - if (! m_updateTimer.isActive()) - { - m_updateTimer.start(c_updateIntervalMsec); - } } void CNetworkVatlib::setOwnAircraftAvionics(const BlackMisc::Aviation::CComSystem &com1, const BlackMisc::Aviation::CComSystem &com2, diff --git a/src/blackmisc/avaircraft.cpp b/src/blackmisc/avaircraft.cpp index c22ba7609..eb35a6291 100644 --- a/src/blackmisc/avaircraft.cpp +++ b/src/blackmisc/avaircraft.cpp @@ -124,15 +124,32 @@ namespace BlackMisc return BlackMisc::calculateHash(hashs, "CAircraft"); } + /* + * metaTypeId + */ + int CAircraft::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAircraft::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + /* * Compare */ - int CAircraft::compare(const QVariant &qv) const + int CAircraft::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - CAircraft aircraft = qv.value(); - return this->getCallsign().compare(aircraft.getCallsign()); + const auto &other = static_cast(otherBase); + + return this->getCallsign().asString().compare(other.getCallsign().asString(), Qt::CaseInsensitive); } /* diff --git a/src/blackmisc/avaircraft.h b/src/blackmisc/avaircraft.h index ec0de50e9..df248cd36 100644 --- a/src/blackmisc/avaircraft.h +++ b/src/blackmisc/avaircraft.h @@ -278,11 +278,6 @@ namespace BlackMisc */ virtual uint getValueHash() const; - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - /*! * \brief Register metadata */ @@ -337,6 +332,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avaircrafticao.cpp b/src/blackmisc/avaircrafticao.cpp index f5ea876c0..4609465e4 100644 --- a/src/blackmisc/avaircrafticao.cpp +++ b/src/blackmisc/avaircrafticao.cpp @@ -1,5 +1,6 @@ #include "avaircrafticao.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -19,6 +20,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CAircraftIcao::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAircraftIcao::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CAircraftIcao::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_designator, this->m_color, this->m_airline, this->m_livery); + const auto rhs = std::tie(other.m_designator, other.m_color, other.m_airline, other.m_livery); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/avaircrafticao.h b/src/blackmisc/avaircrafticao.h index 7011fcc57..046cd2167 100644 --- a/src/blackmisc/avaircrafticao.h +++ b/src/blackmisc/avaircrafticao.h @@ -214,6 +214,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avaircraftsituation.cpp b/src/blackmisc/avaircraftsituation.cpp index aae2813b1..c0febe914 100644 --- a/src/blackmisc/avaircraftsituation.cpp +++ b/src/blackmisc/avaircraftsituation.cpp @@ -23,6 +23,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CAircraftSituation::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAircraftSituation::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CAircraftSituation::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/avaircraftsituation.h b/src/blackmisc/avaircraftsituation.h index b27603fe1..068d1275e 100644 --- a/src/blackmisc/avaircraftsituation.h +++ b/src/blackmisc/avaircraftsituation.h @@ -233,6 +233,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avaltitude.cpp b/src/blackmisc/avaltitude.cpp index 789d2447b..fd932668d 100644 --- a/src/blackmisc/avaltitude.cpp +++ b/src/blackmisc/avaltitude.cpp @@ -58,26 +58,36 @@ namespace BlackMisc return !((*this) == other); } + /* + * metaTypeId + */ + int CAltitude::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAltitude::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CLength::isA(metaTypeId); + } + /* * Compare */ - int CAltitude::compare(const QVariant &qv) const + int CAltitude::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert() || qv.canConvert()); - Q_ASSERT(qv.isValid() && !qv.isNull()); - if (qv.canConvert()) - { - CAltitude other = qv.value(); - if (this->isMeanSeaLevel() && other.isAboveGroundLevel()) return 1; - if (this->isAboveGroundLevel() && other.isMeanSeaLevel()) return -1; - return this->compare(other); - } - else if (qv.canConvert()) - { - return this->compare(qv.value()); - } - qFatal("Invalid comparison"); - return 0; // just for compiler + const auto &other = static_cast(otherBase); + + if (this->isMeanSeaLevel() && other.isAboveGroundLevel()) { return 1; } + if (this->isAboveGroundLevel() && other.isMeanSeaLevel()) { return -1; } + if (*this < other) { return -1; } + if (*this > other) { return 1; } + return 0; } /* diff --git a/src/blackmisc/avaltitude.h b/src/blackmisc/avaltitude.h index 8a957c92a..48b79682d 100644 --- a/src/blackmisc/avaltitude.h +++ b/src/blackmisc/avaltitude.h @@ -39,6 +39,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument @@ -122,17 +137,6 @@ namespace BlackMisc return m_datum; } - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - - /*! - * \todo this is a hack, to avoid hiding inherited names in CPhysicalQuantity - * (see Effective C++ item 33) CPhysicalQuantity::compare is the real culprit - */ - int compare(const CLength &other) const { return static_cast(this)->compare(other); } - /*! * \brief Register metadata */ diff --git a/src/blackmisc/avatcstation.cpp b/src/blackmisc/avatcstation.cpp index e5d8d05e9..42c30bcf4 100644 --- a/src/blackmisc/avatcstation.cpp +++ b/src/blackmisc/avatcstation.cpp @@ -429,15 +429,32 @@ namespace BlackMisc } } + /* + * metaTypeId + */ + int CAtcStation::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAtcStation::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + /* * Compare */ - int CAtcStation::compare(const QVariant &qv) const + int CAtcStation::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - CAtcStation atc = qv.value(); - return this->getCallsign().compare(atc.getCallsign()); + const auto &other = static_cast(otherBase); + + return this->getCallsign().asString().compare(other.getCallsign().asString(), Qt::CaseInsensitive); } /* diff --git a/src/blackmisc/avatcstation.h b/src/blackmisc/avatcstation.h index 801411ec7..7c93e8648 100644 --- a/src/blackmisc/avatcstation.h +++ b/src/blackmisc/avatcstation.h @@ -453,11 +453,6 @@ namespace BlackMisc */ static void registerMetadata(); - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - protected: /*! * \brief Meaningful string representation @@ -466,6 +461,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avcallsign.cpp b/src/blackmisc/avcallsign.cpp index 5dbc48f72..460f871ab 100644 --- a/src/blackmisc/avcallsign.cpp +++ b/src/blackmisc/avcallsign.cpp @@ -98,21 +98,31 @@ namespace BlackMisc } /* - * Compare + * metaTypeId */ - int CCallsign::compare(const QVariant &qv) const + int CCallsign::getMetaTypeId() const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - return this->compare(qv.value()); + return qMetaTypeId(); + } + + /* + * is a + */ + bool CCallsign::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); } /* * Compare */ - int CCallsign::compare(const CCallsign &callsign) const + int CCallsign::compareImpl(const CValueObject &otherBase) const { - return this->m_callsign.compare(callsign.asString(), Qt::CaseInsensitive); + const auto &other = static_cast(otherBase); + + return this->m_callsign.compare(other.asString(), Qt::CaseInsensitive); } /* diff --git a/src/blackmisc/avcallsign.h b/src/blackmisc/avcallsign.h index 538466cdb..b237b4fca 100644 --- a/src/blackmisc/avcallsign.h +++ b/src/blackmisc/avcallsign.h @@ -121,17 +121,6 @@ namespace BlackMisc */ virtual uint getValueHash() const; - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - - /*! - * Compare with other callsign - * \return - */ - virtual int compare(const CCallsign &callsign) const; - /*! * \brief Register metadata */ @@ -145,6 +134,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/avinformationmessage.cpp b/src/blackmisc/avinformationmessage.cpp index 26efcdfa5..be9a3324d 100644 --- a/src/blackmisc/avinformationmessage.cpp +++ b/src/blackmisc/avinformationmessage.cpp @@ -13,6 +13,36 @@ namespace BlackMisc return this->m_message; } + /* + * metaTypeId + */ + int CInformationMessage::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CInformationMessage::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CInformationMessage::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + if (this->m_type < other.m_type) { return -1; } + if (this->m_type > other.m_type) { return 1; } + return this->m_message.compare(other.m_message); + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/avinformationmessage.h b/src/blackmisc/avinformationmessage.h index f04484299..6a2db3acf 100644 --- a/src/blackmisc/avinformationmessage.h +++ b/src/blackmisc/avinformationmessage.h @@ -164,6 +164,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/aviobase.h b/src/blackmisc/aviobase.h index 1cac99ccd..160503b44 100644 --- a/src/blackmisc/aviobase.h +++ b/src/blackmisc/aviobase.h @@ -58,6 +58,26 @@ namespace BlackMisc return this->m_name == other.m_name; } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const { return 0; } + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const { return this->CValueObject::isA(metaTypeId); } + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const + { + Q_UNUSED(other); + qFatal("not implemented"); + return 0; + } + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/blackmiscfreefunctions.cpp b/src/blackmisc/blackmiscfreefunctions.cpp index 49abec738..2e70c2ac3 100644 --- a/src/blackmisc/blackmiscfreefunctions.cpp +++ b/src/blackmisc/blackmiscfreefunctions.cpp @@ -221,7 +221,7 @@ int BlackMisc:: compareQVariants(const QVariant &v1, const QVariant &v2) const CValueObject *cs2 = CValueObject::fromQVariant(v2); if (cs1 && cs2) { - return cs1->compare(v2); // Note, that I have to compare against QVariant + return compare(*cs1, *cs2); } } diff --git a/src/blackmisc/containerbase.h b/src/blackmisc/containerbase.h index 299581fa8..df6052cd2 100644 --- a/src/blackmisc/containerbase.h +++ b/src/blackmisc/containerbase.h @@ -152,6 +152,36 @@ namespace BlackMisc return str += "}"; } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const { return qMetaTypeId>(); } + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId>()) { return true; } + return CValueObject::isA(metaTypeId); + } + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &/*other*/) const + { + //const auto &o = static_cast(other); + //if (derived().size() < o.derived().size()) { return -1; } + //if (derived().size() > o.derived().size()) { return 1; } + //for (auto i1 = derived().begin(), i2 = o.derived().begin(); i1 != derived().end() && i2 != o.derived().end(); ++i1, ++i2) + //{ + // if (*i1 < *i2) { return -1; } + // if (*i1 > *i2) { return 1; } + //} + return 0; + } + virtual void marshallToDbus(QDBusArgument &argument) const { argument.beginArray(qMetaTypeId()); diff --git a/src/blackmisc/coordinategeodetic.cpp b/src/blackmisc/coordinategeodetic.cpp index ef6914f05..e3f09db00 100644 --- a/src/blackmisc/coordinategeodetic.cpp +++ b/src/blackmisc/coordinategeodetic.cpp @@ -25,6 +25,38 @@ namespace BlackMisc return s.arg(this->m_latitude.valueRoundedWithUnit(6, i18n)).arg(this->m_longitude.valueRoundedWithUnit(6, i18n)).arg(this->m_height.valueRoundedWithUnit(i18n)); } + /* + * metaTypeId + */ + int CCoordinateGeodetic::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CCoordinateGeodetic::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CCoordinateGeodetic::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + int cmp = compare(this->m_latitude, other.m_latitude); + if (cmp) { return cmp; } + cmp = compare(this->m_longitude, other.m_longitude); + if (cmp) { return cmp; } + return compare(this->m_height, other.m_height); + } + /* * Marshall to Dbus */ diff --git a/src/blackmisc/coordinategeodetic.h b/src/blackmisc/coordinategeodetic.h index 6c9efab22..9354d668d 100644 --- a/src/blackmisc/coordinategeodetic.h +++ b/src/blackmisc/coordinategeodetic.h @@ -82,6 +82,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus * \param argument diff --git a/src/blackmisc/geoearthangle.cpp b/src/blackmisc/geoearthangle.cpp index 456549858..4c0d56b4c 100644 --- a/src/blackmisc/geoearthangle.cpp +++ b/src/blackmisc/geoearthangle.cpp @@ -71,17 +71,34 @@ namespace BlackMisc return LATorLON(a); } + /* + * metaTypeId + */ + template int CEarthAngle::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CEarthAngle::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CAngle::isA(metaTypeId); + } + /* * Compare */ - template int CEarthAngle::compare(const QVariant &qv) const + template int CEarthAngle::compareImpl(const CValueObject &otherBase) const { - Q_ASSERT(qv.canConvert() || qv.canConvert()); - Q_ASSERT(qv.isValid() && !qv.isNull()); - if (qv.canConvert()) - return this->toAngle().compare(qv.value().toAngle()); - else - return this->toAngle().compare(qv.value()); + const auto &other = static_cast(otherBase); + + if (*this < other) { return -1; } + else if (*this > other) { return 1; } + else { return 0; } } // see here for the reason of thess forward instantiations diff --git a/src/blackmisc/geoearthangle.h b/src/blackmisc/geoearthangle.h index a2e5284b0..c695b98bc 100644 --- a/src/blackmisc/geoearthangle.h +++ b/src/blackmisc/geoearthangle.h @@ -45,6 +45,21 @@ namespace BlackMisc return this->valueRoundedWithUnit(BlackMisc::PhysicalQuantities::CAngleUnit::deg(), 6, i18n); } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument @@ -74,7 +89,7 @@ namespace BlackMisc * \param latOrLon * \return */ - bool operator==(const LATorLON &latOrLon) const + bool operator==(const CEarthAngle &latOrLon) const { return this->CAngle::operator ==(latOrLon); } @@ -84,7 +99,7 @@ namespace BlackMisc * \param latOrLon * \return */ - bool operator!=(const LATorLON &latOrLon) const + bool operator!=(const CEarthAngle &latOrLon) const { return this->CAngle::operator !=(latOrLon); } @@ -116,7 +131,7 @@ namespace BlackMisc * \param latOrLon * \return */ - bool operator >(const LATorLON &latOrLon) const + bool operator >(const CEarthAngle &latOrLon) const { return this->CAngle::operator >(latOrLon); } @@ -126,7 +141,7 @@ namespace BlackMisc * \param latOrLon * \return */ - bool operator <(const LATorLON &latOrLon) const + bool operator <(const CEarthAngle &latOrLon) const { return this->CAngle::operator >(latOrLon); } @@ -136,7 +151,7 @@ namespace BlackMisc * \param latOrLon * \return */ - bool operator <=(const LATorLON &latOrLon) const + bool operator <=(const CEarthAngle &latOrLon) const { return this->CAngle::operator <=(latOrLon); } @@ -146,7 +161,7 @@ namespace BlackMisc * \param latOrLon * \return */ - bool operator >=(const LATorLON &latOrLon) const + bool operator >=(const CEarthAngle &latOrLon) const { return this->CAngle::operator >=(latOrLon); } @@ -156,7 +171,7 @@ namespace BlackMisc * \param latOrLon * \return */ - LATorLON operator +(const LATorLON &latOrLon) const + LATorLON operator +(const CEarthAngle &latOrLon) const { LATorLON l(*this); l += latOrLon; @@ -168,27 +183,13 @@ namespace BlackMisc * \param latOrLon * \return */ - LATorLON operator -(const LATorLON &latOrLon) const + LATorLON operator -(const CEarthAngle &latOrLon) const { LATorLON l(*this); l -= latOrLon; return l; } - /*! - * \brief To angle - * \return - */ - BlackMisc::PhysicalQuantities::CAngle toAngle() const - { - return BlackMisc::PhysicalQuantities::CAngle(static_cast(*this)); - } - - /*! - * Compare - */ - int compare(const QVariant &qv) const; - /*! * Register metadata */ diff --git a/src/blackmisc/mathmatrixbase.cpp b/src/blackmisc/mathmatrixbase.cpp index 1ecfb4579..676500bb2 100644 --- a/src/blackmisc/mathmatrixbase.cpp +++ b/src/blackmisc/mathmatrixbase.cpp @@ -138,6 +138,42 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + template int CMatrixBase::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CMatrixBase::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + template int CMatrixBase::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + for (int r = 0; r < Rows; ++r) + { + for (int c = 0; c < Columns; ++c) + { + if (this->m_matrix(r, c) < other.m_matrix(r, c)) { return -1; } + if (this->m_matrix(r, c) > other.m_matrix(r, c)) { return 1; } + } + } + return 0; + } + /* * Hash */ diff --git a/src/blackmisc/mathmatrixbase.h b/src/blackmisc/mathmatrixbase.h index c373def3b..d06ad3c30 100644 --- a/src/blackmisc/mathmatrixbase.h +++ b/src/blackmisc/mathmatrixbase.h @@ -51,6 +51,21 @@ namespace BlackMisc */ QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus * \param argument diff --git a/src/blackmisc/mathvector3dbase.cpp b/src/blackmisc/mathvector3dbase.cpp index 6eb34e284..133eb3b66 100644 --- a/src/blackmisc/mathvector3dbase.cpp +++ b/src/blackmisc/mathvector3dbase.cpp @@ -8,6 +8,7 @@ #include "blackmisc/coordinateecef.h" #include "blackmisc/coordinatened.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -26,6 +27,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + template int CVector3DBase::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CVector3DBase::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + template int CVector3DBase::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_i, this->m_j, this->m_k); + const auto rhs = std::tie(other.m_i, other.m_j, other.m_k); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Vector to zero */ diff --git a/src/blackmisc/mathvector3dbase.h b/src/blackmisc/mathvector3dbase.h index 76efe48ff..2d65ebe15 100644 --- a/src/blackmisc/mathvector3dbase.h +++ b/src/blackmisc/mathvector3dbase.h @@ -80,6 +80,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Unmarshall from Dbus * \param argument diff --git a/src/blackmisc/nwserver.cpp b/src/blackmisc/nwserver.cpp index 0095d0ae5..195d54837 100644 --- a/src/blackmisc/nwserver.cpp +++ b/src/blackmisc/nwserver.cpp @@ -1,5 +1,6 @@ #include "nwserver.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -18,6 +19,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CServer::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CServer::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CServer::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_name, this->m_description, this->m_address, this->m_port); + const auto rhs = std::tie(other.m_name, other.m_description, other.m_address, other.m_port); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return compare(this->m_user, other.m_user); + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/nwserver.h b/src/blackmisc/nwserver.h index 7e95b3a2d..9e47ec84c 100644 --- a/src/blackmisc/nwserver.h +++ b/src/blackmisc/nwserver.h @@ -181,6 +181,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/nwtextmessage.cpp b/src/blackmisc/nwtextmessage.cpp index 9ac6867c7..a6786ed02 100644 --- a/src/blackmisc/nwtextmessage.cpp +++ b/src/blackmisc/nwtextmessage.cpp @@ -28,6 +28,34 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CTextMessage::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CTextMessage::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CTextMessage::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + return this->m_message.compare(other.m_message); + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/nwtextmessage.h b/src/blackmisc/nwtextmessage.h index b7576ed45..5b9a4bd62 100644 --- a/src/blackmisc/nwtextmessage.h +++ b/src/blackmisc/nwtextmessage.h @@ -234,6 +234,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/nwuser.cpp b/src/blackmisc/nwuser.cpp index 43c82221c..69e9aa41b 100644 --- a/src/blackmisc/nwuser.cpp +++ b/src/blackmisc/nwuser.cpp @@ -1,5 +1,6 @@ #include "nwuser.h" #include "blackmisc/blackmiscfreefunctions.h" +#include namespace BlackMisc { @@ -19,6 +20,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CUser::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CUser::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CUser::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_id, this->m_realname, this->m_email, this->m_password); + const auto rhs = std::tie(other.m_id, other.m_realname, other.m_email, other.m_password); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/nwuser.h b/src/blackmisc/nwuser.h index 20c5de54b..f28af504b 100644 --- a/src/blackmisc/nwuser.h +++ b/src/blackmisc/nwuser.h @@ -185,6 +185,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/pqbase.cpp b/src/blackmisc/pqbase.cpp index cef13d6c9..c9aac01ad 100644 --- a/src/blackmisc/pqbase.cpp +++ b/src/blackmisc/pqbase.cpp @@ -74,6 +74,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CMeasurementUnit::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CMeasurementUnit::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CMeasurementUnit::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /*! * \brief Register metadata of unit and quantity */ diff --git a/src/blackmisc/pqbase.h b/src/blackmisc/pqbase.h index 30b7860f7..e5e5a9b99 100644 --- a/src/blackmisc/pqbase.h +++ b/src/blackmisc/pqbase.h @@ -230,6 +230,21 @@ namespace BlackMisc return this->getSymbol(i18n); } + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus * \param argument diff --git a/src/blackmisc/pqphysicalquantity.cpp b/src/blackmisc/pqphysicalquantity.cpp index b8f52a4c0..27fcb2769 100644 --- a/src/blackmisc/pqphysicalquantity.cpp +++ b/src/blackmisc/pqphysicalquantity.cpp @@ -20,6 +20,16 @@ namespace BlackMisc // void } + /* + * Copy constructor + * (The implicitly generated copy constructor would suffice, but for what seems to be a bug in MSVC2010 template instantiation) + */ + template CPhysicalQuantity::CPhysicalQuantity(const CPhysicalQuantity &other) : + m_value(other.m_value), m_unit(other.m_unit) + { + // void + } + /* * Equal operator == */ @@ -266,22 +276,33 @@ namespace BlackMisc } /* - * Compare + * metaTypeId */ - template int CPhysicalQuantity::compare(const QVariant &qv) const + template int CPhysicalQuantity::getMetaTypeId() const { - Q_ASSERT(qv.canConvert()); - Q_ASSERT(!qv.isNull() && qv.isValid()); - return this->compare(qv.value()); + return qMetaTypeId(); + } + + /* + * is a + */ + template bool CPhysicalQuantity::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); } /* * Compare */ - template int CPhysicalQuantity::compare(const PQ &other) const + template int CPhysicalQuantity::compareImpl(const CValueObject &otherBase) const { - if (other == (*this)) return 0; - return ((*this) < other) ? -1 : 1; + const auto &other = static_cast(otherBase); + + if (*this < other) { return -1; } + else if (*this > other) { return 1; } + else { return 0; } } // see here for the reason of thess forward instantiations diff --git a/src/blackmisc/pqphysicalquantity.h b/src/blackmisc/pqphysicalquantity.h index 15fb2cc48..18ce23f68 100644 --- a/src/blackmisc/pqphysicalquantity.h +++ b/src/blackmisc/pqphysicalquantity.h @@ -61,6 +61,12 @@ namespace BlackMisc */ CPhysicalQuantity(double value, const MU &unit); + /*! + * \brief Copy constructor + * \param other + */ + CPhysicalQuantity(const CPhysicalQuantity &other); + /*! * \brief Rounded value as string * \param i18n @@ -68,6 +74,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + public: /*! * \brief Virtual destructor @@ -357,16 +378,6 @@ namespace BlackMisc * \brief Register metadata of unit and quantity */ static void registerMetadata(); - - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const QVariant &qv) const; - - /*! - * \copydoc BlackObject::compare - */ - virtual int compare(const PQ &other) const; }; } // namespace diff --git a/src/blackmisc/setnetwork.cpp b/src/blackmisc/setnetwork.cpp index 92a19a11b..560dd1e54 100644 --- a/src/blackmisc/setnetwork.cpp +++ b/src/blackmisc/setnetwork.cpp @@ -34,6 +34,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CSettingsNetwork::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CSettingsNetwork::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CSettingsNetwork::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/setnetwork.h b/src/blackmisc/setnetwork.h index b7af81f2e..4a9bb0775 100644 --- a/src/blackmisc/setnetwork.h +++ b/src/blackmisc/setnetwork.h @@ -132,6 +132,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/statusmessage.cpp b/src/blackmisc/statusmessage.cpp index 9160dae63..9501d1ba7 100644 --- a/src/blackmisc/statusmessage.cpp +++ b/src/blackmisc/statusmessage.cpp @@ -33,6 +33,36 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CStatusMessage::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CStatusMessage::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CStatusMessage::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + if (this->m_type < other.m_type) { return -1; } + if (this->m_type > other.m_type) { return 1; } + return this->m_message.compare(other.m_message); + } + /* * Metadata */ diff --git a/src/blackmisc/statusmessage.h b/src/blackmisc/statusmessage.h index d7fced67b..3b8054712 100644 --- a/src/blackmisc/statusmessage.h +++ b/src/blackmisc/statusmessage.h @@ -147,6 +147,21 @@ namespace BlackMisc * \return */ virtual QString convertToQString(bool i18n = false) const; + + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; }; } diff --git a/src/blackmisc/valuemap.cpp b/src/blackmisc/valuemap.cpp index 865c7122d..02bfd12cb 100644 --- a/src/blackmisc/valuemap.cpp +++ b/src/blackmisc/valuemap.cpp @@ -38,6 +38,33 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CValueMap::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CValueMap::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CValueMap::compareImpl(const CValueObject &/*otherBase*/) const + { + qFatal("not implemented"); + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/valuemap.h b/src/blackmisc/valuemap.h index be08dbf29..02f9a19f9 100644 --- a/src/blackmisc/valuemap.h +++ b/src/blackmisc/valuemap.h @@ -131,6 +131,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/valueobject.cpp b/src/blackmisc/valueobject.cpp index 0fd03beb2..47a4b2a36 100644 --- a/src/blackmisc/valueobject.cpp +++ b/src/blackmisc/valueobject.cpp @@ -87,11 +87,21 @@ namespace BlackMisc /* * Compare */ - int CValueObject::compare(const QVariant & /** qv **/) const + int compare(const CValueObject &v1, const CValueObject &v2) { - // not all classes have to implement this - qFatal("Property by index as string not implemented"); - return -1; // avoid compiler warning + if (v1.isA(v2.getMetaTypeId())) + { + return v2.compareImpl(v1) * -1; + } + else if (v2.isA(v1.getMetaTypeId())) + { + return v1.compareImpl(v2); + } + else + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Attempt to compare between instances of unrelated classes"); + return 0; + } } /*! diff --git a/src/blackmisc/valueobject.h b/src/blackmisc/valueobject.h index d38072bbd..e011272fc 100644 --- a/src/blackmisc/valueobject.h +++ b/src/blackmisc/valueobject.h @@ -141,6 +141,15 @@ namespace BlackMisc */ friend bool operator!=(const CValueObject &uc, const CValueMap &valueMap); + /*! + * Compares two instances of related classes + * and returns an integer less than, equal to, or greater than zero + * if v1 is less than, equal to, or greater than v2. + * \return + * \pre The runtime types of the two objects must be the same or related by inheritance. + */ + friend int compare(const CValueObject &v1, const CValueObject &v2); + public: /*! * \brief Virtual destructor @@ -179,15 +188,6 @@ namespace BlackMisc */ virtual uint getValueHash() const = 0; - /*! - * Compares with QVariant with this object - * and returns an integer less than, equal to, or greater than zero - * if this is less than, equal to, or greater than QVariant. - * \remarks allows sorting among QVariants, not all classes implement this - * \return - */ - virtual int compare(const QVariant &qv) const; - /*! * \brief Virtual method to return QVariant, used with DBUS QVariant lists * \return @@ -257,6 +257,30 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const = 0; + /*! + * \brief Returns the Qt meta type ID of this object. + * \return + */ + virtual int getMetaTypeId() const = 0; + + /*! + * \brief Returns true if this object is an instance of the class with the given meta type ID, + * or one of its subclasses. + * \param metaTypeId + * \return + */ + virtual bool isA(int metaTypeId) const { Q_UNUSED(metaTypeId); return false; } + + /*! + * \brief Compare this value with another value of the same type + * \param other + * \return Less than, equal to, or greater than zero if this is + * less than, equal to, or greather than other. + * \pre Other must have the same runtime type as the this object. + * \remark It is usually safer to use the friend function compare() instead. + */ + virtual int compareImpl(const CValueObject &other) const = 0; + /*! * \brief Marshall to DBus * \param argument diff --git a/src/blackmisc/vaudiodevice.cpp b/src/blackmisc/vaudiodevice.cpp index 7208d5c36..4bbd1411e 100644 --- a/src/blackmisc/vaudiodevice.cpp +++ b/src/blackmisc/vaudiodevice.cpp @@ -10,6 +10,7 @@ #include "vaudiodevice.h" #include "blackmisc/blackmiscfreefunctions.h" #include +#include namespace BlackMisc { @@ -90,6 +91,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CAudioDevice::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CAudioDevice::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return this->CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CAudioDevice::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(this->m_type, this->m_deviceIndex, this->m_deviceName, this->m_hostName); + const auto rhs = std::tie(other.m_type, other.m_deviceIndex, other.m_deviceName, other.m_hostName); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/vaudiodevice.h b/src/blackmisc/vaudiodevice.h index 159518f20..4b1fca4e7 100644 --- a/src/blackmisc/vaudiodevice.h +++ b/src/blackmisc/vaudiodevice.h @@ -126,6 +126,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/src/blackmisc/vvoiceroom.cpp b/src/blackmisc/vvoiceroom.cpp index 9cd73d191..4773b0cea 100644 --- a/src/blackmisc/vvoiceroom.cpp +++ b/src/blackmisc/vvoiceroom.cpp @@ -9,9 +9,9 @@ #include "vvoiceroom.h" #include "blackmisc/blackmiscfreefunctions.h" - #include #include +#include namespace BlackMisc { @@ -85,6 +85,39 @@ namespace BlackMisc return s; } + /* + * metaTypeId + */ + int CVoiceRoom::getMetaTypeId() const + { + return qMetaTypeId(); + } + + /* + * is a + */ + bool CVoiceRoom::isA(int metaTypeId) const + { + if (metaTypeId == qMetaTypeId()) { return true; } + + return CValueObject::isA(metaTypeId); + } + + /* + * Compare + */ + int CVoiceRoom::compareImpl(const CValueObject &otherBase) const + { + const auto &other = static_cast(otherBase); + + const auto lhs = std::tie(m_hostname, m_channel, m_connected, m_audioPlaying); + const auto rhs = std::tie(other.m_hostname, other.m_channel, other.m_connected, other.m_audioPlaying); + + if (lhs < rhs) { return -1; } + if (lhs > rhs) { return 1; } + return 0; + } + /* * Marshall to DBus */ diff --git a/src/blackmisc/vvoiceroom.h b/src/blackmisc/vvoiceroom.h index 681b8d1d8..eeafea823 100644 --- a/src/blackmisc/vvoiceroom.h +++ b/src/blackmisc/vvoiceroom.h @@ -166,6 +166,21 @@ namespace BlackMisc */ virtual QString convertToQString(bool i18n = false) const; + /*! + * \copydoc CValueObject::getMetaTypeId + */ + virtual int getMetaTypeId() const; + + /*! + * \copydoc CValueObject::isA + */ + virtual bool isA(int metaTypeId) const; + + /*! + * \copydoc CValueObject::compareImpl + */ + virtual int compareImpl(const CValueObject &other) const; + /*! * \brief Stream to DBus << * \param argument diff --git a/tests/blackmisc/testvariantandmap.cpp b/tests/blackmisc/testvariantandmap.cpp index 44e49c6c5..a9a145d18 100644 --- a/tests/blackmisc/testvariantandmap.cpp +++ b/tests/blackmisc/testvariantandmap.cpp @@ -46,6 +46,10 @@ namespace BlackMiscTest QVERIFY2(station1 == station1qv, "Station should be equal (QVariant)"); QVERIFY2(station2 == station1qv, "Station should be equal (QVariant)"); QVERIFY2(station3 != station1qv, "Station should be equal (QVariant)"); + + QVERIFY2(compare(station1, station1) == 0, "Station should be equal"); + QVERIFY2(compare(station1, station2) == 0, "Station should be equal"); + QVERIFY2(compare(station1, station3) != 0, "Station should not be equal"); } /*