1 /***************************************************************************
2 qgslayoutitemslistview.cpp
3 --------------------------
4 Date : October 2017
5 Copyright : (C) 2017 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16 #include "qgslayoutitemslistview.h"
17 #include "qgslayout.h"
18 #include "qgslayoutmodel.h"
19 #include "qgslayoutdesignerinterface.h"
20 #include "qgslayoutview.h"
21 #include <QHeaderView>
22 #include <QMenu>
23 #include <QMouseEvent>
24
25
QgsLayoutItemsListViewModel(QgsLayoutModel * model,QObject * parent)26 QgsLayoutItemsListViewModel::QgsLayoutItemsListViewModel( QgsLayoutModel *model, QObject *parent )
27 : QSortFilterProxyModel( parent )
28 , mModel( model )
29 {
30 setSourceModel( mModel );
31 }
32
itemFromIndex(const QModelIndex & index) const33 QgsLayoutItem *QgsLayoutItemsListViewModel::itemFromIndex( const QModelIndex &index ) const
34 {
35 return mModel->itemFromIndex( mapToSource( index ) );
36 }
37
setSelected(const QModelIndex & index)38 void QgsLayoutItemsListViewModel::setSelected( const QModelIndex &index )
39 {
40 mModel->setSelected( mapToSource( index ) );
41 }
42
filterAcceptsRow(int sourceRow,const QModelIndex &) const43 bool QgsLayoutItemsListViewModel::filterAcceptsRow( int sourceRow, const QModelIndex & ) const
44 {
45 if ( sourceRow == 0 )
46 return false; // hide empty null item row
47 return true;
48 }
49
data(const QModelIndex & index,int role) const50 QVariant QgsLayoutItemsListViewModel::data( const QModelIndex &index, int role ) const
51 {
52 if ( !index.isValid() )
53 return QVariant();
54
55 QgsLayoutItem *item = itemFromIndex( index );
56 if ( !item )
57 {
58 return QVariant();
59 }
60
61 if ( role == Qt::FontRole )
62 {
63 if ( index.column() == QgsLayoutModel::ItemId && item->isSelected() )
64 {
65 //draw name of selected items in bold
66 QFont boldFont;
67 boldFont.setBold( true );
68 return boldFont;
69 }
70 }
71
72 return QSortFilterProxyModel::data( index, role );
73 }
74
75
76 //
77 // QgsLayoutItemsListView
78 //
79
QgsLayoutItemsListView(QWidget * parent,QgsLayoutDesignerInterface * designer)80 QgsLayoutItemsListView::QgsLayoutItemsListView( QWidget *parent, QgsLayoutDesignerInterface *designer )
81 : QTreeView( parent )
82 , mDesigner( designer )
83 {
84 setColumnWidth( 0, 30 );
85 setColumnWidth( 1, 30 );
86 setDragEnabled( true );
87 setAcceptDrops( true );
88 setDropIndicatorShown( true );
89 setDragDropMode( QAbstractItemView::InternalMove );
90 setContextMenuPolicy( Qt::CustomContextMenu );
91 setIndentation( 0 );
92 connect( this, &QWidget::customContextMenuRequested, this, &QgsLayoutItemsListView::showContextMenu );
93 }
94
setCurrentLayout(QgsLayout * layout)95 void QgsLayoutItemsListView::setCurrentLayout( QgsLayout *layout )
96 {
97 mLayout = layout;
98 mModel = new QgsLayoutItemsListViewModel( layout->itemsModel(), this );
99 setModel( mModel );
100
101 header()->setSectionResizeMode( 0, QHeaderView::Fixed );
102 header()->setSectionResizeMode( 1, QHeaderView::Fixed );
103 setColumnWidth( 0, Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'x' ) * 4 );
104 setColumnWidth( 1, Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'x' ) * 4 );
105 header()->setSectionsMovable( false );
106
107 connect( selectionModel(), &QItemSelectionModel::currentChanged, mModel, &QgsLayoutItemsListViewModel::setSelected );
108 }
109
showContextMenu(QPoint point)110 void QgsLayoutItemsListView::showContextMenu( QPoint point )
111 {
112 if ( !mModel )
113 return;
114 const QModelIndex index = indexAt( point );
115 QgsLayoutItem *item = mModel->itemFromIndex( index );
116 if ( !item )
117 return;
118
119 QMenu *menu = new QMenu( this );
120
121 QAction *copyAction = new QAction( tr( "Copy Item" ), menu );
122 connect( copyAction, &QAction::triggered, this, [this, item]()
123 {
124 mDesigner->view()->copyItems( QList< QgsLayoutItem * >() << item, QgsLayoutView::ClipboardCopy );
125 } );
126 menu->addAction( copyAction );
127 QAction *deleteAction = new QAction( tr( "Delete Item" ), menu );
128 connect( deleteAction, &QAction::triggered, this, [this, item]()
129 {
130 mDesigner->view()->deleteItems( QList< QgsLayoutItem * >() << item );
131 } );
132 menu->addAction( deleteAction );
133 menu->addSeparator();
134
135 QAction *itemPropertiesAction = new QAction( tr( "Item Properties…" ), menu );
136 connect( itemPropertiesAction, &QAction::triggered, this, [this, item]()
137 {
138 mDesigner->showItemOptions( item, true );
139 } );
140 menu->addAction( itemPropertiesAction );
141
142 menu->popup( mapToGlobal( point ) );
143 }
144