File indexing completed on 2024-12-22 04:14:59
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Saurabh Kumar <saurabhk660@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "StoryboardDelegate.h" 0008 #include "StoryboardModel.h" 0009 0010 #include <QLineEdit> 0011 #include <QTextEdit> 0012 #include <QDebug> 0013 #include <QStyle> 0014 #include <QPainter> 0015 #include <QApplication> 0016 #include <QSize> 0017 #include <QMouseEvent> 0018 #include <QListView> 0019 #include <QSpinBox> 0020 #include <QScrollBar> 0021 0022 #include <kis_icon.h> 0023 #include <kis_image_animation_interface.h> 0024 #include <commands_new/kis_switch_current_time_command.h> 0025 #include "KisAddRemoveStoryboardCommand.h" 0026 0027 0028 StoryboardDelegate::StoryboardDelegate(QObject *parent) 0029 : QStyledItemDelegate(parent) 0030 , m_view(nullptr) 0031 , m_imageSize(QSize()) 0032 { 0033 } 0034 0035 StoryboardDelegate::~StoryboardDelegate() 0036 { 0037 } 0038 0039 void StoryboardDelegate::paint(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const 0040 { 0041 p->save(); 0042 { 0043 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0044 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, p, option.widget); 0045 0046 p->setFont(option.font); 0047 if (!index.isValid()) { 0048 p->restore(); 0049 return; 0050 } 0051 if (!index.parent().isValid()) { 0052 QRect parentRect = option.rect; 0053 p->setPen(QPen(option.palette.window(), 2)); 0054 p->drawRect(parentRect); 0055 0056 parentRect.setTopLeft(parentRect.topLeft() + QPoint(4, 4)); 0057 parentRect.setBottomRight(parentRect.bottomRight() - QPoint(4, 4)); 0058 0059 if (option.state & QStyle::State_Selected) { 0060 p->fillRect(option.rect, option.palette.highlight()); 0061 } 0062 else { 0063 p->fillRect(option.rect, option.palette.window()); 0064 } 0065 p->eraseRect(parentRect); 0066 } 0067 else { 0068 //draw the child items 0069 int childNum = index.row(); 0070 QString data = index.data().toString(); 0071 0072 switch (childNum) 0073 { 0074 case StoryboardItem::FrameNumber: 0075 { 0076 if (m_view->thumbnailIsVisible()) { 0077 QRect frameNumRect = option.rect; 0078 frameNumRect.setHeight(m_view->fontMetrics().height()+3); 0079 #if QT_VERSION >= QT_VERSION_CHECK(5,11,0) 0080 frameNumRect.setWidth(3 * m_view->fontMetrics().horizontalAdvance("0") + 2); 0081 #else 0082 frameNumRect.setWidth(3 * m_view->fontMetrics().width('0') + 2); 0083 #endif 0084 frameNumRect.moveBottom(option.rect.top()-1); 0085 p->setPen(QPen(option.palette.dark(), 2)); 0086 p->drawRect(frameNumRect); 0087 p->setPen(QPen(option.palette.text(), 1)); 0088 p->drawText(frameNumRect, Qt::AlignHCenter | Qt::AlignVCenter, data); 0089 0090 if (!m_imageSize.isEmpty()) { 0091 float scale = qMin(option.rect.height() / (float)m_imageSize.height(), (float)option.rect.width() / m_imageSize.width()); 0092 QRect thumbnailRect = option.rect; 0093 thumbnailRect.setSize(m_imageSize * scale); 0094 thumbnailRect.moveCenter(option.rect.center()); 0095 0096 QPixmap thumbnailPixmap= index.data(Qt::UserRole).value<QPixmap>(); 0097 p->drawPixmap(thumbnailRect, thumbnailPixmap); 0098 } 0099 p->setPen(QPen(option.palette.dark(), 2)); 0100 p->drawRect(option.rect); 0101 0102 QRect buttonsRect = option.rect; 0103 buttonsRect.setTop(option.rect.bottom() - 22); 0104 0105 buttonsRect.setWidth(22); 0106 buttonsRect.moveBottomLeft(option.rect.bottomLeft()); 0107 QIcon addIcon = KisIconUtils::loadIcon("list-add"); 0108 p->fillRect(buttonsRect, option.palette.window()); 0109 addIcon.paint(p, buttonsRect); 0110 0111 buttonsRect.moveBottomRight(option.rect.bottomRight()); 0112 QIcon deleteIcon = KisIconUtils::loadIcon("edit-delete"); 0113 p->fillRect(buttonsRect, option.palette.window()); 0114 deleteIcon.paint(p, buttonsRect); 0115 } 0116 else { 0117 QRect frameNumRect = option.rect; 0118 p->setPen(QPen(option.palette.dark(), 2)); 0119 p->drawRect(frameNumRect); 0120 p->setPen(QPen(option.palette.text(), 1)); 0121 p->drawText(frameNumRect, Qt::AlignHCenter | Qt::AlignVCenter, data); 0122 } 0123 break; 0124 } 0125 case StoryboardItem::ItemName: 0126 { 0127 QRect itemNameRect = option.rect; 0128 itemNameRect.setLeft(option.rect.left() + 5); 0129 p->setPen(QPen(option.palette.text(), 1)); 0130 p->drawText(itemNameRect, Qt::AlignLeft | Qt::AlignVCenter, data); 0131 p->setPen(QPen(option.palette.dark(), 2)); 0132 p->drawRect(option.rect); 0133 break; 0134 } 0135 case StoryboardItem::DurationSecond: 0136 { 0137 drawSpinBox(p, option, data, i18nc("suffix in spin box in storyboard that means 'seconds'", "s")); 0138 break; 0139 } 0140 case StoryboardItem::DurationFrame: 0141 { 0142 drawSpinBox(p, option, data, i18nc("suffix in spin box in storyboard that means 'frames'", "f")); 0143 break; 0144 } 0145 default: 0146 { 0147 KIS_SAFE_ASSERT_RECOVER_RETURN(index.model()); 0148 const StoryboardModel* model = dynamic_cast<const StoryboardModel*>(index.model()); 0149 KIS_SAFE_ASSERT_RECOVER_RETURN(model); 0150 if (m_view->commentIsVisible() && model->getComment(index.row() - 4).visibility) { 0151 p->setPen(QPen(option.palette.dark(), 2)); 0152 drawCommentHeader(p, option, index); 0153 } 0154 break; 0155 } 0156 } 0157 } 0158 } 0159 p->restore(); 0160 } 0161 0162 void StoryboardDelegate::drawSpinBox(QPainter *p, const QStyleOptionViewItem &option, QString data, QString suffix) const 0163 { 0164 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0165 QStyleOptionSpinBox spinBoxOption; 0166 spinBoxOption.stepEnabled = QAbstractSpinBox::StepDownEnabled | QAbstractSpinBox::StepUpEnabled; 0167 spinBoxOption.subControls = QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; 0168 spinBoxOption.rect = option.rect; 0169 p->setPen(QPen(option.palette.dark(), 2)); 0170 p->drawRect(option.rect); 0171 style->drawComplexControl(QStyle::CC_SpinBox, &spinBoxOption, p, option.widget); 0172 0173 QRect rect = style->subControlRect(QStyle::CC_SpinBox, &spinBoxOption, 0174 QStyle::QStyle::SC_SpinBoxEditField); 0175 rect.moveTopLeft(option.rect.topLeft()); 0176 p->setPen(QPen(option.palette.text(), 1)); 0177 p->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, data + suffix); 0178 } 0179 0180 QStyleOptionSlider StoryboardDelegate::drawCommentHeader(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const 0181 { 0182 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0183 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(index.model(), QStyleOptionSlider()); 0184 const StoryboardModel* model = dynamic_cast<const StoryboardModel*>(index.model()); 0185 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(model, QStyleOptionSlider()); 0186 QString data = index.data().toString(); 0187 0188 QRect titleRect = option.rect; 0189 titleRect.setHeight(option.fontMetrics.height() + 3); 0190 if (p) { 0191 p->setPen(QPen(option.palette.text(), 1)); 0192 p->drawText(titleRect, Qt::AlignLeft | Qt::AlignVCenter, model->getComment(index.row() - 4).name); 0193 p->setPen(QPen(option.palette.dark(), 2)); 0194 p->drawRect(titleRect); 0195 } 0196 0197 QRect contentRect = option.rect; 0198 contentRect.setTop(option.rect.top() + option.fontMetrics.height() + 3); 0199 if (p) { 0200 p->setPen(QPen(option.palette.dark(), 2)); 0201 p->drawRect(contentRect); 0202 p->save(); 0203 } 0204 contentRect.setTopLeft(contentRect.topLeft() + QPoint(5, 5)); 0205 contentRect.setBottomRight(contentRect.bottomRight() - QPoint(5, 5)); 0206 0207 int scrollValue = index.data(Qt::UserRole).toInt(); 0208 0209 //draw comment 0210 QRect commentRect = contentRect; 0211 commentRect.setRight(contentRect.right() - 15); 0212 QTextDocument doc; 0213 0214 doc.setTextWidth(commentRect.width()); 0215 doc.setDocumentMargin(0); 0216 doc.setDefaultFont(option.font); 0217 QStringList lines = data.split('\n'); 0218 QString HTML; 0219 Q_FOREACH( const QString& line, lines) { 0220 HTML.append("<p>" + line + "</p>"); 0221 } 0222 doc.setHtml(HTML); 0223 QRectF clipRect = commentRect; 0224 clipRect.moveTopLeft(QPoint(0, 0 + scrollValue)); 0225 if (p) { 0226 p->translate(QPoint(commentRect.topLeft().x(), commentRect.topLeft().y() - scrollValue)); 0227 p->setPen(QPen(option.palette.text(), 1)); 0228 doc.drawContents(p, clipRect); 0229 p->restore(); 0230 } 0231 //draw scroll bar 0232 QStyleOptionSlider scrollbarOption; 0233 scrollbarOption.sliderPosition = scrollValue; 0234 scrollbarOption.minimum = 0; 0235 scrollbarOption.maximum = qMax(0.0, doc.size().height() - contentRect.height()); 0236 scrollbarOption.sliderPosition = qMin(scrollValue, scrollbarOption.maximum); 0237 scrollbarOption.pageStep = contentRect.height() - 2; 0238 scrollbarOption.orientation = Qt::Vertical; 0239 0240 QRect scrollRect = option.rect; 0241 scrollRect.setSize(QSize(15, option.rect.height() - option.fontMetrics.height() - 3)); 0242 scrollRect.moveTopLeft(QPoint(0, 0)); 0243 scrollbarOption.rect = scrollRect; 0244 0245 if (p && scrollbarOption.pageStep <= doc.size().height()) { 0246 p->save(); 0247 p->setPen(QPen(option.palette.dark(), 2)); 0248 p->translate(QPoint( option.rect.right()-15, option.rect.top() + option.fontMetrics.height() + 3)); 0249 style->drawComplexControl(QStyle::CC_ScrollBar, &scrollbarOption, p, option.widget); 0250 p->restore(); 0251 } 0252 return scrollbarOption; 0253 } 0254 0255 QSize StoryboardDelegate::sizeHint(const QStyleOptionViewItem &option, 0256 const QModelIndex &index) const 0257 { 0258 if (!index.parent().isValid()) { 0259 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(index.model(), option.rect.size()); 0260 if (m_view->itemOrientation() == Qt::Vertical) { 0261 int width = option.widget->width() - 17; 0262 const StoryboardModel* model = dynamic_cast<const StoryboardModel*>(index.model()); 0263 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(model, option.rect.size()); 0264 int numComments = model->visibleCommentCount(); 0265 int numItem = width/250; 0266 if (numItem <= 0) { 0267 numItem = 1; 0268 } 0269 0270 int thumbnailheight = m_view->thumbnailIsVisible() ? 120 : 0; 0271 int commentHeight = m_view->commentIsVisible() ? numComments*100 : 0; 0272 return QSize(width / numItem, thumbnailheight + option.fontMetrics.height() + 3 + commentHeight + 10); 0273 } 0274 else { 0275 const StoryboardModel* model = dynamic_cast<const StoryboardModel*>(index.model()); 0276 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(model, option.rect.size()); 0277 int numComments = model->visibleCommentCount(); 0278 int commentWidth = 0; 0279 if (numComments && m_view->commentIsVisible()) { 0280 commentWidth = qMax(200, (m_view->viewport()->width() - 250) / numComments); 0281 } 0282 int width = 250 + numComments * commentWidth; 0283 return QSize(width + 10, 120 + option.fontMetrics.height() + 3 + 10); 0284 } 0285 } 0286 else { 0287 return option.rect.size(); 0288 } 0289 } 0290 0291 QWidget *StoryboardDelegate::createEditor(QWidget *parent, 0292 const QStyleOptionViewItem &option , 0293 const QModelIndex &index) const 0294 { 0295 Q_UNUSED(option); 0296 //only create editor for children 0297 if (index.parent().isValid()) { 0298 int row = index.row(); 0299 switch (row) 0300 { 0301 case StoryboardItem::FrameNumber: 0302 return nullptr; 0303 case StoryboardItem::ItemName: 0304 { 0305 QLineEdit *editor = new QLineEdit(parent); 0306 return editor; 0307 } 0308 case StoryboardItem::DurationSecond: 0309 { 0310 QSpinBox *spinbox = new QSpinBox(parent); 0311 spinbox->setRange(0, 999); 0312 spinbox->setSuffix(i18nc("suffix in spin box in storyboard that means 'seconds'", "s")); 0313 return spinbox; 0314 } 0315 case StoryboardItem::DurationFrame: 0316 { 0317 QSpinBox *spinbox = new QSpinBox(parent); 0318 spinbox->setRange(0, 99); 0319 spinbox->setSuffix(i18nc("suffix in spin box in storyboard that means 'frames'", "f")); 0320 return spinbox; 0321 } 0322 default: //for comments 0323 { 0324 QTextEdit *editor = new LimitedTextEditor(280, parent); 0325 return editor; 0326 } 0327 } 0328 } 0329 return nullptr; 0330 } 0331 0332 bool StoryboardDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) 0333 { 0334 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(model, false); 0335 if ((event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) 0336 && (index.flags() & Qt::ItemIsEnabled)) 0337 { 0338 QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); 0339 const bool leftButton = mouseEvent->buttons() & Qt::LeftButton; 0340 0341 //handle the duration edit event 0342 if (index.parent().isValid() && (index.row() == StoryboardItem::DurationSecond || index.row() == StoryboardItem::DurationFrame)) { 0343 QRect upButton = spinBoxUpButton(option); 0344 QRect downButton = spinBoxDownButton(option); 0345 0346 bool upButtonClicked = upButton.isValid() && upButton.contains(mouseEvent->pos()); 0347 bool downButtonClicked = downButton.isValid() && downButton.contains(mouseEvent->pos()); 0348 0349 StoryboardModel* sbModel = dynamic_cast<StoryboardModel*>(model); 0350 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(sbModel, false); 0351 if (leftButton && upButtonClicked) { 0352 KisStoryboardChildEditCommand *cmd = new KisStoryboardChildEditCommand(index.data(), 0353 index.data().toInt() + 1, 0354 index.parent().row(), 0355 index.row(), 0356 sbModel); 0357 if (sbModel->setData(index, index.data().toInt() + 1)) { 0358 sbModel->pushUndoCommand(cmd); 0359 } 0360 return true; 0361 } 0362 else if (leftButton && downButtonClicked) { 0363 KisStoryboardChildEditCommand *cmd = new KisStoryboardChildEditCommand(index.data(), 0364 index.data().toInt() - 1, 0365 index.parent().row(), 0366 index.row(), 0367 sbModel); 0368 if (sbModel->setData(index, index.data().toInt() - 1)) { 0369 sbModel->pushUndoCommand(cmd); 0370 } 0371 return true; 0372 } 0373 } 0374 else if (index.parent().isValid() && index.row() >= StoryboardItem::Comments) { 0375 QStyleOptionSlider scrollBarOption = drawCommentHeader(nullptr, option, index); 0376 QRect upButton = scrollUpButton(option, scrollBarOption); 0377 QRect downButton = scrollDownButton(option, scrollBarOption); 0378 0379 bool upButtonClicked = upButton.isValid() && upButton.contains(mouseEvent->pos()); 0380 bool downButtonClicked = downButton.isValid() && downButton.contains(mouseEvent->pos()); 0381 0382 if (leftButton && upButtonClicked) { 0383 int lastValue = model->data(index, Qt::UserRole).toInt(); 0384 int value = lastValue - option.fontMetrics.height(); 0385 StoryboardModel* modelSB = dynamic_cast<StoryboardModel*>(model); 0386 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(modelSB, false); 0387 modelSB->setCommentScrollData(index, qMax(0, value)); 0388 return true; 0389 } 0390 else if (leftButton && downButtonClicked) { 0391 int lastValue = model->data(index, Qt::UserRole).toInt(); 0392 int value = lastValue + option.fontMetrics.height(); 0393 StoryboardModel* modelSB = dynamic_cast<StoryboardModel*>(model); 0394 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(modelSB, false); 0395 modelSB->setCommentScrollData(index, qMin(scrollBarOption.maximum, value)); 0396 return true; 0397 } 0398 } 0399 0400 else if (index.parent().isValid() && index.row() == StoryboardItem::FrameNumber && m_view->thumbnailIsVisible()) { //thumbnail add/delete events 0401 QRect addItemButton(QPoint(0, 0), QSize(22, 22)); 0402 addItemButton.moveBottomLeft(option.rect.bottomLeft()); 0403 0404 QRect deleteItemButton(QPoint(0, 0), QSize(22, 22)); 0405 deleteItemButton.moveBottomRight(option.rect.bottomRight()); 0406 0407 bool addItemButtonClicked = addItemButton.isValid() && addItemButton.contains(mouseEvent->pos()); 0408 bool deleteItemButtonClicked = deleteItemButton.isValid() && deleteItemButton.contains(mouseEvent->pos()); 0409 0410 StoryboardModel* sbModel = dynamic_cast<StoryboardModel*>(model); 0411 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(sbModel, false); 0412 if (leftButton && addItemButtonClicked) { 0413 sbModel->insertItem(index.parent(), true); 0414 return true; 0415 } 0416 else if (leftButton && deleteItemButtonClicked) { 0417 int row = index.parent().row(); 0418 KisRemoveStoryboardCommand *command = new KisRemoveStoryboardCommand(row, sbModel->getData().at(row), sbModel); 0419 0420 sbModel->removeItem(index.parent(), command); 0421 sbModel->pushUndoCommand(command); 0422 return true; 0423 } 0424 } 0425 } 0426 0427 if ((event->type() == QEvent::MouseMove) && (index.flags() & Qt::ItemIsEnabled)) { 0428 QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); 0429 const bool leftButton = mouseEvent->buttons() & Qt::LeftButton; 0430 0431 QStyleOptionSlider scrollBarOption = drawCommentHeader(nullptr, option, index); 0432 QRect scrollBarRect = scrollBar(option, scrollBarOption); 0433 0434 bool lastClickPosInScroll = scrollBarRect.isValid() && scrollBarRect.contains(m_lastDragPos); 0435 bool currClickPosInScroll = scrollBarRect.isValid() && scrollBarRect.contains(mouseEvent->pos()); 0436 0437 if (leftButton && index.parent().isValid() && index.row() >= StoryboardItem::Comments) { 0438 if (lastClickPosInScroll && currClickPosInScroll) { 0439 int lastValue = model->data(index, Qt::UserRole).toInt(); 0440 int value = lastValue + mouseEvent->pos().y() - m_lastDragPos.y(); 0441 0442 StoryboardModel* modelSB = dynamic_cast<StoryboardModel*>(model); 0443 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(modelSB, false); 0444 if (value >= 0 && value <= scrollBarOption.maximum) { 0445 modelSB->setCommentScrollData(index, value); 0446 return true; 0447 } 0448 return false; 0449 } 0450 m_lastDragPos = mouseEvent->pos(); 0451 } 0452 } 0453 0454 return false; 0455 } 0456 0457 //set the existing data in the editor 0458 void StoryboardDelegate::setEditorData(QWidget *editor, 0459 const QModelIndex &index) const 0460 { 0461 QVariant value = index.data(); 0462 if (index.parent().isValid()) { 0463 int row = index.row(); 0464 switch (row) 0465 { 0466 case StoryboardItem::FrameNumber: //frame thumbnail is uneditable 0467 return; 0468 case StoryboardItem::ItemName: 0469 { 0470 QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); 0471 lineEdit->setText(value.toString()); 0472 return; 0473 } 0474 case StoryboardItem::DurationSecond: 0475 case StoryboardItem::DurationFrame: 0476 { 0477 QSpinBox *spinbox = static_cast<QSpinBox*>(editor); 0478 spinbox->setValue(value.toInt()); 0479 return; 0480 } 0481 default: // for comments 0482 { 0483 QTextEdit *textEdit = static_cast<QTextEdit*>(editor); 0484 textEdit->setText(value.toString()); 0485 textEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); 0486 textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); 0487 textEdit->verticalScrollBar()->setProperty("index", index); 0488 connect(textEdit->verticalScrollBar(), SIGNAL(sliderMoved(int)), this, SLOT(slotCommentScrolledTo(int))); 0489 return; 0490 } 0491 } 0492 } 0493 } 0494 0495 void StoryboardDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, 0496 const QModelIndex &index) const 0497 { 0498 KIS_ASSERT(model); 0499 QVariant value = index.data(); 0500 if (index.parent().isValid()) { 0501 int row = index.row(); 0502 switch (row) 0503 { 0504 case StoryboardItem::FrameNumber: //frame thumbnail is uneditable 0505 return; 0506 case StoryboardItem::ItemName: 0507 { 0508 QLineEdit *lineEdit = static_cast<QLineEdit*>(editor); 0509 QString value = lineEdit->text(); 0510 model->setData(index, value, Qt::EditRole); 0511 return; 0512 } 0513 case StoryboardItem::DurationSecond: 0514 case StoryboardItem::DurationFrame: 0515 { 0516 QSpinBox *spinbox = static_cast<QSpinBox*>(editor); 0517 int value = spinbox->value(); 0518 0519 StoryboardModel* sbModel = dynamic_cast<StoryboardModel*>(model); 0520 KIS_SAFE_ASSERT_RECOVER_RETURN(sbModel); 0521 KisStoryboardChildEditCommand *cmd = new KisStoryboardChildEditCommand(index.data(), 0522 value, 0523 index.parent().row(), 0524 index.row(), 0525 sbModel); 0526 if (sbModel->setData(index, value)) { 0527 sbModel->pushUndoCommand(cmd); 0528 } 0529 return; 0530 } 0531 default: // for comments 0532 { 0533 QTextEdit *textEdit = static_cast<QTextEdit*>(editor); 0534 QString value = textEdit->toPlainText(); 0535 0536 StoryboardModel* sbModel = dynamic_cast<StoryboardModel*>(model); 0537 KIS_SAFE_ASSERT_RECOVER_RETURN(sbModel); 0538 KisStoryboardChildEditCommand *cmd = new KisStoryboardChildEditCommand(index.data(), 0539 value, 0540 index.parent().row(), 0541 index.row(), 0542 sbModel); 0543 0544 if (sbModel->setData(index, value)) { 0545 sbModel->pushUndoCommand(cmd); 0546 } 0547 0548 return; 0549 } 0550 } 0551 } 0552 } 0553 0554 void StoryboardDelegate::updateEditorGeometry(QWidget *editor, 0555 const QStyleOptionViewItem &option, const QModelIndex &index) const 0556 { 0557 if (index.row() < StoryboardItem::Comments) { 0558 editor->setGeometry(option.rect); 0559 } 0560 else { //for comment textedits 0561 QRect commentRect = option.rect; 0562 commentRect.setTop(option.rect.top() + option.fontMetrics.height() + 3); 0563 editor->setGeometry(commentRect); 0564 } 0565 } 0566 0567 void StoryboardDelegate::setView(StoryboardView *view) 0568 { 0569 m_view = view; 0570 } 0571 0572 QRect StoryboardDelegate::spinBoxUpButton(const QStyleOptionViewItem &option) 0573 { 0574 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0575 QStyleOptionSpinBox spinOption; 0576 spinOption.rect = option.rect; 0577 QRect rect = style->subControlRect(QStyle::CC_SpinBox, &spinOption, 0578 QStyle::QStyle::SC_SpinBoxUp); 0579 rect.moveTopRight(option.rect.topRight()); 0580 return rect; 0581 } 0582 0583 QRect StoryboardDelegate::spinBoxDownButton(const QStyleOptionViewItem &option) 0584 { 0585 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0586 QStyleOptionSpinBox spinOption; 0587 spinOption.rect = option.rect; 0588 QRect rect = style->subControlRect(QStyle::CC_SpinBox, &spinOption, 0589 QStyle::QStyle::SC_SpinBoxDown); 0590 rect.moveBottomRight(option.rect.bottomRight()); 0591 return rect; 0592 } 0593 0594 QRect StoryboardDelegate::spinBoxEditField(const QStyleOptionViewItem &option) 0595 { 0596 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0597 QStyleOptionSpinBox spinOption; 0598 spinOption.rect = option.rect; 0599 QRect rect = style->subControlRect(QStyle::CC_SpinBox, &spinOption, 0600 QStyle::QStyle::SC_SpinBoxEditField); 0601 rect.moveTopLeft(option.rect.topLeft()); 0602 return rect; 0603 } 0604 0605 void StoryboardDelegate::slotCommentScrolledTo(int value) const 0606 { 0607 const QModelIndex index = sender()->property("index").toModelIndex(); 0608 KIS_SAFE_ASSERT_RECOVER_RETURN(m_view->model()); 0609 StoryboardModel* model = dynamic_cast<StoryboardModel*>(m_view->model()); 0610 KIS_SAFE_ASSERT_RECOVER_RETURN(model); 0611 model->setCommentScrollData(index, value); 0612 } 0613 0614 QRect StoryboardDelegate::scrollBar(const QStyleOptionViewItem &option, QStyleOptionSlider &scrollBarOption) const 0615 { 0616 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0617 QRect rect = style->subControlRect(QStyle::CC_ScrollBar, &scrollBarOption, 0618 QStyle::QStyle::SC_ScrollBarSlider); 0619 rect.moveTopLeft(rect.topLeft() + scrollBarOption.rect.topLeft()); 0620 rect.moveTopLeft(rect.topLeft() + option.rect.bottomRight() - scrollBarOption.rect.bottomRight()); 0621 return rect; 0622 } 0623 0624 QRect StoryboardDelegate::scrollDownButton(const QStyleOptionViewItem &option, QStyleOptionSlider &scrollBarOption) 0625 { 0626 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0627 QRect rect = style->subControlRect(QStyle::CC_ScrollBar, &scrollBarOption, 0628 QStyle::QStyle::SC_ScrollBarAddLine); 0629 rect.moveTopLeft(rect.topLeft() + scrollBarOption.rect.topLeft()); 0630 rect.moveBottomRight(option.rect.bottomRight()); 0631 return rect; 0632 } 0633 0634 QRect StoryboardDelegate::scrollUpButton(const QStyleOptionViewItem &option, QStyleOptionSlider &scrollBarOption) 0635 { 0636 QStyle *style = option.widget ? option.widget->style() : QApplication::style(); 0637 QRect rect = style->subControlRect(QStyle::CC_ScrollBar, &scrollBarOption, 0638 QStyle::QStyle::SC_ScrollBarSubLine); 0639 rect.moveTopLeft(rect.topLeft() + scrollBarOption.rect.topLeft()); 0640 rect.moveTop(option.rect.bottom() - scrollBarOption.rect.height()); 0641 rect.moveRight(option.rect.right()); 0642 return rect; 0643 } 0644 0645 void StoryboardDelegate::setImageSize(QSize imageSize) 0646 { 0647 m_imageSize = imageSize; 0648 } 0649 0650 bool StoryboardDelegate::isOverlappingActionIcons(const QRect &rect, const QMouseEvent *event) 0651 { 0652 QRect addItemButton(QPoint(0, 0), QSize(22, 22)); 0653 addItemButton.moveBottomLeft(rect.bottomLeft()); 0654 0655 QRect deleteItemButton(QPoint(0, 0), QSize(22, 22)); 0656 deleteItemButton.moveBottomRight(rect.bottomRight()); 0657 0658 bool addItemButtonHover = addItemButton.isValid() && addItemButton.contains(event->pos()); 0659 bool deleteItemButtonHover = deleteItemButton.isValid() && deleteItemButton.contains(event->pos()); 0660 0661 return addItemButtonHover || deleteItemButtonHover; 0662 } 0663 0664 bool StoryboardDelegate::eventFilter(QObject *editor, QEvent *event) 0665 { 0666 if (event->type() == QEvent::KeyPress) { 0667 QKeyEvent* kEvent = static_cast<QKeyEvent*>(event); 0668 QTextEdit* textEditor = qobject_cast<QTextEdit*>(editor); 0669 if (textEditor && kEvent->key() == Qt::Key_Escape) { 0670 emit commitData(textEditor); 0671 emit closeEditor(textEditor, QAbstractItemDelegate::SubmitModelCache); 0672 return true; 0673 } 0674 } 0675 QStyledItemDelegate::eventFilter(editor, event); 0676 return false; 0677 }