15#include <QApplication>
28 : QStyledItemDelegate(parent)
30 , m_imageSize(QSize())
42 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
43 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option,
p, option.widget);
45 p->setFont(option.font);
46 if (!index.isValid()) {
50 if (!index.parent().isValid()) {
51 QRect parentRect = option.rect;
52 p->setPen(QPen(option.palette.window(), 2));
53 p->drawRect(parentRect);
55 parentRect.setTopLeft(parentRect.topLeft() + QPoint(4, 4));
56 parentRect.setBottomRight(parentRect.bottomRight() - QPoint(4, 4));
58 if (option.state & QStyle::State_Selected) {
59 p->fillRect(option.rect, option.palette.highlight());
62 p->fillRect(option.rect, option.palette.window());
64 p->eraseRect(parentRect);
68 int childNum = index.row();
69 QString data = index.data().toString();
76 QRect frameNumRect = option.rect;
77 frameNumRect.setHeight(
m_view->fontMetrics().height()+3);
78 frameNumRect.setWidth(3 *
m_view->fontMetrics().horizontalAdvance(
"0") + 2);
79 frameNumRect.moveBottom(option.rect.top()-1);
80 p->setPen(QPen(option.palette.dark(), 2));
81 p->drawRect(frameNumRect);
82 p->setPen(QPen(option.palette.text(), 1));
83 p->drawText(frameNumRect, Qt::AlignHCenter | Qt::AlignVCenter, data);
86 float scale = qMin(option.rect.height() / (
float)
m_imageSize.height(), (
float)option.rect.width() /
m_imageSize.width());
87 QRect thumbnailRect = option.rect;
89 thumbnailRect.moveCenter(option.rect.center());
91 QPixmap thumbnailPixmap= index.data(Qt::UserRole).value<QPixmap>();
92 p->drawPixmap(thumbnailRect, thumbnailPixmap);
94 p->setPen(QPen(option.palette.dark(), 2));
95 p->drawRect(option.rect);
97 QRect buttonsRect = option.rect;
98 buttonsRect.setTop(option.rect.bottom() - 22);
100 buttonsRect.setWidth(22);
101 buttonsRect.moveBottomLeft(option.rect.bottomLeft());
103 p->fillRect(buttonsRect, option.palette.window());
104 addIcon.paint(
p, buttonsRect);
106 buttonsRect.moveBottomRight(option.rect.bottomRight());
108 p->fillRect(buttonsRect, option.palette.window());
109 deleteIcon.paint(
p, buttonsRect);
112 QRect frameNumRect = option.rect;
113 p->setPen(QPen(option.palette.dark(), 2));
114 p->drawRect(frameNumRect);
115 p->setPen(QPen(option.palette.text(), 1));
116 p->drawText(frameNumRect, Qt::AlignHCenter | Qt::AlignVCenter, data);
122 QRect itemNameRect = option.rect;
123 itemNameRect.setLeft(option.rect.left() + 5);
124 p->setPen(QPen(option.palette.text(), 1));
125 p->drawText(itemNameRect, Qt::AlignLeft | Qt::AlignVCenter, data);
126 p->setPen(QPen(option.palette.dark(), 2));
127 p->drawRect(option.rect);
132 drawSpinBox(
p, option, data, i18nc(
"suffix in spin box in storyboard that means 'seconds'",
"s"));
137 drawSpinBox(
p, option, data, i18nc(
"suffix in spin box in storyboard that means 'frames'",
"f"));
146 p->setPen(QPen(option.palette.dark(), 2));
159 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
160 QStyleOptionSpinBox spinBoxOption;
161 spinBoxOption.stepEnabled = QAbstractSpinBox::StepDownEnabled | QAbstractSpinBox::StepUpEnabled;
162 spinBoxOption.subControls = QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
163 spinBoxOption.rect = option.rect;
164 p->setPen(QPen(option.palette.dark(), 2));
165 p->drawRect(option.rect);
166 style->drawComplexControl(QStyle::CC_SpinBox, &spinBoxOption,
p, option.widget);
168 QRect
rect = style->subControlRect(QStyle::CC_SpinBox, &spinBoxOption,
169 QStyle::QStyle::SC_SpinBoxEditField);
170 rect.moveTopLeft(option.rect.topLeft());
171 p->setPen(QPen(option.palette.text(), 1));
172 p->drawText(
rect, Qt::AlignLeft | Qt::AlignVCenter, data + suffix);
177 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
181 QString data = index.data().toString();
183 QRect titleRect = option.rect;
184 titleRect.setHeight(option.fontMetrics.height() + 3);
186 p->setPen(QPen(option.palette.text(), 1));
187 p->drawText(titleRect, Qt::AlignLeft | Qt::AlignVCenter, model->
getComment(index.row() - 4).
name);
188 p->setPen(QPen(option.palette.dark(), 2));
189 p->drawRect(titleRect);
192 QRect contentRect = option.rect;
193 contentRect.setTop(option.rect.top() + option.fontMetrics.height() + 3);
195 p->setPen(QPen(option.palette.dark(), 2));
196 p->drawRect(contentRect);
199 contentRect.setTopLeft(contentRect.topLeft() + QPoint(5, 5));
200 contentRect.setBottomRight(contentRect.bottomRight() - QPoint(5, 5));
202 int scrollValue = index.data(Qt::UserRole).toInt();
205 QRect commentRect = contentRect;
206 commentRect.setRight(contentRect.right() - 15);
209 doc.setTextWidth(commentRect.width());
210 doc.setDocumentMargin(0);
211 doc.setDefaultFont(option.font);
214 Q_FOREACH(
const QString& line, lines) {
215 HTML.append(
"<p>" + line +
"</p>");
218 QRectF clipRect = commentRect;
219 clipRect.moveTopLeft(QPoint(0, 0 + scrollValue));
221 p->translate(QPoint(commentRect.topLeft().x(), commentRect.topLeft().y() - scrollValue));
222 p->setPen(QPen(option.palette.text(), 1));
223 doc.drawContents(
p, clipRect);
227 QStyleOptionSlider scrollbarOption;
228 scrollbarOption.sliderPosition = scrollValue;
229 scrollbarOption.minimum = 0;
230 scrollbarOption.maximum = qMax(0.0, doc.size().height() - contentRect.height());
231 scrollbarOption.sliderPosition = qMin(scrollValue, scrollbarOption.maximum);
232 scrollbarOption.pageStep = contentRect.height() - 2;
233 scrollbarOption.orientation = Qt::Vertical;
235 QRect scrollRect = option.rect;
236 scrollRect.setSize(QSize(15, option.rect.height() - option.fontMetrics.height() - 3));
237 scrollRect.moveTopLeft(QPoint(0, 0));
238 scrollbarOption.rect = scrollRect;
240 if (
p && scrollbarOption.pageStep <= doc.size().height()) {
242 p->setPen(QPen(option.palette.dark(), 2));
243 p->translate(QPoint( option.rect.right()-15, option.rect.top() + option.fontMetrics.height() + 3));
244 style->drawComplexControl(QStyle::CC_ScrollBar, &scrollbarOption,
p, option.widget);
247 return scrollbarOption;
251 const QModelIndex &index)
const
253 if (!index.parent().isValid()) {
256 int width = option.widget->width() - 17;
260 int numItem = width/250;
267 return QSize(width / numItem, thumbnailheight + option.fontMetrics.height() + 3 + commentHeight + 10);
273 int commentWidth = 0;
275 commentWidth = qMax(200, (
m_view->viewport()->width() - 250) / numComments);
277 int width = 250 + numComments * commentWidth;
278 return QSize(width + 10, 120 + option.fontMetrics.height() + 3 + 10);
282 return option.rect.size();
287 const QStyleOptionViewItem &option ,
288 const QModelIndex &index)
const
292 if (index.parent().isValid()) {
293 int row = index.row();
300 QLineEdit *editor =
new QLineEdit(parent);
305 QSpinBox *spinbox =
new QSpinBox(parent);
306 spinbox->setRange(0, 999);
307 spinbox->setSuffix(i18nc(
"suffix in spin box in storyboard that means 'seconds'",
"s"));
312 QSpinBox *spinbox =
new QSpinBox(parent);
313 spinbox->setRange(0, 99);
314 spinbox->setSuffix(i18nc(
"suffix in spin box in storyboard that means 'frames'",
"f"));
330 if ((event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
331 && (index.flags() & Qt::ItemIsEnabled))
333 QMouseEvent *mouseEvent =
static_cast<QMouseEvent*
>(event);
334 const bool leftButton = mouseEvent->buttons() & Qt::LeftButton;
341 bool upButtonClicked = upButton.isValid() && upButton.contains(mouseEvent->pos());
342 bool downButtonClicked = downButton.isValid() && downButton.contains(mouseEvent->pos());
346 if (leftButton && upButtonClicked) {
348 index.data().toInt() + 1,
349 index.parent().row(),
352 if (sbModel->
setData(index, index.data().toInt() + 1)) {
357 else if (leftButton && downButtonClicked) {
359 index.data().toInt() - 1,
360 index.parent().row(),
363 if (sbModel->
setData(index, index.data().toInt() - 1)) {
374 bool upButtonClicked = upButton.isValid() && upButton.contains(mouseEvent->pos());
375 bool downButtonClicked = downButton.isValid() && downButton.contains(mouseEvent->pos());
377 if (leftButton && upButtonClicked) {
378 int lastValue = model->data(index, Qt::UserRole).toInt();
379 int value = lastValue - option.fontMetrics.height();
385 else if (leftButton && downButtonClicked) {
386 int lastValue = model->data(index, Qt::UserRole).toInt();
387 int value = lastValue + option.fontMetrics.height();
396 QRect addItemButton(QPoint(0, 0), QSize(22, 22));
397 addItemButton.moveBottomLeft(option.rect.bottomLeft());
399 QRect deleteItemButton(QPoint(0, 0), QSize(22, 22));
400 deleteItemButton.moveBottomRight(option.rect.bottomRight());
402 bool addItemButtonClicked = addItemButton.isValid() && addItemButton.contains(mouseEvent->pos());
403 bool deleteItemButtonClicked = deleteItemButton.isValid() && deleteItemButton.contains(mouseEvent->pos());
407 if (leftButton && addItemButtonClicked) {
411 else if (leftButton && deleteItemButtonClicked) {
412 int row = index.parent().row();
422 if ((event->type() == QEvent::MouseMove) && (index.flags() & Qt::ItemIsEnabled)) {
423 QMouseEvent *mouseEvent =
static_cast<QMouseEvent*
>(event);
424 const bool leftButton = mouseEvent->buttons() & Qt::LeftButton;
427 QRect scrollBarRect =
scrollBar(option, scrollBarOption);
429 bool lastClickPosInScroll = scrollBarRect.isValid() && scrollBarRect.contains(
m_lastDragPos);
430 bool currClickPosInScroll = scrollBarRect.isValid() && scrollBarRect.contains(mouseEvent->pos());
433 if (lastClickPosInScroll && currClickPosInScroll) {
434 int lastValue = model->data(index, Qt::UserRole).toInt();
439 if (
value >= 0 &&
value <= scrollBarOption.maximum) {
454 const QModelIndex &index)
const
456 QVariant
value = index.data();
457 if (index.parent().isValid()) {
458 int row = index.row();
465 QLineEdit *lineEdit =
static_cast<QLineEdit*
>(editor);
466 lineEdit->setText(
value.toString());
472 QSpinBox *spinbox =
static_cast<QSpinBox*
>(editor);
473 spinbox->setValue(
value.toInt());
478 QTextEdit *textEdit =
static_cast<QTextEdit*
>(editor);
479 textEdit->setText(
value.toString());
480 textEdit->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
481 textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
482 textEdit->verticalScrollBar()->setProperty(
"index", index);
491 const QModelIndex &index)
const
494 QVariant
value = index.data();
495 if (index.parent().isValid()) {
496 int row = index.row();
503 QLineEdit *lineEdit =
static_cast<QLineEdit*
>(editor);
504 QString
value = lineEdit->text();
505 model->setData(index,
value, Qt::EditRole);
511 QSpinBox *spinbox =
static_cast<QSpinBox*
>(editor);
512 int value = spinbox->value();
518 index.parent().row(),
528 QTextEdit *textEdit =
static_cast<QTextEdit*
>(editor);
529 QString
value = textEdit->toPlainText();
535 index.parent().row(),
550 const QStyleOptionViewItem &option,
const QModelIndex &index)
const
553 editor->setGeometry(option.rect);
556 QRect commentRect = option.rect;
557 commentRect.setTop(option.rect.top() + option.fontMetrics.height() + 3);
558 editor->setGeometry(commentRect);
569 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
570 QStyleOptionSpinBox spinOption;
571 spinOption.rect = option.rect;
572 QRect
rect = style->subControlRect(QStyle::CC_SpinBox, &spinOption,
573 QStyle::QStyle::SC_SpinBoxUp);
574 rect.moveTopRight(option.rect.topRight());
580 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
581 QStyleOptionSpinBox spinOption;
582 spinOption.rect = option.rect;
583 QRect
rect = style->subControlRect(QStyle::CC_SpinBox, &spinOption,
584 QStyle::QStyle::SC_SpinBoxDown);
585 rect.moveBottomRight(option.rect.bottomRight());
591 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
592 QStyleOptionSpinBox spinOption;
593 spinOption.rect = option.rect;
594 QRect
rect = style->subControlRect(QStyle::CC_SpinBox, &spinOption,
595 QStyle::QStyle::SC_SpinBoxEditField);
596 rect.moveTopLeft(option.rect.topLeft());
602 const QModelIndex index = sender()->property(
"index").toModelIndex();
611 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
612 QRect
rect = style->subControlRect(QStyle::CC_ScrollBar, &scrollBarOption,
613 QStyle::QStyle::SC_ScrollBarSlider);
614 rect.moveTopLeft(
rect.topLeft() + scrollBarOption.rect.topLeft());
615 rect.moveTopLeft(
rect.topLeft() + option.rect.bottomRight() - scrollBarOption.rect.bottomRight());
621 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
622 QRect
rect = style->subControlRect(QStyle::CC_ScrollBar, &scrollBarOption,
623 QStyle::QStyle::SC_ScrollBarAddLine);
624 rect.moveTopLeft(
rect.topLeft() + scrollBarOption.rect.topLeft());
625 rect.moveBottomRight(option.rect.bottomRight());
631 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
632 QRect
rect = style->subControlRect(QStyle::CC_ScrollBar, &scrollBarOption,
633 QStyle::QStyle::SC_ScrollBarSubLine);
634 rect.moveTopLeft(
rect.topLeft() + scrollBarOption.rect.topLeft());
635 rect.moveTop(option.rect.bottom() - scrollBarOption.rect.height());
636 rect.moveRight(option.rect.right());
647 QRect addItemButton(QPoint(0, 0), QSize(22, 22));
648 addItemButton.moveBottomLeft(
rect.bottomLeft());
650 QRect deleteItemButton(QPoint(0, 0), QSize(22, 22));
651 deleteItemButton.moveBottomRight(
rect.bottomRight());
653 bool addItemButtonHover = addItemButton.isValid() && addItemButton.contains(event->pos());
654 bool deleteItemButtonHover = deleteItemButton.isValid() && deleteItemButton.contains(event->pos());
656 return addItemButtonHover || deleteItemButtonHover;
661 if (event->type() == QEvent::KeyPress) {
662 QKeyEvent* kEvent =
static_cast<QKeyEvent*
>(event);
663 QTextEdit* textEditor = qobject_cast<QTextEdit*>(editor);
664 if (textEditor && kEvent->key() == Qt::Key_Escape) {
665 Q_EMIT commitData(textEditor);
666 Q_EMIT closeEditor(textEditor, QAbstractItemDelegate::SubmitModelCache);
670 QStyledItemDelegate::eventFilter(editor, event);
float value(const T *src, size_t ch)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
StoryboardDelegate(QObject *parent)
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
void setEditorData(QWidget *editor, const QModelIndex &index) const override
QStyleOptionSlider drawCommentHeader(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const
Draw the comment header.
void setView(StoryboardView *view)
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
QRect scrollDownButton(const QStyleOptionViewItem &option, QStyleOptionSlider &scrollBarOption)
QRect scrollBar(const QStyleOptionViewItem &option, QStyleOptionSlider &scrollBarOption) const
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
QRect spinBoxEditField(const QStyleOptionViewItem &option)
~StoryboardDelegate() override
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
void slotCommentScrolledTo(int value) const
updates the scroll value of the CommentBox in StoryboardModel This enables the model to keep track of...
bool eventFilter(QObject *editor, QEvent *event) override
void drawSpinBox(QPainter *p, const QStyleOptionViewItem &option, QString data, QString suffix) const
Draw the spin box.
QRect spinBoxUpButton(const QStyleOptionViewItem &option)
bool isOverlappingActionIcons(const QRect &rect, const QMouseEvent *event)
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override
QRect spinBoxDownButton(const QStyleOptionViewItem &option)
QRect scrollUpButton(const QStyleOptionViewItem &option, QStyleOptionSlider &scrollBarOption)
void setImageSize(QSize imageSize)
@ DurationFrame
Store the duration in frame at index 3. Data type stored here should be int.
@ FrameNumber
Store the frame number at index 0. Data type stored here should be ThumbnailData.
@ DurationSecond
Store the duration in second at index 2. Data type stored here should be int.
@ ItemName
Store the item name at index 1. Data type stored here should be string.
@ Comments
Store the comments at indices greater_than_or_equal_to to index 4. Data type stored here should be Co...
The main storyboard model. This class manages a StoryboardItemList which is a list of StoryboardItem ...
bool setCommentScrollData(const QModelIndex &index, const QVariant &value)
Sets the scrollValue of the CommentBox object.
StoryboardItemList getData()
StoryboardComment getComment(int row) const
bool insertItem(QModelIndex index, bool after)
inserts item after or before index based on after parameter
void pushUndoCommand(KUndo2Command *command)
bool removeItem(QModelIndex index, KUndo2Command *command=nullptr)
removes item, deletes keyframes within and shifts keyframe after the scene to fill in the gap
int visibleCommentCount() const
Used in StoryboardDelegate and StoryboardView to get size of one storyboard item.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
Qt::Orientation itemOrientation()
whether Comments are below or on the right of Thumbnail
bool thumbnailIsVisible() const
bool commentIsVisible() const
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
QIcon loadIcon(const QString &name)