Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+219
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* ComboBox's popup, optimized for tablets (bigger dropdown/popup)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-03-09
|
||||
*/
|
||||
|
||||
#include "lts_selection_popup.h"
|
||||
#include "ui_lts_selection_popup.h"
|
||||
#include "lts_base.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QRadioButton>
|
||||
#include <QScrollBar>
|
||||
|
||||
//#define NEVER
|
||||
#ifdef NEVER
|
||||
# include <QDebug>
|
||||
#endif // NEVER
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
class RadioButton : public QRadioButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RadioButton(int row, const QString &text)
|
||||
: QRadioButton(text)
|
||||
, m_row(row)
|
||||
{}
|
||||
|
||||
int row() const { return m_row; }
|
||||
|
||||
signals:
|
||||
void doubleClickEvent();
|
||||
|
||||
private:
|
||||
int m_row;
|
||||
|
||||
void mouseDoubleClickEvent(QMouseEvent *) override
|
||||
{
|
||||
emit doubleClickEvent();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
LtsSelectionPopup::LtsSelectionPopup(QAbstractItemModel* model,
|
||||
int currentIndex,
|
||||
QWidget *parent)
|
||||
: LtsFramelessDialog(parent, Behaviour::Popup)
|
||||
, m_ui(new Ui::LtsSelectionPopup) // TODO: morph .ui to QDialog (is QWidget)
|
||||
, m_currentIndex(currentIndex)
|
||||
, m_firstIndex(currentIndex)
|
||||
, m_filter(new QSortFilterProxyModel(this))
|
||||
, m_valid(false)
|
||||
{
|
||||
m_ui->setupUi(this); // i am sorry for this solution, but qlistview's are so unthankfully to work with
|
||||
|
||||
m_filter->setSourceModel(model);
|
||||
m_filter->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
slotFilterChanged();
|
||||
#ifdef TABLET_MODE
|
||||
m_ui->leSearch->setVisible(false);
|
||||
m_ui->label->setVisible(false);
|
||||
#endif
|
||||
connect(m_ui->pbCancel, &QPushButton::clicked, this, &LtsSelectionPopup::reject);
|
||||
connect(m_ui->pbSelect, &QPushButton::clicked, this, &LtsSelectionPopup::accept);
|
||||
connect(m_ui->leSearch, &QLineEdit::textEdited,
|
||||
this, &LtsSelectionPopup::slotFilterChanged);
|
||||
|
||||
#ifdef NEVER
|
||||
// debugging :
|
||||
// // highlighted -> UserInteraction
|
||||
// connect(this, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::highlighted), this, [](int idx){
|
||||
// qCritical() << " called: highlighted(int)";
|
||||
// });
|
||||
|
||||
// currentIndexChanged -> programmatically & UserInteraction
|
||||
connect(this, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::currentIndexChanged), this, [](int idx){
|
||||
qCritical() << " LtsSelectionPopup: called: currentIndexChanged(int), idx=" << idx;
|
||||
});
|
||||
|
||||
// activated -> UserInteraction
|
||||
connect(this, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::activated), this, [](int idx){
|
||||
qCritical() << " LtsSelectionPopup: called: activated(int), idx=" << idx;
|
||||
});
|
||||
// : debugging
|
||||
#endif // NEVER
|
||||
}
|
||||
|
||||
|
||||
LtsSelectionPopup::~LtsSelectionPopup()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void LtsSelectionPopup::slotFilterChanged()
|
||||
{
|
||||
m_filter->setFilterWildcard(m_ui->leSearch->text().count() ? m_ui->leSearch->text() : QStringLiteral("*") /* show everything if nothing was entered */);
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
void LtsSelectionPopup::refresh()
|
||||
{
|
||||
m_valid = false; // invalidate, none selected as all deleted
|
||||
qDeleteAll(m_ui->itemLayoutWidget->findChildren<RadioButton*>()); // delete all RBs
|
||||
QLayoutItem *tem = nullptr;
|
||||
if (m_ui->itemLayoutWidget->layout()->count() > 0)
|
||||
{
|
||||
tem = m_ui->itemLayoutWidget->layout()->takeAt(0);
|
||||
}
|
||||
|
||||
int count = m_filter->rowCount();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int realRow = m_filter->mapToSource(m_filter->index(i, 0)).row();
|
||||
|
||||
RadioButton *rbItem = new RadioButton(realRow, m_filter->data(m_filter->index(i, 0)).toString());
|
||||
int disable = m_filter->data(m_filter->index(i, 0), Qt::UserRole-1).toInt();
|
||||
if (disable == 1)
|
||||
rbItem->setEnabled(false);
|
||||
m_ui->itemLayoutWidget->layout()->addWidget(rbItem);
|
||||
|
||||
if (realRow == m_currentIndex)
|
||||
{
|
||||
rbItem->setChecked(true);
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
connect(rbItem, &RadioButton::doubleClickEvent,
|
||||
this, &LtsSelectionPopup::accept); // is always selected then..
|
||||
connect(rbItem, &RadioButton::toggled,
|
||||
this, [this](bool checked)
|
||||
{
|
||||
if (checked)
|
||||
m_ui->pbSelect->setEnabled(true);
|
||||
});
|
||||
}
|
||||
if (tem)
|
||||
m_ui->itemLayoutWidget->layout()->addItem(tem);
|
||||
|
||||
if (count == 1) // if there is only one item, then allow the user to click Select (or pressing enter) to select the only item available
|
||||
m_valid = true;
|
||||
|
||||
m_ui->pbSelect->setEnabled(m_valid);
|
||||
}
|
||||
|
||||
|
||||
void LtsSelectionPopup::showEvent(QShowEvent *event)
|
||||
{
|
||||
LtsFramelessDialog::showEvent(event);
|
||||
m_ui->leSearch->setFocus();
|
||||
|
||||
resize(sizeHint().width() + m_ui->scrollArea->horizontalScrollBar()->height() , sizeHint().height());
|
||||
}
|
||||
|
||||
|
||||
void LtsSelectionPopup::selectItem(int row, bool bCurrentIndexChanged, bool bActivated)
|
||||
{
|
||||
// order of signals (like Qt 5.9): 1st: currentIndexChanged 2nd: activated
|
||||
|
||||
if (bCurrentIndexChanged)
|
||||
emit currentIndexChanged(row);
|
||||
|
||||
if (bActivated)
|
||||
emit activated(row);
|
||||
|
||||
m_ui->pbSelect->setEnabled(true);
|
||||
|
||||
LtsFramelessDialog::accept(); // only accept if one item is selected
|
||||
}
|
||||
|
||||
|
||||
void LtsSelectionPopup::accept()
|
||||
{
|
||||
const QList<RadioButton *> items = m_ui->itemLayoutWidget->findChildren<RadioButton *>();
|
||||
|
||||
int count = items.count();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
const RadioButton *rb = items.at(i);
|
||||
|
||||
if (rb->isChecked())
|
||||
{
|
||||
int realRow = m_filter->mapToSource(m_filter->index(i, 0)).row();
|
||||
|
||||
bool bCurrentIndexChanged = realRow != m_firstIndex; // currentIndex has changed?
|
||||
bool bActivated = true;
|
||||
selectItem(realRow, bCurrentIndexChanged, bActivated); // & closes dialog
|
||||
return; // no need to go further
|
||||
}
|
||||
}
|
||||
|
||||
// okay, nothing was selected, is there only one item available? if yes, select it and accept
|
||||
if (count == 1)
|
||||
{
|
||||
const RadioButton *rb = items.at(0);
|
||||
selectItem(rb->row(), true, true); // item was not selected before, so it must also be emitted as "activated" // & closes dialog
|
||||
return; // no need to go further
|
||||
}
|
||||
// none selected and multiple choises? ignore..
|
||||
}
|
||||
|
||||
} // namespace LtsWidgets
|
||||
|
||||
#include "lts_selection_popup.moc"
|
||||
Reference in new issue
Block a user