QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgshistorywidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgshistorywidget.cpp
3 ------------------
4 Date : April 2023
5 Copyright : (C) 2023 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 "qgshistorywidget.h"
17#include "qgsgui.h"
19#include "qgshistoryentrynode.h"
20#include "qgssettings.h"
21
22#include <QTextBrowser>
23#include <QtGlobal>
24#include <QMenu>
25
26QgsHistoryWidget::QgsHistoryWidget( const QString &providerId, Qgis::HistoryProviderBackends backends, QgsHistoryProviderRegistry *registry, const QgsHistoryWidgetContext &context, QWidget *parent )
27 : QgsPanelWidget( parent )
28 , mContext( context )
29{
30 setupUi( this );
31
32 mModel = new QgsHistoryEntryModel( providerId, backends, registry, mContext, this );
33 mProxyModel = new QgsHistoryEntryProxyModel( this );
34 mProxyModel->setSourceModel( mModel );
35
36 mTreeView->setModel( mProxyModel );
37
38 mFilterEdit->setShowClearButton( true );
39 mFilterEdit->setShowSearchIcon( true );
40 connect( mFilterEdit, &QLineEdit::textChanged, mProxyModel, &QgsHistoryEntryProxyModel::setFilter );
41 connect( mTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &QgsHistoryWidget::currentItemChanged );
42 connect( mTreeView, &QTreeView::doubleClicked, this, &QgsHistoryWidget::nodeDoubleClicked );
43 mTreeView->setExpandsOnDoubleClick( false );
44
45 mTreeView->setContextMenuPolicy( Qt::CustomContextMenu );
46 connect( mTreeView, &QWidget::customContextMenuRequested, this, &QgsHistoryWidget::showNodeContextMenu );
47
48 // expand first group (usually most recent date group)
49 const QModelIndex firstGroup = mProxyModel->index( 0, 0, QModelIndex() );
50 mTreeView->expand( firstGroup );
51
52 QgsSettings settings;
53 mSplitter->restoreState( settings.value( QStringLiteral( "history/splitterState%1" ).arg( providerId ) ).toByteArray() );
54
55 connect( mSplitter, &QSplitter::splitterMoved, this, [providerId, this]
56 {
57 QgsSettings settings;
58 settings.setValue( QStringLiteral( "history/splitterState%1" ).arg( providerId ), mSplitter->saveState() );
59 } );
60}
61
62void QgsHistoryWidget::currentItemChanged( const QModelIndex &selected, const QModelIndex & )
63{
64 QWidget *newWidget = nullptr;
65 if ( QgsHistoryEntryNode *node = mModel->index2node( mProxyModel->mapToSource( selected ) ) )
66 {
67 newWidget = node->createWidget( mContext );
68 if ( !newWidget )
69 {
70 const QString html = node->html( mContext );
71 if ( !html.isEmpty() )
72 {
73 QTextBrowser *htmlBrowser = new QTextBrowser();
74 htmlBrowser->setOpenExternalLinks( true );
75 htmlBrowser->setHtml( html );
76 newWidget = htmlBrowser;
77 }
78 }
79 if ( newWidget )
80 {
81 mContainerStackedWidget->addWidget( newWidget );
82 mContainerStackedWidget->setCurrentWidget( newWidget );
83 }
84 }
85
86 if ( !newWidget )
87 {
88 //remove current widget, if any
89 if ( mContainerStackedWidget->count() > 1 )
90 {
91 mContainerStackedWidget->removeWidget( mContainerStackedWidget->widget( 1 ) );
92 mContainerStackedWidget->setCurrentIndex( 0 );
93 }
94 }
95}
96
97void QgsHistoryWidget::nodeDoubleClicked( const QModelIndex &index )
98{
99 if ( QgsHistoryEntryNode *node = mModel->index2node( mProxyModel->mapToSource( index ) ) )
100 {
101 if ( node->doubleClicked( mContext ) )
102 return; // double-click handled
103 }
104
105 // otherwise double-clicks expands/collapses the node
106 if ( mTreeView->isExpanded( index ) )
107 mTreeView->collapse( index );
108 else
109 mTreeView->expand( index );
110}
111
112void QgsHistoryWidget::showNodeContextMenu( const QPoint &pos )
113{
114 if ( QgsHistoryEntryNode *node = mModel->index2node( mProxyModel->mapToSource( mTreeView->currentIndex() ) ) )
115 {
116 QMenu *menu = new QMenu();
117
118 node->populateContextMenu( menu, mContext );
119 if ( !menu->isEmpty() )
120 {
121 menu->exec( mTreeView->mapToGlobal( pos ) );
122 }
123 delete menu;
124 }
125}
126
127//
128// QgsHistoryEntryProxyModel
129//
130
132QgsHistoryEntryProxyModel::QgsHistoryEntryProxyModel( QObject *parent )
133 : QSortFilterProxyModel( parent )
134{
135 setDynamicSortFilter( true );
136 setRecursiveFilteringEnabled( true );
137}
138
139void QgsHistoryEntryProxyModel::setFilter( const QString &filter )
140{
141 if ( filter == mFilter )
142 return;
143
144 mFilter = filter;
145 invalidateFilter();
146}
147
148bool QgsHistoryEntryProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
149{
150 if ( mFilter.isEmpty() )
151 return true;
152
153 const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
154 if ( QgsHistoryEntryNode *node = qobject_cast< QgsHistoryEntryModel * >( sourceModel() )->index2node( sourceIndex ) )
155 {
156 if ( !node->matchesString( mFilter ) )
157 {
158 return false;
159 }
160 }
161 return true;
162}
QFlags< HistoryProviderBackend > HistoryProviderBackends
Definition: qgis.h:2847
An item model representing history entries in a hierarchical tree structure.
QgsHistoryEntryNode * index2node(const QModelIndex &index) const
Returns node for given index.
Base class for nodes representing a QgsHistoryEntry.
The QgsHistoryProviderRegistry is a registry for objects which track user history (i....
Contains settings which reflect the context in which a history widget is shown, e....
QgsHistoryWidget(const QString &providerId=QString(), Qgis::HistoryProviderBackends backends=Qgis::HistoryProviderBackend::LocalProfile, QgsHistoryProviderRegistry *registry=nullptr, const QgsHistoryWidgetContext &context=QgsHistoryWidgetContext(), QWidget *parent=nullptr)
Constructor for QgsHistoryWidget, with the specified parent widget.
Base class for any widget that can be shown as a inline panel.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.