Kstars

finddialog.cpp
1/*
2 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "finddialog.h"
8
9#include "kstars.h"
10#include "kstarsdata.h"
11#include "ksnotification.h"
12#include "Options.h"
13#include "detaildialog.h"
14#include "skymap.h"
15#include "skyobjects/skyobject.h"
16#include "skycomponents/starcomponent.h"
17#include "skycomponents/skymapcomposite.h"
18#include "tools/nameresolver.h"
19#include "skyobjectlistmodel.h"
20#include "catalogscomponent.h"
21#include <KMessageBox>
22
23#include <QSortFilterProxyModel>
24#include <QStringListModel>
25#include <QTimer>
26#include <QComboBox>
27#include <QLineEdit>
28#include <QPointer>
29
30FindDialog *FindDialog::m_Instance = nullptr;
31
32FindDialogUI::FindDialogUI(QWidget *parent) : QFrame(parent)
33{
34 setupUi(this);
35
36 FilterType->addItem(i18n("Any"));
37 FilterType->addItem(i18n("Stars"));
38 FilterType->addItem(i18n("Solar System"));
39 FilterType->addItem(i18n("Open Clusters"));
40 FilterType->addItem(i18n("Globular Clusters"));
41 FilterType->addItem(i18n("Gaseous Nebulae"));
42 FilterType->addItem(i18n("Planetary Nebulae"));
43 FilterType->addItem(i18n("Galaxies"));
44 FilterType->addItem(i18n("Comets"));
45 FilterType->addItem(i18n("Asteroids"));
46 FilterType->addItem(i18n("Constellations"));
47 FilterType->addItem(i18n("Supernovae"));
48 FilterType->addItem(i18n("Satellites"));
49
50 SearchList->setMinimumWidth(256);
51 SearchList->setMinimumHeight(320);
52}
53
54FindDialog *FindDialog::Instance()
55{
56 if (m_Instance == nullptr)
57 m_Instance = new FindDialog(KStars::Instance());
58
59 return m_Instance;
60}
61
62FindDialog::FindDialog(QWidget *parent)
63 : QDialog(parent)
64 , timer(nullptr)
65 , m_targetObject(nullptr)
66 , m_dbManager(CatalogsDB::dso_db_path())
67{
68#ifdef Q_OS_OSX
69 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
70#endif
71 ui = new FindDialogUI(this);
72
73 setWindowTitle(i18nc("@title:window", "Find Object"));
74
75 QVBoxLayout *mainLayout = new QVBoxLayout;
76 mainLayout->addWidget(ui);
77 setLayout(mainLayout);
78
80 mainLayout->addWidget(buttonBox);
81 connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotOk()));
82 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
83
84 okB = buttonBox->button(QDialogButtonBox::Ok);
85 okB->setEnabled(false);
86
87 QPushButton *detailB = new QPushButton(i18n("Details..."));
89 connect(detailB, SIGNAL(clicked()), this, SLOT(slotDetails()));
90
91 ui->InternetSearchButton->setVisible(Options::resolveNamesOnline());
92 ui->InternetSearchButton->setEnabled(false);
93 connect(ui->InternetSearchButton, SIGNAL(clicked()), this, SLOT(slotResolve()));
94
95 ui->FilterType->setCurrentIndex(0); // show all types of objects
96
97 fModel = new SkyObjectListModel(this);
98 connect(KStars::Instance()->map(), &SkyMap::removeSkyObject, fModel, &SkyObjectListModel::removeSkyObject);
99 sortModel = new QSortFilterProxyModel(ui->SearchList);
100 sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
101 sortModel->setSourceModel(fModel);
102 sortModel->setSortRole(Qt::DisplayRole);
103 sortModel->setFilterRole(Qt::DisplayRole);
104 sortModel->setDynamicSortFilter(true);
105 sortModel->sort(0);
106
107 ui->SearchList->setModel(sortModel);
108
109 // Connect signals to slots
110 connect(ui->clearHistoryB, &QPushButton::clicked, [&]()
111 {
112 ui->clearHistoryB->setEnabled(false);
113 m_HistoryCombo->clear();
114 m_HistoryList.clear();
115 });
116
117 m_HistoryCombo = new QComboBox(ui->showHistoryB);
118 m_HistoryCombo->move(0, ui->showHistoryB->height());
119 connect(ui->showHistoryB, &QPushButton::clicked, [&]()
120 {
121 if (m_HistoryList.empty() == false)
122 {
123 m_HistoryCombo->showPopup();
124 }
125 });
126
127 connect(m_HistoryCombo, static_cast<void(QComboBox::*)(int)>(&QComboBox::activated),
128 [&](int index)
129 {
130 m_targetObject = m_HistoryList[index];
131 m_targetObject->updateCoordsNow(KStarsData::Instance()->updateNum());
132 m_HistoryCombo->setCurrentIndex(-1);
133 m_HistoryCombo->hidePopup();
134 accept();
135 });
136 connect(ui->SearchBox, &QLineEdit::textChanged, this, &FindDialog::enqueueSearch);
137 connect(ui->SearchBox, &QLineEdit::returnPressed, this, &FindDialog::slotOk);
138 connect(ui->FilterType, &QComboBox::currentTextChanged, this, &FindDialog::enqueueSearch);
139 connect(ui->SearchList, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotOk()));
140 connect(ui->SearchList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FindDialog::slotUpdateButtons);
141
142 // Set focus to object name edit
143 ui->SearchBox->setFocus();
144
145 // First create and paint dialog and then load list
146 QTimer::singleShot(0, this, SLOT(init()));
147
148 listFiltered = false;
149}
150
151void FindDialog::init()
152{
153 const auto &objs = m_dbManager.get_objects(Options::magLimitDrawDeepSky(), 100);
154 for (const auto &obj : objs)
155 {
156 KStarsData::Instance()->skyComposite()->catalogsComponent()->insertStaticObject(
157 obj);
158 }
159 ui->SearchBox->clear();
160 filterByType();
161 sortModel->sort(0);
162 initSelection();
163 m_targetObject = nullptr;
164}
165
166void FindDialog::showEvent(QShowEvent *e)
167{
168 ui->SearchBox->setFocus();
169 e->accept();
170}
171
172void FindDialog::initSelection()
173{
174 if (sortModel->rowCount() <= 0)
175 {
176 okB->setEnabled(false);
177 return;
178 }
179
180 // ui->SearchBox->setModel(sortModel);
181 // ui->SearchBox->setModelColumn(0);
182
183 if (ui->SearchBox->text().isEmpty())
184 {
185 //Pre-select the first item
186 QModelIndex selectItem = sortModel->index(0, sortModel->filterKeyColumn(), QModelIndex());
187 switch (ui->FilterType->currentIndex())
188 {
189 case 0: //All objects, choose Andromeda galaxy
190 {
191 QModelIndex qmi = fModel->index(fModel->indexOf(i18n("Andromeda Galaxy")));
192 selectItem = sortModel->mapFromSource(qmi);
193 break;
194 }
195 case 1: //Stars, choose Aldebaran
196 {
197 QModelIndex qmi = fModel->index(fModel->indexOf(i18n("Aldebaran")));
198 selectItem = sortModel->mapFromSource(qmi);
199 break;
200 }
201 case 2: //Solar system or Asteroids, choose Aaltje
202 case 9:
203 {
204 QModelIndex qmi = fModel->index(fModel->indexOf(i18n("Aaltje")));
205 selectItem = sortModel->mapFromSource(qmi);
206 break;
207 }
208 case 8: //Comets, choose 'Aarseth-Brewington (1989 W1)'
209 {
210 QModelIndex qmi = fModel->index(fModel->indexOf(i18n("Aarseth-Brewington (1989 W1)")));
211 selectItem = sortModel->mapFromSource(qmi);
212 break;
213 }
214 }
215
216 if (selectItem.isValid())
217 {
218 ui->SearchList->selectionModel()->select(selectItem, QItemSelectionModel::ClearAndSelect);
219 ui->SearchList->scrollTo(selectItem);
220 ui->SearchList->setCurrentIndex(selectItem);
221 }
222 }
223
224 listFiltered = true;
225}
226
227void FindDialog::filterByType()
228{
229 KStarsData *data = KStarsData::Instance();
230
231 switch (ui->FilterType->currentIndex())
232 {
233 case 0: // All object types
234 {
236 foreach (int type, data->skyComposite()->objectLists().keys())
237 {
238 allObjects.append(data->skyComposite()->objectLists(SkyObject::TYPE(type)));
239 }
240 fModel->setSkyObjectsList(allObjects);
241 break;
242 }
243 case 1: //Stars
244 {
246 starObjects.append(data->skyComposite()->objectLists(SkyObject::STAR));
247 starObjects.append(data->skyComposite()->objectLists(SkyObject::CATALOG_STAR));
248 fModel->setSkyObjectsList(starObjects);
249 break;
250 }
251 case 2: //Solar system
252 {
254 ssObjects.append(data->skyComposite()->objectLists(SkyObject::PLANET));
255 ssObjects.append(data->skyComposite()->objectLists(SkyObject::COMET));
256 ssObjects.append(data->skyComposite()->objectLists(SkyObject::ASTEROID));
257 ssObjects.append(data->skyComposite()->objectLists(SkyObject::MOON));
258
259 fModel->setSkyObjectsList(ssObjects);
260 break;
261 }
262 case 3: //Open Clusters
263 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::OPEN_CLUSTER));
264 break;
265 case 4: //Globular Clusters
266 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::GLOBULAR_CLUSTER));
267 break;
268 case 5: //Gaseous nebulae
269 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::GASEOUS_NEBULA));
270 break;
271 case 6: //Planetary nebula
272 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::PLANETARY_NEBULA));
273 break;
274 case 7: //Galaxies
275 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::GALAXY));
276 break;
277 case 8: //Comets
278 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::COMET));
279 break;
280 case 9: //Asteroids
281 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::ASTEROID));
282 break;
283 case 10: //Constellations
284 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::CONSTELLATION));
285 break;
286 case 11: //Supernovae
287 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::SUPERNOVA));
288 break;
289 case 12: //Satellites
290 fModel->setSkyObjectsList(data->skyComposite()->objectLists(SkyObject::SATELLITE));
291 break;
292 }
293}
294
296{
298 //const std::size_t searchId = m_currentSearchSequence;
299
300 // JM 2022.08.28: Disabling use of async DB manager until further notice since it appears to cause a crash
301 // on MacOS and some embedded systems.
302 // QEventLoop loop;
303 // QMutexLocker {&dbCallMutex}; // To prevent re-entrant calls into this
304 // connect(m_asyncDBManager.get(), &CatalogsDB::AsyncDBManager::resultReady, &loop, &QEventLoop::quit);
305 // QMetaObject::invokeMethod(m_asyncDBManager.get(), [&](){
306 // m_asyncDBManager->find_objects_by_name(SearchText, 10); });
307 // loop.exec();
308 // std::unique_ptr<CatalogsDB::CatalogObjectList> objs = m_asyncDBManager->result();
309 // if (m_currentSearchSequence != searchId) {
310 // return; // Ignore this search since the search text has changed
311 // }
312
313 auto objs = m_dbManager.find_objects_by_name(SearchText, 10);
314
315 bool exactMatchExists = objs.size() > 0 ? QString::compare(objs.front().name(), SearchText, Qt::CaseInsensitive) : false;
316
317 for (const auto &obj : objs)
318 {
319 KStarsData::Instance()->skyComposite()->catalogsComponent()->insertStaticObject(
320 obj);
321 }
322
324 ui->InternetSearchButton->setText(i18n("Search the Internet for %1", SearchText.isEmpty() ? i18nc("no text to search for",
325 "(nothing)") : SearchText));
326 filterByType();
327 initSelection();
328
329 bool enableInternetSearch = (!exactMatchExists) && (ui->FilterType->currentIndex() == 0);
330 //Select the first item in the list that begins with the filter string
331 if (!SearchText.isEmpty())
332 {
333 QStringList mItems =
335 mItems.sort();
336
337 if (mItems.size())
338 {
339 QModelIndex qmi = fModel->index(fModel->indexOf(mItems[0]));
341
342 if (selectItem.isValid())
343 {
344 ui->SearchList->selectionModel()->select(
346 ui->SearchList->scrollTo(selectItem);
347 ui->SearchList->setCurrentIndex(selectItem);
348 }
349 }
350 ui->InternetSearchButton->setEnabled(enableInternetSearch && !mItems.contains(
351 SearchText, Qt::CaseInsensitive)); // Disable searching the internet when an exact match for SearchText exists in KStars
352 }
353 else
354 ui->InternetSearchButton->setEnabled(false);
355
356 listFiltered = true;
357 slotUpdateButtons();
358}
359
360void FindDialog::slotUpdateButtons()
361{
362 okB->setEnabled(ui->SearchList->selectionModel()->hasSelection());
363
364 if (okB->isEnabled())
365 {
366 okB->setDefault(true);
367 }
368 else if (ui->InternetSearchButton->isEnabled())
369 {
370 ui->InternetSearchButton->setDefault(true);
371 }
372}
373
375{
376 QModelIndex i = ui->SearchList->currentIndex();
377 QVariant sObj = sortModel->data(sortModel->index(i.row(), 0), SkyObjectListModel::SkyObjectRole);
378
379 return reinterpret_cast<SkyObject*>(sObj.value<void *>());
380}
381
382void FindDialog::enqueueSearch()
383{
384 listFiltered = false;
385 if (timer)
386 {
387 timer->stop();
388 }
389 else
390 {
391 timer = new QTimer(this);
392 timer->setSingleShot(true);
393 connect(timer, &QTimer::timeout, [&]()
394 {
395 this->m_currentSearchSequence++;
396 this->filterList();
397 });
398 }
399 timer->start(500);
400}
401
402// Process the search box text to replace equivalent names like "m93" with "m 93"
404{
405 QRegExp re;
406 re.setCaseSensitivity(Qt::CaseInsensitive);
407
408 // Remove multiple spaces and replace them by a single space
409 re.setPattern(" +");
410 searchText.replace(re, " ");
411
412 // If it is an NGC/IC/M catalog number, as in "M 76" or "NGC 5139", check for absence of the space
413 re.setPattern("^(m|ngc|ic)\\s*\\d*$");
414 if (searchText.contains(re))
415 {
416 re.setPattern("\\s*(\\d+)");
417 searchText.replace(re, " \\1");
418 re.setPattern("\\s*$");
419 searchText.remove(re);
420 re.setPattern("^\\s*");
421 searchText.remove(re);
422 }
423
424 // If it is a comet, and starts with c20## or c 20## make it c/20## (or similar with p).
425 re.setPattern("^(c|p)\\s*((19|20).*)");
426 if (searchText.contains(re))
427 {
428 if (searchText.at(0) == 'c' || searchText.at(0) == 'C')
429 searchText.replace(re, "c/\\2");
430 else searchText.replace(re, "p/\\2");
431 }
432
433 // TODO after KDE 4.1 release:
434 // If it is a IAU standard three letter abbreviation for a constellation, then go to that constellation
435 // Check for genetive names of stars. Example: alp CMa must go to alpha Canis Majoris
436
437 return searchText;
438}
439
441{
442 // JM 2022.04.20 Below does not work when a user is simply browsing
443 // and selecting an item without entering any text in the search box.
444 //If no valid object selected, show a sorry-box. Otherwise, emit accept()
445 // if (ui->SearchBox->text().isEmpty())
446 // {
447 // return;
448 // }
450 if (!listFiltered)
451 {
452 filterList();
453 }
455 finishProcessing(selObj, Options::resolveNamesOnline() && ui->InternetSearchButton->isEnabled());
456}
457
459{
460 finishProcessing(nullptr, true);
461}
462
464{
465 CatalogObject *dso = nullptr;
466 const auto &cedata = NameResolver::resolveName(query);
467
468 if (cedata.first)
469 {
470 db_manager.add_object(CatalogsDB::user_catalog_id, cedata.second);
471 const auto &added_object =
472 db_manager.get_object(cedata.second.getId(), CatalogsDB::user_catalog_id);
473
474 if (added_object.first)
475 {
476 dso = &KStarsData::Instance()
477 ->skyComposite()
478 ->catalogsComponent()
479 ->insertStaticObject(added_object.second);
480 }
481 }
482 return dso;
483}
484
485void FindDialog::finishProcessing(SkyObject *selObj, bool resolve)
486{
487 if (!selObj && resolve)
488 {
489 selObj = resolveAndAdd(m_dbManager, processSearchText());
490 }
491 m_targetObject = selObj;
492 if (selObj == nullptr)
493 {
494 QString message = i18n("No object named %1 found.", ui->SearchBox->text());
495 KSNotification::sorry(message, i18n("Bad object name"));
496 }
497 else
498 {
499 selObj->updateCoordsNow(KStarsData::Instance()->updateNum());
500 if (m_HistoryList.contains(selObj) == false)
501 {
502 switch (selObj->type())
503 {
504 case SkyObject::OPEN_CLUSTER:
505 case SkyObject::GLOBULAR_CLUSTER:
506 case SkyObject::GASEOUS_NEBULA:
507 case SkyObject::PLANETARY_NEBULA:
508 case SkyObject::SUPERNOVA_REMNANT:
509 case SkyObject::GALAXY:
510 if (selObj->name() != selObj->longname())
511 m_HistoryCombo->addItem(QString("%1 (%2)")
512 .arg(selObj->name())
513 .arg(selObj->longname()));
514 else
515 m_HistoryCombo->addItem(QString("%1").arg(selObj->longname()));
516 break;
517
518 case SkyObject::STAR:
519 case SkyObject::CATALOG_STAR:
520 case SkyObject::PLANET:
521 case SkyObject::COMET:
522 case SkyObject::ASTEROID:
523 case SkyObject::CONSTELLATION:
524 case SkyObject::MOON:
525 case SkyObject::ASTERISM:
526 case SkyObject::GALAXY_CLUSTER:
527 case SkyObject::DARK_NEBULA:
528 case SkyObject::QUASAR:
529 case SkyObject::MULT_STAR:
530 case SkyObject::RADIO_SOURCE:
531 case SkyObject::SATELLITE:
532 case SkyObject::SUPERNOVA:
533 default:
534 m_HistoryCombo->addItem(QString("%1").arg(selObj->longname()));
535 break;
536 }
537
538 m_HistoryList.append(selObj);
539 }
540 ui->clearHistoryB->setEnabled(true);
541 accept();
542 }
543}
545{
546 switch (e->key())
547 {
548 case Qt::Key_Escape:
549 reject();
550 break;
551 case Qt::Key_Up:
552 {
553 int currentRow = ui->SearchList->currentIndex().row();
554 if (currentRow > 0)
555 {
556 QModelIndex selectItem = sortModel->index(currentRow - 1, sortModel->filterKeyColumn(), QModelIndex());
557 ui->SearchList->selectionModel()->setCurrentIndex(selectItem, QItemSelectionModel::SelectCurrent);
558 }
559 break;
560 }
561 case Qt::Key_Down:
562 {
563 int currentRow = ui->SearchList->currentIndex().row();
564 if (currentRow < sortModel->rowCount() - 1)
565 {
566 QModelIndex selectItem = sortModel->index(currentRow + 1, sortModel->filterKeyColumn(), QModelIndex());
567 ui->SearchList->selectionModel()->setCurrentIndex(selectItem, QItemSelectionModel::SelectCurrent);
568 }
569 break;
570 }
571 }
572}
573
574void FindDialog::slotDetails()
575{
576 if (selectedObject())
577 {
578 QPointer<DetailDialog> dd = new DetailDialog(selectedObject(), KStarsData::Instance()->ut(),
579 KStarsData::Instance()->geo(), KStars::Instance());
580 dd->exec();
581 delete dd;
582 }
583}
584
586{
587 QWidget * const oldParent = parentWidget();
588
589 if (nullptr != parent)
590 {
593 }
594
595 int const result = QDialog::exec();
596
597 if (nullptr != parent)
598 {
601 }
602
603 return result;
604}
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
Manages the catalog database and provides an interface to provide an interface to query and modify th...
Definition catalogsdb.h:183
CatalogObjectList find_objects_by_name(const QString &name, const int limit=-1, const bool exactMatchOnly=false)
Find an objects by name.
CatalogObjectList get_objects(float maglim=default_maglim, int limit=-1)
Get limit objects with magnitude smaller than maglim (smaller = brighter) from the database.
DetailDialog is a window showing detailed information for a selected object.
Dialog window for finding SkyObjects by name.
Definition finddialog.h:43
static CatalogObject * resolveAndAdd(CatalogsDB::DBManager &db_manager, const QString &query)
Resolves an object using the internet and adds it to the database.
void filterList()
When Text is entered in the QLineEdit, filter the List of objects so that only objects which start wi...
void slotResolve()
This slot resolves the object on the internet, ignoring the selection on the list.
int execWithParent(QWidget *parent=nullptr)
exec overrides base's QDialog::exec() to provide a parent widget.
SkyObject * selectedObject() const
void slotOk()
Overloading the Standard QDialogBase slotOk() to show a "sorry" message box if no object is selected ...
static QString processSearchText(QString searchText)
Do some post processing on the search text to interpret what the user meant This could include replac...
void keyPressEvent(QKeyEvent *e) override
Process Keystrokes.
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
SkyMapComposite * skyComposite()
Definition kstarsdata.h:166
static KStars * Instance()
Definition kstars.h:123
void removeSkyObject(SkyObject *object)
Emitted when a sky object is removed from the database.
A model used in Find Object Dialog in QML.
int indexOf(const QString &objectName) const
QStringList filter(const QRegExp &regEx)
Filter the model.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
TYPE
The type classification of the SkyObject.
Definition skyobject.h:112
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
std::pair< bool, CatalogObject > resolveName(const QString &name)
Resolve the name of the given DSO and extract data from various sources.
QCA_EXPORT void init()
void clicked(bool checked)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void activated(int index)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void currentTextChanged(const QString &text)
virtual void accept()
virtual int exec()
virtual void reject()
int result() const const
QPushButton * addButton(StandardButton button)
QPushButton * button(StandardButton which) const const
void accept()
QList< Key > keys() const const
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
int key() const const
void returnPressed()
void textChanged(const QString &text)
void append(QList< T > &&value)
bool contains(const AT &value) const const
qsizetype size() const const
int row() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
void setDefault(bool)
virtual QVariant data(const QModelIndex &index, int role) const const override
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const const override
virtual int rowCount(const QModelIndex &parent) const const override
void setFilterFixedString(const QString &pattern)
virtual void sort(int column, Qt::SortOrder order) override
QString arg(Args &&... args) const const
const QChar at(qsizetype position) const const
int compare(QLatin1StringView s1, const QString &s2, Qt::CaseSensitivity cs)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
void sort(Qt::CaseSensitivity cs)
CaseInsensitive
DisplayRole
Key_Escape
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void timeout()
void setEnabled(bool)
QWidget * parentWidget() const const
void setFocus()
void setParent(QWidget *parent)
void setWindowFlag(Qt::WindowType flag, bool on)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:02 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.