QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsdbqueryhistoryprovider.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdbqueryhistoryprovider.cpp
3 --------------------------
4 begin : April 2023
5 copyright : (C) 2023 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
19#include "qgsapplication.h"
20#include "qgscodeeditorsql.h"
21#include "qgshistoryentry.h"
23#include "qgsprovidermetadata.h"
24#include "qgsproviderregistry.h"
25
26#include <QAction>
27#include <QClipboard>
28#include <QIcon>
29#include <QMenu>
30#include <QMimeData>
31
32#include "moc_qgsdbqueryhistoryprovider.cpp"
33
35
36class DatabaseQueryHistoryNode : public QgsHistoryEntryGroup
37{
38 public:
39 DatabaseQueryHistoryNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider )
40 : QgsHistoryEntryGroup()
41 , mEntry( entry )
42 , mProvider( provider )
43 {
44 }
45
46 protected:
47 QgsHistoryEntry mEntry;
48 QgsDatabaseQueryHistoryProvider *mProvider = nullptr;
49};
50
51class DatabaseQueryValueNode : public DatabaseQueryHistoryNode
52{
53 public:
54 DatabaseQueryValueNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider, const QString &value )
55 : DatabaseQueryHistoryNode( entry, provider )
56 , mValue( value )
57 {}
58
59 QVariant data( int role = Qt::DisplayRole ) const override
60 {
61 switch ( role )
62 {
63 case Qt::DisplayRole:
64 case Qt::ToolTipRole:
65 return mValue;
66
67 default:
68 return QVariant();
69 }
70 }
71
72 QString html( const QgsHistoryWidgetContext & ) const override
73 {
74 return mValue;
75 }
76
77 private:
78 QString mValue;
79};
80
81class DatabaseQueryRootNode : public DatabaseQueryHistoryNode
82{
83 public:
84 DatabaseQueryRootNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider )
85 : DatabaseQueryHistoryNode( entry, provider )
86 {
87 setEntry( entry );
88
89 mProviderKey = mEntry.entry.value( QStringLiteral( "provider" ) ).toString();
90 }
91
92 QVariant data( int role = Qt::DisplayRole ) const override
93 {
94 switch ( role )
95 {
96 case Qt::DisplayRole:
97 case Qt::ToolTipRole:
98 return mEntry.entry.value( QStringLiteral( "query" ) );
99
100 case Qt::DecorationRole:
101 {
102 if ( !mProviderIcon.isNull() )
103 return mProviderIcon;
104
105 if ( QgsProviderMetadata *md = QgsProviderRegistry::instance()->providerMetadata( mProviderKey ) )
106 {
107 mProviderIcon = md->icon();
108 }
109 return mProviderIcon;
110 }
111
112 default:
113 break;
114 }
115 return QVariant();
116 }
117
118 void setEntry( const QgsHistoryEntry &entry )
119 {
120 if ( !mConnectionNode )
121 {
122 mConnectionNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Connection: %1" ).arg( entry.entry.value( QStringLiteral( "connection" ) ).toString() ) );
123 addChild( mConnectionNode );
124 }
125 if ( entry.entry.contains( QStringLiteral( "rows" ) ) )
126 {
127 if ( !mRowsNode )
128 {
129 mRowsNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Row count: %1" ).arg( entry.entry.value( QStringLiteral( "rows" ) ).toString() ) );
130 addChild( mRowsNode );
131 }
132 }
133 if ( entry.entry.contains( QStringLiteral( "time" ) ) )
134 {
135 if ( !mTimeNode )
136 {
137 mTimeNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Execution time: %1 ms" ).arg( entry.entry.value( QStringLiteral( "time" ) ).toString() ) );
138 addChild( mTimeNode );
139 }
140 }
141 }
142
143 QWidget *createWidget( const QgsHistoryWidgetContext & ) override
144 {
145 QgsCodeEditorSQL *editor = new QgsCodeEditorSQL();
146 editor->setText( mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
147 editor->setReadOnly( true );
148 editor->setCaretLineVisible( false );
149 editor->setLineNumbersVisible( false );
150 editor->setFoldingVisible( false );
151 editor->setEdgeMode( QsciScintilla::EdgeNone );
152 editor->setWrapMode( QsciScintilla::WrapMode::WrapWord );
153 return editor;
154 }
155
156 bool doubleClicked( const QgsHistoryWidgetContext &context ) override
157 {
158 if ( QgsDatabaseQueryHistoryWidget *queryHistoryWidget = qobject_cast< QgsDatabaseQueryHistoryWidget * >( context.historyWidget() ) )
159 {
160 queryHistoryWidget->emitSqlTriggered( mEntry.entry.value( QStringLiteral( "connection" ) ).toString(), mEntry.entry.value( QStringLiteral( "provider" ) ).toString(), mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
161 }
162 return true;
163 }
164
165 void populateContextMenu( QMenu *menu, const QgsHistoryWidgetContext &context ) override
166 {
167 if ( QgsDatabaseQueryHistoryWidget *queryHistoryWidget = qobject_cast< QgsDatabaseQueryHistoryWidget * >( context.historyWidget() ) )
168 {
169 QAction *loadAction = new QAction(
170 QObject::tr( "Load SQL Command…" ), menu
171 );
172 QObject::connect( loadAction, &QAction::triggered, menu, [this, queryHistoryWidget] {
173 queryHistoryWidget->emitSqlTriggered( mEntry.entry.value( QStringLiteral( "connection" ) ).toString(), mEntry.entry.value( QStringLiteral( "provider" ) ).toString(), mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
174 } );
175 menu->addAction( loadAction );
176 }
177
178 QAction *copyAction = new QAction(
179 QObject::tr( "Copy SQL Command" ), menu
180 );
181 copyAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionEditCopy.svg" ) ) );
182 QObject::connect( copyAction, &QAction::triggered, menu, [this] {
183 QMimeData *m = new QMimeData();
184 m->setText( mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
185 QApplication::clipboard()->setMimeData( m );
186 } );
187 menu->addAction( copyAction );
188 }
189
190 private:
191 QString mProviderKey;
192 mutable QIcon mProviderIcon;
193 DatabaseQueryValueNode *mConnectionNode = nullptr;
194 DatabaseQueryValueNode *mRowsNode = nullptr;
195 DatabaseQueryValueNode *mTimeNode = nullptr;
196};
197
199
200
204
206{
207 return QStringLiteral( "dbquery" );
208}
209
211{
212 return new DatabaseQueryRootNode( entry, this );
213}
214
216{
217 if ( DatabaseQueryRootNode *dbNode = dynamic_cast<DatabaseQueryRootNode *>( node ) )
218 {
219 dbNode->setEntry( entry );
220 }
221}
222
223//
224// QgsDatabaseQueryHistoryWidget
225//
226
228 : QgsHistoryWidget( QStringLiteral( "dbquery" ), backends, registry, context, parent )
229{
230}
231
232void QgsDatabaseQueryHistoryWidget::emitSqlTriggered( const QString &connectionUri, const QString &provider, const QString &sql )
233{
234 emit sqlTriggered( connectionUri, provider, sql );
235}
QFlags< HistoryProviderBackend > HistoryProviderBackends
Definition qgis.h:3508
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
void setText(const QString &text) override
void setFoldingVisible(bool folding)
Set whether the folding controls are visible in the editor.
void setLineNumbersVisible(bool visible)
Sets whether line numbers should be visible in the editor.
void updateNodeForEntry(QgsHistoryEntryNode *node, const QgsHistoryEntry &entry, const QgsHistoryWidgetContext &context) override
Updates an existing history node for the given entry.
QString id() const override
Returns the provider's unique id, which is used to associate existing history entries with the provid...
QgsHistoryEntryNode * createNodeForEntry(const QgsHistoryEntry &entry, const QgsHistoryWidgetContext &context) override
Creates a new history node for the given entry.
QgsDatabaseQueryHistoryWidget(Qgis::HistoryProviderBackends backends=Qgis::HistoryProviderBackend::LocalProfile, QgsHistoryProviderRegistry *registry=nullptr, const QgsHistoryWidgetContext &context=QgsHistoryWidgetContext(), QWidget *parent=nullptr)
Constructor for QgsDatabaseQueryHistoryWidget, with the specified parent widget.
void sqlTriggered(const QString &connectionUri, const QString &provider, const QString &sql)
Emitted when the user has triggered a previously executed SQL statement in the widget.
void emitSqlTriggered(const QString &connectionUri, const QString &provider, const QString &sql)
Causes the widget to emit the sqlTriggered() signal.
Base class for history entry "group" nodes, which contain children of their own.
Base class for nodes representing a QgsHistoryEntry.
Encapsulates a history entry.
QVariantMap entry
Entry details.
A registry for objects which track user history (i.e.
Contains settings which reflect the context in which a history widget is shown, e....
QgsHistoryWidget * historyWidget() const
Returns the parent history widget.
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.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.