88 m_d->actionMan = actionManager;
95 action = actionManager->
createAction(
"insert_column_left");
98 action = actionManager->
createAction(
"insert_column_right");
101 action = actionManager->
createAction(
"insert_multiple_columns");
104 action = actionManager->
createAction(
"remove_columns_and_pull");
110 action = actionManager->
createAction(
"insert_hold_column");
113 action = actionManager->
createAction(
"insert_multiple_hold_columns");
116 action = actionManager->
createAction(
"remove_hold_column");
119 action = actionManager->
createAction(
"remove_multiple_hold_columns");
125 action = actionManager->
createAction(
"clear_animation_cache");
128 action = actionManager->
createAction(
"copy_columns_to_clipboard");
131 action = actionManager->
createAction(
"cut_columns_to_clipboard");
134 action = actionManager->
createAction(
"paste_columns_from_clipboard");
146 QHeaderView::paintEvent(e);
153 QPainter painter(viewport());
154 const QPoint offset = dirtyRegionOffset();
155 QRect translatedEventRect = e->rect();
156 translatedEventRect.translate(offset);
160 if (orientation() == Qt::Horizontal) {
161 start = visualIndexAt(translatedEventRect.left());
162 end = visualIndexAt(translatedEventRect.right());
164 start = visualIndexAt(translatedEventRect.top());
165 end = visualIndexAt(translatedEventRect.bottom());
168 const bool reverseImpl = orientation() == Qt::Horizontal && isRightToLeft();
171 start = (start == -1 ? count() - 1 : start);
172 end = (end == -1 ? 0 : end);
174 start = (start == -1 ? 0 : start);
175 end = (end == -1 ? count() - 1 : end);
179 start = qMin(start, end);
180 end = qMax(
tmp, end);
185 const int spanStart = start - start %
m_d->fps;
186 const int spanEnd = end - end %
m_d->fps +
m_d->fps - 1;
189 end = qMin(count() - 1, spanEnd);
194 QRect currentSectionRect;
196 const int width = viewport()->width();
197 const int height = viewport()->height();
199 for (
int i = start; i <= end; ++i) {
204 logical = logicalIndex(i);
205 if (orientation() == Qt::Horizontal) {
206 currentSectionRect.setRect(sectionViewportPosition(logical), 0, sectionSize(logical), height);
208 currentSectionRect.setRect(0, sectionViewportPosition(logical), width, sectionSize(logical));
210 currentSectionRect.translate(offset);
212 QVariant variant = model()->headerData(logical, orientation(),
214 if (variant.isValid() && variant.canConvert<QFont>()) {
215 QFont sectionFont = qvariant_cast<QFont>(variant);
216 painter.setFont(sectionFont);
233 const QRect &spanRect,
235 bool isPrevIntegralLine,
238 const QPen &gridPen)
const
240 painter->fillRect(spanRect,
palette.brush(QPalette::Button));
242 int safeRight = spanRect.right();
244 QPen oldPen = painter->pen();
245 painter->setPen(gridPen);
247 int adjustedTop = spanRect.top() + (!isIntegralLine ? spanRect.height() / 2 : 0);
248 painter->drawLine(safeRight, adjustedTop, safeRight, spanRect.bottom());
250 if (isPrevIntegralLine) {
251 painter->drawLine(spanRect.left() + 1, spanRect.top(), spanRect.left() + 1, spanRect.bottom());
254 painter->setPen(oldPen);
256 QString frameIdText = QString::number(userFrameId);
257 QRect textRect(spanRect.topLeft() + QPoint(2, 0), QSize(spanRect.width() - 2, spanRect.height()));
259 QStyleOptionHeader opt;
260 initStyleOption(&opt);
262 QStyle::State state = QStyle::State_None;
264 state |= QStyle::State_Enabled;
265 if (window()->isActiveWindow())
266 state |= QStyle::State_Active;
268 opt.selectedPosition = QStyleOptionHeader::NotAdjacent;
270 opt.textAlignment = Qt::AlignLeft | Qt::AlignTop;
272 opt.text = frameIdText;
273 style->drawControl(QStyle::CE_HeaderLabel, &opt, painter,
this);
282 const int minWidth = 36;
284 int spanWidth = this->
fps;
286 while (spanWidth * sectionWidth < minWidth) {
290 bool splitHappened =
false;
293 splitHappened =
false;
295 if (!(spanWidth & 0x1) &&
296 spanWidth * sectionWidth / 2 > minWidth) {
299 splitHappened =
true;
301 }
else if (!(spanWidth % 3) &&
302 spanWidth * sectionWidth / 3 > minWidth) {
305 splitHappened =
true;
307 }
else if (!(spanWidth % 5) &&
308 spanWidth * sectionWidth / 5 > minWidth) {
311 splitHappened =
true;
314 }
while (splitHappened);
317 if (sectionWidth > minWidth) {
330 QFontMetrics metrics(this->font());
331 const int textHeight = metrics.height();
333 QPoint
p1 =
rect.topLeft() + QPoint(0, textHeight);
334 QPoint
p2 =
rect.topRight() + QPoint(0, textHeight);
336 QRect frameRect = QRect(
p1, QSize(
rect.width(),
rect.height() - textHeight));
338 const int width =
rect.width();
340 int spanWidth =
m_d->calcSpanWidth(width);
342 const int internalIndex = logicalIndex % spanWidth;
343 const int userFrameId = logicalIndex;
345 const int spanEnd = qMin(count(), logicalIndex + spanWidth);
346 QRect spanRect(
rect.topLeft(), QSize(width * (spanEnd - logicalIndex), textHeight));
348#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
349 QStyleOptionViewItem option = viewOptions();
351 QStyleOptionViewItem option;
352 initViewItemOption(&option);
354 const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option,
this);
355 const QColor gridColor =
static_cast<QRgb>(gridHint);
356 const QPen gridPen = QPen(gridColor);
358 if (!internalIndex) {
359 bool isIntegralLine = (logicalIndex + spanWidth) %
m_d->fps == 0;
360 bool isPrevIntegralLine = logicalIndex %
m_d->fps == 0;
361 paintSpan(painter, userFrameId, spanRect, isIntegralLine, isPrevIntegralLine, style(),
palette(), gridPen);
367 QVariant activeValue = model()->headerData(logicalIndex, orientation(),
370 QVariant cachedValue = model()->headerData(logicalIndex, orientation(),
373 QVariant withinRangeValue = model()->headerData(logicalIndex, orientation(),
376 const bool isActive = activeValue.isValid() && activeValue.toBool();
377 const bool isCached = cachedValue.isValid() && cachedValue.toBool();
378 const bool isWithinRange = withinRangeValue.isValid() && withinRangeValue.toBool();
382 }
else if (isCached && isWithinRange) {
386 painter->fillRect(frameRect, fillColor);
389 lines << QLine(
p1,
p2);
390 lines << QLine(frameRect.topRight(), frameRect.bottomRight());
391 lines << QLine(frameRect.bottomLeft(), frameRect.bottomRight());
393 QPen oldPen = painter->pen();
394 painter->setPen(gridPen);
395 painter->drawLines(lines);
396 painter->setPen(oldPen);
415 qreal newSectionSize =
zoom *
m_d->unitSectionSize;
417 if (newSectionSize < m_d->minSectionSize) {
418 newSectionSize =
m_d->minSectionSize;
419 zoom = qreal(newSectionSize) /
m_d->unitSectionSize;
420 }
else if (newSectionSize >
m_d->maxSectionSize) {
421 newSectionSize =
m_d->maxSectionSize;
422 zoom = qreal(newSectionSize) /
m_d->unitSectionSize;
425 m_d->remainder = newSectionSize - floor(newSectionSize);
427 if (newSectionSize != defaultSectionSize()) {
428 setDefaultSectionSize(newSectionSize);
459 int leftmost = std::numeric_limits<int>::max();
460 int rightmost = std::numeric_limits<int>::min();
462 Q_FOREACH (
const QModelIndex &index, indexes) {
463 leftmost = qMin(leftmost, index.column());
464 rightmost = qMax(rightmost, index.column());
465 if (!columns.contains(index.column())) {
466 columns.append(index.column());
470 if (leftmostCol) *leftmostCol = leftmost;
471 if (rightmostCol) *rightmostCol = rightmost;
473 return columns.size();
478 int logical = logicalIndexAt(e->pos());
483 if (e->button() == Qt::RightButton) {
484 if (numSelectedColumns <= 1) {
501 menu.addSection(i18n(
"Edit Columns:"));
511 QMenu *frames = menu.addMenu(i18nc(
"@item:inmenu",
"Keyframe Columns"));
514 frames->addSeparator();
519 QMenu *hold = menu.addMenu(i18nc(
"@item:inmenu",
"Hold Frame Columns"));
522 hold->addSeparator();
532 if (numSelectedColumns > 1) {
541 menu.exec(e->globalPos());
545 }
else if (e->button() == Qt::LeftButton) {
546 m_d->lastPressSectionIndex = logical;
551 QHeaderView::mousePressEvent(e);
556 int logical = logicalIndexAt(e->pos());
559 if (e->buttons() & Qt::LeftButton) {
561 m_d->model->setScrubState(
true);
563 KIS_ASSERT(activeValue.type() == QVariant::Bool);
564 if (activeValue.toBool() !=
true) {
569 if (
m_d->lastPressSectionIndex >= 0 &&
570 logical !=
m_d->lastPressSectionIndex &&
571 e->modifiers() & Qt::ShiftModifier) {
573 const int minCol = qMin(
m_d->lastPressSectionIndex, logical);
574 const int maxCol = qMax(
m_d->lastPressSectionIndex, logical);
576 QItemSelection sel(
m_d->model->index(0, minCol),
m_d->model->index(0, maxCol));
577 selectionModel()->select(sel,
578 QItemSelectionModel::Columns |
579 QItemSelectionModel::SelectCurrent);
586 QHeaderView::mouseMoveEvent(e);
615 if (e->button() == Qt::LeftButton) {
616 int timeUnderMouse = qMax(logicalIndexAt(e->pos()), 0);
618 if (timeUnderMouse !=
m_d->model->currentTime()) {
621 m_d->model->setScrubState(
false);
624 QHeaderView::mouseReleaseEvent(e);