Skip to content
Permalink
Browse files

More QgsSettings updates:

* revives WMS
* QgsSettings::clear() added
* section added to QgsSettings::contains()
* type parameter added to sip binding of QgsSettings.value()
* TODO: customization & evis
  • Loading branch information
jef-n committed Mar 4, 2017
1 parent 96c31a1 commit a10c890383dc636c6300ca91360e64e2db20b27c
Showing 371 changed files with 1,697 additions and 1,677 deletions.
@@ -22,7 +22,7 @@
from builtins import range
import os

from qgis.PyQt.QtCore import Qt, QTimer, QSettings, QCoreApplication, QSize, QByteArray, QFileInfo, QUrl, QDir
from qgis.PyQt.QtCore import Qt, QTimer, QCoreApplication, QSize, QByteArray, QFileInfo, QUrl, QDir
from qgis.PyQt.QtWidgets import QDockWidget, QToolBar, QToolButton, QWidget, QSplitter, QTreeWidget, QAction, QFileDialog, QCheckBox, QSizePolicy, QMenu, QGridLayout, QApplication, QShortcut
from qgis.PyQt.QtGui import QDesktopServices, QKeySequence
from qgis.PyQt.QtWidgets import QVBoxLayout
@@ -31,7 +31,7 @@
from .console_output import ShellOutputScintilla
from .console_editor import EditorTabWidget
from .console_settings import optionsDialog
from qgis.core import QgsApplication, QgsContextHelp
from qgis.core import QgsApplication, QgsContextHelp, QgsSettings
from qgis.gui import QgsFilterLineEdit
from functools import partial

@@ -55,8 +55,9 @@ def show_console():
# set focus to the console so the user can start typing
if _console.isVisible():
_console.activate()
## Shows help on first launch of the console
settings = QSettings()

# Shows help on first launch of the console
settings = QgsSettings()
if settings.value('pythonConsole/contextHelpOnFirstLaunch', True, type=bool):
QgsContextHelp.run("PythonConsole")
settings.setValue('pythonConsole/contextHelpOnFirstLaunch', False)
@@ -106,7 +107,7 @@ def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))

self.settings = QSettings()
self.settings = QgsSettings()

self.shell = ShellScintilla(self)
self.setFocusProxy(self.shell)
@@ -21,11 +21,11 @@
from __future__ import print_function
from builtins import str
from builtins import range
from qgis.PyQt.QtCore import Qt, QObject, QEvent, QSettings, QCoreApplication, QFileInfo, QSize
from qgis.PyQt.QtCore import Qt, QObject, QEvent, QCoreApplication, QFileInfo, QSize
from qgis.PyQt.QtGui import QFont, QFontMetrics, QColor, QKeySequence, QCursor
from qgis.PyQt.QtWidgets import QShortcut, QMenu, QApplication, QWidget, QGridLayout, QSpacerItem, QSizePolicy, QFileDialog, QTabWidget, QTreeWidgetItem, QFrame, QLabel, QToolButton, QMessageBox
from qgis.PyQt.Qsci import QsciScintilla, QsciLexerPython, QsciAPIs, QsciStyle
from qgis.core import QgsApplication
from qgis.core import QgsApplication, QgsSettings
from qgis.gui import QgsMessageBar
import sys
import os
@@ -88,10 +88,10 @@ def __init__(self, parent=None):
self.opening = ['(', '{', '[', "'", '"']
self.closing = [')', '}', ']', "'", '"']

## List of marker line to be deleted from check syntax
# List of marker line to be deleted from check syntax
self.bufferMarkerLine = []

self.settings = QSettings()
self.settings = QgsSettings()

# Enable non-ascii chars for editor
self.setUtf8(True)
@@ -869,7 +869,7 @@ def __init__(self, parent):
QTabWidget.__init__(self, parent=None)
self.parent = parent

self.settings = QSettings()
self.settings = QgsSettings()

self.idx = -1
# Layout for top frame (restore tabs)
@@ -21,11 +21,11 @@
from builtins import range
from builtins import object

from qgis.PyQt.QtCore import Qt, QCoreApplication, QSettings
from qgis.PyQt.QtCore import Qt, QCoreApplication
from qgis.PyQt.QtGui import QColor, QFont, QKeySequence
from qgis.PyQt.QtWidgets import QGridLayout, QSpacerItem, QSizePolicy, QShortcut, QMenu, QApplication
from qgis.PyQt.Qsci import QsciScintilla, QsciLexerPython
from qgis.core import QgsApplication
from qgis.core import QgsApplication, QgsSettings
from qgis.gui import QgsMessageBar
import sys

@@ -85,7 +85,7 @@ def __init__(self, parent=None):
self.parent = parent
self.shell = self.parent.shell

self.settings = QSettings()
self.settings = QgsSettings()

# Creates layout for message bar
self.layout = QGridLayout(self)
@@ -21,7 +21,7 @@
from builtins import bytes
from builtins import range

from qgis.PyQt.QtCore import Qt, QSettings, QByteArray, QCoreApplication, QFile, QSize
from qgis.PyQt.QtCore import Qt, QByteArray, QCoreApplication, QFile, QSize
from qgis.PyQt.QtWidgets import QDialog, QMenu, QShortcut, QApplication
from qgis.PyQt.QtGui import QColor, QKeySequence, QFont, QFontMetrics, QStandardItemModel, QStandardItem, QClipboard
from qgis.PyQt.Qsci import QsciScintilla, QsciLexerPython, QsciAPIs
@@ -33,7 +33,7 @@
import re
import traceback

from qgis.core import QgsApplication
from qgis.core import QgsApplication, QgsSettings
from .ui_console_history_dlg import Ui_HistoryDialogPythonConsole

_init_commands = ["from qgis.core import *", "import qgis.utils",
@@ -52,7 +52,7 @@ def __init__(self, parent=None):
self.opening = ['(', '{', '[', "'", '"']
self.closing = [')', '}', ']', "'", '"']

self.settings = QSettings()
self.settings = QgsSettings()

# Enable non-ascii chars for editor
self.setUtf8(True)
@@ -20,12 +20,13 @@
"""
from builtins import range

from qgis.PyQt.QtCore import QCoreApplication, QSize, QSettings, QFileInfo, Qt
from qgis.PyQt.QtCore import QCoreApplication, QSize, QFileInfo, Qt
from qgis.PyQt.QtWidgets import QDialog, QFileDialog, QMessageBox, QTableWidgetItem
from qgis.PyQt.QtGui import QIcon, QFont, QColor
from .console_compile_apis import PrepareAPIDialog

from .ui_console_settings import Ui_SettingsDialogPythonConsole
from qgis.core import QgsSettings


class optionsDialog(QDialog, Ui_SettingsDialogPythonConsole):
@@ -72,7 +73,7 @@ def enableDisable(self, value):
self.groupBoxPreparedAPI.setEnabled(value)

def loadAPIFile(self):
settings = QSettings()
settings = QgsSettings()
lastDirPath = settings.value("pythonConsole/lastDirAPIPath", "", type=str)
fileAPI, selected_filter = QFileDialog.getOpenFileName(
self, "Open API File", lastDirPath, "API file (*.api)")
@@ -138,7 +139,7 @@ def removeAPI(self):
self.tableWidget.removeRow(index.row())

def saveSettings(self):
settings = QSettings()
settings = QgsSettings()
settings.setValue("pythonConsole/preloadAPI", self.preloadAPI.isChecked())
settings.setValue("pythonConsole/autoSaveScript", self.autoSaveScript.isChecked())

@@ -218,7 +219,7 @@ def saveSettings(self):
settings.setValue("pythonConsole/tripleDoubleQuoteFontColorEditor", self.tripleDoubleQuoteFontColorEditor.color())

def restoreSettings(self):
settings = QSettings()
settings = QgsSettings()
self.spinBox.setValue(settings.value("pythonConsole/fontsize", 10, type=int))
self.spinBoxEditor.setValue(settings.value("pythonConsole/fontsizeEditor", 10, type=int))
self.fontComboBox.setCurrentFont(QFont(settings.value("pythonConsole/fontfamilytext",
@@ -155,7 +155,7 @@ class QgsDataItem : QObject
NoCapabilities,
SetCrs, //!< Can set CRS on layer or group of layers
Fertile, //!< Can create children. Even items without this capability may have children, but cannot create them, it means that children are created by item ancestors.
Fast //!< createChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,wfs,wcs,postgres...) are considered fast because they are reading data only from QSettings
Fast //!< createChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,wfs,wcs,postgres...) are considered fast because they are reading data only from QgsSettings
};
typedef QFlags<QgsDataItem::Capability> Capabilities;

@@ -199,7 +199,7 @@ class QgsProject : QObject, QgsExpressionContextGenerator
/**
* Key value accessors
*
* keys would be the familiar QSettings-like '/' delimited entries,
* keys would be the familiar QgsSettings-like '/' delimited entries,
* implying a hierarchy of keys and corresponding values
*/
QStringList readListEntry( const QString& scope, const QString& key, const QStringList& def = QStringList(), bool *ok = 0 ) const;
@@ -215,13 +215,13 @@ class QgsProject : QObject, QgsExpressionContextGenerator

/** Return keys with values -- do not return keys that contain other keys
*
* @note equivalent to QSettings entryList()
* @note equivalent to QgsSettings entryList()
*/
QStringList entryList( const QString& scope, const QString& key ) const;

/** Return keys with keys -- do not return keys that contain only values
*
* @note equivalent to QSettings subkeyList()
* @note equivalent to QgsSettings subkeyList()
*/
QStringList subkeyList( const QString& scope, const QString& key ) const;

@@ -44,10 +44,11 @@
*/
class QgsSettings : public QObject
{
%TypeHeaderCode
#include <qgssettings.h>

%TypeHeaderCode
#include <qgssettings.h>
%End
typedef PyObject *(*pyqt5_from_qvariant_by_type)(QVariant &value, PyObject *type);
%End

public:

@@ -64,7 +65,7 @@ class QgsSettings : public QObject

/** Construct a QgsSettings object for accessing settings of the application
* called application from the organization called organization, and with parent parent.
*/
*/
explicit QgsSettings( const QString &organization,
const QString &application = QString(), QObject *parent = 0 );

@@ -161,8 +162,23 @@ class QgsSettings : public QObject
* If no default value is specified, a default QVariant is returned.
* An optional Section argument can be used to get a value from a specific Section.
*/
QVariant value( const QString &key, const QVariant &defaultValue = QVariant(),
const QgsSettings::Section section = QgsSettings::Section::NoSection ) const;
SIP_PYOBJECT value( const QString &key, const QVariant &defaultValue = QVariant(),
SIP_PYOBJECT type = 0,
QgsSettings::Section section = QgsSettings::Section::NoSection ) const /ReleaseGIL/;
%MethodCode
QVariant value;

// QSettings has an internal mutex so release the GIL to avoid the possibility of deadlocks.
Py_BEGIN_ALLOW_THREADS
value = sipCpp->value(*a0, *a1, a3);
Py_END_ALLOW_THREADS

pyqt5_from_qvariant_by_type f = (pyqt5_from_qvariant_by_type) sipImportSymbol("pyqt5_from_qvariant_by_type");
sipRes = f(value, a2);

sipIsErr = !sipRes;
%End

//! Removes the setting key and any sub-settings of key.
void remove(const QString &key);
//! Return the sanitized and prefixed key
@@ -176,6 +192,8 @@ class QgsSettings : public QObject
void sync();
//! Returns true if there exists a setting called key; returns false otherwise.
//! If a group is set using beginGroup(), key is taken to be relative to that group.
bool contains(const QString &key) const;
bool contains(const QString &key, QgsSettings::Section section = QgsSettings::Section::NoSection ) const;
//! Removes all entries in the primary location associated to this QgsSettings object.
void clear();

};
@@ -104,12 +104,12 @@ class QgsCollapsibleGroupBox : QgsCollapsibleGroupBoxBasic
#include <qgscollapsiblegroupbox.h>
%End
public:
QgsCollapsibleGroupBox( QWidget *parent /TransferThis/ = 0, QSettings* settings = 0 );
QgsCollapsibleGroupBox( const QString &title, QWidget *parent /TransferThis/ = 0, QSettings* settings = 0 );
QgsCollapsibleGroupBox( QWidget *parent /TransferThis/ = 0, QgsSettings* settings = 0 );
QgsCollapsibleGroupBox( const QString &title, QWidget *parent /TransferThis/ = 0, QgsSettings* settings = 0 );
~QgsCollapsibleGroupBox();

// set custom QSettings pointer if group box was already created from QtDesigner promotion
void setSettings( QSettings* settings );
// set custom QgsSettings pointer if group box was already created from QtDesigner promotion
void setSettings( QgsSettings* settings );

//! set this to false to not save/restore collapsed state
void setSaveCollapsedState( bool save );
@@ -34,8 +34,8 @@ class QgsMessageViewer: QDialog, QgsMessageOutput //, Ui::QgsMessageViewer
void setCheckBoxState( Qt::CheckState state );
// Get checkbox state
Qt::CheckState checkBoxState();
// Specifies a QSettings tag to store/retrieve the checkbox
// Specifies a QgsSettings tag to store/retrieve the checkbox
// state to/from. Use an empty QString to disable this feature.
void setCheckBoxQSettingsLabel( const QString& label );
void setCheckBoxQgsSettingsLabel( const QString& label );
};

@@ -25,12 +25,12 @@ class QgsOptionsDialogBase : QDialog
%End
public:
/** Constructor
* @param settingsKey QSettings subgroup key for saving/restore ui states, e.g. "ProjectProperties".
* @param settingsKey QgsSettings subgroup key for saving/restore ui states, e.g. "ProjectProperties".
* @param parent parent object (owner)
* @param fl widget flags
* @param settings custom QSettings pointer
* @param settings custom QgsSettings pointer
*/
QgsOptionsDialogBase( const QString& settingsKey, QWidget* parent /TransferThis/ = 0, const Qt::WindowFlags& fl = 0, QSettings* settings = 0 );
QgsOptionsDialogBase( const QString& settingsKey, QWidget* parent /TransferThis/ = 0, const Qt::WindowFlags& fl = 0, QgsSettings* settings = 0 );
~QgsOptionsDialogBase();

/** Set up the base ui connections for vertical tabs.
@@ -39,8 +39,8 @@ class QgsOptionsDialogBase : QDialog
*/
void initOptionsBase( bool restoreUi = true, const QString& title = QString() );

// set custom QSettings pointer if dialog used outside QGIS (in plugin)
void setSettings( QSettings* settings );
// set custom QgsSettings pointer if dialog used outside QGIS (in plugin)
void setSettings( QgsSettings* settings );

/** Restore the base ui.
* Sometimes useful to do at end of subclass's constructor.
@@ -18,7 +18,7 @@ class QgsShortcutsManager: QObject

/** Constructor for QgsShortcutsManager.
* @param parent parent object
* @param settingsRoot root QSettings path for storing settings, e.g., "/myplugin/shortcuts". Leave
* @param settingsRoot root QgsSettings path for storing settings, e.g., "/myplugin/shortcuts". Leave
* as the default value to store settings alongside built in QGIS shortcuts, but care must be
* taken to not register actions which conflict with the built in QGIS actions.
*/
@@ -36,13 +36,13 @@
import os.path
from urllib.request import build_opener, install_opener, ProxyHandler

from qgis.PyQt.QtCore import QSettings, Qt
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import QApplication, QDialog, QDialogButtonBox, QMessageBox, QTreeWidgetItem, QWidget
from qgis.PyQt.QtGui import QColor, QCursor

from qgis.core import (QgsApplication, QgsCoordinateReferenceSystem,
QgsCoordinateTransform, QgsGeometry, QgsPoint,
QgsProviderRegistry)
QgsProviderRegistry, QgsSettings)
from qgis.gui import QgsRubberBand

from owslib.csw import CatalogueServiceWeb
@@ -74,7 +74,7 @@ def __init__(self, iface):

self.iface = iface
self.map = iface.mapCanvas()
self.settings = QSettings()
self.settings = QgsSettings()
self.catalog = None
self.catalog_url = None
self.context = StaticContext()
@@ -226,7 +226,7 @@ def set_connection_list_position(self):
# lot of items)
if not exists and conn_count > 0:
# If to_select is null, then the selected connection wasn't found
# by QSettings, which probably means that this is the first time
# by QgsSettings, which probably means that this is the first time
# the user has used CSWClient, so default to the first in the list
# of connetions. Otherwise default to the last.
if not to_select:
@@ -29,7 +29,7 @@

import xml.etree.ElementTree as etree

from qgis.PyQt.QtCore import QSettings
from qgis.core import QgsSettings
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, QListWidgetItem, QMessageBox

from MetaSearch.util import (get_connections_from_file, get_ui_class,
@@ -47,7 +47,7 @@ def __init__(self, mode):

QDialog.__init__(self)
self.setupUi(self)
self.settings = QSettings()
self.settings = QgsSettings()
self.filename = None
self.mode = mode # 0 - save, 1 - load
self.btnBrowse.clicked.connect(self.select_file)
@@ -27,7 +27,7 @@
#
###############################################################################

from qgis.PyQt.QtCore import QSettings
from qgis.core import QgsSettings
from qgis.PyQt.QtWidgets import QDialog, QMessageBox

from MetaSearch.util import get_ui_class
@@ -44,7 +44,7 @@ def __init__(self, conn_name=None):

QDialog.__init__(self)
self.setupUi(self)
self.settings = QSettings()
self.settings = QgsSettings()
self.conn_name = None
self.conn_name_orig = conn_name

3 comments on commit a10c890

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Mar 4, 2017

@jef-n , this created a regression with restoring loaded plugins upon QGIS launch, whereas the /pythonplugins/watchdog/pluginname key isn't removed upon successful plugin launch.

It's odd, since mySettings.remove( "/PythonPlugins/watchDog/" + packageName ); is called (twice actually, once in loadPythonPlugin() and another time in parent restoreSessionPlugins() )

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Mar 4, 2017

If I open the python console and run the following two lines:

settings = QgsSettings()
settomgs.remove('pythonplugins/watchdog/processing')

The key is properly removed. So, somehow, at that stage in the launch process, QgsSettings is able to setValue() properly, but not remove().

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Mar 4, 2017

Seems the problem is that setValue() is case insensitive (resulting in all lower case keys), while remove() isn't. PR #4218 offers a solution.

Please sign in to comment.
You can’t perform that action at this time.