Code editor

This commit is contained in:
Nathan Woodrow 2014-07-12 20:50:08 +10:00
parent 877f07ab5d
commit a284c4e0d1
14 changed files with 607 additions and 24 deletions

View File

@ -5,6 +5,7 @@
%Import QtCore/QtCoremod.sip %Import QtCore/QtCoremod.sip
%Import QtGui/QtGuimod.sip %Import QtGui/QtGuimod.sip
%Import QtXml/QtXmlmod.sip %Import QtXml/QtXmlmod.sip
%Import Qsci/qscimod4.sip
%Import core/core.sip %Import core/core.sip
@ -19,6 +20,9 @@
%Include qgsattributeforminterface.sip %Include qgsattributeforminterface.sip
%Include qgsbusyindicatordialog.sip %Include qgsbusyindicatordialog.sip
%Include qgscollapsiblegroupbox.sip %Include qgscollapsiblegroupbox.sip
%Include qgscodeeditor.sip
%Include qgscodeeditorpython.sip
%Include qgscodeeditorsql.sip
%Include qgscolorbutton.sip %Include qgscolorbutton.sip
%Include qgscolordialog.sip %Include qgscolordialog.sip
%Include qgscomposerview.sip %Include qgscomposerview.sip

View File

@ -0,0 +1,14 @@
class QgsCodeEditor: QsciScintilla
{
%TypeHeaderCode
#include <qgscodeeditor.h>
%End
public:
QgsCodeEditor( QWidget *parent /TransferThis/ = 0, QString title = "" , bool folding = false, bool margin = false );
~QgsCodeEditor();
bool enableMargin( bool margin );
void enableFolding( bool folding);
};

View File

@ -0,0 +1,17 @@
class QgsCodeEditorPython: QgsCodeEditor
{
%TypeHeaderCode
#include <qgscodeeditorpython.h>
%End
public:
QgsCodeEditorPython( QWidget *parent /TransferThis/ = 0, const QList<QString> &filenames = QList<QString>() );
~QgsCodeEditorPython();
void setTitle( QString );
void loadAPIs(const QList<QString> &filenames );
void loadScript( const QString &script );
};

View File

@ -0,0 +1,17 @@
class QgsCodeEditorSQL: QgsCodeEditor
{
%TypeHeaderCode
#include <qgscodeeditorsql.h>
%End
public:
QgsCodeEditorSQL( QWidget *parent /TransferThis/ = 0 );
~QgsCodeEditorSQL();
void setTitle( QString );
void showMargin( bool withMargin );
void showFolding( bool withFolding );
};

View File

@ -463,7 +463,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
grpPythonMacros->setChecked( !pythonMacros.isEmpty() ); grpPythonMacros->setChecked( !pythonMacros.isEmpty() );
if ( !pythonMacros.isEmpty() ) if ( !pythonMacros.isEmpty() )
{ {
ptePythonMacros->setPlainText( pythonMacros ); ptePythonMacros->setText( pythonMacros );
} }
else else
{ {
@ -867,7 +867,7 @@ void QgsProjectProperties::apply()
QgsProject::instance()->writeEntry( "DefaultStyles", "/RandomColors", cbxStyleRandomColors->isChecked() ); QgsProject::instance()->writeEntry( "DefaultStyles", "/RandomColors", cbxStyleRandomColors->isChecked() );
// store project macros // store project macros
QString pythonMacros = ptePythonMacros->toPlainText(); QString pythonMacros = ptePythonMacros->text();
if ( !grpPythonMacros->isChecked() || pythonMacros.isEmpty() ) if ( !grpPythonMacros->isChecked() || pythonMacros.isEmpty() )
{ {
pythonMacros = QString::null; pythonMacros = QString::null;
@ -1467,7 +1467,7 @@ void QgsProjectProperties::editSymbol( QComboBox* cbo )
void QgsProjectProperties::resetPythonMacros() void QgsProjectProperties::resetPythonMacros()
{ {
grpPythonMacros->setChecked( false ); grpPythonMacros->setChecked( false );
ptePythonMacros->setPlainText( "def openProject():\n pass\n\n" \ ptePythonMacros->setText( "def openProject():\n pass\n\n" \
"def saveProject():\n pass\n\n" \ "def saveProject():\n pass\n\n" \
"def closeProject():\n pass\n" ); "def closeProject():\n pass\n" );
} }

View File

@ -725,6 +725,7 @@ TARGET_LINK_LIBRARIES(qgis_core
${QT_QTNETWORK_LIBRARY} ${QT_QTNETWORK_LIBRARY}
${QT_QTSVG_LIBRARY} ${QT_QTSVG_LIBRARY}
${QT_QTWEBKIT_LIBRARY} ${QT_QTWEBKIT_LIBRARY}
${QSCINTILLA_LIBRARY}
${PROJ_LIBRARY} ${PROJ_LIBRARY}
${GEOS_LIBRARY} ${GEOS_LIBRARY}

View File

@ -126,6 +126,9 @@ qgscharacterselectdialog.cpp
qgscollapsiblegroupbox.cpp qgscollapsiblegroupbox.cpp
qgscolorbutton.cpp qgscolorbutton.cpp
qgscolordialog.cpp qgscolordialog.cpp
qgscodeeditor.cpp
qgscodeeditorpython.cpp
qgscodeeditorsql.cpp
qgscomposerruler.cpp qgscomposerruler.cpp
qgscomposerview.cpp qgscomposerview.cpp
qgsprevieweffect.cpp qgsprevieweffect.cpp
@ -316,6 +319,9 @@ qgsblendmodecombobox.h
qgsbusyindicatordialog.h qgsbusyindicatordialog.h
qgscharacterselectdialog.h qgscharacterselectdialog.h
qgscollapsiblegroupbox.h qgscollapsiblegroupbox.h
qgscodeeditor.h
qgscodeeditorpython.h
qgscodeeditorsql.h
qgscolordialog.h qgscolordialog.h
qgsprevieweffect.h qgsprevieweffect.h
qgscomposerruler.h qgscomposerruler.h

133
src/gui/qgscodeeditor.cpp Normal file
View File

@ -0,0 +1,133 @@
/***************************************************************************
qgscodeeditor.cpp - description
--------------------------------------
Date : 06-Oct-2013
Copyright : (C) 2013 by Salvatore Larosa
Email : lrssvtml (at) gmail (dot) com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgscodeeditor.h"
#include <QSettings>
#include <QWidget>
#include <QFont>
#include <QDebug>
QgsCodeEditor::QgsCodeEditor( QWidget *parent, QString title, bool folding, bool margin )
: QsciScintilla( parent ),
mWidgetTitle( title ),
mFolding( folding ),
mMargin( margin )
{
if ( !parent && mWidgetTitle.isEmpty() )
{
setWindowTitle( "QScintilla2 Text Editor" );
setMinimumSize( 800, 300 );
}
else
{
setWindowTitle( mWidgetTitle );
}
setSciWidget();
}
QgsCodeEditor::~QgsCodeEditor()
{
}
void QgsCodeEditor::setSciWidget()
{
setUtf8( true );
setCaretLineVisible( true );
setCaretLineBackgroundColor( QColor( "#fcf3ed" ) );
setBraceMatching( QsciScintilla::SloppyBraceMatch );
setMatchedBraceBackgroundColor( QColor( "#b7f907" ) );
// whether margin will be shown
enableMargin( mMargin );
// whether margin will be shown
enableFolding( mFolding );
// indentation
setAutoIndent( true );
setIndentationWidth( 4 );
setTabIndents( true );
setBackspaceUnindents( true );
setTabWidth( 4 );
// autocomplete
setAutoCompletionThreshold( 2 );
setAutoCompletionSource( QsciScintilla::AcsAPIs );
}
bool QgsCodeEditor::enableMargin( bool margin )
{
if ( margin )
{
QFont marginFont( "Courier", 10 );
setMarginLineNumbers( 1, true );
setMarginsFont( marginFont );
setMarginWidth( 1, "00000" );
setMarginsForegroundColor( QColor( "#3E3EE3" ) );
setMarginsBackgroundColor( QColor( "#f9f9f9" ) );
return true;
}
else
{
setMarginWidth( 0, 0 );
setMarginWidth( 1, 0 );
setMarginWidth( 2, 0 );
return false;
}
}
void QgsCodeEditor::enableFolding( bool folding )
{
if ( folding )
{
setFolding( QsciScintilla::PlainFoldStyle );
setFoldMarginColors( QColor( "#f4f4f4" ), QColor( "#f4f4f4" ) );
}
else
{
setFolding( QsciScintilla::NoFoldStyle );
}
}
// Settings for font and fontsize
bool QgsCodeEditor::isFixedPitch( const QFont& font )
{
const QFontInfo fi( font );
qDebug() << fi.family() << fi.fixedPitch();
return fi.fixedPitch();
}
QFont QgsCodeEditor::getMonospaceFont()
{
QFont font( "monospace" );
if ( isFixedPitch( font ) )
{
return font;
}
font.setStyleHint( QFont::Monospace );
if ( isFixedPitch( font ) )
{
return font;
}
font.setStyleHint( QFont::TypeWriter );
if ( isFixedPitch( font ) )
{
return font;
}
font.setFamily( "courier" );
if ( isFixedPitch( font ) )
{
return font;
}
return font;
}

73
src/gui/qgscodeeditor.h Normal file
View File

@ -0,0 +1,73 @@
/***************************************************************************
qgscodeeditor.h - description
--------------------------------------
Date : 06-Oct-2013
Copyright : (C) 2013 by Salvatore Larosa
Email : lrssvtml (at) gmail (dot) com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCODEEDITOR_H
#define QGSCODEEDITOR_H
#define QSCINTILLA_DLL
#include <QString>
// qscintilla includes
#include <Qsci/qsciapis.h>
class QWidget;
/** \ingroup gui
* A text editor based on QScintilla2.
* \note added in 2.1
*/
class GUI_EXPORT QgsCodeEditor : public QsciScintilla
{
Q_OBJECT
public:
/**
* Construct a new code editor.
*
* @param parent The parent QWidget
* @param title The title to show in the code editor dialog
* @param folding False: Enable margin for code editor
* @param margin False: Enable folding for code editor
* @note added in 2.1
*/
QgsCodeEditor( QWidget *parent = 0, QString title = "" , bool folding = false, bool margin = false );
~QgsCodeEditor();
/** Enable folding
* @param margin Set margin in the editor
*/
bool enableMargin( bool margin );
/** Enable margin
* @param folding Set folding in the editor
*/
void enableFolding( bool folding );
protected:
bool isFixedPitch( const QFont& font );
QFont getMonospaceFont();
private:
void setSciWidget();
QString mWidgetTitle;
bool mFolding;
bool mMargin;
};
#endif

View File

@ -0,0 +1,146 @@
/***************************************************************************
qgscodeeditorpython.cpp - description
--------------------------------------
Date : 06-Oct-2013
Copyright : (C) 2013 by Salvatore Larosa
Email : lrssvtml (at) gmail (dot) com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsapplication.h"
#include "qgscodeeditorpython.h"
#include "qgslogger.h"
#include <QWidget>
#include <QString>
#include <QFont>
#include <QFileInfo>
#include <QMessageBox>
#include <QTextStream>
#include <Qsci/qscilexerpython.h>
QgsCodeEditorPython::QgsCodeEditorPython( QWidget *parent, const QList<QString> &filenames )
: QgsCodeEditor( parent ),
mAPISFilesList( filenames )
{
if ( !parent )
{
setTitle( "Qscintilla2 Python Editor" );
}
setSciLexerPython();
}
QgsCodeEditorPython::~QgsCodeEditorPython()
{
}
void QgsCodeEditorPython::setSciLexerPython()
{
// current line
setCaretWidth( 2 );
setEdgeMode( QsciScintilla::EdgeLine );
setEdgeColumn( 80 );
setEdgeColor( QColor( "#FF0000" ) );
setWhitespaceVisibility( QsciScintilla::WsVisibleAfterIndent );
QFont font = getMonospaceFont();
font.setPointSize( 10 );
QsciLexerPython* pyLexer = new QsciLexerPython();
pyLexer->setDefaultFont( font );
pyLexer->setFont( font, 1 ); // comment
pyLexer->setFont( font, 3 ); // singlequotes
pyLexer->setFont( font, 4 ); // doublequotes
pyLexer->setFont( font, 6 ); // triplequotes
pyLexer->setColor( Qt::red, 1 ); // comment color
pyLexer->setColor( Qt::darkGreen, 5 ); // keyword color
pyLexer->setColor( Qt::darkBlue, 15 ); // decorator color
QsciAPIs* apis = new QsciAPIs( pyLexer );
// check if the file is a prepared apis file.
//QString mPapFileName = QFileInfo( mAPISFilesList[0] ).fileName();
//QString isPapFile = mPapFileName.right( 3 );
//QgsDebugMsg( QString( "file extension: %1" ).arg( isPapFile ) );
if ( mAPISFilesList.isEmpty() )
{
mPapFile = QgsApplication::pkgDataPath() + "/python/qsci_apis/pyqgis.pap";
apis->loadPrepared( mPapFile );
}
else if ( mAPISFilesList.length() == 1 && mAPISFilesList[0].right( 3 ) == "pap" )
{
if ( !QFileInfo( mAPISFilesList[0] ).exists() )
{
QgsDebugMsg( QString( "The apis file %1 not found" ).arg( mAPISFilesList[0] ) );
return;
}
mPapFile = mAPISFilesList[0];
apis->loadPrepared( mPapFile );
}
else
{
for ( int i = 0; i < mAPISFilesList.size(); i++ )
{
if ( !QFileInfo( mAPISFilesList[i] ).exists() )
{
QgsDebugMsg( QString( "The apis file %1 was not found" ).arg( mAPISFilesList[i] ) );
return;
}
else
{
apis->load( mAPISFilesList[i] );
}
}
apis->prepare();
pyLexer->setAPIs( apis );
}
setLexer( pyLexer );
enableMargin( true );
enableFolding( true );
}
void QgsCodeEditorPython::setTitle( QString title )
{
setWindowTitle( title );
}
void QgsCodeEditorPython::loadAPIs( const QList<QString> &filenames )
{
mAPISFilesList = filenames;
//QgsDebugMsg( QString( "The apis files: %1" ).arg( mAPISFilesList[0] ) );
setSciLexerPython();
}
void QgsCodeEditorPython::loadScript( const QString &script )
{
QgsDebugMsg( QString( "The script file: %1" ).arg( script ) );
QFile file( script );
if ( !file.open( QIODevice::ReadOnly ) )
{
QMessageBox::information( 0, "error", file.errorString() );
}
QTextStream in( &file );
//QString line = in.readAll();
//while ( !in.atEnd() )
//{
//QString line = in.readLine();
//QStringList fields = line.split( "," );
//QgsCodeEditor::insert( fields );
//}
setText( in.readAll() );
file.close();
setSciLexerPython();
}

View File

@ -0,0 +1,65 @@
/***************************************************************************
qgscodeeditorpython.h - description
--------------------------------------
Date : 06-Oct-2013
Copyright : (C) 2013 by Salvatore Larosa
Email : lrssvtml (at) gmail (dot) com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCODEEDITORPYTHON_H
#define QGSCODEEDITORPYTHON_H
#include "qgscodeeditor.h"
/** \ingroup gui
* A Python editor based on QScintilla2. Adds syntax highlghiting and
* code autocompletion.
* \note added in 2.1
*/
class GUI_EXPORT QgsCodeEditorPython : public QgsCodeEditor
{
Q_OBJECT
public:
/**
* Construct a new Python editor.
*
* @param parent The parent QWidget
* @param filenames The list of apis files to load for the python lexer
* @note added in 2.1
*/
QgsCodeEditorPython( QWidget *parent = 0 , const QList<QString> &filenames = QList<QString>() );
~QgsCodeEditorPython();
/** Set the widget title */
void setTitle( QString );
/** Load APIs from one or more files
* @param filenames The list of apis files to load for the python lexer
*/
void loadAPIs( QList<QString> const &filenames );
/** Load a script file
* @param script The script file to load
*/
void loadScript( const QString &script );
private:
//QgsCodeEditor *mSciWidget;
//QWidget *mWidget;
void setSciLexerPython();
QList<QString> mAPISFilesList;
QString mPapFile;
};
#endif

View File

@ -0,0 +1,61 @@
/***************************************************************************
qgscodeeditorsql.cpp - description
--------------------------------------
Date : 06-Oct-2013
Copyright : (C) 2013 by Salvatore Larosa
Email : lrssvtml (at) gmail (dot) com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsapplication.h"
#include "qgscodeeditorsql.h"
#include <QWidget>
#include <QString>
#include <QFont>
#include <Qsci/qscilexersql.h>
QgsCodeEditorSQL::QgsCodeEditorSQL( QWidget *parent ) : QgsCodeEditor( parent )
{
if ( !parent )
{
setTitle( "Qscintilla2 SQL Editor" );
}
enableMargin( false );
enableFolding( true );
setSciLexerSQL();
}
QgsCodeEditorSQL::~QgsCodeEditorSQL()
{
}
void QgsCodeEditorSQL::setSciLexerSQL()
{
QsciLexerSQL* sqlLexer = new QsciLexerSQL();
sqlLexer->setDefaultFont( QFont( "Sans", 10 ) );
setLexer( sqlLexer );
}
void QgsCodeEditorSQL::setTitle( QString title )
{
setWindowTitle( title );
}
void QgsCodeEditorSQL::showMargin( bool withMargin )
{
enableMargin( withMargin );
}
void QgsCodeEditorSQL::showFolding( bool withFolding )
{
enableFolding( withFolding );
}

View File

@ -0,0 +1,47 @@
/***************************************************************************
qgscodeeditorsql.h - description
--------------------------------------
Date : 06-Oct-2013
Copyright : (C) 2013 by Salvatore Larosa
Email : lrssvtml (at) gmail (dot) com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCODEEDITORSQL_H
#define QGSCODEEDITORSQL_H
#include "qgscodeeditor.h"
/** \ingroup gui
* A SQL editor based on QScintilla2. Adds syntax highlghiting and
* code autocompletion.
* \note added in 2.1
*/
class GUI_EXPORT QgsCodeEditorSQL : public QgsCodeEditor
{
Q_OBJECT
public:
QgsCodeEditorSQL( QWidget *parent = 0 );
~QgsCodeEditorSQL();
void setTitle( QString );
void showMargin( bool withMargin );
void showFolding( bool withFolding );
private:
//QgsCodeEditor *mSciWidget;
//QWidget *mWidget;
void setSciLexerSQL();
};
#endif

View File

@ -191,7 +191,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>5</number>
</property> </property>
<widget class="QWidget" name="mProjOpts_01"> <widget class="QWidget" name="mProjOpts_01">
<layout class="QVBoxLayout" name="verticalLayout_6"> <layout class="QVBoxLayout" name="verticalLayout_6">
@ -211,8 +211,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>683</width> <width>684</width>
<height>779</height> <height>783</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_8">
@ -798,8 +798,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>683</width> <width>238</width>
<height>779</height> <height>43</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_7">
@ -848,8 +848,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>683</width> <width>684</width>
<height>779</height> <height>783</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_10"> <layout class="QVBoxLayout" name="verticalLayout_10">
@ -920,8 +920,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>683</width> <width>684</width>
<height>779</height> <height>783</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_12"> <layout class="QVBoxLayout" name="verticalLayout_12">
@ -1289,7 +1289,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>667</width> <width>667</width>
<height>1570</height> <height>1391</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_13"> <layout class="QVBoxLayout" name="verticalLayout_13">
@ -2003,8 +2003,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>166</width> <width>684</width>
<height>114</height> <height>783</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_17"> <layout class="QVBoxLayout" name="verticalLayout_17">
@ -2027,14 +2027,7 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_16"> <layout class="QVBoxLayout" name="verticalLayout_16">
<item> <item>
<widget class="QPlainTextEdit" name="ptePythonMacros"> <widget class="QgsCodeEditorPython" name="ptePythonMacros" native="true"/>
<property name="documentTitle">
<string notr="true"/>
</property>
<property name="plainText">
<string/>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -2109,6 +2102,12 @@
<header>qgsprojectionselector.h</header> <header>qgsprojectionselector.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>QgsCodeEditorPython</class>
<extends>QWidget</extends>
<header>qgscodeeditorpython.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<tabstops> <tabstops>
<tabstop>buttonBox</tabstop> <tabstop>buttonBox</tabstop>
@ -2200,10 +2199,10 @@
<tabstop>mWCSUrlLineEdit</tabstop> <tabstop>mWCSUrlLineEdit</tabstop>
<tabstop>scrollArea_6</tabstop> <tabstop>scrollArea_6</tabstop>
<tabstop>grpPythonMacros</tabstop> <tabstop>grpPythonMacros</tabstop>
<tabstop>ptePythonMacros</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../../images/images.qrc"/> <include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>