<h3>Basics</h3>
Data pilot object has the concept of <em>dimensions</em>, where each dimension can be one of column, row, data, or page dimension.  These dimensions are sometimes also referred to as fields i.e. column field, row field etc.  (There is also another dimension called the <em>data layout</em> dimension.)  Each dimension also has multiple members, and each member corresponds with each individual value.  You can think of a dimension as a column in a tabular data, and a member as a cell.

At top level, {ooolxr:ScPivotShell}'s {ooolxr:Execute} method receives all data pilot related shell requests (delete, refresh, and filter to be precise).  Refresh and delete requests are simply routed to {ooolxr:ScDBFunc}'s {ooolxr:RecalcPivotTable} and {ooolxr:DeletePivotTable} methods respectively.  Execution of creation and modification of a data pilot, i.e. when the user clicks OK on the main DataPilot dialog, is handled by {ooolxr:ScCellShell}'s {ooolxr:ExecuteDB} method (which eventually calls {ooolxr:ScDBFunc}'s {ooolxr:MakePivotTable} method).  The same method also handles the launching of the dialog itself, associated with the SID_OPENDLG_PIVOTTABLE slot ID.

<h3>Top-level data pilot object</h3>

Each data pilot in Calc document is represented by {ooolxr:ScDPObject}.

Class {ooolxr:ScDPOutput} represents each data pilot view that is actually displayed on the sheet.  The instance of this class stores the geometry of the data pilot view it represents.  The multi-level column, row, and page fields information are also stored herein.  Each field can have up to 256 levels of headers, and instances of {ooolxr:ScDPOutLevelData} are used to store the field information (aCaption data member stores the label of a field, and aResult data member stores the value of each column or row as an array ordered from left to right).  Have a look at {ooolxr:pColFields}, {ooolxr:pRowFields}, and {ooolxr:pPageFields} that are pointer data members of {ooolxr:ScDPOutput}.  The current levels of column, row, and page fields are stored in {ooolxr:nColFieldCount}, {ooolxr:nRowFieldCount}, and {ooolxr:nPageFieldCount} data members, respectively.  These numbers get updated only when an instance of {ooolxr:ScDPOutput} is constructed; in other words, every time a new level gets introduced in a data pilot view, Calc destroys the old instance of {ooolxr:ScDPOutput} and constructs a new one to take its place.

The data source used to create the data pilot output is stored with the {ooolxr:ScDPObject} object as an {ooolxr:XDimensionsSupplier} interface instance, which is implemented by {ooolxr:ScDPSource} class.  A reference to the {ooolxr:XDimensionsSupplier} instance can be obtained via {ooolxr:ScDPObject}'s {ooolxr:GetSource} method.  The {ooolxr:XNameAccess} reference object returned by the {ooolxr:XDimensionsSupplier} instance (via {ooolxr:getDimensions} call) is implemented by {ooolxr:ScDPDimensions} class.

<h3>Data source access</h3>
To build a data pilot output, you have to parse the original data source at some point.

{ooolxr:ScDPTableData} abstracts the data source access, which can be either a cell range in the same document or an external data source accessed via the registered database functionality (?).  {ooolxr:ScDPTableData} has three child classes: {ooolxr:ScSheetDPData}, {ooolxr:ScDatabaseDPData}, and {ooolxr:ScDPGroupTableData} (the last one is just a proxy implementation of {ooolxr:ScDPTableData} to add grouped items).  {ooolxr:ScSheetDPData} represents a sheet data source within the same document with the data pilot output.  Its {ooolxr:GetNextRow} method makes actual calls to the cell instances to get their values.  The {ooolxr:GetNextRow} method is expected to be called in a loop, and each call retrieves a row, and increments the iterator position.

There is only one instance of {ooolxr:ScDPTableData}, which gets created in {ooolxr:ScDPObject}'s {ooolxr:CreateObjects} method, and is passed to the {ooolxr:ScDPSource} instance, which takes care of destroying it in the end.

The heavy-lifting action of processing the source data and constructing a data pilot output from it is all done within {ooolxr:ScDPSource}'s {ooolxr:CreateRes_Impl} method, where an instance of {ooolxr:ScDPResultData} and two instances of {ooolxr:ScDPResultMember} (for column and row "roots") are created, and the source data gets scanned.  {ooolxr:ScDPResultData} stores metadata on the data field, but not the values themselves.

To get a list of unique entries for each column, {ooolxr:ScDPTableData}'s virtual function {ooolxr:GetColumnEntries} gets called.  Since this method is virtual, it must be overwritten by each derived class.  {ooolxr:ScSheetDPData}'s implementation of {ooolxr:GetColumnEntries} scans all individual cells and pick up their string values, then use {ooolxr:TypedStrCollection} container class to reduce them down to the unique set of values.  It uses {ooolxr:ScDocument}'s {ooolxr:GetString} method to get the string value from each cell, even for numeric cells.

{ooolxr:ScDPItemData} is used to hold a single cell data during the scanning of source data, but this class is also used in other places.

<h3>Double-click on member to expand or shrink</h3>
{ooolxr:ScDPositionData} stores basic information of a given single cell position within the data pilot area.  It is used, for example, when the user double-clicks within a data pilot region by passing an empty instance of that class to the {ooolxr:GetPositionData} method of the corresponding {ooolxr:ScDPObject} instance, which in turn calls {ooolxr:GetPositionData} of {ooolxr:ScDPOutput} class instance.

{ooolxr:ScDPObject}'s {ooolxr:ToggleDetails} method handles expanding and shrinking of child data members of the member whose cell is double-clicked on.

<h3>Switching page field value</h3>
The user can change the page field value from the page field list box located above the main data pilot box.  When the user commits the value change, {ooolxr:ScGridWindow}'s {ooolxr:FilterSelect} gets called from the list box handler ({ooolxr:ScFilterListBox}), and subsequently {ooolxr:ExecPageFieldSelect} of the same class gets called.  The {ooolxr:ScFilterListBox} instance knows which mode it is operating under.  Have a look at {ooolxr:ScFilterBoxMode} enum values for possible mode values for {ooolxr:ScFIlterListBox}.

{ooolxr:ScDBDocFunc}'s {ooolxr:DataPilotUpdate} is the top-level routine that oversees the entire update operation.  This is where the source data gets invalidated, and subsequently reloaded (i.e. {ooolxr:CreateRes_Impl} gets called to re-build the result data from the data source once again).  {ooolxr:DataPilotUpdate} is also called from {ooolxr:ScDBFunc}::{ooolxr:RecalcPivotTable} when the output is being refreshed.

<h3>Filtering data source</h3>
When the user clicks the Filter button at the top of the data pilot area, {ooolxr:ScGridWindow}'s {ooolxr:DoPushButton} gets called.  (This method also gets called when clicking on other buttons within the data pilot output.)  Then the filter dialog gets displayed and returns when done.  If the OK is pressed, it creates a new instance of {ooolxr:ScSheetSourceDesc} with the query parameter from the filter dialog, and passes it to a new instance of {ooolxr:ScDPObject}.  {ooolxr:ScDBDocFunc}'s {ooolxr:DataPilotUpdate} gets called in the end to execute the update operation.

<h3>Undo in Data Pilot</h3>
{ooolxr:ScUndoDataPilot}...

