Repository: spyder-ide/spyder

Issue:
An idea to improve the visual of the 'Lock panes and toolbars' action in the View menu
This is a simple idea to maybe improve the action to lock and unlock panes and toolbars in Spyder.

I can push a PR if you like or you can close if you don't, that is ok too :)

Basically, the icon and text of the action is changed according to the locked state of the panes and toolbars.

![lock_unlock_interface](https://user-images.githubusercontent.com/10170372/80288305-22674180-8705-11ea-966f-fb495cf53932.gif)

For comparison, this is the current behaviour.

![lock_unlock_interface_old](https://user-images.githubusercontent.com/10170372/80288316-30b55d80-8705-11ea-9c0b-73270ffce6bf.gif)




Discussion:
> Basically, the icon and text of the action is changed according to the locked state of the panes and toolbars.

I really like it!! Thanks a lot for the suggestion and your PR is more than welcome!
Excellent! Do I do it against Master or 4.x?
4.x :-)

Resolving patch:
diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py
--- a/spyder/app/mainwindow.py
+++ b/spyder/app/mainwindow.py
@@ -586,8 +586,11 @@ def setup(self):
                                "Close pane")
         self.lock_interface_action = create_action(
             self,
-            _("Lock panes and toolbars"),
-            toggled=self.toggle_lock,
+            (_("Unlock panes and toolbars") if self.interface_locked else
+             _("Lock panes and toolbars")),
+            icon=ima.icon('lock' if self.interface_locked else 'lock_open'),
+            triggered=lambda checked:
+                self.toggle_lock(not self.interface_locked),
             context=Qt.ApplicationShortcut)
         self.register_shortcut(self.lock_interface_action, "_",
                                "Lock unlock panes")
@@ -1332,7 +1335,7 @@ def post_visible_setup(self):
         self.load_last_visible_toolbars()
 
         # Update lock status
-        self.lock_interface_action.setChecked(self.interface_locked)
+        self.toggle_lock(self.interface_locked)
 
         # Hide Internal Console so that people don't use it instead of
         # the External or IPython ones
@@ -2524,6 +2527,11 @@ def toggle_lock(self, value):
         """Lock/Unlock dockwidgets and toolbars"""
         self.interface_locked = value
         CONF.set('main', 'panes_locked', value)
+        self.lock_interface_action.setIcon(
+            ima.icon('lock' if self.interface_locked else 'lock_open'))
+        self.lock_interface_action.setText(
+            _("Unlock panes and toolbars") if self.interface_locked else
+            _("Lock panes and toolbars"))
 
         # Apply lock to panes
         for plugin in (self.widgetlist + self.thirdparty_plugins):


Test patch:
diff --git a/spyder/app/tests/test_mainwindow.py b/spyder/app/tests/test_mainwindow.py
--- a/spyder/app/tests/test_mainwindow.py
+++ b/spyder/app/tests/test_mainwindow.py
@@ -284,8 +284,8 @@ def test_lock_action(main_window):
     action = main_window.lock_interface_action
     plugins = main_window.widgetlist
 
-    # By default the action is checked
-    assert action.isChecked()
+    # By default the interface is locked.
+    assert main_window.interface_locked
 
     # In this state the title bar is an empty QWidget
     for plugin in plugins:
@@ -294,14 +294,16 @@ def test_lock_action(main_window):
         assert isinstance(title_bar, QWidget)
 
     # Test that our custom title bar is shown when the action
-    # is unchecked
-    action.setChecked(False)
+    # is triggered.
+    action.trigger()
     for plugin in plugins:
         title_bar = plugin.dockwidget.titleBarWidget()
         assert isinstance(title_bar, DockTitleBar)
+    assert not main_window.interface_locked
 
     # Restore default state
-    action.setChecked(True)
+    action.trigger()
+    assert main_window.interface_locked
 
 
 @pytest.mark.slow