20 #include <QDesktopServices>
23 #include <QPushButton>
29 , mCopyValueAction( new QAction( tr(
"Copy value" ), this ) )
30 , mCopyKeyAction( new QAction( tr(
"Copy key" ), this ) )
36 mCodeEditorJson->setReadOnly(
true );
37 mCodeEditorJson->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
38 mCodeEditorJson->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
39 mCodeEditorJson->indicatorDefine( QsciScintilla::PlainIndicator, SCINTILLA_UNDERLINE_INDICATOR_INDEX );
40 mCodeEditorJson->SendScintilla( QsciScintillaBase::SCI_SETINDICATORCURRENT, SCINTILLA_UNDERLINE_INDICATOR_INDEX );
41 mCodeEditorJson->SendScintilla( QsciScintillaBase::SCI_SETMOUSEDWELLTIME, 400 );
45 mTreeWidget->setContextMenuPolicy( Qt::ActionsContextMenu );
46 mTreeWidget->addAction( mCopyValueAction );
47 mTreeWidget->addAction( mCopyKeyAction );
49 connect( mTextToolButton, &QToolButton::clicked,
this, &QgsJsonEditWidget::textToolButtonClicked );
50 connect( mTreeToolButton, &QToolButton::clicked,
this, &QgsJsonEditWidget::treeToolButtonClicked );
52 connect( mCopyValueAction, &QAction::triggered,
this, &QgsJsonEditWidget::copyValueActionTriggered );
53 connect( mCopyKeyAction, &QAction::triggered,
this, &QgsJsonEditWidget::copyKeyActionTriggered );
55 connect( mCodeEditorJson, &QgsCodeEditorJson::textChanged,
this, &QgsJsonEditWidget::codeEditorJsonTextChanged );
58 connect( mCodeEditorJson, &QsciScintilla::indicatorClicked,
this, &QgsJsonEditWidget::codeEditorJsonIndicatorClicked );
59 connect( mCodeEditorJson, &QsciScintillaBase::SCN_DWELLSTART,
this, &QgsJsonEditWidget::codeEditorJsonDwellStart );
60 connect( mCodeEditorJson, &QsciScintillaBase::SCN_DWELLEND,
this, &QgsJsonEditWidget::codeEditorJsonDwellEnd );
66 mClickableLinkList.clear();
68 const QJsonDocument jsonDocument = QJsonDocument::fromJson( mJsonText.toUtf8() );
70 mCodeEditorJson->blockSignals(
true );
71 if ( jsonDocument.isNull() )
73 mCodeEditorJson->setText( mJsonText );
77 switch ( mFormatJsonMode )
80 mCodeEditorJson->setText( jsonDocument.toJson( QJsonDocument::Indented ) );
83 mCodeEditorJson->setText( jsonDocument.toJson( QJsonDocument::Compact ) );
86 mCodeEditorJson->setText( mJsonText );
90 mCodeEditorJson->blockSignals(
false );
92 refreshTreeView( jsonDocument );
106 mStackedWidget->setCurrentWidget( mStackedWidgetPageText );
107 mTextToolButton->setChecked(
true );
108 mTreeToolButton->setChecked(
false );
113 mStackedWidget->setCurrentWidget( mStackedWidgetPageTree );
114 mTreeToolButton->setChecked(
true );
115 mTextToolButton->setChecked(
false );
123 mFormatJsonMode = formatJson;
128 mControlsWidget->setVisible( visible );
131 void QgsJsonEditWidget::textToolButtonClicked(
bool checked )
139 void QgsJsonEditWidget::treeToolButtonClicked(
bool checked )
147 void QgsJsonEditWidget::copyValueActionTriggered()
149 if ( !mTreeWidget->currentItem() )
152 const QJsonValue jsonValue = QJsonValue::fromVariant( mTreeWidget->currentItem()->data(
static_cast<int>( TreeWidgetColumn::Value ), Qt::UserRole ) );
154 switch ( jsonValue.type() )
156 case QJsonValue::Null:
157 case QJsonValue::Bool:
158 case QJsonValue::Double:
159 case QJsonValue::Undefined:
160 QApplication::clipboard()->setText( mTreeWidget->currentItem()->text(
static_cast<int>( TreeWidgetColumn::Value ) ) );
162 case QJsonValue::String:
163 QApplication::clipboard()->setText( jsonValue.toString() );
165 case QJsonValue::Array:
167 const QJsonDocument jsonDocument( jsonValue.toArray() );
168 QApplication::clipboard()->setText( jsonDocument.toJson() );
171 case QJsonValue::Object:
173 const QJsonDocument jsonDocument( jsonValue.toObject() );
174 QApplication::clipboard()->setText( jsonDocument.toJson() );
180 void QgsJsonEditWidget::copyKeyActionTriggered()
182 if ( !mTreeWidget->currentItem() )
185 QApplication::clipboard()->setText( mTreeWidget->currentItem()->text(
static_cast<int>( TreeWidgetColumn::Key ) ) );
188 void QgsJsonEditWidget::codeEditorJsonTextChanged()
190 mJsonText = mCodeEditorJson->text();
191 const QJsonDocument jsonDocument = QJsonDocument::fromJson( mJsonText.toUtf8() );
192 refreshTreeView( jsonDocument );
195 void QgsJsonEditWidget::codeEditorJsonIndicatorClicked(
int line,
int index, Qt::KeyboardModifiers state )
197 if ( !state.testFlag( Qt::ControlModifier ) )
200 int position = mCodeEditorJson->positionFromLineIndex( line, index );
201 int clickableLinkListIndex = mCodeEditorJson->SendScintilla( QsciScintillaBase::SCI_INDICATORVALUEAT,
202 SCINTILLA_UNDERLINE_INDICATOR_INDEX,
204 if ( clickableLinkListIndex <= 0 )
207 QDesktopServices::openUrl( mClickableLinkList.at( clickableLinkListIndex - 1 ) );
210 void QgsJsonEditWidget::codeEditorJsonDwellStart(
int position,
int x,
int y )
215 int clickableLinkListIndex = mCodeEditorJson->SendScintilla( QsciScintillaBase::SCI_INDICATORVALUEAT,
216 SCINTILLA_UNDERLINE_INDICATOR_INDEX,
218 if ( clickableLinkListIndex <= 0 )
221 QToolTip::showText( QCursor::pos(),
222 tr(
"%1\nCTRL + click to follow link" ).arg( mClickableLinkList.at( clickableLinkListIndex - 1 ) ) );
225 void QgsJsonEditWidget::codeEditorJsonDwellEnd(
int position,
int x,
int y )
230 QToolTip::hideText();
233 void QgsJsonEditWidget::refreshTreeView(
const QJsonDocument &jsonDocument )
235 mTreeWidget->clear();
237 if ( jsonDocument.isNull() )
240 mTextToolButton->setDisabled(
true );
241 mTreeToolButton->setDisabled(
true );
242 mTreeToolButton->setToolTip( tr(
"Invalid JSON, tree view not available" ) );
247 mTextToolButton->setEnabled(
true );
248 mTreeToolButton->setEnabled(
true );
249 mTreeToolButton->setToolTip( tr(
"Tree view" ) );
252 if ( jsonDocument.isObject() )
254 const QStringList keys = jsonDocument.object().keys();
255 for (
const QString &key : keys )
257 const QJsonValue jsonValue = jsonDocument.object().value( key );
258 QTreeWidgetItem *treeWidgetItem =
new QTreeWidgetItem( mTreeWidget, QStringList() << key );
259 refreshTreeViewItem( treeWidgetItem, jsonValue );
260 mTreeWidget->addTopLevelItem( treeWidgetItem );
261 mTreeWidget->expandItem( treeWidgetItem );
264 else if ( jsonDocument.isArray() )
266 for (
int index = 0; index < jsonDocument.array().size(); index++ )
268 QTreeWidgetItem *treeWidgetItem =
new QTreeWidgetItem( mTreeWidget, QStringList() << QString::number( index ) );
269 refreshTreeViewItem( treeWidgetItem, jsonDocument.array().at( index ) );
270 mTreeWidget->addTopLevelItem( treeWidgetItem );
271 mTreeWidget->expandItem( treeWidgetItem );
275 mTreeWidget->resizeColumnToContents(
static_cast<int>( TreeWidgetColumn::Key ) );
278 void QgsJsonEditWidget::refreshTreeViewItem( QTreeWidgetItem *treeWidgetItem,
const QJsonValue &jsonValue )
280 treeWidgetItem->setData(
static_cast<int>( TreeWidgetColumn::Value ), Qt::UserRole, jsonValue.toVariant() );
282 switch ( jsonValue.type() )
284 case QJsonValue::Null:
285 refreshTreeViewItemValue( treeWidgetItem,
286 QStringLiteral(
"null" ),
289 case QJsonValue::Bool:
290 refreshTreeViewItemValue( treeWidgetItem,
291 jsonValue.toBool() ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ),
294 case QJsonValue::Double:
295 refreshTreeViewItemValue( treeWidgetItem,
296 QString::number( jsonValue.toDouble() ),
299 case QJsonValue::String:
301 const QString jsonValueString = jsonValue.toString();
302 if ( QUrl( jsonValueString ).scheme().isEmpty() )
304 refreshTreeViewItemValue( treeWidgetItem,
310 QLabel *label =
new QLabel( QString(
"<a href='%1'>%1</a>" ).arg( jsonValueString ) );
311 label->setOpenExternalLinks(
true );
312 mTreeWidget->setItemWidget( treeWidgetItem,
static_cast<int>( TreeWidgetColumn::Value ), label );
314 mClickableLinkList.append( jsonValueString );
315 mCodeEditorJson->SendScintilla( QsciScintillaBase::SCI_SETINDICATORVALUE, mClickableLinkList.size() );
316 mCodeEditorJson->SendScintilla( QsciScintillaBase::SCI_INDICATORFILLRANGE,
317 mCodeEditorJson->text().indexOf( jsonValueString ),
318 jsonValueString.size() );
322 case QJsonValue::Array:
324 const QJsonArray jsonArray = jsonValue.toArray();
325 for (
int index = 0; index < jsonArray.size(); index++ )
327 QTreeWidgetItem *treeWidgetItemChild =
new QTreeWidgetItem( treeWidgetItem, QStringList() << QString::number( index ) );
328 refreshTreeViewItem( treeWidgetItemChild, jsonArray.at( index ) );
329 treeWidgetItem->addChild( treeWidgetItemChild );
330 treeWidgetItem->setExpanded(
true );
334 case QJsonValue::Object:
336 const QJsonObject jsonObject = jsonValue.toObject();
337 const QStringList keys = jsonObject.keys();
338 for (
const QString &key : keys )
340 QTreeWidgetItem *treeWidgetItemChild =
new QTreeWidgetItem( treeWidgetItem, QStringList() << key );
341 refreshTreeViewItem( treeWidgetItemChild, jsonObject.value( key ) );
342 treeWidgetItem->addChild( treeWidgetItemChild );
343 treeWidgetItem->setExpanded(
true );
347 case QJsonValue::Undefined:
348 refreshTreeViewItemValue( treeWidgetItem,
349 QStringLiteral(
"Undefined value" ),
355 void QgsJsonEditWidget::refreshTreeViewItemValue( QTreeWidgetItem *treeWidgetItem,
const QString &jsonValueString,
const QColor &textColor )
357 QLabel *label =
new QLabel( jsonValueString );
358 if ( textColor.isValid() )
359 label->setStyleSheet( QStringLiteral(
"color: %1;" ).arg( textColor.name() ) );
360 mTreeWidget->setItemWidget( treeWidgetItem,
static_cast<int>( TreeWidgetColumn::Value ), label );
@ DoubleQuote
Double quote color.
static QFont getMonospaceFont()
Returns the monospaced font to use for code editors.
static QColor color(QgsCodeEditorColorScheme::ColorRole role)
Returns the color to use in the editor for the specified role.