File indexing completed on 2024-05-05 05:46:20
0001 /*************************************************************************** 0002 * Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at> * 0003 * Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> * 0004 * Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl> * 0005 * Copyright (C) 2006 David Saxton <david@bluehaze.org> * 0006 * * 0007 * This program is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 ***************************************************************************/ 0012 0013 #include "propertyeditor.h" 0014 #include "item.h" 0015 #include "itemgroup.h" 0016 #include "iteminterface.h" 0017 #include "ktechlab.h" 0018 #include "propertyeditorcolor.h" 0019 #include "propertyeditorfile.h" 0020 #include "propertyeditorinput.h" 0021 #include "propertyeditorlist.h" 0022 0023 #include "drawparts/drawpart.h" 0024 0025 #include <KIconLoader> 0026 #include <KLocalizedString> 0027 0028 #include <QApplication> 0029 #include <QEvent> 0030 #include <QFontMetrics> 0031 #include <QHeaderView> 0032 #include <QIcon> 0033 #include <QPushButton> 0034 #include <QStyledItemDelegate> 0035 #include <QTimer> 0036 0037 #include <ktechlab_debug.h> 0038 0039 struct PropertyEditorStyledItemColProperty : public QStyledItemDelegate { 0040 PropertyEditor *m_propEditor; 0041 0042 PropertyEditorStyledItemColProperty(PropertyEditor *propEditor) 0043 : QStyledItemDelegate(propEditor) 0044 , m_propEditor(propEditor) 0045 { 0046 } 0047 0048 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override 0049 { 0050 // if ( depth() == 0 ) 0051 // return; 0052 QTableWidgetItem *itemPtr = m_propEditor->item(index.row(), index.column()); 0053 if (!itemPtr) { 0054 qCWarning(KTL_LOG) << " null item"; 0055 return; 0056 } 0057 PropertyEditorItem *itemProp = dynamic_cast<PropertyEditorItem *>(itemPtr); 0058 if (!itemProp) { 0059 qCWarning(KTL_LOG) << " cannot cast item"; 0060 return; 0061 } 0062 0063 m_propEditor->contentsMargins(); 0064 int margin = 3; // listView()->itemMargin(); // TODO set decent value 0065 0066 const int width = option.rect.width(); 0067 const int height = option.rect.height(); 0068 const int top = option.rect.top(); 0069 const int left = option.rect.left(); 0070 0071 const bool isHighlighted = m_propEditor->currentRow() == index.row(); 0072 0073 painter->save(); 0074 0075 // qCWarning(KTL_LOG) << " draw col " << index.column() << " row " << index.row() 0076 // << " isHighlighted=" << isHighlighted << " state_selected=" << option.state.testFlag(QStyle::State_Selected); 0077 0078 if (isHighlighted || option.state.testFlag(QStyle::State_Selected)) { 0079 painter->fillRect(left, top, width, height, option.palette.highlight()); 0080 painter->setPen(option.palette.color(QPalette::BrightText) /* highlightedText() */); 0081 } else { 0082 QColor bgColor = option.palette.color(QPalette::Base); // 2018.12.07 0083 painter->fillRect(left, top, width, height, QBrush(bgColor)); 0084 } 0085 0086 QFont f = option.font; 0087 0088 if (itemProp->property()->changed() || (!itemProp->property()->isAdvanced())) { 0089 f.setBold(true); 0090 } 0091 0092 painter->setFont(f); 0093 painter->drawText(QRect(left + margin, top, width - 1, height - 1), Qt::AlignVCenter, itemProp->text()); 0094 0095 // qCWarning(KTL_LOG) << " draw " << itemProp->text() << " at " << option.rect; 0096 0097 painter->setPen(QColor(200, 200, 200)); // like in table view 0098 painter->drawLine(left + width - 1, top, left + width - 1, top + height - 1); 0099 0100 painter->setPen(QColor(200, 200, 200)); // like in t.v. 0101 painter->drawLine(left - 50, top + height - 1, left + width - 1, top + height - 1); 0102 0103 painter->restore(); 0104 } 0105 /* 0106 virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { 0107 // TODO 0108 } 0109 */ 0110 }; 0111 0112 struct PropertyEditorStyledItemColValue : public QStyledItemDelegate { 0113 PropertyEditor *m_propEditor; 0114 0115 PropertyEditorStyledItemColValue(PropertyEditor *propEditor) 0116 : QStyledItemDelegate(propEditor) 0117 , m_propEditor(propEditor) 0118 { 0119 } 0120 0121 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override 0122 { 0123 // if ( depth() == 0 ) 0124 // return; 0125 0126 QTableWidgetItem *itemPtr = m_propEditor->item(index.row(), index.column()); 0127 if (!itemPtr) { 0128 qCWarning(KTL_LOG) << " null item"; 0129 return; 0130 } 0131 PropertyEditorItem *itemProp = dynamic_cast<PropertyEditorItem *>(itemPtr); 0132 if (!itemProp) { 0133 qCWarning(KTL_LOG) << " cannot cast item"; 0134 return; 0135 } 0136 0137 int margin = 3; // listView()->itemMargin(); // TODO set decent value 0138 0139 const int width = option.rect.width(); 0140 const int height = option.rect.height(); 0141 const int top = option.rect.top(); 0142 const int left = option.rect.left(); 0143 0144 // const bool isHighlighted = m_propEditor->currentRow() == index.row(); // TODO 0145 0146 QColor bgColor = option.palette.color(QPalette::Window); // backgroundColor(0); // 2018.06.02 - is this better? 0147 0148 painter->save(); 0149 0150 Property *property = itemProp->property(); 0151 switch (property->type()) { 0152 // case QVariant::Pixmap: 0153 // { 0154 // p->fillRect(0,0,width,height(),QBrush(backgroundColor())); 0155 // p->drawPixmap(margin, margin, m_property->value().toPixmap()); 0156 // break; 0157 // } 0158 0159 case Variant::Type::Color: { 0160 painter->fillRect(left, top, width, height, QBrush(bgColor)); 0161 // QColor ncolor = m_property->value().toColor(); 0162 QColor ncolor = property->value().value<QColor>(); 0163 painter->setBrush(ncolor); 0164 painter->drawRect(left + margin, top + margin, width - 2 * margin, height - 2 * margin); 0165 // QColorGroup nGroup(cg); 0166 break; 0167 } 0168 0169 case Variant::Type::Bool: { 0170 painter->fillRect(left, top, width, height, QBrush(bgColor)); 0171 if (property->value().toBool()) { 0172 QIcon dialogOkIcon = QIcon::fromTheme("dialog-ok"); 0173 QPixmap okPixmap = dialogOkIcon.pixmap(KIconLoader::SizeSmall); 0174 painter->drawPixmap(left + margin, top + height / 2 - 8, okPixmap); 0175 painter->drawText(QRect(left + margin + 20, top, width, height - 1), Qt::AlignVCenter, i18n("Yes")); 0176 } else { 0177 QIcon dialogCancelIcon = QIcon::fromTheme("dialog-cancel"); 0178 QPixmap cancelPixmap = dialogCancelIcon.pixmap(KIconLoader::SizeSmall); 0179 painter->drawPixmap(left + margin, top + height / 2 - 8, cancelPixmap); 0180 painter->drawText(QRect(left + margin + 20, top, width, height - 1), Qt::AlignVCenter, i18n("No")); 0181 } 0182 break; 0183 } 0184 0185 case Variant::Type::PenStyle: { 0186 painter->fillRect(left, top, width, height, QBrush(bgColor)); 0187 0188 Qt::PenStyle style = DrawPart::nameToPenStyle(property->value().toString()); 0189 int penWidth = 3; 0190 QPen pen(Qt::black, penWidth, style); 0191 painter->setPen(pen); 0192 painter->drawLine(left + height / 2, top + height / 2 - 1, left + width - height / 2, top + height / 2 - 1); 0193 break; 0194 } 0195 0196 #if 0 0197 case Variant::Type::PenCapStyle: 0198 { 0199 p->fillRect(0,0,width,height, QBrush(bgColor)); 0200 0201 PenCapStyle style = DrawPart::nameToPenCapStyle( property->value().toString() ); 0202 int penWidth = 6; 0203 QPen pen( black, penWidth, SolidLine, style, MiterJoin ); 0204 p->setPen( pen ); 0205 p->drawLine( width/2-10, height/2-2, width/2+10, height/2-2 ); 0206 break; 0207 } 0208 #endif 0209 0210 case Variant::Type::None: 0211 case Variant::Type::Int: 0212 case Variant::Type::Raw: 0213 case Variant::Type::Double: 0214 case Variant::Type::String: 0215 case Variant::Type::Multiline: 0216 case Variant::Type::RichText: 0217 case Variant::Type::Select: 0218 case Variant::Type::Combo: 0219 case Variant::Type::FileName: 0220 case Variant::Type::VarName: 0221 case Variant::Type::PenCapStyle: 0222 case Variant::Type::Port: 0223 case Variant::Type::Pin: 0224 case Variant::Type::SevenSegment: 0225 case Variant::Type::KeyPad: { 0226 QStyledItemDelegate::paint(painter, option, index); 0227 break; 0228 } 0229 } 0230 0231 painter->setPen(QColor(200, 200, 200)); // like in t.v. 0232 painter->drawLine(left - 50, top + height - 1, left + width, top + height - 1); 0233 0234 painter->restore(); 0235 } 0236 /* 0237 virtual QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { 0238 // TODO 0239 } 0240 */ 0241 }; 0242 0243 PropertyEditor::PropertyEditor(QWidget *parent) 0244 : QTableWidget(parent) 0245 //, m_items(101, false) // 2018.08.13 - unused 0246 , justClickedItem(false) 0247 , m_lastCellWidgetRow(-1) 0248 , m_lastCellWidgetCol(-1) 0249 , m_colPropertyDelegate(nullptr) 0250 , m_colValueDelegate(nullptr) 0251 { 0252 // m_items.setAutoDelete(false); // 2018.08.13 - unused 0253 0254 setColumnCount(2); 0255 QStringList headerLabels; 0256 headerLabels.append(i18n("Property")); 0257 headerLabels.append(i18n("Value")); 0258 setHorizontalHeaderLabels(headerLabels); 0259 // addColumn( i18n("Property") ); // 2018.08.13 - ported to QTableWidget 0260 // addColumn( i18n("Value") ); 0261 0262 m_colPropertyDelegate = new PropertyEditorStyledItemColProperty(this); 0263 setItemDelegateForColumn(0, m_colPropertyDelegate); 0264 0265 m_colValueDelegate = new PropertyEditorStyledItemColValue(this); 0266 setItemDelegateForColumn(1, m_colValueDelegate); 0267 0268 m_topItem = nullptr; 0269 m_editItem = nullptr; 0270 0271 connect(this, &PropertyEditor::clicked, this, &PropertyEditor::slotClicked); 0272 connect(this, &PropertyEditor::itemActivated, this, &PropertyEditor::slotCurrentChanged); 0273 // connect(this, SIGNAL(expanded(Q3ListViewItem *)), this, SLOT(slotExpanded(Q3ListViewItem *))); // TODO 0274 // connect(this, SIGNAL(collapsed(Q3ListViewItem *)), this, SLOT(slotCollapsed(Q3ListViewItem *))); 0275 0276 // connect(this, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(slotCurrentCellChanged(int, int, int, int))); 0277 connect(this, &PropertyEditor::currentCellChanged, this, &PropertyEditor::slotCurrentCellChanged); 0278 0279 // connect(header(), SIGNAL(sizeChange( int, int, int )), this, SLOT(slotColumnSizeChanged( int, int, int ))); // TODO 0280 // connect(header(), SIGNAL(clicked( int )), this, SLOT(moveEditor())); 0281 // connect(header(), SIGNAL(sectionHandleDoubleClicked ( int )), this, SLOT(slotColumnSizeChanged( int ))); 0282 0283 m_defaults = new QPushButton(viewport()); 0284 m_defaults->setFocusPolicy(Qt::NoFocus); 0285 setFocusPolicy(Qt::ClickFocus); 0286 m_defaults->setIcon(QIcon::fromTheme("edit-undo")); 0287 m_defaults->setToolTip(i18n("Undo changes")); 0288 m_defaults->hide(); 0289 connect(m_defaults, &QPushButton::clicked, this, &PropertyEditor::resetItem); 0290 0291 // TODO 0292 const int itemMargin = 2; 0293 // setRootIsDecorated( false ); 0294 // setShowSortIndicator( false ); 0295 // setTooltipColumn(0); // TODO equivalent? 0296 setSortingEnabled(false /*true*/); // note: enabling it causes crashes, apperently 0297 horizontalHeader()->setSortIndicatorShown(false); 0298 horizontalHeader()->setContentsMargins(itemMargin, itemMargin, itemMargin, itemMargin); 0299 // setItemMargin(2); // needed? 0300 horizontalHeader()->setSectionResizeMode(QHeaderView::QHeaderView::Stretch); 0301 horizontalHeader()->setSectionsMovable(false); 0302 // header()->setMovingEnabled( false ); 0303 verticalHeader()->setVisible(false); 0304 // setTreeStepSize(0); 0305 setSelectionMode(QAbstractItemView::SingleSelection); 0306 0307 m_baseRowHeight = QFontMetrics(font()).height() + itemMargin * 2; 0308 } 0309 0310 PropertyEditor::~PropertyEditor() 0311 { 0312 // note: delete m_colPropertyDelegate and m_colValueDelegate 0313 } 0314 0315 void PropertyEditor::slotClicked(const QModelIndex &index) 0316 { 0317 if (!index.isValid()) 0318 return; 0319 0320 // 2019.01.19 - moved to slotCurrentCellChanged() 0321 // if (index.column() == 1) { 0322 // // PropertyEditorItem *i = static_cast<PropertyEditorItem *>(item);// 2018.08.13 - not needed 0323 // createEditor(index); 0324 // } 0325 0326 justClickedItem = true; 0327 } 0328 0329 void PropertyEditor::slotCurrentChanged(QTableWidgetItem * /*itemParam*/) 0330 { 0331 // TODO 0332 // if (itemParam == firstChild()) 0333 // { 0334 // Q3ListViewItem *oldItem = item; 0335 // while (item && (!item->isSelectable() || !item->isVisible())) 0336 // item = item->itemBelow(); 0337 // 0338 // if (item && item!=oldItem) 0339 // { 0340 // setSelected(item,true); 0341 // return; 0342 // } 0343 // } 0344 } 0345 0346 void PropertyEditor::slotCurrentCellChanged(int currentRow, int currentColumn, int /*previousRow*/, int /*previousColumn*/) 0347 { 0348 viewport()->repaint(); // force a repaint to clear the "selected" background on items 0349 0350 if (currentColumn == 0) { 0351 setCurrentCell(currentRow, 1); // move focus to the value column 0352 } 0353 if (currentColumn == 1) { 0354 createEditor(currentIndex()); 0355 } 0356 } 0357 0358 void PropertyEditor::slotExpanded(QTableWidgetItem *item) 0359 { 0360 if (!item) 0361 return; 0362 moveEditor(); 0363 } 0364 0365 void PropertyEditor::slotCollapsed(QTableWidgetItem *item) 0366 { 0367 if (!item) 0368 return; 0369 moveEditor(); 0370 } 0371 0372 void PropertyEditor::createEditor(const QModelIndex &index) 0373 { 0374 PropertyEditorItem *i = dynamic_cast<PropertyEditorItem *>(item(index.row(), index.column())); 0375 if (!i) { 0376 qCWarning(KTL_LOG) << "no item"; 0377 return; 0378 } 0379 0380 // int y = viewportToContents(QPoint(0, itemRect(i).y())).y(); 0381 // QRect geometry(columnWidth(0), y, columnWidth(1), i->height()); 0382 0383 // delete m_currentEditor; 0384 // m_currentEditor->deleteLater(); 0385 if (m_lastCellWidgetRow >= 0 && m_lastCellWidgetCol >= 0) { 0386 removeCellWidget(m_lastCellWidgetRow, m_lastCellWidgetCol); 0387 m_lastCellWidgetRow = -1; 0388 m_lastCellWidgetCol = -1; 0389 } 0390 m_currentEditor = nullptr; 0391 0392 m_editItem = i; 0393 0394 PropertySubEditor *editor = nullptr; 0395 switch (i->type()) { 0396 case Variant::Type::String: 0397 editor = new PropertyEditorInput(viewport(), i->property()); 0398 break; 0399 0400 case Variant::Type::Port: 0401 case Variant::Type::Pin: 0402 case Variant::Type::Combo: 0403 case Variant::Type::VarName: 0404 case Variant::Type::Select: 0405 case Variant::Type::PenStyle: 0406 case Variant::Type::PenCapStyle: 0407 case Variant::Type::SevenSegment: 0408 case Variant::Type::KeyPad: 0409 editor = new PropertyEditorList(viewport(), i->property()); 0410 break; 0411 0412 case Variant::Type::FileName: 0413 qCDebug(KTL_LOG) << "creating PropertyEditorFile"; 0414 editor = new PropertyEditorFile(viewport(), i->property()); 0415 break; 0416 0417 case Variant::Type::Int: 0418 editor = new PropertyEditorSpin(viewport(), i->property()); 0419 break; 0420 0421 case Variant::Type::Double: 0422 editor = new PropertyEditorDblSpin(viewport(), i->property()); 0423 break; 0424 0425 case Variant::Type::Color: 0426 editor = new PropertyEditorColor(viewport(), i->property()); 0427 break; 0428 0429 case Variant::Type::Bool: 0430 editor = new PropertyEditorBool(viewport(), i->property()); 0431 break; 0432 0433 case Variant::Type::Raw: 0434 case Variant::Type::Multiline: 0435 case Variant::Type::RichText: 0436 case Variant::Type::None: 0437 break; 0438 } 0439 0440 if (editor) { 0441 // addChild(editor); 0442 // moveChild(editor, geometry.x(), geometry.y()); 0443 m_lastCellWidgetRow = index.row(); 0444 m_lastCellWidgetCol = index.column(); 0445 setCellWidget(index.row(), index.column(), editor); 0446 editor->show(); 0447 0448 editor->setFocus(); 0449 } 0450 0451 m_currentEditor = editor; 0452 showDefaultsButton(i->property()->changed()); 0453 } 0454 0455 void PropertyEditor::showDefaultsButton(bool show) 0456 { 0457 QRect editItemRect = visualItemRect(m_editItem); 0458 int y = editItemRect.y(); // viewportToContents(QPoint(0, itemRect(m_editItem).y())).y(); // TODO 0459 QRect geometry(columnWidth(0), y, columnWidth(1), editItemRect.height() /* m_editItem->height() TOOD */); 0460 m_defaults->resize(m_baseRowHeight, m_baseRowHeight); 0461 0462 if (!show) { 0463 if (m_currentEditor) { 0464 if (m_currentEditor->leavesTheSpaceForRevertButton()) { 0465 geometry.setWidth(geometry.width() - m_defaults->width()); 0466 } 0467 m_currentEditor->resize(geometry.width(), geometry.height()); 0468 } 0469 m_defaults->hide(); 0470 return; 0471 } 0472 0473 QPoint p = geometry.topLeft(); // = contentsToViewport(QPoint(0, geometry.y())); // TODO 0474 m_defaults->move(geometry.x() + geometry.width() - m_defaults->width(), p.y()); 0475 if (m_currentEditor) { 0476 m_currentEditor->move(m_currentEditor->x(), p.y()); 0477 m_currentEditor->resize(geometry.width() - m_defaults->width(), geometry.height()); 0478 } 0479 m_defaults->show(); 0480 } 0481 0482 void PropertyEditor::updateDefaultsButton() 0483 { 0484 QTableWidgetItem *currItem = currentItem(); 0485 if (!currItem) { 0486 m_editItem = nullptr; 0487 return; 0488 } 0489 m_editItem = dynamic_cast<PropertyEditorItem*>(currItem); 0490 if (!m_editItem) { 0491 qCWarning(KTL_LOG) << "failed to cast current item to PropertyEditorItem, " << currItem; 0492 return; 0493 } 0494 qCDebug(KTL_LOG) << "currentItem=" << currentItem(); 0495 qCDebug(KTL_LOG) << "m_editItem=" << m_editItem; 0496 qCDebug(KTL_LOG) << "m_editItem->property=" << m_editItem->property(); 0497 showDefaultsButton(m_editItem->property()->changed()); 0498 repaint(); // m_editItem->repaint(); 0499 } 0500 0501 void PropertyEditor::slotColumnSizeChanged(int section, int, int newS) 0502 { 0503 if (m_currentEditor) { 0504 if (section == 0) { 0505 m_currentEditor->move(newS, m_currentEditor->y()); 0506 } else { 0507 if (m_defaults->isVisible()) 0508 m_currentEditor->resize(newS - m_defaults->width(), m_currentEditor->height()); 0509 else 0510 m_currentEditor->resize(newS - (m_currentEditor->leavesTheSpaceForRevertButton() ? m_defaults->width() : 0), m_currentEditor->height()); 0511 } 0512 } 0513 } 0514 0515 void PropertyEditor::slotColumnSizeChanged(int section) 0516 { 0517 setColumnWidth(1, viewport()->width() - columnWidth(0)); 0518 slotColumnSizeChanged(section, 0, horizontalHeader()->sectionSize(section)); 0519 if (m_currentEditor) { 0520 if (m_defaults->isVisible()) 0521 m_currentEditor->resize(columnWidth(1) - m_defaults->width(), m_currentEditor->height()); 0522 else 0523 m_currentEditor->resize(columnWidth(1) - (m_currentEditor->leavesTheSpaceForRevertButton() ? m_defaults->width() : 0), m_currentEditor->height()); 0524 } 0525 } 0526 0527 void PropertyEditor::reset() 0528 { 0529 // if ( m_currentEditor ) 0530 // m_currentEditor->deleteLater(); 0531 if (m_lastCellWidgetRow >= 0 && m_lastCellWidgetCol >= 0) { 0532 removeCellWidget(m_lastCellWidgetRow, m_lastCellWidgetCol); 0533 m_lastCellWidgetRow = -1; 0534 m_lastCellWidgetCol = -1; 0535 } 0536 m_currentEditor = nullptr; 0537 0538 if (m_defaults->isVisible()) 0539 m_defaults->hide(); 0540 0541 // clear(); 0542 QTableWidget::reset(); 0543 m_editItem = nullptr; 0544 m_topItem = nullptr; 0545 } 0546 0547 QSize PropertyEditor::sizeHint() const 0548 { 0549 return QSize(QFontMetrics(font()).horizontalAdvance(horizontalHeaderItem(0)->text() + horizontalHeaderItem(1)->text() + " "), QTableWidget::sizeHint().height()); 0550 } 0551 0552 void PropertyEditor::create(ItemGroup *b) 0553 { 0554 qCDebug(KTL_LOG) << "b=" << b; 0555 m_pItemGroup = b; 0556 0557 // QCString selectedPropertyName1, selectedPropertyName2; 0558 // QByteArray selectedPropertyName1, selectedPropertyName2; // 2018.08. 13 - dead code 0559 0560 fill(); 0561 /* 2018.08. 13 - dead code 0562 //select prev. selecteed item 0563 PropertyEditorItem * item = 0; 0564 if (!selectedPropertyName2.isEmpty()) //try other one for old buffer 0565 item = m_items[selectedPropertyName2]; 0566 if (!item && !selectedPropertyName1.isEmpty()) //try old one for current buffer 0567 item = m_items[selectedPropertyName1]; 0568 if (item) 0569 { 0570 setItemSelected(item, true); 0571 scrollToItem(item); 0572 } else { 0573 qCWarning(KTL_LOG) << "no item to select "; 0574 } 0575 */ 0576 qCDebug(KTL_LOG) << "column count= " << columnCount() << "rowCount=" << rowCount(); 0577 } 0578 0579 void PropertyEditor::fill() 0580 { 0581 reset(); 0582 0583 if (!m_pItemGroup || !m_pItemGroup->activeItem()) { 0584 qCWarning(KTL_LOG) << " no active item " << m_pItemGroup; 0585 return; 0586 } 0587 0588 if (!m_topItem) { 0589 m_topItem = new PropertyEditorItem(this, "Top Item"); 0590 } 0591 0592 // m_items.clear(); // 2018.08.13 - unused 0593 setRowCount(0); // remove all items from the table 0594 0595 VariantDataMap *vmap = m_pItemGroup->activeItem()->variantMap(); 0596 // Build the list 0597 for (VariantDataMap::iterator vait = vmap->begin(); vait != vmap->end(); ++vait) { 0598 Variant *v = *vait; 0599 if (v->isHidden()) { 0600 continue; 0601 } 0602 qCDebug(KTL_LOG) << "add variant id=" << v->id() << " v=" << v; 0603 0604 switch (v->type()) { 0605 case Variant::Type::String: 0606 case Variant::Type::Port: 0607 case Variant::Type::Pin: 0608 case Variant::Type::Combo: 0609 case Variant::Type::VarName: 0610 case Variant::Type::Select: 0611 case Variant::Type::PenStyle: 0612 case Variant::Type::PenCapStyle: 0613 case Variant::Type::SevenSegment: 0614 case Variant::Type::KeyPad: 0615 case Variant::Type::FileName: 0616 case Variant::Type::Int: 0617 case Variant::Type::Double: 0618 case Variant::Type::Color: 0619 case Variant::Type::Bool: 0620 // These are all handled by the ItemEditor 0621 break; 0622 0623 case Variant::Type::Raw: 0624 case Variant::Type::Multiline: 0625 case Variant::Type::None: 0626 case Variant::Type::RichText: 0627 // These are not handled by the ItemEditor 0628 continue; 0629 } 0630 0631 const int nextRow = rowCount(); 0632 setRowCount(nextRow + 1); 0633 { 0634 QTableWidgetItem *itemPropName = new PropertyEditorItem(m_topItem, v); 0635 itemPropName->setText(v->editorCaption()); 0636 itemPropName->setFlags(Qt::ItemIsEnabled); 0637 setItem(nextRow, 0, itemPropName); 0638 } 0639 { 0640 PropertyEditorItem *itemPropValue = new PropertyEditorItem(m_topItem, v); 0641 itemPropValue->setText(v->displayString()); 0642 connect(v, SIGNAL(valueChanged(QVariant, QVariant)), itemPropValue, SLOT(propertyValueChanged())); 0643 // TODO ‘virtual void PropertyEditorItem::propertyValueChanged()’ is protected within this context 0644 // connect(v, qOverload<QVariant, QVariant>(&Variant::valueChanged), 0645 // itemPropValue, &PropertyEditorItem::propertyValueChanged); 0646 itemPropValue->updateValue(); 0647 setItem(nextRow, 1, itemPropValue); 0648 } 0649 // m_items.insert( v->id().latin1(), item ); // 2018.08.13 - unused 0650 } 0651 } 0652 0653 void PropertyEditor::setFocus() 0654 { 0655 selectedItems(); 0656 PropertyEditorItem *item = static_cast<PropertyEditorItem *>(selectedItem()); 0657 if (item) { 0658 if (!justClickedItem) { 0659 scrollToItem(item); 0660 } 0661 justClickedItem = false; 0662 } else { 0663 // select an item before focusing 0664 item = static_cast<PropertyEditorItem *>(itemAt(QPoint(10, 1))); 0665 if (item) { 0666 scrollToItem(item); // ensureItemVisible(item); 0667 item->setSelected(true); // setSelected(item, true); 0668 } 0669 } 0670 if (m_currentEditor) { 0671 m_currentEditor->setFocus(); 0672 } else { 0673 QTableWidget::setFocus(); 0674 } 0675 } 0676 0677 void PropertyEditor::resetItem() 0678 { 0679 if (m_editItem) { 0680 ItemInterface::self()->slotSetData(m_editItem->property()->id(), m_editItem->property()->defaultValue()); 0681 } 0682 } 0683 0684 void PropertyEditor::moveEditor() 0685 { 0686 if (!m_currentEditor) 0687 return; 0688 0689 QPoint p = QPoint(0, visualItemRect(m_editItem).y()); // = contentsToViewport(QPoint(0, itemPos(m_editItem))); // TODO 0690 m_currentEditor->move(m_currentEditor->x(), p.y()); 0691 if (m_defaults->isVisible()) { 0692 m_defaults->move(m_defaults->x(), p.y()); 0693 } 0694 } 0695 0696 void PropertyEditor::resizeEvent(QResizeEvent *ev) 0697 { 0698 QTableWidget::resizeEvent(ev); 0699 updateDefaultsButton(); 0700 // if(m_defaults->isVisible()) 0701 // { 0702 // rect(); 0703 // QRect r = visualItemRect(m_editItem) ; // = itemRect(m_editItem); // TODO 0704 // if(r.y()) { // r.y() == 0 if the item is not visible on the screen 0705 // m_defaults->move(r.x() + r.width() - m_defaults->width(), r.y()); 0706 // } 0707 // } 0708 // 0709 // if ( m_currentEditor ) 0710 // { 0711 // m_currentEditor->resize( 0712 // columnWidth(1)-((m_currentEditor->leavesTheSpaceForRevertButton()||m_defaults->isVisible()) ? m_defaults->width() : 0), 0713 // m_currentEditor->height()); 0714 // } 0715 } 0716 0717 bool PropertyEditor::handleKeyPress(QKeyEvent * /*ev*/) 0718 { 0719 #if 0 // TODO 0720 const int k = ev->key(); 0721 const Qt::ButtonState s = ev->state(); 0722 0723 //selection moving 0724 QTableWidgetItem *item = 0; 0725 0726 if ((s==Qt::NoButton && k==Qt::Key_Up) || k==Qt::Key_Backtab) { 0727 //find prev visible 0728 item = selectedItem() ? selectedItem()->itemAbove() : 0; 0729 while (item && (!item->flags().testFlag(Qt::ItemIsSelectable) || !item->isVisible())) 0730 item = item->itemAbove(); 0731 if (!item) 0732 return true; 0733 } 0734 else if (s==Qt::NoButton && (k==Qt::Key_Down || k==Qt::Key_Tab)) { 0735 //find next visible 0736 item = selectedItem() ? selectedItem()->itemBelow() : 0; 0737 while (item && (!item->flags().testFlag(Qt::ItemIsSelectable) || !item->isVisible())) 0738 item = item->itemBelow(); 0739 if (!item) 0740 return true; 0741 } 0742 else if(s==Qt::NoButton && k==Qt::Key_Home) { 0743 if (m_currentEditor && m_currentEditor->hasFocus()) 0744 return false; 0745 //find 1st visible 0746 item = firstChild(); 0747 while (item && (!item->flags().testFlag(Qt::ItemIsSelectable) || !item->isVisible())) 0748 item = item->itemBelow(); 0749 } 0750 else if(s==Qt::NoButton && k==Qt::Key_End) { 0751 if (m_currentEditor && m_currentEditor->hasFocus()) 0752 return false; 0753 //find last visible 0754 item = selectedItem(); 0755 Q3ListViewItem *lastVisible = item; 0756 while (item) { // && (!item->isSelectable() || !item->isVisible())) 0757 item = item->itemBelow(); 0758 if (item && item->flags().testFlag(Qt::ItemIsSelectable) && item->isVisible()) 0759 lastVisible = item; 0760 } 0761 item = lastVisible; 0762 } 0763 if(item) { 0764 ev->accept(); 0765 scrollToItem(item); 0766 item->setSelected(true); // setSelected(item, true); 0767 return true; 0768 } 0769 #endif 0770 return false; 0771 } 0772 0773 PropertyEditorItem *PropertyEditor::selectedItem() 0774 { 0775 QModelIndexList selList = selectedIndexes(); 0776 if (selList.empty()) { 0777 return nullptr; 0778 } 0779 if (selList.size() > 1) { 0780 qCWarning(KTL_LOG) << " unexpected selection size of " << selList.size(); 0781 } 0782 QModelIndex selIndex = selList.first(); 0783 PropertyEditorItem *itemProp = dynamic_cast<PropertyEditorItem *>(item(selIndex.row(), selIndex.column())); 0784 if (!itemProp) { 0785 qCWarning(KTL_LOG) << " failed to cast " << selIndex; 0786 } 0787 return itemProp; 0788 } 0789 0790 #include "moc_propertyeditor.cpp"