You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmWxSelectWellsWidget.cpp

244 lines
7.9 KiB
C++

#include "nmWxSelectWellsWidget.h"
#include <QLineEdit>
#include <QCheckBox>
#include <QEvent>
#include <QStringList>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QMouseEvent>
#include <QLabel>
#include <QDebug>
#include <QListWidget>
#include "nmData/nmDataLogFile.h"
#include <QTextEdit>
#include <QShortcut>
#include <QKeySequence>
#include <QApplication>
nmWxSelectWellsWidget::nmWxSelectWellsWidget(QWidget* aParent) :
QWidget(aParent),
m_pListWidget(new QListWidget(this)),
m_pLineEdit(new QTextEdit(this)),
m_nLastClickedIndex(-1)
{
// 主布局
QGridLayout* layout = new QGridLayout;
this->setLayout(layout);
layout->addWidget(new QLabel(tr("Select Wells: ")), 0, 0);
layout->addWidget(m_pListWidget, 1, 0);
layout->addWidget(new QLabel(tr("Selected Wells: ")), 0, 1);
layout->addWidget(m_pLineEdit, 1, 1);
// m_pLineEdit->setText(multiLineText);
m_pLineEdit->setReadOnly(true);
// 快捷键Ctrl+A全选Ctrl+Shift+A清空选择
QShortcut* selectAllShortcut = new QShortcut(QKeySequence::SelectAll, this);
selectAllShortcut->setContext(Qt::WidgetWithChildrenShortcut);
connect(selectAllShortcut, SIGNAL(activated()), this, SLOT(onSelectAllItems()));
QShortcut* clearSelectionShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_A), this);
clearSelectionShortcut->setContext(Qt::WidgetWithChildrenShortcut);
connect(clearSelectionShortcut, SIGNAL(activated()), this, SLOT(onClearSelectedItems()));
this->setMinimumWidth(200);
}
void nmWxSelectWellsWidget::addItems(QStringList items, QList<QVariant> values)
{
if (m_items.count() > values.count()) {
return;
}
for (int i = 0; i < items.count(); i++) {
this->addItem(items[i], values[i]);
this->onUpdateSelections();
}
}
void nmWxSelectWellsWidget::addItem(QString name, QVariant value)
{
m_items.append(name);
m_values.append(value);
nmWxSelectWellItemWidget* itemWidget = new nmWxSelectWellItemWidget(NULL, name, value);
itemWidget->setFixedHeight(25);
itemWidget->setFixedWidth(200);
if (m_selectItems.contains(name)) {
itemWidget->setSelected(true);
}
// itemWidget->setMinimumWidth(m_pListWidget->viewport()->width()); // 设置widget的最小宽度为列表视图的宽度
QListWidgetItem* item = new QListWidgetItem;
nmDataLogFile::getInstance()->writeLog(QString(" %1 ").arg(item->sizeHint().width()));
item->setSizeHint(QSize(200, 30));
m_pListWidget->addItem(item);
m_pListWidget->setItemWidget(item, itemWidget);
connect(itemWidget, SIGNAL(sigItemClicked()), this, SLOT(onUpdateSelections()));
}
QStringList nmWxSelectWellsWidget::getItems()
{
QStringList items = m_pLineEdit->toPlainText().split("\n");
items.removeAll(QString());
return items;
}
void nmWxSelectWellsWidget::setSelectedItems(QStringList selectItems)
{
m_selectItems = selectItems;
}
void nmWxSelectWellsWidget::onUpdateSelections()
{
// 如果由井项点击触发则记录点击位置并处理Shift范围选择
nmWxSelectWellItemWidget* clickedItemWidget = qobject_cast<nmWxSelectWellItemWidget*>(sender());
if (clickedItemWidget) {
const int clickedIndex = this->indexOfItemWidget(clickedItemWidget);
if (clickedIndex >= 0) {
const bool shiftPressed = QApplication::keyboardModifiers() & Qt::ShiftModifier;
if (shiftPressed && m_nLastClickedIndex >= 0 && m_nLastClickedIndex != clickedIndex) {
// Shift+点击:将上次点击项到当前项之间的井批量设置为当前选择状态
this->setRangeItemsSelected(m_nLastClickedIndex, clickedIndex, clickedItemWidget->getSelected());
}
m_nLastClickedIndex = clickedIndex;
}
}
QStringList nameList;
// 遍历所有的itemWidget获取所有被选中的信息
for (int i = 0; i < m_pListWidget->count(); i++) {
nmWxSelectWellItemWidget* itemWidget = static_cast<nmWxSelectWellItemWidget*>(m_pListWidget->itemWidget(m_pListWidget->item(i)));
if (itemWidget->getSelected()) {
nameList.append(m_items[i]);
}
}
m_pLineEdit->setPlainText(nameList.join("\n"));
}
// 查找井项在列表中的位置
int nmWxSelectWellsWidget::indexOfItemWidget(nmWxSelectWellItemWidget* itemWidget) const
{
for (int i = 0; i < m_pListWidget->count(); i++) {
if (m_pListWidget->itemWidget(m_pListWidget->item(i)) == itemWidget) {
return i;
}
}
return -1;
}
// 批量设置所有井的选中状态,最后统一刷新右侧文本
void nmWxSelectWellsWidget::setAllItemsSelected(bool selected)
{
for (int i = 0; i < m_pListWidget->count(); i++) {
nmWxSelectWellItemWidget* itemWidget = static_cast<nmWxSelectWellItemWidget*>(m_pListWidget->itemWidget(m_pListWidget->item(i)));
if (!itemWidget) {
continue;
}
// 屏蔽单项信号,避免批量操作时重复刷新
const bool oldSignalsBlocked = itemWidget->blockSignals(true);
itemWidget->setSelected(selected);
itemWidget->blockSignals(oldSignalsBlocked);
}
this->onUpdateSelections();
}
// 批量设置指定范围内井的选中状态
void nmWxSelectWellsWidget::setRangeItemsSelected(int fromIndex, int toIndex, bool selected)
{
// 允许从下往上Shift+点击
if (fromIndex > toIndex) {
const int tempIndex = fromIndex;
fromIndex = toIndex;
toIndex = tempIndex;
}
for (int i = fromIndex; i <= toIndex && i < m_pListWidget->count(); i++) {
nmWxSelectWellItemWidget* itemWidget = static_cast<nmWxSelectWellItemWidget*>(m_pListWidget->itemWidget(m_pListWidget->item(i)));
if (!itemWidget) {
continue;
}
// 屏蔽单项信号,范围处理完成后由外层统一刷新
const bool oldSignalsBlocked = itemWidget->blockSignals(true);
itemWidget->setSelected(selected);
itemWidget->blockSignals(oldSignalsBlocked);
}
}
// 响应Ctrl+A全选所有井
void nmWxSelectWellsWidget::onSelectAllItems()
{
this->setAllItemsSelected(true);
}
// 响应Ctrl+Shift+A清空所有已选择井
void nmWxSelectWellsWidget::onClearSelectedItems()
{
this->setAllItemsSelected(false);
}
nmWxSelectWellItemWidget::nmWxSelectWellItemWidget()
: m_pCBox(NULL)
{
}
nmWxSelectWellItemWidget::nmWxSelectWellItemWidget(QWidget *parent, QString name, QVariant value)
: QWidget(parent),
m_pCBox(NULL),
m_sName(name),
m_iValue(value)
{
this->initUI();
}
void nmWxSelectWellItemWidget::setSelected(bool selected)
{
if (m_pCBox) {
m_pCBox->setChecked(selected);
}
}
bool nmWxSelectWellItemWidget::getSelected()
{
if (m_pCBox) {
return m_pCBox->isChecked();
}
return false;
}
void nmWxSelectWellItemWidget::toggleSelected()
{
this->setSelected(!this->getSelected());
}
void nmWxSelectWellItemWidget::initUI()
{
// 可以设置鼠标样式,表明这个部件可以被点击
setCursor(Qt::PointingHandCursor);
// 设置QCheckBox
QHBoxLayout* layout = new QHBoxLayout;
setLayout(layout);
m_pCBox = new QCheckBox(this);
m_pCBox->setText(m_sName);
layout->setAlignment(Qt::AlignVCenter);
layout->setContentsMargins(10, 0, 0, 0);
layout->setSpacing(0);
connect(m_pCBox, SIGNAL(stateChanged(int)), this, SLOT(onStateChanged(int)));
}
void nmWxSelectWellItemWidget::mousePressEvent(QMouseEvent *event)
{
// 当鼠标左键被按下时,执行一些操作
if (event->button() == Qt::LeftButton) {
// 处理点击事件,例如发出一个信号或者调用一个槽函数
qDebug() << "ClickableWidget was clicked!";
}
QWidget::mousePressEvent(event); // 调用基类的处理函数
this->toggleSelected();
emit this->sigItemClicked();
}
void nmWxSelectWellItemWidget::onStateChanged(int)
{
emit this->sigItemClicked();
}