QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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#include <QString>
32
33#include "moc_qgsdbqueryhistoryprovider.cpp"
34
35using namespace Qt::StringLiterals;
36
38
39class DatabaseQueryHistoryNode : public QgsHistoryEntryGroup
40{
41 public:
42 DatabaseQueryHistoryNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider )
43 : QgsHistoryEntryGroup()
44 , mEntry( entry )
45 , mProvider( provider )
46 {}
47
48 protected:
49 QgsHistoryEntry mEntry;
50 QgsDatabaseQueryHistoryProvider *mProvider = nullptr;
51};
52
53class DatabaseQueryValueNode : public DatabaseQueryHistoryNode
54{
55 public:
56 DatabaseQueryValueNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider, const QString &value )
57 : DatabaseQueryHistoryNode( entry, provider )
58 , mValue( value )
59 {}
60
61 QVariant data( int role = Qt::DisplayRole ) const override
62 {
63 switch ( role )
64 {
65 case Qt::DisplayRole:
66 case Qt::ToolTipRole:
67 return mValue;
68
69 default:
70 return QVariant();
71 }
72 }
73
74 QString html( const QgsHistoryWidgetContext & ) const override { return mValue; }
75
76 private:
77 QString mValue;
78};
79
80class DatabaseQueryRootNode : public DatabaseQueryHistoryNode
81{
82 public:
83 DatabaseQueryRootNode( const QgsHistoryEntry &entry, QgsDatabaseQueryHistoryProvider *provider )
84 : DatabaseQueryHistoryNode( entry, provider )
85 {
86 setEntry( entry );
87
88 mProviderKey = mEntry.entry.value( u"provider"_s ).toString();
89 }
90
91 QVariant data( int role = Qt::DisplayRole ) const override
92 {
93 switch ( role )
94 {
95 case Qt::DisplayRole:
96 case Qt::ToolTipRole:
97 return mEntry.entry.value( u"query"_s );
98
99 case Qt::DecorationRole:
100 {
101 if ( !mProviderIcon.isNull() )
102 return mProviderIcon;
103
104 if ( QgsProviderMetadata *md = QgsProviderRegistry::instance()->providerMetadata( mProviderKey ) )
105 {
106 mProviderIcon = md->icon();
107 }
108 return mProviderIcon;
109 }
110
111 default:
112 break;
113 }
114 return QVariant();
115 }
116
117 void setEntry( const QgsHistoryEntry &entry )
118 {
119 if ( !mConnectionNode )
120 {
121 mConnectionNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Connection: %1" ).arg( entry.entry.value( u"connection"_s ).toString() ) );
122 addChild( mConnectionNode );
123 }
124 if ( entry.entry.contains( u"rows"_s ) )
125 {
126 if ( !mRowsNode )
127 {
128 mRowsNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Row count: %1" ).arg( entry.entry.value( u"rows"_s ).toString() ) );
129 addChild( mRowsNode );
130 }
131 }
132 if ( entry.entry.contains( u"time"_s ) )
133 {
134 if ( !mTimeNode )
135 {
136 mTimeNode = new DatabaseQueryValueNode( mEntry, mProvider, QObject::tr( "Execution time: %1 ms" ).arg( entry.entry.value( u"time"_s ).toString() ) );
137 addChild( mTimeNode );
138 }
139 }
140 }
141
142 QWidget *createWidget( const QgsHistoryWidgetContext & ) override
143 {
144 QgsCodeEditorSQL *editor = new QgsCodeEditorSQL();
145 editor->setText( mEntry.entry.value( u"query"_s ).toString() );
146 editor->setReadOnly( true );
147 editor->setCaretLineVisible( false );
148 editor->setLineNumbersVisible( false );
149 editor->setFoldingVisible( false );
150 editor->setEdgeMode( QsciScintilla::EdgeNone );
151 editor->setWrapMode( QsciScintilla::WrapMode::WrapWord );
152 return editor;
153 }
154
155 bool doubleClicked( const QgsHistoryWidgetContext &context ) override
156 {
157 if ( QgsDatabaseQueryHistoryWidget *queryHistoryWidget = qobject_cast< QgsDatabaseQueryHistoryWidget * >( context.historyWidget() ) )
158 {
159 queryHistoryWidget->emitSqlTriggered( mEntry.entry.value( u"connection"_s ).toString(), mEntry.entry.value( u"provider"_s ).toString(), mEntry.entry.value( u"query"_s ).toString() );
160 }
161 return true;
162 }
163
164 void populateContextMenu( QMenu *menu, const QgsHistoryWidgetContext &context ) override
165 {
166 if ( QgsDatabaseQueryHistoryWidget *queryHistoryWidget = qobject_cast< QgsDatabaseQueryHistoryWidget * >( context.historyWidget() ) )
167 {
168 QAction *loadAction = new QAction( QObject::tr( "Load SQL Command…" ), menu );
169 QObject::connect( loadAction, &QAction::triggered, menu, [this, queryHistoryWidget] {
170 queryHistoryWidget->emitSqlTriggered( mEntry.entry.value( u"connection"_s ).toString(), mEntry.entry.value( u"provider"_s ).toString(), mEntry.entry.value( u"query"_s ).toString() );
171 } );
172 menu->addAction( loadAction );
173 }
174
175 QAction *copyAction = new QAction( QObject::tr( "Copy SQL Command" ), menu );
176 copyAction->setIcon( QgsApplication::getThemeIcon( u"mActionEditCopy.svg"_s ) );
177 QObject::connect( copyAction, &QAction::triggered, menu, [this] {
178 QMimeData *m = new QMimeData();
179 m->setText( mEntry.entry.value( u"query"_s ).toString() );
180 QApplication::clipboard()->setMimeData( m );
181 } );
182 menu->addAction( copyAction );
183 }
184
185 private:
186 QString mProviderKey;
187 mutable QIcon mProviderIcon;
188 DatabaseQueryValueNode *mConnectionNode = nullptr;
189 DatabaseQueryValueNode *mRowsNode = nullptr;
190 DatabaseQueryValueNode *mTimeNode = nullptr;
191};
192
194
195
198
200{
201 return u"dbquery"_s;
202}
203
205{
206 return new DatabaseQueryRootNode( entry, this );
207}
208
210{
211 if ( DatabaseQueryRootNode *dbNode = dynamic_cast<DatabaseQueryRootNode *>( node ) )
212 {
213 dbNode->setEntry( entry );
214 }
215}
216
217//
218// QgsDatabaseQueryHistoryWidget
219//
220
222 : QgsHistoryWidget( u"dbquery"_s, backends, registry, context, parent )
223{}
224
225void QgsDatabaseQueryHistoryWidget::emitSqlTriggered( const QString &connectionUri, const QString &provider, const QString &sql )
226{
227 emit sqlTriggered( connectionUri, provider, sql );
228}
QFlags< HistoryProviderBackend > HistoryProviderBackends
Definition qgis.h:3622
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.