QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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#include "qgscodeeditorsql.h"
19#include "qgshistoryentry.h"
20#include "qgsprovidermetadata.h"
21#include "qgsproviderregistry.h"
22#include "qgsapplication.h"
23
24#include <QIcon>
25#include <QAction>
26#include <QMenu>
27#include <QMimeData>
28#include <QClipboard>
29
31
32class DatabaseQueryHistoryNode : public QgsHistoryEntryGroup
33{
34 public:
35
36 DatabaseQueryHistoryNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider )
38 , mEntry( entry )
39 , mProvider( provider )
40 {
41 }
42
43 protected:
44
45 QgsHistoryEntry mEntry;
46 QgsDatabaseQueryHistoryProvider *mProvider = nullptr;
47
48};
49
50class DatabaseQueryValueNode : public DatabaseQueryHistoryNode
51{
52 public:
53
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
79 QString mValue;
80
81};
82
83class DatabaseQueryRootNode : public DatabaseQueryHistoryNode
84{
85 public:
86
87 DatabaseQueryRootNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider )
88 : DatabaseQueryHistoryNode( entry, provider )
89 {
90 setEntry( entry );
91
92 mProviderKey = mEntry.entry.value( QStringLiteral( "provider" ) ).toString();
93 }
94
95 QVariant data( int role = Qt::DisplayRole ) const override
96 {
97 switch ( role )
98 {
99 case Qt::DisplayRole:
100 case Qt::ToolTipRole:
101 return mEntry.entry.value( QStringLiteral( "query" ) );
102
103 case Qt::DecorationRole:
104 {
105 if ( !mProviderIcon.isNull() )
106 return mProviderIcon;
107
108 if ( QgsProviderMetadata *md = QgsProviderRegistry::instance()->providerMetadata( mProviderKey ) )
109 {
110 mProviderIcon = md->icon();
111 }
112 return mProviderIcon;
113 }
114
115 default:
116 break;
117 }
118 return QVariant();
119 }
120
121 void setEntry( const QgsHistoryEntry &entry )
122 {
123 if ( !mConnectionNode )
124 {
125 mConnectionNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Connection: %1" ).arg( entry.entry.value( QStringLiteral( "connection" ) ).toString() ) );
126 addChild( mConnectionNode );
127 }
128 if ( entry.entry.contains( QStringLiteral( "rows" ) ) )
129 {
130 if ( !mRowsNode )
131 {
132 mRowsNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Row count: %1" ).arg( entry.entry.value( QStringLiteral( "rows" ) ).toString() ) );
133 addChild( mRowsNode );
134 }
135 }
136 if ( entry.entry.contains( QStringLiteral( "time" ) ) )
137 {
138 if ( !mTimeNode )
139 {
140 mTimeNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Execution time: %1 ms" ).arg( entry.entry.value( QStringLiteral( "time" ) ).toString() ) );
141 addChild( mTimeNode );
142 }
143 }
144 }
145
146 QWidget *createWidget( const QgsHistoryWidgetContext & ) override
147 {
148 QgsCodeEditorSQL *editor = new QgsCodeEditorSQL();
149 editor->setText( mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
150 editor->setReadOnly( true );
151 editor->setCaretLineVisible( false );
152 editor->setLineNumbersVisible( false );
153 editor->setFoldingVisible( false );
154 editor->setEdgeMode( QsciScintilla::EdgeNone );
155 editor->setWrapMode( QsciScintilla::WrapMode::WrapWord );
156 return editor;
157 }
158
159 bool doubleClicked( const QgsHistoryWidgetContext & ) override
160 {
161 mProvider->emitOpenSqlDialog( mEntry.entry.value( QStringLiteral( "connection" ) ).toString(),
162 mEntry.entry.value( QStringLiteral( "provider" ) ).toString(),
163 mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
164 return true;
165 }
166
167 void populateContextMenu( QMenu *menu, const QgsHistoryWidgetContext & ) override
168 {
169 QAction *executeAction = new QAction(
170 QObject::tr( "Execute SQL Command…" ), menu );
171 QObject::connect( executeAction, &QAction::triggered, menu, [ = ]
172 {
173 mProvider->emitOpenSqlDialog( mEntry.entry.value( QStringLiteral( "connection" ) ).toString(),
174 mEntry.entry.value( QStringLiteral( "provider" ) ).toString(),
175 mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
176 } );
177 menu->addAction( executeAction );
178
179 QAction *copyAction = new QAction(
180 QObject::tr( "Copy SQL Command" ), menu );
181 copyAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionEditCopy.svg" ) ) );
182 QObject::connect( copyAction, &QAction::triggered, menu, [ = ]
183 {
184 QMimeData *m = new QMimeData();
185 m->setText( mEntry.entry.value( QStringLiteral( "query" ) ).toString() );
186 QApplication::clipboard()->setMimeData( m );
187 } );
188 menu->addAction( copyAction );
189 }
190
191 private:
192
193 QString mProviderKey;
194 mutable QIcon mProviderIcon;
195 DatabaseQueryValueNode *mConnectionNode = nullptr;
196 DatabaseQueryValueNode *mRowsNode = nullptr;
197 DatabaseQueryValueNode *mTimeNode = nullptr;
198
199};
200
202
203
205{
206}
207
209{
210 return QStringLiteral( "dbquery" );
211}
212
214{
215 return new DatabaseQueryRootNode( entry, this );
216}
217
219{
220 if ( DatabaseQueryRootNode *dbNode = dynamic_cast< DatabaseQueryRootNode * >( node ) )
221 {
222 dbNode->setEntry( entry );
223 }
224}
225
226void QgsDatabaseQueryHistoryProvider::emitOpenSqlDialog( const QString &connectionUri, const QString &provider, const QString &sql )
227{
228 emit openSqlDialog( connectionUri, provider, sql );
229}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A SQL editor based on QScintilla2.
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.
History provider for operations database queries.
void emitOpenSqlDialog(const QString &connectionUri, const QString &provider, const QString &sql)
Causes the provider to emit the openSqlDialog() signal.
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...
void openSqlDialog(const QString &connectionUri, const QString &provider, const QString &sql)
Emitted when the provider wants to trigger a SQL execution dialog.
QgsHistoryEntryNode * createNodeForEntry(const QgsHistoryEntry &entry, const QgsHistoryWidgetContext &context) override
Creates a new history node for the given entry.
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.
Contains settings which reflect the context in which a history widget is shown, e....
Holds data provider key, description, and associated shared library file or function pointer informat...
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.