| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <algorithm> |
| |
|
| | #include <QScrollBar> |
| | #include <QTableView> |
| | #include <QHeaderView> |
| | #include <QToolButton> |
| | #include <QMenu> |
| | #include <QBoxLayout> |
| | #include <QLabel> |
| | #include <QLineEdit> |
| | #include <QContextMenuEvent> |
| | #include <QSortFilterProxyModel> |
| |
|
| | #include "lc_flexlayout.h" |
| | #include "qg_actionhandler.h" |
| | #include "qg_blockwidget.h" |
| |
|
| | #include "lc_actiongroupmanager.h" |
| | #include "rs_blocklist.h" |
| | #include "rs_debug.h" |
| | #include "rs_settings.h" |
| | #include "lc_widgets_common.h" |
| | #include "rs_graphic.h" |
| | #include "rs_graphicview.h" |
| |
|
| | QG_BlockModel::QG_BlockModel(QObject * parent) : QAbstractTableModel(parent) { |
| | m_iconBlockVisible = QIcon(":/icons/visible.lci"); |
| | |
| | m_iconBlockHidden = QIcon(":/icons/not_visible.lci"); |
| | } |
| |
|
| | int QG_BlockModel::rowCount ( const QModelIndex & ) const { |
| | return m_listBlock.size(); |
| | } |
| |
|
| | QModelIndex QG_BlockModel::parent ( const QModelIndex & ) const { |
| | return QModelIndex(); |
| | } |
| |
|
| | QModelIndex QG_BlockModel::index ( int row, int column, const QModelIndex & ) const { |
| | if ( row >= m_listBlock.size() || row < 0) |
| | return QModelIndex(); |
| | return createIndex ( row, column); |
| | } |
| |
|
| | bool blockLessThan(const RS_Block *s1, const RS_Block *s2) { |
| | return s1->getName() < s2->getName(); |
| | } |
| |
|
| | void QG_BlockModel::setBlockList(RS_BlockList* bl) { |
| | |
| | |
| | |
| | beginResetModel(); |
| | m_listBlock.clear(); |
| | if (bl == nullptr){ |
| | endResetModel(); |
| | return; |
| | } |
| | for (int i=0; i<bl->count(); ++i) { |
| | if ( !bl->at(i)->isUndone() ) |
| | m_listBlock.append(bl->at(i)); |
| | } |
| | setActiveBlock(bl->getActive()); |
| | std::sort( m_listBlock.begin(), m_listBlock.end(), blockLessThan); |
| |
|
| | |
| | endResetModel(); |
| | } |
| |
|
| |
|
| | RS_Block *QG_BlockModel::getBlock( int row) const{ |
| | if ( row >= m_listBlock.size() || row < 0) |
| | return nullptr; |
| | return m_listBlock.at(row); |
| | } |
| |
|
| | QModelIndex QG_BlockModel::getIndex (RS_Block * blk) const{ |
| | int row = m_listBlock.indexOf(blk); |
| | if (row<0) |
| | return QModelIndex(); |
| | return createIndex ( row, NAME); |
| | } |
| |
|
| | QVariant QG_BlockModel::data ( const QModelIndex & index, int role ) const { |
| | if (!index.isValid() || index.row() >= m_listBlock.size()) |
| | return QVariant(); |
| |
|
| | RS_Block* blk = m_listBlock.at(index.row()); |
| |
|
| | if (role ==Qt::DecorationRole && index.column() == VISIBLE) { |
| | if (!blk->isFrozen()) { |
| | return m_iconBlockVisible; |
| | } else { |
| | return m_iconBlockHidden; |
| | } |
| | } |
| | if (role ==Qt::DisplayRole && index.column() == NAME) { |
| | return blk->getName(); |
| | } |
| | if (role == Qt::FontRole && index.column() == NAME) { |
| | if (m_activeBlock && m_activeBlock == blk) { |
| | QFont font; |
| | font.setBold(true); |
| | return font; |
| | } |
| | } |
| | |
| | return QVariant(); |
| | } |
| |
|
| | |
| | |
| | |
| | QG_BlockWidget::QG_BlockWidget(LC_ActionGroupManager* agm,QG_ActionHandler* ah, QWidget* parent, |
| | const char* name, Qt::WindowFlags f) |
| | : LC_GraphicViewAwareWidget(parent, name, f) { |
| | m_actionGroupManager = agm; |
| | m_actionHandler = ah; |
| | m_blockList = nullptr; |
| | m_lastBlock = nullptr; |
| |
|
| | m_blockModel = new QG_BlockModel(this); |
| |
|
| | m_proxyModel = new QSortFilterProxyModel(this); |
| | m_proxyModel->setSourceModel(m_blockModel); |
| | m_proxyModel->setFilterKeyColumn(QG_BlockModel::NAME); |
| | m_proxyModel->setDynamicSortFilter(false); |
| |
|
| | m_blockView = new QTableView(this); |
| | m_blockView->setModel (m_proxyModel); |
| | m_blockView->setShowGrid (false); |
| | m_blockView->setSelectionMode(QAbstractItemView::ExtendedSelection); |
| | m_blockView->setEditTriggers(QAbstractItemView::NoEditTriggers); |
| | m_blockView->setFocusPolicy(Qt::NoFocus); |
| | m_blockView->setColumnWidth(QG_BlockModel::VISIBLE, 20); |
| | m_blockView->verticalHeader()->hide(); |
| | m_blockView->horizontalHeader()->setStretchLastSection(true); |
| | m_blockView->horizontalHeader()->hide(); |
| |
|
| | #ifndef DONT_FORCE_WIDGETS_CSS |
| | blockView->setStyleSheet("QWidget {background-color: white;} QScrollBar{ background-color: none }"); |
| | #endif |
| | auto* lay = new QVBoxLayout(this); |
| | lay->setSpacing ( 2 ); |
| | lay->setContentsMargins(2, 2, 2, 2); |
| |
|
| | auto layButtons = new LC_FlexLayout(0,5,5); |
| |
|
| | addToolbarButton(layButtons, RS2::ActionBlocksDefreezeAll); |
| | addToolbarButton(layButtons, RS2::ActionBlocksFreezeAll); |
| | addToolbarButton(layButtons, RS2::ActionBlocksCreate); |
| | addToolbarButton(layButtons, RS2::ActionBlocksAdd); |
| | addToolbarButton(layButtons, RS2::ActionBlocksRemove); |
| | addToolbarButton(layButtons, RS2::ActionBlocksAttributes); |
| | addToolbarButton(layButtons, RS2::ActionBlocksEdit); |
| | addToolbarButton(layButtons, RS2::ActionBlocksSave); |
| | addToolbarButton(layButtons, RS2::ActionBlocksInsert); |
| |
|
| | |
| | m_matchBlockName = new QLineEdit(this); |
| | m_matchBlockName->setReadOnly(false); |
| | m_matchBlockName->setPlaceholderText(tr("Filter")); |
| | m_matchBlockName->setClearButtonEnabled(true); |
| | m_matchBlockName->setToolTip(tr("Looking for matching block names")); |
| | connect(m_matchBlockName, &QLineEdit::textChanged, this, &QG_BlockWidget::slotUpdateBlockList); |
| |
|
| | lay->addWidget(m_matchBlockName); |
| | lay->addLayout(layButtons); |
| | |
| | lay->addWidget(m_blockView); |
| |
|
| | connect(m_blockView, &QTableView::clicked, this, &QG_BlockWidget::slotActivated); |
| | connect(m_blockView->selectionModel(), &QItemSelectionModel::selectionChanged, |
| | this, &QG_BlockWidget::slotSelectionChanged); |
| |
|
| | updateWidgetSettings(); |
| | } |
| |
|
| | void QG_BlockWidget::addToolbarButton(LC_FlexLayout* layButtons, RS2::ActionType actionType) { |
| | QAction* action = m_actionGroupManager->getActionByType(actionType); |
| | if (action != nullptr) { |
| | auto button = new QToolButton(this); |
| | button->setDefaultAction(action); |
| | layButtons->addWidget(button); |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_BlockWidget::update() { |
| | RS_DEBUG->print("QG_BlockWidget::update()"); |
| |
|
| | if (m_blockList==nullptr) { |
| | RS_DEBUG->print("QG_BlockWidget::update(): blockList is nullptr"); |
| | m_blockModel->setActiveBlock(nullptr); |
| | m_blockModel->setBlockList(nullptr); |
| | m_lastBlock = nullptr; |
| | return; |
| | } |
| |
|
| | RS_Block* activeBlock =m_blockList->getActive(); |
| |
|
| | m_blockModel->setBlockList(m_blockList); |
| |
|
| | RS_Block* b = m_lastBlock; |
| | activateBlock(activeBlock); |
| | m_lastBlock = b; |
| | m_blockView->resizeRowsToContents(); |
| |
|
| | restoreSelections(); |
| |
|
| | RS_DEBUG->print("QG_BlockWidget::update() done"); |
| | } |
| |
|
| |
|
| | void QG_BlockWidget::restoreSelections() const { |
| | QItemSelectionModel* selectionModel = m_blockView->selectionModel(); |
| | selectionModel->clearSelection(); |
| |
|
| | for (auto block : *m_blockList) { |
| | if (block == nullptr || !block->isSelectedInBlockList()) { |
| | continue; |
| | } |
| | QModelIndex sourceIdx = m_blockModel->getIndex(block); |
| | if (!sourceIdx.isValid()) { |
| | continue; |
| | } |
| | QModelIndex proxyIdx = m_proxyModel->mapFromSource(sourceIdx); |
| | if (proxyIdx.isValid()) { |
| | QItemSelection selection(proxyIdx, proxyIdx); |
| | selectionModel->select(selection, QItemSelectionModel::Select); |
| | } |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | void QG_BlockWidget::activateBlock(RS_Block* block) { |
| | RS_DEBUG->print("QG_BlockWidget::activateBlock()"); |
| |
|
| | if (block == nullptr || m_blockList == nullptr || m_proxyModel == nullptr) { |
| | return; |
| | } |
| |
|
| | m_lastBlock = m_blockList->getActive(); |
| | m_blockList->activate(block); |
| | int yPos = m_blockView->verticalScrollBar()->value(); |
| | QModelIndex sourceIdx = m_blockModel->getIndex(block); |
| | if (!sourceIdx.isValid()) { |
| | return; |
| | } |
| | QModelIndex proxyIdx = m_proxyModel->mapFromSource(sourceIdx); |
| |
|
| | |
| | bool selected = block->isSelectedInBlockList(); |
| |
|
| | if (proxyIdx.isValid()) { |
| | m_blockView->setCurrentIndex(proxyIdx); |
| | } |
| | m_blockModel->setActiveBlock(block); |
| | m_blockView->viewport()->update(); |
| |
|
| | |
| | QItemSelectionModel::SelectionFlag selFlag = selected ? QItemSelectionModel::Select : QItemSelectionModel::Deselect; |
| | block->selectedInBlockList(selected); |
| | if (proxyIdx.isValid()) { |
| | m_blockView->selectionModel()->select(QItemSelection(proxyIdx, proxyIdx), selFlag); |
| | } |
| | m_blockView->verticalScrollBar()->setValue(yPos); |
| | } |
| |
|
| | |
| | |
| | |
| | void QG_BlockWidget::slotActivated(const QModelIndex &blockIdx) { |
| | if (!blockIdx.isValid() || m_blockList == nullptr || m_proxyModel == nullptr) { |
| | return; |
| | } |
| |
|
| | QModelIndex sourceIdx = m_proxyModel->mapToSource(blockIdx); |
| | if (!sourceIdx.isValid()) { |
| | return; |
| | } |
| |
|
| | RS_Block* block = m_blockModel->getBlock(sourceIdx.row()); |
| | if (block == nullptr) { |
| | return; |
| | } |
| |
|
| | if (sourceIdx.column() == QG_BlockModel::VISIBLE) { |
| | RS_Block* b = m_blockList->getActive(); |
| | m_blockList->activate(block); |
| | m_actionHandler->setCurrentAction(RS2::ActionBlocksToggleView); |
| | activateBlock(b); |
| | return; |
| | } |
| |
|
| | if (sourceIdx.column() == QG_BlockModel::NAME) { |
| | m_lastBlock = m_blockList->getActive(); |
| | activateBlock(block); |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_BlockWidget::slotSelectionChanged( |
| | const QItemSelection &selected, |
| | const QItemSelection &deselected) const { |
| | if (m_proxyModel == nullptr) { |
| | return; |
| | } |
| |
|
| | |
| | foreach (QModelIndex proxyIdx, selected.indexes()) { |
| | QModelIndex sourceIdx = m_proxyModel->mapToSource(proxyIdx); |
| | if (sourceIdx.isValid()) { |
| | RS_Block* block = m_blockModel->getBlock(sourceIdx.row()); |
| | if (block != nullptr) { |
| | block->selectedInBlockList(true); |
| | } |
| | } |
| | } |
| |
|
| | |
| | foreach (QModelIndex proxyIdx, deselected.indexes()) { |
| | QModelIndex sourceIdx = m_proxyModel->mapToSource(proxyIdx); |
| | if (sourceIdx.isValid()) { |
| | RS_Block* block = m_blockModel->getBlock(sourceIdx.row()); |
| | if (block != nullptr) { |
| | block->selectedInBlockList(false); |
| | } |
| | } |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_BlockWidget::contextMenuEvent(QContextMenuEvent *e) { |
| | |
| | |
| | auto contextMenu = std::make_unique<QMenu>(this); |
| | auto menu = contextMenu.get(); |
| | |
| | addMenuItem(menu, RS2::ActionBlocksDefreezeAll); |
| | addMenuItem(menu, RS2::ActionBlocksFreezeAll); |
| | contextMenu->addSeparator(); |
| | |
| | addMenuItem(menu, RS2::ActionBlocksToggleView); |
| | addMenuItem(menu, RS2::ActionBlocksRemove); |
| | contextMenu->addSeparator(); |
| | |
| | addMenuItem(menu, RS2::ActionBlocksAdd); |
| | addMenuItem(menu, RS2::ActionBlocksAttributes); |
| | addMenuItem(menu, RS2::ActionBlocksEdit); |
| | addMenuItem(menu, RS2::ActionBlocksInsert); |
| | addMenuItem(menu, RS2::ActionBlocksCreate); |
| | contextMenu->exec(QCursor::pos()); |
| | e->accept(); |
| | } |
| |
|
| | void QG_BlockWidget::addMenuItem(QMenu* contextMenu, RS2::ActionType actionType) { |
| | auto action = m_actionGroupManager->getActionByType(actionType); |
| | if (action != nullptr) { |
| | contextMenu->addAction(action); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | void QG_BlockWidget::keyPressEvent(QKeyEvent* e) { |
| | switch (e->key()) { |
| | case Qt::Key_Escape: |
| | emit escape(); |
| | break; |
| |
|
| | default: |
| | QWidget::keyPressEvent(e); |
| | break; |
| | } |
| | } |
| |
|
| |
|
| | void QG_BlockWidget::blockAdded(RS_Block*) { |
| | update(); |
| | if (! m_matchBlockName->text().isEmpty()) { |
| | slotUpdateBlockList(); |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_BlockWidget::slotUpdateBlockList() const { |
| | if (m_blockList == nullptr || m_proxyModel == nullptr) { |
| | return; |
| | } |
| |
|
| | QString input = m_matchBlockName->text(); |
| | if (input.isEmpty()) { |
| | m_proxyModel->setFilterRegularExpression(QRegularExpression("")); |
| | } else { |
| | bool hasPattern = input.contains('*') || input.contains('?'); |
| | if (!hasPattern) { |
| | input = "*" + input + "*"; |
| | } |
| | QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(input), QRegularExpression::CaseInsensitiveOption); |
| | m_proxyModel->setFilterRegularExpression(rx); |
| | } |
| |
|
| | restoreSelections(); |
| | } |
| |
|
| | void QG_BlockWidget::updateWidgetSettings() const { |
| | LC_GROUP("Widgets"); { |
| | bool flatIcons = LC_GET_BOOL("DockWidgetsFlatIcons", true); |
| | int iconSize = LC_GET_INT("DockWidgetsIconSize", 16); |
| |
|
| | QSize size(iconSize, iconSize); |
| |
|
| | QList<QToolButton *> widgets = this->findChildren<QToolButton *>(); |
| | foreach(QToolButton *w, widgets) { |
| | w->setAutoRaise(flatIcons); |
| | w->setIconSize(size); |
| | } |
| | } |
| | LC_GROUP_END(); |
| | } |
| |
|
| | void QG_BlockWidget::setGraphicView(RS_GraphicView* gv){ |
| | if (gv == nullptr) { |
| | setBlockList(nullptr); |
| | } |
| | else { |
| | auto graphic = gv->getGraphic(); |
| | if (graphic == nullptr) { |
| | setBlockList(nullptr); |
| | } |
| | else { |
| | setBlockList(graphic->getBlockList()); |
| | } |
| | } |
| | } |
| |
|
| | void QG_BlockWidget::setBlockList(RS_BlockList* blockList) { |
| | if (m_blockList != nullptr) { |
| | m_blockList->removeListener(this); |
| | } |
| | m_blockList = blockList; |
| | if (blockList != nullptr) { |
| | m_blockList->addListener(this); |
| | } |
| | update(); |
| | } |
| | |
| |
|