Repository: spyder-ide/spyder

Issue:
Pressing Ctrl+P twice opens file switcher twice
## Description of your problem

**What steps will reproduce the problem?**
1. Press Ctrl-P
2. Press Ctrl-P again

**What is the expected output? What do you see instead?**

The first Ctrl-P opens the selection pop up. The second Ctrl-P should (preferably) close it while open, or at least do nothing. Instead, it seems a second pop up is opened over the first one (you then have to press Esc twice to close both of them).
## Versions and main components
- Spyder Version: Spyder 3.0.0.dev0 (from `spyder-ide` conda channel)
- Python Version: 3.5.2
- Operating system: Linux
## Dependencies

Please go to the menu entry `Help > Optional Dependencies` (or
`Help > Dependencies`), press the button `Copy to clipboard`
and paste the contents below:

jedi >=0.8.1     :  0.9.0 (OK)
matplotlib >=1.0 :  None (NOK)
nbconvert >=4.0  :  4.2.0 (OK)
numpy >=1.7      :  None (NOK)
pandas >=0.13.1  :  None (NOK)
pep8 >=0.6       :  1.7.0 (OK)
psutil >=0.3     :  4.3.0 (OK)
pyflakes >=0.6.0 :  1.2.3 (OK)
pygments >=2.0   :  2.1.3 (OK)
qtconsole >=4.2.0:  4.2.1 (OK)
rope >=0.9.4     :  0.9.4-1 (OK)
sphinx >=0.6.6   :  1.4.1 (OK)
sympy >=0.7.3    :  None (NOK)



Discussion:
Thanks for reporting @pitrou! I verified that the error is present in master.

@ccordoba12, are you working on this?

Not sure if pressing `Ctrl+P` should close it (this is similar to something I requested about hiding dockwidgets if the same shortcut used to show it also served to hide), I think ESC is a pretty natural choice.

@jitseniesen thoughts?

You need to focus dockwidgets more often than closing them. The popup on the other hand in constantly being shown and hidden, so I feel it's a more natural choice to toggle it with the shortcut.

> I feel it's a more natural choice to toggle it with the shortcut

I agree with @Nodd on this one. Pressing Ctrl+P should toggle the switcher between visible and hidden.


Resolving patch:
diff --git a/spyderlib/widgets/editor.py b/spyderlib/widgets/editor.py
--- a/spyderlib/widgets/editor.py
+++ b/spyderlib/widgets/editor.py
@@ -581,10 +581,16 @@ def open_fileswitcher_dlg(self):
         """Open file list management dialog box"""
         if not self.tabs.count():
             return
+        if self.fileswitcher_dlg is not None and \
+          self.fileswitcher_dlg.is_visible:
+            self.fileswitcher_dlg.hide()
+            self.fileswitcher_dlg.is_visible = False
+            return
         self.fileswitcher_dlg = FileSwitcher(self, self.tabs, self.data)
         self.fileswitcher_dlg.sig_goto_file.connect(self.set_stack_index)
         self.fileswitcher_dlg.sig_close_file.connect(self.close_file)
         self.fileswitcher_dlg.show()
+        self.fileswitcher_dlg.is_visible = True
 
     def update_fileswitcher_dlg(self):
         """Synchronize file list dialog box with editor widget tabs"""
diff --git a/spyderlib/widgets/fileswitcher.py b/spyderlib/widgets/fileswitcher.py
--- a/spyderlib/widgets/fileswitcher.py
+++ b/spyderlib/widgets/fileswitcher.py
@@ -225,6 +225,7 @@ def __init__(self, parent, tabs, data):
         self.initial_path = None          # Fullpath of initial active editor
         self.initial_editor = None        # Initial active editor
         self.line_number = None           # Selected line number in filer
+        self.is_visible = False           # Is the switcher visible?
 
         help_text = _("Press <b>Enter</b> to switch files or <b>Esc</b> to "
                       "cancel.<br><br>Type to filter filenames.<br><br>"
@@ -326,12 +327,14 @@ def save_initial_state(self):
             self.initial_cursors[paths[i]] = editor.textCursor()
 
     def accept(self):
+        self.is_visible = False
         QDialog.accept(self)
         self.list.clear()
 
     def restore_initial_state(self):
         """Restores initial cursors and initial active editor."""
         self.list.clear()
+        self.is_visible = False
         editors = self.editors_by_path
 
         for path in self.initial_cursors:


Test patch: