listpick 0.1.13.55__py3-none-any.whl → 0.1.13.56__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- listpick/listpick_app.py +87 -196
- listpick/ui/footer.py +47 -34
- listpick/utils/utils.py +24 -50
- {listpick-0.1.13.55.dist-info → listpick-0.1.13.56.dist-info}/METADATA +1 -1
- {listpick-0.1.13.55.dist-info → listpick-0.1.13.56.dist-info}/RECORD +9 -12
- listpick/listpick_app_1.py +0 -3250
- listpick/lpapp2.py +0 -3153
- listpick/ui/footer_1.py +0 -213
- {listpick-0.1.13.55.dist-info → listpick-0.1.13.56.dist-info}/WHEEL +0 -0
- {listpick-0.1.13.55.dist-info → listpick-0.1.13.56.dist-info}/entry_points.txt +0 -0
- {listpick-0.1.13.55.dist-info → listpick-0.1.13.56.dist-info}/licenses/LICENSE.txt +0 -0
- {listpick-0.1.13.55.dist-info → listpick-0.1.13.56.dist-info}/top_level.txt +0 -0
listpick/listpick_app.py
CHANGED
|
@@ -140,7 +140,6 @@ class Picker:
|
|
|
140
140
|
footer_string_refresh_function: Optional[Callable] = None,
|
|
141
141
|
footer_timer: float=1,
|
|
142
142
|
get_footer_string_startup=False,
|
|
143
|
-
unicode_char_width: bool = True,
|
|
144
143
|
|
|
145
144
|
colours_start: int =0,
|
|
146
145
|
colours_end: int =-1,
|
|
@@ -257,7 +256,7 @@ class Picker:
|
|
|
257
256
|
self.footer_string_refresh_function = footer_string_refresh_function
|
|
258
257
|
self.footer_timer = footer_timer
|
|
259
258
|
self.get_footer_string_startup = get_footer_string_startup,
|
|
260
|
-
|
|
259
|
+
|
|
261
260
|
|
|
262
261
|
|
|
263
262
|
self.colours_start = colours_start
|
|
@@ -313,16 +312,16 @@ class Picker:
|
|
|
313
312
|
self.debug_level = debug_level
|
|
314
313
|
|
|
315
314
|
|
|
315
|
+
|
|
316
|
+
|
|
316
317
|
self.initialise_picker_state(reset_colours=self.reset_colours)
|
|
317
318
|
|
|
318
319
|
|
|
319
320
|
# Note: We have to set the footer after initialising the picker state so that the footer can use the get_function_data method
|
|
320
|
-
|
|
321
|
-
self.
|
|
322
|
-
# self.footer = self.footer_options[self.footer_style]
|
|
323
|
-
|
|
324
|
-
self.footer = CompactFooter(self.stdscr, colours_start, self.get_function_data)
|
|
321
|
+
self.footer_options = [StandardFooter(self.stdscr, colours_start, self.get_function_data), CompactFooter(self.stdscr, colours_start, self.get_function_data), NoFooter(self.stdscr, colours_start, self.get_function_data)]
|
|
322
|
+
self.footer = self.footer_options[self.footer_style]
|
|
325
323
|
|
|
324
|
+
# self.footer = CompactFooter(self.stdscr, colours_start, self.get_function_data)
|
|
326
325
|
|
|
327
326
|
|
|
328
327
|
def calculate_section_sizes(self):
|
|
@@ -385,6 +384,7 @@ class Picker:
|
|
|
385
384
|
def initialise_picker_state(self, reset_colours=False) -> None:
|
|
386
385
|
""" Initialise state variables for the picker. These are: debugging and colours. """
|
|
387
386
|
|
|
387
|
+
|
|
388
388
|
if curses.has_colors() and self.colours != None:
|
|
389
389
|
# raise Exception("Terminal does not support color")
|
|
390
390
|
curses.start_color()
|
|
@@ -474,6 +474,7 @@ class Picker:
|
|
|
474
474
|
|
|
475
475
|
if len(self.indexed_items) > 0 and len(self.indexed_items) >= self.cursor_pos and len(self.indexed_items[0][1]) >= self.id_column:
|
|
476
476
|
self.cursor_pos_id = self.indexed_items[self.cursor_pos][1][self.id_column]
|
|
477
|
+
self.cursor_pos_prev = self.cursor_pos
|
|
477
478
|
|
|
478
479
|
self.items, self.header = self.refresh_function()
|
|
479
480
|
|
|
@@ -597,8 +598,6 @@ class Picker:
|
|
|
597
598
|
else:
|
|
598
599
|
self.cursor_pos = 0
|
|
599
600
|
|
|
600
|
-
# if self.display_infobox:
|
|
601
|
-
# self.infobox_picker = self.infobox(self.stdscr, self.infobox_items, self.infobox_title)
|
|
602
601
|
|
|
603
602
|
|
|
604
603
|
def move_column(self, direction: int) -> None:
|
|
@@ -658,13 +657,6 @@ class Picker:
|
|
|
658
657
|
pass
|
|
659
658
|
self.stdscr.refresh()
|
|
660
659
|
|
|
661
|
-
def draw_screen_wr(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
|
|
662
|
-
""" Try-except wrapper for the draw_screen_() method to prevent crashes when rapidly resizing the terminal. """
|
|
663
|
-
try:
|
|
664
|
-
self.draw_screen(self.indexed_items, self.highlights, clear=clear)
|
|
665
|
-
except:
|
|
666
|
-
self.logger.warning(f"draw_screen function error")
|
|
667
|
-
|
|
668
660
|
def draw_screen(self, indexed_items: list[Tuple[int, list[str]]], highlights: list[dict] = [{}], clear: bool = True) -> None:
|
|
669
661
|
""" Draw Picker screen. """
|
|
670
662
|
self.logger.debug("Draw screen.")
|
|
@@ -694,7 +686,7 @@ class Picker:
|
|
|
694
686
|
# rows = [v[1] for v in self.indexed_items] if len(self.indexed_items) else self.items
|
|
695
687
|
# Determine widths based only on the currently displayed indexed rows
|
|
696
688
|
rows = [v[1] for v in self.indexed_items[start_index:end_index]] if len(self.indexed_items) else self.items
|
|
697
|
-
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w
|
|
689
|
+
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
698
690
|
visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
|
|
699
691
|
visible_columns_total_width = sum(visible_column_widths) + len(self.separator)*(len(visible_column_widths)-1)
|
|
700
692
|
|
|
@@ -793,10 +785,10 @@ class Picker:
|
|
|
793
785
|
else:
|
|
794
786
|
cell_value = self.indexed_items[row][1][col] + self.separator
|
|
795
787
|
# cell_value = cell_value[:min(cell_width, cell_max_width)-len(self.separator)]
|
|
796
|
-
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)-len(self.separator)
|
|
788
|
+
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)-len(self.separator))
|
|
797
789
|
cell_value = cell_value + self.separator
|
|
798
790
|
# cell_value = cell_value
|
|
799
|
-
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width)
|
|
791
|
+
cell_value = truncate_to_display_width(cell_value, min(cell_width, cell_max_width))
|
|
800
792
|
# row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width))
|
|
801
793
|
self.stdscr.addstr(y, cell_pos, cell_value, curses.color_pair(self.colours_start+colour_pair_number) | curses.A_BOLD)
|
|
802
794
|
# Part of the cell is on screen
|
|
@@ -838,7 +830,7 @@ class Picker:
|
|
|
838
830
|
def draw_highlights(highlights: list[dict], idx: int, y: int, item: tuple[int, list[str]]):
|
|
839
831
|
self.logger.debug(f"function: draw_highlights()")
|
|
840
832
|
if len(highlights) == 0: return None
|
|
841
|
-
full_row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols
|
|
833
|
+
full_row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
842
834
|
row_str = full_row_str[self.leftmost_char:]
|
|
843
835
|
for highlight in highlights:
|
|
844
836
|
if "row" in highlight:
|
|
@@ -854,13 +846,13 @@ class Picker:
|
|
|
854
846
|
continue
|
|
855
847
|
|
|
856
848
|
elif type(highlight["field"]) == type(0) and highlight["field"] not in self.hidden_columns:
|
|
857
|
-
match = re.search(highlight["match"], truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], centre=False
|
|
849
|
+
match = re.search(highlight["match"], truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], centre=False), re.IGNORECASE)
|
|
858
850
|
if not match: continue
|
|
859
851
|
field_start = sum([width for i, width in enumerate(self.column_widths[:highlight["field"]]) if i not in self.hidden_columns]) + sum([1 for i in range(highlight["field"]) if i not in self.hidden_columns])*wcswidth(self.separator)
|
|
860
852
|
|
|
861
853
|
## We want to search the non-centred values but highlight the centred values.
|
|
862
854
|
if self.centre_in_cols:
|
|
863
|
-
tmp = truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], self.centre_in_cols
|
|
855
|
+
tmp = truncate_to_display_width(item[1][highlight["field"]], self.column_widths[highlight["field"]], self.centre_in_cols)
|
|
864
856
|
field_start += (len(tmp) - len(tmp.lstrip()))
|
|
865
857
|
|
|
866
858
|
highlight_start = field_start + match.start()
|
|
@@ -882,11 +874,11 @@ class Picker:
|
|
|
882
874
|
item = self.indexed_items[idx]
|
|
883
875
|
y = idx - start_index + self.top_space
|
|
884
876
|
|
|
885
|
-
|
|
877
|
+
row_str = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
|
|
886
878
|
# row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))
|
|
887
|
-
row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols
|
|
879
|
+
row_str_orig = format_row(item[1], self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
888
880
|
row_str_left_adj = clip_left(row_str_orig, self.leftmost_char)
|
|
889
|
-
row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width)
|
|
881
|
+
row_str = truncate_to_display_width(row_str_left_adj, min(w-self.startx, visible_columns_total_width))
|
|
890
882
|
# row_str = truncate_to_display_width(row_str, min(w-self.startx, visible_columns_total_width))[self.leftmost_char:]
|
|
891
883
|
|
|
892
884
|
## Display the standard row
|
|
@@ -899,7 +891,7 @@ class Picker:
|
|
|
899
891
|
|
|
900
892
|
# Higlight cursor cell and selected cells
|
|
901
893
|
if self.cell_cursor:
|
|
902
|
-
|
|
894
|
+
self.selected_cells_by_row = get_selected_cells_by_row(self.cell_selections)
|
|
903
895
|
if item[0] in self.selected_cells_by_row:
|
|
904
896
|
for j in self.selected_cells_by_row[item[0]]:
|
|
905
897
|
highlight_cell(idx, j, visible_column_widths, colour_pair_number=25)
|
|
@@ -979,8 +971,6 @@ class Picker:
|
|
|
979
971
|
else:
|
|
980
972
|
self.stdscr.addstr(0,w-3," ", curses.color_pair(self.colours_start+23) | curses.A_BOLD)
|
|
981
973
|
|
|
982
|
-
# self.stdscr.refresh()
|
|
983
|
-
|
|
984
974
|
## Display footer
|
|
985
975
|
if self.show_footer:
|
|
986
976
|
# self.footer = NoFooter(self.stdscr, self.colours_start, self.get_function_data)
|
|
@@ -995,77 +985,11 @@ class Picker:
|
|
|
995
985
|
self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
|
|
996
986
|
self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
|
|
997
987
|
|
|
998
|
-
|
|
999
|
-
self.stdscr.refresh()
|
|
1000
|
-
|
|
1001
988
|
## Display infobox
|
|
1002
989
|
if self.display_infobox:
|
|
1003
990
|
self.infobox(self.stdscr, message=self.infobox_items, title=self.infobox_title)
|
|
1004
991
|
# self.stdscr.timeout(2000) # timeout is set to 50 in order to get the infobox to be displayed so here we reset it to 2000
|
|
1005
|
-
# self.stdscr.refresh()
|
|
1006
992
|
|
|
1007
|
-
# if self.display_infobox:
|
|
1008
|
-
# # self.stdscr.refresh()
|
|
1009
|
-
# # self.infobox(self.stdscr, message=self.infobox_items, title=self.infobox_title)
|
|
1010
|
-
#
|
|
1011
|
-
# infobox_width, infobox_height = w//2, 3*h//5
|
|
1012
|
-
# infobox_x, infobox_y = w - (infobox_width + 4), 3
|
|
1013
|
-
# self.infobox_picker.stdscr.mvwin(infobox_y, infobox_x)
|
|
1014
|
-
# self.infobox_picker.stdscr.resize(infobox_height, infobox_width)
|
|
1015
|
-
# self.infobox_picker.run()
|
|
1016
|
-
# self.infobox_picker.stdscr.noutrefresh()
|
|
1017
|
-
# else:
|
|
1018
|
-
# # self.stdscr.noutrefresh()
|
|
1019
|
-
# pass
|
|
1020
|
-
#
|
|
1021
|
-
#
|
|
1022
|
-
# if not self.display_only:
|
|
1023
|
-
# curses.doupdate()
|
|
1024
|
-
# self.stdscr.refresh()
|
|
1025
|
-
# pass
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
# def infobox___(self, stdscr: curses.window, message: list =[], title: str ="Infobox", colours_end: int = 0, duration: int = 4):
|
|
1029
|
-
# """ Display non-interactive infobox window. """
|
|
1030
|
-
#
|
|
1031
|
-
# self.logger.info(f"function: infobox()")
|
|
1032
|
-
# h, w = stdscr.getmaxyx()
|
|
1033
|
-
# notification_width, notification_height = w//2, 3*h//5
|
|
1034
|
-
# message_width = notification_width-5
|
|
1035
|
-
#
|
|
1036
|
-
# notification_x, notification_y = w-(notification_width+4), 3
|
|
1037
|
-
# if not message: message = "!!"
|
|
1038
|
-
# if isinstance(message, str):
|
|
1039
|
-
# submenu_items = [" "+message[i*message_width:(i+1)*message_width] for i in range(len(message)//message_width+1)]
|
|
1040
|
-
# else:
|
|
1041
|
-
# submenu_items = message
|
|
1042
|
-
#
|
|
1043
|
-
# notification_remap_keys = {
|
|
1044
|
-
# curses.KEY_RESIZE: curses.KEY_F5,
|
|
1045
|
-
# 27: ord('q')
|
|
1046
|
-
# }
|
|
1047
|
-
# if len(submenu_items) > notification_height - 2:
|
|
1048
|
-
# submenu_items = submenu_items[:notification_height-3] + [f"{'....':^{notification_width}}"]
|
|
1049
|
-
# # while True:
|
|
1050
|
-
# h, w = stdscr.getmaxyx()
|
|
1051
|
-
#
|
|
1052
|
-
# submenu_win = self.stdscr.derwin(notification_height, notification_width, 3, w - (notification_width+4))
|
|
1053
|
-
# infobox_data = {
|
|
1054
|
-
# "items": submenu_items,
|
|
1055
|
-
# "colours": notification_colours,
|
|
1056
|
-
# "colours_start": self.notification_colours_start,
|
|
1057
|
-
# "disabled_keys": [ord('z'), ord('c')],
|
|
1058
|
-
# "show_footer": False,
|
|
1059
|
-
# "top_gap": 0,
|
|
1060
|
-
# "key_remappings": notification_remap_keys,
|
|
1061
|
-
# "display_only": True,
|
|
1062
|
-
# "hidden_columns": [],
|
|
1063
|
-
# "title": title,
|
|
1064
|
-
# "reset_colours": False,
|
|
1065
|
-
# }
|
|
1066
|
-
# submenu_win.noutrefresh()
|
|
1067
|
-
# OptionPicker = Picker(submenu_win, **infobox_data)
|
|
1068
|
-
# return OptionPicker
|
|
1069
993
|
|
|
1070
994
|
|
|
1071
995
|
def infobox(self, stdscr: curses.window, message: str ="", title: str ="Infobox", colours_end: int = 0, duration: int = 4) -> curses.window:
|
|
@@ -1208,7 +1132,6 @@ class Picker:
|
|
|
1208
1132
|
"debug": self.debug,
|
|
1209
1133
|
"debug_level": self.debug_level,
|
|
1210
1134
|
"reset_colours": self.reset_colours,
|
|
1211
|
-
"unicode_char_width": self.unicode_char_width,
|
|
1212
1135
|
}
|
|
1213
1136
|
return function_data
|
|
1214
1137
|
|
|
@@ -1307,7 +1230,7 @@ class Picker:
|
|
|
1307
1230
|
while True:
|
|
1308
1231
|
h, w = stdscr.getmaxyx()
|
|
1309
1232
|
|
|
1310
|
-
choose_opts_widths = get_column_widths(options
|
|
1233
|
+
choose_opts_widths = get_column_widths(options)
|
|
1311
1234
|
window_width = min(max(sum(choose_opts_widths) + 6, 50) + 6, w)
|
|
1312
1235
|
window_height = min(h//2, max(6, len(options)+3))
|
|
1313
1236
|
|
|
@@ -1462,8 +1385,6 @@ class Picker:
|
|
|
1462
1385
|
self.initialise_variables()
|
|
1463
1386
|
elif setting == "pc":
|
|
1464
1387
|
self.pin_cursor = not self.pin_cursor
|
|
1465
|
-
elif setting == "unicode":
|
|
1466
|
-
self.unicode_char_width = not self.unicode_char_width
|
|
1467
1388
|
|
|
1468
1389
|
elif setting.startswith("ft"):
|
|
1469
1390
|
if len(setting) > 2 and setting[2:].isnumeric():
|
|
@@ -1527,6 +1448,7 @@ class Picker:
|
|
|
1527
1448
|
self.draw_screen(self.indexed_items, self.highlights)
|
|
1528
1449
|
self.notification(self.stdscr, message=f"Theme {self.colour_theme_number} applied.")
|
|
1529
1450
|
|
|
1451
|
+
|
|
1530
1452
|
else:
|
|
1531
1453
|
self.user_settings = ""
|
|
1532
1454
|
return None
|
|
@@ -1550,6 +1472,7 @@ class Picker:
|
|
|
1550
1472
|
""" Toggle selection of item at index. """
|
|
1551
1473
|
self.logger.info(f"function: toggle_item()")
|
|
1552
1474
|
self.selections[index] = not self.selections[index]
|
|
1475
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1553
1476
|
|
|
1554
1477
|
def select_all(self) -> None:
|
|
1555
1478
|
""" Select all in indexed_items. """
|
|
@@ -1558,8 +1481,8 @@ class Picker:
|
|
|
1558
1481
|
self.selections[self.indexed_items[i][0]] = True
|
|
1559
1482
|
for i in self.cell_selections.keys():
|
|
1560
1483
|
self.cell_selections[i] = True
|
|
1561
|
-
|
|
1562
|
-
|
|
1484
|
+
|
|
1485
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1563
1486
|
|
|
1564
1487
|
def deselect_all(self) -> None:
|
|
1565
1488
|
""" Deselect all items in indexed_items. """
|
|
@@ -1568,7 +1491,7 @@ class Picker:
|
|
|
1568
1491
|
self.selections[i] = False
|
|
1569
1492
|
for i in self.cell_selections.keys():
|
|
1570
1493
|
self.cell_selections[i] = False
|
|
1571
|
-
self.
|
|
1494
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1572
1495
|
|
|
1573
1496
|
def handle_visual_selection(self, selecting:bool = True) -> None:
|
|
1574
1497
|
""" Toggle visual selection or deselection. """
|
|
@@ -1596,22 +1519,15 @@ class Picker:
|
|
|
1596
1519
|
xend = max(self.start_selection_col, self.selected_column)
|
|
1597
1520
|
for i in range(ystart, yend + 1):
|
|
1598
1521
|
if self.indexed_items[i][0] not in self.unselectable_indices:
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
self.selected_cells_by_row[row] = []
|
|
1602
|
-
|
|
1603
|
-
for col in range(xstart, xend+1):
|
|
1604
|
-
cell_index = (row, col)
|
|
1522
|
+
for j in range(xstart, xend+1):
|
|
1523
|
+
cell_index = (self.indexed_items[i][0], j)
|
|
1605
1524
|
self.cell_selections[cell_index] = True
|
|
1606
|
-
|
|
1607
|
-
self.selected_cells_by_row[row].append(col)
|
|
1608
|
-
# Remove duplicates
|
|
1609
|
-
self.selected_cells_by_row[row] = list(set(self.selected_cells_by_row[row]))
|
|
1610
|
-
|
|
1611
1525
|
self.start_selection = -1
|
|
1612
1526
|
self.end_selection = -1
|
|
1613
1527
|
self.is_selecting = False
|
|
1614
1528
|
|
|
1529
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1530
|
+
|
|
1615
1531
|
elif self.is_deselecting:
|
|
1616
1532
|
self.end_selection = self.indexed_items[self.cursor_pos][0]
|
|
1617
1533
|
self.end_selection = self.cursor_pos
|
|
@@ -1627,22 +1543,14 @@ class Picker:
|
|
|
1627
1543
|
xstart = min(self.start_selection_col, self.selected_column)
|
|
1628
1544
|
xend = max(self.start_selection_col, self.selected_column)
|
|
1629
1545
|
for i in range(ystart, yend + 1):
|
|
1630
|
-
row = self.indexed_items[i][0]
|
|
1631
1546
|
if self.indexed_items[i][0] not in self.unselectable_indices:
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
self.selected_cells_by_row[row].remove(col)
|
|
1636
|
-
except:
|
|
1637
|
-
pass
|
|
1638
|
-
cell_index = (row, col)
|
|
1639
|
-
self.cell_selections[cell_index] = False
|
|
1640
|
-
if self.selected_cells_by_row[row] == []:
|
|
1641
|
-
del self.selected_cells_by_row[row]
|
|
1642
|
-
|
|
1547
|
+
for j in range(xstart, xend+1):
|
|
1548
|
+
cell_index = (self.indexed_items[i][0], j)
|
|
1549
|
+
self.cell_selections[cell_index] = False
|
|
1643
1550
|
self.start_selection = -1
|
|
1644
1551
|
self.end_selection = -1
|
|
1645
1552
|
self.is_deselecting = False
|
|
1553
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1646
1554
|
|
|
1647
1555
|
def cursor_down(self, count=1) -> bool:
|
|
1648
1556
|
""" Move cursor down. """
|
|
@@ -1760,6 +1668,7 @@ class Picker:
|
|
|
1760
1668
|
if not acceptable_data_type:
|
|
1761
1669
|
break
|
|
1762
1670
|
if not acceptable_data_type:
|
|
1671
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
1763
1672
|
self.notification(self.stdscr, message="Error pasting data.")
|
|
1764
1673
|
return None
|
|
1765
1674
|
|
|
@@ -1870,7 +1779,6 @@ class Picker:
|
|
|
1870
1779
|
with self.data_lock:
|
|
1871
1780
|
self.items, self.header = tmp_items, tmp_header
|
|
1872
1781
|
self.data_ready = True
|
|
1873
|
-
self.draw_screen(self.indexed_items, self.highlights)
|
|
1874
1782
|
|
|
1875
1783
|
def save_input_history(self, file_path: str) -> bool:
|
|
1876
1784
|
""" Save input field history. Returns True if successful save. """
|
|
@@ -1917,7 +1825,7 @@ class Picker:
|
|
|
1917
1825
|
|
|
1918
1826
|
def get_word_list(self) -> list[str]:
|
|
1919
1827
|
""" Get a list of all words used in any cell of the picker. Used for completion in search/filter input_field. """
|
|
1920
|
-
self.logger.info(f"function:
|
|
1828
|
+
self.logger.info(f"function: infobox()")
|
|
1921
1829
|
translator = str.maketrans('', '', string.punctuation)
|
|
1922
1830
|
|
|
1923
1831
|
words = []
|
|
@@ -2018,7 +1926,8 @@ class Picker:
|
|
|
2018
1926
|
|
|
2019
1927
|
if self.display_only:
|
|
2020
1928
|
self.stdscr.refresh()
|
|
2021
|
-
|
|
1929
|
+
function_data = self.get_function_data()
|
|
1930
|
+
return [], "", function_data
|
|
2022
1931
|
|
|
2023
1932
|
# Main loop
|
|
2024
1933
|
|
|
@@ -2039,7 +1948,7 @@ class Picker:
|
|
|
2039
1948
|
initial_time = time.time()
|
|
2040
1949
|
|
|
2041
1950
|
self.draw_screen(self.indexed_items, self.highlights, clear=False)
|
|
2042
|
-
|
|
1951
|
+
|
|
2043
1952
|
self.refreshing_data = False
|
|
2044
1953
|
self.data_ready = False
|
|
2045
1954
|
|
|
@@ -2159,7 +2068,6 @@ class Picker:
|
|
|
2159
2068
|
options += [["rh", "Toggle row header"]]
|
|
2160
2069
|
options += [["modes", "Toggle modes"]]
|
|
2161
2070
|
options += [["ft", "Cycle through footer styles (accepts ft#)"]]
|
|
2162
|
-
options += [["unicode", "Toggle b/w using len and wcwidth to calculate char width."]]
|
|
2163
2071
|
options += [[f"s{i}", f"Select col. {i}"] for i in range(len(self.items[0]))]
|
|
2164
2072
|
options += [[f"!{i}", f"Toggle col. {i}"] for i in range(len(self.items[0]))]
|
|
2165
2073
|
options += [["ara", "Add empty row after cursor."]]
|
|
@@ -2224,31 +2132,11 @@ class Picker:
|
|
|
2224
2132
|
if len(self.indexed_items) > 0:
|
|
2225
2133
|
item_index = self.indexed_items[self.cursor_pos][0]
|
|
2226
2134
|
cell_index = (self.indexed_items[self.cursor_pos][0], self.selected_column)
|
|
2227
|
-
row, col = cell_index
|
|
2228
2135
|
selected_count = sum(self.selections.values())
|
|
2229
2136
|
if self.max_selected == -1 or selected_count >= self.max_selected:
|
|
2230
2137
|
self.toggle_item(item_index)
|
|
2231
2138
|
|
|
2232
2139
|
self.cell_selections[cell_index] = not self.cell_selections[cell_index]
|
|
2233
|
-
## Set self.selected_cells_by_row
|
|
2234
|
-
# If any cells in the current row are selected
|
|
2235
|
-
if row in self.selected_cells_by_row:
|
|
2236
|
-
# If the current cell is selected then remove it
|
|
2237
|
-
if col in self.selected_cells_by_row[row]:
|
|
2238
|
-
# If the current cell is the only cell in the row that is selected then remove the row from the dict
|
|
2239
|
-
if len(self.selected_cells_by_row[row]) == 1:
|
|
2240
|
-
|
|
2241
|
-
del self.selected_cells_by_row[row]
|
|
2242
|
-
# else remove only the index of the current cell
|
|
2243
|
-
else:
|
|
2244
|
-
self.selected_cells_by_row[row].remove(col)
|
|
2245
|
-
# If there are cells in the row that are selected then append the current cell to the row
|
|
2246
|
-
else:
|
|
2247
|
-
self.selected_cells_by_row[row].append(col)
|
|
2248
|
-
# Add the a list containing only the current column
|
|
2249
|
-
else:
|
|
2250
|
-
self.selected_cells_by_row[row] = [col]
|
|
2251
|
-
|
|
2252
2140
|
self.cursor_down()
|
|
2253
2141
|
elif self.check_key("select_all", key, self.keys_dict): # Select all (m or ctrl-a)
|
|
2254
2142
|
self.select_all()
|
|
@@ -2264,6 +2152,8 @@ class Picker:
|
|
|
2264
2152
|
if new_pos < len(self.indexed_items):
|
|
2265
2153
|
self.cursor_pos = new_pos
|
|
2266
2154
|
|
|
2155
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2156
|
+
|
|
2267
2157
|
elif self.check_key("cursor_bottom", key, self.keys_dict):
|
|
2268
2158
|
new_pos = len(self.indexed_items)-1
|
|
2269
2159
|
while True:
|
|
@@ -2271,7 +2161,12 @@ class Picker:
|
|
|
2271
2161
|
else: break
|
|
2272
2162
|
if new_pos < len(self.items) and new_pos >= 0:
|
|
2273
2163
|
self.cursor_pos = new_pos
|
|
2274
|
-
|
|
2164
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2165
|
+
# current_row = items_per_page - 1
|
|
2166
|
+
# if current_page + 1 == (len(self.indexed_items) + items_per_page - 1) // items_per_page:
|
|
2167
|
+
#
|
|
2168
|
+
# current_row = (len(self.indexed_items) +items_per_page - 1) % items_per_page
|
|
2169
|
+
# self.draw_screen(self.indexed_items, self.highlights)
|
|
2275
2170
|
elif self.check_key("enter", key, self.keys_dict):
|
|
2276
2171
|
self.logger.info(f"key_function enter")
|
|
2277
2172
|
# Print the selected indices if any, otherwise print the current index
|
|
@@ -2351,6 +2246,7 @@ class Picker:
|
|
|
2351
2246
|
if len(self.indexed_items) > 0:
|
|
2352
2247
|
current_index = self.indexed_items[self.cursor_pos][0]
|
|
2353
2248
|
sort_items(self.indexed_items, sort_method=self.columns_sort_method[self.sort_column], sort_column=self.sort_column, sort_reverse=self.sort_reverse[self.sort_column]) # Re-sort self.items based on new column
|
|
2249
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2354
2250
|
self.cursor_pos = [row[0] for row in self.indexed_items].index(current_index)
|
|
2355
2251
|
self.logger.info(f"key_function cycle_sort_order. (sort_column, sort_method, sort_reverse) = ({self.sort_column}, {self.columns_sort_method[self.sort_column]}, {self.sort_reverse[self.sort_column]})")
|
|
2356
2252
|
elif self.check_key("col_select", key, self.keys_dict):
|
|
@@ -2374,7 +2270,7 @@ class Picker:
|
|
|
2374
2270
|
|
|
2375
2271
|
## Scroll with column select
|
|
2376
2272
|
rows = self.get_visible_rows()
|
|
2377
|
-
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w
|
|
2273
|
+
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2378
2274
|
visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
|
|
2379
2275
|
column_set_width = sum(visible_column_widths)+len(self.separator)*len(visible_column_widths)
|
|
2380
2276
|
start_of_cell = sum(visible_column_widths[:self.selected_column])+len(self.separator)*self.selected_column
|
|
@@ -2401,7 +2297,8 @@ class Picker:
|
|
|
2401
2297
|
|
|
2402
2298
|
## Scroll with column select
|
|
2403
2299
|
rows = self.get_visible_rows()
|
|
2404
|
-
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w
|
|
2300
|
+
self.column_widths = get_column_widths(rows, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2301
|
+
|
|
2405
2302
|
visible_column_widths = [c for i,c in enumerate(self.column_widths) if i not in self.hidden_columns]
|
|
2406
2303
|
column_set_width = sum(visible_column_widths)+len(self.separator)*len(visible_column_widths)
|
|
2407
2304
|
start_of_cell = sum(visible_column_widths[:self.selected_column])+len(self.separator)*self.selected_column
|
|
@@ -2416,13 +2313,18 @@ class Picker:
|
|
|
2416
2313
|
self.leftmost_char = start_of_cell
|
|
2417
2314
|
|
|
2418
2315
|
self.leftmost_char = max(0, min(column_set_width - display_width + 5, self.leftmost_char))
|
|
2419
|
-
|
|
2316
|
+
#
|
|
2420
2317
|
elif self.check_key("scroll_right", key, self.keys_dict):
|
|
2421
2318
|
self.logger.info(f"key_function scroll_right")
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2319
|
+
rows = self.get_visible_rows()
|
|
2320
|
+
longest_row_str_len = 0
|
|
2321
|
+
for i in range(len(rows)):
|
|
2322
|
+
item = rows[i]
|
|
2323
|
+
row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)[self.leftmost_char:]
|
|
2324
|
+
if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
|
|
2325
|
+
|
|
2326
|
+
if longest_row_str_len >= w-self.startx:
|
|
2327
|
+
self.leftmost_char = self.leftmost_char+5
|
|
2426
2328
|
|
|
2427
2329
|
elif self.check_key("scroll_left", key, self.keys_dict):
|
|
2428
2330
|
self.logger.info(f"key_function scroll_left")
|
|
@@ -2439,7 +2341,7 @@ class Picker:
|
|
|
2439
2341
|
rows = self.get_visible_rows()
|
|
2440
2342
|
for i in range(len(rows)):
|
|
2441
2343
|
item = rows[i]
|
|
2442
|
-
row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols
|
|
2344
|
+
row_str = format_row(item, self.hidden_columns, self.column_widths, self.separator, self.centre_in_cols)
|
|
2443
2345
|
if len(row_str) > longest_row_str_len: longest_row_str_len=len(row_str)
|
|
2444
2346
|
# for i in range(len(self.indexed_items)):
|
|
2445
2347
|
# item = self.indexed_items[i]
|
|
@@ -2510,37 +2412,44 @@ class Picker:
|
|
|
2510
2412
|
|
|
2511
2413
|
# elif self.check_key("increase_lines_per_page", key, self.keys_dict):
|
|
2512
2414
|
# self.items_per_page += 1
|
|
2415
|
+
# self.draw_screen(self.indexed_items, self.highlights)
|
|
2513
2416
|
# elif self.check_key("decrease_lines_per_page", key, self.keys_dict):
|
|
2514
2417
|
# if self.items_per_page > 1:
|
|
2515
2418
|
# self.items_per_page -= 1
|
|
2516
|
-
|
|
2419
|
+
# self.draw_screen(self.indexed_items, self.highlights)
|
|
2517
2420
|
elif self.check_key("decrease_column_width", key, self.keys_dict):
|
|
2518
2421
|
self.logger.info(f"key_function decrease_column_width")
|
|
2519
2422
|
if self.max_column_width > 10:
|
|
2520
2423
|
self.max_column_width -= 10
|
|
2521
2424
|
# self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=2)
|
|
2425
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2522
2426
|
elif self.check_key("increase_column_width", key, self.keys_dict):
|
|
2523
2427
|
self.logger.info(f"key_function increase_column_width")
|
|
2524
2428
|
if self.max_column_width < 1000:
|
|
2525
2429
|
self.max_column_width += 10
|
|
2526
2430
|
# self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2431
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2527
2432
|
elif self.check_key("visual_selection_toggle", key, self.keys_dict):
|
|
2528
2433
|
self.logger.info(f"key_function visual_selection_toggle")
|
|
2529
2434
|
self.handle_visual_selection()
|
|
2435
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2530
2436
|
|
|
2531
2437
|
elif self.check_key("visual_deselection_toggle", key, self.keys_dict):
|
|
2532
2438
|
self.logger.info(f"key_function visual_deselection_toggle")
|
|
2533
2439
|
self.handle_visual_selection(selecting=False)
|
|
2440
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2534
2441
|
|
|
2535
2442
|
elif key == curses.KEY_RESIZE: # Terminal resize signal
|
|
2536
2443
|
|
|
2537
2444
|
self.calculate_section_sizes()
|
|
2538
|
-
self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w
|
|
2445
|
+
self.column_widths = get_column_widths(self.items, header=self.header, max_column_width=self.max_column_width, number_columns=self.number_columns, max_total_width=w)
|
|
2539
2446
|
|
|
2447
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2540
2448
|
|
|
2541
2449
|
|
|
2542
2450
|
elif self.check_key("filter_input", key, self.keys_dict):
|
|
2543
2451
|
self.logger.info(f"key_function filter_input")
|
|
2452
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2544
2453
|
usrtxt = f"{self.filter_query} " if self.filter_query else ""
|
|
2545
2454
|
field_end_f = lambda: self.stdscr.getmaxyx()[1]-38 if self.show_footer else lambda: self.stdscr.getmaxyx()[1]-3
|
|
2546
2455
|
if self.show_footer and self.footer.height >= 2: field_end_f = lambda: self.stdscr.getmaxyx()[1]-38
|
|
@@ -2585,6 +2494,7 @@ class Picker:
|
|
|
2585
2494
|
|
|
2586
2495
|
elif self.check_key("search_input", key, self.keys_dict):
|
|
2587
2496
|
self.logger.info(f"key_function search_input")
|
|
2497
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2588
2498
|
usrtxt = f"{self.search_query} " if self.search_query else ""
|
|
2589
2499
|
field_end_f = lambda: self.stdscr.getmaxyx()[1]-38 if self.show_footer else lambda: self.stdscr.getmaxyx()[1]-3
|
|
2590
2500
|
if self.show_footer and self.footer.height >= 3: field_end_f = lambda: self.stdscr.getmaxyx()[1]-38
|
|
@@ -2692,6 +2602,7 @@ class Picker:
|
|
|
2692
2602
|
# self.mode_index = 0
|
|
2693
2603
|
# self.highlights = [highlight for highlight in self.highlights if "type" not in highlight or highlight["type"] != "search" ]
|
|
2694
2604
|
# continue
|
|
2605
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2695
2606
|
|
|
2696
2607
|
elif self.check_key("opts_input", key, self.keys_dict):
|
|
2697
2608
|
self.logger.info(f"key_function opts_input")
|
|
@@ -2930,12 +2841,9 @@ class Picker:
|
|
|
2930
2841
|
self.stdscr.clear()
|
|
2931
2842
|
self.stdscr.refresh()
|
|
2932
2843
|
self.initialise_variables()
|
|
2844
|
+
self.draw_screen(self.indexed_items, self.highlights)
|
|
2933
2845
|
|
|
2934
2846
|
|
|
2935
|
-
# The refresh symbol colour is not updated when the data is retrieved so remains white until a key is pressed.
|
|
2936
|
-
# if key != -1:
|
|
2937
|
-
# self.draw_screen(self.indexed_items, self.highlights, clear=clear_screen)
|
|
2938
|
-
|
|
2939
2847
|
|
|
2940
2848
|
self.draw_screen(self.indexed_items, self.highlights, clear=clear_screen)
|
|
2941
2849
|
|
|
@@ -3177,28 +3085,21 @@ def main() -> None:
|
|
|
3177
3085
|
pass
|
|
3178
3086
|
|
|
3179
3087
|
function_data["colour_theme_number"] = 3
|
|
3180
|
-
function_data["modes"] = [
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
]
|
|
3195
|
-
highlights = [
|
|
3196
|
-
{
|
|
3197
|
-
"field": 1,
|
|
3198
|
-
"match": "a",
|
|
3199
|
-
"color": 8,
|
|
3200
|
-
}
|
|
3201
|
-
]
|
|
3088
|
+
# function_data["modes"] = [
|
|
3089
|
+
# {
|
|
3090
|
+
# 'filter': '',
|
|
3091
|
+
# 'sort': 0,
|
|
3092
|
+
# 'name': 'All',
|
|
3093
|
+
# },
|
|
3094
|
+
# {
|
|
3095
|
+
# 'filter': '--2 miss',
|
|
3096
|
+
# 'name': 'miss',
|
|
3097
|
+
# },
|
|
3098
|
+
# {
|
|
3099
|
+
# 'filter': '--2 mp4',
|
|
3100
|
+
# 'name': 'mp4',
|
|
3101
|
+
# },
|
|
3102
|
+
# ]
|
|
3202
3103
|
function_data["cell_cursor"] = True
|
|
3203
3104
|
function_data["display_modes"] = True
|
|
3204
3105
|
function_data["centre_in_cols"] = True
|
|
@@ -3209,19 +3110,9 @@ def main() -> None:
|
|
|
3209
3110
|
function_data["centre_in_terminal_vertical"] = True
|
|
3210
3111
|
function_data["highlight_full_row"] = True
|
|
3211
3112
|
function_data["pin_cursor"] = True
|
|
3212
|
-
function_data["display_infobox"] = True
|
|
3213
|
-
function_data["infobox_items"] = [["1"], ["2"], ["3"]]
|
|
3214
|
-
function_data["infobox_title"] = "Title"
|
|
3215
|
-
function_data["footer_string"] = "Title"
|
|
3216
|
-
function_data["highlights"] = highlights
|
|
3217
|
-
function_data["show_footer"] = False
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
3113
|
# function_data["debug"] = True
|
|
3221
3114
|
# function_data["debug_level"] = 1
|
|
3222
3115
|
stdscr = start_curses()
|
|
3223
|
-
# h, w = stdscr.getmaxyx()
|
|
3224
|
-
# win = stdscr.derwin(h, w//2, 0, 0)
|
|
3225
3116
|
try:
|
|
3226
3117
|
# Run the Picker
|
|
3227
3118
|
# h, w = stdscr.getmaxyx()
|