xlsx-1.2.0: src/Codec/Xlsx/Types/SheetViews.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
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 GHC.Generics (Generic)
import Codec.Xlsx.LensCompat (makeLenses)
import Control.DeepSeq (NFData)
import Data.Default
import Data.Maybe (catMaybes, maybeToList, listToMaybe)
import Text.XML
import Text.XML.Cursor
import qualified Data.Map as Map
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 (Eq, Ord, Show, Generic)
instance NFData SheetView
-- | 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 (Eq, Ord, Show, Generic)
instance NFData Selection
-- | 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 (Eq, Ord, Show, Generic)
instance NFData Pane
{-------------------------------------------------------------------------------
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 (Eq, Ord, Show, Generic)
instance NFData SheetViewType
-- | 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, Ord, Show, Generic)
instance NFData PaneType
-- | 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, Ord, Show, Generic)
instance NFData PaneState
{-------------------------------------------------------------------------------
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 (addSmlNamespace "pane") >=> fromCursor
_sheetViewSelection = cur $/ element (addSmlNamespace "selection") >=> fromCursor
return SheetView{..}
instance FromXenoNode SheetView where
fromXenoNode root = parseAttributes root $ do
_sheetViewWindowProtection <- maybeAttr "windowProtection"
_sheetViewShowFormulas <- maybeAttr "showFormulas"
_sheetViewShowGridLines <- maybeAttr "showGridLines"
_sheetViewShowRowColHeaders <- maybeAttr "showRowColHeaders"
_sheetViewShowZeros <- maybeAttr "showZeros"
_sheetViewRightToLeft <- maybeAttr "rightToLeft"
_sheetViewTabSelected <- maybeAttr "tabSelected"
_sheetViewShowRuler <- maybeAttr "showRuler"
_sheetViewShowOutlineSymbols <- maybeAttr "showOutlineSymbols"
_sheetViewDefaultGridColor <- maybeAttr "defaultGridColor"
_sheetViewShowWhiteSpace <- maybeAttr "showWhiteSpace"
_sheetViewType <- maybeAttr "view"
_sheetViewTopLeftCell <- maybeAttr "topLeftCell"
_sheetViewColorId <- maybeAttr "colorId"
_sheetViewZoomScale <- maybeAttr "zoomScale"
_sheetViewZoomScaleNormal <- maybeAttr "zoomScaleNormal"
_sheetViewZoomScaleSheetLayoutView <- maybeAttr "zoomScaleSheetLayoutView"
_sheetViewZoomScalePageLayoutView <- maybeAttr "zoomScalePageLayoutView"
_sheetViewWorkbookViewId <- fromAttr "workbookViewId"
(_sheetViewPane, _sheetViewSelection) <-
toAttrParser . collectChildren root $
(,) <$> maybeFromChild "pane" <*> fromChildList "selection"
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{..}
instance FromXenoNode Pane where
fromXenoNode root =
parseAttributes root $ do
_paneXSplit <- maybeAttr "xSplit"
_paneYSplit <- maybeAttr "ySplit"
_paneTopLeftCell <- maybeAttr "topLeftCell"
_paneActivePane <- maybeAttr "activePane"
_paneState <- maybeAttr "state"
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{..}
instance FromXenoNode Selection where
fromXenoNode root =
parseAttributes root $ do
_selectionPane <- maybeAttr "pane"
_selectionActiveCell <- maybeAttr "activeCell"
_selectionActiveCellId <- maybeAttr "activeCellId"
_selectionSqref <- maybeAttr "sqref"
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
instance FromAttrBs SheetViewType where
fromAttrBs "normal" = return SheetViewTypeNormal
fromAttrBs "pageBreakPreview" = return SheetViewTypePageBreakPreview
fromAttrBs "pageLayout" = return SheetViewTypePageLayout
fromAttrBs x = unexpectedAttrBs "SheetViewType" x
-- | 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
instance FromAttrBs PaneType where
fromAttrBs "bottomRight" = return PaneTypeBottomRight
fromAttrBs "topRight" = return PaneTypeTopRight
fromAttrBs "bottomLeft" = return PaneTypeBottomLeft
fromAttrBs "topLeft" = return PaneTypeTopLeft
fromAttrBs x = unexpectedAttrBs "PaneType" x
-- | 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
instance FromAttrBs PaneState where
fromAttrBs "split" = return PaneStateSplit
fromAttrBs "frozen" = return PaneStateFrozen
fromAttrBs "frozenSplit" = return PaneStateFrozenSplit
fromAttrBs x = unexpectedAttrBs "PaneState" x