File indexing completed on 2024-04-21 03:44:54

0001 /*
0002     SPDX-FileCopyrightText: 2004 Jeff Woods Jason Harris <jcwoods@bellsouth.net, jharris@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "ksalmanac.h"
0010 #include "kstarsdatetime.h"
0011 #include "ui_observinglist.h"
0012 #include "catalogsdb.h"
0013 
0014 #include <QAbstractTableModel>
0015 #include <QDialog>
0016 #include <QFrame>
0017 #include <QList>
0018 #include <QPixmap>
0019 #include <QTime>
0020 
0021 #include <functional>
0022 #include <memory>
0023 
0024 class QSortFilterProxyModel;
0025 class QStandardItem;
0026 class QStandardItemModel;
0027 class QTimer;
0028 
0029 class GeoLocation;
0030 class KSDssDownloader;
0031 class KStars;
0032 class KStarsDateTime;
0033 class ObsListPopupMenu;
0034 class SkyObject;
0035 class SkyPoint;
0036 
0037 class ObservingListUI : public QFrame, public Ui::ObservingList
0038 {
0039     Q_OBJECT
0040 
0041   public:
0042     explicit ObservingListUI(QWidget *parent);
0043 };
0044 
0045 /** @class ObservingList
0046     *Tool window for managing a custom list of objects.  The window
0047     *displays the Name, RA, Dec, mag, and type of each object in the list.
0048     *
0049     *By selecting an object in the list, you can perform a number of functions
0050     *on that object:
0051     *+ Center it in the display
0052     *+ Examine its Details Window
0053     *+ Point the telescope at it
0054     *+ Attach a custom icon or name label (TBD)
0055     *+ Attach a trail (solar system only) (TBD)
0056     *+ Open the AltVsTime tool
0057     *
0058     *The user can also save/load their observing lists, and can export
0059     *list data (TBD: as HTML table?  CSV format?  plain text?)
0060     *
0061     *The observing notes associated with the selected object are displayed
0062     *below the list.
0063     *
0064     *TODO:
0065     *+ Implement a "shaded" state, in which the UI is compressed to
0066     *  make it easier to float on the KStars window.  Displays only
0067     *  object names, and single-letter action buttons, and no user log.
0068     *+ Implement an InfoBox version (the ultimate shaded state)
0069     *
0070     *@short Tool for managing a custom list of objects
0071     *@author Jeff Woods, Jason Harris
0072     *@version 1.0
0073     */
0074 
0075 class ObservingList : public QDialog
0076 {
0077     Q_OBJECT
0078 
0079   public:
0080     ObservingList();
0081     virtual ~ObservingList() override = default;
0082 
0083     /** @return reference to the current observing list
0084             */
0085     QList<QSharedPointer<SkyObject>> &obsList() { return m_WishList; }
0086 
0087     /** @return reference to the current observing list
0088             */
0089     QList<QSharedPointer<SkyObject>> &sessionList() { return m_SessionList; }
0090 
0091     /** @return pointer to the currently-selected object in the observing list
0092             *@note if more than one object is selected, this function returns 0.
0093             */
0094     inline SkyObject *currentObject() const { return m_CurrentObject; }
0095 
0096     /** @short If the current list has unsaved changes, ask the user about saving it.
0097             *@note also clears the list in preparation of opening a new one
0098             */
0099     void saveCurrentList();
0100 
0101     /** @short Plot the SkyObject's Altitude vs Time in the AVTPlotWidget.
0102            *@p o pointer to the object to be plotted
0103            */
0104     void plot(SkyObject *o);
0105 
0106     /** @short Return the altitude of the given SkyObject for the given hour.
0107             *@p p pointer to the SkyObject
0108             *@p hour time at which altitude has to be found
0109             */
0110     double findAltitude(SkyPoint *p, double hour = 0);
0111 
0112     /** @short Sets the image parameters for the current object
0113             *@p o The passed object for setting the parameters
0114             */
0115     void setCurrentImage(const SkyObject *o);
0116 
0117     /**
0118          * @short Returns a path to the current image, or a writable image.
0119          */
0120     QString getCurrentImagePath();
0121 
0122     /** @short Save the user log text to a file.
0123             *@note the log is attached to the current object in obsList.
0124             */
0125     void saveCurrentUserLog();
0126 
0127     /** @short decides on whether to enable the SaveImages button or not
0128             */
0129     void setSaveImagesButton();
0130 
0131     /** @short This is the declaration of the event filter function
0132          * which is installed on the KImageFilePreview and the TabeView
0133          */
0134     bool eventFilter(QObject *obj, QEvent *event) override;
0135 
0136     /** @short saves a thumbnail image for the details dialog
0137          * from the downloaded image
0138          */
0139     void saveThumbImage();
0140 
0141     QString getTime(const SkyObject *o) const;
0142 
0143     QTime scheduledTime(SkyObject *o) const;
0144 
0145     void setTime(const SkyObject *o, QTime t);
0146 
0147     inline GeoLocation *geoLocation() { return geo; }
0148 
0149     inline KStarsDateTime dateTime() const { return dt; }
0150 
0151     /** @short return the object with the name as the passed
0152          * QString from the Session List, return null otherwise
0153          */
0154     SkyObject *findObjectByName(QString name);
0155 
0156     /** @short make a selection in the session view
0157          */
0158     void selectObject(const SkyObject *o);
0159 
0160     /** @short set the default image in the image preview.
0161          */
0162     void setDefaultImage();
0163 
0164     /** @short get object name. If sky object has no name, generate a name based on catalog number.
0165          * @param o pointer to the sky object
0166          * @param translated set to true if the translated name is required.
0167          */
0168     QString getObjectName(const SkyObject *o, bool translated = true);
0169 
0170     /**
0171          * @return true if the selected list contains the given object
0172          */
0173     inline bool contains(const SkyObject *o, bool session = false) { return bool(findObject(o, session)); }
0174 
0175     QSharedPointer<SkyObject> findObject(const SkyObject *o, bool session = false);
0176 
0177   public slots:
0178     /** @short add a new object to list
0179             *@p o pointer to the object to add to the list
0180             *@p session flag toggle adding the object to the session list
0181             *@p update flag to toggle the call of slotSaveList
0182             */
0183     void slotAddObject(const SkyObject *o = nullptr, bool session = false, bool update = false);
0184 
0185     /** @short Remove skyobjects which are highlighted in the
0186             *observing list tool from the observing list.
0187             */
0188     void slotRemoveSelectedObjects();
0189 
0190     /** @short Remove skyobject from the observing list.
0191             *@p o pointer to the SkyObject to be removed.
0192             *@p session flag to tell it whether to remove the object
0193             *from the sessionlist or from the wishlist
0194             *@p update flag to toggle the call of slotSaveList
0195             *Use SkyMap::clickedObject() if o is nullptr (default)
0196             */
0197     void slotRemoveObject(const SkyObject *o = nullptr, bool session = false, bool update = false);
0198 
0199     /** @short center the selected object in the display
0200             */
0201     void slotCenterObject();
0202 
0203     /** @short slew the telescope to the selected object
0204             */
0205     void slotSlewToObject();
0206 
0207     /**
0208          * @brief slotAddToEkosScheduler Add object to Ekos scheduler
0209          */
0210     void slotAddToEkosScheduler();
0211 
0212     /** @short Show the details window for the selected object
0213             */
0214     void slotDetails();
0215 
0216     /** @short Show the Altitude vs Time for selecteld objects
0217             */
0218     void slotAVT();
0219 
0220     /** @short Open the WUT dialog
0221         */
0222     void slotWUT();
0223 
0224     /** @short Add the object to the Session List
0225             */
0226     void slotAddToSession();
0227 
0228     /** @short Open the Find Dialog
0229             */
0230     void slotFind();
0231 
0232     /** @short Batch add from a list of objects */
0233     void slotBatchAdd();
0234 
0235     /** @short Tasks needed when changing the selected object
0236             *Save the user log of the previous selected object,
0237             *find the new selected object in the obsList, and
0238             *show the notes associated with the new selected object
0239             */
0240     void slotNewSelection();
0241 
0242     /** @short load an observing list from disk.
0243             */
0244     void slotOpenList();
0245 
0246     /** @short save the current observing list to disk.
0247             */
0248     void slotSaveList();
0249 
0250     /** @short Load the Wish list from disk.
0251             */
0252     void slotLoadWishList();
0253 
0254     /** @short save the current observing session plan to disk, specify filename.
0255             */
0256     void slotSaveSessionAs(bool nativeSave = true);
0257 
0258     /** @short save the current session
0259             */
0260     void slotSaveSession(bool nativeSave = true);
0261 
0262     /** @short construct a new observing list using the wizard.
0263             */
0264     void slotWizard();
0265 
0266     /** @short toggle the setEnabled flags according to current view
0267             *set the m_currentItem to nullptr and clear selections
0268             *@p index captures the integer value sent by the signal
0269             *which is the currentIndex of the table
0270             */
0271     void slotChangeTab(int index);
0272 
0273     /** @short Opens the Location dialog to set the GeoLocation
0274             *for the sessionlist.
0275             */
0276     void slotLocation();
0277 
0278     /** @short Updates the tableviews for the new geolocation and date
0279             */
0280     void slotUpdate();
0281 
0282     /** @short Takes the time from the QTimeEdit box and sets it as the
0283             *time parameter in the tableview of the SessionList.
0284             */
0285     void slotSetTime();
0286 
0287     /** @short Downloads the corresponding DSS or SDSS image from the web and
0288             *displays it
0289             */
0290     void slotGetImage(bool _dss = false, const SkyObject *o = nullptr);
0291 
0292     void slotSearchImage();
0293 
0294     /** @short Downloads the images of all the objects in the session list
0295             *Note: This downloads the SDSS image, checks if the size is > default image
0296             *and gets the DSS image if that's the case
0297             */
0298     void slotSaveAllImages();
0299 
0300     /** @short saves the image synchronously from a given URL into a given file
0301             *@p url the url from which the image has to be downloaded
0302             *@p filename the file onto which the url has to be copied to
0303             *NOTE: This is not a generic image saver, it is specific to the current object
0304             */
0305     void saveImage(QUrl url, QString filename, const SkyObject *o = nullptr);
0306 
0307     /** @short Shows the image in a ImageViewer window.
0308             */
0309     void slotImageViewer();
0310 
0311     /** @short Remove the current image
0312             */
0313     void slotDeleteCurrentImage();
0314 
0315     /** @short Removes all the save DSS/SDSS images from the disk.
0316             */
0317     void slotDeleteAllImages();
0318 
0319     /** @short download the DSS image and show it
0320             */
0321     void slotDSS() { slotGetImage(true); }
0322 
0323     /**
0324          *@short Present the user with options to get the right DSS image for the job
0325          */
0326     void slotCustomDSS();
0327 
0328     /** @short Export a target list to the oal compliant format
0329             */
0330     void slotOALExport();
0331 
0332     void slotAddVisibleObj();
0333 
0334     /**
0335          * @short Show the eyepiece field view
0336          */
0337     void slotEyepieceView();
0338 
0339     /**
0340          * @short Recalculate and update the values of the altitude in the wishlist for the current time
0341          */
0342     void slotUpdateAltitudes();
0343 
0344     /**
0345          * @brief slotClearList Remove all objects from current list
0346          */
0347     void slotClearList();
0348 
0349   protected slots:
0350     void slotClose();
0351     void downloadReady(bool success);
0352 
0353   protected:
0354     void showEvent(QShowEvent *) override;
0355 
0356   private:
0357     /**
0358          * @short Return the active list
0359          * @return The session list or the wish list depending on which tab is currently being viewed.
0360          */
0361     inline QList<QSharedPointer<SkyObject>> &getActiveList() { return ((sessionView) ? m_SessionList : m_WishList); }
0362 
0363     /**
0364          * @short Return the active itemmodel
0365          * @return the session model or the wishlist model depending on which tab is currently being viewed.
0366          */
0367     inline QStandardItemModel *getActiveModel() const { return (sessionView ? m_SessionModel.get() : m_WishListModel.get()); }
0368 
0369     /**
0370          * @short Return the active sort model
0371          * @return the session sort model or the wishlist sort model depending on which tab is currently being viewed.
0372          */
0373     inline QSortFilterProxyModel *getActiveSortModel() const
0374     {
0375         return (sessionView ? m_SessionSortModel.get() : m_WishListSortModel.get());
0376     }
0377 
0378     /**
0379          * @short Return the active view
0380          * @return the active view in the UI -- session view or wishlist view depending on which one is active.
0381          */
0382     inline QTableView *getActiveView() const { return ((sessionView) ? (ui->SessionView) : (ui->WishListView)); }
0383 
0384     /**
0385          * @short Get the currently selected item indexes
0386          * @return a QModelIndexList containing the selected rows in the active QTableView
0387          */
0388     inline QModelIndexList getSelectedItems() const { return getActiveView()->selectionModel()->selectedRows(); }
0389 
0390     std::unique_ptr<KSAlmanac> ksal;
0391     ObservingListUI *ui { nullptr };
0392     QList<QSharedPointer<SkyObject>> m_WishList, m_SessionList;
0393     SkyObject *LogObject { nullptr };
0394     SkyObject *m_CurrentObject { nullptr };
0395     bool isModified { false };
0396     bool sessionView { false };
0397     bool dss { false };
0398     bool singleSelection { false };
0399     bool showScope { false };
0400     bool noSelection { false };
0401     QString m_listFileName, m_currentImageFileName, m_currentThumbImageFileName;
0402     KStarsDateTime dt;
0403     GeoLocation *geo { nullptr };
0404     std::unique_ptr<QStandardItemModel> m_WishListModel;
0405     std::unique_ptr<QStandardItemModel> m_SessionModel;
0406     std::unique_ptr<QSortFilterProxyModel> m_WishListSortModel;
0407     std::unique_ptr<QSortFilterProxyModel> m_SessionSortModel;
0408     QHash<QString, QTime> TimeHash;
0409     std::unique_ptr<ObsListPopupMenu> pmenu;
0410     KSDssDownloader *m_dl { nullptr };
0411     QHash<SkyObject *, QPixmap> ImagePreviewHash;
0412     QPixmap m_NoImagePixmap;
0413     QTimer *m_altitudeUpdater { nullptr };
0414     std::function<QStandardItem *(const SkyPoint &)> m_altCostHelper;
0415     bool m_initialWishlistLoad { false };
0416     CatalogsDB::DBManager m_manager;
0417 };