File indexing completed on 2024-04-28 15:09:11

0001 /*
0002     SPDX-FileCopyrightText: 2022 Jasem Mutlaq <mutlaqja@ikarustech.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "ui_opticaltrains.h"
0010 
0011 #include <indi/indifilterwheel.h>
0012 #include <indi/indifocuser.h>
0013 
0014 #include <QDialog>
0015 #include <QSqlDatabase>
0016 #include <QQueue>
0017 #include <QPointer>
0018 
0019 class QSqlTableModel;
0020 class ComboDelegate;
0021 class NotEditableDelegate;
0022 class DoubleDelegate;
0023 class IntegerDelegate;
0024 class ToggleDelegate;
0025 class ProfileInfo;
0026 
0027 namespace Ekos
0028 {
0029 
0030 class OpticalTrainManager : public QDialog, public Ui::OpticalTrain
0031 {
0032         Q_OBJECT
0033         Q_PROPERTY(QStringList trainNames READ getTrainNames)
0034 
0035     public:
0036 
0037         static OpticalTrainManager *Instance();
0038         static void release();
0039 
0040         typedef enum
0041         {
0042             Mount,
0043             Camera,
0044             Rotator,
0045             GuideVia,
0046             DustCap,
0047             Scope,
0048             FilterWheel,
0049             Focuser,
0050             Reducer,
0051             LightBox
0052         } Role;
0053 
0054         void setProfile(const QSharedPointer<ProfileInfo> &profile);
0055         void checkOpticalTrains();
0056 
0057         bool exists(uint8_t id) const;
0058         const QVariantMap getOpticalTrain(uint8_t id) const;
0059         const QVariantMap getOpticalTrain(const QString &name) const;
0060         const QList<QVariantMap> &getOpticalTrains() const
0061         {
0062             return m_OpticalTrains;
0063         }
0064         const QStringList &getTrainNames() const
0065         {
0066             return m_TrainNames;
0067         }
0068 
0069         void addOpticalTrain(const QJsonObject &value);
0070 
0071         /**
0072          * @brief Select an optical train and fill the field values in the train editor with the
0073          *        appropriate values of the selected optical train.
0074          * @param item optical train list item
0075          * @return true if optical train found
0076          */
0077         bool selectOpticalTrain(QListWidgetItem *item);
0078 
0079         /**
0080          * @brief findTrainContainingDevice Search optical trains for device match a specific role.
0081          * @param name Device Name
0082          * @param role Device Role
0083          * @return Train containing device name matching the specified role
0084          */
0085         QString findTrainContainingDevice(const QString &name, Role role);
0086 
0087         /**
0088          * @brief Select an optical train and fill the field values in the train editor with the
0089          *        appropriate values of the selected optical train.
0090          * @param name optical train name
0091          * @return true if optical train found
0092          */
0093         bool selectOpticalTrain(const QString &name);
0094 
0095         /**
0096          * @brief Show the dialog and select an optical train for editing.
0097          * @param name optical train name
0098          */
0099         void openEditor(const QString &name);
0100 
0101         /**
0102          * @brief setOpticalTrainValue Set specific field of optical train
0103          * @param name Name of optical field
0104          * @param field Name of field
0105          * @param value Value of field
0106          * @return True if set is successful, false otherwise.
0107          */
0108         bool setOpticalTrainValue(const QString &name, const QString &field, const QVariant &value);
0109 
0110         /**
0111          * @brief Change the name of the currently selected optical train to a new value
0112          * @param name new train name
0113          */
0114         void renameCurrentOpticalTrain(const QString &name);
0115 
0116         /**
0117          * @brief setOpticalTrain Replaces optical train matching the name of the passed train.
0118          * @param train Train information, including name and database id
0119          * @return True if train is successfully updated in the database.
0120          */
0121         bool setOpticalTrain(const QJsonObject &train);
0122 
0123         /**
0124          * @brief removeOpticalTrain Remove optical train from database and all associated settings
0125          * @param name name if the optical train to remove
0126          * @return True if successful, false if id is not found.
0127          */
0128         bool removeOpticalTrain(const QString &name);
0129 
0130         void refreshModel();
0131         void refreshTrains();
0132         void refreshOpticalElements();
0133         void reset();
0134         /**
0135          * @brief syncDevices Sync delegates and then update model accordingly.
0136          */
0137         void syncDevices();
0138 
0139         /**
0140          * @brief syncActiveDevices Syncs ACTIVE_DEVICES in INDI as per the optical train settings.
0141          */
0142         void syncActiveDevices();
0143 
0144         /**
0145          * @brief getGenericDevice Find Generic Device matching given Role in the given train
0146          * @param train Train Name
0147          * @param role Device Role
0148          * @param generic Generic Device. If found, the pointer is pointing to GenericDevice
0149          * @return True if found, false if not found.
0150          */
0151         bool getGenericDevice(const QString &train, Role role, QSharedPointer<ISD::GenericDevice> &generic);
0152 
0153         /**
0154          * @brief syncActiveProperties Since ACTIVE_DEVICE properties
0155          * @param train Train map
0156          * @param device Generic device
0157          */
0158         void syncActiveProperties(const QVariantMap &train, const QSharedPointer<ISD::GenericDevice> &device);
0159 
0160         /**
0161          * @brief id Get database ID for a given train
0162          * @param name Name of train
0163          * @return ID if exists, or -1 if not found.
0164          */
0165         int id(const QString &name) const;
0166 
0167         /**
0168          * @brief name Get database name for a given name
0169          * @param id database ID for the train to get
0170          * @return Train name, or empty string if not found.
0171          */
0172         QString name(int id) const;
0173 
0174         ISD::Mount *getMount(const QString &name);
0175         ISD::DustCap *getDustCap(const QString &name);
0176         ISD::LightBox *getLightBox(const QString &name);
0177         QJsonObject getScope(const QString &name);
0178         double getReducer(const QString &name);
0179         ISD::Rotator *getRotator(const QString &name);
0180         ISD::Focuser *getFocuser(const QString &name);
0181         ISD::FilterWheel *getFilterWheel(const QString &name);
0182         ISD::Camera *getCamera(const QString &name);
0183         ISD::Guider *getGuider(const QString &name);
0184         ISD::AdaptiveOptics *getAdaptiveOptics(const QString &name);
0185 
0186     signals:
0187         void updated();
0188         void configurationRequested(bool show);
0189 
0190     protected:
0191         void initModel();
0192         QStringList getMissingDevices() const;
0193 
0194     private slots:
0195         /**
0196          * @brief Update an element value in the currently selected optical train
0197          * @param cb combo box holding the new value
0198          * @param element element name
0199          */
0200         void updateOpticalTrainValue(QComboBox *cb, const QString &element);
0201         /**
0202          * @brief Update an element value in the currently selected optical train
0203          * @param value the new value
0204          * @param element element name
0205          */
0206         void updateOpticalTrainValue(double value, const QString &element);
0207 
0208     private:
0209 
0210         OpticalTrainManager();
0211         static OpticalTrainManager *m_Instance;
0212 
0213         /**
0214          * @brief generateOpticalTrains Automatically generate optical trains based on the current profile information.
0215          * This happens when users use the tool for the first time.
0216          */
0217         void generateOpticalTrains();
0218 
0219         /**
0220          * @brief Add a new optical train with the given name
0221          * @param index train index (0, 1, 2..etc)
0222          * @param name train name
0223          * @return unique train name
0224          */
0225         QString addOpticalTrain(uint8_t index, const QString &name);
0226 
0227         void checkMissingDevices();
0228 
0229         /**
0230            * @brief syncDelegatesToDevices Parses INDI devices and updates delegates accordingly.
0231            * @return True if all devices synced. False if no new devices synced.
0232            */
0233         bool syncDelegatesToDevices();
0234 
0235         /**
0236          * @brief Create a unique train name
0237          * @param name original train name
0238          * @return name, eventually added (i) to make the train name unique
0239          */
0240         QString uniqueTrainName(QString name);
0241 
0242         QSharedPointer<ProfileInfo> m_Profile;
0243         QList<QVariantMap> m_OpticalTrains;
0244         QTimer m_CheckMissingDevicesTimer;
0245         QTimer m_DelegateTimer;
0246         QVariantMap *m_CurrentOpticalTrain = nullptr;
0247 
0248         // make changes persistent
0249         bool m_Persistent = false;
0250 
0251         // Table model
0252         QSqlTableModel *m_OpticalTrainsModel = { nullptr };
0253 
0254         QStringList m_TrainNames;
0255         // Device names
0256         QStringList m_MountNames;
0257         QStringList m_DustCapNames;
0258         QStringList m_LightBoxNames;
0259         QStringList m_ScopeNames;
0260         QStringList m_ReducerNames;
0261         QStringList m_RotatorNames;
0262         QStringList m_FocuserNames;
0263         QStringList m_FilterWheelNames;
0264         QStringList m_CameraNames;
0265         QStringList m_GuiderNames;
0266 };
0267 
0268 }