1package ui23import (4 tea "charm.land/bubbletea/v2"56 "src.rest/cat/012/internal/sheet"7 "src.rest/cat/012/internal/ui/picker"8)910// Hidden sheets, as in Sheets: the tab menu's Hide sheet takes a sheet11// out of the tabs, and View > Hidden sheets lists them to show one12// again. Formulas still read a hidden sheet; moving between sheets, the13// tab strip, Go to sheet and Find in all sheets skip it, and going to a14// cell on it (Go to, a named range) says it's hidden rather than show it.1516func init() {17 register(18 &command{id: "sheet.hide", title: "Hide sheet", desc: "Hide the sheet's tab; formulas still read it",19 enabled: func(m *Model) bool { return len(m.book().Visible()) > 1 }, run: (*Model).hideSheet},20 &command{id: "sheet.unhide", title: "Hidden sheets", desc: "List the hidden sheets and show one again",21 enabled: func(m *Model) bool { return len(m.book().HiddenSheets()) > 0 }, run: func(m *Model) tea.Cmd {22 m.openHiddenPicker()23 return nil24 }},25 )26}2728// hideSheet hides the sheet shown and shows the next visible one.29func (m *Model) hideSheet() tea.Cmd {30 s := m.sheet31 i := m.book().Index(s)32 if err := m.book().HideSheet(s); err != nil {33 m.fail(err.Error())34 return nil35 }36 m.afterSheetsChange(nil, i)37 m.note = "Hid " + s.Name() + "; View > Hidden sheets shows it again"38 return nil39}4041// openHiddenPicker lists the hidden sheets; Enter shows the one picked42// again. A macro records the pick as the command's answer.43func (m *Model) openHiddenPicker() {44 var items []picker.Item45 for _, s := range m.book().HiddenSheets() {46 detail := "empty"47 if used, ok := s.UsedRange(); ok {48 detail = used.String() + ", " + cellCount(s.Len())49 }50 items = append(items, picker.Item{51 Title: s.Name(), Name: len(s.Name()), Detail: detail, Desc: "Show " + s.Name() + " again",52 Pick: func() tea.Cmd {53 m.closeOverlay()54 if err := m.book().UnhideSheet(s); err != nil {55 m.fail(err.Error())56 return nil57 }58 m.showSheet(s)59 m.note = "Unhid " + s.Name()60 return nil61 },62 })63 }64 p := m.newPicker("Hidden sheets", "Type a sheet name", 60, items)65 p.Action = "unhide"66 p.Answers = true67 m.openOverlay(p)68}6970// refuseHidden says so and reports true when s is a hidden sheet, which71// isn't shown until it's unhidden.72func (m *Model) refuseHidden(s *sheet.Sheet) bool {73 if s == nil || !s.Hidden() {74 return false75 }76 m.fail(hiddenMsg(s))77 return true78}7980func hiddenMsg(s *sheet.Sheet) string {81 return s.Name() + " is hidden; View > Hidden sheets shows it again"82}8384// visibleSheets are the sheets with tabs, and the sheet shown if it85// somehow isn't among them, so the tab strip always has it.86func (m *Model) visibleSheets() []*sheet.Sheet {87 if !m.sheet.Hidden() {88 return m.book().Visible()89 }90 var out []*sheet.Sheet91 for _, s := range m.book().Sheets() {92 if !s.Hidden() || s == m.sheet {93 out = append(out, s)94 }95 }96 return out97}9899// nearVisible is the visible sheet at index i of the workbook or the100// nearest one after it, else before it.101func (m *Model) nearVisible(i int) *sheet.Sheet {102 book := m.book()103 for j := max(i, 0); j < book.Len(); j++ {104 if s := book.Sheet(j); !s.Hidden() {105 return s106 }107 }108 for j := min(i, book.Len()-1); j >= 0; j-- {109 if s := book.Sheet(j); !s.Hidden() {110 return s111 }112 }113 return book.Sheet(0)114}