QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
qgslayoutitemslistview.cpp
Go to the documentation of this file.
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
17#include "qgslayout.h"
18#include "qgslayoutmodel.h"
20#include "qgslayoutview.h"
21#include "qgslayoutitemgroup.h"
22#include <QHeaderView>
23#include <QMenu>
24#include <QMouseEvent>
25
26
28 : QSortFilterProxyModel( parent )
29 , mModel( model )
30{
31 setSourceModel( mModel );
32}
33
35{
36 return mModel->itemFromIndex( mapToSource( index ) );
37}
38
39QModelIndex QgsLayoutItemsListViewModel::indexForItem( QgsLayoutItem *item, const int column ) const
40{
41 return mapFromSource( mModel->indexForItem( item, column ) );
42}
43
44void QgsLayoutItemsListViewModel::setSelected( const QModelIndex &index )
45{
46 mModel->setSelected( mapToSource( index ) );
47}
48
49bool QgsLayoutItemsListViewModel::filterAcceptsRow( int sourceRow, const QModelIndex & ) const
50{
51 if ( sourceRow == 0 )
52 return false; // hide empty null item row
53 return true;
54}
55
56QVariant QgsLayoutItemsListViewModel::data( const QModelIndex &index, int role ) const
57{
58 if ( !index.isValid() )
59 return QVariant();
60
61 QgsLayoutItem *item = itemFromIndex( index );
62 if ( !item )
63 {
64 return QVariant();
65 }
66
67 if ( role == Qt::FontRole )
68 {
69 if ( index.column() == QgsLayoutModel::ItemId && item->isSelected() )
70 {
71 //draw name of selected items in bold
72 QFont boldFont;
73 boldFont.setBold( true );
74 return boldFont;
75 }
76 }
77
78 return QSortFilterProxyModel::data( index, role );
79}
80
81
82//
83// QgsLayoutItemsListView
84//
85
87 : QTreeView( parent )
88 , mDesigner( designer )
89{
90 setColumnWidth( 0, 30 );
91 setColumnWidth( 1, 30 );
92 setDragEnabled( true );
93 setAcceptDrops( true );
94 setDropIndicatorShown( true );
95 setDragDropMode( QAbstractItemView::InternalMove );
96 setContextMenuPolicy( Qt::CustomContextMenu );
97 setIndentation( 0 );
98
99 // Allow multi selection from the list view
100 setSelectionMode( QAbstractItemView::ExtendedSelection );
101 setSelectionBehavior( QAbstractItemView::SelectRows );
102
103 connect( this, &QWidget::customContextMenuRequested, this, &QgsLayoutItemsListView::showContextMenu );
104 connect( mDesigner->view(), &QgsLayoutView::itemFocused, this, &QgsLayoutItemsListView::onItemFocused );
105}
106
108{
109 mLayout = layout;
110 mModel = new QgsLayoutItemsListViewModel( layout->itemsModel(), this );
111 setModel( mModel );
112
113 header()->setSectionResizeMode( 0, QHeaderView::Fixed );
114 header()->setSectionResizeMode( 1, QHeaderView::Fixed );
115 setColumnWidth( 0, Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'x' ) * 4 );
116 setColumnWidth( 1, Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'x' ) * 4 );
117 header()->setSectionsMovable( false );
118
119 connect( selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsLayoutItemsListView::updateSelection );
120}
121
122void QgsLayoutItemsListView::updateSelection()
123{
124 // Do nothing if we are currenlty updating the selection
125 // because user has selected/deselected some items in the
126 // graphics view
127 if ( !mModel || mUpdatingFromView )
128 return;
129
130 // Set the updating flag
131 mUpdatingSelection = true;
132
133 // Deselect all items from the layout (prevent firing signals, selection will be changed)
134 whileBlocking( mLayout )->deselectAll();
135
136 // Build the list of selected items
137 QList<QgsLayoutItem *> selectedItems;
138 for ( const QModelIndex &index : selectionModel()->selectedIndexes() )
139 {
140 if ( QgsLayoutItem *item = mModel->itemFromIndex( index ) )
141 {
142 selectedItems << item;
143 }
144 }
145
146
147 bool itemSelected = false;
148
149 // Check if the clicked item was selected or deselected
150 if ( selectionModel()->isSelected( selectionModel()->currentIndex() ) )
151 {
152 // It it was selected, set it as the layout's selected item;
153 // This will show the item properties
154 QgsLayoutItem *currentItem = mModel->itemFromIndex( selectionModel()->currentIndex() );
155 mLayout->setSelectedItem( currentItem );
156 itemSelected = true;
157 }
158 for ( QgsLayoutItem *item : selectedItems )
159 {
160 if ( !itemSelected )
161 {
162 // If clicked item was actually deselected, set the first selected item in the list
163 // as the layout's selected item
164 mLayout->setSelectedItem( item );
165 itemSelected = true;
166 }
167 else
168 {
169 item->setSelected( true );
170 }
171
172 // find top level group this item is contained within, and mark the group as selected
173 QgsLayoutItemGroup *group = item->parentGroup();
174 while ( group && group->parentGroup() )
175 {
176 group = group->parentGroup();
177 }
178 if ( group && group != item )
179 group->setSelected( true );
180
181 }
182 // Reset the updating flag
183 mUpdatingSelection = false;
184}
185
186void QgsLayoutItemsListView::onItemFocused( QgsLayoutItem *focusedItem )
187{
188 // Do nothing if we are in the middle of selecting items in the layoutView
189 if ( !mModel || mUpdatingSelection )
190 return;
191
192 // Set the updating flag
193 mUpdatingFromView = true;
194
195 // Deselect all items in list
196 clearSelection();
197
198 // Set the current index to the focused item
199 QModelIndex index = mModel->indexForItem( focusedItem );
200 if ( index.isValid() )
201 {
202 setCurrentIndex( index );
203 }
204
205 // Select rows in the item list for every selected items in the graphics view
206 const QList< QgsLayoutItem *> selectedItems = mLayout->selectedLayoutItems();
207 for ( QgsLayoutItem *item : selectedItems )
208 {
209 const QModelIndex firstCol = mModel->indexForItem( item );
210 if ( firstCol.isValid() )
211 {
212 // Select the whole row
213 QItemSelection selection;
214 selection.select( firstCol, firstCol.siblingAtColumn( mModel->columnCount( firstCol.parent() ) - 1 ) );
215 selectionModel()->select( selection, QItemSelectionModel::Select );
216 }
217 }
218 // Reset the updating flag
219 mUpdatingFromView = false;
220}
221
222void QgsLayoutItemsListView::showContextMenu( QPoint point )
223{
224 if ( !mModel )
225 return;
226 const QModelIndex index = indexAt( point );
227 QgsLayoutItem *item = mModel->itemFromIndex( index );
228 if ( !item )
229 return;
230
231 QMenu *menu = new QMenu( this );
232
233 QAction *copyAction = new QAction( tr( "Copy Item" ), menu );
234 connect( copyAction, &QAction::triggered, this, [this, item]()
235 {
236 mDesigner->view()->copyItems( QList< QgsLayoutItem * >() << item, QgsLayoutView::ClipboardCopy );
237 } );
238 menu->addAction( copyAction );
239 QAction *deleteAction = new QAction( tr( "Delete Item" ), menu );
240 connect( deleteAction, &QAction::triggered, this, [this, item]()
241 {
242 mDesigner->view()->deleteItems( QList< QgsLayoutItem * >() << item );
243 } );
244 menu->addAction( deleteAction );
245 menu->addSeparator();
246
247 QAction *itemPropertiesAction = new QAction( tr( "Item Properties…" ), menu );
248 connect( itemPropertiesAction, &QAction::triggered, this, [this, item]()
249 {
250 mDesigner->showItemOptions( item, true );
251 } );
252 menu->addAction( itemPropertiesAction );
253
254 menu->popup( mapToGlobal( point ) );
255}
static const double UI_SCALE_FACTOR
UI scaling factor.
Definition qgis.h:4086
A common interface for layout designer dialogs and widgets.
virtual void showItemOptions(QgsLayoutItem *item, bool bringPanelToFront=true)=0
Shows the configuration widget for the specified layout item.
virtual QgsLayoutView * view()=0
Returns the layout view utilized by the designer.
A container for grouping several QgsLayoutItems.
Base class for graphical items within a QgsLayout.
QgsLayoutItemGroup * parentGroup() const
Returns the item's parent group, if the item is part of a QgsLayoutItemGroup group.
virtual void setSelected(bool selected)
Sets whether the item should be selected.
Model for the layout items list view.
QgsLayoutItem * itemFromIndex(const QModelIndex &index) const
Returns the layout item listed at the specified index.
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
QgsLayoutItemsListViewModel(QgsLayoutModel *model, QObject *parent)
constructor
void setSelected(const QModelIndex &index)
Sets the selected index.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex indexForItem(QgsLayoutItem *item, const int column=0) const
Returns the model index matching the specified layout item.
void setCurrentLayout(QgsLayout *layout)
Sets the current layout.
QgsLayoutItemsListView(QWidget *parent, QgsLayoutDesignerInterface *designer)
Constructor for QgsLayoutItemsListView.
A model for items attached to a layout.
QgsLayoutItem * itemFromIndex(const QModelIndex &index) const
Returns the QgsLayoutItem corresponding to a QModelIndex index, if possible.
QModelIndex indexForItem(QgsLayoutItem *item, int column=0)
Returns the QModelIndex corresponding to a QgsLayoutItem item and column, if possible.
void itemFocused(QgsLayoutItem *item)
Emitted when an item is "focused" in the view, i.e.
@ ClipboardCopy
Copy items.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
Definition qgslayout.h:50
QgsLayoutModel * itemsModel()
Returns the items model attached to the layout.
QList< QgsLayoutItem * > selectedLayoutItems(bool includeLockedItems=true)
Returns list of selected layout items.
void setSelectedItem(QgsLayoutItem *item)
Clears any selected items and sets item as the current selection.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:4258