Skip to content

Commit cc40c71

Browse files
committed
unlimited chars, not A-F, A-B
1 parent 92e26bd commit cc40c71

File tree

2 files changed

+136
-62
lines changed

2 files changed

+136
-62
lines changed

pyradio/radio.py

+15-20
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,6 @@ def _show_theme_help(self):
11551155
self._show_help(txt, mode_to_set=self.ws.THEME_HELP_MODE, caption=' Themes Help ')
11561156

11571157
def _show_search_help(self):
1158-
self.search.restore_data = [ self.search.string, self.search._curs_pos ]
11591158
if platform.lower().startswith('darwin'):
11601159
txt = """Left| / |Right |Move to next / previous character.
11611160
HOME|,|^A| / |END|,|^E |Move to start / end of line.
@@ -1186,7 +1185,6 @@ def _show_search_help(self):
11861185
self._show_help(txt, mode_to_set=self.ws.SEARCH_HELP_MODE, caption=' Search Help ')
11871186

11881187
def _show_line_editor_help(self):
1189-
#self.search.restore_data = [ self.search.string, self.search._curs_pos ]
11901188
if platform.lower().startswith('darwin'):
11911189
txt = """Left| / |Right |Move to next / previous character.
11921190
HOME|,|^A| / |END|,|^E |Move to start / end of line.
@@ -2083,24 +2081,21 @@ def keypress(self, char):
20832081
return
20842082

20852083
elif char in (ord('t'), ) and \
2086-
self.ws.operation_mode not in \
2087-
(self.ws.EDIT_STATION_MODE, self.ws.ADD_STATION_MODE) and \
2088-
self.ws.operation_mode not in self.ws.PASSIVE_WINDOWS:
2089-
# only open it on main modes
2090-
if self.ws.window_mode != self.ws.THEME_MODE and \
2091-
self.ws.operation_mode <= self.ws.SEARCH_PLAYLIST_MODE and \
2092-
not self.is_search_mode(self.ws.operation_mode):
2093-
self.jumpnr = ''
2094-
self._random_requested = False
2095-
self._config_win = None
2096-
self.theme_forced_selection = None
2097-
if self.ws.operation_mode == self.ws.NORMAL_MODE:
2098-
self.selections[self.ws.operation_mode] = [self.selection, self.startPos, self.playing, self.stations]
2099-
#self.ws.previous_operation_mode = self.ws.operation_mode
2100-
#self.ws.operation_mode = self.ws.window_mode = self.ws.THEME_MODE
2101-
self.ws.operation_mode = self.ws.THEME_MODE
2102-
self._show_theme_selector()
2103-
return
2084+
self.ws.operation_mode not in (self.ws.EDIT_STATION_MODE,
2085+
self.ws.ADD_STATION_MODE, self.ws.THEME_MODE) and \
2086+
self.ws.operation_mode not in self.ws.PASSIVE_WINDOWS and \
2087+
not self.is_search_mode(self.ws.operation_mode):
2088+
self.jumpnr = ''
2089+
self._random_requested = False
2090+
self._config_win = None
2091+
self.theme_forced_selection = None
2092+
if self.ws.operation_mode == self.ws.NORMAL_MODE:
2093+
self.selections[self.ws.operation_mode] = [self.selection, self.startPos, self.playing, self.stations]
2094+
#self.ws.previous_operation_mode = self.ws.operation_mode
2095+
#self.ws.operation_mode = self.ws.window_mode = self.ws.THEME_MODE
2096+
self.ws.operation_mode = self.ws.THEME_MODE
2097+
self._show_theme_selector()
2098+
return
21042099

21052100
elif char == ord('P') and self.ws.operation_mode in \
21062101
(self.ws.NORMAL_MODE, self.ws.PLAYLIST_MODE):

pyradio/simple_curses_widgets.py

+121-42
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class SimpleCursesLineEdit(object):
6262
_auto_width = 1
6363

6464
""" string to redisplay after exiting help """
65-
restore_data = []
65+
_restore_data = []
6666

6767
log = None
6868
_log_file = ''
@@ -233,11 +233,6 @@ def _prepare_to_show(self):
233233
self._edit_win = curses.newwin(1, maxX - len(self._disp_caption), self.y, self.x + len(self._disp_caption))
234234

235235
maxY, maxX = self._edit_win.getmaxyx()
236-
#self._caption_win.bkgd('*', curses.A_REVERSE)
237-
#if self._boxed:
238-
# self._max_width = maxX - 1
239-
#else:
240-
# self._max_width = maxX
241236

242237
def refreshEditWindow(self, opening=False):
243238
if self._focused:
@@ -248,13 +243,13 @@ def refreshEditWindow(self, opening=False):
248243
else:
249244
active_edit_color = self.caption_color
250245
self._edit_win.erase()
251-
#self._edit_win.bkgd('-', self.edit_color)
252246
if opening:
253-
if self.restore_data:
254-
self._string = self.restore_data[0]
255-
self._curs_pos = self.restore_data[1]
256-
self._edit_win.addstr(0, 0, self._string, active_edit_color)
257-
self.restore_data = []
247+
if self._restore_data:
248+
self._string = self._restore_data[0]
249+
self._curs_pos = self._restore_data[1]
250+
self._first = self._restore_data[2]
251+
self._edit_win.addstr(0, 0, self._string[self._first:self._first+self._max_chars_to_display], active_edit_color)
252+
self._restore_data = []
258253
else:
259254
self._curs_pos = 0
260255
else:
@@ -266,6 +261,7 @@ def refreshEditWindow(self, opening=False):
266261
self.log(' - curs_pos = {}\n'.format(self._curs_pos))
267262
if self.focused:
268263
self._edit_win.chgat(0, self._curs_pos, 1, self.cursor_color)
264+
logger.error('curs = {}'.format(self._curs_pos))
269265
logger.error('DE string length = {}'.format(len(self.string)))
270266

271267
self._edit_win.refresh()
@@ -307,6 +303,26 @@ def show(self, parent_win, **kwargs):
307303
self._caption_win.refresh()
308304
self.refreshEditWindow(opening)
309305

306+
def _delete_char(self):
307+
if self._first + self._curs_pos < len(self._string):
308+
self._string = self._string[:self._first + self._curs_pos] + self._string[self._first + self._curs_pos+1:]
309+
if self._first + self._max_chars_to_display > len(self.string):
310+
if self._first > 0:
311+
self._first -= 1
312+
313+
def _backspace_char(self):
314+
if self._first + self._curs_pos > 0:
315+
self._string = self._string[:self._first + self._curs_pos-1] + self._string[self._first + self._curs_pos:]
316+
if len(self.string) < self._max_chars_to_display:
317+
self._first = 0
318+
if self._curs_pos > 0:
319+
self._curs_pos -= 1
320+
elif self._first + self._max_chars_to_display >= len(self.string):
321+
self._first -= 1
322+
else:
323+
if self._curs_pos > 0:
324+
self._curs_pos -= 1
325+
310326
def keypress(self, win, char):
311327
"""
312328
returns:
@@ -331,7 +347,7 @@ def keypress(self, win, char):
331347
if platform.startswith('win'):
332348
if char == 420:
333349
""" A-D, clear to end of line """
334-
self.string = self._string[:self._curs_pos]
350+
self.string = self._string[:self._first + self._curs_pos]
335351
self.refreshEditWindow()
336352
return 1
337353
elif char == 422:
@@ -357,6 +373,7 @@ def keypress(self, win, char):
357373

358374
if char in (ord('?'), ):
359375
# display help
376+
self._restore_data = [ self.string, self._curs_pos, self._first ]
360377
return 2
361378
elif char in (curses.KEY_ENTER, ord('\n'), ord('\r')):
362379
""" ENTER """
@@ -380,61 +397,119 @@ def keypress(self, win, char):
380397
self.log(' *** char = {}\n'.format(char))
381398
if char in (ord('d'), ):
382399
""" A-D, clear to end of line """
383-
self.string = self._string[:self._curs_pos]
400+
if self.string:
401+
self.string = self._string[:self._first + self._curs_pos]
384402
elif char in (ord('f'), ):
385403
""" A-F, move to next word """
386404
pos = len(self._string)
387-
for n in range(self._curs_pos + 1, len(self._string)):
405+
for n in range(self._first + self._curs_pos + 1, len(self._string)):
388406
if self._string[n] in word_delim:
389407
pos = n
390408
break
391-
self._curs_pos = pos
409+
if pos == len(self._string):
410+
# word delimiter not found
411+
self._curs_pos = pos - self._first
412+
self._first = len(self.string) - self._max_chars_to_display
413+
if self._first < 0:
414+
self._first = 0
415+
else:
416+
# word delimiter found
417+
if len(self.string) < self._max_chars_to_display or \
418+
pos < self._first + self._max_chars_to_display:
419+
# pos is on screen
420+
self._curs_pos = pos - self._first + 1
421+
else:
422+
# pos is not on screen
423+
logger.error('DE 1 pos = {0}, len = {1}, max = {2}'.format(pos, len(self.string), self._max_chars_to_display))
424+
self._first = pos
425+
self._curs_pos = 1
426+
pos = 0
427+
while len(self.string) - (self._first + pos + 1) < self._max_chars_to_display:
428+
pos -= 1
429+
self._first = self._first + pos + 1
430+
self._curs_pos = self._curs_pos + abs(pos) - 1
431+
logger.error('DE 2 pos = {0}, len = {1}, max = {2}'.format(pos, len(self.string), self._max_chars_to_display))
432+
392433
elif char in (ord('b'), ):
393434
""" A-B, move to previous word """
394435
pos = 0
395-
for n in range(self._curs_pos - 1, 0, -1):
436+
for n in range(self._first + self._curs_pos - 1, 0, -1):
396437
if self._string[n] in word_delim:
397438
pos = n
398439
break
399-
self._curs_pos = pos
440+
if pos == 0:
441+
self._curs_pos = pos
442+
self._first = 0
443+
else:
444+
pass
400445
else:
401446
return 1
402447
elif char in (curses.KEY_RIGHT, ):
403448
""" KEY_RIGHT """
404-
self._curs_pos += 1
405-
if len(self._string) < self._curs_pos:
406-
self._curs_pos = len(self._string)
449+
if self.string:
450+
logger.error('DE max = {0}, curs = {1}, first = {2}'.format(self._max_chars_to_display, self._curs_pos, self._first))
451+
if len(self.string) < self._max_chars_to_display:
452+
self._curs_pos += 1
453+
logger.error('DE 1 curs increased = {}'.format(self._curs_pos))
454+
if self._curs_pos > len(self.string):
455+
self._curs_pos = len(self.string)
456+
else:
457+
if len(self._string) < self._first + self._curs_pos:
458+
self._curs_pos = len(self._string) - self._max_chars_to_display
459+
logger.error('DE 2 curs modified = {}'.format(self._curs_pos))
460+
else:
461+
if self._curs_pos == self._max_chars_to_display:
462+
if len(self._string) > self._first + self._curs_pos:
463+
self._first += 1
464+
logger.error('DE 3 first increased = {}'.format(self._first))
465+
else:
466+
self._curs_pos += 1
467+
logger.error('DE 4 curs increased = {}'.format(self._curs_pos))
407468
elif char in (curses.KEY_LEFT, ):
408469
""" KEY_LEFT """
409-
self._curs_pos -= 1
410-
if self._curs_pos < 0:
411-
self._curs_pos = 0
470+
if self.string:
471+
if len(self.string) < self._max_chars_to_display:
472+
self._curs_pos -= 1
473+
if self._curs_pos < 0:
474+
self._curs_pos = 0
475+
else:
476+
if self._curs_pos == 0:
477+
self._first -= 1
478+
if self._first < 0:
479+
self._first = 0
480+
else:
481+
self._curs_pos -= 1
412482
elif char in (curses.KEY_HOME, curses.ascii.SOH):
413483
""" KEY_HOME, ^A """
414484
self._curs_pos = 0
415485
self._first = 0
416486
elif char in (curses.KEY_END, curses.ascii.ENQ):
417487
""" KEY_END, ^E """
418-
self._curs_pos = len(self._string)
419-
self._first = len(self.string) - self._max_chars_to_display
420-
if self._first < 0:
421-
self._first = 0
488+
if self.string:
489+
self._curs_pos = len(self._string)
490+
if self._curs_pos > self._max_chars_to_display:
491+
self._curs_pos = self._max_chars_to_display
492+
self._first = len(self.string) - self._max_chars_to_display
493+
if self._first < 0:
494+
self._first = 0
422495
elif char in (curses.ascii.ETB, ):
423496
""" ^W, clear to start of line """
424-
self.string = self._string[self._curs_pos:]
425-
self._curs_pos = 0
497+
if self.string:
498+
self.string = self._string[self._first + self._curs_pos:]
499+
self._curs_pos = 0
500+
self._first = 0
426501
elif char in (curses.ascii.NAK, ):
427502
""" ^U, clear line """
428503
self.string = ''
504+
self._curs_pos = self._first = 0
429505
elif char in (curses.KEY_DC, curses.ascii.EOT):
430506
""" DEL key, ^D """
431-
if self._curs_pos < len(self._string):
432-
self._string = self._string[:self._curs_pos] + self._string[self._curs_pos+1:]
507+
if self.string:
508+
self._delete_char()
433509
elif char in (curses.KEY_BACKSPACE, curses.ascii.BS,127):
434510
""" KEY_BACKSPACE """
435-
if self._curs_pos > 0:
436-
self._string = self._string[:self._curs_pos-1] + self._string[self._curs_pos:]
437-
self._curs_pos -= 1
511+
if self.string:
512+
self._backspace_char()
438513
elif char in (curses.KEY_UP, curses.ascii.DLE):
439514
""" KEY_UP, ^N """
440515
if self._key_up_function_handler is not None:
@@ -494,7 +569,8 @@ def keypress(self, win, char):
494569
curses.ungetch(char)
495570
elif char in (curses.ascii.VT, ):
496571
""" Ctrl-K - delete to end of line """
497-
self._string = self._string[:self._curs_pos]
572+
if self.string:
573+
self._string = self._string[:self._first + self._curs_pos]
498574
elif 0<= char <=31:
499575
pass
500576
else:
@@ -504,24 +580,26 @@ def keypress(self, win, char):
504580
if len(self._string) == self._max_chars_to_display:
505581
logger.error('DE max width reached {0} - {1}'.format(len(self._string), self._max_chars_to_display))
506582
#self._first += 1
507-
return 1
583+
# return 1
508584
if version_info < (3, 0):
509585
if 32 <= char < 127:
510586
# accept only ascii characters
511-
if len(self._string) == self._curs_pos:
587+
if len(self._string) == self._first + self._curs_pos:
512588
self._string += chr(char)
513589
else:
514-
self._string = self._string[:self._curs_pos] + chr(char) + self._string[self._curs_pos:]
515-
self._curs_pos += 1
590+
self._string = self._string[:self._first + self._curs_pos] + chr(char) + self._string[self._first + self._curs_pos:]
516591
else:
517592
if platform.startswith('win'):
518593
char = chr(char)
519594
else:
520595
char = self._get_char(win, char)
521-
if len(self._string) == self._curs_pos:
596+
if len(self._string) == self._first + self._curs_pos:
522597
self._string += char
523598
else:
524-
self._string = self._string[:self._curs_pos] + char + self._string[self._curs_pos:]
599+
self._string = self._string[:self._first + self._curs_pos] + char + self._string[self._first + self._curs_pos:]
600+
if self._curs_pos == self._max_chars_to_display:
601+
self._first += 1
602+
else:
525603
self._curs_pos += 1
526604

527605
self.refreshEditWindow()
@@ -563,6 +641,7 @@ def get_check_next_byte():
563641
else:
564642
buf = bytearray(bytes)
565643
out = self._decode_string(buf)
644+
logger.error('de out = "{0}", len = {1}'.format(out, len(out)))
566645
#out = buf.decode('utf-8')
567646
return out
568647

0 commit comments

Comments
 (0)