Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 2 additions & 14 deletions Orange/widgets/data/owpythonscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from Orange.base import Learner, Model
from Orange.widgets import widget, gui
from Orange.widgets.utils import itemmodels
from Orange.widgets.settings import Setting, SettingsHandler
from Orange.widgets.settings import Setting
from Orange.widgets.utils.widgetpreview import WidgetPreview
from Orange.widgets.widget import OWWidget, Input, Output

Expand Down Expand Up @@ -364,14 +364,6 @@ def select_row(view, row):
QItemSelectionModel.ClearAndSelect)


class PrepareSavingSettingsHandler(SettingsHandler):
"""Calls storeSpecificSettings, which is currently not called from non-context handlers."""

def pack_data(self, widget):
widget.storeSpecificSettings()
return super().pack_data(widget)


class OWPythonScript(widget.OWWidget):
name = "Python Script"
description = "Write a Python script and run it on input data or models."
Expand All @@ -397,8 +389,6 @@ class Outputs:

signal_names = ("data", "learner", "classifier", "object")

settingsHandler = PrepareSavingSettingsHandler()

libraryListSource = \
Setting([Script("Hello world", "print('Hello world')\n")])
currentScriptIndex = Setting(0)
Expand Down Expand Up @@ -528,6 +518,7 @@ def __init__(self):
select_row(self.libraryView, self.currentScriptIndex)

self.restoreScriptText()
self.settingsAboutToBePacked.connect(self.saveScriptText)

self.splitCanvas.setSizes([2, 1])
if self.splitterState is not None:
Expand All @@ -537,9 +528,6 @@ def __init__(self):
self.controlArea.layout().addStretch(1)
self.resize(800, 600)

def storeSpecificSettings(self):
self.saveScriptText()

def restoreScriptText(self):
if self.scriptText is not None:
current = self.text.toPlainText()
Expand Down
19 changes: 14 additions & 5 deletions Orange/widgets/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,12 @@ def _add_defaults(self, data):
new_data.update(data)
return new_data

def _prepare_defaults(self, widget):
self.defaults = self.provider.pack(widget)
for setting, data, _ in self.provider.traverse_settings(data=self.defaults):
if setting.schema_only:
data.pop(setting.name, None)

def pack_data(self, widget):
"""
Pack the settings for the given widget. This method is used when
Expand All @@ -504,6 +510,7 @@ def pack_data(self, widget):
----------
widget : OWWidget
"""
widget.settingsAboutToBePacked.emit()
packed_settings = self.provider.pack(widget)
packed_settings[VERSION_KEY] = self.widget_class.settings_version
return packed_settings
Expand All @@ -517,10 +524,8 @@ def update_defaults(self, widget):
----------
widget : OWWidget
"""
self.defaults = self.provider.pack(widget)
for setting, data, _ in self.provider.traverse_settings(data=self.defaults):
if setting.schema_only:
data.pop(setting.name, None)
widget.settingsAboutToBePacked.emit()
self._prepare_defaults(widget)
self.write_defaults()

def fast_save(self, widget, name, value):
Expand Down Expand Up @@ -675,6 +680,7 @@ def update_defaults(self, widget):
Merge the widgets local contexts into the global contexts and persist
the settings (including the contexts) to disk.
"""
widget.settingsAboutToBePacked.emit()
self.settings_from_widget(widget)
globs = self.global_contexts
assert widget.context_settings is not globs
Expand All @@ -683,7 +689,10 @@ def update_defaults(self, widget):
globs.sort(key=lambda c: -c.time)
del globs[self.MAX_SAVED_CONTEXTS:]

super().update_defaults(widget)
# Save non-context settings. Do not call super().update_defaults, so that
# settingsAboutToBePacked is emitted once.
self._prepare_defaults(widget)
self.write_defaults()

def new_context(self, *args):
"""Create a new context."""
Expand Down
16 changes: 15 additions & 1 deletion Orange/widgets/tests/test_context_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from io import BytesIO
from unittest import TestCase
from unittest.mock import Mock, patch, call
from AnyQt.QtCore import pyqtSignal as Signal, QObject
from Orange.widgets.settings import (
ContextHandler, ContextSetting, Context, Setting, SettingsPrinter,
VERSION_KEY, IncompatibleContext
Expand All @@ -11,13 +12,14 @@
__author__ = 'anze'


class SimpleWidget:
class SimpleWidget(QObject):
settings_version = 1

setting = Setting(42)
schema_only_setting = Setting(None, schema_only=True)

context_setting = ContextSetting(42)
settingsAboutToBePacked = Signal()

migrate_settings = Mock()
migrate_context = Mock()
Expand Down Expand Up @@ -213,6 +215,18 @@ def test_close_context(self):
handler.close_context(widget)
self.assertEqual(widget.schema_only_setting, 0xD06F00D)

def test_about_pack_settings_signal(self):
handler = ContextHandler()
handler.bind(SimpleWidget)
widget = SimpleWidget()
handler.initialize(widget)
fn = Mock()
widget.settingsAboutToBePacked.connect(fn)
handler.pack_data(widget)
self.assertEqual(1, fn.call_count)
handler.update_defaults(widget)
self.assertEqual(2, fn.call_count)


class TestSettingsPrinter(TestCase):
def test_formats_contexts(self):
Expand Down
18 changes: 17 additions & 1 deletion Orange/widgets/tests/test_settings_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from unittest.mock import patch, Mock
import warnings

from AnyQt.QtCore import pyqtSignal as Signal, QObject

from Orange.tests import named_file
from Orange.widgets.settings import SettingsHandler, Setting, SettingProvider,\
VERSION_KEY, rename_setting, Context, migrate_str_to_variable
Expand Down Expand Up @@ -342,13 +344,25 @@ def override_default_settings(self, widget, defaults=None):
if os.path.isfile(filename):
os.remove(filename)

def test_about_pack_settings_signal(self):
handler = SettingsHandler()
handler.bind(SimpleWidget)
widget = SimpleWidget()
handler.initialize(widget)
fn = Mock()
widget.settingsAboutToBePacked.connect(fn)
handler.pack_data(widget)
self.assertEqual(1, fn.call_count)
handler.update_defaults(widget)
self.assertEqual(2, fn.call_count)


class Component:
int_setting = Setting(42)
schema_only_setting = Setting("only", schema_only=True)


class SimpleWidget:
class SimpleWidget(QObject):
settings_version = 1

setting = Setting(42)
Expand All @@ -357,8 +371,10 @@ class SimpleWidget:
non_setting = 5

component = SettingProvider(Component)
settingsAboutToBePacked = Signal()

def __init__(self):
super().__init__()
self.component = Component()

migrate_settings = Mock()
Expand Down
1 change: 1 addition & 0 deletions Orange/widgets/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ class OWWidget(QDialog, OWComponent, Report, ProgressBarMixin,
#: :type: list of :class:`Message`
UserAdviceMessages = []

settingsAboutToBePacked = Signal()
contextAboutToBeOpened = Signal(object)
contextOpened = Signal()
contextClosed = Signal()
Expand Down