@@ -472,6 +472,7 @@ local function toggle_choice(get_ordered_data_fn)
472472 get_enabled_button_token (ENABLED_PEN_LEFT , DISABLED_PEN_LEFT ),
473473 get_enabled_button_token (ENABLED_PEN_CENTER , DISABLED_PEN_CENTER ),
474474 get_enabled_button_token (ENABLED_PEN_RIGHT , DISABLED_PEN_RIGHT ),
475+ ' ' ,
475476 },
476477 }
477478end
@@ -562,6 +563,7 @@ function Spreadsheet:init()
562563 sort_stack = {},
563564 sort_order = {}, -- list of indices into filtered_unit_ids (or cache.filtered_units)
564565 cache = {}, -- cached pointers; reset at end of frame
566+ cur_col = nil ,
565567 refresh_units = true ,
566568 refresh_headers = true ,
567569 }
@@ -718,6 +720,9 @@ function Spreadsheet:init()
718720 self .shared .sort_stack [1 ] = {col = self .subviews .name , rev = false }
719721 self .shared .sort_stack [2 ] = {col = self .subviews .favorites , rev = false }
720722
723+ -- set initial selection
724+ self :set_cur_col (self .subviews .favorites )
725+
721726 self .namelist = self .subviews .name .subviews .col_list
722727 self :addviews {
723728 widgets .Scrollbar {
@@ -730,6 +735,16 @@ function Spreadsheet:init()
730735 self .namelist :setFocus (true )
731736end
732737
738+ local CURSOR_PEN = dfhack .pen .parse {fg = COLOR_GREY , bg = COLOR_CYAN }
739+
740+ function Spreadsheet :set_cur_col (col )
741+ if self .shared .cur_col then
742+ self .shared .cur_col .subviews .col_list .cursor_pen = COLOR_LIGHTCYAN
743+ end
744+ self .shared .cur_col = col
745+ col .subviews .col_list .cursor_pen = CURSOR_PEN
746+ end
747+
733748function Spreadsheet :zoom_to_unit ()
734749 local idx = self .namelist :getSelected ()
735750 if not idx then return end
@@ -739,25 +754,62 @@ function Spreadsheet:zoom_to_unit()
739754 xyz2pos (dfhack .units .getPosition (unit )), true , true )
740755end
741756
742- -- TODO these are dependent on having a column cursor
743757function Spreadsheet :zoom_to_col_source ()
744- -- TODO
758+ if not self .shared .cur_col or not self .shared .cur_col .zoom_fn then return end
759+ self .shared .cur_col .zoom_fn ()
745760end
746761
747762function Spreadsheet :sort_by_current_col ()
748- -- TODO
763+ if not self .shared .cur_col then return end
764+ self .shared .cur_col :sort (true )
749765end
750766
751767function Spreadsheet :hide_current_col ()
752- -- TODO
768+ if not self .shared .cur_col then return end
769+ self .shared .cur_col :hide_column ()
753770end
754771
755772function Spreadsheet :hide_current_col_group ()
756- -- TODO
773+ if not self .shared .cur_col then return end
774+ self .shared .cur_col :hide_group ()
757775end
758776
777+ -- utf8-ize and, if needed, quote and escape
778+ local function make_csv_cell (fmt , ...)
779+ local str = fmt :format (... )
780+ str = dfhack .df2utf (str )
781+ if str :find (' [,"]' ) then
782+ str = str :gsub (' "' , ' ""' )
783+ str = (' "%s"' ):format (str )
784+ end
785+ return str
786+ end
787+
788+ -- exports visible data, in the current sort, to a .csv file
759789function Spreadsheet :export ()
760- -- TODO
790+ local file = io.open (' manipulator.csv' , ' a+' )
791+ if not file then
792+ dfhack .printerr (' could not open export file: manipulator.csv' )
793+ return
794+ end
795+ file :write (make_csv_cell (' %s,' , self .subviews .name .label ))
796+ for _ , col in ipairs (self .cols .subviews ) do
797+ if col .hidden then goto continue end
798+ file :write (make_csv_cell (' %s/%s,' , col .group , col .label ))
799+ :: continue::
800+ end
801+ file :write (NEWLINE )
802+ for row = 1 ,# self .shared .filtered_unit_ids do
803+ file :write (make_csv_cell (' %s' , self .subviews .name :get_sorted_data (row )))
804+ file :write (' ,' )
805+ for _ , col in ipairs (self .cols .subviews ) do
806+ if col .hidden then goto continue end
807+ file :write (make_csv_cell (' %s,' , col :get_sorted_data (row ) or ' ' ))
808+ :: continue::
809+ end
810+ file :write (NEWLINE )
811+ end
812+ file :close ()
761813end
762814
763815function Spreadsheet :jump_to_group (group )
@@ -1107,7 +1159,6 @@ function Manipulator:init()
11071159 label = ' Sort/reverse sort' ,
11081160 key = ' CUSTOM_SHIFT_S' ,
11091161 on_activate = function () self .subviews .sheet :sort_by_current_col () end ,
1110- enabled = false ,
11111162 },
11121163 widgets .HotkeyLabel {
11131164 frame = {b = 2 , l = 22 },
@@ -1122,23 +1173,20 @@ function Manipulator:init()
11221173 label = ' Export to csv' ,
11231174 key = ' CUSTOM_SHIFT_E' ,
11241175 on_activate = function () self .subviews .sheet :export () end ,
1125- enabled = false ,
11261176 },
11271177 widgets .HotkeyLabel {
11281178 frame = {b = 1 , l = 0 },
11291179 auto_width = true ,
11301180 label = ' Hide column' ,
11311181 key = ' CUSTOM_SHIFT_H' ,
11321182 on_activate = function () self .subviews .sheet :hide_current_col () end ,
1133- enabled = false ,
11341183 },
11351184 widgets .HotkeyLabel {
11361185 frame = {b = 1 , l = 22 },
11371186 auto_width = true ,
11381187 label = ' Hide group' ,
11391188 key = ' CUSTOM_CTRL_H' ,
11401189 on_activate = function () self .subviews .sheet :hide_current_col_group () end ,
1141- enabled = false ,
11421190 },
11431191 widgets .HotkeyLabel {
11441192 frame = {b = 1 , l = 46 },
@@ -1160,7 +1208,6 @@ function Manipulator:init()
11601208 label = ' Zoom to source' ,
11611209 key = ' CUSTOM_CTRL_Z' ,
11621210 on_activate = function () self .subviews .sheet :zoom_to_col_source () end ,
1163- enabled = false ,
11641211 },
11651212 widgets .HotkeyLabel {
11661213 frame = {b = 0 , l = 46 },
0 commit comments