{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} module Codec.Xlsx.Types.SheetViews ( -- * Structured type to construct 'SheetViews' SheetView(..) , Selection(..) , Pane(..) , SheetViewType(..) , PaneType(..) , PaneState(..) -- * Lenses -- ** SheetView , sheetViewColorId , sheetViewDefaultGridColor , sheetViewRightToLeft , sheetViewShowFormulas , sheetViewShowGridLines , sheetViewShowOutlineSymbols , sheetViewShowRowColHeaders , sheetViewShowRuler , sheetViewShowWhiteSpace , sheetViewShowZeros , sheetViewTabSelected , sheetViewTopLeftCell , sheetViewType , sheetViewWindowProtection , sheetViewWorkbookViewId , sheetViewZoomScale , sheetViewZoomScaleNormal , sheetViewZoomScalePageLayoutView , sheetViewZoomScaleSheetLayoutView , sheetViewPane , sheetViewSelection -- ** Selection , selectionActiveCell , selectionActiveCellId , selectionPane , selectionSqref -- ** Pane , paneActivePane , paneState , paneTopLeftCell , paneXSplit , paneYSplit ) where import Control.Lens (makeLenses) import Data.Default import Data.Maybe (catMaybes, maybeToList, listToMaybe) import Text.XML import Text.XML.Cursor import qualified Data.Map as Map #if !MIN_VERSION_base(4,8,0) import Control.Applicative () #endif import Codec.Xlsx.Types.Common import Codec.Xlsx.Parser.Internal import Codec.Xlsx.Writer.Internal {------------------------------------------------------------------------------- Main types -------------------------------------------------------------------------------} -- | Worksheet view -- -- A single sheet view definition. When more than one sheet view is defined in -- the file, it means that when opening the workbook, each sheet view -- corresponds to a separate window within the spreadsheet application, where -- each window is showing the particular sheet containing the same -- workbookViewId value, the last sheetView definition is loaded, and the others -- are discarded. When multiple windows are viewing the same sheet, multiple -- sheetView elements (with corresponding workbookView entries) are saved. -- -- TODO: The @pivotSelection@ and @extLst@ child elements are unsupported. -- -- See Section 18.3.1.87 "sheetView (Worksheet View)" (p. 1880) data SheetView = SheetView { -- | Index to the color value for row/column text headings and gridlines. -- This is an 'index color value' (ICV) rather than rgb value. _sheetViewColorId :: Maybe Int -- | Flag indicating that the consuming application should use the default -- grid lines color (system dependent). Overrides any color specified in -- colorId. , _sheetViewDefaultGridColor :: Maybe Bool -- | Flag indicating whether the sheet is in 'right to left' display mode. -- When in this mode, Column A is on the far right, Column B ;is one column -- left of Column A, and so on. Also, information in cells is displayed in -- the Right to Left format. , _sheetViewRightToLeft :: Maybe Bool -- | Flag indicating whether this sheet should display formulas. , _sheetViewShowFormulas :: Maybe Bool -- | Flag indicating whether this sheet should display gridlines. , _sheetViewShowGridLines :: Maybe Bool -- | Flag indicating whether the sheet has outline symbols visible. This -- flag shall always override SheetPr element's outlinePr child element -- whose attribute is named showOutlineSymbols when there is a conflict. , _sheetViewShowOutlineSymbols :: Maybe Bool -- | Flag indicating whether the sheet should display row and column headings. , _sheetViewShowRowColHeaders :: Maybe Bool -- | Show the ruler in Page Layout View. , _sheetViewShowRuler :: Maybe Bool -- | Flag indicating whether page layout view shall display margins. False -- means do not display left, right, top (header), and bottom (footer) -- margins (even when there is data in the header or footer). , _sheetViewShowWhiteSpace :: Maybe Bool -- | Flag indicating whether the window should show 0 (zero) in cells -- containing zero value. When false, cells with zero value appear blank -- instead of showing the number zero. , _sheetViewShowZeros :: Maybe Bool -- | Flag indicating whether this sheet is selected. When only 1 sheet is -- selected and active, this value should be in synch with the activeTab -- value. In case of a conflict, the Start Part setting wins and sets the -- active sheet tab. -- -- Multiple sheets can be selected, but only one sheet shall be active at -- one time. , _sheetViewTabSelected :: Maybe Bool -- | Location of the top left visible cell Location of the top left visible -- cell in the bottom right pane (when in Left-to-Right mode). , _sheetViewTopLeftCell :: Maybe CellRef -- | Indicates the view type. , _sheetViewType :: Maybe SheetViewType -- | Flag indicating whether the panes in the window are locked due to -- workbook protection. This is an option when the workbook structure is -- protected. , _sheetViewWindowProtection :: Maybe Bool -- | Zero-based index of this workbook view, pointing to a workbookView -- element in the bookViews collection. -- -- NOTE: This attribute is required. , _sheetViewWorkbookViewId :: Int -- | Window zoom magnification for current view representing percent values. -- This attribute is restricted to values ranging from 10 to 400. Horizontal & -- Vertical scale together. , _sheetViewZoomScale :: Maybe Int -- | Zoom magnification to use when in normal view, representing percent -- values. This attribute is restricted to values ranging from 10 to 400. -- Horizontal & Vertical scale together. , _sheetViewZoomScaleNormal :: Maybe Int -- | Zoom magnification to use when in page layout view, representing -- percent values. This attribute is restricted to values ranging from 10 to -- 400. Horizontal & Vertical scale together. , _sheetViewZoomScalePageLayoutView :: Maybe Int -- | Zoom magnification to use when in page break preview, representing -- percent values. This attribute is restricted to values ranging from 10 to -- 400. Horizontal & Vertical scale together. , _sheetViewZoomScaleSheetLayoutView :: Maybe Int -- | Worksheet view pane , _sheetViewPane :: Maybe Pane -- | Worksheet view selection -- -- Minimum of 0, maximum of 4 elements , _sheetViewSelection :: [Selection] } deriving (Show, Eq, Ord) -- | Worksheet view selection. -- -- Section 18.3.1.78 "selection (Selection)" (p. 1864) data Selection = Selection { -- | Location of the active cell _selectionActiveCell :: Maybe CellRef -- | 0-based index of the range reference (in the array of references listed -- in sqref) containing the active cell. Only used when the selection in -- sqref is not contiguous. Therefore, this value needs to be aware of the -- order in which the range references are written in sqref. -- -- When this value is out of range then activeCell can be used. , _selectionActiveCellId :: Maybe Int -- | The pane to which this selection belongs. , _selectionPane :: Maybe PaneType -- | Range of the selection. Can be non-contiguous set of ranges. , _selectionSqref :: Maybe SqRef } deriving (Show, Eq, Ord) -- | Worksheet view pane -- -- Section 18.3.1.66 "pane (View Pane)" (p. 1843) data Pane = Pane { -- | The pane that is active. _paneActivePane :: Maybe PaneType -- | Indicates whether the pane has horizontal / vertical splits, and -- whether those splits are frozen. , _paneState :: Maybe PaneState -- | Location of the top left visible cell in the bottom right pane (when in -- Left-To-Right mode). , _paneTopLeftCell :: Maybe CellRef -- | Horizontal position of the split, in 1/20th of a point; 0 (zero) if -- none. If the pane is frozen, this value indicates the number of columns -- visible in the top pane. , _paneXSplit :: Maybe Double -- | Vertical position of the split, in 1/20th of a point; 0 (zero) if none. -- If the pane is frozen, this value indicates the number of rows visible in -- the left pane. , _paneYSplit :: Maybe Double } deriving (Show, Eq, Ord) {------------------------------------------------------------------------------- Enumerations -------------------------------------------------------------------------------} -- | View setting of the sheet -- -- Section 18.18.69 "ST_SheetViewType (Sheet View Type)" (p. 2726) data SheetViewType = -- | Normal view SheetViewTypeNormal -- | Page break preview | SheetViewTypePageBreakPreview -- | Page layout view | SheetViewTypePageLayout deriving (Show, Eq, Ord) -- | Pane type -- -- Section 18.18.52 "ST_Pane (Pane Types)" (p. 2710) data PaneType = -- | Bottom left pane, when both vertical and horizontal splits are applied. -- -- This value is also used when only a horizontal split has been applied, -- dividing the pane into upper and lower regions. In that case, this value -- specifies the bottom pane. PaneTypeBottomLeft -- Bottom right pane, when both vertical and horizontal splits are applied. | PaneTypeBottomRight -- | Top left pane, when both vertical and horizontal splits are applied. -- -- This value is also used when only a horizontal split has been applied, -- dividing the pane into upper and lower regions. In that case, this value -- specifies the top pane. -- -- This value is also used when only a vertical split has been applied, -- dividing the pane into right and left regions. In that case, this value -- specifies the left pane | PaneTypeTopLeft -- | Top right pane, when both vertical and horizontal splits are applied. -- -- This value is also used when only a vertical split has been applied, -- dividing the pane into right and left regions. In that case, this value -- specifies the right pane. | PaneTypeTopRight deriving (Eq, Show, Ord) -- | State of the sheet's pane. -- -- Section 18.18.53 "ST_PaneState (Pane State)" (p. 2711) data PaneState = -- | Panes are frozen, but were not split being frozen. In this state, when -- the panes are unfrozen again, a single pane results, with no split. In -- this state, the split bars are not adjustable. PaneStateFrozen -- | Panes are frozen and were split before being frozen. In this state, -- when the panes are unfrozen again, the split remains, but is adjustable. | PaneStateFrozenSplit -- | Panes are split, but not frozen. In this state, the split bars are -- adjustable by the user. | PaneStateSplit deriving (Eq, Show, Ord) {------------------------------------------------------------------------------- Lenses -------------------------------------------------------------------------------} makeLenses ''SheetView makeLenses ''Selection makeLenses ''Pane {------------------------------------------------------------------------------- Default instances -------------------------------------------------------------------------------} -- | NOTE: The 'Default' instance for 'SheetView' sets the required attribute -- '_sheetViewWorkbookViewId' to @0@. instance Default SheetView where def = SheetView { _sheetViewColorId = Nothing , _sheetViewDefaultGridColor = Nothing , _sheetViewRightToLeft = Nothing , _sheetViewShowFormulas = Nothing , _sheetViewShowGridLines = Nothing , _sheetViewShowOutlineSymbols = Nothing , _sheetViewShowRowColHeaders = Nothing , _sheetViewShowRuler = Nothing , _sheetViewShowWhiteSpace = Nothing , _sheetViewShowZeros = Nothing , _sheetViewTabSelected = Nothing , _sheetViewTopLeftCell = Nothing , _sheetViewType = Nothing , _sheetViewWindowProtection = Nothing , _sheetViewWorkbookViewId = 0 , _sheetViewZoomScale = Nothing , _sheetViewZoomScaleNormal = Nothing , _sheetViewZoomScalePageLayoutView = Nothing , _sheetViewZoomScaleSheetLayoutView = Nothing , _sheetViewPane = Nothing , _sheetViewSelection = [] } instance Default Selection where def = Selection { _selectionActiveCell = Nothing , _selectionActiveCellId = Nothing , _selectionPane = Nothing , _selectionSqref = Nothing } instance Default Pane where def = Pane { _paneActivePane = Nothing , _paneState = Nothing , _paneTopLeftCell = Nothing , _paneXSplit = Nothing , _paneYSplit = Nothing } {------------------------------------------------------------------------------- Rendering -------------------------------------------------------------------------------} -- | See @CT_SheetView@, p. 3913 instance ToElement SheetView where toElement nm SheetView{..} = Element { elementName = nm , elementNodes = map NodeElement . concat $ [ map (toElement "pane") (maybeToList _sheetViewPane) , map (toElement "selection") _sheetViewSelection -- TODO: pivotSelection -- TODO: extLst ] , elementAttributes = Map.fromList . catMaybes $ [ "windowProtection" .=? _sheetViewWindowProtection , "showFormulas" .=? _sheetViewShowFormulas , "showGridLines" .=? _sheetViewShowGridLines , "showRowColHeaders" .=? _sheetViewShowRowColHeaders , "showZeros" .=? _sheetViewShowZeros , "rightToLeft" .=? _sheetViewRightToLeft , "tabSelected" .=? _sheetViewTabSelected , "showRuler" .=? _sheetViewShowRuler , "showOutlineSymbols" .=? _sheetViewShowOutlineSymbols , "defaultGridColor" .=? _sheetViewDefaultGridColor , "showWhiteSpace" .=? _sheetViewShowWhiteSpace , "view" .=? _sheetViewType , "topLeftCell" .=? _sheetViewTopLeftCell , "colorId" .=? _sheetViewColorId , "zoomScale" .=? _sheetViewZoomScale , "zoomScaleNormal" .=? _sheetViewZoomScaleNormal , "zoomScaleSheetLayoutView" .=? _sheetViewZoomScaleSheetLayoutView , "zoomScalePageLayoutView" .=? _sheetViewZoomScalePageLayoutView , Just $ "workbookViewId" .= _sheetViewWorkbookViewId ] } -- | See @CT_Selection@, p. 3914 instance ToElement Selection where toElement nm Selection{..} = Element { elementName = nm , elementNodes = [] , elementAttributes = Map.fromList . catMaybes $ [ "pane" .=? _selectionPane , "activeCell" .=? _selectionActiveCell , "activeCellId" .=? _selectionActiveCellId , "sqref" .=? _selectionSqref ] } -- | See @CT_Pane@, p. 3913 instance ToElement Pane where toElement nm Pane{..} = Element { elementName = nm , elementNodes = [] , elementAttributes = Map.fromList . catMaybes $ [ "xSplit" .=? _paneXSplit , "ySplit" .=? _paneYSplit , "topLeftCell" .=? _paneTopLeftCell , "activePane" .=? _paneActivePane , "state" .=? _paneState ] } -- | See @ST_SheetViewType@, p. 3913 instance ToAttrVal SheetViewType where toAttrVal SheetViewTypeNormal = "normal" toAttrVal SheetViewTypePageBreakPreview = "pageBreakPreview" toAttrVal SheetViewTypePageLayout = "pageLayout" -- | See @ST_Pane@, p. 3914 instance ToAttrVal PaneType where toAttrVal PaneTypeBottomRight = "bottomRight" toAttrVal PaneTypeTopRight = "topRight" toAttrVal PaneTypeBottomLeft = "bottomLeft" toAttrVal PaneTypeTopLeft = "topLeft" -- | See @ST_PaneState@, p. 3929 instance ToAttrVal PaneState where toAttrVal PaneStateSplit = "split" toAttrVal PaneStateFrozen = "frozen" toAttrVal PaneStateFrozenSplit = "frozenSplit" {------------------------------------------------------------------------------- Parsing -------------------------------------------------------------------------------} -- | See @CT_SheetView@, p. 3913 instance FromCursor SheetView where fromCursor cur = do _sheetViewWindowProtection <- maybeAttribute "windowProtection" cur _sheetViewShowFormulas <- maybeAttribute "showFormulas" cur _sheetViewShowGridLines <- maybeAttribute "showGridLines" cur _sheetViewShowRowColHeaders <- maybeAttribute "showRowColHeaders"cur _sheetViewShowZeros <- maybeAttribute "showZeros" cur _sheetViewRightToLeft <- maybeAttribute "rightToLeft" cur _sheetViewTabSelected <- maybeAttribute "tabSelected" cur _sheetViewShowRuler <- maybeAttribute "showRuler" cur _sheetViewShowOutlineSymbols <- maybeAttribute "showOutlineSymbols" cur _sheetViewDefaultGridColor <- maybeAttribute "defaultGridColor" cur _sheetViewShowWhiteSpace <- maybeAttribute "showWhiteSpace" cur _sheetViewType <- maybeAttribute "view" cur _sheetViewTopLeftCell <- maybeAttribute "topLeftCell" cur _sheetViewColorId <- maybeAttribute "colorId" cur _sheetViewZoomScale <- maybeAttribute "zoomScale" cur _sheetViewZoomScaleNormal <- maybeAttribute "zoomScaleNormal" cur _sheetViewZoomScaleSheetLayoutView <- maybeAttribute "zoomScaleSheetLayoutView" cur _sheetViewZoomScalePageLayoutView <- maybeAttribute "zoomScalePageLayoutView" cur _sheetViewWorkbookViewId <- fromAttribute "workbookViewId" cur let _sheetViewPane = listToMaybe $ cur $/ element (n_ "pane") >=> fromCursor _sheetViewSelection = cur $/ element (n_ "selection") >=> fromCursor return SheetView{..} -- | See @CT_Pane@, p. 3913 instance FromCursor Pane where fromCursor cur = do _paneXSplit <- maybeAttribute "xSplit" cur _paneYSplit <- maybeAttribute "ySplit" cur _paneTopLeftCell <- maybeAttribute "topLeftCell" cur _paneActivePane <- maybeAttribute "activePane" cur _paneState <- maybeAttribute "state" cur return Pane{..} -- | See @CT_Selection@, p. 3914 instance FromCursor Selection where fromCursor cur = do _selectionPane <- maybeAttribute "pane" cur _selectionActiveCell <- maybeAttribute "activeCell" cur _selectionActiveCellId <- maybeAttribute "activeCellId" cur _selectionSqref <- maybeAttribute "sqref" cur return Selection{..} -- | See @ST_SheetViewType@, p. 3913 instance FromAttrVal SheetViewType where fromAttrVal "normal" = readSuccess SheetViewTypeNormal fromAttrVal "pageBreakPreview" = readSuccess SheetViewTypePageBreakPreview fromAttrVal "pageLayout" = readSuccess SheetViewTypePageLayout fromAttrVal t = invalidText "SheetViewType" t -- | See @ST_Pane@, p. 3914 instance FromAttrVal PaneType where fromAttrVal "bottomRight" = readSuccess PaneTypeBottomRight fromAttrVal "topRight" = readSuccess PaneTypeTopRight fromAttrVal "bottomLeft" = readSuccess PaneTypeBottomLeft fromAttrVal "topLeft" = readSuccess PaneTypeTopLeft fromAttrVal t = invalidText "PaneType" t -- | See @ST_PaneState@, p. 3929 instance FromAttrVal PaneState where fromAttrVal "split" = readSuccess PaneStateSplit fromAttrVal "frozen" = readSuccess PaneStateFrozen fromAttrVal "frozenSplit" = readSuccess PaneStateFrozenSplit fromAttrVal t = invalidText "PaneState" t