15#include <kconfiggroup.h>
18#include <ksharedconfig.h>
22#include <QContextMenuEvent>
28#include <QPersistentModelIndex>
29#include <QApplication>
38#define DRAG_WHILE_DRAG_WORKAROUND
41#ifdef DRAG_WHILE_DRAG_WORKAROUND
42#define DRAG_WHILE_DRAG_WORKAROUND_START() d->isDragging = true
43#define DRAG_WHILE_DRAG_WORKAROUND_STOP() d->isDragging = false
45#define DRAG_WHILE_DRAG_WORKAROUND_START()
46#define DRAG_WHILE_DRAG_WORKAROUND_STOP()
55#ifdef DRAG_WHILE_DRAG_WORKAROUND
64#ifdef DRAG_WHILE_DRAG_WORKAROUND
72 , m_draggingFlag(false)
75 setItemDelegate(&
d->delegate);
77 setMouseTracking(
true);
78 setSelectionBehavior(SelectRows);
79 setDefaultDropAction(Qt::MoveAction);
80 setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
81 setSelectionMode(QAbstractItemView::ExtendedSelection);
82 setRootIsDecorated(
false);
86 setDragDropMode(QAbstractItemView::DragDrop);
88 setDropIndicatorShown(
true);
93 connect(scroller, SIGNAL(stateChanged(QScroller::State)),
106 QTreeView::setModel(model);
108 if (!this->model()->inherits(
"KisNodeModel") && !this->model()->inherits(
"KisNodeFilterProxyModel")) {
109 qWarning() <<
"NodeView may not work with" << model->metaObject()->className();
111 if (this->model()->columnCount() != 3) {
112 qWarning() <<
"NodeView: expected 2 model columns, got " << this->model()->columnCount();
132 for (
int i = 0, n = list.count(); i < n; ++i) {
133 if (list.at(i).isMutable) {
135 connect(a, SIGNAL(toggled(
bool,QPersistentModelIndex,
int)),
148 d->delegate.toggleSolo(index);
156 event->type() == QEvent::MouseButtonPress ) {
157 const QMouseEvent *mevent =
static_cast<const QMouseEvent*
>(event);
158 if (mevent->modifiers() & Qt::ControlModifier)
159 return QItemSelectionModel::NoUpdate;
162 return QTreeView::selectionCommand(index, event);
169 QModelIndex index = QTreeView::indexAt(point);
170 if (!index.isValid()) {
173 index = QTreeView::indexAt(point - QPoint(point.x(), 0) + QPoint(width() / 2, 0));
183 case QEvent::MouseButtonPress: {
186 const QPoint pos =
static_cast<QMouseEvent*
>(e)->pos();
190 return QTreeView::viewportEvent(e);
192 QModelIndex index = model()->buddy(
indexAt(pos));
193 if (
d->delegate.editorEvent(e, model(),
optionForIndex(index), index)) {
197 case QEvent::Leave: {
198 QEvent e(QEvent::Leave);
200 d->hovered = QModelIndex();
202 case QEvent::MouseMove: {
203#ifdef DRAG_WHILE_DRAG_WORKAROUND
209 const QPoint pos =
static_cast<QMouseEvent*
>(e)->pos();
212 if (
d->hovered.isValid()) {
213 QEvent e(QEvent::Leave);
217 QEvent e(QEvent::Enter);
224 Qt::MouseButtons
buttons =
static_cast<QMouseEvent*
>(e)->
buttons();
225 if ((Qt::LeftButton | Qt::MiddleButton) &
buttons) {
226 if ((pos -
d->lastPos).manhattanLength() > qApp->startDragDistance()) {
227 return QTreeView::viewportEvent(e);
232 case QEvent::ToolTip: {
233 const QPoint pos =
static_cast<QHelpEvent*
>(e)->pos();
235 return QTreeView::viewportEvent(e);
237 QModelIndex index = model()->buddy(
indexAt(pos));
238 return d->delegate.editorEvent(e, model(),
optionForIndex(index), index);
240 case QEvent::Resize: {
241 scheduleDelayedItemsLayout();
247 return QTreeView::viewportEvent(e);
252 QTreeView::contextMenuEvent(e);
253 QModelIndex i =
indexAt(e->pos());
255 i = model()->buddy(i);
266 QTreeView::currentChanged(current, previous);
267 if (current != previous) {
268 Q_ASSERT(!current.isValid() || current.model() == model());
276 QTreeView::dataChanged(topLeft, bottomRight);
278 for (
int x = topLeft.row(); x <= bottomRight.row(); ++x) {
279 for (
int y = topLeft.column(); y <= bottomRight.column(); ++y) {
280 QModelIndex index = topLeft.sibling(x, y);
282 if (currentIndex() != index) {
283 setCurrentIndex(index);
294 QTreeView::selectionChanged(selected, deselected);
302 list[num].state = on;
308#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
309 QStyleOptionViewItem option = viewOptions();
311 QStyleOptionViewItem option;
312 initViewItemOption(&option);
314 option.rect = visualRect(index);
315 if (index == currentIndex())
316 option.state |= QStyle::State_HasFocus;
323 QTreeView::startDrag(supportedActions);
328 const QModelIndexList selectedIndexes = selectionModel()->selectedIndexes();
329 Q_ASSERT(!selectedIndexes.isEmpty());
331 const int itemCount = selectedIndexes.count();
341 else if (itemCount > 4) {
345 else if (itemCount < xCount) {
349 int yCount = itemCount / xCount;
350 if (itemCount % xCount != 0) {
354 if (yCount > xCount) {
359 QPixmap dragPixmap(xCount * size + xCount - 1, yCount * size + yCount - 1);
360 dragPixmap.fill(Qt::transparent);
362 QPainter painter(&dragPixmap);
365 Q_FOREACH (
const QModelIndex &selectedIndex, selectedIndexes) {
367 painter.drawPixmap(x, y, QPixmap::fromImage(img.scaled(QSize(size, size), Qt::KeepAspectRatio, Qt::SmoothTransformation)));
370 if (x >= dragPixmap.width()) {
374 if (y >= dragPixmap.height()) {
385 header()->setStretchLastSection(
false);
390 if (
KisConfig(
false).useLayerSelectionCheckbox()) {
393 header()->resizeSection(
DEFAULT_COL, event->size().width() - otherColumnsWidth);
398 QTreeView::resizeEvent(event);
404 QTreeView::paintEvent(event);
408 const QModelIndex &index)
const
410#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
411 QStyleOptionViewItem option = viewOptions();
413 QStyleOptionViewItem option;
414 initViewItemOption(&option);
418 d->delegate.drawBranches(painter, option, index);
423 QTreeView::dropEvent(ev);
429 QSize size(visualRect(model()->index(0, 0, QModelIndex())).width(), visualRect(model()->index(0, 0, QModelIndex())).height());
430 int scrollBarValue = verticalScrollBar()->value();
432 QPoint cursorPosition = QWidget::mapFromGlobal(QCursor::pos());
434 int numberRow = (cursorPosition.y() + scrollBarValue) / size.height();
438 if (abs((cursorPosition.y() + scrollBarValue) - size.height()*numberRow) > (size.height()/2)) {
442 if (numberRow > model()->rowCount(QModelIndex())) {
443 numberRow = model()->rowCount(QModelIndex());
453 QVariant data = QVariant::fromValue(
454 static_cast<void*
>(
const_cast<QMimeData*
>(ev->mimeData())));
457 QTreeView::dragEnterEvent(ev);
463 QTreeView::dragMoveEvent(ev);
468 QTreeView::dragLeaveEvent(e);
484 d->delegate.slotUpdateIcon();
495 d->delegate.slotConfigChanged();
#define DRAG_WHILE_DRAG_WORKAROUND_START()
#define DRAG_WHILE_DRAG_WORKAROUND_STOP()
bool useLayerSelectionCheckbox(bool defaultValue=false) const
@ PropertiesRole
A list of properties the part has.
@ ActiveRole
Whether the section is the active one.
int selectedButtonColumnWidth() const
int visibilityColumnWidth() const
static KisNodeViewColorScheme * instance()
QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index, const QEvent *event) const override
void setDraggingFlag(bool flag=true)
virtual void showContextMenu(const QPoint &globalPos, const QModelIndex &index)
void contextMenuRequested(const QPoint &globalPos, const QModelIndex &index)
void paintEvent(QPaintEvent *event) override
void selectionChanged(const QModelIndexList &)
void dragMoveEvent(QDragMoveEvent *ev) override
void updateNode(const QModelIndex &index)
void resizeEvent(QResizeEvent *event) override
bool viewportEvent(QEvent *event) override
int cursorPageIndex() const
void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override
NodeView(QWidget *parent=0)
void slotScrollerStateChanged(QScroller::State state)
void toggleSolo(const QModelIndex &index)
void slotConfigurationChanged()
void slotUpdateIcons()
called with a theme change to refresh icon colors
void dropEvent(QDropEvent *ev) override
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles=QVector< int >()) override
QStyleOptionViewItem optionForIndex(const QModelIndex &index) const
void slotActionToggled(bool on, const QPersistentModelIndex &index, int property)
QPixmap createDragPixmap() const
QPersistentModelIndex hovered
void dragEnterEvent(QDragEnterEvent *e) override
void addPropertyActions(QMenu *menu, const QModelIndex &index)
void startDrag(Qt::DropActions supportedActions) override
void setModel(QAbstractItemModel *model) override
void dragLeaveEvent(QDragLeaveEvent *e) override
void updateSelectedCheckboxColumn()
void contextMenuEvent(QContextMenuEvent *event) override
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override
QModelIndex indexAt(const QPoint &point) const override
QString buttons(const T &ev)