//********************************************************************* // Constructor: ExcelTableRow() // /// <summary> /// Initializes a new instance of the <see cref="ExcelTableRow" /> /// class. /// </summary> /// /// <param name="excelTableReader"> /// The table reader object that owns this object. /// </param> //********************************************************************* public ExcelTableRow ( ExcelTableReader excelTableReader ) { m_oExcelTableReader = excelTableReader; AssertValid(); }
ReadPolarCoordinates ( ExcelTableReader.ExcelTableRow oRow, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(oVertex != null); AssertValid(); String sR; Boolean bHasR = oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.PolarR, out sR); String sAngle; Boolean bHasAngle = oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.PolarAngle, out sAngle); if (bHasR != bHasAngle) { // R or Angle alone won't do. goto Error; } if (!bHasR && !bHasAngle) { return (false); } Single fR, fAngle; if ( !Single.TryParse(sR, out fR) || !Single.TryParse(sAngle, out fAngle) ) { goto Error; } oVertex.SetValue(ReservedMetadataKeys.PolarLayoutCoordinates, new SinglePolarCoordinates(fR, fAngle) ); return (true); Error: Range oInvalidCell = oRow.GetRangeForCell( VertexTableColumnNames.PolarR); OnWorkbookFormatError( String.Format( "There is a problem with the vertex polar coordinates at {0}." + " If you enter polar coordinates, they must include both" + " {1} and {2} numbers. Any numbers are acceptable." + "\r\n\r\n" + "Polar coordinates are used only when a Layout of Polar" + " or Polar Absolute is selected in the graph pane." , ExcelUtil.GetRangeAddress(oInvalidCell), VertexTableColumnNames.PolarR, VertexTableColumnNames.PolarAngle ), oInvalidCell ); // Make the compiler happy. return (false); }
ReadImageUri ( ExcelTableReader.ExcelTableRow oRow, IVertex oVertex, VertexRadiusConverter oVertexRadiusConverter, Nullable<Single> oVertexImageSize ) { Debug.Assert(oRow != null); Debug.Assert(oVertex != null); Debug.Assert(oVertexRadiusConverter != null); AssertValid(); String sImageUri; if ( !oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.ImageUri, out sImageUri) ) { return (false); } if ( sImageUri.ToLower().StartsWith("www.") ) { // The Uri class thinks that "www.somewhere.com" is a relative // path. Fix that. sImageUri= "http://" + sImageUri; } Uri oUri; // Is the URI either an URL or a full file path? if ( !Uri.TryCreate(sImageUri, UriKind.Absolute, out oUri) ) { // No. It appears to be a relative path. Range oCell = oRow.GetRangeForCell( VertexTableColumnNames.ImageUri); String sWorkbookPath = ( (Workbook)(oCell.Worksheet.Parent) ).Path; if ( !String.IsNullOrEmpty(sWorkbookPath) ) { sImageUri = Path.Combine(sWorkbookPath, sImageUri); } else { OnWorkbookFormatError( String.Format( "The image file path specified in cell {0} is a relative" + " path. Relative paths must be relative to the saved" + " workbook file, but the workbook hasn't been saved yet." + " Either save the workbook or change the image file to" + " an absolute path, such as \"C:\\MyImages\\Image.jpg\"." , ExcelUtil.GetRangeAddress(oCell) ), oCell ); } } // Note that sImageUri may or may not be a valid URI string. If it is // not, GetImageSynchronousIgnoreDpi() will return an error image. ImageSource oImage = ( new WpfImageUtil() ).GetImageSynchronousIgnoreDpi(sImageUri); if (oVertexImageSize.HasValue) { // Resize the image. Double dLongerDimension = oVertexRadiusConverter.WorkbookToLongerImageDimension( oVertexImageSize.Value); Debug.Assert(dLongerDimension >= 1); oImage = ( new WpfImageUtil() ).ResizeImage(oImage, (Int32)dLongerDimension); } oVertex.SetValue(ReservedMetadataKeys.PerVertexImage, oImage); return (true); }
ReadRadius ( ExcelTableReader.ExcelTableRow oRow, VertexRadiusConverter oVertexRadiusConverter, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(oVertex != null); Debug.Assert(oVertexRadiusConverter != null); AssertValid(); String sRadius; if ( !oRow.TryGetNonEmptyStringFromCell(VertexTableColumnNames.Radius, out sRadius) ) { return ( new Nullable<Single>() ); } Single fRadius; if ( !Single.TryParse(sRadius, out fRadius) ) { Range oInvalidCell = oRow.GetRangeForCell( VertexTableColumnNames.Radius); OnWorkbookFormatError( String.Format( "The cell {0} contains an invalid size. The vertex size," + " which is optional, must be a number. Any number is" + " acceptable, although {1} is used for any number less than" + " {1} and {2} is used for any number greater than {2}." , ExcelUtil.GetRangeAddress(oInvalidCell), VertexRadiusConverter.MinimumRadiusWorkbook, VertexRadiusConverter.MaximumRadiusWorkbook ), oInvalidCell ); } oVertex.SetValue( ReservedMetadataKeys.PerVertexRadius, oVertexRadiusConverter.WorkbookToGraph(fRadius) ); return ( new Nullable<Single>(fRadius) ); }
ReadVertexTable ( ListObject oVertexTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph, out Boolean bLayoutAndZOrderSet ) { Debug.Assert(oVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); bLayoutAndZOrderSet = false; if (GetTableColumnIndex(oVertexTable, VertexTableColumnNames.VertexName, false) == NoSuchColumn) { // Nothing can be done without vertex names. return; } Boolean bReadAllEdgeAndVertexColumns = oReadWorkbookContext.ReadAllEdgeAndVertexColumns; if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oVertexTable); } // Get the names of all the column pairs that are used to add custom // menu items to the vertex context menu in the graph. TableColumnAdder oTableColumnAdder = new TableColumnAdder(); ICollection< KeyValuePair<String, String> > aoCustomMenuItemPairNames = oTableColumnAdder.GetColumnPairNames(oVertexTable, VertexTableColumnNames.CustomMenuItemTextBase, VertexTableColumnNames.CustomMenuItemActionBase); IVertexCollection oVertices = oGraph.Vertices; Dictionary<String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; Dictionary<Int32, IIdentityProvider> oEdgeRowIDDictionary = oReadWorkbookContext.EdgeRowIDDictionary; BooleanConverter oBooleanConverter = oReadWorkbookContext.BooleanConverter; VertexVisibilityConverter oVertexVisibilityConverter = new VertexVisibilityConverter(); VertexLabelPositionConverter oVertexLabelPositionConverter = new VertexLabelPositionConverter(); ExcelTableReader oExcelTableReader = new ExcelTableReader(oVertexTable); HashSet<String> oColumnNamesToExclude = new HashSet<String>( new String[] { VertexTableColumnNames.VertexName } ); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the name of the vertex. String sVertexName; if ( !oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.VertexName, out sVertexName) ) { continue; } // If the vertex was added to the graph as part of an edge, // retrieve the vertex. IVertex oVertex; if ( !oVertexNameDictionary.TryGetValue(sVertexName, out oVertex) ) { oVertex = null; } // Assume a default visibility. Visibility eVisibility = Visibility.ShowIfInAnEdge; String sVisibility; if ( oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility) ) { if ( !oVertexVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility) ) { OnInvalidVisibility(oRow); } } switch (eVisibility) { case Visibility.ShowIfInAnEdge: // If the vertex is part of an edge, show it using the // specified vertex attributes. Otherwise, skip the vertex // row. if (oVertex == null) { continue; } break; case Visibility.Skip: // Skip the vertex row and any edge rows that include the // vertex. Do not read them into the graph. if (oVertex != null) { // Remove the vertex and its incident edges from the // graph and dictionaries. RemoveVertex(oVertex, oReadWorkbookContext, oGraph); } continue; case Visibility.Hide: // If the vertex is part of an edge, hide it and its // incident edges. Otherwise, skip the vertex row. if (oVertex == null) { continue; } HideVertex(oVertex); break; case Visibility.Show: // Show the vertex using the specified attributes // regardless of whether it is part of an edge. if (oVertex == null) { oVertex = CreateVertex(sVertexName, oVertices, oVertexNameDictionary); } oVertex.SetValue( ReservedMetadataKeys.VertexHasVisibilityOfShow, null); break; default: Debug.Assert(false); break; } Debug.Assert(oVertex != null); // If ReadWorkbookContext.FillIDColumns is true, add the vertex to // the vertex row ID dictionary and set the vertex's Tag to the row // ID. oReadWorkbookContext.AddToRowIDDictionary(oRow, oVertex, false); if (bReadAllEdgeAndVertexColumns) { // All columns except the vertex name should be read and stored // as metadata on the vertex. ReadAllColumns( oExcelTableReader, oRow, oVertex, oColumnNamesToExclude); continue; } // Layout and z-order. if ( ReadLayoutAndZOrder(oRow, oVertex) ) { bLayoutAndZOrderSet = true; } // Location and Locked. if (!oReadWorkbookContext.IgnoreVertexLocations) { System.Drawing.PointF oLocation; Boolean bLocationSpecified = TryGetLocation(oRow, VertexTableColumnNames.X, VertexTableColumnNames.Y, oReadWorkbookContext.VertexLocationConverter, out oLocation); if (bLocationSpecified) { oVertex.Location = oLocation; } ReadLocked(oRow, oBooleanConverter, bLocationSpecified, oVertex); } // Polar coordinates. ReadPolarCoordinates(oRow, oVertex); // Marked. ReadMarked(oRow, oBooleanConverter, oVertex); // Custom menu items. if (aoCustomMenuItemPairNames.Count > 0) { ReadCustomMenuItems(oRow, aoCustomMenuItemPairNames, oVertex); } // Alpha. ReadAlpha(oRow, oVertex); // Tooltip. ReadCellAndSetMetadata(oRow, VertexTableColumnNames.ToolTip, oVertex, ReservedMetadataKeys.PerVertexToolTip); // Label. if (oReadWorkbookContext.ReadVertexLabels) { ReadCellAndSetMetadata(oRow, VertexTableColumnNames.Label, oVertex, ReservedMetadataKeys.PerVertexLabel); } // Label fill color. ReadColor(oRow, VertexTableColumnNames.LabelFillColor, oVertex, ReservedMetadataKeys.PerVertexLabelFillColor, oReadWorkbookContext.ColorConverter2); // Label position. ReadLabelPosition(oRow, oVertexLabelPositionConverter, oVertex); // Radius. Nullable<Single> oRadiusWorkbook = new Nullable<Single>(); oRadiusWorkbook = ReadRadius(oRow, oReadWorkbookContext.VertexRadiusConverter, oVertex); // Shape. VertexShape eVertexShape; if ( !ReadShape(oRow, oVertex, out eVertexShape) ) { eVertexShape = oReadWorkbookContext.DefaultVertexShape; } // Label font size. if (eVertexShape == VertexShape.Label && oRadiusWorkbook.HasValue) { // The vertex radius is used to specify font size when the // shape is Label. oVertex.SetValue( ReservedMetadataKeys.PerVertexLabelFontSize, oReadWorkbookContext.VertexRadiusConverter. WorkbookToLabelFontSize(oRadiusWorkbook.Value) ); } // Image URI. if (eVertexShape == VertexShape.Image && oReadWorkbookContext.ReadVertexImages) { ReadImageUri(oRow, oVertex, oReadWorkbookContext.VertexRadiusConverter, oRadiusWorkbook.HasValue ? oRadiusWorkbook : oReadWorkbookContext.DefaultVertexImageSize ); } // Color ReadColor(oRow, VertexTableColumnNames.Color, oVertex, ReservedMetadataKeys.PerColor, oReadWorkbookContext.ColorConverter2); } if (bReadAllEdgeAndVertexColumns) { // Store the vertex column names on the graph. oGraph.SetValue( ReservedMetadataKeys.AllVertexMetadataKeys, FilterColumnNames(oExcelTableReader, oColumnNamesToExclude) ); } }
ReadMarked ( ExcelTableReader.ExcelTableRow oRow, BooleanConverter oBooleanConverter, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(oBooleanConverter != null); Debug.Assert(oVertex != null); AssertValid(); Boolean bMarked; if ( !TryGetBoolean(oRow, VertexTableColumnNames.IsMarked, oBooleanConverter, out bMarked) ) { return; } oVertex.SetValue(ReservedMetadataKeys.Marked, bMarked); return; }
ReadVisibility ( ExcelTableReader.ExcelTableRow oRow, GroupVisibilityConverter oGroupVisibilityConverter, String sGroupName, HashSet<String> oSkippedGroupNames, HashSet<String> oHiddenGroupNames ) { Debug.Assert(oRow != null); Debug.Assert(oGroupVisibilityConverter != null); Debug.Assert( !String.IsNullOrEmpty(sGroupName) ); Debug.Assert(oSkippedGroupNames != null); Debug.Assert(oHiddenGroupNames != null); AssertValid(); // Assume a default visibility. Visibility eVisibility = Visibility.Show; String sVisibility; if ( oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility) && !oGroupVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility) ) { OnInvalidVisibility(oRow); } if (eVisibility == Visibility.Skip) { oSkippedGroupNames.Add(sGroupName); } else if (eVisibility == Visibility.Hide) { oHiddenGroupNames.Add(sGroupName); } }
ReadGroupTable ( ListObject oGroupTable, ReadWorkbookContext oReadWorkbookContext, HashSet<String> oSkippedGroupNames, HashSet<String> oHiddenGroupNames ) { Debug.Assert(oGroupTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oSkippedGroupNames != null); Debug.Assert(oHiddenGroupNames != null); AssertValid(); if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oGroupTable); } Dictionary<String, ExcelTemplateGroupInfo> oGroupNameDictionary = new Dictionary<String, ExcelTemplateGroupInfo>(); ColorConverter2 oColorConverter2 = oReadWorkbookContext.ColorConverter2; GroupVisibilityConverter oGroupVisibilityConverter = new GroupVisibilityConverter(); BooleanConverter oBooleanConverter = oReadWorkbookContext.BooleanConverter; ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupTable); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the group information. String sGroupName; Color oVertexColor; VertexShape eVertexShape; if ( !oRow.TryGetNonEmptyStringFromCell(GroupTableColumnNames.Name, out sGroupName) || !TryGetColor(oRow, GroupTableColumnNames.VertexColor, oColorConverter2, out oVertexColor) || !TryGetVertexShape(oRow, GroupTableColumnNames.VertexShape, out eVertexShape) ) { continue; } ReadVisibility(oRow, oGroupVisibilityConverter, sGroupName, oSkippedGroupNames, oHiddenGroupNames); Boolean bCollapsed = false; Boolean bCollapsedCellValue; if ( TryGetBoolean(oRow, GroupTableColumnNames.Collapsed, oBooleanConverter, out bCollapsedCellValue) && bCollapsedCellValue ) { bCollapsed = true; } String sCollapsedAttributes; if ( !oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.CollapsedAttributes, out sCollapsedAttributes) ) { sCollapsedAttributes = null; } Int32 iRowIDAsInt32; Nullable<Int32> iRowID = null; if ( oRow.TryGetInt32FromCell(CommonTableColumnNames.ID, out iRowIDAsInt32) ) { iRowID = iRowIDAsInt32; } ExcelTemplateGroupInfo oExcelTemplateGroupInfo = new ExcelTemplateGroupInfo(sGroupName, iRowID, oVertexColor, eVertexShape, bCollapsed, sCollapsedAttributes); if (oReadWorkbookContext.ReadGroupLabels) { String sLabel; if ( oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.Label, out sLabel) ) { oExcelTemplateGroupInfo.Label = sLabel; } } if (!oReadWorkbookContext.IgnoreVertexLocations) { System.Drawing.PointF oCollapsedLocation; if ( TryGetLocation(oRow, GroupTableColumnNames.CollapsedX, GroupTableColumnNames.CollapsedY, oReadWorkbookContext.VertexLocationConverter, out oCollapsedLocation) ) { oExcelTemplateGroupInfo.CollapsedLocation = oCollapsedLocation; } } try { oGroupNameDictionary.Add(sGroupName, oExcelTemplateGroupInfo); } catch (ArgumentException) { Range oInvalidCell = oRow.GetRangeForCell( GroupTableColumnNames.Name); OnWorkbookFormatError( String.Format( "The cell {0} contains a duplicate group name. There" + " can't be two rows with the same group name." , ExcelUtil.GetRangeAddress(oInvalidCell) ), oInvalidCell ); } } return (oGroupNameDictionary); }
ReadTopColumn ( ListObject oTopMetricsTable, String sColumnHeader, StringBuilder oTopMetrics ) { Debug.Assert(oTopMetricsTable != null); Debug.Assert( !String.IsNullOrEmpty(sColumnHeader) ); Debug.Assert(oTopMetrics != null); StringBuilder oTopColumn = new StringBuilder(); Boolean bColumnIsEmpty = true; oTopColumn.Append(sColumnHeader); oTopColumn.Append(':'); ExcelTableReader oExcelTableReader = new ExcelTableReader(oTopMetricsTable); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { String sItemName; if ( oRow.TryGetNonEmptyStringFromCell(sColumnHeader, out sItemName) ) { StringUtil.AppendAfterEmptyLine(oTopColumn, sItemName); bColumnIsEmpty = false; } } if (!bColumnIsEmpty) { StringUtil.AppendSectionSeparator(oTopMetrics); oTopMetrics.Append( oTopColumn.ToString() ); } }
PrependGroupLabelsWithGroupNames ( ListObject oGroupTable ) { Debug.Assert(oGroupTable != null); // Use ExcelTableReader to accomplish the task with minimal code. // // Note that ExcelTableReader is optimized for reading, and that its // use for writing incurs the overhead of a COM call for each written // cell. There typically aren't many groups, though, so this is // probably tolerable. // // If this turns out to be too slow, something similar to the code in // TableColumnMapper.MapViaCopy() will need to be implemented. ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupTable); if ( oExcelTableReader.ColumnNames.Contains(GroupTableColumnNames.Name) && oExcelTableReader.ColumnNames.Contains(GroupTableColumnNames.Label) ) { foreach (ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { String sName; if ( oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.Name, out sName) ) { String sLabel; if ( oRow.TryGetNonEmptyStringFromCell( GroupTableColumnNames.Label, out sLabel) ) { sName += ": " + sLabel; } oRow.GetRangeForCell(GroupTableColumnNames.Label) .set_Value(Missing.Value, sName); } } } }
FilterColumnNames ( ExcelTableReader oExcelTableReader, HashSet<String> oColumnNamesToExclude ) { Debug.Assert(oExcelTableReader != null); Debug.Assert(oColumnNamesToExclude != null); AssertValid(); List<String> oFilteredColumnNames = new List<String>(); foreach (String sColumnName in oExcelTableReader.ColumnNames) { if ( !oColumnNamesToExclude.Contains(sColumnName) ) { oFilteredColumnNames.Add(sColumnName); } } return ( oFilteredColumnNames.ToArray() ); }
ReadAllColumns ( ExcelTableReader oExcelTableReader, ExcelTableReader.ExcelTableRow oRow, IMetadataProvider oEdgeOrVertex, HashSet<String> oColumnNamesToExclude ) { Debug.Assert(oExcelTableReader != null); Debug.Assert(oRow != null); Debug.Assert(oEdgeOrVertex != null); Debug.Assert(oColumnNamesToExclude != null); AssertValid(); foreach (String sColumnName in oExcelTableReader.ColumnNames) { String sValue; if ( !oColumnNamesToExclude.Contains(sColumnName) && oRow.TryGetNonEmptyStringFromCell(sColumnName, out sValue) ) { oEdgeOrVertex.SetValue(sColumnName, sValue); } } }
TryGetVertexShape ( ExcelTableReader.ExcelTableRow oRow, String sColumnName, out VertexShape eShape ) { Debug.Assert(oRow != null); Debug.Assert( !String.IsNullOrEmpty(sColumnName) ); AssertValid(); eShape = VertexShape.Circle; String sShape; if ( !oRow.TryGetNonEmptyStringFromCell(sColumnName, out sShape) ) { return (false); } VertexShapeConverter oVertexShapeConverter = new VertexShapeConverter(); if ( !oVertexShapeConverter.TryWorkbookToGraph(sShape, out eShape) ) { OnWorkbookFormatErrorWithDropDown(oRow, sColumnName, "shape"); } return (true); }
TryGetLocation ( ExcelTableReader.ExcelTableRow oRow, String sXColumnName, String sYColumnName, VertexLocationConverter oVertexLocationConverter, out PointF oLocation ) { Debug.Assert(oRow != null); Debug.Assert( !String.IsNullOrEmpty(sXColumnName) ); Debug.Assert( !String.IsNullOrEmpty(sYColumnName) ); Debug.Assert(oVertexLocationConverter != null); AssertValid(); oLocation = PointF.Empty; String sX, sY; Boolean bHasX = oRow.TryGetNonEmptyStringFromCell( sXColumnName, out sX); Boolean bHasY = oRow.TryGetNonEmptyStringFromCell( sYColumnName, out sY); if (bHasX != bHasY) { // X or Y alone won't do. goto Error; } if (!bHasX && !bHasY) { return (false); } Single fX, fY; if ( !Single.TryParse(sX, out fX) || !Single.TryParse(sY, out fY) ) { goto Error; } // Transform the location from workbook coordinates to graph // coordinates. oLocation = oVertexLocationConverter.WorkbookToGraph(fX, fY); return (true); Error: Range oInvalidCell = oRow.GetRangeForCell(sXColumnName); OnWorkbookFormatError( String.Format( "There is a problem with the location at {0}. If you enter a" + " location, it must include both X and Y numbers. Any" + " numbers are acceptable, although {1} is used for any" + " number less than {1} and and {2} is used for any number" + " greater than {2}." , ExcelUtil.GetRangeAddress(oInvalidCell), VertexLocationConverter.MinimumXYWorkbook.ToString( ExcelTemplateForm.Int32Format), VertexLocationConverter.MaximumXYWorkbook.ToString( ExcelTemplateForm.Int32Format) ), oInvalidCell ); // Make the compiler happy. return (false); }
TryGetColor ( ExcelTableReader.ExcelTableRow oRow, String sColumnName, ColorConverter2 oColorConverter2, out Color oColor ) { Debug.Assert(oRow != null); Debug.Assert( !String.IsNullOrEmpty(sColumnName) ); Debug.Assert(oColorConverter2 != null); AssertValid(); oColor = Color.Empty; String sColor; if ( !oRow.TryGetNonEmptyStringFromCell(sColumnName, out sColor) ) { return (false); } if ( !oColorConverter2.TryWorkbookToGraph(sColor, out oColor) ) { Range oInvalidCell = oRow.GetRangeForCell(sColumnName); OnWorkbookFormatError( String.Format( "The cell {0} contains an unrecognized color. Right-click the" + " cell and select Select Color on the right-click menu." , ExcelUtil.GetRangeAddress(oInvalidCell) ), oInvalidCell ); } return (true); }
GetRowIDDictionary ( ListObject oTable, String sColumnName ) { Debug.Assert(oTable != null); Debug.Assert( !String.IsNullOrEmpty(sColumnName) ); Dictionary<Int32, Object> oRowIDDictionary = new Dictionary<Int32, Object>(); // The code that reads the table can handle hidden rows, but not hidden // columns. Temporarily show all hidden columns in the table. ExcelHiddenColumns oHiddenColumns = ExcelColumnHider.ShowHiddenColumns(oTable); try { ExcelTableReader oExcelTableReader = new ExcelTableReader(oTable); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { Int32 iRowID; Double dCellValue; if ( oRow.TryGetInt32FromCell(CommonTableColumnNames.ID, out iRowID) && oRow.TryGetDoubleFromCell(sColumnName, out dCellValue) ) { oRowIDDictionary[iRowID] = dCellValue; } } } finally { ExcelColumnHider.RestoreHiddenColumns(oTable, oHiddenColumns); } return (oRowIDDictionary); }
//********************************************************************* // Constructor: ExcelTableRow() // /// <summary> /// Initializes a new instance of the <see cref="ExcelTableRow" /> /// class. /// </summary> /// /// <param name="excelTableReader"> /// The table reader object that owns this object. /// </param> //********************************************************************* public ExcelTableRow ( ExcelTableReader excelTableReader ) { m_oExcelTableReader = excelTableReader; AssertValid(); }
ReadGroupVertexTable ( ListObject oGroupVertexTable, ReadWorkbookContext oReadWorkbookContext, Dictionary<String, ExcelTemplateGroupInfo> oGroupNameDictionary, IGraph oGraph ) { Debug.Assert(oGroupVertexTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGroupNameDictionary != null); Debug.Assert(oGraph != null); AssertValid(); Dictionary<String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; ExcelTableReader oExcelTableReader = new ExcelTableReader(oGroupVertexTable); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the group vertex information from the row. String sGroupName, sVertexName; if ( !oRow.TryGetNonEmptyStringFromCell( GroupVertexTableColumnNames.GroupName, out sGroupName) || !oRow.TryGetNonEmptyStringFromCell( GroupVertexTableColumnNames.VertexName, out sVertexName) ) { continue; } // Get the group information for the vertex. ExcelTemplateGroupInfo oExcelTemplateGroupInfo; IVertex oVertex; if ( !oGroupNameDictionary.TryGetValue(sGroupName, out oExcelTemplateGroupInfo) || !oVertexNameDictionary.TryGetValue(sVertexName, out oVertex) ) { continue; } // If the vertex should get its color or shape from the group, set // the vertex's color or shape. Boolean bReadColorFromGroup, bReadShapeFromGroup; GetReadColorAndShapeFlags(oVertex, oExcelTemplateGroupInfo, oReadWorkbookContext, out bReadColorFromGroup, out bReadShapeFromGroup); if (bReadColorFromGroup) { oVertex.SetValue(ReservedMetadataKeys.PerColor, oExcelTemplateGroupInfo.VertexColor); } if (bReadShapeFromGroup) { oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, oExcelTemplateGroupInfo.VertexShape); } oExcelTemplateGroupInfo.Vertices.AddLast(oVertex); } }
ReadEdgeTable ( ListObject oEdgeTable, ReadWorkbookContext oReadWorkbookContext, IGraph oGraph ) { Debug.Assert(oEdgeTable != null); Debug.Assert(oReadWorkbookContext != null); Debug.Assert(oGraph != null); AssertValid(); Boolean bReadAllEdgeAndVertexColumns = oReadWorkbookContext.ReadAllEdgeAndVertexColumns; if (oReadWorkbookContext.FillIDColumns) { FillIDColumn(oEdgeTable); } Dictionary<String, IVertex> oVertexNameDictionary = oReadWorkbookContext.VertexNameDictionary; EdgeVisibilityConverter oEdgeVisibilityConverter = new EdgeVisibilityConverter(); Boolean bGraphIsDirected = (oGraph.Directedness == GraphDirectedness.Directed); ExcelTableReader oExcelTableReader = new ExcelTableReader(oEdgeTable); IVertexCollection oVertices = oGraph.Vertices; IEdgeCollection oEdges = oGraph.Edges; HashSet<String> oColumnNamesToExclude = new HashSet<String>( new String[] { EdgeTableColumnNames.Vertex1Name, EdgeTableColumnNames.Vertex2Name } ); foreach ( ExcelTableReader.ExcelTableRow oRow in oExcelTableReader.GetRows() ) { // Get the names of the edge's vertices. String sVertex1Name, sVertex2Name; Boolean bVertex1IsEmpty = !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.Vertex1Name, out sVertex1Name); Boolean bVertex2IsEmpty = !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.Vertex2Name, out sVertex2Name); if (bVertex1IsEmpty && bVertex2IsEmpty) { // Skip empty rows. continue; } if (bVertex1IsEmpty || bVertex2IsEmpty) { // A half-empty row is an error. OnHalfEmptyEdgeRow(oRow, bVertex1IsEmpty); } // Assume a default visibility. Visibility eVisibility = Visibility.Show; String sVisibility; if ( oRow.TryGetNonEmptyStringFromCell( CommonTableColumnNames.Visibility, out sVisibility) && !oEdgeVisibilityConverter.TryWorkbookToGraph( sVisibility, out eVisibility) ) { OnInvalidVisibility(oRow); } if (eVisibility == Visibility.Skip) { // Skip the edge an continue to the next edge. continue; } // Create the specified vertices or retrieve them from the // dictionary. IVertex oVertex1 = VertexNameToVertex( sVertex1Name, oVertices, oVertexNameDictionary); IVertex oVertex2 = VertexNameToVertex( sVertex2Name, oVertices, oVertexNameDictionary); // Add an edge connecting the vertices. IEdge oEdge = oEdges.Add(oVertex1, oVertex2, bGraphIsDirected); // If ReadWorkbookContext.FillIDColumns is true, add the edge to // the edge row ID dictionary and set the edge's Tag to the row ID. oReadWorkbookContext.AddToRowIDDictionary(oRow, oEdge, true); if (bReadAllEdgeAndVertexColumns) { // All columns except the vertex names should be read and // stored as metadata on the edge. ReadAllColumns(oExcelTableReader, oRow, oEdge, oColumnNamesToExclude); continue; } if (eVisibility == Visibility.Hide) { // Hide the edge and continue to the next edge. oEdge.SetValue(ReservedMetadataKeys.Visibility, VisibilityKeyValue.Hidden); continue; } // Alpha. Boolean bAlphaIsZero = ReadAlpha(oRow, oEdge); if (bAlphaIsZero) { continue; } // Color. ReadColor(oRow, EdgeTableColumnNames.Color, oEdge, ReservedMetadataKeys.PerColor, oReadWorkbookContext.ColorConverter2); // Width. ReadWidth(oRow, oReadWorkbookContext.EdgeWidthConverter, oEdge); // Style. ReadStyle(oRow, oReadWorkbookContext.EdgeStyleConverter, oEdge); // Label. if (oReadWorkbookContext.ReadEdgeLabels) { ReadCellAndSetMetadata(oRow, EdgeTableColumnNames.Label, oEdge, ReservedMetadataKeys.PerEdgeLabel); ReadColor(oRow, EdgeTableColumnNames.LabelTextColor, oEdge, ReservedMetadataKeys.PerEdgeLabelTextColor, oReadWorkbookContext.ColorConverter2); ReadLabelFontSize(oRow, oReadWorkbookContext.FontSizeConverter, oEdge); } // Weight. if (oReadWorkbookContext.ReadEdgeWeights) { ReadEdgeWeight(oRow, oEdge); } } if (bReadAllEdgeAndVertexColumns) { // Store the edge column names on the graph. oGraph.SetValue( ReservedMetadataKeys.AllEdgeMetadataKeys, FilterColumnNames(oExcelTableReader, oColumnNamesToExclude) ); } }
ReadLocked ( ExcelTableReader.ExcelTableRow oRow, BooleanConverter oBooleanConverter, Boolean bLocationSpecified, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(oBooleanConverter != null); Debug.Assert(oVertex != null); AssertValid(); Boolean bLocked; if ( !TryGetBoolean(oRow, VertexTableColumnNames.Locked, oBooleanConverter, out bLocked) ) { return; } if (bLocked && !bLocationSpecified) { Range oInvalidCell = oRow.GetRangeForCell( VertexTableColumnNames.Locked); OnWorkbookFormatError( String.Format( "The cell {0} indicates that the vertex should be locked," + " but the vertex has no X and Y location values. Either" + " clear the lock or specify a vertex location." , ExcelUtil.GetRangeAddress(oInvalidCell) ), oInvalidCell ); } oVertex.SetValue(ReservedMetadataKeys.LockVertexLocation, bLocked); }
ReadWidth ( ExcelTableReader.ExcelTableRow oRow, EdgeWidthConverter oEdgeWidthConverter, IEdge oEdge ) { Debug.Assert(oRow != null); Debug.Assert(oEdgeWidthConverter != null); AssertValid(); String sWidth; if ( !oRow.TryGetNonEmptyStringFromCell(EdgeTableColumnNames.Width, out sWidth) ) { return; } Single fWidth; if ( !Single.TryParse(sWidth, out fWidth) ) { Range oInvalidCell = oRow.GetRangeForCell( EdgeTableColumnNames.Width); OnWorkbookFormatError( String.Format( "The cell {0} contains an invalid width. The edge width," + " which is optional, must be a number. Any number is" + " acceptable, although {1} is used for any number less than" + " {1} and {2} is used for any number greater than {2}." , ExcelUtil.GetRangeAddress(oInvalidCell), EdgeWidthConverter.MinimumWidthWorkbook, EdgeWidthConverter.MaximumWidthWorkbook ), oInvalidCell ); } oEdge.SetValue(ReservedMetadataKeys.PerEdgeWidth, oEdgeWidthConverter.WorkbookToGraph(fWidth) ); }
ReadCustomMenuItems ( ExcelTableReader.ExcelTableRow oRow, ICollection< KeyValuePair<String, String> > aoCustomMenuItemPairNames, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(aoCustomMenuItemPairNames != null); Debug.Assert(oVertex != null); AssertValid(); // List of string pairs, one pair for each custom menu item to add to // the vertex's context menu in the graph. The key is the custom menu // item text and the value is the custom menu item action. List<KeyValuePair<String, String>> oCustomMenuItemInformation = new List<KeyValuePair<String, String>>(); foreach (KeyValuePair<String, String> oPairNames in aoCustomMenuItemPairNames) { String sCustomMenuItemText, sCustomMenuItemAction; // Both the menu item text and menu item action must be specified. // Skip the pair if either is missing. if ( !oRow.TryGetNonEmptyStringFromCell(oPairNames.Key, out sCustomMenuItemText) || !oRow.TryGetNonEmptyStringFromCell(oPairNames.Value, out sCustomMenuItemAction) ) { continue; } Int32 iCustomMenuItemTextLength = sCustomMenuItemText.Length; if (iCustomMenuItemTextLength > MaximumCustomMenuItemTextLength) { Range oInvalidCell = oRow.GetRangeForCell(oPairNames.Key); OnWorkbookFormatError( String.Format( "The cell {0} contains custom menu item text that is {1}" + " characters long. Custom menu item text can't be" + " longer than {2} characters." , ExcelUtil.GetRangeAddress(oInvalidCell), iCustomMenuItemTextLength, MaximumCustomMenuItemTextLength ), oInvalidCell ); } oCustomMenuItemInformation.Add( new KeyValuePair<String, String>( sCustomMenuItemText, sCustomMenuItemAction) ); } if (oCustomMenuItemInformation.Count > 0) { oVertex.SetValue( ReservedMetadataKeys.CustomContextMenuItems, oCustomMenuItemInformation.ToArray() ); } }
ReadStyle ( ExcelTableReader.ExcelTableRow oRow, EdgeStyleConverter oEdgeStyleConverter, IEdge oEdge ) { Debug.Assert(oRow != null); Debug.Assert(oEdgeStyleConverter != null); AssertValid(); String sStyle; if ( !oRow.TryGetNonEmptyStringFromCell(EdgeTableColumnNames.Style, out sStyle) ) { return; } EdgeStyle eStyle; if ( !oEdgeStyleConverter.TryWorkbookToGraph(sStyle, out eStyle) ) { OnWorkbookFormatErrorWithDropDown(oRow, EdgeTableColumnNames.Style, "style"); } oEdge.SetValue(ReservedMetadataKeys.PerEdgeStyle, eStyle); }
ReadLabelPosition ( ExcelTableReader.ExcelTableRow oRow, VertexLabelPositionConverter oVertexLabelPositionConverter, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(oVertex != null); Debug.Assert(oVertexLabelPositionConverter != null); AssertValid(); String sLabelPosition; if ( !oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.LabelPosition, out sLabelPosition) ) { return; } VertexLabelPosition eLabelPosition; if ( !oVertexLabelPositionConverter.TryWorkbookToGraph(sLabelPosition, out eLabelPosition) ) { OnWorkbookFormatErrorWithDropDown(oRow, VertexTableColumnNames.LabelPosition, "label position"); } oVertex.SetValue( ReservedMetadataKeys.PerVertexLabelPosition, eLabelPosition); }
ReadEdgeWeight ( ExcelTableReader.ExcelTableRow oRow, IEdge oEdge ) { Debug.Assert(oRow != null); AssertValid(); Double dEdgeWeight = 0; if ( !oRow.TryGetDoubleFromCell(EdgeTableColumnNames.EdgeWeight, out dEdgeWeight) ) { // There is no edge weight column, or the edge weight cell for this // edge is empty. dEdgeWeight = 1; } oEdge.SetValue(ReservedMetadataKeys.EdgeWeight, dEdgeWeight); }
ReadShape ( ExcelTableReader.ExcelTableRow oRow, IVertex oVertex, out VertexShape eShape ) { Debug.Assert(oRow != null); Debug.Assert(oVertex != null); AssertValid(); if ( TryGetVertexShape(oRow, VertexTableColumnNames.Shape, out eShape) ) { oVertex.SetValue(ReservedMetadataKeys.PerVertexShape, eShape); return (true); } return (false); }
ReadLabelFontSize ( ExcelTableReader.ExcelTableRow oRow, FontSizeConverter oFontSizeConverter, IEdge oEdge ) { Debug.Assert(oRow != null); Debug.Assert(oFontSizeConverter != null); AssertValid(); String sLabelFontSize; if ( !oRow.TryGetNonEmptyStringFromCell( EdgeTableColumnNames.LabelFontSize, out sLabelFontSize) ) { return; } Single fLabelFontSize; if ( !Single.TryParse(sLabelFontSize, out fLabelFontSize) ) { Range oInvalidCell = oRow.GetRangeForCell( EdgeTableColumnNames.LabelFontSize); OnWorkbookFormatError( String.Format( "The cell {0} contains an invalid label font size. The label" + " font size, which is optional, must be a number. Any" + " number is acceptable, although {1} is used for any number" + " less than {1} and {2} is used for any number greater than" + " {2}." , ExcelUtil.GetRangeAddress(oInvalidCell), FontSizeConverter.MinimumFontSizeWorkbook, FontSizeConverter.MaximumFontSizeWorkbook ), oInvalidCell ); } oEdge.SetValue(ReservedMetadataKeys.PerEdgeLabelFontSize, oFontSizeConverter.WorkbookToGraph(fLabelFontSize) ); }
ReadLayoutAndZOrder ( ExcelTableReader.ExcelTableRow oRow, IVertex oVertex ) { Debug.Assert(oRow != null); Debug.Assert(oVertex != null); AssertValid(); String sOrder; if ( !oRow.TryGetNonEmptyStringFromCell( VertexTableColumnNames.LayoutOrder, out sOrder) ) { return (false); } Single fOrder; if ( !Single.TryParse(sOrder, out fOrder) ) { Range oInvalidCell = oRow.GetRangeForCell( VertexTableColumnNames.LayoutOrder); OnWorkbookFormatError( String.Format( "The cell {0} contains an invalid layout order. The layout" + " order, which is optional, must be a number." , ExcelUtil.GetRangeAddress(oInvalidCell) ), oInvalidCell ); } oVertex.SetValue( ReservedMetadataKeys.SortableLayoutAndZOrder, fOrder); return (true); }
OnHalfEmptyEdgeRow ( ExcelTableReader.ExcelTableRow oRow, Boolean bVertex1IsEmpty ) { Debug.Assert(oRow != null); AssertValid(); Range oVertex1Cell = oRow.GetRangeForCell( EdgeTableColumnNames.Vertex1Name); Range oVertex2Cell = oRow.GetRangeForCell( EdgeTableColumnNames.Vertex2Name); Range oEmptyCell = bVertex1IsEmpty ? oVertex1Cell : oVertex2Cell; Range oNonEmptyCell = bVertex1IsEmpty ? oVertex2Cell : oVertex1Cell; String sEmptyRangeAddress = ExcelUtil.GetRangeAddress(oEmptyCell); String sNonEmptyRangeAddress = ExcelUtil.GetRangeAddress(oNonEmptyCell); String sErrorMessage = String.Format( "Cell {0} contains a vertex name but cell {1} is empty." + " You can include an empty row, which will be ignored," + " but you can't include a half-empty row." + "\r\n\r\n" + "You can fix the problem by entering a vertex name in {1} or" + " deleting the name in {0}." , sNonEmptyRangeAddress, sEmptyRangeAddress ); OnWorkbookFormatError(sErrorMessage, oEmptyCell); }
AddToRowIDDictionary ( ExcelTableReader.ExcelTableRow row, IIdentityProvider edgeOrVertex, Boolean isEdge ) { Debug.Assert(row != null); Debug.Assert(edgeOrVertex != null); AssertValid(); if (!m_bFillIDColumns) { return; } Dictionary<Int32, IIdentityProvider> oRowIDDictionary = isEdge ? m_oEdgeRowIDDictionary : m_oVertexRowIDDictionary; // Because the derived class fills in its ID column if the column // exists, each cell in the column should be valid. String sRowID; Int32 iRowID = Int32.MinValue; if ( row.TryGetNonEmptyStringFromCell(CommonTableColumnNames.ID, out sRowID) && Int32.TryParse(sRowID, out iRowID) ) { oRowIDDictionary.Add(iRowID, edgeOrVertex); Debug.Assert(edgeOrVertex is IMetadataProvider); // Store the row ID in the edge or vertex tag. ( (IMetadataProvider)edgeOrVertex ).Tag = iRowID; } }
TryGetBoolean ( ExcelTableReader.ExcelTableRow oRow, String sColumnName, BooleanConverter oBooleanConverter, out Boolean bBoolean ) { Debug.Assert(oRow != null); Debug.Assert( !String.IsNullOrEmpty(sColumnName) ); Debug.Assert(oBooleanConverter != null); AssertValid(); bBoolean = false; String sBoolean; if ( !oRow.TryGetNonEmptyStringFromCell(sColumnName, out sBoolean) ) { return (false); } if ( !oBooleanConverter.TryWorkbookToGraph(sBoolean, out bBoolean) ) { OnWorkbookFormatErrorWithDropDown(oRow, sColumnName, "value"); } return (true); }