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

0001 /*
0002     SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "ui_finddialog.h"
0010 #include "catalogsdb.h"
0011 
0012 #include <QDialog>
0013 #include <QKeyEvent>
0014 
0015 class QTimer;
0016 class QComboBox;
0017 class QStringListModel;
0018 class QSortFilterProxyModel;
0019 class SkyObjectListModel;
0020 class SkyObject;
0021 class DeepSkyObject;
0022 
0023 class FindDialogUI : public QFrame, public Ui::FindDialog
0024 {
0025     Q_OBJECT
0026   public:
0027     explicit FindDialogUI(QWidget *parent = nullptr);
0028 };
0029 
0030 /**
0031  * @class FindDialog
0032  * Dialog window for finding SkyObjects by name.  The dialog contains
0033  * a QListBox showing the list of named objects, a QLineEdit for filtering
0034  * the list by name, and a QCombobox for filtering the list by object type.
0035  *
0036  * 2018-12 JM: The dialog is a singleton since we need a single instance in KStars.
0037  * @short Find Object Dialog
0038  * @author Jason Harris
0039  * @author Jasem Mutlaq
0040  * @version 1.1
0041  */
0042 class FindDialog : public QDialog
0043 {
0044     Q_OBJECT
0045   public:
0046     static FindDialog *Instance();
0047 
0048     /**
0049      * @return the target object (need not be the same as currently selected object!)
0050      *
0051      * @note Avoid using selectedObject()
0052      */
0053     inline SkyObject *targetObject() { return m_targetObject; }
0054 
0055 
0056     /**
0057      * @brief exec overrides base's QDialog::exec() to provide a parent widget.
0058      * @param parent is the widget to position the FindDialog instance againt.
0059      * @return QDialog::exec() result.
0060      */
0061     int execWithParent(QWidget* parent = nullptr);
0062 
0063     // Backend methods
0064     /**
0065      * @short Do some post processing on the search text to interpret what the user meant
0066      * This could include replacing text like "m93" with "m 93"
0067      */
0068     static QString processSearchText(QString searchText);
0069 
0070     // FIXME: Move this method to a better place, maybe into the NameResolver
0071     /**
0072      * @short Resolves an object using the internet and adds it to the database
0073      * @note Can only be called when KStars is fully initialized
0074      * @return a pointer to the DeepSkyObject (instance managed by internetResolvedComponent) if successful, nullptr otherwise
0075      */
0076     static CatalogObject *resolveAndAdd(CatalogsDB::DBManager &db_manager, const QString &query);
0077 
0078   public slots:
0079     /**
0080      * When Text is entered in the QLineEdit, filter the List of objects
0081      * so that only objects which start with the filter text are shown.
0082      */
0083     void filterList();
0084 
0085     // FIXME: Still valid for QDialog?  i.e., does QDialog have a slotOk() ?
0086     /**
0087      * Overloading the Standard QDialogBase slotOk() to show a "sorry"
0088      * message box if no object is selected and internet resolution was
0089      * disabled/failed when the user presses Ok.  The window is not
0090      * closed in this case.
0091      */
0092     void slotOk();
0093 
0094     /**
0095      * @short This slot resolves the object on the internet, ignoring the selection on the list
0096      */
0097     void slotResolve();
0098 
0099   private slots:
0100     /** Init object list after opening dialog. */
0101     void init();
0102 
0103     /** Set the selected item to the first item in the list */
0104     void initSelection();
0105 
0106     void enqueueSearch();
0107 
0108     void slotDetails();
0109 
0110     /** Enable/disable the OK button, and set the default button */
0111     void slotUpdateButtons();
0112 
0113   protected:
0114     /**
0115      * Process Keystrokes.  The Up and Down arrow keys are used to select the
0116      * Previous/Next item in the listbox of named objects.  The Esc key closes
0117      * the window with no selection, using reject().
0118      * @param e The QKeyEvent pointer
0119      */
0120     void keyPressEvent(QKeyEvent *e) override;
0121 
0122     void showEvent(QShowEvent *e) override;
0123 
0124     /** @return the currently-selected item from the listbox of named objects */
0125     SkyObject *selectedObject() const;
0126 
0127   private:
0128     /**
0129      * Constructor. Creates all widgets and packs them in QLayouts. Connects
0130      * Signals and Slots. Runs initObjectList().
0131      */
0132     explicit FindDialog(QWidget *parent = nullptr);
0133 
0134     static FindDialog *m_Instance;
0135 
0136     /**
0137      * @short processSearchText(QString) called on the text entered in the find dialog
0138      */
0139     inline QString processSearchText() { return processSearchText(ui->SearchBox->text()); }
0140 
0141     /** @short Finishes the processing towards closing the dialog initiated by slotOk() or slotResolve() */
0142     void finishProcessing(SkyObject *selObj = nullptr, bool resolve = true);
0143 
0144     /** @short pre-filter the list of objects according to the selected object type. */
0145     void filterByType();
0146 
0147     FindDialogUI *ui { nullptr };
0148     SkyObjectListModel *fModel { nullptr };
0149     QSortFilterProxyModel *sortModel { nullptr };
0150     QTimer *timer { nullptr };
0151     bool listFiltered { false };
0152     std::size_t m_currentSearchSequence { 0 };
0153     QPushButton *okB { nullptr };
0154     SkyObject *m_targetObject { nullptr };
0155 
0156     // History
0157     QComboBox *m_HistoryCombo { nullptr};
0158     QList<SkyObject *> m_HistoryList;
0159 
0160     // DSO Database
0161     CatalogsDB::DBManager m_dbManager; // runs in this thread
0162 };