From 80ac32dea433c2711df6d97ecee9f29528f430ca Mon Sep 17 00:00:00 2001 From: Spiros Georgaras Date: Sun, 22 May 2022 14:21:26 +0300 Subject: [PATCH] - version 0.8.9.20 (0.9-beta-17) - going back to history will ask to save a modified playlist - fixing #157 (python2 only) - other minor changes --- Changelog | 8 +- README.html | 8 +- pyradio/__init__.py | 2 +- pyradio/browser.py | 24 ++-- pyradio/config_window.py | 32 ++--- pyradio/edit.py | 32 +++-- pyradio/install.py | 2 +- pyradio/radio.py | 199 ++++++++++++++----------------- pyradio/simple_curses_widgets.py | 6 +- pyradio/themes.py | 12 +- pyradio/window_stack.py | 46 +++---- 11 files changed, 188 insertions(+), 183 deletions(-) diff --git a/Changelog b/Changelog index fdef858a..8862b71c 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,12 @@ +2022-05-22 s-n-g + * version 0.8.9.20 (0.9-beta-17) + * going back to history will ask to save a modified playlist + * fixing #157 (python2 only) + * other minor changes + 2022-05-19 s-n-g * version 0.8.9.19 (0.9-beta16) - * fixing main window galobal shortcuts + * fixing main window galobal shortcuts ( #156 ) * fixing RadioBrowser Search Window global shortcuts 2022-05-18 s-n-g diff --git a/README.html b/README.html index 094a1d20..5c66260d 100644 --- a/README.html +++ b/README.html @@ -153,9 +153,15 @@

Requirements Changelog Top

 
+2022-05-22 s-n-g
+    * version 0.8.9.20 (0.9-beta-17)
+    * going back to history will ask to save a modified playlist
+    * fixing #157 (python2 only)
+    * other minor changes
+
 2022-05-19 s-n-g
     * version 0.8.9.19 (0.9-beta16)
-    * fixing main window galobal shortcuts
+    * fixing main window galobal shortcuts ( #156 )
     * fixing RadioBrowser  Search Window global shortcuts
 
 2022-05-18 s-n-g
diff --git a/pyradio/__init__.py b/pyradio/__init__.py
index 598b89f7..e17a92fc 100644
--- a/pyradio/__init__.py
+++ b/pyradio/__init__.py
@@ -1,6 +1,6 @@
 " pyradio -- Console radio player. "
 
-version_info = (0, 8, 9, 19)
+version_info = (0, 8, 9, 20)
 
 # Set it to True if new stations have been
 # added to the package's stations.csv
diff --git a/pyradio/browser.py b/pyradio/browser.py
index 69d920ac..9c8b9d1e 100644
--- a/pyradio/browser.py
+++ b/pyradio/browser.py
@@ -399,8 +399,8 @@ def set_global_functions(self, global_functions):
         self._global_functions = {}
         if global_functions is not None:
             self._global_functions = dict(global_functions)
-            if 't' in self._global_functions.keys():
-                del self._global_functions['t']
+            if ord('t') in self._global_functions.keys():
+                del self._global_functions[ord('t')]
             # if 'T' in self._global_functions.keys():
             #     del self._global_functions['T']
 
@@ -1712,8 +1712,8 @@ def __init__(
         self._global_functions = {}
         if global_functions is not None:
             self._global_functions = global_functions.copy()
-            if 't' in self._global_functions.keys():
-                del self._global_functions['t']
+            if ord('t') in self._global_functions.keys():
+                del self._global_functions[ord('t')]
 
     @property
     def urls(self):
@@ -2138,8 +2138,8 @@ def keypress(self, char):
                 logger.error('---=== Server Selection is None ===---')
                 self._server_selection_window = None
 
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
             return 1
         if char in (
             curses.KEY_EXIT, 27, ord('q')
@@ -2312,8 +2312,8 @@ def __init__(self,
 
         if global_functions is not None:
             self._global_functions = dict(global_functions)
-            if 't' in self._global_functions.keys():
-                del self._global_functions['t']
+            if ord('t') in self._global_functions.keys():
+                del self._global_functions[ord('t')]
 
     def __del__(self):
         for a_widget in self._widgets:
@@ -4012,8 +4012,8 @@ def __init__(self, parent, servers, current_server, show_random=False, global_fu
         # if global_functions is not None:
         #     logger.error('\n\n{}\n\n'.format(global_functions))
         #     self._global_functions = deepcopy(global_functions)
-        #     if 't' in self._global_functions.keys():
-        #             del self._global_functions['t']
+        #     if ord('t') in self._global_functions.keys():
+        #             del self._global_functions[ord('t')]
 
         if show_random:
             self.items.reverse()
@@ -4073,8 +4073,8 @@ def keypress(self, char):
         if self._too_small:
             return 1
 
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
             return 1
         elif char in (
             curses.KEY_EXIT, ord('q'), 27,
diff --git a/pyradio/config_window.py b/pyradio/config_window.py
index a74b2bed..2854418c 100644
--- a/pyradio/config_window.py
+++ b/pyradio/config_window.py
@@ -25,8 +25,8 @@ def set_global_functions(global_functions):
     ret = {}
     if global_functions is not None:
         ret = dict(global_functions)
-        if 't' in ret.keys():
-            del ret['t']
+        if ord('t') in ret.keys():
+            del ret[ord('t')]
     return ret
 
 class PyRadioConfigWindow(object):
@@ -362,8 +362,8 @@ def keypress(self, char):
         if self.too_small:
             return 1, []
         val = list(self._config_options.items())[self.selection]
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
         elif val[0] == 'radiobrowser':
             if char in (curses.KEY_RIGHT, ord('l'),
                         ord(' '), curses.KEY_ENTER, ord('\n')):
@@ -867,8 +867,8 @@ def keypress(self, char):
                 ''' cancel '''
                 self.edit_string = ''
                 ret = 0
-        elif chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        elif char in self._global_functions.keys():
+            self._global_functions[char]()
             return 1
 
         if ret == 1:
@@ -1186,8 +1186,8 @@ def keypress(self, char):
                  5 - add parameter
                  6 - line editor help
         '''
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
             return -1
         elif char in (
             curses.KEY_ENTER, ord('\n'),
@@ -1487,8 +1487,8 @@ def keypress(self, char):
         '''
         if self.editing == 0:
             ''' focus on players '''
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (9, ):
                 if self._players[self.selection][1]:
                     self._switch_column()
@@ -1893,8 +1893,8 @@ def _col_row_to_selection(self, a_column, a_row):
     def keypress(self, char):
         ''' Encoding key press
         '''
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
 
         elif char in (ord('c'), ):
             self.encoding = self._config_encoding
@@ -2292,8 +2292,8 @@ def keypress(self, char):
          0, station path    - selected station path (for paste window)
          1, ''              - Cancel
         '''
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
 
         elif self._select_playlist_error == -1 or \
                 self._select_playlist_error == 0:
@@ -2532,8 +2532,8 @@ def keypress(self, char):
             self.setStation(self._orig_playlist)
             return -1, ''
 
-        elif chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        elif char in self._global_functions.keys():
+            self._global_functions[char]()
             return -1, ''
 
         return PyRadioSelectPlaylist.keypress(self, char)
diff --git a/pyradio/edit.py b/pyradio/edit.py
index 7d48ddbd..d10210fc 100644
--- a/pyradio/edit.py
+++ b/pyradio/edit.py
@@ -383,7 +383,7 @@ def show(self, item=None):
                 self._win.addstr(17 + step, 5, '─' * (self.maxX - 10), curses.color_pair(3))
             except:
                 self._win.addstr(17 + step, 3, '─'.encode('utf-8') * (self.maxX - 10), curses.color_pair(3))
-            self._win.addstr(17 + step, int((self.maxX - 33) / 2), ' Player Keys (Not in Line Editor) ', curses.color_pair(4))
+            self._win.addstr(17 + step, int((self.maxX - 42) / 2), ' Global Functions (with \ in Line Editor) ', curses.color_pair(4))
 
             self._win.addstr(18 + step, 5, '-', curses.color_pair(4))
             self._win.addstr('/', curses.color_pair(5))
@@ -400,6 +400,14 @@ def show(self, item=None):
             self._win.addstr('ute player / Save ', curses.color_pair(5))
             self._win.addstr('v', curses.color_pair(4))
             self._win.addstr('olume (not in vlc).', curses.color_pair(5))
+            if step + 21 < self.maxY:
+                self._win.addstr(20 + step, 5, 'W', curses.color_pair(4))
+                self._win.addstr(' / ', curses.color_pair(5))
+                self._win.addstr('w', curses.color_pair(4))
+                self._win.addstr(20 + step, 23, 'Toggle titles log / like a station', curses.color_pair(5))
+            if step + 22 < self.maxY:
+                self._win.addstr(21 + step, 5, 'T', curses.color_pair(4))
+                self._win.addstr(21 + step, 23, 'Toggle transparency', curses.color_pair(5))
 
         if item:
             self._set_item(item)
@@ -629,8 +637,8 @@ def keypress(self, char):
                     self.new_station = None
                     self._reset_editors_modes()
                     ret = -1
-            elif chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            elif char in self._global_functions.keys():
+                self._global_functions[char]()
 
         if self._focus > 1:
             self._reset_editors_modes()
@@ -958,7 +966,7 @@ def show(self):
                 self._win.addstr(18 + adjust_line_Y, 5, '─' * (self.maxX - 10), curses.color_pair(3))
             except:
                 self._win.addstr(18 + adjust_line_Y, 3, '─'.encode('utf-8') * (self.maxX - 10), curses.color_pair(3))
-            self._win.addstr(18 + adjust_line_Y, int((self.maxX - 33) / 2), ' Player Keys (Not in Line Editor) ', curses.color_pair(4))
+            self._win.addstr(18 + adjust_line_Y, int((self.maxX - 42) / 2), ' Global Functions (with \ in Line Editor) ', curses.color_pair(4))
 
             self._win.addstr(19 + adjust_line_Y, 5, '-', curses.color_pair(4))
             self._win.addstr('/', curses.color_pair(5))
@@ -975,6 +983,14 @@ def show(self):
             self._win.addstr('ute player / Save ', curses.color_pair(5))
             self._win.addstr('v', curses.color_pair(4))
             self._win.addstr('olume (not in vlc).', curses.color_pair(5))
+            if adjust_line_Y + 22 < self.maxY:
+                self._win.addstr(21 + adjust_line_Y, 5, 'W', curses.color_pair(4))
+                self._win.addstr(' / ', curses.color_pair(5))
+                self._win.addstr('w', curses.color_pair(4))
+                self._win.addstr(21 + adjust_line_Y, 23, 'Toggle titles log / like a station', curses.color_pair(5))
+            if adjust_line_Y + 23 < self.maxY:
+                self._win.addstr(22 + adjust_line_Y, 5, 'T', curses.color_pair(4))
+                self._win.addstr(22 + adjust_line_Y, 23, 'Toggle transparency', curses.color_pair(5))
 
         self._win.refresh()
         self._update_focus()
@@ -1150,8 +1166,8 @@ def keypress(self, char):
                     # cancel
                     self._widgets[0].string = ''
                     ret = -1
-            elif chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            elif char in self._global_functions.keys():
+                self._global_functions[char]()
         #self._show_title()
         #self.show()
         return self._get_result(ret)
@@ -1236,8 +1252,8 @@ def keypress(self, char):
                  0: go on
                  1: Ok
         """
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
 
         elif char in (curses.KEY_ENTER, ord('\n'), ord('\r'), ord('s')):
             return 1
diff --git a/pyradio/install.py b/pyradio/install.py
index a2ac4faa..895e740d 100644
--- a/pyradio/install.py
+++ b/pyradio/install.py
@@ -634,7 +634,7 @@ def update_or_uninstall_on_windows(self, mode='update', from_pyradio=False, firs
                     b.write(')\n')
 
                     b.write('devel\\build_install_pyradio.bat -u\n')
-                    b.write('PAUSE\n')
+                    # b.write('PAUSE\n')
                     b.write('GOTO endofscript\n')
                 b.write('ECHO.\n\n')
                 b.write(':downloaderror\n')
diff --git a/pyradio/radio.py b/pyradio/radio.py
index d1dc5cb2..fc99fb41 100644
--- a/pyradio/radio.py
+++ b/pyradio/radio.py
@@ -228,6 +228,7 @@ class PyRadio(object):
 
     detect_if_player_exited = True
 
+
     def ll(self, msg):
         logger.error('DE ==========')
         logger.error('DE ===> {}'.format(msg))
@@ -310,6 +311,7 @@ def __init__(self, pyradio_config,
                 self.ws.PLAYLIST_NOT_FOUND_ERROR_MODE: self._print_playlist_not_found_error,
                 self.ws.PLAYLIST_LOAD_ERROR_MODE: self._print_playlist_load_error,
                 self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE: self._redisplay_print_save_modified_playlist,
+                self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_BACK_IN_HISTORY_MODE: self._redisplay_print_save_modified_playlist,
                 self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_EXITING_MODE: self._redisplay_print_save_modified_playlist,
                 self.ws.PLAYLIST_RELOAD_CONFIRM_MODE: self._print_playlist_reload_confirmation,
                 self.ws.PLAYLIST_DIRTY_RELOAD_CONFIRM_MODE: self._print_playlist_dirty_reload_confirmation,
@@ -480,16 +482,16 @@ def __init__(self, pyradio_config,
         }
 
         self._global_functions = {
-            'w': self._tag_a_title,
-            'W': self._toggle_titles_logging,
-            'T': self._toggle_transparency,
-            '+': self._volume_up,
-            '=': self._volume_up,
-            '.': self._volume_up,
-            '-': self._volume_down,
-            ',': self._volume_down,
-            'm': self._volume_mute,
-            'v': self._volume_save
+            ord('w'): self._tag_a_title,
+            ord('W'): self._toggle_titles_logging,
+            ord('T'): self._toggle_transparency,
+            ord('+'): self._volume_up,
+            ord('='): self._volume_up,
+            ord('.'): self._volume_up,
+            ord('-'): self._volume_down,
+            ord(','): self._volume_down,
+            ord('m'): self._volume_mute,
+            ord('v'): self._volume_save
         }
 
 
@@ -4613,30 +4615,6 @@ def _normal_station_info(self):
         else:
             self._print_station_info_error()
 
-    def _handle_limited_height_keys(self, char):
-        if char in (ord('+'), ord('='), ord('.')):
-            self._update_status_bar_right()
-            self._volume_up()
-
-        elif char in (ord('-'), ord(',')):
-            self._update_status_bar_right()
-            self._volume_down()
-
-        elif char in (ord('m'), ):
-            self._update_status_bar_right()
-            self._volume_mute()
-
-        elif char in (ord('v'), ):
-            self._update_status_bar_right()
-            self._volume_save()
-
-        elif char in (ord('W'), ):
-            self._toggle_titles_logging()
-
-        elif char in (ord('w'), ):
-            logger.error('==== w!')
-            self._tag_a_title()
-
     def _browser_server_selection(self):
         if self._cnf._online_browser:
             self._cnf._online_browser.select_servers()
@@ -4914,28 +4892,15 @@ def keypress(self, char):
             self._i_am_resizing = False
             return
 
-        if char in (ord('w'), ) and self.ws.operation_mode in (
-            self.ws.NORMAL_MODE,
-            self.ws.PLAYLIST_MODE
-        ):
-            self._tag_a_title()
-            return
-
-        elif char in (ord('W'), ) and self.ws.operation_mode in (
-            self.ws.NORMAL_MODE,
-            self.ws.PLAYLIST_MODE
-        ):
-            self._toggle_titles_logging()
-            return
-
         ''' if small exit '''
         if self._limited_height_mode or self._limited_width_mode:
-            self._handle_limited_height_keys(char)
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             return
 
         if self.ws.operation_mode == self.ws.WIN_UNINSTALL_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self.ws.close_window()
                 if char in (ord('y'), ):
@@ -4946,8 +4911,8 @@ def keypress(self, char):
             return
 
         if self.ws.operation_mode == self.ws.WIN_PRINT_EXE_LOCATION_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('q'), curses.KEY_EXIT, 27):
                 self.ws.close_window()
                 curses.ungetch('q')
@@ -4955,8 +4920,8 @@ def keypress(self, char):
             return
 
         if self.ws.operation_mode == self.ws.WIN_MANAGE_PLAYERS_MSG_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self.ws.close_window()
                 curses.ungetch('q')
@@ -4964,8 +4929,8 @@ def keypress(self, char):
             return
 
         if self.ws.operation_mode == self.ws.WIN_REMOVE_OLD_INSTALLATION_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self.ws.close_window()
                 self.refreshBody()
@@ -5145,7 +5110,17 @@ def keypress(self, char):
 
             elif char == ord('\\'):
                 ''' \\ pressed - go back in history '''
-                self._goto_history_back_handler()
+                if self._cnf.dirty_playlist:
+                    if self._cnf.auto_save_playlist:
+                        ''' save playlist '''
+                        ret = self.saveCurrentPlaylist()
+                        if ret == 0:
+                            self._goto_history_back_handler()
+                    else:
+                        ''' ask to save playlist '''
+                        self._print_save_modified_playlist(self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_BACK_IN_HISTORY_MODE)
+                else:
+                    self._goto_history_back_handler()
 
             elif char == ord(']'):
                 ''' ] pressed - go to first playlist in history '''
@@ -5323,8 +5298,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.NOT_IMPLEMENTED_YET_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self.ws.close_window()
                 self.refreshBody()
@@ -5748,8 +5723,8 @@ def keypress(self, char):
 
         elif self.ws.operation_mode == self.ws.BROWSER_SERVER_SELECTION_MODE and \
                 char not in self._chars_to_bypass:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             if self._server_selection_window:
                 ret = self._server_selection_window.keypress(char)
@@ -5830,8 +5805,8 @@ def keypress(self, char):
                 (char not in self._chars_to_bypass_on_editor or \
                 self._cnf._online_browser.line_editor_has_focus()):
 
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
 
             ''' handle browser search key press '''
@@ -5877,8 +5852,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.BROWSER_SORT_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             ret = self._cnf._online_browser.keypress(char)
             if ret < 1:
@@ -5938,8 +5913,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.ASK_TO_CREATE_NEW_THEME_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             if self.theme_forced_selection:
                 self._theme_selector.set_theme(self.theme_forced_selection)
@@ -6044,8 +6019,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.ASK_TO_SAVE_BROWSER_CONFIG_TO_EXIT:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ord('n')):
                 self.ws.close_window()
                 if char == ord('y'):
@@ -6072,8 +6047,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.ASK_TO_SAVE_BROWSER_CONFIG_FROM_CONFIG:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ord('n')):
                 self.ws.close_window()
                 if char == ord('y'):
@@ -6103,8 +6078,8 @@ def keypress(self, char):
 
         elif self.ws.operation_mode == self.ws.ASK_TO_SAVE_BROWSER_CONFIG_FROM_BROWSER:
             logger.error('DE =========================')
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ord('n')):
                 self.ws.close_window()
                 if char == ord('y'):
@@ -6142,8 +6117,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.CLEAR_ALL_REGISTERS_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ord('n')):
                 self.ws.close_window()
                 if char == ord('y'):
@@ -6160,8 +6135,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.UPDATE_NOTIFICATION_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 with self._update_notify_lock:
                     self._update_version = ''
@@ -6174,8 +6149,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.UPDATE_NOTIFICATION_OK_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             # ok
             self.detect_if_player_exited = False
@@ -6193,8 +6168,8 @@ def keypress(self, char):
             return -1
 
         elif self.ws.operation_mode == self.ws.UPDATE_NOTIFICATION_NOK_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self.helpWinContainer = None
                 self.helpWin = None
@@ -6329,15 +6304,9 @@ def keypress(self, char):
             self._toggle_transparency()
             return
 
-        elif chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        elif char in self._global_functions.keys():
+            self._global_functions[char]()
             return
-        # elif char in (ord('+'), ord('='), ord('.'),
-        #               ord('-'), ord(','), ord('m'),
-        #               ord('v'), ord('W'), ord('w')):
-        #     self._handle_limited_height_keys(char)
-        #     logger.error('\n\nhere\n\n')
-        #     return
 
         elif self.ws.operation_mode == self.ws.PLAYLIST_SCAN_ERROR_MODE:
             ''' exit due to scan error '''
@@ -6347,8 +6316,8 @@ def keypress(self, char):
             return -1
 
         elif self.ws.operation_mode == self.ws.PLAYLIST_RECOVERY_ERROR_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self._cnf.playlist_recovery_result = 0
                 self.ws.close_window()
@@ -6356,8 +6325,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_EXITING_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ord('Y')):
                 self.ws.close_window()
                 if not self._cnf.locked and char == ord('Y'):
@@ -6395,9 +6364,10 @@ def keypress(self, char):
                     return
             return
 
-        elif self.ws.operation_mode == self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+        elif self.ws.operation_mode in (self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE,
+                                        self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_BACK_IN_HISTORY_MODE):
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             else:
                 self.ws.close_window()
                 if char in (ord('y'), ord('Y')):
@@ -6405,12 +6375,18 @@ def keypress(self, char):
                         self._cnf.auto_save_playlist = True
                     ret = self.saveCurrentPlaylist()
                     if ret == 0:
-                        self._open_playlist()
+                        if self.ws.operation_mode == self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE:
+                            self._open_playlist()
+                        else:
+                            self._goto_history_back_handler()
                     else:
                         if self._cnf.browsing_station_service:
                             self._cnf.removed_playlist_history_item()
                 elif char in (ord('n'), ):
-                    self._open_playlist()
+                    if self.ws.operation_mode == self.ws.ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE:
+                        self._open_playlist()
+                    else:
+                        self._goto_history_back_handler()
                 elif char in (curses.KEY_EXIT, ord('q'), 27):
                     self.bodyWin.nodelay(True)
                     char = self.bodyWin.getch()
@@ -6423,8 +6399,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.PLAYLIST_DIRTY_RELOAD_CONFIRM_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ord('Y')):
                 if not self._cnf.locked and char == ord('Y'):
                     self._cnf.confirm_playlist_reload = False
@@ -6440,8 +6416,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.PLAYLIST_RELOAD_CONFIRM_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             if char in (ord('y'), ord('Y')):
                 if not self._cnf.locked and char == ord('Y'):
@@ -6459,8 +6435,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.REMOVE_STATION_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             if char in (ord('y'), ord('Y')):
                 self._set_active_stations()
@@ -6492,8 +6468,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.FOREIGN_PLAYLIST_ASK_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char in (ord('y'), ):
                 ret = self._cnf.copy_playlist_to_config_dir()
                 if ret == 0:
@@ -6585,8 +6561,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode == self.ws.STATIONS_ASK_TO_INTEGRATE_MODE:
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
             elif char == ord('y'):
                 self._cnf._integrate_stations = False
                 self.ws.close_window()
@@ -6609,9 +6585,8 @@ def keypress(self, char):
             return
 
         elif self.ws.operation_mode in self.ws.PASSIVE_WINDOWS:
-            logger.error('--- PASSIVE_WINDOWS ----')
-            if chr(char) in self._global_functions.keys():
-                self._global_functions[chr(char)]()
+            if char in self._global_functions.keys():
+                self._global_functions[char]()
                 return
             if self.ws.operation_mode in (
                     self.ws.MAIN_HELP_MODE,
diff --git a/pyradio/simple_curses_widgets.py b/pyradio/simple_curses_widgets.py
index ffa43ea5..5f3c72a7 100644
--- a/pyradio/simple_curses_widgets.py
+++ b/pyradio/simple_curses_widgets.py
@@ -2086,8 +2086,8 @@ def set_global_functions(self, global_functions):
         self._global_functions = {}
         if global_functions is not None:
             self._global_functions = dict(global_functions)
-            if 't' in self._global_functions.keys():
-                del self._global_functions['t']
+            if ord('t') in self._global_functions.keys():
+                del self._global_functions[ord('t')]
             # if 'T' in self._global_functions.keys():
             #     del self._global_functions['T']
 
@@ -2909,7 +2909,7 @@ def keypress(self, win, char):
                 self._paste_mode = False
                 if self._mode_changed:
                     self._mode_changed()
-            self._global_functions[chr(char)]()
+            self._global_functions[char]()
 
         else:
             self._backslash_pressed = False
diff --git a/pyradio/themes.py b/pyradio/themes.py
index a6891786..7a5c53ea 100644
--- a/pyradio/themes.py
+++ b/pyradio/themes.py
@@ -472,10 +472,10 @@ def set_global_functions(self, global_functions):
         self._global_functions = {}
         if global_functions is not None:
             self._global_functions = dict(global_functions)
-            if 't' in self._global_functions.keys():
-                del self._global_functions['t']
-            if 'T' in self._global_functions.keys():
-                del self._global_functions['T']
+            if ord('t') in self._global_functions.keys():
+                del self._global_functions[ord('t')]
+            if ord('T') in self._global_functions.keys():
+                del self._global_functions[ord('T')]
 
     def show(self):
         self._themes = [['dark', 'dark']]
@@ -839,8 +839,8 @@ def keypress(self, char):
         """
         if  self._too_small:
             return -1, False
-        if chr(char) in self._global_functions.keys():
-            self._global_functions[chr(char)]()
+        if char in self._global_functions.keys():
+            self._global_functions[char]()
             return -3, False
         if char in (ord('e'), ):
             ''' edit theme '''
diff --git a/pyradio/window_stack.py b/pyradio/window_stack.py
index 0e68dcd6..9e9d7ad7 100644
--- a/pyradio/window_stack.py
+++ b/pyradio/window_stack.py
@@ -31,28 +31,29 @@ class Window_Stack_Constants(object):
     REMOVE_STATION_MODE = 50
     SAVE_PLAYLIST_MODE = 51
     ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE = 52
-    ASK_TO_SAVE_PLAYLIST_WHEN_EXITING_MODE = 53
-    ADD_STATION_MODE = 54
-    EDIT_STATION_MODE = 55
-    CLEAR_REGISTER_MODE = 56
-    CLEAR_ALL_REGISTERS_MODE = 57
-    STATION_INFO_MODE = 58
-    CREATE_PLAYLIST_MODE = 59
-    RENAME_PLAYLIST_MODE = 60
-    COPY_PLAYLIST_MODE = 61
-    CONNECTION_MODE = 62
-    PASTE_MODE = 63
-    UNNAMED_REGISTER_MODE = 64
-    PLAYER_PARAMS_MODE = 65
-    STATIONS_ASK_TO_INTEGRATE_MODE = 66
-    STATION_DATABASE_INFO_MODE = 67
-    VOTE_RESULT_MODE = 68
-    BROWSER_SORT_MODE = 69
-    BROWSER_SERVER_SELECTION_MODE = 70
-    BROWSER_SEARCH_MODE = 71
-    BROWSER_OPEN_MODE = 72
-    BROWSER_PERFORMING_SEARCH_MODE = 73
-    RADIO_BROWSER_CONFIG_MODE = 74
+    ASK_TO_SAVE_PLAYLIST_WHEN_BACK_IN_HISTORY_MODE = 53
+    ASK_TO_SAVE_PLAYLIST_WHEN_EXITING_MODE = 54
+    ADD_STATION_MODE = 55
+    EDIT_STATION_MODE = 56
+    CLEAR_REGISTER_MODE = 57
+    CLEAR_ALL_REGISTERS_MODE = 58
+    STATION_INFO_MODE = 59
+    CREATE_PLAYLIST_MODE = 60
+    RENAME_PLAYLIST_MODE = 61
+    COPY_PLAYLIST_MODE = 62
+    CONNECTION_MODE = 63
+    PASTE_MODE = 64
+    UNNAMED_REGISTER_MODE = 65
+    PLAYER_PARAMS_MODE = 66
+    STATIONS_ASK_TO_INTEGRATE_MODE = 67
+    STATION_DATABASE_INFO_MODE = 68
+    VOTE_RESULT_MODE = 69
+    BROWSER_SORT_MODE = 70
+    BROWSER_SERVER_SELECTION_MODE = 71
+    BROWSER_SEARCH_MODE = 72
+    BROWSER_OPEN_MODE = 73
+    BROWSER_PERFORMING_SEARCH_MODE = 74
+    RADIO_BROWSER_CONFIG_MODE = 75
     MAIN_HELP_MODE = 100
     MAIN_HELP_MODE_PAGE_2 = 101
     MAIN_HELP_MODE_PAGE_3 = 102
@@ -149,6 +150,7 @@ class Window_Stack_Constants(object):
         REMOVE_STATION_MODE: 'REMOVE_STATION_MODE',
         SAVE_PLAYLIST_MODE: 'SAVE_PLAYLIST_MODE',
         ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE: 'ASK_TO_SAVE_PLAYLIST_WHEN_OPENING_PLAYLIST_MODE',
+        ASK_TO_SAVE_PLAYLIST_WHEN_BACK_IN_HISTORY_MODE: 'ASK_TO_SAVE_PLAYLIST_WHEN_BACK_IN_HISTORY_MODE',
         ASK_TO_SAVE_PLAYLIST_WHEN_EXITING_MODE: 'ASK_TO_SAVE_PLAYLIST_WHEN_EXITING_MODE',
         MAIN_HELP_MODE: 'MAIN_HELP_MODE',
         MAIN_HELP_MODE_PAGE_2: 'MAIN_HELP_MODE_PAGE_2',